@solidjs/signals 2.0.0-rc.2 → 2.0.0-rc.20
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 +6505 -0
- package/dist/dev.attribution.js +3484 -0
- package/dist/dev.js +10227 -9508
- package/dist/observe/affects-marks.js +86 -0
- package/dist/observe/affects.js +112 -0
- package/dist/observe/attribution.js +7 -0
- package/dist/observe/boundaries.js +696 -0
- package/dist/observe/core/action.js +182 -0
- package/dist/observe/core/async.js +824 -0
- package/dist/observe/core/attribution-costs.js +66 -0
- package/dist/observe/core/attribution-feedback.js +280 -0
- package/dist/observe/core/attribution-hooks.js +83 -0
- package/dist/observe/core/attribution-queries.js +43 -0
- package/dist/observe/core/attribution.js +3079 -0
- package/dist/observe/core/constants.js +269 -0
- package/dist/observe/core/context.js +63 -0
- package/dist/observe/core/copies.js +10 -0
- package/dist/observe/core/core.js +1707 -0
- package/dist/observe/core/dev.js +394 -0
- package/dist/observe/core/effect.js +193 -0
- package/dist/observe/core/error-hooks.js +71 -0
- package/dist/observe/core/error.js +82 -0
- package/dist/observe/core/external.js +97 -0
- package/dist/observe/core/graph.js +162 -0
- package/dist/observe/core/heap.js +124 -0
- package/dist/observe/core/identities.js +62 -0
- package/dist/observe/core/invariants.js +12 -0
- package/dist/observe/core/lanes.js +972 -0
- package/dist/observe/core/owner.js +371 -0
- package/dist/observe/core/scheduler.js +1157 -0
- package/dist/observe/core/truth.js +47 -0
- package/dist/observe/core/verdict.js +470 -0
- package/dist/observe/deferred.js +186 -0
- package/dist/observe/flatten.js +79 -0
- package/dist/observe/from.js +248 -0
- package/dist/observe/index.js +71 -0
- package/dist/observe/map.js +593 -0
- package/dist/observe/reveal.js +212 -0
- package/dist/observe/signals.js +717 -0
- package/dist/observe/store/affects.js +142 -0
- package/dist/observe/store/edges.js +39 -0
- package/dist/observe/store/hooks.js +16 -0
- package/dist/observe/store/index.js +47 -0
- package/dist/observe/store/optimistic.js +713 -0
- package/dist/observe/store/projection.js +345 -0
- package/dist/observe/store/reconcile.js +281 -0
- package/dist/observe/store/store.js +2127 -0
- package/dist/observe/store/storePath.js +103 -0
- package/dist/observe/store/target.js +46 -0
- package/dist/observe/store/types.js +83 -0
- package/dist/observe/store/utils.js +1063 -0
- package/dist/prod/affects-marks.js +86 -0
- package/dist/prod/affects.js +98 -112
- package/dist/prod/attribution.js +45 -0
- package/dist/prod/boundaries.js +578 -468
- package/dist/prod/core/action.js +92 -59
- package/dist/prod/core/async.js +522 -336
- package/dist/prod/core/attribution-hooks.js +3 -0
- package/dist/prod/core/constants.js +168 -44
- package/dist/prod/core/context.js +12 -16
- package/dist/prod/core/copies.js +10 -0
- package/dist/prod/core/core.js +1345 -627
- package/dist/prod/core/dev.js +123 -1
- package/dist/prod/core/effect.js +113 -80
- package/dist/prod/core/error-hooks.js +71 -0
- package/dist/prod/core/error.js +18 -4
- package/dist/prod/core/external.js +6 -7
- package/dist/prod/core/graph.js +119 -72
- package/dist/prod/core/heap.js +85 -109
- package/dist/prod/core/identities.js +62 -0
- package/dist/prod/core/invariants.js +1 -32
- package/dist/prod/core/lanes.js +931 -132
- package/dist/prod/core/owner.js +192 -129
- package/dist/prod/core/scheduler.js +948 -642
- package/dist/prod/core/truth.js +47 -0
- package/dist/prod/core/verdict.js +409 -420
- package/dist/prod/deferred.js +184 -0
- package/dist/prod/flatten.js +77 -0
- package/dist/prod/from.js +248 -0
- package/dist/prod/index.js +40 -16
- package/dist/prod/map.js +481 -211
- package/dist/prod/reveal.js +212 -0
- package/dist/prod/signals.js +401 -84
- package/dist/prod/store/affects.js +142 -0
- package/dist/prod/store/edges.js +39 -0
- package/dist/prod/store/hooks.js +16 -0
- package/dist/prod/store/index.js +27 -18
- package/dist/prod/store/optimistic.js +707 -0
- package/dist/prod/store/projection.js +331 -0
- package/dist/prod/store/reconcile.js +281 -0
- package/dist/prod/store/store.js +1952 -267
- package/dist/prod/store/storePath.js +1 -1
- package/dist/prod/store/target.js +43 -0
- package/dist/prod/store/types.js +83 -0
- package/dist/prod/store/utils.js +997 -138
- package/dist/types/affects-marks.d.ts +14 -0
- package/dist/types/affects.d.ts +12 -30
- package/dist/types/attribution.d.ts +19 -0
- package/dist/types/attribution.prod.d.ts +22 -0
- package/dist/types/boundaries.d.ts +99 -124
- package/dist/types/carved.d.ts +1 -0
- package/dist/types/core/action.d.ts +23 -9
- package/dist/types/core/async.d.ts +34 -6
- package/dist/types/core/attribution-costs.d.ts +35 -0
- package/dist/types/core/attribution-feedback.d.ts +133 -0
- package/dist/types/core/attribution-hooks.d.ts +307 -8
- package/dist/types/core/attribution-queries.d.ts +24 -0
- package/dist/types/core/attribution.d.ts +802 -72
- package/dist/types/core/constants.d.ts +195 -38
- package/dist/types/core/copies.d.ts +54 -0
- package/dist/types/core/core.d.ts +295 -65
- package/dist/types/core/dev.d.ts +509 -22
- package/dist/types/core/effect.d.ts +1 -1
- package/dist/types/core/error-hooks.d.ts +71 -0
- package/dist/types/core/error.d.ts +18 -1
- package/dist/types/core/graph.d.ts +40 -1
- package/dist/types/core/heap.d.ts +5 -5
- package/dist/types/core/identities.d.ts +17 -0
- package/dist/types/core/index.d.ts +11 -7
- package/dist/types/core/invariants.d.ts +1 -26
- package/dist/types/core/lanes.d.ts +74 -43
- package/dist/types/core/owner.d.ts +27 -9
- package/dist/types/core/scheduler.d.ts +353 -102
- package/dist/types/core/truth.d.ts +18 -0
- package/dist/types/core/types.d.ts +97 -71
- package/dist/types/core/verdict.d.ts +35 -0
- package/dist/types/deferred.d.ts +28 -0
- package/dist/types/flatten.d.ts +8 -0
- package/dist/types/from.d.ts +47 -0
- package/dist/types/index.d.ts +33 -7
- package/dist/types/map.d.ts +4 -2
- package/dist/types/reveal.d.ts +19 -0
- package/dist/types/signals.d.ts +196 -45
- package/dist/types/store/affects.d.ts +12 -0
- package/dist/types/store/edges.d.ts +9 -0
- package/dist/types/store/hooks.d.ts +62 -0
- package/dist/types/store/index.d.ts +42 -15
- package/dist/types/store/optimistic.d.ts +24 -45
- package/dist/types/store/projection.d.ts +17 -68
- package/dist/types/store/reconcile.d.ts +3 -46
- package/dist/types/store/store.d.ts +133 -136
- package/dist/types/store/storePath.d.ts +1 -1
- package/dist/types/store/target.d.ts +166 -0
- package/dist/types/store/types.d.ts +105 -0
- package/dist/types/store/utils.d.ts +188 -0
- package/package.json +31 -26
- package/dist/node.cjs +0 -8745
- package/dist/prod/core/optimistic.js +0 -265
- package/dist/prod/store/next/optimistic.js +0 -385
- package/dist/prod/store/next/projection.js +0 -172
- package/dist/prod/store/next/reconcile.js +0 -331
- package/dist/prod/store/next/store.js +0 -1499
- package/dist/prod/store/next/target.js +0 -20
- package/dist/types/core/optimistic.d.ts +0 -6
- package/dist/types/store/next/optimistic.d.ts +0 -20
- package/dist/types/store/next/projection.d.ts +0 -8
- package/dist/types/store/next/reconcile.d.ts +0 -3
- package/dist/types/store/next/store.d.ts +0 -77
- package/dist/types/store/next/target.d.ts +0 -117
- package/dist/types-cjs/affects.d.cts +0 -47
- package/dist/types-cjs/boundaries.d.cts +0 -175
- package/dist/types-cjs/core/action.d.cts +0 -64
- package/dist/types-cjs/core/async.d.cts +0 -21
- package/dist/types-cjs/core/attribution-hooks.d.cts +0 -52
- package/dist/types-cjs/core/attribution.d.cts +0 -186
- package/dist/types-cjs/core/constants.d.cts +0 -97
- package/dist/types-cjs/core/context.d.cts +0 -36
- package/dist/types-cjs/core/core.d.cts +0 -163
- package/dist/types-cjs/core/dev.d.cts +0 -81
- package/dist/types-cjs/core/effect.d.cts +0 -30
- package/dist/types-cjs/core/error.d.cts +0 -47
- package/dist/types-cjs/core/external.d.cts +0 -15
- package/dist/types-cjs/core/graph.d.cts +0 -6
- package/dist/types-cjs/core/heap.d.cts +0 -22
- package/dist/types-cjs/core/index.d.cts +0 -13
- package/dist/types-cjs/core/invariants.d.cts +0 -59
- package/dist/types-cjs/core/lanes.d.cts +0 -44
- package/dist/types-cjs/core/optimistic.d.cts +0 -6
- package/dist/types-cjs/core/owner.d.cts +0 -124
- package/dist/types-cjs/core/scheduler.d.cts +0 -180
- package/dist/types-cjs/core/types.d.cts +0 -192
- package/dist/types-cjs/core/verdict.d.cts +0 -2
- package/dist/types-cjs/index.d.cts +0 -10
- package/dist/types-cjs/map.d.cts +0 -69
- package/dist/types-cjs/package.json +0 -3
- package/dist/types-cjs/signals.d.cts +0 -624
- package/dist/types-cjs/store/index.d.cts +0 -19
- package/dist/types-cjs/store/next/optimistic.d.cts +0 -20
- package/dist/types-cjs/store/next/projection.d.cts +0 -8
- package/dist/types-cjs/store/next/reconcile.d.cts +0 -3
- package/dist/types-cjs/store/next/store.d.cts +0 -77
- package/dist/types-cjs/store/next/target.d.cts +0 -117
- package/dist/types-cjs/store/optimistic.d.cts +0 -45
- package/dist/types-cjs/store/projection.d.cts +0 -70
- package/dist/types-cjs/store/reconcile.d.cts +0 -46
- package/dist/types-cjs/store/store.d.cts +0 -138
- package/dist/types-cjs/store/storePath.d.cts +0 -58
- package/dist/types-cjs/store/utils.d.cts +0 -74
|
@@ -1,265 +0,0 @@
|
|
|
1
|
-
import { NOT_PENDING, unwrapOverride, STATUS_UNINITIALIZED, CONFIG_HAS_LANE, OVERRIDE_UNDEFINED, STATUS_PENDING, REACTIVE_MANUAL_WRITE, REACTIVE_OPTIMISTIC_DIRTY, EFFECT_RENDER, EFFECT_USER } from "./constants.js";
|
|
2
|
-
|
|
3
|
-
import { ext, latestReadActive, currentOptimisticLane, stale } from "./core.js";
|
|
4
|
-
|
|
5
|
-
import { NotReadyError } from "./error.js";
|
|
6
|
-
|
|
7
|
-
import "./invariants.js";
|
|
8
|
-
|
|
9
|
-
import { resolveTransition, getOrCreateLane, hasActiveOverride, activeLanes, signalLanes, findLane, resolveLane, assignOrMergeLane } from "./lanes.js";
|
|
10
|
-
|
|
11
|
-
import { GlobalQueue, activeTransition, globalQueue, clock, insertSubs, schedule } from "./scheduler.js";
|
|
12
|
-
|
|
13
|
-
/**
|
|
14
|
-
* The optimistic write engine, moved out of core.ts/scheduler.ts. Everything
|
|
15
|
-
* here serves only optimistic overrides — createOptimistic,
|
|
16
|
-
* createOptimisticStore (and its store-node writes), and the verdict layer's
|
|
17
|
-
* companions (which are optimistic nodes). Modules that can create optimistic
|
|
18
|
-
* state call `installOptimisticEngine()` before creating it; apps that never
|
|
19
|
-
* import one of those APIs never retain any of this.
|
|
20
|
-
*
|
|
21
|
-
* Core call sites fire the hooks behind guards on state only this module can
|
|
22
|
-
* create (`_overrideValue !== undefined`, `currentOptimisticLane !== null`,
|
|
23
|
-
* `_optimisticNodes.length`, `activeLanes.size`), so `!` invocations are safe
|
|
24
|
-
* once the gate holds — the same late-binding contract as verdict.ts.
|
|
25
|
-
*/
|
|
26
|
-
/** The optimistic half of setSignal, fired when `_overrideValue !== undefined`. */ function optimisticWrite(e, n) {
|
|
27
|
-
const t = e.o?.De !== NOT_PENDING;
|
|
28
|
-
const i = t ? unwrapOverride(e.o?.De) : e.be;
|
|
29
|
-
if (typeof n === "function") n = n(i);
|
|
30
|
-
const u = !!(e.S & STATUS_UNINITIALIZED) || !e.Ue || !e.Ue(i, n);
|
|
31
|
-
if (!u) {
|
|
32
|
-
// Same-value write with an active override still entangles the current
|
|
33
|
-
// action's transition — the hold must outlast all overlapping actions.
|
|
34
|
-
if (t) {
|
|
35
|
-
const n = resolveTransition(e);
|
|
36
|
-
if (n && activeTransition !== n) globalQueue.initTransition(n);
|
|
37
|
-
}
|
|
38
|
-
return n;
|
|
39
|
-
}
|
|
40
|
-
if (t) globalQueue.initTransition(resolveTransition(e));
|
|
41
|
-
// No revert target is stashed: while the override is active every reader
|
|
42
|
-
// sees it (A17), so authoritative arrivals commit silently into _value and
|
|
43
|
-
// reverting is just dropping the override — _value is already correct.
|
|
44
|
-
else globalQueue.k.Ke.push(e);
|
|
45
|
-
// Stamp ownership on the node (post-merge, so entangled writers share the
|
|
46
|
-
// joint root). resolveTransition prefers this over the lane's _transition,
|
|
47
|
-
// which a shared subscriber can merge across transactions (#2912).
|
|
48
|
-
ext(e).Et = activeTransition;
|
|
49
|
-
const l = getOrCreateLane(e);
|
|
50
|
-
ext(e).Be = l;
|
|
51
|
-
e.T |= CONFIG_HAS_LANE;
|
|
52
|
-
// Literal undefined must not land raw: the slot doubles as the optimistic
|
|
53
|
-
// brand, and erasing it makes the write invisible and routes follow-up
|
|
54
|
-
// writes off the optimistic path into permanent commits (#2898).
|
|
55
|
-
ext(e).De = n === undefined ? OVERRIDE_UNDEFINED : n;
|
|
56
|
-
// syncCompanions only pokes _pendingSignal/_latestValueComputed — with
|
|
57
|
-
// neither companion present the call is a guaranteed no-op.
|
|
58
|
-
(e.o?.Ge !== undefined || e.o?.ge !== undefined) && GlobalQueue.Oe !== null && GlobalQueue.Oe(e, n);
|
|
59
|
-
if (e.Se !== undefined) e.Te = clock;
|
|
60
|
-
// §12e: computed-only slot
|
|
61
|
-
insertSubs(e, true);
|
|
62
|
-
schedule();
|
|
63
|
-
return n;
|
|
64
|
-
}
|
|
65
|
-
|
|
66
|
-
/**
|
|
67
|
-
* transitionComplete's override blockage: a settling transition stays open
|
|
68
|
-
* while one of its optimistic nodes holds an active override that is still
|
|
69
|
-
* pending on real (non-affects-sentinel) async.
|
|
70
|
-
*/ function transitionBlocked(e) {
|
|
71
|
-
for (let n = 0; n < e.Ke.length; n++) {
|
|
72
|
-
const t = e.Ke[n];
|
|
73
|
-
if (hasActiveOverride(t) && "S" in t && t.S & STATUS_PENDING && t.o?._ instanceof NotReadyError) {
|
|
74
|
-
return true;
|
|
75
|
-
}
|
|
76
|
-
}
|
|
77
|
-
return false;
|
|
78
|
-
}
|
|
79
|
-
|
|
80
|
-
function resolveOptimisticNodes(e) {
|
|
81
|
-
// Settlement writes below (snapCompanionsToState → updatePendingSignal-style
|
|
82
|
-
// notifications) may push fresh optimistic nodes; only this batch settles
|
|
83
|
-
// now, so iterate a fixed window and splice it out at the end.
|
|
84
|
-
const n = e.length;
|
|
85
|
-
for (let t = 0; t < n; t++) {
|
|
86
|
-
const n = e[t];
|
|
87
|
-
if (n.o !== null) n.o.Be = undefined;
|
|
88
|
-
// Revert is a pure drop: there is no revert target to commit —
|
|
89
|
-
// override-covered authoritative values hold in _pendingValue and
|
|
90
|
-
// elevate on their OWN transition's schedule (A18 as re-ruled 2026-07-07).
|
|
91
|
-
if (!(n.S & STATUS_PENDING)) n.S &= ~STATUS_UNINITIALIZED;
|
|
92
|
-
const i = n.o?.De;
|
|
93
|
-
ext(n).De = NOT_PENDING;
|
|
94
|
-
if (i !== NOT_PENDING && n.be !== unwrapOverride(i)) insertSubs(n, true);
|
|
95
|
-
n._e = null;
|
|
96
|
-
if (n.o !== null) n.o.Et = null;
|
|
97
|
-
}
|
|
98
|
-
// Settlement checkpoint (#2838): companions caught in this batch (or owned
|
|
99
|
-
// by a node in it) re-derive from committed state, so verdicts survive the
|
|
100
|
-
// transition that produced them (A19 — pending is a property of the data).
|
|
101
|
-
for (let t = 0; t < n; t++) {
|
|
102
|
-
const n = e[t];
|
|
103
|
-
if (n.o?.Ge || n.o?.ge) GlobalQueue.un(n);
|
|
104
|
-
const i = n.o?.It;
|
|
105
|
-
if (i && (i.o?.Ge === n || i.o?.ge === n)) GlobalQueue.un(i);
|
|
106
|
-
}
|
|
107
|
-
e.splice(0, n);
|
|
108
|
-
}
|
|
109
|
-
|
|
110
|
-
function runQueue(e, n) {
|
|
111
|
-
for (let t = 0; t < e.length; t++) e[t](n);
|
|
112
|
-
}
|
|
113
|
-
|
|
114
|
-
/**
|
|
115
|
-
* Run effects from all lanes that are ready (no pending async).
|
|
116
|
-
*/ function runLaneEffects(e) {
|
|
117
|
-
for (const n of activeLanes) {
|
|
118
|
-
if (n.tn || n.Ae.size > 0) continue;
|
|
119
|
-
const t = n.en[e - 1];
|
|
120
|
-
if (t.length) {
|
|
121
|
-
n.en[e - 1] = [];
|
|
122
|
-
runQueue(t, e);
|
|
123
|
-
}
|
|
124
|
-
}
|
|
125
|
-
}
|
|
126
|
-
|
|
127
|
-
function cleanupCompletedLanes(e) {
|
|
128
|
-
for (const n of activeLanes) {
|
|
129
|
-
const t = e ? n._e === e : !n._e;
|
|
130
|
-
if (!t) continue;
|
|
131
|
-
if (!n.tn) {
|
|
132
|
-
if (n.en[0].length) runQueue(n.en[0], EFFECT_RENDER);
|
|
133
|
-
if (n.en[1].length) runQueue(n.en[1], EFFECT_USER);
|
|
134
|
-
}
|
|
135
|
-
if (n.nn.o?.Be === n) if (n.nn.o !== null) n.nn.o.Be = undefined;
|
|
136
|
-
n.Ae.clear();
|
|
137
|
-
n.en[0].length = 0;
|
|
138
|
-
n.en[1].length = 0;
|
|
139
|
-
activeLanes.delete(n);
|
|
140
|
-
signalLanes.delete(n.nn);
|
|
141
|
-
}
|
|
142
|
-
}
|
|
143
|
-
|
|
144
|
-
/** read()'s per-lane suspension test (pending-throw path, lane context). */ function laneSuspends(e) {
|
|
145
|
-
// Per-lane suspension: only throw if in same lane as pending async
|
|
146
|
-
// AND the node doesn't have an active override (overrides are the visible value,
|
|
147
|
-
// downstream in the lane should read the override, not throw)
|
|
148
|
-
const n = e.o?.Be;
|
|
149
|
-
if (!n) return false;
|
|
150
|
-
return findLane(n) === findLane(currentOptimisticLane) && !hasActiveOverride(e);
|
|
151
|
-
}
|
|
152
|
-
|
|
153
|
-
/**
|
|
154
|
-
* read()'s entanglement gate: a reader recomputing under an optimistic lane
|
|
155
|
-
* that reads a pending mid-transition write sees the committed value; the sub
|
|
156
|
-
* is recorded for replay at commit.
|
|
157
|
-
*/ function gatedRead(e, n, t) {
|
|
158
|
-
if (latestReadActive || e.Pe === NOT_PENDING || e.Se || n !== e && !(n.ie & REACTIVE_MANUAL_WRITE)) {
|
|
159
|
-
return false;
|
|
160
|
-
}
|
|
161
|
-
activeTransition.ln.add(t);
|
|
162
|
-
return true;
|
|
163
|
-
}
|
|
164
|
-
|
|
165
|
-
/**
|
|
166
|
-
* read()'s value selection under a lane: return the committed `_value` for
|
|
167
|
-
* optimistic/lane-assigned signals, stale-mode reads, and pending owners.
|
|
168
|
-
*/ function laneReadsCommitted(e, n, t) {
|
|
169
|
-
if (e.o?.De !== undefined || !!e.o?.Be || !!(n.S & STATUS_PENDING)) return true;
|
|
170
|
-
if (n === e && stale && t.o?.It !== e) {
|
|
171
|
-
// The committed view can hide a same-tick ambient write (a lane member —
|
|
172
|
-
// even just an isPending companion flip — puts the reader "under a lane"
|
|
173
|
-
// against unrelated plain writes). With no transaction the write commits
|
|
174
|
-
// at THIS flush's end with no re-delivery, so record the reader for
|
|
175
|
-
// replay at commit — the same contract gatedRead provides when a
|
|
176
|
-
// transaction is active (#2963). If a transaction forms mid-flush,
|
|
177
|
-
// initTransition carries the recording over to it.
|
|
178
|
-
if (e.Pe !== NOT_PENDING && activeTransition === null) globalQueue.k.ln.add(t);
|
|
179
|
-
return true;
|
|
180
|
-
}
|
|
181
|
-
return false;
|
|
182
|
-
}
|
|
183
|
-
|
|
184
|
-
/**
|
|
185
|
-
* recompute()'s lane posture: resolve the node's own lane (own=true), or adopt
|
|
186
|
-
* a dependency's optimistic lane (own=false — parent-deeper-than-owned-child
|
|
187
|
-
* can run before its OPT-dirty child propagates).
|
|
188
|
-
*/ function recomputeLane(e, n) {
|
|
189
|
-
if (n) {
|
|
190
|
-
const n = resolveLane(e);
|
|
191
|
-
if (!n) return null;
|
|
192
|
-
// Wake-only lane demotion (#3009): a plain write to a latest()-tracked
|
|
193
|
-
// source rides the optimistic channel only to wake verdict companions —
|
|
194
|
-
// its lane is sourced by the companion shadow (_parentSource set) and owns
|
|
195
|
-
// no transaction. When such a node is pulled mid-tick by a latest()/
|
|
196
|
-
// isPending() probe, lane posture would direct-commit _value, leaking the
|
|
197
|
-
// queued write into committed reads before the flush. Return `false` so
|
|
198
|
-
// recompute() runs plain: the value stages and commits with the flush.
|
|
199
|
-
// (el's own override slot excludes companions themselves; a lane merged
|
|
200
|
-
// into a real optimistic lane resolves to a non-companion source.)
|
|
201
|
-
if (!globalQueue.sn && !activeTransition && !n._e && n.nn.o?.It !== undefined && e.o?.De === undefined) {
|
|
202
|
-
if (e.o !== null) e.o.Be = undefined;
|
|
203
|
-
return false;
|
|
204
|
-
}
|
|
205
|
-
return n;
|
|
206
|
-
}
|
|
207
|
-
for (let n = e.nt; n; n = n.it) {
|
|
208
|
-
const t = n.ut;
|
|
209
|
-
if (t.ie & REACTIVE_OPTIMISTIC_DIRTY) {
|
|
210
|
-
const n = resolveLane(t);
|
|
211
|
-
if (n) {
|
|
212
|
-
e.ie |= REACTIVE_OPTIMISTIC_DIRTY;
|
|
213
|
-
assignOrMergeLane(e, n);
|
|
214
|
-
return n;
|
|
215
|
-
}
|
|
216
|
-
}
|
|
217
|
-
}
|
|
218
|
-
return null;
|
|
219
|
-
}
|
|
220
|
-
|
|
221
|
-
/** recompute()'s catch path: track pending async in the current lane. */ function laneAsyncPending(e) {
|
|
222
|
-
const n = findLane(currentOptimisticLane);
|
|
223
|
-
if (n.nn !== e) {
|
|
224
|
-
n.Ae.add(e);
|
|
225
|
-
ext(e).Be = n;
|
|
226
|
-
e.T |= CONFIG_HAS_LANE;
|
|
227
|
-
GlobalQueue.de !== null && GlobalQueue.de(n.nn);
|
|
228
|
-
}
|
|
229
|
-
}
|
|
230
|
-
|
|
231
|
-
/** recompute()'s success path: the node's async settled, clear it from its lane. */ function laneAsyncSettled(e) {
|
|
232
|
-
const n = resolveLane(e);
|
|
233
|
-
if (n) {
|
|
234
|
-
n.Ae.delete(e);
|
|
235
|
-
GlobalQueue.de !== null && GlobalQueue.de(n.nn);
|
|
236
|
-
}
|
|
237
|
-
}
|
|
238
|
-
|
|
239
|
-
function trackOptimisticStore(e) {
|
|
240
|
-
// After initTransition, globalQueue._batch IS activeTransition (same reference)
|
|
241
|
-
globalQueue.k.cn.add(e);
|
|
242
|
-
schedule();
|
|
243
|
-
}
|
|
244
|
-
|
|
245
|
-
/**
|
|
246
|
-
* Installs the engine's hooks. Idempotent; called by every module that can
|
|
247
|
-
* create optimistic state (verdict.ts at module top level, createOptimistic
|
|
248
|
-
* and createOptimisticStore at first call) BEFORE any optimistic node exists.
|
|
249
|
-
*/ function installOptimisticEngine() {
|
|
250
|
-
if (GlobalQueue.vt !== null) return;
|
|
251
|
-
GlobalQueue.vt = optimisticWrite;
|
|
252
|
-
GlobalQueue.fn = resolveOptimisticNodes;
|
|
253
|
-
GlobalQueue.dn = transitionBlocked;
|
|
254
|
-
GlobalQueue.En = cleanupCompletedLanes;
|
|
255
|
-
GlobalQueue.Tn = runLaneEffects;
|
|
256
|
-
GlobalQueue.Ft = gatedRead;
|
|
257
|
-
GlobalQueue.ht = laneSuspends;
|
|
258
|
-
GlobalQueue.gt = laneReadsCommitted;
|
|
259
|
-
GlobalQueue.je = recomputeLane;
|
|
260
|
-
GlobalQueue.$e = laneAsyncPending;
|
|
261
|
-
GlobalQueue.ze = laneAsyncSettled;
|
|
262
|
-
GlobalQueue.Nn = trackOptimisticStore;
|
|
263
|
-
}
|
|
264
|
-
|
|
265
|
-
export { installOptimisticEngine };
|
|
@@ -1,385 +0,0 @@
|
|
|
1
|
-
import { computed, ext, setSignal, isEqual } from "../../core/core.js";
|
|
2
|
-
|
|
3
|
-
import { CONFIG_AUTO_DISPOSE, STATUS_PENDING, NOT_PENDING, unwrapOverride, CONFIG_OPTIMISTIC } from "../../core/constants.js";
|
|
4
|
-
|
|
5
|
-
import { GlobalQueue, insertSubs, schedule, globalQueue } from "../../core/scheduler.js";
|
|
6
|
-
|
|
7
|
-
import "../../core/invariants.js";
|
|
8
|
-
|
|
9
|
-
import "../../core/verdict.js";
|
|
10
|
-
|
|
11
|
-
import "../../core/effect.js";
|
|
12
|
-
|
|
13
|
-
import { installOptimisticEngine } from "../../core/optimistic.js";
|
|
14
|
-
|
|
15
|
-
import { $TARGET, markRawIngest, setNextOptimisticViewResolver, isWrappable, rawValuesUsed, isRawValue } from "../store.js";
|
|
16
|
-
|
|
17
|
-
import { runProjectionComputedNext } from "./projection.js";
|
|
18
|
-
|
|
19
|
-
import { wrapNext, runAuthoritative, storeSetterNext, hasActiveOverride, unwrapValue, getNode, getHasNode, targetsEqual, getKeySetNode, bumpDeep } from "./store.js";
|
|
20
|
-
|
|
21
|
-
import { setOptHooks } from "./target.js";
|
|
22
|
-
|
|
23
|
-
/**
|
|
24
|
-
* Store rewrite — optimistic stores (§3/§7, RUL-3): no store-side layer, no
|
|
25
|
-
* backup snapshots. Nodes in an optimistic family are ARMED core signals
|
|
26
|
-
* (`_overrideValue` slot), so every user write rides the engine's
|
|
27
|
-
* optimisticWrite — per-transaction ownership, entanglement, reverts, and
|
|
28
|
-
* flash-at-flush are inherited, not reimplemented. Membership edits live on
|
|
29
|
-
* armed presence nodes (the §6 overlay), so structural optimism reverts with
|
|
30
|
-
* the same per-transaction granularity (FINDING-2's fix by construction).
|
|
31
|
-
*
|
|
32
|
-
* Derived form = an optimistic projection: the derive's recompute and its
|
|
33
|
-
* async commits run under projectionWriteActive (authoritative landings
|
|
34
|
-
* commit silently beneath any active overrides). The transitionBlocked
|
|
35
|
-
* store-half (#2951) is installed here for next-shaped targets, chaining the
|
|
36
|
-
* legacy/engine checks.
|
|
37
|
-
*/ let blockedInstalled = false;
|
|
38
|
-
|
|
39
|
-
function installNextBlockedHalf() {
|
|
40
|
-
if (blockedInstalled) return;
|
|
41
|
-
blockedInstalled = true;
|
|
42
|
-
// Late-bind the optimistic machinery into the plain store/reconcile paths
|
|
43
|
-
// (all call sites are fam?.opt-gated, so this always runs first) and the
|
|
44
|
-
// affects witness's view resolver.
|
|
45
|
-
setOptHooks({
|
|
46
|
-
notifyOptimisticWrites: notifyOptimisticWrites,
|
|
47
|
-
optimisticView: optimisticView,
|
|
48
|
-
applyTentative: applyTentative
|
|
49
|
-
});
|
|
50
|
-
setNextOptimisticViewResolver((e, t) => optimisticView(e, t));
|
|
51
|
-
// Scheduler flush tails call _clearOptimisticStores whenever tracked
|
|
52
|
-
// stores exist; next has no layer to clear — reverts are engine-native —
|
|
53
|
-
// so the hook only empties the batch set.
|
|
54
|
-
if (!GlobalQueue.Vt) {
|
|
55
|
-
GlobalQueue.Vt = e => {
|
|
56
|
-
e.clear();
|
|
57
|
-
};
|
|
58
|
-
}
|
|
59
|
-
const e = GlobalQueue.dn;
|
|
60
|
-
GlobalQueue.dn = t => {
|
|
61
|
-
for (const e of t.cn) {
|
|
62
|
-
const t = e?.[$TARGET];
|
|
63
|
-
const n = t?.fam?.node;
|
|
64
|
-
// The hold exists to keep optimistic state alive until the store's own
|
|
65
|
-
// truth lands (#2951). Once the family carries NO live overrides (a
|
|
66
|
-
// landing consumed them, or they never existed), a pending firewall is
|
|
67
|
-
// no reason to park the transaction — blocking then leaks it forever
|
|
68
|
-
// when the in-flight question is never answered (undisposed fixtures).
|
|
69
|
-
if (n != null && n.S & STATUS_PENDING && familyHasLiveOverrides(t.fam)) return true;
|
|
70
|
-
}
|
|
71
|
-
return e(t);
|
|
72
|
-
};
|
|
73
|
-
}
|
|
74
|
-
|
|
75
|
-
function familyHasLiveOverrides(e) {
|
|
76
|
-
const t = e.overlaid;
|
|
77
|
-
if (t === undefined || t.size === 0) return false;
|
|
78
|
-
for (const e of t) {
|
|
79
|
-
for (const t of [ e.n, e.h ]) {
|
|
80
|
-
if (t === null) continue;
|
|
81
|
-
for (const e of Reflect.ownKeys(t)) {
|
|
82
|
-
const n = t[e];
|
|
83
|
-
if (n.o?.De !== undefined && n.o?.De !== NOT_PENDING) return true;
|
|
84
|
-
}
|
|
85
|
-
}
|
|
86
|
-
if (e.k !== null && e.k.o?.De !== undefined && e.k.o?.De !== NOT_PENDING) return true;
|
|
87
|
-
}
|
|
88
|
-
t.clear();
|
|
89
|
-
// nothing live — drop the bookkeeping
|
|
90
|
-
return false;
|
|
91
|
-
}
|
|
92
|
-
|
|
93
|
-
function createOptimisticStoreNext(e, t, n) {
|
|
94
|
-
// Engine first (armed nodes need optimisticWrite installed before any
|
|
95
|
-
// node exists), then the next-shape hooks.
|
|
96
|
-
installOptimisticEngine();
|
|
97
|
-
installNextBlockedHalf();
|
|
98
|
-
const i = typeof e === "function";
|
|
99
|
-
if (!i && n === undefined) n = t;
|
|
100
|
-
const o = i ? t : e;
|
|
101
|
-
const r = {
|
|
102
|
-
map: new WeakMap,
|
|
103
|
-
node: null,
|
|
104
|
-
shallow: !!n?.shallow,
|
|
105
|
-
opt: true
|
|
106
|
-
};
|
|
107
|
-
const s = wrapNext(o, null, null, r);
|
|
108
|
-
r.px = s;
|
|
109
|
-
if (r.shallow) {
|
|
110
|
-
s[$TARGET].s = true;
|
|
111
|
-
markRawIngest(o);
|
|
112
|
-
}
|
|
113
|
-
if (i) {
|
|
114
|
-
const t = e;
|
|
115
|
-
// Async commits land outside the computed's sync body — re-apply the
|
|
116
|
-
// authoritative-write posture there too. Landings consume the family's
|
|
117
|
-
// tentative overrides (RUL-2: visible landed truth replaces optimism) —
|
|
118
|
-
// both the reconcile-channel commit and per-op post-await draft writes.
|
|
119
|
-
const consume = () => consumeOverridesNext(r);
|
|
120
|
-
const wrapCommit = e => {
|
|
121
|
-
runAuthoritative(e);
|
|
122
|
-
consume();
|
|
123
|
-
};
|
|
124
|
-
let i;
|
|
125
|
-
if (n?.seedLoadingValue) i = {
|
|
126
|
-
loadingValue: undefined
|
|
127
|
-
};
|
|
128
|
-
const o = computed(() => {
|
|
129
|
-
runAuthoritative(() => runProjectionComputedNext(s, t, n?.key === undefined ? "id" : n.key, wrapCommit, consume));
|
|
130
|
-
}, i);
|
|
131
|
-
o.T &= ~CONFIG_AUTO_DISPOSE;
|
|
132
|
-
r.node = o;
|
|
133
|
-
}
|
|
134
|
-
return [ s, e => storeSetterNext(s, e) ];
|
|
135
|
-
}
|
|
136
|
-
|
|
137
|
-
// ---- optimistic-only store machinery (moved from next/store.ts /
|
|
138
|
-
// next/reconcile.ts so plain-store bundles tree-shake it) ----
|
|
139
|
-
/** Diff the draft against the current OPTIMISTIC VIEW (committed + active
|
|
140
|
-
* overrides — the same view the draft was seeded from) and emit engine writes
|
|
141
|
-
* for exactly the changed keys. Visible-view diffing keeps no-op writes from
|
|
142
|
-
* entangling lanes (RUL-10 / opt R38). */ function notifyOptimisticWrites(e, t) {
|
|
143
|
-
// A bare write while the store's own truth is in flight rides THAT
|
|
144
|
-
// transaction (#2951, legacy parity): entangle the firewall's transition so
|
|
145
|
-
// the override survives until the refetch settles instead of flash-reverting
|
|
146
|
-
// at plain flush end. The blocked-check store-half keeps that transaction
|
|
147
|
-
// from settling while the firewall is pending.
|
|
148
|
-
const n = e.fam?.node;
|
|
149
|
-
if (n?._e) globalQueue.initTransition(n._e);
|
|
150
|
-
const i = e.v;
|
|
151
|
-
const visible = (t, n) => {
|
|
152
|
-
const i = e.n?.[t];
|
|
153
|
-
return i !== undefined && hasActiveOverride(i) ? unwrapOverride(i.o?.De) : n;
|
|
154
|
-
};
|
|
155
|
-
const visiblePresent = t => {
|
|
156
|
-
const n = e.h?.[t];
|
|
157
|
-
return n !== undefined && hasActiveOverride(n) ? !!unwrapOverride(n.o?.De) : t in i;
|
|
158
|
-
};
|
|
159
|
-
let o = false;
|
|
160
|
-
const r = Array.isArray(t);
|
|
161
|
-
for (const n of Reflect.ownKeys(t)) {
|
|
162
|
-
if (r && n === "length") continue;
|
|
163
|
-
const s = unwrapValue(t[n]);
|
|
164
|
-
if (!visiblePresent(n)) {
|
|
165
|
-
// Optimistic add: value node + presence node + membership bump.
|
|
166
|
-
setSignal(getNode(e, n, i[n]), () => s);
|
|
167
|
-
setSignal(getHasNode(e, n, n in i), true);
|
|
168
|
-
o = true;
|
|
169
|
-
} else {
|
|
170
|
-
const t = visible(n, i[n]);
|
|
171
|
-
if (!isEqual(t, s) && !targetsEqual(t, s)) {
|
|
172
|
-
setSignal(getNode(e, n, t), () => s);
|
|
173
|
-
if (r) o = true;
|
|
174
|
-
}
|
|
175
|
-
}
|
|
176
|
-
}
|
|
177
|
-
for (const n of Reflect.ownKeys(i)) {
|
|
178
|
-
if (r && n === "length") continue;
|
|
179
|
-
if (n in t || !visiblePresent(n)) continue;
|
|
180
|
-
// Optimistic delete: node reads undefined, presence flips, membership bumps.
|
|
181
|
-
setSignal(getNode(e, n, i[n]), () => undefined);
|
|
182
|
-
setSignal(getHasNode(e, n, true), false);
|
|
183
|
-
o = true;
|
|
184
|
-
}
|
|
185
|
-
if (r) {
|
|
186
|
-
const n = visible("length", i.length);
|
|
187
|
-
if (n !== t.length) {
|
|
188
|
-
setSignal(getNode(e, "length", n), () => t.length);
|
|
189
|
-
o = true;
|
|
190
|
-
}
|
|
191
|
-
}
|
|
192
|
-
if (o) setSignal(getKeySetNode(e), e => e + 1);
|
|
193
|
-
// Deep-witness: optimistic value writes notify deep() subscribers too
|
|
194
|
-
// (structural ones already ride the key-set bump above).
|
|
195
|
-
bumpDeep(e);
|
|
196
|
-
// Discard the draft — committed raw is untouched (revert target by
|
|
197
|
-
// construction). Register the root store for the scheduler's settle hooks
|
|
198
|
-
// and the target for landing consumption (RUL-2).
|
|
199
|
-
e.pb = null;
|
|
200
|
-
(e.fam.overlaid ??= new Set).add(e);
|
|
201
|
-
GlobalQueue.Nn?.(e.fam.px ?? e.px);
|
|
202
|
-
}
|
|
203
|
-
|
|
204
|
-
/**
|
|
205
|
-
* Landing consumption (RUL-2): fresh authoritative data supersedes every
|
|
206
|
-
* tentative override in the family. Mirrors legacy clearProjectionOverride —
|
|
207
|
-
* drop the override, clear lane/ownership, notify subscribers whose visible
|
|
208
|
-
* value changes (reversion effects go to regular queues via the projection
|
|
209
|
-
* write posture the caller holds).
|
|
210
|
-
*/ function consumeOverridesNext(e) {
|
|
211
|
-
const t = e.overlaid;
|
|
212
|
-
if (t === undefined || t.size === 0) return;
|
|
213
|
-
runAuthoritative(() => {
|
|
214
|
-
for (const e of t) {
|
|
215
|
-
const drop = (e, t) => {
|
|
216
|
-
if (!hasActiveOverride(e)) return;
|
|
217
|
-
const n = unwrapOverride(e.o?.De);
|
|
218
|
-
// Full legacy reset (clearOptimisticOverride parity): the landing is
|
|
219
|
-
// authoritative NOW — fold committed into the node directly instead
|
|
220
|
-
// of riding a transaction's commit (whose queues may be stashed with
|
|
221
|
-
// the transaction parked; the wake would strand until it settles).
|
|
222
|
-
ext(e).De = NOT_PENDING;
|
|
223
|
-
e.T |= CONFIG_OPTIMISTIC;
|
|
224
|
-
const i = e.o;
|
|
225
|
-
if (i) {
|
|
226
|
-
i.Et = null;
|
|
227
|
-
i.Be = undefined;
|
|
228
|
-
}
|
|
229
|
-
e.Pe = NOT_PENDING;
|
|
230
|
-
e.be = t;
|
|
231
|
-
if (!e.Ue || !e.Ue(n, t)) {
|
|
232
|
-
insertSubs(e, true);
|
|
233
|
-
schedule();
|
|
234
|
-
}
|
|
235
|
-
};
|
|
236
|
-
// Landing consumes STRUCTURAL optimism only (legacy layer parity):
|
|
237
|
-
// membership edits, array length, and the value overrides written WITH
|
|
238
|
-
// them (a key carrying an active presence override is an add/delete —
|
|
239
|
-
// classified BEFORE the adoption may have made the key exist in landed
|
|
240
|
-
// data). A pure value override on a key the landing carries stays with
|
|
241
|
-
// its owning transaction (rapid-toggle contract: a live action's edit
|
|
242
|
-
// of an existing entity rides on top of landed truth).
|
|
243
|
-
const t = Array.isArray(e.v);
|
|
244
|
-
const n = e.h;
|
|
245
|
-
let i = null;
|
|
246
|
-
if (n !== null) {
|
|
247
|
-
for (const e of Reflect.ownKeys(n)) {
|
|
248
|
-
if (hasActiveOverride(n[e])) (i ??= new Set).add(e);
|
|
249
|
-
}
|
|
250
|
-
}
|
|
251
|
-
const o = e.n;
|
|
252
|
-
if (o !== null) {
|
|
253
|
-
for (const n of Reflect.ownKeys(o)) {
|
|
254
|
-
const r = i?.has(n) || !(n in e.v) || t && n === "length";
|
|
255
|
-
if (!r) continue;
|
|
256
|
-
drop(o[n], t && n === "length" ? e.v.length : e.v[n]);
|
|
257
|
-
}
|
|
258
|
-
}
|
|
259
|
-
if (n !== null) {
|
|
260
|
-
for (const t of Reflect.ownKeys(n)) drop(n[t], t in e.v);
|
|
261
|
-
}
|
|
262
|
-
if (e.k !== null && hasActiveOverride(e.k)) {
|
|
263
|
-
ext(e.k).De = NOT_PENDING;
|
|
264
|
-
e.k.T |= CONFIG_OPTIMISTIC;
|
|
265
|
-
const t = e.k.o;
|
|
266
|
-
if (t) {
|
|
267
|
-
t.Et = null;
|
|
268
|
-
t.Be = undefined;
|
|
269
|
-
}
|
|
270
|
-
insertSubs(e.k, true);
|
|
271
|
-
schedule();
|
|
272
|
-
}
|
|
273
|
-
}
|
|
274
|
-
t.clear();
|
|
275
|
-
});
|
|
276
|
-
}
|
|
277
|
-
|
|
278
|
-
/** Optimistic-view composition for snapshot/deep (O1: snapshot is the CURRENT
|
|
279
|
-
* view, lane values included; a fresh copy per call during pending windows —
|
|
280
|
-
* RUL-12). Returns `src` untouched when no override is active on `t`. */ function optimisticView(e, t) {
|
|
281
|
-
if (e.fam?.opt !== true) return t;
|
|
282
|
-
let n = null;
|
|
283
|
-
const ensure = () => n ??= Array.isArray(t) ? [ ...t ] : {
|
|
284
|
-
...t
|
|
285
|
-
};
|
|
286
|
-
const i = e.n;
|
|
287
|
-
if (i !== null) {
|
|
288
|
-
for (const e of Reflect.ownKeys(i)) {
|
|
289
|
-
const n = i[e];
|
|
290
|
-
if (!hasActiveOverride(n)) continue;
|
|
291
|
-
const o = unwrapOverride(n.o?.De);
|
|
292
|
-
if (e === "length" && Array.isArray(t)) {
|
|
293
|
-
if (t.length !== o) ensure().length = o;
|
|
294
|
-
} else if (!isEqual(t[e], o)) ensure()[e] = o;
|
|
295
|
-
}
|
|
296
|
-
}
|
|
297
|
-
const o = e.h;
|
|
298
|
-
if (o !== null) {
|
|
299
|
-
for (const e of Reflect.ownKeys(o)) {
|
|
300
|
-
const i = o[e];
|
|
301
|
-
if (!hasActiveOverride(i)) continue;
|
|
302
|
-
const r = !!unwrapOverride(i.o?.De);
|
|
303
|
-
if (!r && e in (n ?? t)) delete ensure()[e];
|
|
304
|
-
}
|
|
305
|
-
}
|
|
306
|
-
return n ?? t;
|
|
307
|
-
}
|
|
308
|
-
|
|
309
|
-
function applyTentative(e, t, n) {
|
|
310
|
-
const i = e.pb ?? e.v;
|
|
311
|
-
const o = optimisticView(e, i);
|
|
312
|
-
const r = e.fam.map;
|
|
313
|
-
const s = Array.isArray(t);
|
|
314
|
-
if (Array.isArray(o) !== s) return;
|
|
315
|
-
// kind change at root: flat overrides below
|
|
316
|
-
const l = [];
|
|
317
|
-
const u = s ? [ ...t ] : shallowWithSymbols(t);
|
|
318
|
-
const match = (e, t) => {
|
|
319
|
-
if (!isWrappable(e) || !isWrappable(t)) return null;
|
|
320
|
-
if (rawValuesUsed && (isRawValue(e) || isRawValue(t))) return null;
|
|
321
|
-
if (Array.isArray(e) !== Array.isArray(t)) return null;
|
|
322
|
-
if (n) {
|
|
323
|
-
const i = n(e);
|
|
324
|
-
const o = n(t);
|
|
325
|
-
if (i !== undefined && o !== undefined && i !== o) return null;
|
|
326
|
-
}
|
|
327
|
-
return r.get(unwrapValue(e)) ?? null;
|
|
328
|
-
};
|
|
329
|
-
if (s) {
|
|
330
|
-
const e = o;
|
|
331
|
-
let i = null;
|
|
332
|
-
for (let o = 0; o < t.length; o++) {
|
|
333
|
-
const r = t[o];
|
|
334
|
-
if (!isWrappable(r)) continue;
|
|
335
|
-
let s;
|
|
336
|
-
if (n) {
|
|
337
|
-
const t = n(r);
|
|
338
|
-
if (t !== undefined) {
|
|
339
|
-
if (i === null) {
|
|
340
|
-
i = new Map;
|
|
341
|
-
for (let t = 0; t < e.length; t++) {
|
|
342
|
-
const o = unwrapValue(e[t]);
|
|
343
|
-
if (isWrappable(o)) {
|
|
344
|
-
const e = n(o);
|
|
345
|
-
if (e !== undefined && !i.has(e)) i.set(e, o);
|
|
346
|
-
}
|
|
347
|
-
}
|
|
348
|
-
}
|
|
349
|
-
s = i.get(t);
|
|
350
|
-
} else s = unwrapValue(e[o]);
|
|
351
|
-
} else s = unwrapValue(e[o]);
|
|
352
|
-
const c = match(s, r);
|
|
353
|
-
if (c !== null) {
|
|
354
|
-
// Keep the existing row in the slot (identity preserved); recurse.
|
|
355
|
-
u[o] = unwrapValue(s);
|
|
356
|
-
l.push([ c, r ]);
|
|
357
|
-
}
|
|
358
|
-
}
|
|
359
|
-
} else {
|
|
360
|
-
for (const e of Reflect.ownKeys(t)) {
|
|
361
|
-
const n = unwrapValue(o[e]);
|
|
362
|
-
const i = t[e];
|
|
363
|
-
const r = match(n, i);
|
|
364
|
-
if (r !== null) {
|
|
365
|
-
u[e] = n;
|
|
366
|
-
l.push([ r, i ]);
|
|
367
|
-
}
|
|
368
|
-
}
|
|
369
|
-
}
|
|
370
|
-
// Flat overrides for this level (adds, removals, moved slots, length, leaf
|
|
371
|
-
// values) — preserve any live user draft backing across the call.
|
|
372
|
-
const c = e.pb;
|
|
373
|
-
e.pb = null;
|
|
374
|
-
notifyOptimisticWrites(e, u);
|
|
375
|
-
e.pb = c;
|
|
376
|
-
for (let e = 0; e < l.length; e++) applyTentative(l[e][0], unwrapValue(l[e][1]), n);
|
|
377
|
-
}
|
|
378
|
-
|
|
379
|
-
function shallowWithSymbols(e) {
|
|
380
|
-
const t = {};
|
|
381
|
-
for (const n of Reflect.ownKeys(e)) t[n] = e[n];
|
|
382
|
-
return t;
|
|
383
|
-
}
|
|
384
|
-
|
|
385
|
-
export { consumeOverridesNext, createOptimisticStoreNext, notifyOptimisticWrites, optimisticView };
|