@mmstack/primitives 22.0.2 → 22.0.3
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.
|
@@ -2459,6 +2459,82 @@ function isOpaque(value) {
|
|
|
2459
2459
|
value !== null &&
|
|
2460
2460
|
value[OPAQUE] === true);
|
|
2461
2461
|
}
|
|
2462
|
+
/**
|
|
2463
|
+
* @internal Runtime brand carrying a store node's lazily-built leaf probe. Exported (like
|
|
2464
|
+
* {@link OPAQUE}) only so the `{ readonly [LEAF]: () => boolean }` brand on the store types is
|
|
2465
|
+
* nameable in the emitted declarations — not part of the supported surface; use {@link isLeaf}.
|
|
2466
|
+
*/
|
|
2467
|
+
const LEAF = Symbol('@mmstack/primitives::store/LEAF');
|
|
2468
|
+
/**
|
|
2469
|
+
* @internal Whether a value is a terminal leaf: a concrete non-record/non-array value always is;
|
|
2470
|
+
* `null`/`undefined` is a leaf only when vivification is disabled (with vivify on it can still
|
|
2471
|
+
* materialize a container, so it stays a descendable substore).
|
|
2472
|
+
*/
|
|
2473
|
+
function isLeafValue(value, vivifyEnabled) {
|
|
2474
|
+
if (value == null)
|
|
2475
|
+
return !vivifyEnabled;
|
|
2476
|
+
if (isOpaque(value))
|
|
2477
|
+
return true; // opaque always wins — even arrays
|
|
2478
|
+
return !Array.isArray(value) && !isRecord(value);
|
|
2479
|
+
}
|
|
2480
|
+
/**
|
|
2481
|
+
* @internal Constant leaf probes for nodes whose leaf-ness is statically known, so the reactive
|
|
2482
|
+
* `computed` can be skipped entirely.
|
|
2483
|
+
*/
|
|
2484
|
+
function alwaysTrue() {
|
|
2485
|
+
return true;
|
|
2486
|
+
}
|
|
2487
|
+
function alwaysFalse() {
|
|
2488
|
+
return false;
|
|
2489
|
+
}
|
|
2490
|
+
/**
|
|
2491
|
+
* @internal Attaches a lazy, memoized leaf probe to a store node. The probe (`() => boolean`)
|
|
2492
|
+
* closes over the node's value signal and its (stable) vivify setting, building the backing
|
|
2493
|
+
* `computed` on first call so leaf-ness tracks the live value reactively without taxing every
|
|
2494
|
+
* node access. Idempotent.
|
|
2495
|
+
*/
|
|
2496
|
+
function markAsLeaf(sig, value, vivifyEnabled, noUnionLeaves) {
|
|
2497
|
+
if (typeof sig[LEAF] !== 'function') {
|
|
2498
|
+
let memo;
|
|
2499
|
+
const probe = () => {
|
|
2500
|
+
if (memo)
|
|
2501
|
+
return memo();
|
|
2502
|
+
const v = untracked(value);
|
|
2503
|
+
memo =
|
|
2504
|
+
isOpaque(v) || (v == null && !vivifyEnabled) || noUnionLeaves
|
|
2505
|
+
? isLeafValue(v, vivifyEnabled)
|
|
2506
|
+
? alwaysTrue
|
|
2507
|
+
: alwaysFalse
|
|
2508
|
+
: computed(() => isLeafValue(value(), vivifyEnabled));
|
|
2509
|
+
return memo();
|
|
2510
|
+
};
|
|
2511
|
+
Object.defineProperty(sig, LEAF, {
|
|
2512
|
+
value: probe,
|
|
2513
|
+
enumerable: false,
|
|
2514
|
+
configurable: true,
|
|
2515
|
+
});
|
|
2516
|
+
}
|
|
2517
|
+
return sig;
|
|
2518
|
+
}
|
|
2519
|
+
/**
|
|
2520
|
+
* Reports whether a store node is currently a **leaf** — a terminal value the store does not
|
|
2521
|
+
* descend into (a primitive, `Date`, `RegExp`, {@link opaque} object, class instance, or a
|
|
2522
|
+
* `null`/`undefined` hole when vivification is off) rather than a record/array substore.
|
|
2523
|
+
*
|
|
2524
|
+
* Leaf-ness reflects the node's **live** value: the probe is reactive and memoized, so calling
|
|
2525
|
+
* `isLeaf` inside a `computed`/`effect` re-evaluates when the node's shape changes.
|
|
2526
|
+
*
|
|
2527
|
+
* @internal Exposed for advanced/niche interop only — not part of the supported public surface
|
|
2528
|
+
* and may change without a major version bump.
|
|
2529
|
+
*
|
|
2530
|
+
* @example
|
|
2531
|
+
* const s = store({ name: 'Ada', address: { city: 'London' } });
|
|
2532
|
+
* isLeaf(s.name); // true
|
|
2533
|
+
* isLeaf(s.address); // false — a substore
|
|
2534
|
+
*/
|
|
2535
|
+
function isLeaf(value) {
|
|
2536
|
+
return isStore(value) && value[LEAF]?.() === true;
|
|
2537
|
+
}
|
|
2462
2538
|
const IS_STORE = Symbol('@mmstack/primitives::store/IS_STORE');
|
|
2463
2539
|
const SCOPE_PARENT = Symbol('@mmstack/primitives::store/SCOPE_PARENT');
|
|
2464
2540
|
/**
|
|
@@ -2521,7 +2597,7 @@ function hasOwnKey(value, key) {
|
|
|
2521
2597
|
* @internal
|
|
2522
2598
|
* Makes an array store
|
|
2523
2599
|
*/
|
|
2524
|
-
function toArrayStore(source, injector, vivify) {
|
|
2600
|
+
function toArrayStore(source, injector, vivify, noUnionLeaves = false) {
|
|
2525
2601
|
if (isStore(source))
|
|
2526
2602
|
return source;
|
|
2527
2603
|
const isMutableSource = isMutable(source);
|
|
@@ -2632,9 +2708,10 @@ function toArrayStore(source, injector, vivify) {
|
|
|
2632
2708
|
});
|
|
2633
2709
|
const childSample = untracked(computation);
|
|
2634
2710
|
const childVivify = resolveVivify(childSample, vivify);
|
|
2635
|
-
const proxy = Array.isArray(childSample)
|
|
2636
|
-
? toArrayStore(computation, injector, childVivify)
|
|
2637
|
-
: toStore(computation, injector, childVivify);
|
|
2711
|
+
const proxy = Array.isArray(childSample) && !isOpaque(childSample)
|
|
2712
|
+
? toArrayStore(computation, injector, childVivify, noUnionLeaves)
|
|
2713
|
+
: toStore(computation, injector, childVivify, noUnionLeaves);
|
|
2714
|
+
markAsLeaf(proxy, computation, childVivify !== false, noUnionLeaves);
|
|
2638
2715
|
const ref = new WeakRef(proxy);
|
|
2639
2716
|
storeCache.set(idx, ref);
|
|
2640
2717
|
PROXY_CLEANUP.register(proxy, { target, prop: idx }, ref);
|
|
@@ -2651,7 +2728,7 @@ function toArrayStore(source, injector, vivify) {
|
|
|
2651
2728
|
* const state = store({ user: { name: 'John' } });
|
|
2652
2729
|
* const nameSignal = state.user.name; // WritableSignal<string>
|
|
2653
2730
|
*/
|
|
2654
|
-
function toStore(source, injector, vivify = false) {
|
|
2731
|
+
function toStore(source, injector, vivify = false, noUnionLeaves = false) {
|
|
2655
2732
|
if (isStore(source))
|
|
2656
2733
|
return source;
|
|
2657
2734
|
if (!injector)
|
|
@@ -2692,7 +2769,7 @@ function toStore(source, injector, vivify = false) {
|
|
|
2692
2769
|
return () => {
|
|
2693
2770
|
if (!isWritableSource)
|
|
2694
2771
|
return s;
|
|
2695
|
-
return untracked(() => toStore(source.asReadonly(), injector, vivify));
|
|
2772
|
+
return untracked(() => toStore(source.asReadonly(), injector, vivify, noUnionLeaves));
|
|
2696
2773
|
};
|
|
2697
2774
|
if (prop === 'extend')
|
|
2698
2775
|
return (seed) => scopedStore(s, seed, isMutableSource
|
|
@@ -2745,9 +2822,10 @@ function toStore(source, injector, vivify = false) {
|
|
|
2745
2822
|
});
|
|
2746
2823
|
const childSample = untracked(computation);
|
|
2747
2824
|
const childVivify = resolveVivify(childSample, vivify);
|
|
2748
|
-
const proxy = Array.isArray(childSample)
|
|
2749
|
-
? toArrayStore(computation, injector, childVivify)
|
|
2750
|
-
: toStore(computation, injector, childVivify);
|
|
2825
|
+
const proxy = Array.isArray(childSample) && !isOpaque(childSample)
|
|
2826
|
+
? toArrayStore(computation, injector, childVivify, noUnionLeaves)
|
|
2827
|
+
: toStore(computation, injector, childVivify, noUnionLeaves);
|
|
2828
|
+
markAsLeaf(proxy, computation, childVivify !== false, noUnionLeaves);
|
|
2751
2829
|
const ref = new WeakRef(proxy);
|
|
2752
2830
|
storeCache.set(prop, ref);
|
|
2753
2831
|
PROXY_CLEANUP.register(proxy, { target, prop }, ref);
|
|
@@ -2841,14 +2919,14 @@ function scopedStore(parent, seed, kind, injector) {
|
|
|
2841
2919
|
* @see {@link toStore}
|
|
2842
2920
|
*/
|
|
2843
2921
|
function store(value, opt) {
|
|
2844
|
-
return toStore(signal(value, opt), opt?.injector, opt?.vivify ?? false);
|
|
2922
|
+
return toStore(signal(value, opt), opt?.injector, opt?.vivify ?? false, opt?.noUnionLeaves ?? false);
|
|
2845
2923
|
}
|
|
2846
2924
|
/**
|
|
2847
2925
|
* Creates a MutableSignalStore from a value.
|
|
2848
2926
|
* @see {@link toStore}
|
|
2849
2927
|
*/
|
|
2850
2928
|
function mutableStore(value, opt) {
|
|
2851
|
-
return toStore(mutable(value, opt), opt?.injector, opt?.vivify ?? false);
|
|
2929
|
+
return toStore(mutable(value, opt), opt?.injector, opt?.vivify ?? false, opt?.noUnionLeaves ?? false);
|
|
2852
2930
|
}
|
|
2853
2931
|
|
|
2854
2932
|
// Internal dummy store for server-side rendering
|
|
@@ -3329,5 +3407,5 @@ function withHistory(sourceOrValue, opt) {
|
|
|
3329
3407
|
* Generated bundle index. Do not edit.
|
|
3330
3408
|
*/
|
|
3331
3409
|
|
|
3332
|
-
export { batteryStatus, chunked, clipboard, combineWith, debounce, debounced, derived, distinct, elementSize, elementVisibility, filter, filterWith, focusWithin, geolocation, idle, indexArray, isDerivation, isMutable, isOpaque, isStore, keyArray, map, mapArray, mapObject, mediaQuery, mousePosition, mutable, mutableStore, nestedEffect, networkStatus, opaque, 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 };
|
|
3410
|
+
export { batteryStatus, chunked, clipboard, combineWith, debounce, debounced, derived, distinct, elementSize, elementVisibility, filter, filterWith, focusWithin, geolocation, idle, indexArray, isDerivation, isLeaf, isMutable, isOpaque, isStore, keyArray, map, mapArray, mapObject, mediaQuery, mousePosition, mutable, mutableStore, nestedEffect, networkStatus, opaque, 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 };
|
|
3333
3411
|
//# sourceMappingURL=mmstack-primitives.mjs.map
|