@mmstack/primitives 22.9.2 → 22.9.4
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
CHANGED
|
@@ -766,7 +766,8 @@ const profile = persistedStore({ first: '', last: '' }, {
|
|
|
766
766
|
`persistedStore` is `store()` + `persist()`. Reach for `persist(store, opt)` directly to add durability to a store you already have — one you also `meshSync`, or a worker-owned store's replica. Persistence is a reader over the op-log, so it composes with the other readers on the same store.
|
|
767
767
|
|
|
768
768
|
```typescript
|
|
769
|
-
import { store, persist
|
|
769
|
+
import { store, persist } from '@mmstack/primitives';
|
|
770
|
+
import { meshSync } from '@mmstack/mesh';
|
|
770
771
|
|
|
771
772
|
const doc = store({ title: '', body: '' });
|
|
772
773
|
persist(doc, { key: 'draft', store: idbKeyval }); // durable to IndexedDB
|
|
@@ -1740,8 +1740,7 @@ function createImmutableObjectUpdater(source, key, vivifyFn) {
|
|
|
1740
1740
|
return { ...vivified, [key]: next };
|
|
1741
1741
|
});
|
|
1742
1742
|
}
|
|
1743
|
-
function
|
|
1744
|
-
const sample = untracked(source);
|
|
1743
|
+
function createUpdaterFromSample(source, key, vivify, sample) {
|
|
1745
1744
|
// fast path for when vivification is off
|
|
1746
1745
|
if (!vivify) {
|
|
1747
1746
|
if (Array.isArray(sample) && typeof key === 'number') {
|
|
@@ -1789,6 +1788,19 @@ function createUpdater(source, key, vivify) {
|
|
|
1789
1788
|
? createMutableObjectUpdater(source, key, vivifyFn)
|
|
1790
1789
|
: createImmutableObjectUpdater(source, key, vivifyFn);
|
|
1791
1790
|
}
|
|
1791
|
+
/**
|
|
1792
|
+
* Selects the property updater once, on the first actual write. Construction must not sample the
|
|
1793
|
+
* source: a writable derivation may currently throw, and reads still need a child producer that can
|
|
1794
|
+
* subscribe and recover. The routing sample remains deliberately untracked, so deferring it adds no
|
|
1795
|
+
* dependency to the caller.
|
|
1796
|
+
*/
|
|
1797
|
+
function createUpdater(source, key, vivify) {
|
|
1798
|
+
let update;
|
|
1799
|
+
return (next) => {
|
|
1800
|
+
update ??= createUpdaterFromSample(source, key, vivify, untracked(source));
|
|
1801
|
+
update(next);
|
|
1802
|
+
};
|
|
1803
|
+
}
|
|
1792
1804
|
function derived(source, optOrKey, opt) {
|
|
1793
1805
|
const vivify = typeof optOrKey === 'object' ? false : (opt?.vivify ?? false);
|
|
1794
1806
|
// With vivification the source may legitimately be null/undefined
|
|
@@ -4218,14 +4230,19 @@ function alwaysFalse() {
|
|
|
4218
4230
|
function markAsLeaf(sig, value, vivifyEnabled, noUnionLeaves) {
|
|
4219
4231
|
if (typeof sig[LEAF] !== 'function') {
|
|
4220
4232
|
let memo;
|
|
4233
|
+
let initialClassification;
|
|
4221
4234
|
const probe = () => {
|
|
4222
4235
|
if (memo)
|
|
4223
4236
|
return memo();
|
|
4224
|
-
|
|
4225
|
-
|
|
4226
|
-
|
|
4227
|
-
|
|
4228
|
-
|
|
4237
|
+
if (noUnionLeaves) {
|
|
4238
|
+
initialClassification ??= computed(() => isLeafValue(value(), vivifyEnabled));
|
|
4239
|
+
const result = initialClassification();
|
|
4240
|
+
memo = result ? alwaysTrue : alwaysFalse;
|
|
4241
|
+
initialClassification = undefined;
|
|
4242
|
+
}
|
|
4243
|
+
else {
|
|
4244
|
+
memo = computed(() => isLeafValue(value(), vivifyEnabled));
|
|
4245
|
+
}
|
|
4229
4246
|
return memo();
|
|
4230
4247
|
};
|
|
4231
4248
|
Object.defineProperty(sig, LEAF, {
|
|
@@ -4573,21 +4590,19 @@ function mutableChildEqual(a, b) {
|
|
|
4573
4590
|
* correct after it. The only place a child node is constructed — shared by every container kind.
|
|
4574
4591
|
*/
|
|
4575
4592
|
function buildChildNode(target, prop, isMutableSource, options) {
|
|
4576
|
-
|
|
4577
|
-
const
|
|
4578
|
-
const
|
|
4579
|
-
const equalFn = isMutableSource && (isRecord$1(value) || Array.isArray(value))
|
|
4580
|
-
? mutableChildEqual
|
|
4581
|
-
: undefined;
|
|
4593
|
+
let vivifyFn = options.vivify === false ? createVivify(false) : undefined;
|
|
4594
|
+
const resolveVivifyFn = (sample) => (vivifyFn ??= createVivify(resolveVivify(sample, options.vivify)));
|
|
4595
|
+
const lazyVivify = (value, key) => resolveVivifyFn(value)(value, key);
|
|
4582
4596
|
const computation = derived(target, {
|
|
4583
|
-
from: (v) =>
|
|
4584
|
-
|
|
4585
|
-
|
|
4597
|
+
from: (v) => {
|
|
4598
|
+
resolveVivifyFn(v);
|
|
4599
|
+
return v?.[prop];
|
|
4600
|
+
},
|
|
4601
|
+
onChange: createFallbackOnChange(target, prop, lazyVivify, isMutableSource),
|
|
4602
|
+
equal: isMutableSource ? mutableChildEqual : undefined,
|
|
4586
4603
|
});
|
|
4587
|
-
const childSample = untracked(computation);
|
|
4588
|
-
const childVivify = resolveVivify(childSample, options.vivify);
|
|
4589
4604
|
const proxy = toStore(computation, options);
|
|
4590
|
-
markAsLeaf(proxy, computation,
|
|
4605
|
+
markAsLeaf(proxy, computation, options.vivify !== false, options.noUnionLeaves);
|
|
4591
4606
|
return proxy;
|
|
4592
4607
|
}
|
|
4593
4608
|
/**
|
|
@@ -4726,7 +4741,16 @@ function toStore(source, { injector, vivify = false, noUnionLeaves = false, ...r
|
|
|
4726
4741
|
if ((typeof prop === 'symbol' && prop !== Symbol.iterator) ||
|
|
4727
4742
|
(typeof prop === 'string' && SIGNAL_FN_PROP.has(prop)))
|
|
4728
4743
|
return target[prop];
|
|
4729
|
-
const
|
|
4744
|
+
const child = (key) => getCachedChild(target, prop, () => buildChildNode(target, key, isMutableSource, STORE_OPTIONS), STORE_OPTIONS[STORE_SHARED_GLOBALS].cache, STORE_OPTIONS[STORE_SHARED_GLOBALS].registry);
|
|
4745
|
+
let k;
|
|
4746
|
+
try {
|
|
4747
|
+
k = untracked(kind);
|
|
4748
|
+
}
|
|
4749
|
+
catch (cause) {
|
|
4750
|
+
if (typeof prop === 'string' && prop !== 'extend')
|
|
4751
|
+
return child(isIndexProp(prop) ? +prop : prop);
|
|
4752
|
+
throw cause;
|
|
4753
|
+
}
|
|
4730
4754
|
if (prop === 'extend' && k !== 'array')
|
|
4731
4755
|
return (seed) => scopedStore(s, seed, isMutableSource
|
|
4732
4756
|
? 'mutable'
|
|
@@ -4745,7 +4769,7 @@ function toStore(source, { injector, vivify = false, noUnionLeaves = false, ...r
|
|
|
4745
4769
|
}
|
|
4746
4770
|
if (k === 'array' && !isIndexProp(prop))
|
|
4747
4771
|
return Reflect.get(target, prop, receiver);
|
|
4748
|
-
return
|
|
4772
|
+
return child(k === 'array' ? +prop : prop);
|
|
4749
4773
|
},
|
|
4750
4774
|
});
|
|
4751
4775
|
return s;
|