@solidjs/signals 2.0.0-beta.25 → 2.0.0-beta.26

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.
@@ -122,6 +122,14 @@ function isRawValue(e) {
122
122
 
123
123
  function markRawOne(e) {
124
124
  if (isWrappable(e)) {
125
+ // A store proxy is already tracked elsewhere: the shallow boundary passes
126
+ // it through by reference (replaced, never edited — same slot semantics
127
+ // as a raw) instead of claiming it raw. The sticky mark is global, so
128
+ // marking a live proxy would make wrap() serve it verbatim through every
129
+ // OTHER store too — downstream deep stores then captured it instead of
130
+ // wrapping it in their own family, and their writes landed in the
131
+ // upstream store's override layer (#2932).
132
+ if (e[$TARGET] !== undefined) return;
125
133
  rawValuesUsed = true;
126
134
  rawValues.add(e);
127
135
  }
@@ -255,7 +263,7 @@ function ownEnumerableKeysPlain(e) {
255
263
  * The value a store leaf's backing signal currently shows to readers: active
256
264
  * override, else held pending value, else committed value.
257
265
  */ function visibleNodeValue(e) {
258
- return e.Ee !== undefined && e.Ee !== NOT_PENDING ? unwrapOverride(e.Ee) : e.Ne !== NOT_PENDING ? e.Ne : e.Pe;
266
+ return e.Ae !== undefined && e.Ae !== NOT_PENDING ? unwrapOverride(e.Ae) : e._e !== NOT_PENDING ? e._e : e.Ue;
259
267
  }
260
268
 
261
269
  function hasOwnStoreProperty(e, t) {
@@ -306,11 +314,11 @@ function getNode(e, t, r, n, o = isEqual, i) {
306
314
  }
307
315
  }, e[STORE_FIREWALL]);
308
316
  if (e[STORE_OPTIMISTIC]) {
309
- O.Ee = NOT_PENDING;
317
+ O.Ae = NOT_PENDING;
310
318
  }
311
319
  if (i && r in i) {
312
320
  const e = i[r];
313
- O.Ve = e === undefined ? NO_SNAPSHOT : e;
321
+ O.xe = e === undefined ? NO_SNAPSHOT : e;
314
322
  snapshotSources?.add(O);
315
323
  }
316
324
  if (typeof r === "symbol" && r !== $TRACK && r !== $AFFECTS) symbolKeyedRecords.add(t);
@@ -428,11 +436,11 @@ o) {
428
436
  // Callers guard on `pendingCheckActive`, which only flips inside
429
437
  // isPending() — the verdict layer is loaded and its hook installed.
430
438
  const r = e[STORE_NODE]?.[$AFFECTS];
431
- if (r?.t) GlobalQueue.Lt(r);
439
+ if (r?.t) GlobalQueue.Dt(r);
432
440
  if (affectsScopes.size) {
433
441
  const n = e[STORE_VALUE];
434
442
  for (const [e, o] of affectsScopes) {
435
- if (e !== r && e.t && o.scope.has(n) && (o.key === undefined || o.key === t)) GlobalQueue.Lt(e);
443
+ if (e !== r && e.t && o.scope.has(n) && (o.key === undefined || o.key === t)) GlobalQueue.Dt(e);
436
444
  }
437
445
  }
438
446
  }
@@ -574,8 +582,8 @@ function getPropertyDescriptor(e, t, r) {
574
582
  function prepareStoreWrite(e, t, r) {
575
583
  if (e[STORE_OPTIMISTIC]) {
576
584
  const t = e[STORE_FIREWALL];
577
- if (t?.Ue) {
578
- globalQueue.initTransition(t.Ue);
585
+ if (t?.Ie) {
586
+ globalQueue.initTransition(t.Ie);
579
587
  }
580
588
  }
581
589
  const n = e[STORE_VALUE];
@@ -756,20 +764,27 @@ const storeTraps = {
756
764
  Writing?.add(n);
757
765
  return n;
758
766
  }
759
- let c = i ? E || !S ? read(o[t]) : (read(o[t]), f[t]) : f[t];
760
- c === $DELETED && (c = undefined);
767
+ let R = i ? E || !S ? read(o[t]) : (read(o[t]), f[t]) : f[t];
768
+ R === $DELETED && (R = undefined);
761
769
  if (!i) {
762
- if (!E && typeof c === "function" && !Object.prototype.hasOwnProperty.call(f, t)) {
770
+ if (!E && typeof R === "function" && !Object.prototype.hasOwnProperty.call(f, t)) {
763
771
  let t;
764
- return !Array.isArray(e[STORE_VALUE]) && (t = Object.getPrototypeOf(e[STORE_VALUE])) && t !== Object.prototype ? c.bind(f) : c;
772
+ return !Array.isArray(e[STORE_VALUE]) && (t = Object.getPrototypeOf(e[STORE_VALUE])) && t !== Object.prototype ? R.bind(f) : R;
765
773
  } else if (getObserver() && !n) {
766
- return read(getNode(e, o, t, isWrappable(c) ? wrap(c, e) : c, isEqual, e[STORE_SNAPSHOT_PROPS]));
774
+ return read(getNode(e, o, t, isWrappable(R) ? wrap(R, e) : R, isEqual, e[STORE_SNAPSHOT_PROPS]));
767
775
  }
768
776
  }
769
777
  // Untracked fall-through (tracked reads already threw via their node in
770
778
  // read(); the dev strictRead error above wins first for memo parity).
771
- if (!n) throwIfUninitialized(e);
772
- return isWrappable(c) ? wrap(c, e) : c;
779
+ // Observer-present reads must NOT re-consult the flag here: during the
780
+ // settle flush the firewall has recomputed (first values live on the
781
+ // pending rail, served by read() above) but its UNINITIALIZED clear is
782
+ // deferred to batch commit — vetoing read()'s verdict with the stale flag
783
+ // threw a fresh NotReadyError for an already-settled source, which no
784
+ // sweep would ever release (#2938: projection over an async store wedged
785
+ // its Loading boundary on `undefined`).
786
+ if (!n && !getObserver()) throwIfUninitialized(e);
787
+ return isWrappable(R) ? wrap(R, e) : R;
773
788
  },
774
789
  has(e, t) {
775
790
  if (t === $PROXY || t === $TRACK || t === "__proto__") return true;
@@ -800,37 +815,48 @@ const storeTraps = {
800
815
  const s = getOverlayLayer(e, t);
801
816
  const E = s ? s[t] : o;
802
817
  const S = s ? s[t] !== $DELETED : t in e[STORE_VALUE];
803
- const f = unwrapStoreValue(r);
804
- if (e[STORE_SHALLOW] && isWrappable(f)) rawValues.add(f);
818
+ // Shallow slots hold store proxies verbatim (pass-through reference,
819
+ // never raw-marked see markRawOne/#2932); everything else unwraps
820
+ // and marks as usual.
821
+ const f = !!e[STORE_SHALLOW] && r?.[$TARGET] !== undefined;
822
+ const R = f ? r : unwrapStoreValue(r);
823
+ if (e[STORE_SHALLOW] && !f && isWrappable(R)) {
824
+ // Flip the live gate too: a bare add was inert unless something else
825
+ // had already marked a raw somewhere (wrap() checks rawValuesUsed
826
+ // first), so the documented set-trap ingest mark silently no-oped in
827
+ // apps whose only shallow data arrived through writes.
828
+ rawValuesUsed = true;
829
+ rawValues.add(R);
830
+ }
805
831
  // Symbol-keyed writes on arrays are metadata, not index writes — never run
806
832
  // them through the numeric index/length machinery (`parseInt` on a symbol
807
833
  // throws). #2769
808
834
  const c = typeof t === "string" ? Number(t) : -1;
809
- const R = Array.isArray(O) && Number.isInteger(c) && c >= 0 && c < 4294967295 && String(c) === t;
810
- const T = R ? c + 1 : 0;
811
- const u = R && (getOverlayLayer(e, "length") ?? O).length;
812
- const a = R && T > u ? T : undefined;
813
- if (E === f && a === undefined) return true;
835
+ const T = Array.isArray(O) && Number.isInteger(c) && c >= 0 && c < 4294967295 && String(c) === t;
836
+ const u = T ? c + 1 : 0;
837
+ const a = T && (getOverlayLayer(e, "length") ?? O).length;
838
+ const l = T && u > a ? u : undefined;
839
+ if (E === R && l === undefined) return true;
814
840
  armOptimisticStoreWrite(e, n);
815
- if (f !== undefined && f === o && a === undefined) {
841
+ if (R !== undefined && R === o && l === undefined) {
816
842
  delete e[i]?.[t];
817
843
  if (i === STORE_OPTIMISTIC_OVERRIDE) delete e[STORE_OPTIMISTIC_OWNERS]?.[t];
818
844
  } else {
819
845
  const r = e[i] || (e[i] = Object.create(null));
820
- r[t] = f;
846
+ r[t] = R;
821
847
  stampOptimisticOwner(e, i, t);
822
- if (a !== undefined) {
823
- r.length = a;
848
+ if (l !== undefined) {
849
+ r.length = l;
824
850
  stampOptimisticOwner(e, i, "length");
825
851
  }
826
852
  }
827
- notifyStoreProperty(e, t, "set", f, E, S);
853
+ notifyStoreProperty(e, t, "set", R, E, S);
828
854
  // Shrinking an array's length must remove the truncated indices, otherwise
829
855
  // they leak through `has`, `ownKeys`, and (tracked) index reads from the
830
856
  // underlying value. Mark each as deleted and notify so reactive reads update. #2768
831
- if (Array.isArray(O) && t === "length" && typeof f === "number" && typeof E === "number" && f < E) {
857
+ if (Array.isArray(O) && t === "length" && typeof R === "number" && typeof E === "number" && R < E) {
832
858
  const t = e[i] || (e[i] = Object.create(null));
833
- for (let r = f; r < E; r++) {
859
+ for (let r = R; r < E; r++) {
834
860
  if (t[r] === $DELETED) continue;
835
861
  const n = r in t ? t[r] : O[r];
836
862
  if (!(r in t) && !(r in O)) continue;
@@ -840,13 +866,13 @@ const storeTraps = {
840
866
  }
841
867
  }
842
868
  // notify length change
843
- if (Array.isArray(O) && t !== "length" && a !== undefined) {
869
+ if (Array.isArray(O) && t !== "length" && l !== undefined) {
844
870
  const t = getNodes(e, STORE_NODE);
845
871
  if (t.length) {
846
- setSignal(t.length, a);
872
+ setSignal(t.length, l);
847
873
  } else if (!projectionWriteActive && !e[STORE_OPTIMISTIC]) {
848
- const r = upsertStoreNode(e, t, "length", u, e[STORE_SNAPSHOT_PROPS]);
849
- setSignal(r, a);
874
+ const r = upsertStoreNode(e, t, "length", a, e[STORE_SNAPSHOT_PROPS]);
875
+ setSignal(r, l);
850
876
  }
851
877
  }
852
878
  if (false) ;
@@ -3,6 +3,7 @@ import type { Computed, Link } from "./types.js";
3
3
  export declare function addPendingSource(el: Computed<any>, source: Computed<any>): boolean;
4
4
  export declare function setPendingError(el: Computed<any>, source?: Computed<any>, error?: any): void;
5
5
  export declare function forEachDependent(el: Computed<any>, fn: (node: Computed<any>, link: Link) => void): void;
6
+ export declare function releaseSettledDependents(el: Computed<any>): void;
6
7
  export declare function settlePendingSource(el: Computed<any>): void;
7
8
  export declare function isThenable<T>(value: T | PromiseLike<T>): value is PromiseLike<T>;
8
9
  export declare function handleAsync<T>(el: Computed<T>, result: T | PromiseLike<T> | AsyncIterable<T>, setter?: (value: T) => void): T;
@@ -3,6 +3,7 @@ import type { Computed, Link } from "./types.cjs";
3
3
  export declare function addPendingSource(el: Computed<any>, source: Computed<any>): boolean;
4
4
  export declare function setPendingError(el: Computed<any>, source?: Computed<any>, error?: any): void;
5
5
  export declare function forEachDependent(el: Computed<any>, fn: (node: Computed<any>, link: Link) => void): void;
6
+ export declare function releaseSettledDependents(el: Computed<any>): void;
6
7
  export declare function settlePendingSource(el: Computed<any>): void;
7
8
  export declare function isThenable<T>(value: T | PromiseLike<T>): value is PromiseLike<T>;
8
9
  export declare function handleAsync<T>(el: Computed<T>, result: T | PromiseLike<T> | AsyncIterable<T>, setter?: (value: T) => void): T;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@solidjs/signals",
3
- "version": "2.0.0-beta.25",
3
+ "version": "2.0.0-beta.26",
4
4
  "description": "Solid's reactive primitives: signals, memos, effects, stores, and async-aware computations.",
5
5
  "author": "Ryan Carniato",
6
6
  "license": "MIT",