/** * Recursive shape for the `keys` option of `merge` / `replace`. * Mirrors the shape of the `source` argument (reconcile iterates * source): at each object level the keys match source's property * names; at an array the leaf is `{ key: string }` naming the id * field of the array's element, optionally with nested options for * that element. */ export type ReconcileKeys = T extends ReadonlyArray ? U extends object ? { key: Extract } & { [K in keyof U]?: ReconcileKeys } : never : T extends object ? { [K in keyof T]?: ReconcileKeys } : never /** * Return type of `mutable()` / `signalify()`. Arrays become writable * arrays; objects are readonly-stripped so a frozen-input `T` still * types as assignable; Map/Set keep their class types. All variants * add `Record` — mutable proxies support dynamic * string **and symbol** keys at runtime, including on Map/Set * instances (the proxy uses `ProxyHandlerObject`-based trapping so * `map.customProp = 'x'` is reactive). */ export type Mutable = T extends Map | Set ? T & Record : T extends ReadonlyArray ? U[] & Record : { -readonly [K in keyof T]: T[K] } & Record /** * Deep-readonly view of `T`. Recurses through arrays, Maps, Sets, and * plain objects; leaves primitives, functions, and built-ins alone. * Used to tag a `store`'s first tuple element so direct writes are * rejected at the type level. */ export type DeepReadonly = T extends (...args: any[]) => any ? T : T extends ReadonlyArray ? ReadonlyArray> : T extends ReadonlyMap ? ReadonlyMap, DeepReadonly> : T extends ReadonlySet ? ReadonlySet> : T extends object ? { readonly [K in keyof T]: DeepReadonly } : T /** * Deep-mutable counterpart of `DeepReadonly` — strips `readonly` * through arrays, Maps, Sets, and plain objects. Used for the * setter's draft argument so a frozen/readonly input can still be * mutated inside `setStore`. */ export type DeepMutable = T extends (...args: any[]) => any ? T : T extends ReadonlyArray ? DeepMutable[] : T extends ReadonlyMap ? Map, DeepMutable> : T extends ReadonlySet ? Set> : T extends object ? { -readonly [K in keyof T]: DeepMutable } : T /** * Return type of `store(source)`: a `[DeepReadonly, setStore]` * tuple. `setStore` receives a mutator that sees the writable draft * and runs inside `batch()`. */ export type Store = readonly [ DeepReadonly, (mutator: (draft: DeepMutable) => void) => void, ]