@solidjs/signals 2.0.0-rc.18 → 2.0.0-rc.19
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/dist/dev-shared.js +168 -88
- package/dist/dev.attribution.js +16 -13
- package/dist/dev.js +272 -129
- package/dist/observe/boundaries.js +88 -67
- package/dist/observe/core/action.js +8 -0
- package/dist/observe/core/async.js +46 -34
- package/dist/observe/core/attribution.js +30 -28
- package/dist/observe/core/constants.js +21 -1
- package/dist/observe/core/core.js +164 -136
- package/dist/observe/core/effect.js +6 -6
- package/dist/observe/core/graph.js +3 -3
- package/dist/observe/core/heap.js +5 -5
- package/dist/observe/core/lanes.js +104 -84
- package/dist/observe/core/owner.js +10 -9
- package/dist/observe/core/scheduler.js +38 -35
- package/dist/observe/core/truth.js +6 -6
- package/dist/observe/core/verdict.js +13 -13
- package/dist/observe/deferred.js +39 -40
- package/dist/observe/index.js +2 -2
- package/dist/observe/map.js +22 -22
- package/dist/observe/reveal.js +5 -5
- package/dist/observe/signals.js +57 -15
- package/dist/observe/store/affects.js +1 -1
- package/dist/observe/store/hooks.js +3 -0
- package/dist/observe/store/optimistic.js +11 -11
- package/dist/observe/store/projection.js +34 -21
- package/dist/observe/store/reconcile.js +2 -2
- package/dist/observe/store/store.js +63 -53
- package/dist/observe/store/utils.js +7 -2
- package/dist/prod/boundaries.js +153 -132
- package/dist/prod/core/action.js +8 -0
- package/dist/prod/core/async.js +55 -43
- package/dist/prod/core/constants.js +14 -1
- package/dist/prod/core/core.js +162 -134
- package/dist/prod/core/effect.js +9 -9
- package/dist/prod/core/graph.js +3 -3
- package/dist/prod/core/heap.js +12 -12
- package/dist/prod/core/lanes.js +98 -78
- package/dist/prod/core/owner.js +15 -14
- package/dist/prod/core/scheduler.js +43 -40
- package/dist/prod/core/truth.js +6 -6
- package/dist/prod/core/verdict.js +17 -17
- package/dist/prod/deferred.js +39 -40
- package/dist/prod/index.js +2 -2
- package/dist/prod/map.js +14 -14
- package/dist/prod/reveal.js +8 -8
- package/dist/prod/signals.js +46 -4
- package/dist/prod/store/affects.js +1 -1
- package/dist/prod/store/hooks.js +3 -0
- package/dist/prod/store/optimistic.js +16 -16
- package/dist/prod/store/projection.js +22 -9
- package/dist/prod/store/reconcile.js +2 -2
- package/dist/prod/store/store.js +262 -262
- package/dist/prod/store/utils.js +2 -0
- package/dist/types/core/action.d.ts +8 -0
- package/dist/types/core/constants.d.ts +20 -0
- package/dist/types/core/core.d.ts +14 -1
- package/dist/types/core/dev.d.ts +1 -1
- package/dist/types/core/index.d.ts +1 -1
- package/dist/types/core/lanes.d.ts +5 -1
- package/dist/types/core/scheduler.d.ts +2 -0
- package/dist/types/index.d.ts +3 -1
- package/dist/types/signals.d.ts +37 -0
- package/dist/types/store/target.d.ts +2 -0
- package/package.json +1 -1
|
@@ -251,7 +251,7 @@ function releaseSlot(e) {
|
|
|
251
251
|
// holds: its release waits for the commit that resolves it. So does a leaf of
|
|
252
252
|
// a held container (#4146): a mainline write it carried is in the held
|
|
253
253
|
// staging too, where it would read as the hold's until the landing.
|
|
254
|
-
const slotKept = e => e.
|
|
254
|
+
const slotKept = e => e.ie !== NOT_PENDING || e.l & CONFIG_OVERRIDE || e.O.k?.l & CONFIG_HELD;
|
|
255
255
|
|
|
256
256
|
setSlotUnobserved(e => {
|
|
257
257
|
if (slotKept(e)) deferredReleases.add(e); else releaseSlot(e);
|
|
@@ -262,9 +262,9 @@ setSlotUnobserved(e => {
|
|
|
262
262
|
* pending one — and held by the container's transaction when the container
|
|
263
263
|
* is held (#3706: the unit of the hold is the key — a key the batch left
|
|
264
264
|
* unchanged stages nothing and holds no one). */ function bornStaged(e, t, n, r) {
|
|
265
|
-
if (t.
|
|
265
|
+
if (t.je && t.je(t.le, n)) return;
|
|
266
266
|
queuePendingNode(t);
|
|
267
|
-
t.
|
|
267
|
+
t.ie = n;
|
|
268
268
|
const o = e.k;
|
|
269
269
|
if (o === null) return;
|
|
270
270
|
// a node-less staging holds nothing (`stageOn`)
|
|
@@ -343,8 +343,8 @@ function getHasNode(e, t) {
|
|
|
343
343
|
// pending backing staged — so whoever asked for it reads the frame it
|
|
344
344
|
// would have read had the node been there from the write.
|
|
345
345
|
if (e.pb !== null && !directCommit) {
|
|
346
|
-
t.
|
|
347
|
-
t.
|
|
346
|
+
t.le = preBatch(e);
|
|
347
|
+
t.ie = e.pb;
|
|
348
348
|
queuePendingNode(t);
|
|
349
349
|
}
|
|
350
350
|
}
|
|
@@ -363,8 +363,8 @@ function getHasNode(e, t) {
|
|
|
363
363
|
* (`storeParkHook`) — the one case the staging home exists for. */ function stageOn(e, t) {
|
|
364
364
|
if (e.k === null && passLane === null && (context === null || globalQueue.q) && !deriveHolds(e)) return;
|
|
365
365
|
const n = getContainerNode(e);
|
|
366
|
-
if (n.
|
|
367
|
-
n.
|
|
366
|
+
if (n.ie === NOT_PENDING) queuePendingNode(n);
|
|
367
|
+
n.ie = t;
|
|
368
368
|
// A28 (4): a write issued inside a pass outside a flush (a creation-time
|
|
369
369
|
// derive) is promoted at the pass's end — the batch with it.
|
|
370
370
|
if (context !== null) notePromotedWrite(n);
|
|
@@ -408,7 +408,7 @@ function bumpDeep(e) {
|
|
|
408
408
|
// the node; the comparator is the store's, done).
|
|
409
409
|
if (e.l & CONFIG_OVERRIDE) setSignal(e, t); else {
|
|
410
410
|
if (e.l & CONFIG_HELD) joinFuture(txOf(e));
|
|
411
|
-
if (snapshotCaptureActive) captureWriteSnapshot(e, e.
|
|
411
|
+
if (snapshotCaptureActive) captureWriteSnapshot(e, e.le);
|
|
412
412
|
insertSubs(e);
|
|
413
413
|
schedule();
|
|
414
414
|
}
|
|
@@ -543,7 +543,7 @@ const plainProto = e => {
|
|
|
543
543
|
const n = overlayOnto(e, e.sc === 2 ? wideClone(e.v, e) : cloneRaw(e.v, e), t);
|
|
544
544
|
e.pb = n;
|
|
545
545
|
// The staging IS the pending backing: re-point the container node.
|
|
546
|
-
if (e.k?.
|
|
546
|
+
if (e.k?.ie === t) e.k.ie = n;
|
|
547
547
|
return n;
|
|
548
548
|
}
|
|
549
549
|
|
|
@@ -555,7 +555,7 @@ const plainProto = e => {
|
|
|
555
555
|
// An optimistic edit composes on the view the user saw and becomes
|
|
556
556
|
// guesses at the setter's exit: nothing is staged, nothing folds
|
|
557
557
|
// (optimistic.ts).
|
|
558
|
-
if (userWrite && e.fam?.opt === true && !pendingNotify.has(e)) return e.pb = optHooks.draft(e);
|
|
558
|
+
if (optHooks && userWrite && e.fam?.opt === true && !pendingNotify.has(e)) return e.pb = optHooks.draft(e);
|
|
559
559
|
if (t !== null && !isOwned(t)) {
|
|
560
560
|
// An adopted object awaiting its fold is the user's: the draft writes a
|
|
561
561
|
// clone of it. The clone is the batch's staging — unless the adoption is
|
|
@@ -564,7 +564,7 @@ const plainProto = e => {
|
|
|
564
564
|
// mainline setter mid-hold publishes mainline; the held keys stay held).
|
|
565
565
|
t = e.pb = cloneRaw(t, e);
|
|
566
566
|
const n = e.k;
|
|
567
|
-
if (n !== null && !(n.l & CONFIG_HELD)) n.
|
|
567
|
+
if (n !== null && !(n.l & CONFIG_HELD)) n.ie = t;
|
|
568
568
|
} else if (t === null) {
|
|
569
569
|
const n = e.v;
|
|
570
570
|
if (!directCommit) queueFold(e);
|
|
@@ -645,7 +645,7 @@ const plainProto = e => {
|
|
|
645
645
|
} else r = e.v;
|
|
646
646
|
if (directCommit) {
|
|
647
647
|
e.pb = null;
|
|
648
|
-
if (e.k !== null) e.k.
|
|
648
|
+
if (e.k !== null) e.k.le = t;
|
|
649
649
|
} else {
|
|
650
650
|
// Eager (INTERNALS §3): the backing swaps now — handlers read the
|
|
651
651
|
// adopted object before the flush — while the container node, when
|
|
@@ -741,7 +741,7 @@ let foldIndex = null;
|
|
|
741
741
|
if (r.pb === null) continue;
|
|
742
742
|
// folded already (a direct commit)
|
|
743
743
|
const o = r.k;
|
|
744
|
-
if (o !== null && o.
|
|
744
|
+
if (o !== null && o.ie !== NOT_PENDING) {
|
|
745
745
|
// held: commits with its hold
|
|
746
746
|
foldList.push(r);
|
|
747
747
|
foldOlds.push(t[n]);
|
|
@@ -776,9 +776,9 @@ let foldIndex = null;
|
|
|
776
776
|
if (t.ch) {
|
|
777
777
|
const n = e.Vt;
|
|
778
778
|
const r = t.v;
|
|
779
|
-
if (t.h?.[n] === e) e.
|
|
779
|
+
if (t.h?.[n] === e) e.le = untrack(() => n in r); else if (t.n?.[n] === e) e.le = untrack(() => unwrapValue(r[n]));
|
|
780
780
|
}
|
|
781
|
-
return e.
|
|
781
|
+
return e.le;
|
|
782
782
|
};
|
|
783
783
|
|
|
784
784
|
installStoreHooks(storePark, () => {
|
|
@@ -812,7 +812,7 @@ function runDirect(e) {
|
|
|
812
812
|
const n = e.k;
|
|
813
813
|
const r = e.pb;
|
|
814
814
|
if (r !== null) {
|
|
815
|
-
if (r === e.v) ; else if (e.ovl && (e.v !== t || !overlayRebuilds(e, r) && n?.T?.
|
|
815
|
+
if (r === e.v) ; else if (e.ovl && (e.v !== t || !overlayRebuilds(e, r) && n?.T?.st !== t)) {
|
|
816
816
|
// Overlay flatten (#3044): the backing keeps its identity, so the
|
|
817
817
|
// `t.v === old` gate below skips path copying (the parent slot
|
|
818
818
|
// already points here) and the adopted-notify (setter
|
|
@@ -830,9 +830,9 @@ function runDirect(e) {
|
|
|
830
830
|
if (hasOwn.call(r, t)) copyOwn(n, r, t); else delete n[t];
|
|
831
831
|
}
|
|
832
832
|
} else {
|
|
833
|
-
for (const e of Reflect.ownKeys(r)) copyOwn(n, r, e);
|
|
833
|
+
for (const e of Reflect.ownKeys(r)) if (e !== $OWNER) copyOwn(n, r, e);
|
|
834
834
|
for (const e of Reflect.ownKeys(t)) {
|
|
835
|
-
if (!hasOwn.call(r, e)) delete n[e];
|
|
835
|
+
if (e !== $OWNER && !hasOwn.call(r, e)) delete n[e];
|
|
836
836
|
}
|
|
837
837
|
}
|
|
838
838
|
} else {
|
|
@@ -850,7 +850,7 @@ function runDirect(e) {
|
|
|
850
850
|
// subscribes to was a transient staging home (INTERNALS §5: an
|
|
851
851
|
// observer-less write holds a transient record until the fold,
|
|
852
852
|
// discarded with it) — gone with the batch.
|
|
853
|
-
if (n.o === null) e.k = null; else if (n.
|
|
853
|
+
if (n.o === null) e.k = null; else if (n.le instanceof LaneView) n.le.base = e.v; else n.le = e.v;
|
|
854
854
|
}
|
|
855
855
|
if (e.v !== t && e.u) {
|
|
856
856
|
const n = parentSlotKey(e, t);
|
|
@@ -883,29 +883,39 @@ function reportReplacedContainers(e, t, n, r) {
|
|
|
883
883
|
const o = r ?? Reflect.ownKeys(n);
|
|
884
884
|
const i = Array.isArray(n);
|
|
885
885
|
const l = storeRootOwner(e);
|
|
886
|
+
// Items the array held before the write: an index that now holds one of
|
|
887
|
+
// them was moved into place (an in-place splice / shift), not replaced.
|
|
888
|
+
let u = null;
|
|
886
889
|
for (const r of o) {
|
|
887
890
|
if (i && r === "length" || r === $OWNER) continue;
|
|
888
891
|
if (e.del?.has(r)) continue;
|
|
889
892
|
const o = unwrapValue(t[r]);
|
|
890
|
-
const
|
|
891
|
-
if (o === null ||
|
|
892
|
-
|
|
893
|
-
|
|
894
|
-
|
|
895
|
-
|
|
896
|
-
|
|
897
|
-
|
|
898
|
-
|
|
893
|
+
const f = unwrapValue(n[r]);
|
|
894
|
+
if (o === null || f === null || typeof o !== "object" || typeof f !== "object" || o === f || targetsEqual(o, f)) continue;
|
|
895
|
+
if (i) {
|
|
896
|
+
if (u === null) {
|
|
897
|
+
u = new Set;
|
|
898
|
+
for (const e of t) u.add(unwrapValue(e));
|
|
899
|
+
}
|
|
900
|
+
if (u.has(f)) continue;
|
|
901
|
+
}
|
|
902
|
+
const s = Array.isArray(f);
|
|
903
|
+
if (s !== Array.isArray(o)) continue;
|
|
904
|
+
let a;
|
|
905
|
+
let c = 0;
|
|
906
|
+
if (s) {
|
|
907
|
+
a = f.length;
|
|
908
|
+
if (a > REPLACED_CENSUS_MAX) continue;
|
|
899
909
|
const e = new Set;
|
|
900
910
|
for (const t of o) e.add(unwrapValue(t));
|
|
901
|
-
for (const t of
|
|
911
|
+
for (const t of f) if (e.has(unwrapValue(t))) c++;
|
|
902
912
|
} else {
|
|
903
|
-
const e = Object.keys(
|
|
904
|
-
|
|
905
|
-
if (
|
|
906
|
-
for (const t of e) if (sameLeaf(o[t],
|
|
913
|
+
const e = Object.keys(f);
|
|
914
|
+
a = e.length;
|
|
915
|
+
if (a > REPLACED_CENSUS_MAX) continue;
|
|
916
|
+
for (const t of e) if (sameLeaf(o[t], f[t])) c++;
|
|
907
917
|
}
|
|
908
|
-
attrHooks.storeReplaced(storePathOf(e) + "." + String(r),
|
|
918
|
+
attrHooks.storeReplaced(storePathOf(e) + "." + String(r), s, a, c, s ? o.length : Object.keys(o).length, l);
|
|
909
919
|
}
|
|
910
920
|
}
|
|
911
921
|
|
|
@@ -935,7 +945,7 @@ function heldDerivation(e, t, n) {
|
|
|
935
945
|
// Optimistic channel: a user's writes on an optimistic family become
|
|
936
946
|
// guesses on the nodes (lanes); the draft is discarded, the committed
|
|
937
947
|
// backing never touched.
|
|
938
|
-
if (userWrite && e.fam?.opt === true) {
|
|
948
|
+
if (optHooks && userWrite && e.fam?.opt === true) {
|
|
939
949
|
// The draft is discarded first: the diff reads the target (its nodes
|
|
940
950
|
// are born from the committed frame, not the draft).
|
|
941
951
|
e.pb = null;
|
|
@@ -1185,7 +1195,7 @@ function inDraft(e) {
|
|
|
1185
1195
|
* "adoption is eager by contract" — and the node keeps the frame committed
|
|
1186
1196
|
* readers under a hold still see), `t.v` otherwise. */ function committed(e) {
|
|
1187
1197
|
const t = e.k;
|
|
1188
|
-
if (t !== null) return t.
|
|
1198
|
+
if (t !== null) return t.ie !== NOT_PENDING ? asBacking(t.le) : e.v;
|
|
1189
1199
|
// A node-less staging (`stageOn`): the fold queue remembers the frame.
|
|
1190
1200
|
return e.pb !== null ? preBatch(e) : e.v;
|
|
1191
1201
|
}
|
|
@@ -1197,7 +1207,7 @@ function inDraft(e) {
|
|
|
1197
1207
|
* committed frame. */ function stagingReader() {
|
|
1198
1208
|
let e = context;
|
|
1199
1209
|
if (e === null) return null;
|
|
1200
|
-
if (e.Pt) e = e.
|
|
1210
|
+
if (e.Pt) e = e.ht ?? null;
|
|
1201
1211
|
return e === null || e.l & CONFIG_CHILDREN_FORBIDDEN ? null : e;
|
|
1202
1212
|
}
|
|
1203
1213
|
|
|
@@ -1271,7 +1281,7 @@ function inDraft(e) {
|
|
|
1271
1281
|
// probe) judges the container like any node — for a key the batch
|
|
1272
1282
|
// changed; an unchanged key is committed and final (A22: pending is per
|
|
1273
1283
|
// key). A held container's committed frame is the node's.
|
|
1274
|
-
if (verdict === null || !i && t !== undefined && !keyChanged(e, t, n)) return i ? asBacking(o.
|
|
1284
|
+
if (verdict === null || !i && t !== undefined && !keyChanged(e, t, n)) return i ? asBacking(o.le) : e.v;
|
|
1275
1285
|
return o === null ? committed(e) : asBacking(read(o));
|
|
1276
1286
|
}
|
|
1277
1287
|
// A pass reading a key the batch left unchanged: the same value in both
|
|
@@ -1304,7 +1314,7 @@ function inDraft(e) {
|
|
|
1304
1314
|
|
|
1305
1315
|
/** Did the HELD staging (the container node's, not a mainline layer above
|
|
1306
1316
|
* it) change `key`? */ function heldKeyChanged(e, t, n = true) {
|
|
1307
|
-
return changedBetween(e, e.k.
|
|
1317
|
+
return changedBetween(e, e.k.le, e.k.ie, t, n) && !adoptChild(e, t);
|
|
1308
1318
|
}
|
|
1309
1319
|
|
|
1310
1320
|
/** The values of a held frame, built once per frame: neither the committed
|
|
@@ -1331,14 +1341,14 @@ function rawsOf(e) {
|
|
|
1331
1341
|
* `version` holds. A record's keys pair by name; an array's by the family's
|
|
1332
1342
|
* key — without a family the pairing is not known here and the hold stands. */ function adoptChild(e, t) {
|
|
1333
1343
|
const n = e.k;
|
|
1334
|
-
const r = asBacking(n.
|
|
1344
|
+
const r = asBacking(n.le);
|
|
1335
1345
|
const o = r[t];
|
|
1336
|
-
const i = n.
|
|
1346
|
+
const i = n.ie[t];
|
|
1337
1347
|
const l = Array.isArray(r) ? e.fam?.key : null;
|
|
1338
1348
|
if (e.s || l === undefined || !sameRow(o, i, l) || !isWrappable(o) || !isWrappable(i) || Array.isArray(o) !== Array.isArray(i) || lookupTarget(o, e.fam) !== undefined || lookupTarget(i, e.fam) !== undefined ||
|
|
1339
1349
|
// A raw in both frames (the same objects swapped or reordered) is its
|
|
1340
1350
|
// own row: pairing it with another would alias the two after the commit.
|
|
1341
|
-
rawsOf(r).has(i) || rawsOf(n.
|
|
1351
|
+
rawsOf(r).has(i) || rawsOf(n.ie).has(o)) return false;
|
|
1342
1352
|
// A raw-marked value wraps to itself, a proxy to its own target: neither
|
|
1343
1353
|
// is a fresh target around `ov`.
|
|
1344
1354
|
const u = wrap(o, e, t)[$TARGET];
|
|
@@ -1383,7 +1393,7 @@ function changedBetween(e, t, n, r, o) {
|
|
|
1383
1393
|
* tracked or not, applies the hold and A28 rules a signal's read does. A
|
|
1384
1394
|
* projection's unheld staging is ahead for a handler (`familyAhead`). */ function nodeValue(e, t, n) {
|
|
1385
1395
|
let r = read(e);
|
|
1386
|
-
if (e.
|
|
1396
|
+
if (e.ie !== NOT_PENDING && !(e.l & CONFIG_HELD) && context === null && n.fam !== null) r = e.ie;
|
|
1387
1397
|
return r === FORCE ? t : r;
|
|
1388
1398
|
}
|
|
1389
1399
|
|
|
@@ -1403,7 +1413,7 @@ function changedBetween(e, t, n, r, o) {
|
|
|
1403
1413
|
if (l) {
|
|
1404
1414
|
// The link's committed value follows the inner store's (what a lane
|
|
1405
1415
|
// over it covers — its reveal and revert compare against it, S4).
|
|
1406
|
-
o.
|
|
1416
|
+
o.le = n;
|
|
1407
1417
|
if (o.l & CONFIG_OVERRIDE) u = t;
|
|
1408
1418
|
} else u = t;
|
|
1409
1419
|
}
|
|
@@ -1476,7 +1486,7 @@ function changedBetween(e, t, n, r, o) {
|
|
|
1476
1486
|
* classification, as core reads it — `heldNotFinal`). */ function holdWithDerive(e, t) {
|
|
1477
1487
|
const n = e.fam?.node;
|
|
1478
1488
|
if (n !== undefined && n !== null && !userWrite && // the derive's own write (its draft or landing), not a user setter's
|
|
1479
|
-
n.l & CONFIG_HELD && t.
|
|
1489
|
+
n.l & CONFIG_HELD && t.ie !== NOT_PENDING &&
|
|
1480
1490
|
// A node carrying a guess is the lane's: its staging is the truth beneath
|
|
1481
1491
|
// the guess (`setSignal` → `laneWrite`), never re-homed by the store.
|
|
1482
1492
|
!(t.l & (CONFIG_HELD | CONFIG_OVERRIDE))) {
|
|
@@ -1508,10 +1518,10 @@ function changedBetween(e, t, n, r, o) {
|
|
|
1508
1518
|
// A container's arrangement guess is not a backing: the view composes
|
|
1509
1519
|
// over the base it is shown over.
|
|
1510
1520
|
const t = asBacking(read(getContainerNode(e)));
|
|
1511
|
-
return e.fam?.opt === true ? optHooks.view(e, t) : t;
|
|
1521
|
+
return optHooks && e.fam?.opt === true ? optHooks.view(e, t) : t;
|
|
1512
1522
|
}
|
|
1513
1523
|
const t = readSource(e);
|
|
1514
|
-
return optRead(e) ? optHooks.view(e, t) : t;
|
|
1524
|
+
return optHooks && optRead(e) ? optHooks.view(e, t) : t;
|
|
1515
1525
|
}
|
|
1516
1526
|
|
|
1517
1527
|
/** A read on an optimistic family that composes the lanes' values: not the
|
|
@@ -1678,11 +1688,11 @@ const traps = {
|
|
|
1678
1688
|
const o = read(r);
|
|
1679
1689
|
if (!e.ch || n !== e.v) return !!o;
|
|
1680
1690
|
const i = t in n;
|
|
1681
|
-
r.
|
|
1691
|
+
r.le = i;
|
|
1682
1692
|
// the link follows the inner store (S4)
|
|
1683
1693
|
if (r.l & CONFIG_OVERRIDE) return !!o;
|
|
1684
1694
|
return i;
|
|
1685
|
-
} else if (optRead(e)) {
|
|
1695
|
+
} else if (optHooks && optRead(e)) {
|
|
1686
1696
|
const n = optHooks.has(e, t);
|
|
1687
1697
|
if (n !== undefined) return n;
|
|
1688
1698
|
}
|
|
@@ -1718,7 +1728,7 @@ const traps = {
|
|
|
1718
1728
|
if (!r && (!e.ch || n.l & CONFIG_OVERRIDE || !(t in i))) return undefined;
|
|
1719
1729
|
} else i = readSource(e, t, true);
|
|
1720
1730
|
let l;
|
|
1721
|
-
if (!o && optRead(e)) {
|
|
1731
|
+
if (optHooks && !o && optRead(e)) {
|
|
1722
1732
|
const n = optHooks.descriptor(e, t);
|
|
1723
1733
|
if (n === null) return undefined;
|
|
1724
1734
|
l = n;
|
|
@@ -1825,7 +1835,7 @@ const traps = {
|
|
|
1825
1835
|
const n = e.k;
|
|
1826
1836
|
if (n === null) return false;
|
|
1827
1837
|
const r = n.Ct;
|
|
1828
|
-
return r !== null && r.u === t && (!(t.R & REACTIVE_RECOMPUTING_DEPS) || r.
|
|
1838
|
+
return r !== null && r.u === t && (!(t.R & REACTIVE_RECOMPUTING_DEPS) || r.Ie === t.Ne);
|
|
1829
1839
|
}
|
|
1830
1840
|
|
|
1831
1841
|
function storeSetter(e, t, n = true) {
|
|
@@ -1863,7 +1873,7 @@ function storeSetter(e, t, n = true) {
|
|
|
1863
1873
|
// A returned replacement: on an optimistic family a user's is itself an
|
|
1864
1874
|
// optimistic edit — diffed against the view as guesses (`next` parity);
|
|
1865
1875
|
// otherwise it is adopted as the incoming truth.
|
|
1866
|
-
if (n && r.fam?.opt === true && !writeOverride) optHooks.writes(r, unwrapValue(l)); else adoptPB(r, unwrapValue(l));
|
|
1876
|
+
if (optHooks && n && r.fam?.opt === true && !writeOverride) optHooks.writes(r, unwrapValue(l)); else adoptPB(r, unwrapValue(l));
|
|
1867
1877
|
}
|
|
1868
1878
|
// A34 (3), #3612 — the derived store's twin of `setMemo`: a user write to
|
|
1869
1879
|
// a derivation another transaction holds is nobody's proposal; it becomes
|
|
@@ -2030,7 +2040,7 @@ function snapshotWalk(e, t, n) {
|
|
|
2030
2040
|
if (o.ovl) materializePB(o);
|
|
2031
2041
|
i = o.pb;
|
|
2032
2042
|
}
|
|
2033
|
-
if (optRead(o)) i = optHooks.view(o, i);
|
|
2043
|
+
if (optHooks && optRead(o)) i = optHooks.view(o, i);
|
|
2034
2044
|
if (i === r) break;
|
|
2035
2045
|
r = i;
|
|
2036
2046
|
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { SUPPORTS_PROXY } from "../core/constants.js";
|
|
1
|
+
import { SUPPORTS_PROXY, CONFIG_KEY_BAG } from "../core/constants.js";
|
|
2
2
|
|
|
3
3
|
import { createMemo } from "../signals.js";
|
|
4
4
|
|
|
@@ -921,7 +921,12 @@ const omitTraps = {
|
|
|
921
921
|
f++;
|
|
922
922
|
i = o;
|
|
923
923
|
if (typeof o === "function") {
|
|
924
|
-
|
|
924
|
+
// Observe tiers name it and exempt it from UNSTABLE_MEMO_OUTPUT (see
|
|
925
|
+
// CONFIG_KEY_BAG); prod passes no options.
|
|
926
|
+
n[r] = createMemo(o, {
|
|
927
|
+
name: "merge",
|
|
928
|
+
St: CONFIG_KEY_BAG
|
|
929
|
+
});
|
|
925
930
|
t[r++] = SOURCE_MEMO;
|
|
926
931
|
continue;
|
|
927
932
|
}
|