@mmstack/primitives 22.9.1 → 22.9.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.
@@ -1740,8 +1740,7 @@ function createImmutableObjectUpdater(source, key, vivifyFn) {
1740
1740
  return { ...vivified, [key]: next };
1741
1741
  });
1742
1742
  }
1743
- function createUpdater(source, key, vivify) {
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
- memo = noUnionLeaves
4225
- ? isLeafValue(untracked(value), vivifyEnabled)
4226
- ? alwaysTrue
4227
- : alwaysFalse
4228
- : computed(() => isLeafValue(value(), vivifyEnabled));
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
- const value = untracked(target);
4577
- const nodeVivify = resolveVivify(value, options.vivify);
4578
- const vivifyFn = createVivify(nodeVivify);
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) => v?.[prop],
4584
- onChange: createFallbackOnChange(target, prop, vivifyFn, isMutableSource),
4585
- equal: equalFn,
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, childVivify !== false, options.noUnionLeaves);
4605
+ markAsLeaf(proxy, computation, options.vivify !== false, options.noUnionLeaves);
4591
4606
  return proxy;
4592
4607
  }
4593
4608
  /**
@@ -4723,7 +4738,19 @@ function toStore(source, { injector, vivify = false, noUnionLeaves = false, ...r
4723
4738
  [STORE_SHARED_GLOBALS]: STORE_OPTIONS[STORE_SHARED_GLOBALS],
4724
4739
  }));
4725
4740
  };
4726
- const k = untracked(kind);
4741
+ if ((typeof prop === 'symbol' && prop !== Symbol.iterator) ||
4742
+ (typeof prop === 'string' && SIGNAL_FN_PROP.has(prop)))
4743
+ return target[prop];
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
+ }
4727
4754
  if (prop === 'extend' && k !== 'array')
4728
4755
  return (seed) => scopedStore(s, seed, isMutableSource
4729
4756
  ? 'mutable'
@@ -4740,11 +4767,9 @@ function toStore(source, { injector, vivify = false, noUnionLeaves = false, ...r
4740
4767
  yield receiver[i];
4741
4768
  };
4742
4769
  }
4743
- if (typeof prop === 'symbol' || SIGNAL_FN_PROP.has(prop))
4744
- return target[prop];
4745
4770
  if (k === 'array' && !isIndexProp(prop))
4746
4771
  return Reflect.get(target, prop, receiver);
4747
- return getCachedChild(target, prop, () => buildChildNode(target, k === 'array' ? +prop : prop, isMutableSource, STORE_OPTIONS), STORE_OPTIONS[STORE_SHARED_GLOBALS].cache, STORE_OPTIONS[STORE_SHARED_GLOBALS].registry);
4772
+ return child(k === 'array' ? +prop : prop);
4748
4773
  },
4749
4774
  });
4750
4775
  return s;