@mmstack/primitives 21.0.20 → 21.0.22

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mmstack/primitives",
3
- "version": "21.0.20",
3
+ "version": "21.0.22",
4
4
  "keywords": [
5
5
  "angular",
6
6
  "signals",
@@ -31,6 +31,7 @@
31
31
  "default": "./fesm2022/mmstack-primitives.mjs"
32
32
  }
33
33
  },
34
+ "type": "module",
34
35
  "dependencies": {
35
36
  "tslib": "^2.3.0"
36
37
  }
@@ -685,6 +685,128 @@ declare function pipeable<TSig extends Signal<any>>(signal: TSig): PipeableSigna
685
685
  */
686
686
  declare function piped<T>(initial: T, opt?: CreateSignalOptions<T>): PipeableSignal<T, WritableSignal<T>>;
687
687
 
688
+ /**
689
+ * Derives a value (`U`) from a freshly-reset buffer (`T`). Mutate the buffer
690
+ * and either return it directly or derive a different value from it. Naming
691
+ * matches Angular's `linkedSignal` `computation` convention.
692
+ */
693
+ type Computation<T, U> = (buffer: T) => U;
694
+ /**
695
+ * Options for {@link pooled}.
696
+ */
697
+ type CreatePooledOptions<T, U = T> = {
698
+ /** Factory for a buffer slot. Called at most twice in total per pool. */
699
+ create: () => T;
700
+ /**
701
+ * Restores a dirty buffer in-place, or returns a replacement instance. Not
702
+ * called on freshly-created buffers — only on reused ones.
703
+ */
704
+ reset: (dirty: T) => void | T;
705
+ /** Writes into the buffer and returns the derived value. */
706
+ computation: Computation<T, U>;
707
+ /**
708
+ * Pre-allocate both buffer slots at construction. Use when `create()` is
709
+ * expensive and you'd rather pay the cost up front than on the first reads.
710
+ * @default false
711
+ */
712
+ eager?: boolean;
713
+ } & CreateSignalOptions<U>;
714
+ /**
715
+ * A `Signal<U>` backed by a two-slot object pool: `create` is called at most
716
+ * twice over the pool's lifetime, and the two `T` instances are swapped on
717
+ * every recomputation with `reset` invoked on the dirty one before
718
+ * `computation` writes into it. Consecutive reads return different identities,
719
+ * so the default `Object.is` equality still flags changes.
720
+ *
721
+ * **Retention contract:** the returned value is only valid until the next
722
+ * recomputation of this signal. The container is recycled and `reset`,
723
+ * mutating any reference you still hold — do not store the result, pass it to
724
+ * async code, or hand it to consumers that outlive the current reactive tick.
725
+ *
726
+ * For collection buffers prefer the presets: {@link pooledArray},
727
+ * {@link pooledMap}, {@link pooledSet}.
728
+ *
729
+ * @see [Angular `linkedSignal`](https://angular.dev/api/core/linkedSignal) — carries previous *state* forward; complementary, not a substitute.
730
+ *
731
+ * @example
732
+ * ```ts
733
+ * const source = signal<{ active: boolean }[]>([]);
734
+ *
735
+ * const counters = pooled<{ total: number; active: number }>({
736
+ * create: () => ({ total: 0, active: 0 }),
737
+ * reset: (c) => { c.total = 0; c.active = 0; },
738
+ * computation: (c) => {
739
+ * for (const item of source()) { c.total++; if (item.active) c.active++; }
740
+ * return c;
741
+ * },
742
+ * });
743
+ * ```
744
+ */
745
+ declare function pooled<T, U = T>({ create, reset, computation, ...opt }: CreatePooledOptions<T, U>): Signal<U>;
746
+
747
+ /**
748
+ * Options for the preset pool helpers. Same shape as
749
+ * {@link CreatePooledOptions}, with `create` and `reset` made optional — each
750
+ * helper supplies its own defaults.
751
+ */
752
+ type CreateProvidedPooledOptions<T, U = T> = Omit<CreatePooledOptions<T, U>, 'create' | 'reset'> & Partial<Pick<CreatePooledOptions<T, U>, 'create' | 'reset'>>;
753
+ /**
754
+ * Array-buffer preset for {@link pooled}. Recycles a single array per slot;
755
+ * cleared via `arr.length = 0` between reads.
756
+ *
757
+ * Two overloads: a {@link Computation} shorthand (most common) or the full
758
+ * options object when you need `eager` or custom `create`/`reset`.
759
+ *
760
+ * Generic inference defaults `T` to `unknown[]` — annotate the callback or
761
+ * pass the type argument for tighter element types.
762
+ *
763
+ * @see {@link pooled} for the retention contract.
764
+ *
765
+ * @example
766
+ * ```ts
767
+ * const activeIds = pooledArray<number[]>((buf) => {
768
+ * for (const item of items()) if (item.active) buf.push(item.id);
769
+ * return buf;
770
+ * });
771
+ * ```
772
+ */
773
+ declare function pooledArray<T extends unknown[], U = T>(computation: Computation<T, U>, opt?: CreateSignalOptions<U>): Signal<U>;
774
+ declare function pooledArray<T extends unknown[], U = T>(opt: CreateProvidedPooledOptions<T, U>): Signal<U>;
775
+ /**
776
+ * Set-buffer preset for {@link pooled}. Recycles a single `Set` per slot;
777
+ * cleared via `.clear()` between reads. Overload shape mirrors
778
+ * {@link pooledArray}.
779
+ *
780
+ * @see {@link pooled} for the retention contract.
781
+ *
782
+ * @example
783
+ * ```ts
784
+ * const distinctRoles = pooledSet<Set<string>>((buf) => {
785
+ * for (const u of users()) buf.add(u.role);
786
+ * return buf;
787
+ * });
788
+ * ```
789
+ */
790
+ declare function pooledSet<T extends Set<unknown>, U = T>(computation: Computation<T, U>, opt?: CreateSignalOptions<U>): Signal<U>;
791
+ declare function pooledSet<T extends Set<unknown>, U = T>(opt: CreateProvidedPooledOptions<T, U>): Signal<U>;
792
+ /**
793
+ * Map-buffer preset for {@link pooled}. Recycles a single `Map` per slot;
794
+ * cleared via `.clear()` between reads. Overload shape mirrors
795
+ * {@link pooledArray}.
796
+ *
797
+ * @see {@link pooled} for the retention contract.
798
+ *
799
+ * @example
800
+ * ```ts
801
+ * const byId = pooledMap<Map<number, User>>((buf) => {
802
+ * for (const u of users()) buf.set(u.id, u);
803
+ * return buf;
804
+ * });
805
+ * ```
806
+ */
807
+ declare function pooledMap<T extends Map<unknown, unknown>, U = T>(computation: Computation<T, U>, opt?: CreateSignalOptions<U>): Signal<U>;
808
+ declare function pooledMap<T extends Map<unknown, unknown>, U = T>(opt: CreateProvidedPooledOptions<T, U>): Signal<U>;
809
+
688
810
  /**
689
811
  * Represents the size of an element.
690
812
  */
@@ -1507,7 +1629,6 @@ type StoredSignal<T> = WritableSignal<T> & {
1507
1629
  *
1508
1630
  * @Component({
1509
1631
  * selector: 'app-settings',
1510
- * standalone: true,
1511
1632
  * template: `
1512
1633
  * Theme:
1513
1634
  * <select [ngModel]="theme()" (ngModelChange)="theme.set($event)">
@@ -1828,5 +1949,5 @@ type CreateHistoryOptions<T> = Omit<CreateSignalOptions<T[]>, 'equal'> & {
1828
1949
  */
1829
1950
  declare function withHistory<T>(source: WritableSignal<T>, opt?: CreateHistoryOptions<T>): SignalWithHistory<T>;
1830
1951
 
1831
- export { chunked, combineWith, debounce, debounced, derived, distinct, elementSize, elementVisibility, filter, indexArray, isDerivation, isMutable, isStore, keyArray, map, mapArray, mapObject, mediaQuery, mousePosition, mutable, mutableStore, nestedEffect, networkStatus, pageVisibility, pipeable, piped, prefersDarkMode, prefersReducedMotion, scrollPosition, select, sensor, sensors, store, stored, tabSync, tap, throttle, throttled, toFakeDerivation, toFakeSignalDerivation, toStore, toWritable, until, windowSize, withHistory };
1832
- export type { CreateChunkedOptions, CreateDebouncedOptions, CreateHistoryOptions, CreateStoredOptions, CreateThrottledOptions, DebouncedSignal, DerivedSignal, ElementSize, ElementSizeOptions, ElementSizeSignal, ElementVisibilityOptions, ElementVisibilitySignal, MousePositionOptions, MousePositionSignal, MutableSignal, MutableSignalStore, NetworkStatusSignal, PipeableSignal, ScrollPosition, ScrollPositionOptions, ScrollPositionSignal, SignalStore, SignalWithHistory, StoredSignal, ThrottledSignal, UntilOptions, WindowSize, WindowSizeOptions, WindowSizeSignal, WritableSignalStore };
1952
+ export { chunked, combineWith, debounce, debounced, derived, distinct, elementSize, elementVisibility, filter, indexArray, isDerivation, isMutable, isStore, keyArray, map, mapArray, mapObject, mediaQuery, mousePosition, mutable, mutableStore, nestedEffect, networkStatus, pageVisibility, pipeable, piped, pooled, pooledArray, pooledMap, pooledSet, prefersDarkMode, prefersReducedMotion, scrollPosition, select, sensor, sensors, store, stored, tabSync, tap, throttle, throttled, toFakeDerivation, toFakeSignalDerivation, toStore, toWritable, until, windowSize, withHistory };
1953
+ export type { Computation, CreateChunkedOptions, CreateDebouncedOptions, CreateHistoryOptions, CreatePooledOptions, CreateProvidedPooledOptions, CreateStoredOptions, CreateThrottledOptions, DebouncedSignal, DerivedSignal, ElementSize, ElementSizeOptions, ElementSizeSignal, ElementVisibilityOptions, ElementVisibilitySignal, MousePositionOptions, MousePositionSignal, MutableSignal, MutableSignalStore, NetworkStatusSignal, PipeableSignal, ScrollPosition, ScrollPositionOptions, ScrollPositionSignal, SignalStore, SignalWithHistory, StoredSignal, ThrottledSignal, UntilOptions, WindowSize, WindowSizeOptions, WindowSizeSignal, WritableSignalStore };