@mmstack/primitives 21.0.23 → 21.0.25
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 +511 -65
- package/fesm2022/mmstack-primitives.mjs.map +1 -1
- package/package.json +1 -1
- package/types/mmstack-primitives.d.ts +400 -30
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.
|
|
@@ -564,7 +622,30 @@ declare const mapArray: typeof indexArray;
|
|
|
564
622
|
* @param mapFn The mapping function. Receives the item and its index as a Signal.
|
|
565
623
|
* @param options Optional configuration:
|
|
566
624
|
* - `onDestroy`: A callback invoked when a mapped item is removed from the array.
|
|
625
|
+
* - `key`: A custom key extractor for identity matching (e.g. `(item) => item.id`)
|
|
626
|
+
* when item references change but conceptual identity is preserved.
|
|
567
627
|
* @returns A `Signal<U[]>` containing the mapped array.
|
|
628
|
+
*
|
|
629
|
+
* @example
|
|
630
|
+
* ```ts
|
|
631
|
+
* const users = signal([
|
|
632
|
+
* { id: 1, name: 'Alice' },
|
|
633
|
+
* { id: 2, name: 'Bob' },
|
|
634
|
+
* ]);
|
|
635
|
+
*
|
|
636
|
+
* const rows = keyArray(
|
|
637
|
+
* users,
|
|
638
|
+
* (user, index) => ({
|
|
639
|
+
* label: computed(() => `#${index()} ${user.name}`),
|
|
640
|
+
* id: user.id,
|
|
641
|
+
* }),
|
|
642
|
+
* { key: (u) => u.id },
|
|
643
|
+
* );
|
|
644
|
+
*
|
|
645
|
+
* // Reordering users() rebuilds index signals only — `rows` entries
|
|
646
|
+
* // are matched by id and reused, not re-created.
|
|
647
|
+
* users.set([users()[1], users()[0]]);
|
|
648
|
+
* ```
|
|
568
649
|
*/
|
|
569
650
|
declare function keyArray<T, U, K>(source: Signal<T[]> | (() => T[]), mapFn: (v: T, i: Signal<number>) => U, options?: {
|
|
570
651
|
onDestroy?: (value: U) => void;
|
|
@@ -579,12 +660,71 @@ declare function keyArray<T, U, K>(source: Signal<T[]> | (() => T[]), mapFn: (v:
|
|
|
579
660
|
type MappedObject<T extends object, U> = {
|
|
580
661
|
[K in keyof T]: U;
|
|
581
662
|
};
|
|
663
|
+
/**
|
|
664
|
+
* Reactively maps each property of an object signal into a new object,
|
|
665
|
+
* preserving the same set of keys. For each key, `mapFn` receives a stable
|
|
666
|
+
* per-key signal — outputs for keys that haven't been added or removed are
|
|
667
|
+
* reused on subsequent reads. Sibling to {@link indexArray} / {@link keyArray}
|
|
668
|
+
* but for object records.
|
|
669
|
+
*
|
|
670
|
+
* The type of per-key signal passed into `mapFn` depends on the source:
|
|
671
|
+
* - `MutableSignal<T>` source → `MutableSignal<T[K]>` (in-place mutation)
|
|
672
|
+
* - `WritableSignal<T>` source → `WritableSignal<T[K]>` (two-way binding)
|
|
673
|
+
* - read-only `Signal<T>` or `() => T` source → read-only `Signal<T[K]>`
|
|
674
|
+
*
|
|
675
|
+
* @typeParam T The object type held by the source signal.
|
|
676
|
+
* @typeParam U The type produced for each key by `mapFn`.
|
|
677
|
+
*
|
|
678
|
+
* @param source A `MutableSignal<T>` whose properties are mapped with full
|
|
679
|
+
* in-place mutation capability via the per-key `MutableSignal`.
|
|
680
|
+
* @param mapFn Receives each key and its per-key `MutableSignal<T[K]>`.
|
|
681
|
+
* @param options Optional `onDestroy(value)` callback fired when a key is
|
|
682
|
+
* removed from the source.
|
|
683
|
+
* @returns A read-only signal of the mapped object.
|
|
684
|
+
*
|
|
685
|
+
* @example
|
|
686
|
+
* ```ts
|
|
687
|
+
* const state = mutable({ name: 'Alice', age: 30 });
|
|
688
|
+
* const view = mapObject(state, (key, prop) => ({
|
|
689
|
+
* label: key,
|
|
690
|
+
* current: computed(() => prop()),
|
|
691
|
+
* onInput: (next: any) => prop.set(next),
|
|
692
|
+
* }));
|
|
693
|
+
* view().age.onInput(31);
|
|
694
|
+
* state(); // { name: 'Alice', age: 31 }
|
|
695
|
+
* ```
|
|
696
|
+
*/
|
|
582
697
|
declare function mapObject<T extends object, U>(source: MutableSignal<T>, mapFn: <K extends keyof T>(key: K, value: MutableSignal<T[K]>) => U, options?: {
|
|
583
698
|
onDestroy?: (value: U) => void;
|
|
584
699
|
}): Signal<MappedObject<T, U>>;
|
|
700
|
+
/**
|
|
701
|
+
* Reactively maps each property of a `WritableSignal<T>` into a new object.
|
|
702
|
+
* Each key's per-property signal supports `.set` / `.update` for two-way
|
|
703
|
+
* binding back into the parent object.
|
|
704
|
+
*
|
|
705
|
+
* @example
|
|
706
|
+
* ```ts
|
|
707
|
+
* const user = signal({ name: 'Alice', age: 30 });
|
|
708
|
+
* const inputs = mapObject(user, (key, prop) => ({
|
|
709
|
+
* value: prop,
|
|
710
|
+
* setValue: (v: any) => prop.set(v),
|
|
711
|
+
* }));
|
|
712
|
+
* ```
|
|
713
|
+
*/
|
|
585
714
|
declare function mapObject<T extends object, U>(source: WritableSignal<T>, mapFn: <K extends keyof T>(key: K, value: WritableSignal<T[K]>) => U, options?: {
|
|
586
715
|
onDestroy?: (value: U) => void;
|
|
587
716
|
}): Signal<MappedObject<T, U>>;
|
|
717
|
+
/**
|
|
718
|
+
* Reactively maps each property of a read-only `Signal<T>` (or plain `() => T`
|
|
719
|
+
* accessor) into a new object. Per-key signals are read-only.
|
|
720
|
+
*
|
|
721
|
+
* @example
|
|
722
|
+
* ```ts
|
|
723
|
+
* const config = computed(() => ({ theme: 'dark', density: 'compact' }));
|
|
724
|
+
* const view = mapObject(config, (key, prop) => `${key}: ${prop()}`);
|
|
725
|
+
* view(); // { theme: 'theme: dark', density: 'density: compact' }
|
|
726
|
+
* ```
|
|
727
|
+
*/
|
|
588
728
|
declare function mapObject<T extends object, U>(source: (() => T) | Signal<T>, mapFn: <K extends keyof T>(key: K, value: Signal<T[K]>) => U, options?: {
|
|
589
729
|
onDestroy?: (value: U) => void;
|
|
590
730
|
}): Signal<MappedObject<T, U>>;
|
|
@@ -650,28 +790,136 @@ type PipeableSignal<T, TSig extends Signal<T> = Signal<T>> = TSig & {
|
|
|
650
790
|
*/
|
|
651
791
|
type SignalValue<TSig extends Signal<any>> = TSig extends Signal<infer V> ? V : never;
|
|
652
792
|
|
|
653
|
-
/**
|
|
793
|
+
/**
|
|
794
|
+
* Synchronous projection of a signal value with optional `CreateSignalOptions`
|
|
795
|
+
* (custom `equal`, `debugName`, etc.). Equivalent to `map` plus the ability to
|
|
796
|
+
* pass signal options through to the underlying `computed()`.
|
|
797
|
+
*
|
|
798
|
+
* @example
|
|
799
|
+
* ```ts
|
|
800
|
+
* const user = piped({ id: 1, name: 'Alice' });
|
|
801
|
+
* const name = user.pipe(select((u) => u.name));
|
|
802
|
+
* name(); // 'Alice'
|
|
803
|
+
* ```
|
|
804
|
+
*/
|
|
654
805
|
declare const select: <I, O>(projector: (v: I) => O, opt?: CreateSignalOptions<O>) => Operator<I, O>;
|
|
655
|
-
/**
|
|
806
|
+
/**
|
|
807
|
+
* Combine the piped signal with another `Signal` using a projector. The result
|
|
808
|
+
* recomputes whenever either source changes.
|
|
809
|
+
*
|
|
810
|
+
* @example
|
|
811
|
+
* ```ts
|
|
812
|
+
* const price = piped(10);
|
|
813
|
+
* const quantity = signal(3);
|
|
814
|
+
* const total = price.pipe(combineWith(quantity, (p, q) => p * q));
|
|
815
|
+
* total(); // 30
|
|
816
|
+
* ```
|
|
817
|
+
*/
|
|
656
818
|
declare const combineWith: <A, B, R>(other: Signal<B>, project: (a: A, b: B) => R, opt?: CreateSignalOptions<R>) => Operator<A, R>;
|
|
657
|
-
/**
|
|
819
|
+
/**
|
|
820
|
+
* Suppress emissions while consecutive values are considered equal. The
|
|
821
|
+
* comparator defaults to `Object.is`; pass a custom one for structural or
|
|
822
|
+
* key-based equality (e.g. compare by `id` only).
|
|
823
|
+
*
|
|
824
|
+
* @example
|
|
825
|
+
* ```ts
|
|
826
|
+
* const user = piped({ id: 1, lastSeen: Date.now() });
|
|
827
|
+
* const byId = user.pipe(distinct((a, b) => a.id === b.id));
|
|
828
|
+
* // byId only re-emits when `id` changes, not on every `lastSeen` update
|
|
829
|
+
* ```
|
|
830
|
+
*/
|
|
658
831
|
declare const distinct: <T>(equal?: (a: T, b: T) => boolean) => Operator<T, T>;
|
|
659
|
-
/**
|
|
832
|
+
/**
|
|
833
|
+
* Pure synchronous transform from input to output. Equivalent to a `computed()`
|
|
834
|
+
* that reads the source and returns `fn(value)`.
|
|
835
|
+
*
|
|
836
|
+
* @example
|
|
837
|
+
* ```ts
|
|
838
|
+
* const count = piped(2);
|
|
839
|
+
* const doubled = count.pipe(map((n) => n * 2));
|
|
840
|
+
* doubled(); // 4
|
|
841
|
+
* ```
|
|
842
|
+
*/
|
|
660
843
|
declare const map: <I, O>(fn: (v: I) => O) => Operator<I, O>;
|
|
661
|
-
/**
|
|
844
|
+
/**
|
|
845
|
+
* Keep only values that pass the predicate. The result holds the last passing
|
|
846
|
+
* value across emissions; before any value passes, the result is `undefined` —
|
|
847
|
+
* see {@link filterWith} when you need a non-`undefined` seed.
|
|
848
|
+
*
|
|
849
|
+
* @example
|
|
850
|
+
* ```ts
|
|
851
|
+
* const event = piped<MouseEvent | null>(null);
|
|
852
|
+
* const clicks = event.pipe(filter((e): e is MouseEvent => e?.type === 'click'));
|
|
853
|
+
* clicks(); // undefined until a click happens, then the last MouseEvent
|
|
854
|
+
* ```
|
|
855
|
+
*/
|
|
662
856
|
declare const filter: <T>(predicate: (v: T) => boolean) => Operator<T, T | undefined>;
|
|
663
|
-
/**
|
|
857
|
+
/**
|
|
858
|
+
* Run a side effect on every emission without altering the signal value. Wraps
|
|
859
|
+
* Angular's `effect()`, so it must run in an injection context or receive an
|
|
860
|
+
* explicit `injector`. Use for logging / analytics — not for setting other
|
|
861
|
+
* signals (that's what regular `effect()` is for).
|
|
862
|
+
*
|
|
863
|
+
* @example
|
|
864
|
+
* ```ts
|
|
865
|
+
* const count = piped(0);
|
|
866
|
+
* count.pipe(tap((n) => console.log('count:', n)));
|
|
867
|
+
* count.set(1); // logs 'count: 1'
|
|
868
|
+
* ```
|
|
869
|
+
*/
|
|
664
870
|
declare const tap: <T>(fn: (v: T) => void, injector?: Injector) => Operator<T, T>;
|
|
665
871
|
/**
|
|
666
|
-
* Like {@link filter}, but emits `initial` until a value passes the
|
|
667
|
-
*
|
|
872
|
+
* Like {@link filter}, but emits `initial` until a value first passes the
|
|
873
|
+
* predicate. Eliminates the `T | undefined` return type at the cost of an
|
|
874
|
+
* explicit seed value.
|
|
875
|
+
*
|
|
876
|
+
* @example
|
|
877
|
+
* ```ts
|
|
878
|
+
* const event = piped<MouseEvent | null>(null);
|
|
879
|
+
* const lastClick = event.pipe(filterWith((e) => e?.type === 'click', null));
|
|
880
|
+
* lastClick(); // null until the first click, then the most recent click event
|
|
881
|
+
* ```
|
|
668
882
|
*/
|
|
669
883
|
declare const filterWith: <T>(predicate: (v: T) => boolean, initial: T) => Operator<T, T>;
|
|
670
|
-
/**
|
|
884
|
+
/**
|
|
885
|
+
* Emit `initial` on the first read, then mirror the source on every subsequent
|
|
886
|
+
* read. Useful for giving a pipeline a sensible seed value before the source
|
|
887
|
+
* is ready (e.g. loading state).
|
|
888
|
+
*
|
|
889
|
+
* @example
|
|
890
|
+
* ```ts
|
|
891
|
+
* const data = piped<User | null>(null);
|
|
892
|
+
* const view = data.pipe(startWith<User | null, 'loading'>('loading'));
|
|
893
|
+
* view(); // 'loading' on first read, then User | null afterward
|
|
894
|
+
* ```
|
|
895
|
+
*/
|
|
671
896
|
declare const startWith: <T, U>(initial: U) => Operator<T, T | U>;
|
|
672
|
-
/**
|
|
897
|
+
/**
|
|
898
|
+
* Emit `[prev, curr]` tuples so consumers can react to transitions instead of
|
|
899
|
+
* raw values. On the first emission `prev` is `undefined`.
|
|
900
|
+
*
|
|
901
|
+
* @example
|
|
902
|
+
* ```ts
|
|
903
|
+
* const count = piped(0);
|
|
904
|
+
* const delta = count.pipe(pairwise(), map(([prev, curr]) => curr - (prev ?? 0)));
|
|
905
|
+
* count.set(5);
|
|
906
|
+
* delta(); // 5
|
|
907
|
+
* ```
|
|
908
|
+
*/
|
|
673
909
|
declare const pairwise: <T>() => Operator<T, [T | undefined, T]>;
|
|
674
|
-
/**
|
|
910
|
+
/**
|
|
911
|
+
* Reduce-like accumulator that folds each emission into a running result.
|
|
912
|
+
* Behaves like `Array.prototype.reduce` but applied over time, with the
|
|
913
|
+
* accumulator persisted across emissions.
|
|
914
|
+
*
|
|
915
|
+
* @example
|
|
916
|
+
* ```ts
|
|
917
|
+
* const delta = piped(0);
|
|
918
|
+
* const total = delta.pipe(scan((acc, n) => acc + n, 0));
|
|
919
|
+
* delta.set(5); // total() === 5
|
|
920
|
+
* delta.set(3); // total() === 8
|
|
921
|
+
* ```
|
|
922
|
+
*/
|
|
675
923
|
declare const scan: <T, R>(reducer: (acc: R, curr: T) => R, seed: R) => Operator<T, R>;
|
|
676
924
|
|
|
677
925
|
/**
|
|
@@ -829,6 +1077,15 @@ type BatteryStatus = {
|
|
|
829
1077
|
* Battery Status API. Returns `null` until the underlying `getBattery()`
|
|
830
1078
|
* promise resolves, or permanently when the API is unsupported (Firefox /
|
|
831
1079
|
* Safari at the time of writing). SSR-safe.
|
|
1080
|
+
*
|
|
1081
|
+
* @example
|
|
1082
|
+
* ```ts
|
|
1083
|
+
* const battery = batteryStatus();
|
|
1084
|
+
* effect(() => {
|
|
1085
|
+
* const b = battery();
|
|
1086
|
+
* if (b) console.log(`${Math.round(b.level * 100)}% • charging: ${b.charging}`);
|
|
1087
|
+
* });
|
|
1088
|
+
* ```
|
|
832
1089
|
*/
|
|
833
1090
|
declare function batteryStatus(debugName?: string): Signal<BatteryStatus | null>;
|
|
834
1091
|
|
|
@@ -963,6 +1220,15 @@ type FocusWithinTarget = ElementRef<Element> | Element | Signal<ElementRef<Eleme
|
|
|
963
1220
|
* Defaults `target` to the current `ElementRef` so it can be used inline in a
|
|
964
1221
|
* component's `class` field. SSR-safe — returns a constant `false` signal on
|
|
965
1222
|
* the server.
|
|
1223
|
+
*
|
|
1224
|
+
* @example
|
|
1225
|
+
* ```ts
|
|
1226
|
+
* @Component({ ... })
|
|
1227
|
+
* class MenuComponent {
|
|
1228
|
+
* // Defaults to the host element — flips true when focus is inside.
|
|
1229
|
+
* readonly hasFocus = focusWithin();
|
|
1230
|
+
* }
|
|
1231
|
+
* ```
|
|
966
1232
|
*/
|
|
967
1233
|
declare function focusWithin(target?: FocusWithinTarget): Signal<boolean>;
|
|
968
1234
|
|
|
@@ -1019,6 +1285,14 @@ type IdleSignal = Signal<boolean> & {
|
|
|
1019
1285
|
* activity) resets the timer and flips the signal back to `false`.
|
|
1020
1286
|
*
|
|
1021
1287
|
* SSR-safe — always `false` with a frozen `since` date on the server.
|
|
1288
|
+
*
|
|
1289
|
+
* @example
|
|
1290
|
+
* ```ts
|
|
1291
|
+
* const isAway = idle({ ms: 30_000 });
|
|
1292
|
+
* effect(() => {
|
|
1293
|
+
* if (isAway()) console.log('idle since', isAway.since());
|
|
1294
|
+
* });
|
|
1295
|
+
* ```
|
|
1022
1296
|
*/
|
|
1023
1297
|
declare function idle(opt?: IdleOptions): IdleSignal;
|
|
1024
1298
|
|
|
@@ -1212,6 +1486,14 @@ type NetworkStatusSignal = Signal<boolean> & {
|
|
|
1212
1486
|
*
|
|
1213
1487
|
* @param debugName Optional debug name for the signal.
|
|
1214
1488
|
* @returns A `NetworkStatusSignal` instance.
|
|
1489
|
+
*
|
|
1490
|
+
* @example
|
|
1491
|
+
* ```ts
|
|
1492
|
+
* const online = networkStatus();
|
|
1493
|
+
* effect(() => {
|
|
1494
|
+
* if (!online()) console.log('offline since', online.since());
|
|
1495
|
+
* });
|
|
1496
|
+
* ```
|
|
1215
1497
|
*/
|
|
1216
1498
|
declare function networkStatus(debugName?: string): NetworkStatusSignal;
|
|
1217
1499
|
|
|
@@ -1226,6 +1508,15 @@ type ScreenOrientation = {
|
|
|
1226
1508
|
*
|
|
1227
1509
|
* SSR-safe — returns a constant `portrait-primary / 0°` signal on the server
|
|
1228
1510
|
* and in environments without `screen.orientation` support.
|
|
1511
|
+
*
|
|
1512
|
+
* @example
|
|
1513
|
+
* ```ts
|
|
1514
|
+
* const screenOrientation = orientation();
|
|
1515
|
+
* effect(() => {
|
|
1516
|
+
* const { type, angle } = screenOrientation();
|
|
1517
|
+
* console.log(`${type} at ${angle}°`);
|
|
1518
|
+
* });
|
|
1519
|
+
* ```
|
|
1229
1520
|
*/
|
|
1230
1521
|
declare function orientation(debugName?: string): Signal<ScreenOrientation>;
|
|
1231
1522
|
|
|
@@ -1641,6 +1932,27 @@ type SensorsOptions<TKey extends keyof SensorTypedOptions> = {
|
|
|
1641
1932
|
type Sensors<TKey extends keyof SensorTypedOptions> = {
|
|
1642
1933
|
[K in TKey]: SensorTypedOptions[K]['returnType'];
|
|
1643
1934
|
};
|
|
1935
|
+
/**
|
|
1936
|
+
* Bulk sensor factory — creates several sensor signals at once and returns
|
|
1937
|
+
* them keyed by sensor type. Convenient when a single consumer needs to react
|
|
1938
|
+
* to multiple browser signals; for a single sensor prefer {@link sensor}
|
|
1939
|
+
* directly.
|
|
1940
|
+
*
|
|
1941
|
+
* @typeParam TType The union of sensor keys being requested.
|
|
1942
|
+
* @param track Array of sensor type keys to create.
|
|
1943
|
+
* @param opt Optional per-sensor options keyed by sensor type.
|
|
1944
|
+
* @returns A record `{ [key]: <SensorReturnType> }` for each requested key.
|
|
1945
|
+
*
|
|
1946
|
+
* @example
|
|
1947
|
+
* ```ts
|
|
1948
|
+
* const { windowSize, networkStatus } = sensors(
|
|
1949
|
+
* ['windowSize', 'networkStatus'],
|
|
1950
|
+
* { windowSize: { throttle: 200 } },
|
|
1951
|
+
* );
|
|
1952
|
+
*
|
|
1953
|
+
* effect(() => console.log(windowSize(), networkStatus()));
|
|
1954
|
+
* ```
|
|
1955
|
+
*/
|
|
1644
1956
|
declare function sensors<const TType extends keyof SensorTypedOptions>(track: TType[], opt?: SensorsOptions<TType>): Sensors<TType>;
|
|
1645
1957
|
|
|
1646
1958
|
/**
|
|
@@ -1709,28 +2021,75 @@ type MutableArrayStore<T extends any[]> = MutableSignal<T> & {
|
|
|
1709
2021
|
readonly length: Signal<number>;
|
|
1710
2022
|
[Symbol.iterator](): Iterator<MutableSignalStore<T[number]>>;
|
|
1711
2023
|
};
|
|
1712
|
-
|
|
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<{
|
|
1713
2041
|
[K in keyof Required<T>]: SignalStore<NonNullable<T>[K]>;
|
|
1714
|
-
}>
|
|
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>);
|
|
1715
2067
|
type WritableSignalStore<T> = WritableSignal<T> & {
|
|
1716
2068
|
readonly asReadonlyStore: () => SignalStore<T>;
|
|
1717
|
-
} & (NonNullable<T> extends BaseType ? unknown : NonNullable<T> extends Array<any> ? WritableArrayStore<NonNullable<T>> :
|
|
1718
|
-
[K in keyof Required<T>]: WritableSignalStore<NonNullable<T>[K]>;
|
|
1719
|
-
}>);
|
|
2069
|
+
} & (IsAny<T> extends true ? WritableSignalStoreObject<T> : NonNullable<T> extends BaseType ? unknown : NonNullable<T> extends Array<any> ? WritableArrayStore<NonNullable<T>> : WritableSignalStoreObject<T>);
|
|
1720
2070
|
type MutableSignalStore<T> = MutableSignal<T> & {
|
|
1721
2071
|
readonly asReadonlyStore: () => SignalStore<T>;
|
|
1722
|
-
} & (NonNullable<T> extends BaseType ? unknown : NonNullable<T> extends Array<any> ? MutableArrayStore<NonNullable<T>> :
|
|
1723
|
-
|
|
1724
|
-
|
|
1725
|
-
declare function toStore<T extends AnyRecord>(source:
|
|
1726
|
-
declare function toStore<T extends AnyRecord>(source: WritableSignal<T>, injector?: Injector): WritableSignalStore<T>;
|
|
1727
|
-
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>;
|
|
1728
2076
|
/**
|
|
1729
2077
|
* Creates a WritableSignalStore from a value.
|
|
1730
2078
|
* @see {@link toStore}
|
|
1731
2079
|
*/
|
|
1732
2080
|
declare function store<T extends AnyRecord>(value: T, opt?: CreateSignalOptions<T> & {
|
|
1733
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;
|
|
1734
2093
|
}): WritableSignalStore<T>;
|
|
1735
2094
|
/**
|
|
1736
2095
|
* Creates a MutableSignalStore from a value.
|
|
@@ -1738,6 +2097,17 @@ declare function store<T extends AnyRecord>(value: T, opt?: CreateSignalOptions<
|
|
|
1738
2097
|
*/
|
|
1739
2098
|
declare function mutableStore<T extends AnyRecord>(value: T, opt?: CreateSignalOptions<T> & {
|
|
1740
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;
|
|
1741
2111
|
}): MutableSignalStore<T>;
|
|
1742
2112
|
|
|
1743
2113
|
/**
|
|
@@ -2168,4 +2538,4 @@ type CreateHistoryOptions<T> = Omit<CreateSignalOptions<T[]>, 'equal'> & {
|
|
|
2168
2538
|
declare function withHistory<T>(sourceOrValue: WritableSignal<T> | T, opt?: CreateHistoryOptions<T>): SignalWithHistory<T>;
|
|
2169
2539
|
|
|
2170
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 };
|
|
2171
|
-
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 };
|