@mmstack/primitives 21.0.28 → 21.0.29
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.
|
@@ -2440,6 +2440,82 @@ function isOpaque(value) {
|
|
|
2440
2440
|
value !== null &&
|
|
2441
2441
|
value[OPAQUE] === true);
|
|
2442
2442
|
}
|
|
2443
|
+
/**
|
|
2444
|
+
* @internal Runtime brand carrying a store node's lazily-built leaf probe. Exported (like
|
|
2445
|
+
* {@link OPAQUE}) only so the `{ readonly [LEAF]: () => boolean }` brand on the store types is
|
|
2446
|
+
* nameable in the emitted declarations — not part of the supported surface; use {@link isLeaf}.
|
|
2447
|
+
*/
|
|
2448
|
+
const LEAF = Symbol('@mmstack/primitives::store/LEAF');
|
|
2449
|
+
/**
|
|
2450
|
+
* @internal Whether a value is a terminal leaf: a concrete non-record/non-array value always is;
|
|
2451
|
+
* `null`/`undefined` is a leaf only when vivification is disabled (with vivify on it can still
|
|
2452
|
+
* materialize a container, so it stays a descendable substore).
|
|
2453
|
+
*/
|
|
2454
|
+
function isLeafValue(value, vivifyEnabled) {
|
|
2455
|
+
if (value == null)
|
|
2456
|
+
return !vivifyEnabled;
|
|
2457
|
+
if (isOpaque(value))
|
|
2458
|
+
return true; // opaque always wins — even arrays
|
|
2459
|
+
return !Array.isArray(value) && !isRecord(value);
|
|
2460
|
+
}
|
|
2461
|
+
/**
|
|
2462
|
+
* @internal Constant leaf probes for nodes whose leaf-ness is statically known, so the reactive
|
|
2463
|
+
* `computed` can be skipped entirely.
|
|
2464
|
+
*/
|
|
2465
|
+
function alwaysTrue() {
|
|
2466
|
+
return true;
|
|
2467
|
+
}
|
|
2468
|
+
function alwaysFalse() {
|
|
2469
|
+
return false;
|
|
2470
|
+
}
|
|
2471
|
+
/**
|
|
2472
|
+
* @internal Attaches a lazy, memoized leaf probe to a store node. The probe (`() => boolean`)
|
|
2473
|
+
* closes over the node's value signal and its (stable) vivify setting, building the backing
|
|
2474
|
+
* `computed` on first call so leaf-ness tracks the live value reactively without taxing every
|
|
2475
|
+
* node access. Idempotent.
|
|
2476
|
+
*/
|
|
2477
|
+
function markAsLeaf(sig, value, vivifyEnabled, noUnionLeaves) {
|
|
2478
|
+
if (typeof sig[LEAF] !== 'function') {
|
|
2479
|
+
let memo;
|
|
2480
|
+
const probe = () => {
|
|
2481
|
+
if (memo)
|
|
2482
|
+
return memo();
|
|
2483
|
+
const v = untracked(value);
|
|
2484
|
+
memo =
|
|
2485
|
+
isOpaque(v) || (v == null && !vivifyEnabled) || noUnionLeaves
|
|
2486
|
+
? isLeafValue(v, vivifyEnabled)
|
|
2487
|
+
? alwaysTrue
|
|
2488
|
+
: alwaysFalse
|
|
2489
|
+
: computed(() => isLeafValue(value(), vivifyEnabled));
|
|
2490
|
+
return memo();
|
|
2491
|
+
};
|
|
2492
|
+
Object.defineProperty(sig, LEAF, {
|
|
2493
|
+
value: probe,
|
|
2494
|
+
enumerable: false,
|
|
2495
|
+
configurable: true,
|
|
2496
|
+
});
|
|
2497
|
+
}
|
|
2498
|
+
return sig;
|
|
2499
|
+
}
|
|
2500
|
+
/**
|
|
2501
|
+
* Reports whether a store node is currently a **leaf** — a terminal value the store does not
|
|
2502
|
+
* descend into (a primitive, `Date`, `RegExp`, {@link opaque} object, class instance, or a
|
|
2503
|
+
* `null`/`undefined` hole when vivification is off) rather than a record/array substore.
|
|
2504
|
+
*
|
|
2505
|
+
* Leaf-ness reflects the node's **live** value: the probe is reactive and memoized, so calling
|
|
2506
|
+
* `isLeaf` inside a `computed`/`effect` re-evaluates when the node's shape changes.
|
|
2507
|
+
*
|
|
2508
|
+
* @internal Exposed for advanced/niche interop only — not part of the supported public surface
|
|
2509
|
+
* and may change without a major version bump.
|
|
2510
|
+
*
|
|
2511
|
+
* @example
|
|
2512
|
+
* const s = store({ name: 'Ada', address: { city: 'London' } });
|
|
2513
|
+
* isLeaf(s.name); // true
|
|
2514
|
+
* isLeaf(s.address); // false — a substore
|
|
2515
|
+
*/
|
|
2516
|
+
function isLeaf(value) {
|
|
2517
|
+
return isStore(value) && value[LEAF]?.() === true;
|
|
2518
|
+
}
|
|
2443
2519
|
const IS_STORE = Symbol('@mmstack/primitives::store/IS_STORE');
|
|
2444
2520
|
const SCOPE_PARENT = Symbol('@mmstack/primitives::store/SCOPE_PARENT');
|
|
2445
2521
|
/**
|
|
@@ -2502,7 +2578,7 @@ function hasOwnKey(value, key) {
|
|
|
2502
2578
|
* @internal
|
|
2503
2579
|
* Makes an array store
|
|
2504
2580
|
*/
|
|
2505
|
-
function toArrayStore(source, injector, vivify) {
|
|
2581
|
+
function toArrayStore(source, injector, vivify, noUnionLeaves = false) {
|
|
2506
2582
|
if (isStore(source))
|
|
2507
2583
|
return source;
|
|
2508
2584
|
const isMutableSource = isMutable(source);
|
|
@@ -2612,9 +2688,10 @@ function toArrayStore(source, injector, vivify) {
|
|
|
2612
2688
|
});
|
|
2613
2689
|
const childSample = untracked(computation);
|
|
2614
2690
|
const childVivify = resolveVivify(childSample, vivify);
|
|
2615
|
-
const proxy = Array.isArray(childSample)
|
|
2616
|
-
? toArrayStore(computation, injector, childVivify)
|
|
2617
|
-
: toStore(computation, injector, childVivify);
|
|
2691
|
+
const proxy = Array.isArray(childSample) && !isOpaque(childSample)
|
|
2692
|
+
? toArrayStore(computation, injector, childVivify, noUnionLeaves)
|
|
2693
|
+
: toStore(computation, injector, childVivify, noUnionLeaves);
|
|
2694
|
+
markAsLeaf(proxy, computation, childVivify !== false, noUnionLeaves);
|
|
2618
2695
|
const ref = new WeakRef(proxy);
|
|
2619
2696
|
storeCache.set(idx, ref);
|
|
2620
2697
|
PROXY_CLEANUP.register(proxy, { target, prop: idx }, ref);
|
|
@@ -2631,7 +2708,7 @@ function toArrayStore(source, injector, vivify) {
|
|
|
2631
2708
|
* const state = store({ user: { name: 'John' } });
|
|
2632
2709
|
* const nameSignal = state.user.name; // WritableSignal<string>
|
|
2633
2710
|
*/
|
|
2634
|
-
function toStore(source, injector, vivify = false) {
|
|
2711
|
+
function toStore(source, injector, vivify = false, noUnionLeaves = false) {
|
|
2635
2712
|
if (isStore(source))
|
|
2636
2713
|
return source;
|
|
2637
2714
|
if (!injector)
|
|
@@ -2672,7 +2749,7 @@ function toStore(source, injector, vivify = false) {
|
|
|
2672
2749
|
return () => {
|
|
2673
2750
|
if (!isWritableSource)
|
|
2674
2751
|
return s;
|
|
2675
|
-
return untracked(() => toStore(source.asReadonly(), injector, vivify));
|
|
2752
|
+
return untracked(() => toStore(source.asReadonly(), injector, vivify, noUnionLeaves));
|
|
2676
2753
|
};
|
|
2677
2754
|
if (prop === 'extend')
|
|
2678
2755
|
return (seed) => scopedStore(s, seed, isMutableSource
|
|
@@ -2725,9 +2802,10 @@ function toStore(source, injector, vivify = false) {
|
|
|
2725
2802
|
});
|
|
2726
2803
|
const childSample = untracked(computation);
|
|
2727
2804
|
const childVivify = resolveVivify(childSample, vivify);
|
|
2728
|
-
const proxy = Array.isArray(childSample)
|
|
2729
|
-
? toArrayStore(computation, injector, childVivify)
|
|
2730
|
-
: toStore(computation, injector, childVivify);
|
|
2805
|
+
const proxy = Array.isArray(childSample) && !isOpaque(childSample)
|
|
2806
|
+
? toArrayStore(computation, injector, childVivify, noUnionLeaves)
|
|
2807
|
+
: toStore(computation, injector, childVivify, noUnionLeaves);
|
|
2808
|
+
markAsLeaf(proxy, computation, childVivify !== false, noUnionLeaves);
|
|
2731
2809
|
const ref = new WeakRef(proxy);
|
|
2732
2810
|
storeCache.set(prop, ref);
|
|
2733
2811
|
PROXY_CLEANUP.register(proxy, { target, prop }, ref);
|
|
@@ -2820,14 +2898,14 @@ function scopedStore(parent, seed, kind, injector) {
|
|
|
2820
2898
|
* @see {@link toStore}
|
|
2821
2899
|
*/
|
|
2822
2900
|
function store(value, opt) {
|
|
2823
|
-
return toStore(signal(value, opt), opt?.injector, opt?.vivify ?? false);
|
|
2901
|
+
return toStore(signal(value, opt), opt?.injector, opt?.vivify ?? false, opt?.noUnionLeaves ?? false);
|
|
2824
2902
|
}
|
|
2825
2903
|
/**
|
|
2826
2904
|
* Creates a MutableSignalStore from a value.
|
|
2827
2905
|
* @see {@link toStore}
|
|
2828
2906
|
*/
|
|
2829
2907
|
function mutableStore(value, opt) {
|
|
2830
|
-
return toStore(mutable(value, opt), opt?.injector, opt?.vivify ?? false);
|
|
2908
|
+
return toStore(mutable(value, opt), opt?.injector, opt?.vivify ?? false, opt?.noUnionLeaves ?? false);
|
|
2831
2909
|
}
|
|
2832
2910
|
|
|
2833
2911
|
// Internal dummy store for server-side rendering
|
|
@@ -3304,5 +3382,5 @@ function withHistory(sourceOrValue, opt) {
|
|
|
3304
3382
|
* Generated bundle index. Do not edit.
|
|
3305
3383
|
*/
|
|
3306
3384
|
|
|
3307
|
-
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 };
|
|
3385
|
+
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 };
|
|
3308
3386
|
//# sourceMappingURL=mmstack-primitives.mjs.map
|