@mmstack/primitives 21.0.24 → 21.0.26
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +52 -0
- package/fesm2022/mmstack-primitives.mjs +305 -54
- package/fesm2022/mmstack-primitives.mjs.map +1 -1
- package/package.json +1 -1
- package/types/mmstack-primitives.d.ts +135 -19
package/package.json
CHANGED
|
@@ -228,6 +228,55 @@ declare function mutable<T>(initial: T, opt?: CreateSignalOptions<T>): MutableSi
|
|
|
228
228
|
*/
|
|
229
229
|
declare function isMutable<T = any>(value: WritableSignal<T>): value is MutableSignal<T>;
|
|
230
230
|
|
|
231
|
+
/** @internal Narrows `'array'` so it is only assignable when `T` is an array type. */
|
|
232
|
+
type VivifyArray<T> = T extends any[] ? 'array' : never;
|
|
233
|
+
/** @internal Narrows `'object'` so it is only assignable when `T` is an object type. */
|
|
234
|
+
type VivifyObject<T> = T extends object ? 'object' : never;
|
|
235
|
+
/**
|
|
236
|
+
* Controls **autovivification** — whether, and as what shape, a writable `derived` (or `store`)
|
|
237
|
+
* creates a missing container when the source value is `null`/`undefined` at the moment of a
|
|
238
|
+
* write. Without it, writing through a nullish value is a no-op; with it, a deep write such as
|
|
239
|
+
* `derived(user, 'name', { vivify: 'object' }).set('Ada')` materializes the missing object
|
|
240
|
+
* instead of silently dropping the write.
|
|
241
|
+
*
|
|
242
|
+
* A **present** value is always preserved — updated in place for a `MutableSignal` source,
|
|
243
|
+
* copied for an immutable one. Vivification only ever *creates*, it never *replaces*.
|
|
244
|
+
*
|
|
245
|
+
* Variants:
|
|
246
|
+
* - `false` — **default.** Off; a write through a nullish source does nothing.
|
|
247
|
+
* - `true` / `'auto'` — infer the shape from the key: an array (`[]`) for a numeric / index key,
|
|
248
|
+
* a plain object (`{}`) otherwise.
|
|
249
|
+
* - `'object'` — always create a plain object (`{}`). Only assignable when `T` is an object.
|
|
250
|
+
* - `'array'` — always create an array (`[]`). Only assignable when `T` is an array.
|
|
251
|
+
* - `() => T` — a factory producing the container to create. Called only on a nullish source,
|
|
252
|
+
* once per vivification (a fresh instance each time), so a present value is never clobbered.
|
|
253
|
+
* Useful for seeding defaults, e.g. `() => ({ items: [], total: 0 })`.
|
|
254
|
+
*
|
|
255
|
+
* @typeParam T - The type of the container that may be created (the source/parent value).
|
|
256
|
+
*
|
|
257
|
+
* @example
|
|
258
|
+
* ```ts
|
|
259
|
+
* const user = signal<{ name: string } | null>(null);
|
|
260
|
+
*
|
|
261
|
+
* derived(user, 'name').set('Ada'); // off: dropped, user() === null
|
|
262
|
+
* derived(user, 'name', { vivify: 'object' }).set('Ada'); // user() === { name: 'Ada' }
|
|
263
|
+
* ```
|
|
264
|
+
*/
|
|
265
|
+
type Vivify<T = any> = 'auto' | boolean | (() => T) | VivifyArray<T> | VivifyObject<T>;
|
|
266
|
+
/**
|
|
267
|
+
* Options mix-in that adds an optional {@link Vivify} setting to the `options` argument of the
|
|
268
|
+
* `derived` / `store` key & index overloads.
|
|
269
|
+
*
|
|
270
|
+
* @typeParam T - The type of the container that may be vivified (the source/parent value).
|
|
271
|
+
*/
|
|
272
|
+
type WithVivify<T> = {
|
|
273
|
+
/**
|
|
274
|
+
* Whether, and as what shape, to create a missing container when the source value is
|
|
275
|
+
* `null`/`undefined` at write time. Defaults to `false` (no vivification). See {@link Vivify}.
|
|
276
|
+
*/
|
|
277
|
+
vivify?: Vivify<T>;
|
|
278
|
+
};
|
|
279
|
+
|
|
231
280
|
/**
|
|
232
281
|
* Options for creating a derived signal using the full `derived` function signature.
|
|
233
282
|
* @typeParam T - The type of the source signal's value (parent).
|
|
@@ -290,7 +339,10 @@ declare function derived<T, U>(source: WritableSignal<T>, opt: CreateDerivedOpti
|
|
|
290
339
|
* @typeParam TKey The key of the property to derive.
|
|
291
340
|
* @param source The source `WritableSignal` (holding an object).
|
|
292
341
|
* @param key The key of the property to derive.
|
|
293
|
-
* @param options Optional signal options for the derived signal.
|
|
342
|
+
* @param options Optional signal options for the derived signal. Also accepts a
|
|
343
|
+
* {@link Vivify} `vivify` flag (off by default) that, when set, creates the missing
|
|
344
|
+
* container instead of dropping a write made through a `null`/`undefined` source —
|
|
345
|
+
* e.g. `derived(user, 'name', { vivify: 'object' })`. See {@link WithVivify}.
|
|
294
346
|
* @returns A `DerivedSignal` instance.
|
|
295
347
|
*
|
|
296
348
|
* @example
|
|
@@ -306,7 +358,7 @@ declare function derived<T, U>(source: WritableSignal<T>, opt: CreateDerivedOpti
|
|
|
306
358
|
* console.log(user().name); // Outputs: Jane
|
|
307
359
|
* ```
|
|
308
360
|
*/
|
|
309
|
-
declare function derived<T extends object, TKey extends keyof T>(source: MutableSignal<T>, key: TKey, opt?: CreateSignalOptions<T[TKey]>): DerivedSignal<T, T[TKey]> & MutableSignal<T[TKey]>;
|
|
361
|
+
declare function derived<T extends object, TKey extends keyof T>(source: MutableSignal<T>, key: TKey, opt?: CreateSignalOptions<T[TKey]> & WithVivify<T>): DerivedSignal<T, T[TKey]> & MutableSignal<T[TKey]>;
|
|
310
362
|
/**
|
|
311
363
|
* Creates a `DerivedSignal` that derives a property from an object held by the source signal.
|
|
312
364
|
* This overload is a convenient shorthand for accessing object properties.
|
|
@@ -315,7 +367,10 @@ declare function derived<T extends object, TKey extends keyof T>(source: Mutable
|
|
|
315
367
|
* @typeParam TKey The key of the property to derive.
|
|
316
368
|
* @param source The source `WritableSignal` (holding an object).
|
|
317
369
|
* @param key The key of the property to derive.
|
|
318
|
-
* @param options Optional signal options for the derived signal.
|
|
370
|
+
* @param options Optional signal options for the derived signal. Also accepts a
|
|
371
|
+
* {@link Vivify} `vivify` flag (off by default) that, when set, creates the missing
|
|
372
|
+
* container instead of dropping a write made through a `null`/`undefined` source —
|
|
373
|
+
* e.g. `derived(user, 'name', { vivify: 'object' })`. See {@link WithVivify}.
|
|
319
374
|
* @returns A `DerivedSignal` instance.
|
|
320
375
|
*
|
|
321
376
|
* @example
|
|
@@ -331,7 +386,7 @@ declare function derived<T extends object, TKey extends keyof T>(source: Mutable
|
|
|
331
386
|
* console.log(user().name); // Outputs: Jane
|
|
332
387
|
* ```
|
|
333
388
|
*/
|
|
334
|
-
declare function derived<T extends object, TKey extends keyof T>(source: WritableSignal<T>, key: TKey, opt?: CreateSignalOptions<T[TKey]>): DerivedSignal<T, T[TKey]>;
|
|
389
|
+
declare function derived<T extends object, TKey extends keyof T>(source: WritableSignal<T>, key: TKey, opt?: CreateSignalOptions<T[TKey]> & WithVivify<T>): DerivedSignal<T, T[TKey]>;
|
|
335
390
|
/**
|
|
336
391
|
* Creates a `DerivedSignal` that derives its value from another `MutableSignal`.
|
|
337
392
|
* Use mutuable signals with caution, but very useful for deeply nested structures.
|
|
@@ -354,7 +409,7 @@ declare function derived<T extends object, TKey extends keyof T>(source: Writabl
|
|
|
354
409
|
* console.log(user().name); // Outputs: Jane
|
|
355
410
|
* ```
|
|
356
411
|
*/
|
|
357
|
-
declare function derived<T, U>(source: MutableSignal<T>, optOrKey: CreateDerivedOptions<T, U> | keyof T, opt?: CreateSignalOptions<U>): DerivedSignal<T, U> & MutableSignal<U>;
|
|
412
|
+
declare function derived<T, U>(source: MutableSignal<T>, optOrKey: CreateDerivedOptions<T, U> | keyof T, opt?: CreateSignalOptions<U> & WithVivify<T>): DerivedSignal<T, U> & MutableSignal<U>;
|
|
358
413
|
/**
|
|
359
414
|
* Creates a `DerivedSignal` from an array, deriving an element by its index.
|
|
360
415
|
* This overload is a convenient shorthand for accessing array elements.
|
|
@@ -362,7 +417,10 @@ declare function derived<T, U>(source: MutableSignal<T>, optOrKey: CreateDerived
|
|
|
362
417
|
* @typeParam T The type of the source signal's value (must be an array).
|
|
363
418
|
* @param source The source `WritableSignal` (holding an array).
|
|
364
419
|
* @param index The index of the element to derive.
|
|
365
|
-
* @param options Optional signal options for the derived signal.
|
|
420
|
+
* @param options Optional signal options for the derived signal. Also accepts a
|
|
421
|
+
* {@link Vivify} `vivify` flag (off by default) that, when set, creates the missing
|
|
422
|
+
* container instead of dropping a write made through a `null`/`undefined` source —
|
|
423
|
+
* e.g. `derived(user, 'name', { vivify: 'object' })`. See {@link WithVivify}.
|
|
366
424
|
* @returns A `DerivedSignal` instance.
|
|
367
425
|
*
|
|
368
426
|
* @example
|
|
@@ -378,7 +436,7 @@ declare function derived<T, U>(source: MutableSignal<T>, optOrKey: CreateDerived
|
|
|
378
436
|
* console.log(numbers()); // Outputs: [1, 5, 3]
|
|
379
437
|
* ```
|
|
380
438
|
*/
|
|
381
|
-
declare function derived<T extends any[]>(source: WritableSignal<T>, index: number, opt?: CreateSignalOptions<T[number]>): DerivedSignal<T, T[number]>;
|
|
439
|
+
declare function derived<T extends any[]>(source: WritableSignal<T>, index: number, opt?: CreateSignalOptions<T[number]> & WithVivify<T>): DerivedSignal<T, T[number]>;
|
|
382
440
|
/**
|
|
383
441
|
* Creates a "fake" `DerivedSignal` from a simple value. This is useful for creating
|
|
384
442
|
* `FormControlSignal` instances that are not directly derived from another signal.
|
|
@@ -1963,28 +2021,75 @@ type MutableArrayStore<T extends any[]> = MutableSignal<T> & {
|
|
|
1963
2021
|
readonly length: Signal<number>;
|
|
1964
2022
|
[Symbol.iterator](): Iterator<MutableSignalStore<T[number]>>;
|
|
1965
2023
|
};
|
|
1966
|
-
|
|
2024
|
+
/**
|
|
2025
|
+
* @internal Resolves to `true` only for `any`. In a conditional type, `any` distributes across
|
|
2026
|
+
* *both* branches (`unknown | object`), and `unknown | X` collapses to `unknown` — which would
|
|
2027
|
+
* erase a store's property access and `extend`. Guarding on this routes an `any`-typed store to
|
|
2028
|
+
* the full object shape instead.
|
|
2029
|
+
*/
|
|
2030
|
+
type IsAny<T> = 0 extends 1 & T ? true : false;
|
|
2031
|
+
/**
|
|
2032
|
+
* @internal Flattens an intersection (`A & B & C`) into a single object literal so editor
|
|
2033
|
+
* tooltips show the resolved members instead of the raw intersection chain. Display-only —
|
|
2034
|
+
* structurally identical to its input.
|
|
2035
|
+
*/
|
|
2036
|
+
type Simplify<T> = {
|
|
2037
|
+
[K in keyof T]: T[K];
|
|
2038
|
+
} & {};
|
|
2039
|
+
/** @internal The object shape of a readonly store: a child store per key, plus `extend`. */
|
|
2040
|
+
type SignalStoreObject<T> = Simplify<Readonly<{
|
|
1967
2041
|
[K in keyof Required<T>]: SignalStore<NonNullable<T>[K]>;
|
|
1968
|
-
}>
|
|
2042
|
+
}> & {
|
|
2043
|
+
readonly extend: {
|
|
2044
|
+
<L extends AnyRecord>(source: Signal<L>): SignalStore<Simplify<Omit<NonNullable<T>, keyof L> & L>>;
|
|
2045
|
+
<L extends AnyRecord>(props: L): SignalStore<Simplify<Omit<NonNullable<T>, keyof L> & L>>;
|
|
2046
|
+
};
|
|
2047
|
+
}>;
|
|
2048
|
+
/** @internal The object shape of a writable store. */
|
|
2049
|
+
type WritableSignalStoreObject<T> = Simplify<Readonly<{
|
|
2050
|
+
[K in keyof Required<T>]: WritableSignalStore<NonNullable<T>[K]>;
|
|
2051
|
+
}> & {
|
|
2052
|
+
readonly extend: {
|
|
2053
|
+
<L extends AnyRecord>(source: WritableSignal<L>): WritableSignalStore<Simplify<Omit<NonNullable<T>, keyof L> & L>>;
|
|
2054
|
+
<L extends AnyRecord>(props: L): WritableSignalStore<Simplify<Omit<NonNullable<T>, keyof L> & L>>;
|
|
2055
|
+
};
|
|
2056
|
+
}>;
|
|
2057
|
+
/** @internal The object shape of a mutable store. */
|
|
2058
|
+
type MutableSignalStoreObject<T> = Simplify<Readonly<{
|
|
2059
|
+
[K in keyof Required<T>]: MutableSignalStore<NonNullable<T>[K]>;
|
|
2060
|
+
}> & {
|
|
2061
|
+
readonly extend: {
|
|
2062
|
+
<L extends AnyRecord>(source: MutableSignal<L>): MutableSignalStore<Simplify<Omit<NonNullable<T>, keyof L> & L>>;
|
|
2063
|
+
<L extends AnyRecord>(props: L): MutableSignalStore<Simplify<Omit<NonNullable<T>, keyof L> & L>>;
|
|
2064
|
+
};
|
|
2065
|
+
}>;
|
|
2066
|
+
type SignalStore<T> = Signal<T> & (IsAny<T> extends true ? SignalStoreObject<T> : NonNullable<T> extends BaseType ? unknown : NonNullable<T> extends Array<any> ? SignalArrayStore<NonNullable<T>> : SignalStoreObject<T>);
|
|
1969
2067
|
type WritableSignalStore<T> = WritableSignal<T> & {
|
|
1970
2068
|
readonly asReadonlyStore: () => SignalStore<T>;
|
|
1971
|
-
} & (NonNullable<T> extends BaseType ? unknown : NonNullable<T> extends Array<any> ? WritableArrayStore<NonNullable<T>> :
|
|
1972
|
-
[K in keyof Required<T>]: WritableSignalStore<NonNullable<T>[K]>;
|
|
1973
|
-
}>);
|
|
2069
|
+
} & (IsAny<T> extends true ? WritableSignalStoreObject<T> : NonNullable<T> extends BaseType ? unknown : NonNullable<T> extends Array<any> ? WritableArrayStore<NonNullable<T>> : WritableSignalStoreObject<T>);
|
|
1974
2070
|
type MutableSignalStore<T> = MutableSignal<T> & {
|
|
1975
2071
|
readonly asReadonlyStore: () => SignalStore<T>;
|
|
1976
|
-
} & (NonNullable<T> extends BaseType ? unknown : NonNullable<T> extends Array<any> ? MutableArrayStore<NonNullable<T>> :
|
|
1977
|
-
|
|
1978
|
-
|
|
1979
|
-
declare function toStore<T extends AnyRecord>(source:
|
|
1980
|
-
declare function toStore<T extends AnyRecord>(source: WritableSignal<T>, injector?: Injector): WritableSignalStore<T>;
|
|
1981
|
-
declare function toStore<T extends AnyRecord>(source: Signal<T>, injector?: Injector): SignalStore<T>;
|
|
2072
|
+
} & (IsAny<T> extends true ? MutableSignalStoreObject<T> : NonNullable<T> extends BaseType ? unknown : NonNullable<T> extends Array<any> ? MutableArrayStore<NonNullable<T>> : MutableSignalStoreObject<T>);
|
|
2073
|
+
declare function toStore<T extends AnyRecord>(source: MutableSignal<T>, injector?: Injector, vivify?: Vivify): MutableSignalStore<T>;
|
|
2074
|
+
declare function toStore<T extends AnyRecord>(source: WritableSignal<T>, injector?: Injector, vivify?: Vivify): WritableSignalStore<T>;
|
|
2075
|
+
declare function toStore<T extends AnyRecord>(source: Signal<T>, injector?: Injector, vivify?: Vivify): SignalStore<T>;
|
|
1982
2076
|
/**
|
|
1983
2077
|
* Creates a WritableSignalStore from a value.
|
|
1984
2078
|
* @see {@link toStore}
|
|
1985
2079
|
*/
|
|
1986
2080
|
declare function store<T extends AnyRecord>(value: T, opt?: CreateSignalOptions<T> & {
|
|
1987
2081
|
injector?: Injector;
|
|
2082
|
+
/**
|
|
2083
|
+
* Opt-in autovivification: when writing through a `null`/`undefined` path, create the
|
|
2084
|
+
* missing intermediate containers instead of dropping the write. Off by default.
|
|
2085
|
+
*
|
|
2086
|
+
* Levels whose current value is a known object/array re-vivify as that same shape — the
|
|
2087
|
+
* knowledge is captured when the path is first accessed and cached, so it holds even after
|
|
2088
|
+
* the value is later nulled. This option governs only genuinely-unknown (currently
|
|
2089
|
+
* `null`/`undefined`) levels: `'auto'` (an array for index keys, an object otherwise), an
|
|
2090
|
+
* explicit `'object'`/`'array'`, or a `() => container` factory. See {@link Vivify}.
|
|
2091
|
+
*/
|
|
2092
|
+
vivify?: Vivify;
|
|
1988
2093
|
}): WritableSignalStore<T>;
|
|
1989
2094
|
/**
|
|
1990
2095
|
* Creates a MutableSignalStore from a value.
|
|
@@ -1992,6 +2097,17 @@ declare function store<T extends AnyRecord>(value: T, opt?: CreateSignalOptions<
|
|
|
1992
2097
|
*/
|
|
1993
2098
|
declare function mutableStore<T extends AnyRecord>(value: T, opt?: CreateSignalOptions<T> & {
|
|
1994
2099
|
injector?: Injector;
|
|
2100
|
+
/**
|
|
2101
|
+
* Opt-in autovivification: when writing through a `null`/`undefined` path, create the
|
|
2102
|
+
* missing intermediate containers instead of dropping the write. Off by default.
|
|
2103
|
+
*
|
|
2104
|
+
* Levels whose current value is a known object/array re-vivify as that same shape — the
|
|
2105
|
+
* knowledge is captured when the path is first accessed and cached, so it holds even after
|
|
2106
|
+
* the value is later nulled. This option governs only genuinely-unknown (currently
|
|
2107
|
+
* `null`/`undefined`) levels: `'auto'` (an array for index keys, an object otherwise), an
|
|
2108
|
+
* explicit `'object'`/`'array'`, or a `() => container` factory. See {@link Vivify}.
|
|
2109
|
+
*/
|
|
2110
|
+
vivify?: Vivify;
|
|
1995
2111
|
}): MutableSignalStore<T>;
|
|
1996
2112
|
|
|
1997
2113
|
/**
|
|
@@ -2422,4 +2538,4 @@ type CreateHistoryOptions<T> = Omit<CreateSignalOptions<T[]>, 'equal'> & {
|
|
|
2422
2538
|
declare function withHistory<T>(sourceOrValue: WritableSignal<T> | T, opt?: CreateHistoryOptions<T>): SignalWithHistory<T>;
|
|
2423
2539
|
|
|
2424
2540
|
export { batteryStatus, chunked, clipboard, combineWith, debounce, debounced, derived, distinct, elementSize, elementVisibility, filter, filterWith, focusWithin, geolocation, idle, indexArray, isDerivation, isMutable, isStore, keyArray, map, mapArray, mapObject, mediaQuery, mousePosition, mutable, mutableStore, nestedEffect, networkStatus, orientation, pageVisibility, pairwise, pipeable, piped, pooled, pooledArray, pooledMap, pooledSet, prefersDarkMode, prefersReducedMotion, scan, scrollPosition, select, sensor, sensors, signalFromEvent, startWith, store, stored, tabSync, tap, throttle, throttled, toFakeDerivation, toFakeSignalDerivation, toStore, toWritable, until, windowSize, withHistory };
|
|
2425
|
-
export type { BatteryStatus, ClipboardSignal, Computation, CreateChunkedOptions, CreateDebouncedOptions, CreateHistoryOptions, CreatePooledOptions, CreateProvidedPooledOptions, CreateStoredOptions, CreateThrottledOptions, DebouncedSignal, DerivedSignal, ElementSize, ElementSizeOptions, ElementSizeSignal, ElementVisibilityOptions, ElementVisibilitySignal, GeolocationOptions, GeolocationSignal, IdleOptions, IdleSignal, MousePositionOptions, MousePositionSignal, MutableSignal, MutableSignalStore, NetworkStatusSignal, PipeableSignal, ScreenOrientation, ScrollPosition, ScrollPositionOptions, ScrollPositionSignal, SignalFromEventOptions, SignalStore, SignalWithHistory, StoredSignal, ThrottledSignal, UntilOptions, WindowSize, WindowSizeOptions, WindowSizeSignal, WritableSignalStore };
|
|
2541
|
+
export type { BatteryStatus, ClipboardSignal, Computation, CreateChunkedOptions, CreateDebouncedOptions, CreateHistoryOptions, CreatePooledOptions, CreateProvidedPooledOptions, CreateStoredOptions, CreateThrottledOptions, DebouncedSignal, DerivedSignal, ElementSize, ElementSizeOptions, ElementSizeSignal, ElementVisibilityOptions, ElementVisibilitySignal, GeolocationOptions, GeolocationSignal, IdleOptions, IdleSignal, MousePositionOptions, MousePositionSignal, MutableSignal, MutableSignalStore, NetworkStatusSignal, PipeableSignal, ScreenOrientation, ScrollPosition, ScrollPositionOptions, ScrollPositionSignal, SignalFromEventOptions, SignalStore, SignalWithHistory, StoredSignal, ThrottledSignal, UntilOptions, Vivify, WindowSize, WindowSizeOptions, WindowSizeSignal, WithVivify, WritableSignalStore };
|