UNPKG

fluidstate

Version:

Library for fine-grained reactivity state management

244 lines (243 loc) 7.74 kB
/** * Options for configuring the behavior of the `cloneInert` function. */ export type CloneInertOptions = { /** * Whether the clone is deep. * @default true */ deep?: boolean; /** * Whether computed property values should be excluded from the clone * @default false */ excludeComputed?: boolean; }; type IfEquals<X, Y, A = X, B = never> = (<T>() => T extends X ? 1 : 2) extends <T>() => T extends Y ? 1 : 2 ? A : B; /** * This utility helps us extract only writable keys of an object, which is currently * the best way to detect non-computed keys */ type WritableKeys<T> = { [P in keyof T]-?: IfEquals<{ [Q in P]: T[P]; }, { -readonly [Q in P]: T[P]; }, P>; }[keyof T]; type CloneInertReadonlyTupleResult<T, Options extends CloneInertOptions, DepthLimit extends number, DepthTracker extends unknown[]> = T extends readonly [ infer T1, infer T2, infer T3, infer T4, infer T5, infer T6 ] ? readonly [ CloneInertResultWithDepthLimit<T1, Options, DepthLimit, [ 0, ...DepthTracker ]>, CloneInertResultWithDepthLimit<T2, Options, DepthLimit, [ 0, ...DepthTracker ]>, CloneInertResultWithDepthLimit<T3, Options, DepthLimit, [ 0, ...DepthTracker ]>, CloneInertResultWithDepthLimit<T4, Options, DepthLimit, [ 0, ...DepthTracker ]>, CloneInertResultWithDepthLimit<T5, Options, DepthLimit, [ 0, ...DepthTracker ]>, CloneInertResultWithDepthLimit<T6, Options, DepthLimit, [ 0, ...DepthTracker ]> ] : T extends readonly [infer T1, infer T2, infer T3, infer T4, infer T5] ? readonly [ CloneInertResultWithDepthLimit<T1, Options, DepthLimit, [ 0, ...DepthTracker ]>, CloneInertResultWithDepthLimit<T2, Options, DepthLimit, [ 0, ...DepthTracker ]>, CloneInertResultWithDepthLimit<T3, Options, DepthLimit, [ 0, ...DepthTracker ]>, CloneInertResultWithDepthLimit<T4, Options, DepthLimit, [ 0, ...DepthTracker ]>, CloneInertResultWithDepthLimit<T5, Options, DepthLimit, [ 0, ...DepthTracker ]> ] : T extends readonly [infer T1, infer T2, infer T3, infer T4] ? readonly [ CloneInertResultWithDepthLimit<T1, Options, DepthLimit, [ 0, ...DepthTracker ]>, CloneInertResultWithDepthLimit<T2, Options, DepthLimit, [ 0, ...DepthTracker ]>, CloneInertResultWithDepthLimit<T3, Options, DepthLimit, [ 0, ...DepthTracker ]>, CloneInertResultWithDepthLimit<T4, Options, DepthLimit, [ 0, ...DepthTracker ]> ] : T extends readonly [infer T1, infer T2, infer T3] ? readonly [ CloneInertResultWithDepthLimit<T1, Options, DepthLimit, [ 0, ...DepthTracker ]>, CloneInertResultWithDepthLimit<T2, Options, DepthLimit, [ 0, ...DepthTracker ]>, CloneInertResultWithDepthLimit<T3, Options, DepthLimit, [ 0, ...DepthTracker ]> ] : T extends readonly [infer T1, infer T2] ? readonly [ CloneInertResultWithDepthLimit<T1, Options, DepthLimit, [ 0, ...DepthTracker ]>, CloneInertResultWithDepthLimit<T2, Options, DepthLimit, [ 0, ...DepthTracker ]> ] : T extends readonly [infer T1] ? readonly [ CloneInertResultWithDepthLimit<T1, Options, DepthLimit, [ 0, ...DepthTracker ]> ] : undefined; type CloneInertTupleResult<T, Options extends CloneInertOptions, DepthLimit extends number, DepthTracker extends unknown[]> = T extends [infer T1, infer T2, infer T3, infer T4, infer T5, infer T6] ? [ CloneInertResultWithDepthLimit<T1, Options, DepthLimit, [ 0, ...DepthTracker ]>, CloneInertResultWithDepthLimit<T2, Options, DepthLimit, [ 0, ...DepthTracker ]>, CloneInertResultWithDepthLimit<T3, Options, DepthLimit, [ 0, ...DepthTracker ]>, CloneInertResultWithDepthLimit<T4, Options, DepthLimit, [ 0, ...DepthTracker ]>, CloneInertResultWithDepthLimit<T5, Options, DepthLimit, [ 0, ...DepthTracker ]>, CloneInertResultWithDepthLimit<T6, Options, DepthLimit, [ 0, ...DepthTracker ]> ] : T extends [infer T1, infer T2, infer T3, infer T4, infer T5] ? [ CloneInertResultWithDepthLimit<T1, Options, DepthLimit, [ 0, ...DepthTracker ]>, CloneInertResultWithDepthLimit<T2, Options, DepthLimit, [ 0, ...DepthTracker ]>, CloneInertResultWithDepthLimit<T3, Options, DepthLimit, [ 0, ...DepthTracker ]>, CloneInertResultWithDepthLimit<T4, Options, DepthLimit, [ 0, ...DepthTracker ]>, CloneInertResultWithDepthLimit<T5, Options, DepthLimit, [ 0, ...DepthTracker ]> ] : T extends [infer T1, infer T2, infer T3, infer T4] ? [ CloneInertResultWithDepthLimit<T1, Options, DepthLimit, [ 0, ...DepthTracker ]>, CloneInertResultWithDepthLimit<T2, Options, DepthLimit, [ 0, ...DepthTracker ]>, CloneInertResultWithDepthLimit<T3, Options, DepthLimit, [ 0, ...DepthTracker ]>, CloneInertResultWithDepthLimit<T4, Options, DepthLimit, [ 0, ...DepthTracker ]> ] : T extends [infer T1, infer T2, infer T3] ? [ CloneInertResultWithDepthLimit<T1, Options, DepthLimit, [ 0, ...DepthTracker ]>, CloneInertResultWithDepthLimit<T2, Options, DepthLimit, [ 0, ...DepthTracker ]>, CloneInertResultWithDepthLimit<T3, Options, DepthLimit, [ 0, ...DepthTracker ]> ] : T extends [infer T1, infer T2] ? [ CloneInertResultWithDepthLimit<T1, Options, DepthLimit, [ 0, ...DepthTracker ]>, CloneInertResultWithDepthLimit<T2, Options, DepthLimit, [ 0, ...DepthTracker ]> ] : T extends [infer T1] ? [ CloneInertResultWithDepthLimit<T1, Options, DepthLimit, [ 0, ...DepthTracker ]> ] : undefined; type CloneInertResultWithDepthLimit<T, Options extends CloneInertOptions, DepthLimit extends number, DepthTracker extends unknown[]> = Options extends { excludeComputed: true; } ? DepthTracker["length"] extends DepthLimit ? T : CloneInertTupleResult<T, Options, DepthLimit, DepthTracker> extends {} ? CloneInertTupleResult<T, Options, DepthLimit, DepthTracker> : CloneInertReadonlyTupleResult<T, Options, DepthLimit, DepthTracker> extends {} ? CloneInertReadonlyTupleResult<T, Options, DepthLimit, DepthTracker> : T extends Map<infer Key, infer Value> ? Map<CloneInertResultWithDepthLimit<Key, Options, DepthLimit, [ 0, ...DepthTracker ]>, CloneInertResultWithDepthLimit<Value, Options, DepthLimit, [ 0, ...DepthTracker ]>> : T extends Set<infer Item> ? Set<CloneInertResultWithDepthLimit<Item, Options, DepthLimit, [ 0, ...DepthTracker ]>> : T extends Array<infer Item> ? Array<CloneInertResultWithDepthLimit<Item, Options, DepthLimit, [ 0, ...DepthTracker ]>> : T extends ReadonlyArray<infer Item> ? ReadonlyArray<CloneInertResultWithDepthLimit<Item, Options, DepthLimit, [ 0, ...DepthTracker ]>> : T extends object ? { [K in WritableKeys<T>]: CloneInertResultWithDepthLimit<T[K], Options, DepthLimit, [ 0, ...DepthTracker ]>; } : T : T; export type CloneInertResult<T, Options extends CloneInertOptions> = Options extends { deep: false; } ? CloneInertResultWithDepthLimit<T, Options, 1, []> : CloneInertResultWithDepthLimit<T, Options, 15, []>; export {};