@solidjs/signals 2.0.0-rc.19 → 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 +553 -264
- package/dist/dev.attribution.js +18 -18
- package/dist/dev.js +1030 -439
- package/dist/observe/affects.js +12 -2
- package/dist/observe/boundaries.js +168 -115
- package/dist/observe/core/async.js +57 -37
- package/dist/observe/core/attribution.js +6 -6
- package/dist/observe/core/constants.js +9 -1
- package/dist/observe/core/copies.js +10 -0
- package/dist/observe/core/core.js +261 -181
- package/dist/observe/core/effect.js +32 -27
- package/dist/observe/core/graph.js +7 -7
- package/dist/observe/core/heap.js +29 -29
- package/dist/observe/core/lanes.js +301 -101
- package/dist/observe/core/owner.js +13 -13
- package/dist/observe/core/scheduler.js +124 -69
- package/dist/observe/core/truth.js +9 -7
- package/dist/observe/core/verdict.js +160 -98
- package/dist/observe/deferred.js +1 -1
- package/dist/observe/index.js +2 -0
- package/dist/observe/map.js +120 -116
- package/dist/observe/reveal.js +48 -48
- package/dist/observe/signals.js +5 -5
- package/dist/observe/store/affects.js +2 -2
- package/dist/observe/store/optimistic.js +272 -176
- package/dist/observe/store/projection.js +21 -10
- package/dist/observe/store/reconcile.js +8 -2
- package/dist/observe/store/store.js +91 -55
- package/dist/observe/store/types.js +11 -1
- package/dist/observe/store/utils.js +1 -1
- package/dist/prod/affects.js +12 -2
- package/dist/prod/boundaries.js +164 -109
- package/dist/prod/core/async.js +201 -181
- package/dist/prod/core/constants.js +9 -1
- package/dist/prod/core/copies.js +10 -0
- package/dist/prod/core/core.js +244 -164
- package/dist/prod/core/dev.js +108 -3
- package/dist/prod/core/effect.js +28 -23
- package/dist/prod/core/graph.js +9 -9
- package/dist/prod/core/heap.js +16 -16
- package/dist/prod/core/identities.js +1 -1
- package/dist/prod/core/lanes.js +307 -95
- package/dist/prod/core/owner.js +22 -22
- package/dist/prod/core/scheduler.js +266 -211
- package/dist/prod/core/truth.js +9 -7
- package/dist/prod/core/verdict.js +161 -99
- package/dist/prod/deferred.js +1 -1
- package/dist/prod/index.js +2 -0
- package/dist/prod/map.js +78 -74
- package/dist/prod/reveal.js +34 -34
- package/dist/prod/signals.js +3 -3
- package/dist/prod/store/affects.js +15 -15
- package/dist/prod/store/optimistic.js +185 -89
- package/dist/prod/store/projection.js +49 -38
- package/dist/prod/store/reconcile.js +8 -2
- package/dist/prod/store/store.js +99 -63
- package/dist/prod/store/types.js +11 -1
- package/dist/types/affects.d.ts +3 -2
- package/dist/types/boundaries.d.ts +14 -2
- package/dist/types/core/async.d.ts +2 -1
- package/dist/types/core/constants.d.ts +8 -0
- package/dist/types/core/copies.d.ts +54 -0
- package/dist/types/core/core.d.ts +15 -0
- package/dist/types/core/dev.d.ts +1 -1
- package/dist/types/core/lanes.d.ts +8 -1
- package/dist/types/core/scheduler.d.ts +36 -4
- package/dist/types/core/truth.d.ts +3 -1
- package/dist/types/core/types.d.ts +6 -0
- package/dist/types/index.d.ts +2 -0
- package/dist/types/store/hooks.d.ts +15 -1
- package/dist/types/store/store.d.ts +2 -1
- package/dist/types/store/target.d.ts +5 -0
- package/dist/types/store/types.d.ts +7 -0
- package/package.json +1 -1
|
@@ -26,12 +26,13 @@ import { globalQueue, schedule, heldRunHook, haltReactivity, GlobalQueue } from
|
|
|
26
26
|
// staged); the flush's commit replays this effect. Its first run is not this
|
|
27
27
|
// creation's (A29). A lane's node likewise: its run is the lane's, queued
|
|
28
28
|
// by the pass and released at the reveal (lanes.ts).
|
|
29
|
-
!r?.defer && E.
|
|
29
|
+
!r?.defer && E.ue === NOT_PENDING && !E.T?.Je?.V && (E.i === EFFECT_USER || r?.schedule ? globalQueue.enqueue(E.i, runEffect.bind(null, E)) : // Type 0: the synchronous first render, not a queued run (D-19).
|
|
30
|
+
runEffect(E, 0));
|
|
30
31
|
}
|
|
31
32
|
|
|
32
33
|
function notifyEffectStatus() {
|
|
33
34
|
const t = this.m;
|
|
34
|
-
const e = this.T?.
|
|
35
|
+
const e = this.T?.U;
|
|
35
36
|
if (t & STATUS_ERROR) {
|
|
36
37
|
globalQueue.notify(this, STATUS_PENDING, 0);
|
|
37
38
|
if (this.i === EFFECT_USER) {
|
|
@@ -48,18 +49,20 @@ function notifyEffectStatus() {
|
|
|
48
49
|
return;
|
|
49
50
|
}
|
|
50
51
|
// Dev locates the halt at the node that threw: the StatusError's
|
|
51
|
-
// source, upstream of this effect when a computed failed.
|
|
52
|
-
|
|
52
|
+
// source, upstream of this effect when a computed failed. The rethrow is
|
|
53
|
+
// the user's error, not the wrapper: the wrapper's `source` is a node, and
|
|
54
|
+
// a reporter that serializes the throw walks the reactive graph.
|
|
55
|
+
escalate(this, unwrapStatusError(e), this);
|
|
53
56
|
} else if (this.i === EFFECT_RENDER) {
|
|
54
57
|
globalQueue.notify(this, STATUS_PENDING | STATUS_ERROR, t, e);
|
|
55
58
|
}
|
|
56
59
|
}
|
|
57
60
|
|
|
58
61
|
/** An effect's error no boundary takes halts the system (boundary-or-halt):
|
|
59
|
-
* halted with `cause
|
|
62
|
+
* halted with `cause` and rethrown; dev locates it at `subject`. */ function escalate(t, e, o = t) {
|
|
60
63
|
if (!globalQueue.notify(t, STATUS_ERROR, STATUS_ERROR)) {
|
|
61
64
|
haltReactivity(e);
|
|
62
|
-
throw
|
|
65
|
+
throw e;
|
|
63
66
|
}
|
|
64
67
|
}
|
|
65
68
|
|
|
@@ -70,10 +73,12 @@ function runEffect(t, e) {
|
|
|
70
73
|
// effect's update too (maintainer, 2026-10-02: "we held the queue but let
|
|
71
74
|
// the sync renders through… we definitely shouldn't be showing portals
|
|
72
75
|
// early") — a Portal's or head-tag's render effect writes outside the
|
|
73
|
-
// hidden subtree. The synchronous first render on creation
|
|
74
|
-
// run and goes through
|
|
75
|
-
//
|
|
76
|
-
|
|
76
|
+
// hidden subtree. The synchronous first render on creation (`type` 0) is
|
|
77
|
+
// not a queued run and goes through, whichever boundary above is on its
|
|
78
|
+
// fallback then — an outer one about to reveal in this flush included
|
|
79
|
+
// (#4343). `_modified` stays set; the boundary re-queues the run
|
|
80
|
+
// (`release`).
|
|
81
|
+
if (e && heldRunHook?.(t)) return;
|
|
77
82
|
// Error arm (#2840), user effects only: a compute-phase error that is still
|
|
78
83
|
// the node's settled state at effect time runs the bundle's error handler in
|
|
79
84
|
// this same imperative, writable scope. Unwrap the StatusError used for
|
|
@@ -85,13 +90,13 @@ function runEffect(t, e) {
|
|
|
85
90
|
// notifyEffectStatus, and a runner queued by an earlier valueChanged in the
|
|
86
91
|
// same flush must not be hijacked by a later-arriving error status.
|
|
87
92
|
if (t.m & STATUS_ERROR && t.i === EFFECT_USER) {
|
|
88
|
-
const e = unwrapStatusError(t.T?.
|
|
89
|
-
t.
|
|
93
|
+
const e = unwrapStatusError(t.T?.U);
|
|
94
|
+
t.It = t.le;
|
|
90
95
|
t.Qe = false;
|
|
91
96
|
try {
|
|
92
|
-
t.
|
|
93
|
-
const e = t.
|
|
94
|
-
t.
|
|
97
|
+
t.kt ? t.kt(e, () => {
|
|
98
|
+
const e = t.Vt;
|
|
99
|
+
t.Vt = undefined;
|
|
95
100
|
e?.();
|
|
96
101
|
}) : console.error(e);
|
|
97
102
|
} catch (e) {
|
|
@@ -101,26 +106,26 @@ function runEffect(t, e) {
|
|
|
101
106
|
}
|
|
102
107
|
// Captured before the callback: its own throw errors the node below, but
|
|
103
108
|
// the compute pass that produced `_value` was clean, so its tail still goes.
|
|
104
|
-
const o = t.T?.
|
|
109
|
+
const o = t.T?.U == null;
|
|
105
110
|
// Observe tier, like its `effectRunEnd` twin below: the frame the engine
|
|
106
111
|
// opens here is what stamps the callback's writes as the effect's (the
|
|
107
112
|
// cascade an observer reports) and what times the callback (the `effect`
|
|
108
113
|
// record) — facts a production observer needs, not only a dev console.
|
|
109
114
|
if (attrHooks !== null) attrHooks.effectRunStart(t);
|
|
110
|
-
const r = t.
|
|
111
|
-
t.
|
|
115
|
+
const r = t.Vt;
|
|
116
|
+
t.Vt = undefined;
|
|
112
117
|
try {
|
|
113
118
|
r?.();
|
|
114
|
-
const e = t.Ge(t.le, t.
|
|
119
|
+
const e = t.Ge(t.le, t.It);
|
|
115
120
|
if (false && e !== undefined && typeof e !== "function") ;
|
|
116
121
|
// The final cleanup is invoked by disposeChildren at true disposal.
|
|
117
|
-
t.
|
|
122
|
+
t.Vt = e;
|
|
118
123
|
} catch (e) {
|
|
119
|
-
ext(t).
|
|
124
|
+
ext(t).U = new StatusError(t, e);
|
|
120
125
|
t.m |= STATUS_ERROR;
|
|
121
126
|
escalate(t, e);
|
|
122
127
|
} finally {
|
|
123
|
-
t.
|
|
128
|
+
t.It = t.le;
|
|
124
129
|
t.Qe = false;
|
|
125
130
|
// The run applied: this is the frame now, so the dependency tail the
|
|
126
131
|
// compute pass left linked goes (A30, #3438 — `recompute` defers an
|
|
@@ -134,7 +139,7 @@ function runEffect(t, e) {
|
|
|
134
139
|
if (attrHooks !== null) attrHooks.effectRunEnd(t);
|
|
135
140
|
}
|
|
136
141
|
|
|
137
|
-
GlobalQueue.
|
|
142
|
+
GlobalQueue.q = runEffect;
|
|
138
143
|
|
|
139
144
|
/**
|
|
140
145
|
* Internal tracked effect - bypasses heap, goes directly to effect queue.
|
|
@@ -153,16 +158,16 @@ GlobalQueue.K = runEffect;
|
|
|
153
158
|
} finally {}
|
|
154
159
|
};
|
|
155
160
|
const o = computed(() => {
|
|
156
|
-
const e = o.
|
|
157
|
-
o.
|
|
161
|
+
const e = o.Vt;
|
|
162
|
+
o.Vt = undefined;
|
|
158
163
|
e?.();
|
|
159
164
|
const r = staleValues(t);
|
|
160
|
-
o.
|
|
165
|
+
o.Vt = r;
|
|
161
166
|
}, {
|
|
162
167
|
...e,
|
|
163
168
|
lazy: true
|
|
164
169
|
});
|
|
165
|
-
o.
|
|
170
|
+
o.Vt = undefined;
|
|
166
171
|
o.l = o.l & ~CONFIG_AUTO_DISPOSE | CONFIG_CHILDREN_FORBIDDEN;
|
|
167
172
|
o.Qe = true;
|
|
168
173
|
o.i = EFFECT_TRACKED;
|
|
@@ -21,7 +21,7 @@ function unlinkSubs(e) {
|
|
|
21
21
|
const l = e.G;
|
|
22
22
|
const o = e.t;
|
|
23
23
|
const s = e.en;
|
|
24
|
-
if (o !== null) o.en = s; else n.
|
|
24
|
+
if (o !== null) o.en = s; else n.Ot = s;
|
|
25
25
|
if (s !== null) s.t = o; else {
|
|
26
26
|
n.o = o;
|
|
27
27
|
if (o === null) {
|
|
@@ -29,7 +29,7 @@ function unlinkSubs(e) {
|
|
|
29
29
|
// unobserved closure, no NodeExtension to hold it.
|
|
30
30
|
// A user hook that throws is collected like a cleanup (owner.ts): the
|
|
31
31
|
// unlink and the teardown around it carry on.
|
|
32
|
-
if (n.l & CONFIG_SLOT_NODE) slotUnobservedHook(n); else if (n.T?.
|
|
32
|
+
if (n.l & CONFIG_SLOT_NODE) slotUnobservedHook(n); else if (n.T?.Gt) runCleanup(n.T.Gt);
|
|
33
33
|
// No more subscribers; only tear down if CONFIG_AUTO_DISPOSE is set.
|
|
34
34
|
// A pending node is exempt: its in-flight async work is an observer —
|
|
35
35
|
// tearing down would orphan the work and re-execute it on the next
|
|
@@ -133,7 +133,7 @@ function link(e, n) {
|
|
|
133
133
|
if (s) {
|
|
134
134
|
o = l !== null ? l.G : n.C;
|
|
135
135
|
if (o !== null && o.S === e) {
|
|
136
|
-
o.
|
|
136
|
+
o.de = n.Ne;
|
|
137
137
|
n._ = o;
|
|
138
138
|
return;
|
|
139
139
|
}
|
|
@@ -143,15 +143,15 @@ function link(e, n) {
|
|
|
143
143
|
// [deps.._depsTail] prefix — the O(1) equivalent of scanning the dep list
|
|
144
144
|
// (the old alien-signals `isValidLink` walk, O(n²) when a computation
|
|
145
145
|
// re-reads earlier deps non-consecutively, e.g. store leaf reads).
|
|
146
|
-
const r = e.
|
|
147
|
-
if (r !== null && r.u === n && (!s || r.
|
|
148
|
-
const t = n._ = e.
|
|
146
|
+
const r = e.Ot;
|
|
147
|
+
if (r !== null && r.u === n && (!s || r.de === n.Ne)) return;
|
|
148
|
+
const t = n._ = e.Ot = {
|
|
149
149
|
S: e,
|
|
150
150
|
u: n,
|
|
151
151
|
G: o,
|
|
152
152
|
en: r,
|
|
153
153
|
t: null,
|
|
154
|
-
|
|
154
|
+
de: n.Ne
|
|
155
155
|
};
|
|
156
156
|
if (l !== null) l.G = t; else n.C = t;
|
|
157
157
|
if (r !== null) r.t = t; else e.o = t;
|
|
@@ -11,22 +11,22 @@ import { dirtyQueue } from "./scheduler.js";
|
|
|
11
11
|
* callback to the user queue once the pass has committed (see
|
|
12
12
|
* GlobalQueue._update, #3291).
|
|
13
13
|
*/ function enqueueSub(e) {
|
|
14
|
-
if (dirtyQueue.
|
|
14
|
+
if (dirtyQueue.Et > e.lt) dirtyQueue.Et = e.lt;
|
|
15
15
|
insertIntoHeap(e, dirtyQueue);
|
|
16
16
|
}
|
|
17
17
|
|
|
18
18
|
function actualInsertIntoHeap(e, t) {
|
|
19
|
-
const E = (e._parent?.Pt ? e._parent.
|
|
20
|
-
if (E >= e.
|
|
21
|
-
const n = e.
|
|
22
|
-
const I = t.
|
|
23
|
-
if (I === undefined) t.
|
|
24
|
-
const t = I.
|
|
25
|
-
t.
|
|
26
|
-
e.
|
|
27
|
-
I.
|
|
19
|
+
const E = (e._parent?.Pt ? e._parent.Ht?.lt : e._parent?.lt) ?? -1;
|
|
20
|
+
if (E >= e.lt) e.lt = E + 1;
|
|
21
|
+
const n = e.lt;
|
|
22
|
+
const I = t.jt[n];
|
|
23
|
+
if (I === undefined) t.jt[n] = e; else {
|
|
24
|
+
const t = I.Ct;
|
|
25
|
+
t.Rt = e;
|
|
26
|
+
e.Ct = t;
|
|
27
|
+
I.Ct = e;
|
|
28
28
|
}
|
|
29
|
-
if (n > t.
|
|
29
|
+
if (n > t.yt) t.yt = n;
|
|
30
30
|
}
|
|
31
31
|
|
|
32
32
|
function insertIntoHeap(e, t) {
|
|
@@ -65,23 +65,23 @@ function deleteFromHeap(e, t) {
|
|
|
65
65
|
const E = e.R;
|
|
66
66
|
if (!(E & (REACTIVE_IN_HEAP | REACTIVE_IN_HEAP_HEIGHT))) return;
|
|
67
67
|
e.R = E & -25;
|
|
68
|
-
const n = e.
|
|
69
|
-
if (e.
|
|
70
|
-
const E = e.
|
|
71
|
-
const I = t.
|
|
68
|
+
const n = e.lt;
|
|
69
|
+
if (e.Ct === e) t.jt[n] = undefined; else {
|
|
70
|
+
const E = e.Rt;
|
|
71
|
+
const I = t.jt[n];
|
|
72
72
|
const i = E ?? I;
|
|
73
|
-
if (e === I) t.
|
|
74
|
-
i.
|
|
73
|
+
if (e === I) t.jt[n] = E; else e.Ct.Rt = E;
|
|
74
|
+
i.Ct = e.Ct;
|
|
75
75
|
}
|
|
76
|
-
e.
|
|
77
|
-
e.
|
|
76
|
+
e.Ct = e;
|
|
77
|
+
e.Rt = undefined;
|
|
78
78
|
}
|
|
79
79
|
|
|
80
80
|
function markHeap(e) {
|
|
81
81
|
if (e.p) return;
|
|
82
82
|
e.p = true;
|
|
83
|
-
for (let t = 0; t <= e.
|
|
84
|
-
for (let E = e.
|
|
83
|
+
for (let t = 0; t <= e.yt; t++) {
|
|
84
|
+
for (let E = e.jt[t]; E !== undefined; E = E.Rt) {
|
|
85
85
|
if (E.R & REACTIVE_IN_HEAP) markNode(E);
|
|
86
86
|
}
|
|
87
87
|
}
|
|
@@ -98,25 +98,25 @@ function markNode(e, t = REACTIVE_DIRTY) {
|
|
|
98
98
|
|
|
99
99
|
function runHeap(e, t) {
|
|
100
100
|
e.p = false;
|
|
101
|
-
for (e.
|
|
102
|
-
let E = e.
|
|
101
|
+
for (e.Et = 0; e.Et <= e.yt; e.Et++) {
|
|
102
|
+
let E = e.jt[e.Et];
|
|
103
103
|
while (E !== undefined) {
|
|
104
104
|
if (E.R & REACTIVE_IN_HEAP) t(E); else adjustHeight(E, e);
|
|
105
|
-
E = e.
|
|
105
|
+
E = e.jt[e.Et];
|
|
106
106
|
}
|
|
107
107
|
}
|
|
108
|
-
e.
|
|
108
|
+
e.yt = 0;
|
|
109
109
|
}
|
|
110
110
|
|
|
111
111
|
function adjustHeight(e, t) {
|
|
112
112
|
deleteFromHeap(e, t);
|
|
113
|
-
let E = e.
|
|
113
|
+
let E = e.lt;
|
|
114
114
|
for (let t = e.C; t; t = t.G) {
|
|
115
115
|
const e = t.S;
|
|
116
|
-
if (e.X && e.
|
|
116
|
+
if (e.X && e.lt >= E) E = e.lt + 1;
|
|
117
117
|
}
|
|
118
|
-
if (e.
|
|
119
|
-
e.
|
|
118
|
+
if (e.lt !== E) {
|
|
119
|
+
e.lt = E;
|
|
120
120
|
for (let E = e.o; E !== null; E = E.t) insertIntoHeapHeight(E.u, t);
|
|
121
121
|
}
|
|
122
122
|
}
|