@mmstack/primitives 22.1.1 → 22.1.2

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": "22.1.1",
3
+ "version": "22.1.2",
4
4
  "keywords": [
5
5
  "angular",
6
6
  "signals",
@@ -25,7 +25,7 @@ type CreateChunkedOptions<T> = {
25
25
  /**
26
26
  * Creates a new `Signal` that processes an array of items in time-sliced chunks. This is useful for handling large lists without blocking the main thread.
27
27
  *
28
- * The returned signal will initially contain the first `chunkSize` items from the source array. It will then schedule updates to include additional chunks of items based on the specified `duration`.
28
+ * The returned signal will initially contain the first `chunkSize` items from the source array. It will then schedule updates to include additional chunks of items based on the specified `delay`.
29
29
  *
30
30
  * @template T The type of items in the array.
31
31
  * @param source A `Signal` or a function that returns an array of items to be processed in chunks.
@@ -34,7 +34,7 @@ type CreateChunkedOptions<T> = {
34
34
  *
35
35
  * @example
36
36
  * const largeList = signal(Array.from({ length: 1000 }, (_, i) => i));
37
- * const chunkedList = chunked(largeList, { chunkSize: 100, duration: 100 });
37
+ * const chunkedList = chunked(largeList, { chunkSize: 100, delay: 100 });
38
38
  */
39
39
  declare function chunked<T>(source: Signal<T[]> | (() => T[]), options?: CreateChunkedOptions<T>): Signal<T[]>;
40
40
 
@@ -141,8 +141,9 @@ declare function pausableEffect(effectFn: (registerCleanup: EffectCleanupRegiste
141
141
  /**
142
142
  * Like `signal`, but pausable. While paused, READS hold the last value; writes still land on the
143
143
  * underlying signal and surface on resume. Built on the `keepPrevious`/`hold` shape — a
144
- * `linkedSignal` gated on the pause predicate, with `set`/`update`/`asReadonly` forwarded to the
145
- * source signal. With no `pause` option it defaults to the ambient `PAUSED_CONTEXT`; `pause: false`
144
+ * `linkedSignal` gated on the pause predicate, with `set`/`update` forwarded to the source signal.
145
+ * `asReadonly()` returns the held (gated) view, so both views of the signal agree while paused.
146
+ * With no `pause` option it defaults to the ambient `PAUSED_CONTEXT`; `pause: false`
146
147
  * makes it a plain `signal` — no `linkedSignal` is created.
147
148
  *
148
149
  * NOTE: while paused, `set(x)` followed by a read returns the *held* (pre-pause) value, not `x` — the
@@ -176,6 +177,11 @@ type TransitionRef = {
176
177
  *
177
178
  * Must be called in an injection context. This is the *async* generalization (Tier 2): it adds
178
179
  * no rendering cost and needs no fork — holding direct/sync readers is a separate, deferred tier.
180
+ *
181
+ * Caveat: work must go in flight by the first post-write render to be awaited. A loader that
182
+ * starts later (a debounced request signal, a chained/deferred resource) is not attributable to
183
+ * this transition — the no-async fallback will have already resolved `done`. Trigger such work
184
+ * eagerly inside `fn`, or coordinate it separately.
179
185
  */
180
186
  declare function injectStartTransition(): (fn: () => void) => TransitionRef;
181
187
 
@@ -331,6 +337,11 @@ type TransactionRef = {
331
337
  * The writes land on LIVE state immediately (so derived variables and connector requests see the
332
338
  * new values and refetch); only the *display* is held, via `scope.hold`. Must run in an injection
333
339
  * context.
340
+ *
341
+ * Caveat: work must go in flight by the first post-write render to be part of the transaction. A
342
+ * loader that starts later (a debounced request signal, a chained/deferred resource) is not
343
+ * attributable to it — the no-async fallback will have already committed and released the hold,
344
+ * after which `abort()` is a no-op. Trigger such work eagerly inside `fn`.
334
345
  */
335
346
  declare function injectStartTransaction(): (fn: () => void) => TransactionRef;
336
347
 
@@ -524,7 +535,7 @@ declare function mutable<T>(initial: T, opt?: CreateSignalOptions<T>): MutableSi
524
535
  * myMutableSignal.mutate(x => x + 1); // This is safe.
525
536
  * }
526
537
  */
527
- declare function isMutable<T = any>(value: WritableSignal<T>): value is MutableSignal<T>;
538
+ declare function isMutable<T = unknown>(value: WritableSignal<T>): value is MutableSignal<T>;
528
539
 
529
540
  /** @internal Narrows `'array'` so it is only assignable when `T` is an array type. */
530
541
  type VivifyArray<T> = T extends any[] ? 'array' : never;
@@ -1085,7 +1096,7 @@ type SignalPipe<In> = {
1085
1096
  * @see {@link SignalPipe}
1086
1097
  * @example
1087
1098
  * ```ts
1088
- * import { piped } from '@ngrx/signals';
1099
+ * import { piped } from '@mmstack/primitives';
1089
1100
  *
1090
1101
  * const count = piped(1);
1091
1102
  *
@@ -1248,7 +1259,7 @@ declare const scan: <T, R>(reducer: (acc: R, curr: T) => R, seed: R) => Operator
1248
1259
  */
1249
1260
  declare function pipeable<TSig extends Signal<any>>(signal: TSig): PipeableSignal<SignalValue<TSig>, TSig>;
1250
1261
  /**
1251
- * Create a new **writable** signal and return it as a `PipableSignal`.
1262
+ * Create a new **writable** signal and return it as a `PipeableSignal`.
1252
1263
  *
1253
1264
  * The returned value is a `WritableSignal<T>` with `.set`, `.update`, `.asReadonly`
1254
1265
  * still available (via intersection type), plus a chainable `.pipe(...)`.
@@ -1382,6 +1393,22 @@ declare function pooledSet<T extends Set<unknown>, U = T>(opt: CreateProvidedPoo
1382
1393
  declare function pooledMap<T extends Map<unknown, unknown>, U = T>(computation: Computation<T, U>, opt?: CreateSignalOptions<U>): Signal<U>;
1383
1394
  declare function pooledMap<T extends Map<unknown, unknown>, U = T>(opt: CreateProvidedPooledOptions<T, U>): Signal<U>;
1384
1395
 
1396
+ /**
1397
+ * Options shared by every sensor: an optional `debugName` for the produced signal(s) and an
1398
+ * optional `Injector` that lifts the injection-context requirement.
1399
+ */
1400
+ type SensorRunOptions = {
1401
+ /** Optional debug name for the produced signal(s). */
1402
+ debugName?: string;
1403
+ /**
1404
+ * Injector used to resolve the sensor's dependencies (`PLATFORM_ID`, `DestroyRef`, default
1405
+ * `ElementRef` targets, ...). Provide it when creating the sensor outside an injection
1406
+ * context — e.g. in `ngOnInit`, an event handler, or an effect body. When omitted, the
1407
+ * sensor must be created in an injection context (a constructor / field initializer).
1408
+ */
1409
+ injector?: Injector;
1410
+ };
1411
+
1385
1412
  type BatteryStatus = {
1386
1413
  readonly level: number;
1387
1414
  readonly charging: boolean;
@@ -1403,7 +1430,7 @@ type BatteryStatus = {
1403
1430
  * });
1404
1431
  * ```
1405
1432
  */
1406
- declare function batteryStatus(debugName?: string): Signal<BatteryStatus | null>;
1433
+ declare function batteryStatus(opt?: string | SensorRunOptions): Signal<BatteryStatus | null>;
1407
1434
 
1408
1435
  type ClipboardSignal = Signal<string> & {
1409
1436
  /**
@@ -1425,7 +1452,7 @@ type ClipboardSignal = Signal<string> & {
1425
1452
  * in browsers that gate it. Errors from `navigator.clipboard.readText` are
1426
1453
  * swallowed silently to keep the signal value stable.
1427
1454
  */
1428
- declare function clipboard(debugName?: string): ClipboardSignal;
1455
+ declare function clipboard(opt?: string | SensorRunOptions): ClipboardSignal;
1429
1456
 
1430
1457
  /**
1431
1458
  * Represents the size of an element.
@@ -1437,10 +1464,7 @@ interface ElementSize {
1437
1464
  /**
1438
1465
  * Options for configuring the `elementSize` sensor.
1439
1466
  */
1440
- type ElementSizeOptions = ResizeObserverOptions & {
1441
- /** Optional debug name for the internal signal. */
1442
- debugName?: string;
1443
- };
1467
+ type ElementSizeOptions = ResizeObserverOptions & SensorRunOptions;
1444
1468
  type ElementSizeSignal = Signal<ElementSize | undefined>;
1445
1469
  /**
1446
1470
  * Creates a read-only signal that tracks the size of a target DOM element.
@@ -1466,10 +1490,7 @@ declare function elementSize(target?: ElementRef<Element> | Element | Signal<Ele
1466
1490
  * Options for configuring the `elementVisibility` sensor, extending
1467
1491
  * standard `IntersectionObserverInit` options.
1468
1492
  */
1469
- type ElementVisibilityOptions = IntersectionObserverInit & {
1470
- /** Optional debug name for the internal signal. */
1471
- debugName?: string;
1472
- };
1493
+ type ElementVisibilityOptions = IntersectionObserverInit & SensorRunOptions;
1473
1494
  type ElementVisibilitySignal = Signal<IntersectionObserverEntry | undefined> & {
1474
1495
  readonly visible: Signal<boolean>;
1475
1496
  };
@@ -1546,17 +1567,15 @@ type FocusWithinTarget = ElementRef<Element> | Element | Signal<ElementRef<Eleme
1546
1567
  * }
1547
1568
  * ```
1548
1569
  */
1549
- declare function focusWithin(target?: FocusWithinTarget): Signal<boolean>;
1570
+ declare function focusWithin(target?: FocusWithinTarget, opt?: SensorRunOptions): Signal<boolean>;
1550
1571
 
1551
- type GeolocationOptions = PositionOptions & {
1572
+ type GeolocationOptions = PositionOptions & SensorRunOptions & {
1552
1573
  /**
1553
1574
  * If `true`, uses `navigator.geolocation.watchPosition` and updates the
1554
1575
  * signal continuously. Otherwise a single `getCurrentPosition` call is made.
1555
1576
  * @default false
1556
1577
  */
1557
1578
  watch?: boolean;
1558
- /** Optional debug name for the produced signal. */
1559
- debugName?: string;
1560
1579
  };
1561
1580
  type GeolocationSignal = Signal<GeolocationPosition | null> & {
1562
1581
  readonly error: Signal<GeolocationPositionError | null>;
@@ -1577,7 +1596,7 @@ type GeolocationSignal = Signal<GeolocationPosition | null> & {
1577
1596
  */
1578
1597
  declare function geolocation(opt?: GeolocationOptions): GeolocationSignal;
1579
1598
 
1580
- type IdleOptions = {
1599
+ type IdleOptions = SensorRunOptions & {
1581
1600
  /**
1582
1601
  * Milliseconds of user inactivity before the signal flips to `true`.
1583
1602
  * @default 60_000
@@ -1588,11 +1607,12 @@ type IdleOptions = {
1588
1607
  * @default ['mousemove','keydown','touchstart','scroll','visibilitychange']
1589
1608
  */
1590
1609
  events?: string[];
1591
- /** Optional debug name for the produced signal. */
1592
- debugName?: string;
1593
1610
  };
1594
1611
  type IdleSignal = Signal<boolean> & {
1595
- /** Timestamp of the last idle/active transition. */
1612
+ /**
1613
+ * Timestamp of the last idle/active transition. Before any transition has occurred it
1614
+ * holds the sensor's creation time, not an actual transition.
1615
+ */
1596
1616
  readonly since: Signal<Date>;
1597
1617
  };
1598
1618
  /**
@@ -1656,7 +1676,7 @@ declare function idle(opt?: IdleOptions): IdleSignal;
1656
1676
  * }
1657
1677
  * ```
1658
1678
  */
1659
- declare function mediaQuery(query: string, debugName?: string): Signal<boolean>;
1679
+ declare function mediaQuery(query: string, opt?: string | SensorRunOptions): Signal<boolean>;
1660
1680
  /**
1661
1681
  * Creates a read-only signal that tracks the user's OS/browser preference
1662
1682
  * for a dark color scheme using the `(prefers-color-scheme: dark)` media query.
@@ -1678,7 +1698,7 @@ declare function mediaQuery(query: string, debugName?: string): Signal<boolean>;
1678
1698
  * });
1679
1699
  * ```
1680
1700
  */
1681
- declare function prefersDarkMode(debugName?: string): Signal<boolean>;
1701
+ declare function prefersDarkMode(opt?: string | SensorRunOptions): Signal<boolean>;
1682
1702
  /**
1683
1703
  * Creates a read-only signal that tracks the user's OS/browser preference
1684
1704
  * for reduced motion using the `(prefers-reduced-motion: reduce)` media query.
@@ -1704,7 +1724,7 @@ declare function prefersDarkMode(debugName?: string): Signal<boolean>;
1704
1724
  * });
1705
1725
  * ```
1706
1726
  */
1707
- declare function prefersReducedMotion(debugName?: string): Signal<boolean>;
1727
+ declare function prefersReducedMotion(opt?: string | SensorRunOptions): Signal<boolean>;
1708
1728
 
1709
1729
  type MousePosition = {
1710
1730
  x: number;
@@ -1713,13 +1733,15 @@ type MousePosition = {
1713
1733
  /**
1714
1734
  * Options for configuring the `mousePosition` sensor.
1715
1735
  */
1716
- type MousePositionOptions = {
1736
+ type MousePositionOptions = SensorRunOptions & {
1717
1737
  /**
1718
1738
  * The target element to listen for mouse movements on.
1719
- * Can be `window`, `document`, an `HTMLElement`, or an `ElementRef<HTMLElement>`.
1739
+ * Can be `window`, `document`, an `HTMLElement`, an `ElementRef<HTMLElement>`, or a
1740
+ * `Signal` resolving to one (e.g. a `viewChild` result) — listeners re-attach when the
1741
+ * signal's element changes, and nothing is tracked while it is `null`/`undefined`.
1720
1742
  * @default window
1721
1743
  */
1722
- target?: Window | Document | HTMLElement | ElementRef<HTMLElement>;
1744
+ target?: Window | Document | HTMLElement | ElementRef<HTMLElement> | Signal<HTMLElement | ElementRef<HTMLElement> | null | undefined>;
1723
1745
  /**
1724
1746
  * Defines the coordinate system for the reported position.
1725
1747
  * - `'client'`: Coordinates relative to the viewport (`clientX`, `clientY`).
@@ -1733,10 +1755,6 @@ type MousePositionOptions = {
1733
1755
  * @default false
1734
1756
  */
1735
1757
  touch?: boolean;
1736
- /**
1737
- * Optional debug name for the internal signal.
1738
- */
1739
- debugName?: string;
1740
1758
  /**
1741
1759
  * Optional delay in milliseconds to throttle the updates.
1742
1760
  * @default 100
@@ -1790,7 +1808,10 @@ declare function mousePosition(opt?: MousePositionOptions): MousePositionSignal;
1790
1808
  * It's a boolean signal with an attached `since` signal.
1791
1809
  */
1792
1810
  type NetworkStatusSignal = Signal<boolean> & {
1793
- /** A signal tracking the timestamp of the last status change. */
1811
+ /**
1812
+ * A signal tracking the timestamp of the last status change. Before any change has
1813
+ * occurred it holds the sensor's creation time, not an actual transition.
1814
+ */
1794
1815
  readonly since: Signal<Date>;
1795
1816
  };
1796
1817
  /**
@@ -1800,7 +1821,8 @@ type NetworkStatusSignal = Signal<boolean> & {
1800
1821
  * An additional `since` signal is attached, tracking when the status last changed.
1801
1822
  * It's SSR-safe and automatically cleans up its event listeners.
1802
1823
  *
1803
- * @param debugName Optional debug name for the signal.
1824
+ * @param opt Optional debug name for the signal, or a {@link SensorRunOptions} object
1825
+ * (with an optional `injector` for creation outside an injection context).
1804
1826
  * @returns A `NetworkStatusSignal` instance.
1805
1827
  *
1806
1828
  * @example
@@ -1811,14 +1833,20 @@ type NetworkStatusSignal = Signal<boolean> & {
1811
1833
  * });
1812
1834
  * ```
1813
1835
  */
1814
- declare function networkStatus(debugName?: string): NetworkStatusSignal;
1836
+ declare function networkStatus(opt?: string | SensorRunOptions): NetworkStatusSignal;
1815
1837
 
1816
- type ScreenOrientation = {
1838
+ type ScreenOrientationState = {
1817
1839
  /** Angle in degrees relative to the natural orientation. */
1818
1840
  readonly angle: number;
1819
1841
  /** One of the four `OrientationType` strings. */
1820
1842
  readonly type: OrientationType;
1821
1843
  };
1844
+ /**
1845
+ * @deprecated Use {@link ScreenOrientationState} instead — this name shadows the DOM's global
1846
+ * `ScreenOrientation` interface in any module that imports it, silently changing the meaning of
1847
+ * `screen.orientation`-related typings there.
1848
+ */
1849
+ type ScreenOrientation = ScreenOrientationState;
1822
1850
  /**
1823
1851
  * Creates a read-only signal that tracks `screen.orientation`.
1824
1852
  *
@@ -1834,7 +1862,7 @@ type ScreenOrientation = {
1834
1862
  * });
1835
1863
  * ```
1836
1864
  */
1837
- declare function orientation(debugName?: string): Signal<ScreenOrientation>;
1865
+ declare function orientation(opt?: string | SensorRunOptions): Signal<ScreenOrientationState>;
1838
1866
 
1839
1867
  /**
1840
1868
  * Creates a read-only signal that tracks the page's visibility state.
@@ -1844,7 +1872,8 @@ declare function orientation(debugName?: string): Signal<ScreenOrientation>;
1844
1872
  * The primitive is SSR-safe and automatically cleans up its event listeners
1845
1873
  * when the creating context is destroyed.
1846
1874
  *
1847
- * @param debugName Optional debug name for the signal.
1875
+ * @param opt Optional debug name for the signal, or a {@link SensorRunOptions} object
1876
+ * (with an optional `injector` for creation outside an injection context).
1848
1877
  * @returns A read-only `Signal<DocumentVisibilityState>`. On the server,
1849
1878
  * it returns a static signal with a value of `'visible'`.
1850
1879
  *
@@ -1872,7 +1901,7 @@ declare function orientation(debugName?: string): Signal<ScreenOrientation>;
1872
1901
  * }
1873
1902
  * ```
1874
1903
  */
1875
- declare function pageVisibility(debugName?: string): Signal<DocumentVisibilityState>;
1904
+ declare function pageVisibility(opt?: string | SensorRunOptions): Signal<DocumentVisibilityState>;
1876
1905
 
1877
1906
  /**
1878
1907
  * Represents the scroll position.
@@ -1886,21 +1915,21 @@ type ScrollPosition = {
1886
1915
  /**
1887
1916
  * Options for configuring the `scrollPosition` sensor.
1888
1917
  */
1889
- type ScrollPositionOptions = {
1918
+ type ScrollPositionOptions = SensorRunOptions & {
1890
1919
  /**
1891
1920
  * The target to listen for scroll events on.
1892
- * Can be `window` (for page scroll) or an `HTMLElement`/`ElementRef<HTMLElement>`.
1921
+ * Can be `window` (for page scroll), an `HTMLElement`/`ElementRef<HTMLElement>`, or a
1922
+ * `Signal` resolving to one (e.g. a `viewChild` result) — listeners re-attach when the
1923
+ * signal's element changes, and nothing is tracked while it is `null`/`undefined`.
1893
1924
  * @default window
1894
1925
  */
1895
- target?: Window | HTMLElement | ElementRef<HTMLElement>;
1926
+ target?: Window | HTMLElement | ElementRef<HTMLElement> | Signal<HTMLElement | ElementRef<HTMLElement> | null | undefined>;
1896
1927
  /**
1897
1928
  * Optional delay in milliseconds to throttle the updates.
1898
1929
  * Scroll events can fire very rapidly.
1899
1930
  * @default 100 // A common default for scroll throttling
1900
1931
  */
1901
1932
  throttle?: number;
1902
- /** Optional debug name for the internal signal. */
1903
- debugName?: string;
1904
1933
  };
1905
1934
  /**
1906
1935
  * A specialized Signal that tracks scroll position.
@@ -1931,26 +1960,17 @@ type ScrollPositionSignal = Signal<ScrollPosition> & {
1931
1960
  * selector: 'app-scroll-tracker',
1932
1961
  * template: `
1933
1962
  * <p>Window Scroll: X: {{ windowScroll().x }}, Y: {{ windowScroll().y }}</p>
1934
- * <div #scrollableDiv style="height: 200px; width: 200px; overflow: auto; border: 1px solid black;">
1935
- * <div style="height: 400px; width: 400px;">Scroll me!</div>
1936
- * </div>
1937
- * @if (divScroll()) {
1938
- * <p>Div Scroll: X: {{ divScroll().x }}, Y: {{ divScroll().y }}</p>
1939
- * }
1963
+ * <p>Host Scroll: X: {{ hostScroll().x }}, Y: {{ hostScroll().y }}</p>
1940
1964
  * `
1941
1965
  * })
1942
1966
  * export class ScrollTrackerComponent {
1943
1967
  * readonly windowScroll = scrollPosition(); // Defaults to window
1968
+ * // Signal targets (e.g. viewChild) attach once the element exists:
1944
1969
  * readonly scrollableDiv = viewChild<ElementRef<HTMLDivElement>>('scrollableDiv');
1945
- * readonly divScroll = scrollPosition({ target: this.scrollableDiv() }); // Example with element target
1970
+ * readonly divScroll = scrollPosition({ target: this.scrollableDiv });
1946
1971
  *
1947
1972
  * constructor() {
1948
- * effect(() => {
1949
- * console.log('Window scrolled to:', this.windowScroll());
1950
- * if (this.divScroll()) {
1951
- * console.log('Div scrolled to:', this.divScroll());
1952
- * }
1953
- * });
1973
+ * effect(() => console.log('Window scrolled to:', this.windowScroll()));
1954
1974
  * }
1955
1975
  * }
1956
1976
  * ```
@@ -1967,13 +1987,9 @@ type WindowSize = {
1967
1987
  readonly height: number;
1968
1988
  };
1969
1989
  /**
1970
- * Options for configuring the `mousePosition` sensor.
1990
+ * Options for configuring the `windowSize` sensor.
1971
1991
  */
1972
- type WindowSizeOptions = {
1973
- /**
1974
- * Optional debug name for the internal signal.
1975
- */
1976
- debugName?: string;
1992
+ type WindowSizeOptions = SensorRunOptions & {
1977
1993
  /**
1978
1994
  * Optional delay in milliseconds to throttle the updates.
1979
1995
  * @default 100
@@ -2050,27 +2066,19 @@ type SensorTypedOptions = {
2050
2066
  returnType: MousePositionSignal;
2051
2067
  };
2052
2068
  networkStatus: {
2053
- opt: {
2054
- debugName?: string;
2055
- };
2069
+ opt: SensorRunOptions;
2056
2070
  returnType: NetworkStatusSignal;
2057
2071
  };
2058
2072
  pageVisibility: {
2059
- opt: {
2060
- debugName?: string;
2061
- };
2073
+ opt: SensorRunOptions;
2062
2074
  returnType: Signal<DocumentVisibilityState>;
2063
2075
  };
2064
2076
  darkMode: {
2065
- opt: {
2066
- debugName?: string;
2067
- };
2077
+ opt: SensorRunOptions;
2068
2078
  returnType: Signal<boolean>;
2069
2079
  };
2070
2080
  reducedMotion: {
2071
- opt: {
2072
- debugName?: string;
2073
- };
2081
+ opt: SensorRunOptions;
2074
2082
  returnType: Signal<boolean>;
2075
2083
  };
2076
2084
  scrollPosition: {
@@ -2082,9 +2090,8 @@ type SensorTypedOptions = {
2082
2090
  returnType: WindowSizeSignal;
2083
2091
  };
2084
2092
  mediaQuery: {
2085
- opt: {
2093
+ opt: SensorRunOptions & {
2086
2094
  query: string;
2087
- debugName?: string;
2088
2095
  };
2089
2096
  returnType: Signal<boolean>;
2090
2097
  };
@@ -2093,21 +2100,15 @@ type SensorTypedOptions = {
2093
2100
  returnType: GeolocationSignal;
2094
2101
  };
2095
2102
  clipboard: {
2096
- opt: {
2097
- debugName?: string;
2098
- };
2103
+ opt: SensorRunOptions;
2099
2104
  returnType: ClipboardSignal;
2100
2105
  };
2101
2106
  orientation: {
2102
- opt: {
2103
- debugName?: string;
2104
- };
2105
- returnType: Signal<ScreenOrientation>;
2107
+ opt: SensorRunOptions;
2108
+ returnType: Signal<ScreenOrientationState>;
2106
2109
  };
2107
2110
  batteryStatus: {
2108
- opt: {
2109
- debugName?: string;
2110
- };
2111
+ opt: SensorRunOptions;
2111
2112
  returnType: Signal<BatteryStatus | null>;
2112
2113
  };
2113
2114
  idle: {
@@ -2115,8 +2116,7 @@ type SensorTypedOptions = {
2115
2116
  returnType: IdleSignal;
2116
2117
  };
2117
2118
  focusWithin: {
2118
- opt: {
2119
- debugName?: string;
2119
+ opt: SensorRunOptions & {
2120
2120
  target?: ElementRef<Element> | Element | Signal<ElementRef<Element> | Element | null>;
2121
2121
  };
2122
2122
  returnType: Signal<boolean>;
@@ -2188,12 +2188,12 @@ declare function sensor(type: 'reducedMotion' | 'reduced-motion', options?: Sens
2188
2188
  /**
2189
2189
  * Creates a sensor signal that tracks the provided media query.
2190
2190
  * @param type Must be `'mediaQuery'`.
2191
- * @param options Optional configuration for the media query sensor, including `query` and `debugName`.
2191
+ * @param options Required configuration for the media query sensor `query` is mandatory, `debugName` optional.
2192
2192
  * @returns A `Signal<boolean>` which is `true` if the media query currently matches.
2193
2193
  * @see {mediaQuery} for detailed documentation and examples.
2194
2194
  * @example const isDesktop = sensor('mediaQuery', { query: '(min-width: 1024px)' });
2195
2195
  */
2196
- declare function sensor(type: 'mediaQuery', options?: SensorTypedOptions['mediaQuery']['opt']): Signal<boolean>;
2196
+ declare function sensor(type: 'mediaQuery', options: SensorTypedOptions['mediaQuery']['opt']): Signal<boolean>;
2197
2197
  /**
2198
2198
  * Creates a sensor signal that tracks the browser window's inner dimensions (width and height).
2199
2199
  * @param type Must be `'windowSize'`.
@@ -2226,7 +2226,7 @@ declare function sensor(type: 'clipboard', options?: SensorTypedOptions['clipboa
2226
2226
  * Creates a sensor signal tracking the screen orientation.
2227
2227
  * @see {orientation}
2228
2228
  */
2229
- declare function sensor(type: 'orientation', options?: SensorTypedOptions['orientation']['opt']): Signal<ScreenOrientation>;
2229
+ declare function sensor(type: 'orientation', options?: SensorTypedOptions['orientation']['opt']): Signal<ScreenOrientationState>;
2230
2230
  /**
2231
2231
  * Creates a sensor signal tracking the system battery status.
2232
2232
  * @see {batteryStatus}
@@ -2378,7 +2378,7 @@ type Opaque<T> = T & {
2378
2378
  readonly [OPAQUE]: true;
2379
2379
  };
2380
2380
  /** @internal Strips the opaque brand from the value a leaf signal carries. */
2381
- type UnwrapOpqaue<T> = T extends {
2381
+ type UnwrapOpaque<T> = T extends {
2382
2382
  readonly [OPAQUE]: true;
2383
2383
  } ? Omit<T, typeof OPAQUE> : T;
2384
2384
  type BaseType = string | number | boolean | symbol | bigint | undefined | null | Function | Date | RegExp | {
@@ -2450,15 +2450,15 @@ type MutableSignalStoreObject<T> = Simplify<Readonly<{
2450
2450
  <L extends AnyRecord>(props: L): MutableSignalStore<Simplify<Omit<NonNullable<T>, keyof L> & L>>;
2451
2451
  };
2452
2452
  }>;
2453
- type SignalStore<T> = Signal<UnwrapOpqaue<T>> & (IsAny<T> extends true ? SignalStoreObject<T> : NonNullable<T> extends BaseType ? {
2453
+ type SignalStore<T> = Signal<UnwrapOpaque<T>> & (IsAny<T> extends true ? SignalStoreObject<T> : NonNullable<T> extends BaseType ? {
2454
2454
  readonly [LEAF]: () => boolean;
2455
2455
  } : NonNullable<T> extends any[] ? SignalArrayStore<NonNullable<T>> : SignalStoreObject<T>);
2456
- type WritableSignalStore<T> = WritableSignal<UnwrapOpqaue<T>> & {
2456
+ type WritableSignalStore<T> = WritableSignal<UnwrapOpaque<T>> & {
2457
2457
  readonly asReadonlyStore: () => SignalStore<T>;
2458
2458
  } & (IsAny<T> extends true ? WritableSignalStoreObject<T> : NonNullable<T> extends BaseType ? {
2459
2459
  readonly [LEAF]: () => boolean;
2460
2460
  } : NonNullable<T> extends any[] ? WritableArrayStore<NonNullable<T>> : WritableSignalStoreObject<T>);
2461
- type MutableSignalStore<T> = MutableSignal<UnwrapOpqaue<T>> & {
2461
+ type MutableSignalStore<T> = MutableSignal<UnwrapOpaque<T>> & {
2462
2462
  readonly asReadonlyStore: () => SignalStore<T>;
2463
2463
  } & (IsAny<T> extends true ? MutableSignalStoreObject<T> : NonNullable<T> extends BaseType ? {
2464
2464
  readonly [LEAF]: () => boolean;
@@ -2692,8 +2692,8 @@ type StoredSignal<T> = WritableSignal<T> & {
2692
2692
  *
2693
2693
  * @template T The type of value held by the signal and stored (after serialization).
2694
2694
  * @param fallback The default value of type `T` to use when no value is found in storage
2695
- * or when deserialization fails. The signal's value will never be `null` or `undefined`
2696
- * publicly, it will always revert to this fallback.
2695
+ * or when deserialization fails. A stored value (including a legitimate `null` for a
2696
+ * nullable `T`) always round-trips; the fallback only surfaces when the entry is absent.
2697
2697
  * @param options Configuration options (`CreateStoredOptions<T>`). Requires at least the `key`.
2698
2698
  * @returns A `StoredSignal<T>` instance. This signal behaves like a standard `WritableSignal<T>`,
2699
2699
  * but its value is persisted. It includes a `.clear()` method to remove the item from storage
@@ -2706,7 +2706,8 @@ type StoredSignal<T> = WritableSignal<T> & {
2706
2706
  * - **Error Handling:** Catches and logs errors during serialization/deserialization in dev mode.
2707
2707
  * - **Tab Sync:** If `syncTabs` is true, listens to `storage` events to keep the signal value
2708
2708
  * consistent across browser tabs using the same key. Cleanup is handled automatically
2709
- * using `DestroyRef`.
2709
+ * using `DestroyRef`. Web Storage only: the `storage` event never fires for custom `store`
2710
+ * adapters, so `syncTabs` has no effect with one.
2710
2711
  * - **Removal:** Use the `.clear()` method on the returned signal to remove the item from storage.
2711
2712
  * Setting the signal to the fallback value will store the fallback value, not remove the item.
2712
2713
  *
@@ -2741,7 +2742,7 @@ type SyncSignalOptions = {
2741
2742
  id: string;
2742
2743
  };
2743
2744
  /**
2744
- * @example tabSync(signal('dark), {id: 'theme})
2745
+ * @example tabSync(signal('dark'), { id: 'theme' })
2745
2746
  */
2746
2747
  declare function tabSync<T extends WritableSignal<any>>(sig: T, opt: SyncSignalOptions | string): T;
2747
2748
  /**
@@ -2778,6 +2779,8 @@ type CreateThrottledOptions<T> = CreateSignalOptions<T> & {
2778
2779
  /**
2779
2780
  * If `true`, the throttled signal emits the latest pending value at the end
2780
2781
  * of each cooldown window (only when at least one write occurred during it).
2782
+ * Note: with both `leading` and `trailing` set to `false` the throttled view
2783
+ * never updates (writes still reach `.original`).
2781
2784
  * @default true
2782
2785
  */
2783
2786
  trailing?: boolean;
@@ -2868,6 +2871,10 @@ declare function toWritable<T>(source: Signal<T>, set: (value: T) => void, updat
2868
2871
  /**
2869
2872
  * If `true` (the default), the returned signal will be a computed signal that depends on the source signal.
2870
2873
  * If `false`, the returned signal will be a direct wrapper around the source signal without creating a new computed signal.
2874
+ *
2875
+ * CAUTION: with `pure: false` the `set`/`update`/`asReadonly` methods are patched directly
2876
+ * onto the signal object you passed in — every other holder of that signal sees it become
2877
+ * writable. Only use it with a signal you created and own exclusively.
2871
2878
  * @default true
2872
2879
  */
2873
2880
  pure?: boolean;
@@ -3024,4 +3031,4 @@ type CreateHistoryOptions<T> = Omit<CreateSignalOptions<T[]>, 'equal'> & {
3024
3031
  declare function withHistory<T>(sourceOrValue: WritableSignal<T> | T, opt?: CreateHistoryOptions<T>): SignalWithHistory<T>;
3025
3032
 
3026
3033
  export { MmActivity, SuspenseBoundary, SuspenseBoundaryBase, UnscopedSuspenseBoundary, activeTransaction, batteryStatus, chunked, clipboard, combineWith, createTransaction, createTransitionScope, debounce, debounced, derived, distinct, elementSize, elementVisibility, filter, filterWith, focusWithin, forkStore, geolocation, holdUntilReady, idle, indexArray, injectPaused, injectRegisterResource, injectStartTransaction, injectStartTransition, injectTransitionScope, isDerivation, isLeaf, isMutable, isOpaque, isStore, keepPrevious, keyArray, map, mapArray, mapObject, mediaQuery, merge3, mousePosition, mutable, mutableStore, nestedEffect, networkStatus, opaque, orientation, pageVisibility, pairwise, pausableComputed, pausableEffect, pausableSignal, pipeable, piped, pooled, pooledArray, pooledMap, pooledSet, prefersDarkMode, prefersReducedMotion, providePaused, provideTransitionScope, registerResource, resolvePause, scan, scrollPosition, select, sensor, sensors, signalFromEvent, startWith, store, stored, tabSync, tap, throttle, throttled, toFakeDerivation, toFakeSignalDerivation, toStore, toWritable, until, windowSize, withHistory };
3027
- export type { BatteryStatus, ClipboardSignal, Computation, CreateChunkedOptions, CreateDebouncedOptions, CreateHistoryOptions, CreatePooledOptions, CreateProvidedPooledOptions, CreateStoredOptions, CreateThrottledOptions, DebouncedSignal, DerivedSignal, ElementSize, ElementSizeOptions, ElementSizeSignal, ElementVisibilityOptions, ElementVisibilitySignal, Fork, ForkStrategy, GeolocationOptions, GeolocationSignal, IdleOptions, IdleSignal, MousePositionOptions, MousePositionSignal, MutableSignal, MutableSignalStore, NetworkStatusSignal, Opaque, PausableOptions, PauseOption, PipeableSignal, ReconcileFn, RegisterOptions, ScreenOrientation, ScrollPosition, ScrollPositionOptions, ScrollPositionSignal, SignalFromEventOptions, SignalStore, SignalWithHistory, StoredSignal, SuspendType, ThrottledSignal, Transaction, TransactionRef, TransitionRef, TransitionScope, UntilOptions, Vivify, WindowSize, WindowSizeOptions, WindowSizeSignal, WithVivify, WritableSignalStore };
3034
+ export type { BatteryStatus, ClipboardSignal, Computation, CreateChunkedOptions, CreateDebouncedOptions, CreateHistoryOptions, CreatePooledOptions, CreateProvidedPooledOptions, CreateStoredOptions, CreateThrottledOptions, DebouncedSignal, DerivedSignal, ElementSize, ElementSizeOptions, ElementSizeSignal, ElementVisibilityOptions, ElementVisibilitySignal, Fork, ForkStrategy, Frame, GeolocationOptions, GeolocationSignal, IdleOptions, IdleSignal, MousePositionOptions, MousePositionSignal, MutableSignal, MutableSignalStore, NetworkStatusSignal, Opaque, PausableOptions, PauseOption, PipeableSignal, ReconcileFn, RegisterOptions, ScreenOrientation, ScreenOrientationState, ScrollPosition, ScrollPositionOptions, ScrollPositionSignal, SensorRunOptions, SignalFromEventOptions, SignalStore, SignalWithHistory, StoredSignal, SuspendType, ThrottledSignal, Transaction, TransactionRef, TransitionRef, TransitionScope, UntilOptions, Vivify, WindowSize, WindowSizeOptions, WindowSizeSignal, WithVivify, WritableSignalStore };