All files / hooks/use-stack/src types.ts

0% Statements 0/0
0% Branches 0/0
0% Functions 0/0
0% Lines 0/0

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80                                                                                                                                                               
/**
 * Accepted initial value for {@link useStack}.
 *
 * Mirrors `useState`'s lazy-initializer support: pass an array, any iterable of
 * values, or a function returning one of those (evaluated once on mount). The
 * **last** element becomes the top of the stack (the next item to be popped).
 *
 * @template T - Element type.
 *
 * @example
 * ```ts
 * useStack<string>();                  // empty
 * useStack<string>(["a", "b"]);        // "b" is the top
 * useStack(new Set(["a", "b"]));       // any iterable works
 * useStack(() => expensiveInit());     // lazy
 * ```
 */
export type StackInitializer<T> = Iterable<T> | (() => Iterable<T>);
 
/**
 * Stable action handlers returned by {@link useStack}. Every function keeps a
 * stable identity across renders, so the actions object is safe to use as a
 * `useEffect`/`useMemo` dependency.
 *
 * @template T - Element type.
 */
export interface UseStackActions<T> {
  /**
   * Push one or more items onto the top of the stack. Items are pushed in
   * argument order, so the **last** argument ends up on top. Calling with no
   * arguments is a no-op and does not trigger a re-render.
   */
  push: (...items: T[]) => void;
 
  /**
   * Pop the top item: remove it from the stack and return it. Returns
   * `undefined` when the stack is empty (in which case it is a no-op and does
   * not trigger a re-render).
   *
   * The returned value reflects the top of the stack at call time. When `pop`
   * is called multiple times synchronously within the same event (before React
   * re-renders), each call returns the same top snapshot even though the
   * underlying state correctly shrinks — read the returned `stack` array after
   * the render for the settled state.
   */
  pop: () => T | undefined;
 
  /**
   * Peek at the top item (the next item that `pop` would return) without
   * mutating the stack. Returns `undefined` when the stack is empty. Stable
   * across renders and always reflects the latest state.
   */
  peek: () => T | undefined;
 
  /**
   * Remove every item. Clearing an already-empty stack is a no-op.
   */
  clear: () => void;
 
  /**
   * Reset the stack back to the initial value provided at mount (a fresh copy,
   * so later mutations never affect the stored initial).
   */
  reset: () => void;
}
 
/**
 * Return type of {@link useStack}: a tuple of the current (read-only) stack and
 * the stable action handlers.
 *
 * The stack is typed as `readonly T[]` on purpose — mutating it directly (e.g.
 * `stack.push(...)`) would bypass React state and break immutability, so the
 * type steers callers to the actions instead. Read access works as usual:
 * `stack[stack.length - 1]` is the top, `stack[0]` is the bottom, and
 * `stack.length` is the size.
 *
 * @template T - Element type.
 */
export type UseStackReturn<T> = [readonly T[], UseStackActions<T>];