All files / react-classic/src immutable.ts

100% Statements 19/19
100% Branches 6/6
100% Functions 2/2
100% Lines 19/19

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 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 1231x                           1x 1x                                                                                                       1x 9x 9x 9x 9x 9x 9x 10x 10x 9x 9x 9x 9x                                                                               1x 3x 3x  
import {
  anchor,
  type Immutable,
  type ImmutableOutput,
  type Linkable,
  type LinkableSchema,
  type ModelInput,
  type Mutable,
  type MutablePart,
  type MutationKey,
  type StateBaseOptions,
  type StateOptions,
} from '@anchorlib/core';
import type { AnchorState } from './types.js';
import { useStableRef } from './hooks.js';
import { useVariable } from './ref.js';
 
/**
 * A React hook that creates an immutable state from a linkable object.
 *
 * This hook wraps the provided linkable object in an immutable container,
 * ensuring that the state cannot be directly mutated and must be updated
 * through proper state update mechanisms.
 *
 * @template T - The type of the linkable object
 * @template S - The schema type for the anchor options
 * @param init - The initial linkable object to make immutable
 * @param options - Optional anchor configuration options
 * @returns An anchor state containing the immutable version of the input object
 */
export function useImmutable<T extends Linkable, S extends LinkableSchema = LinkableSchema>(
  init: T,
  options?: StateOptions<S>
): AnchorState<Immutable<T>>;
 
/**
 * A React hook that creates an immutable state from a model input with a schema.
 *
 * This hook creates an immutable state by applying a schema to the provided model input,
 * ensuring type safety and immutability of the resulting state.
 *
 * @template S - The schema type
 * @template T - The type of the model input
 * @param init - The initial model input to make immutable
 * @param schema - The schema to apply to the model input
 * @param options - Optional base state configuration options
 * @returns An anchor state containing the immutable version of the input object
 */
export function useImmutable<S extends LinkableSchema, T extends ModelInput<S>>(
  init: T,
  schema?: S,
  options?: StateBaseOptions
): AnchorState<ImmutableOutput<T>>;
 
/**
 * A React hook that creates an immutable state from a linkable object or model input.
 *
 * This hook provides a flexible way to create immutable states, handling both direct
 * linkable objects and model inputs with optional schemas.
 *
 * @template T - The type of the linkable object
 * @template S - The schema type for the anchor options
 * @param init - The initial object to make immutable
 * @param schemaOptions - Either a schema or state options
 * @param options - Optional base state configuration options
 * @returns An anchor state containing the immutable version of the input object
 */
export function useImmutable<T extends Linkable, S extends LinkableSchema = LinkableSchema>(
  init: T,
  schemaOptions?: S | StateOptions<S>,
  options?: StateBaseOptions
): AnchorState<Immutable<T> | ImmutableOutput<T>> {
  const [state, setState] = useVariable<ModelInput<T>>(
    (replace) => {
      return anchor.immutable(replace ?? (init as ModelInput<S>), schemaOptions as S, options) as ModelInput<T>;
    },
    [init, options]
  );
  return [state.value, state, setState] as AnchorState<Immutable<T> | ImmutableOutput<T>>;
}
 
/**
 * A React hook that creates a mutable version of an immutable state.
 *
 * This hook provides a way to work with immutable state in a mutable manner,
 * allowing controlled mutations through the returned mutable reference.
 *
 * @template T - The type of the linkable object
 * @param state - The immutable state to make mutable
 * @returns A mutable version of the input state
 */
export function useWriter<T extends Linkable>(state: T): Mutable<T>;
 
/**
 * A React hook that creates a mutable version of an immutable state with specific mutation contracts.
 *
 * This hook provides a way to work with immutable state in a mutable manner,
 * allowing controlled mutations through the returned mutable reference based on the provided contracts.
 *
 * @template T - The type of the linkable object
 * @template K - The mutation key contract array type
 * @param state - The immutable state to make mutable
 * @param contracts - Mutation key contracts that define allowed mutations
 * @returns A mutable version of the input state with only the specified mutations allowed
 */
export function useWriter<T extends Linkable, K extends MutationKey<T>[]>(state: T, contracts: K): MutablePart<T, K>;
 
/**
 * A React hook that creates a mutable version of an immutable state.
 *
 * This hook provides a way to work with immutable state in a mutable manner,
 * allowing controlled mutations through the returned mutable reference.
 *
 * @template T - The type of the linkable object
 * @template K - The mutation key contract array type
 * @param state - The immutable state to make mutable
 * @param contracts - Optional mutation key contracts that define allowed mutations
 * @returns A mutable version of the input state
 */
export function useWriter<T extends Linkable, K extends MutationKey<T>[]>(state: T, contracts?: K): MutablePart<T, K> {
  return useStableRef(() => anchor.writable(state, contracts), [state, ...(contracts ?? [])]).value;
}