@solidjs/signals 2.0.0-rc.15 → 2.0.0-rc.16
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 +785 -367
- package/dist/dev.attribution.js +75 -52
- package/dist/dev.js +1120 -567
- package/dist/observe/affects-marks.js +86 -0
- package/dist/observe/affects.js +22 -73
- package/dist/observe/boundaries.js +191 -189
- package/dist/observe/core/async.js +175 -131
- package/dist/observe/core/attribution-queries.js +1 -1
- package/dist/observe/core/attribution.js +176 -159
- package/dist/observe/core/constants.js +17 -3
- package/dist/observe/core/context.js +3 -3
- package/dist/observe/core/core.js +503 -363
- package/dist/observe/core/dev.js +66 -38
- package/dist/observe/core/effect.js +48 -48
- package/dist/observe/core/error.js +5 -3
- package/dist/observe/core/external.js +5 -6
- package/dist/observe/core/graph.js +57 -43
- package/dist/observe/core/heap.js +33 -33
- package/dist/observe/core/identities.js +62 -0
- package/dist/observe/core/lanes.js +226 -259
- package/dist/observe/core/owner.js +62 -50
- package/dist/observe/core/scheduler.js +319 -171
- package/dist/observe/core/truth.js +45 -0
- package/dist/observe/core/verdict.js +88 -50
- package/dist/observe/deferred.js +184 -0
- package/dist/observe/index.js +7 -1
- package/dist/observe/map.js +345 -260
- package/dist/observe/reveal.js +76 -76
- package/dist/observe/signals.js +41 -30
- package/dist/observe/store/affects.js +6 -6
- package/dist/observe/store/edges.js +39 -0
- package/dist/observe/store/optimistic.js +41 -36
- package/dist/observe/store/projection.js +68 -55
- package/dist/observe/store/store.js +157 -104
- package/dist/prod/affects-marks.js +86 -0
- package/dist/prod/affects.js +23 -72
- package/dist/prod/boundaries.js +155 -153
- package/dist/prod/core/async.js +171 -127
- package/dist/prod/core/constants.js +17 -3
- package/dist/prod/core/context.js +3 -3
- package/dist/prod/core/core.js +478 -342
- package/dist/prod/core/effect.js +68 -68
- package/dist/prod/core/error.js +5 -3
- package/dist/prod/core/external.js +5 -6
- package/dist/prod/core/graph.js +57 -43
- package/dist/prod/core/heap.js +38 -38
- package/dist/prod/core/identities.js +62 -0
- package/dist/prod/core/lanes.js +217 -250
- package/dist/prod/core/owner.js +62 -51
- package/dist/prod/core/scheduler.js +310 -162
- package/dist/prod/core/truth.js +45 -0
- package/dist/prod/core/verdict.js +87 -49
- package/dist/prod/deferred.js +182 -0
- package/dist/prod/index.js +7 -1
- package/dist/prod/map.js +360 -275
- package/dist/prod/reveal.js +76 -76
- package/dist/prod/signals.js +41 -30
- package/dist/prod/store/affects.js +6 -6
- package/dist/prod/store/edges.js +39 -0
- package/dist/prod/store/optimistic.js +37 -33
- package/dist/prod/store/projection.js +25 -19
- package/dist/prod/store/store.js +142 -96
- package/dist/types/affects-marks.d.ts +14 -0
- package/dist/types/boundaries.d.ts +1 -1
- package/dist/types/core/async.d.ts +10 -0
- package/dist/types/core/constants.d.ts +13 -1
- package/dist/types/core/core.d.ts +44 -2
- package/dist/types/core/dev.d.ts +43 -13
- package/dist/types/core/graph.d.ts +11 -0
- package/dist/types/core/identities.d.ts +17 -0
- package/dist/types/core/index.d.ts +2 -1
- package/dist/types/core/lanes.d.ts +2 -14
- package/dist/types/core/owner.d.ts +5 -3
- package/dist/types/core/scheduler.d.ts +47 -28
- package/dist/types/core/truth.d.ts +16 -0
- package/dist/types/core/types.d.ts +21 -0
- package/dist/types/core/verdict.d.ts +32 -0
- package/dist/types/deferred.d.ts +28 -0
- package/dist/types/index.d.ts +6 -0
- package/dist/types/map.d.ts +2 -2
- package/dist/types/signals.d.ts +28 -7
- package/dist/types/store/edges.d.ts +9 -0
- package/dist/types/store/index.d.ts +10 -3
- package/dist/types/store/optimistic.d.ts +3 -2
- package/dist/types/store/projection.d.ts +4 -3
- package/dist/types/store/store.d.ts +1 -1
- package/dist/types/store/target.d.ts +16 -8
- package/dist/types/store/types.d.ts +14 -0
- package/package.json +1 -1
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
import { CONFIG_VERDICT, CONFIG_AUTHORITATIVE, STATUS_ERROR, CONFIG_SLOT_NODE, REACTIVE_RECOMPUTING_DEPS } from "./core/constants.js";
|
|
2
|
+
|
|
3
|
+
import { ext } from "./core/core.js";
|
|
4
|
+
|
|
5
|
+
import { enqueueSub } from "./core/heap.js";
|
|
6
|
+
|
|
7
|
+
import { GlobalQueue } from "./core/scheduler.js";
|
|
8
|
+
|
|
9
|
+
// The mark core: a declared not-final state on a node that reads pending
|
|
10
|
+
// (`isPending` → true) on the node and everything derived from it, without
|
|
11
|
+
// holding anything or entangling a reader. Two declarers share it:
|
|
12
|
+
// `affects()` (affects.ts — a mark scoped to a transaction, with a store
|
|
13
|
+
// half) and `createDeferred` (deferred.ts — a mark whose lifetime is the
|
|
14
|
+
// node's own flight). Split out so the second does not ship the first.
|
|
15
|
+
// Representation: a count on the marked node (`_x._marks`). Coverage of the
|
|
16
|
+
// derivations is pull-derived at probe time — `isPending`'s read walks the
|
|
17
|
+
// probed node's dependencies for a marked one (verdict.ts → `_marked`) — so
|
|
18
|
+
// nothing is stored downstream and a mid-window recompute strands nothing.
|
|
19
|
+
// The push half is the verdict readers' re-derivation when a node's marks
|
|
20
|
+
// start and end (`repoll`): the only notification a mark makes.
|
|
21
|
+
/** Live marks, every declarer — the gate on the probe's walk. */
|
|
22
|
+
let active = 0;
|
|
23
|
+
|
|
24
|
+
/** The verdict readers downstream of `node` — through derivations, stopping
|
|
25
|
+
* at effects — re-derive: the mark's one notification (a probe's answer
|
|
26
|
+
* changed with no value notifying anyone). Truth readers (`until`, the
|
|
27
|
+
* `refresh` waiter) too, which a lagging flight parked (deferred.ts) — but
|
|
28
|
+
* not through a derived store, whose leaves change only once its derive
|
|
29
|
+
* re-runs: they re-derive at that write. */ function repoll(e, r = new Set, o = CONFIG_VERDICT | CONFIG_AUTHORITATIVE) {
|
|
30
|
+
for (let t = e.o; t !== null; t = t.t) {
|
|
31
|
+
const e = t.u;
|
|
32
|
+
if (r.has(e)) continue;
|
|
33
|
+
r.add(e);
|
|
34
|
+
if (e.l & o) enqueueSub(e);
|
|
35
|
+
if (!e.i) repoll(e, r, o);
|
|
36
|
+
// A derived store's derive: its leaves' readers derive from it too
|
|
37
|
+
// (store/projection.ts; a live target's property, has and keys nodes).
|
|
38
|
+
const n = e.fam;
|
|
39
|
+
if (n) for (const e of n.live) for (const o of [ e.n, e.h, {
|
|
40
|
+
k: e.k,
|
|
41
|
+
d: e.dk
|
|
42
|
+
} ]) if (o) for (const e of Reflect.ownKeys(o)) o[e] && repoll(o[e], r, CONFIG_VERDICT);
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
/** A node is covered by a live mark iff it carries one, or derives — through
|
|
47
|
+
* its current dependencies — from one that does. A store slot derives from
|
|
48
|
+
* its family's derive (a derived store's leaves are not the derive's
|
|
49
|
+
* dependents, store/projection.ts), so coverage hops there. A real error
|
|
50
|
+
* outranks an inherited mark (A24 (c)): coverage does not flow through an
|
|
51
|
+
* errored node (a direct mark on one still reads pending). Mid-recompute,
|
|
52
|
+
* only the validated prefix of the dependency list is this pass's. */ function marked(e, r) {
|
|
53
|
+
if (e.T !== null && e.T.I !== 0) return true;
|
|
54
|
+
const o = e;
|
|
55
|
+
if (o.m & STATUS_ERROR || r.has(e)) return false;
|
|
56
|
+
r.add(e);
|
|
57
|
+
if (o.l & CONFIG_SLOT_NODE) {
|
|
58
|
+
const e = o.O?.fam?.node;
|
|
59
|
+
return e != null && marked(e, r);
|
|
60
|
+
}
|
|
61
|
+
const t = o.R & REACTIVE_RECOMPUTING_DEPS ? o._ : undefined;
|
|
62
|
+
if (t !== null) for (let e = o.C ?? null; e !== null; e = e.G) {
|
|
63
|
+
if (marked(e.S, r)) return true;
|
|
64
|
+
if (e === t) break;
|
|
65
|
+
}
|
|
66
|
+
return false;
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
/** One mark on `node`. The declarer repolls once its bookkeeping is done. */ function mark(e) {
|
|
70
|
+
ext(e).I++;
|
|
71
|
+
active++;
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
/** Drops one mark from `node`: true when it was the last — the node's
|
|
75
|
+
* verdict readers have re-derived. */ function unmark(e) {
|
|
76
|
+
active--;
|
|
77
|
+
if (--e.T.I !== 0) return false;
|
|
78
|
+
repoll(e);
|
|
79
|
+
return true;
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
GlobalQueue.p = e => active !== 0 && marked(e, new Set);
|
|
83
|
+
|
|
84
|
+
GlobalQueue.N = mark;
|
|
85
|
+
|
|
86
|
+
export { mark, repoll, unmark };
|
package/dist/prod/affects.js
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
import { $REFRESH,
|
|
1
|
+
import { $REFRESH, STATUS_PENDING, CONFIG_SLOT_NODE } from "./core/constants.js";
|
|
2
2
|
|
|
3
|
-
import
|
|
3
|
+
import "./core/core.js";
|
|
4
4
|
|
|
5
|
-
import {
|
|
5
|
+
import { schedule, resolveTx, flushTransaction, installMarkHooks, GlobalQueue } from "./core/scheduler.js";
|
|
6
6
|
|
|
7
|
-
import {
|
|
7
|
+
import { mark, repoll, unmark } from "./affects-marks.js";
|
|
8
8
|
|
|
9
9
|
import { storeMarks, installStoreAffects, releaseMarkScope } from "./store/affects.js";
|
|
10
10
|
|
|
@@ -21,60 +21,22 @@ import { $TARGET } from "./store/types.js";
|
|
|
21
21
|
// a node of its transaction (`blocked` never sees it), and a reader of marked
|
|
22
22
|
// data joins nothing through it. A mark is never a re-ask, so a declared
|
|
23
23
|
// reload's own `refresh()` cannot silence it; a real error outranks it.
|
|
24
|
-
// Representation:
|
|
25
|
-
//
|
|
26
|
-
//
|
|
27
|
-
//
|
|
28
|
-
// nothing is stored downstream and a mid-window recompute strands nothing.
|
|
29
|
-
// The push half is the verdict readers' re-derivation at registration and at
|
|
30
|
-
// release (`repoll`): the only notification a mark makes.
|
|
24
|
+
// Representation: the mark core (affects-marks.ts) — a count on the marked
|
|
25
|
+
// node, coverage pull-derived at probe time, readers repolled at registration
|
|
26
|
+
// and release. Here: each mark's scope (the transaction's `_marks`, or the
|
|
27
|
+
// ambient list) and the store half.
|
|
31
28
|
// Installed on `GlobalQueue` when imported: a program that never declares a
|
|
32
29
|
// mark carries none of this.
|
|
33
|
-
/**
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
/** Marks declared outside a transaction: released at the next seam. */ const ambient = [];
|
|
37
|
-
|
|
38
|
-
/** The verdict readers downstream of `node` — through derivations, stopping
|
|
39
|
-
* at effects — re-derive: the mark's one notification (a probe's answer
|
|
40
|
-
* changed with no value notifying anyone). */ function repoll(e, t = new Set) {
|
|
41
|
-
for (let r = e.t; r !== null; r = r.o) {
|
|
42
|
-
const e = r.l;
|
|
43
|
-
if (t.has(e)) continue;
|
|
44
|
-
t.add(e);
|
|
45
|
-
if (e.i & CONFIG_VERDICT) enqueueSub(e);
|
|
46
|
-
if (!e.u) repoll(e, t);
|
|
47
|
-
}
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
/** A node is covered by a live mark iff it carries one, or derives — through
|
|
51
|
-
* its current dependencies — from one that does. A real error outranks an
|
|
52
|
-
* inherited mark (A24 (c)): coverage does not flow through an errored node
|
|
53
|
-
* (a direct mark on one still reads pending). Mid-recompute, only the
|
|
54
|
-
* validated prefix of the dependency list is this pass's. */ function marked(e, t) {
|
|
55
|
-
if (e.m !== null && e.m.T !== 0) return true;
|
|
56
|
-
const r = e;
|
|
57
|
-
if (r.S & STATUS_ERROR || t.has(e)) return false;
|
|
58
|
-
t.add(e);
|
|
59
|
-
const n = r.R & REACTIVE_RECOMPUTING_DEPS ? r.G : undefined;
|
|
60
|
-
if (n !== null) for (let e = r.p ?? null; e !== null; e = e._) {
|
|
61
|
-
if (marked(e.I, t)) return true;
|
|
62
|
-
if (e === n) break;
|
|
63
|
-
}
|
|
64
|
-
return false;
|
|
65
|
-
}
|
|
30
|
+
/** Marks declared outside a transaction: released at the next seam. */
|
|
31
|
+
const ambient = [];
|
|
66
32
|
|
|
67
33
|
/** Releases one scope's marks (a landed transaction's, the ambient list at
|
|
68
34
|
* the seam): a node whose last mark drops re-derives its verdict readers. */ function release(e) {
|
|
69
35
|
for (let t = 0; t < e.length; t++) {
|
|
70
36
|
const r = e[t];
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
// A store mark's carrier: its scope (and the marks the nodes born in
|
|
75
|
-
// its window inherited) goes with it.
|
|
76
|
-
releaseMarkScope(r);
|
|
77
|
-
}
|
|
37
|
+
// A store mark's carrier: its scope (and the marks the nodes born in
|
|
38
|
+
// its window inherited) goes with the last mark.
|
|
39
|
+
if (unmark(r)) releaseMarkScope(r);
|
|
78
40
|
}
|
|
79
41
|
e.length = 0;
|
|
80
42
|
}
|
|
@@ -85,16 +47,11 @@ let active = 0;
|
|
|
85
47
|
const t = flushTransaction;
|
|
86
48
|
if (t === null) ambient.push(e); else {
|
|
87
49
|
const r = resolveTx(t);
|
|
88
|
-
(r.
|
|
50
|
+
(r.I ??= []).push(e);
|
|
89
51
|
}
|
|
90
52
|
repoll(e);
|
|
91
53
|
}
|
|
92
54
|
|
|
93
|
-
function mark(e) {
|
|
94
|
-
ext(e).T++;
|
|
95
|
-
active++;
|
|
96
|
-
}
|
|
97
|
-
|
|
98
55
|
function affects(e, t) {
|
|
99
56
|
// A store (the store half, store/affects.ts): the slot's leaf, or the
|
|
100
57
|
// record's carrier and every live node under it.
|
|
@@ -106,26 +63,20 @@ function affects(e, t) {
|
|
|
106
63
|
schedule();
|
|
107
64
|
return;
|
|
108
65
|
}
|
|
109
|
-
const
|
|
110
|
-
if (!
|
|
66
|
+
const s = e?.[$REFRESH];
|
|
67
|
+
if (!s) {
|
|
111
68
|
return;
|
|
112
69
|
}
|
|
113
|
-
register(
|
|
70
|
+
register(s);
|
|
114
71
|
schedule();
|
|
115
72
|
}
|
|
116
73
|
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
GlobalQueue.O = mark;
|
|
120
|
-
|
|
121
|
-
GlobalQueue.k = release;
|
|
122
|
-
|
|
123
|
-
GlobalQueue.A = e => {
|
|
74
|
+
installMarkHooks(release, e => {
|
|
124
75
|
if (ambient.length === 0) return;
|
|
125
76
|
// The flush parked: the declaration's window is the frame's — the marks
|
|
126
77
|
// are its transaction's ("nothing async below ⇒ no window").
|
|
127
78
|
if (e !== null) {
|
|
128
|
-
const t = e.
|
|
79
|
+
const t = e.I ??= [];
|
|
129
80
|
for (let e = 0; e < ambient.length; e++) t.push(ambient[e]);
|
|
130
81
|
ambient.length = 0;
|
|
131
82
|
return;
|
|
@@ -137,15 +88,15 @@ GlobalQueue.A = e => {
|
|
|
137
88
|
let t = 0;
|
|
138
89
|
const r = [];
|
|
139
90
|
for (let e = 0; e < ambient.length; e++) {
|
|
140
|
-
const
|
|
141
|
-
if (inFlight(
|
|
91
|
+
const s = ambient[e];
|
|
92
|
+
if (inFlight(s)) ambient[t++] = s; else r.push(s);
|
|
142
93
|
}
|
|
143
94
|
ambient.length = t;
|
|
144
95
|
if (r.length !== 0) release(r);
|
|
145
|
-
};
|
|
96
|
+
});
|
|
146
97
|
|
|
147
98
|
function inFlight(e) {
|
|
148
|
-
return (e.
|
|
99
|
+
return (e.m & STATUS_PENDING) !== 0 || (e.l & CONFIG_SLOT_NODE) !== 0 && GlobalQueue.k?.(e) === true;
|
|
149
100
|
}
|
|
150
101
|
|
|
151
102
|
export { affects };
|