@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
|
@@ -0,0 +1,182 @@
|
|
|
1
|
+
import { isThenable } from "./async.js";
|
|
2
|
+
|
|
3
|
+
import "./core.js";
|
|
4
|
+
|
|
5
|
+
import "./dev.js";
|
|
6
|
+
|
|
7
|
+
import { joinFuture, newTransaction, enterAction, exitAction, resolveTx, schedule, actionDepth, flush, nextQuestion, setQuestion, question } from "./scheduler.js";
|
|
8
|
+
|
|
9
|
+
import { attrHooks } from "./attribution-hooks.js";
|
|
10
|
+
|
|
11
|
+
/** A slice of the body runs in the action's transaction: the flush that
|
|
12
|
+
* carries its writes parks into it (`joinFuture` — merging whatever the tick
|
|
13
|
+
* already joined: O1, an action that opens in a tick owns it; a second
|
|
14
|
+
* action in the tick, or one called from the body, merges into the first).
|
|
15
|
+
* A resumed slice drains at once: the seam parks what it wrote (the action
|
|
16
|
+
* holds the transaction open) or, the body having returned, lands it. A
|
|
17
|
+
* nested action resuming synchronously inside the outer body does not drain
|
|
18
|
+
* — that would park the outer's remaining writes' frame mid-slice; the outer
|
|
19
|
+
* step's own return does. */ function inTransaction(t, n, e) {
|
|
20
|
+
// The slice and its flush ask this action's question (A18 provenance):
|
|
21
|
+
// the guesses it writes and the flights it starts are stamped with it.
|
|
22
|
+
const o = question;
|
|
23
|
+
setQuestion(n);
|
|
24
|
+
joinFuture(t);
|
|
25
|
+
const i = e();
|
|
26
|
+
if (actionDepth === 0) flush();
|
|
27
|
+
setQuestion(o);
|
|
28
|
+
return i;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
/**
|
|
32
|
+
* The primitive for mutations: imperative async workflows whose *writes span
|
|
33
|
+
* an async gap* — optimistic write, server round-trip, reconciling write —
|
|
34
|
+
* where intermediate state must not leak and failure must revert cleanly
|
|
35
|
+
* (pair with `createOptimistic` / `createOptimisticStore`).
|
|
36
|
+
*
|
|
37
|
+
* Navigation-shaped updates do not need an action. A plain setter call is
|
|
38
|
+
* enough: reads pull the async, and downstream async computeds hold their
|
|
39
|
+
* previous values per-node until the new ones are ready (`isPending` /
|
|
40
|
+
* `latest` expose the in-flight state). Reach for `action` only when writes
|
|
41
|
+
* happen *after* async work, not merely upstream of it.
|
|
42
|
+
*
|
|
43
|
+
* Framework-level actions (router form actions, server actions) are
|
|
44
|
+
* specializations of this primitive: they are actions in exactly this sense —
|
|
45
|
+
* the same transactional semantics — with form binding, serialization, and
|
|
46
|
+
* submission tracking layered on top. The shared name is deliberate.
|
|
47
|
+
*
|
|
48
|
+
* Wraps a generator function so each invocation runs as a single transaction
|
|
49
|
+
* that holds every signal/store write between yields. The surrounding UI sees
|
|
50
|
+
* one atomic update when the action completes; nothing is committed until
|
|
51
|
+
* every action in the transaction has returned.
|
|
52
|
+
*
|
|
53
|
+
* `yield` is the transaction-safe suspension point: the action waits for a
|
|
54
|
+
* yielded promise and re-enters the transaction before running the code after
|
|
55
|
+
* it. A plain `await` does NOT — the runtime has no hook into an async
|
|
56
|
+
* generator's internal await continuations, so code between an `await` and
|
|
57
|
+
* the next `yield` runs OUTSIDE the transaction: writes to fresh signals
|
|
58
|
+
* commit immediately, and anything that creates a reader there — `until()`,
|
|
59
|
+
* `latest()`, a memo or effect, a mount — is created mainline, where a read of
|
|
60
|
+
* this action's held state makes it born held (A29): staged with the
|
|
61
|
+
* transaction and replayed at its commit. `await` is still the ergonomic
|
|
62
|
+
* choice for typed results; just put a bare `yield` before any write or
|
|
63
|
+
* reader creation that follows it — including the expression of the next
|
|
64
|
+
* `yield`, which is evaluated before the step re-enters:
|
|
65
|
+
*
|
|
66
|
+
* ```ts
|
|
67
|
+
* const saved = await api.createTodo(text); // typed result
|
|
68
|
+
* yield; // re-enter the transaction before writing or reading
|
|
69
|
+
* setTodos(t => { ... });
|
|
70
|
+
* yield until(() => todos.some(t => t.id === saved.id));
|
|
71
|
+
* ```
|
|
72
|
+
*
|
|
73
|
+
* The same holds inside an async helper the action yields
|
|
74
|
+
* (`yield (async () => { ... })()`): everything after its first `await` runs
|
|
75
|
+
* outside the transaction. An `await refresh(x)` or `await until(...)` there
|
|
76
|
+
* waits for this action's commit, which waits on the helper, so it hangs
|
|
77
|
+
* whenever `x` re-ran during the action (#4263) and works otherwise. Call
|
|
78
|
+
* `refresh(x)` in the generator once the helper returns; `yield` it only when
|
|
79
|
+
* the action needs the fresh value.
|
|
80
|
+
*
|
|
81
|
+
* (For the same reason, don't call `flush()` inside an action body — it
|
|
82
|
+
* cannot reveal the held writes and is refused.)
|
|
83
|
+
*
|
|
84
|
+
* Each call returns a `Promise` that resolves with the generator's return
|
|
85
|
+
* value, or rejects if it throws. Pair with `createOptimistic` /
|
|
86
|
+
* `createOptimisticStore` to apply tentative writes that auto-revert if the
|
|
87
|
+
* action fails.
|
|
88
|
+
*
|
|
89
|
+
* @example
|
|
90
|
+
* ```ts
|
|
91
|
+
* const [todos, setTodos] = createOptimisticStore<Todo[]>([]);
|
|
92
|
+
*
|
|
93
|
+
* const addTodo = action(async function* (text: string) {
|
|
94
|
+
* const tempId = crypto.randomUUID();
|
|
95
|
+
* setTodos(t => { t.push({ id: tempId, text, pending: true }); }); // optimistic
|
|
96
|
+
* const saved = await api.createTodo(text); // network round-trip, typed
|
|
97
|
+
* yield; // re-enter the transaction
|
|
98
|
+
* setTodos(t => {
|
|
99
|
+
* const i = t.findIndex(x => x.id === tempId);
|
|
100
|
+
* if (i >= 0) t[i] = saved;
|
|
101
|
+
* });
|
|
102
|
+
* return saved;
|
|
103
|
+
* });
|
|
104
|
+
*
|
|
105
|
+
* await addTodo("buy milk");
|
|
106
|
+
* ```
|
|
107
|
+
*/ function action(t) {
|
|
108
|
+
return (...n) => new Promise((e, o) => {
|
|
109
|
+
const i = t(...n);
|
|
110
|
+
// The action's transaction, held open until the body returns. The
|
|
111
|
+
// first slice's writes are carried by the tick's scheduled flush.
|
|
112
|
+
const r = newTransaction(false);
|
|
113
|
+
r.tt = 1;
|
|
114
|
+
r.nt = true;
|
|
115
|
+
const s = nextQuestion();
|
|
116
|
+
const done = (t, n, i = false) => {
|
|
117
|
+
resolveTx(r).tt--;
|
|
118
|
+
schedule();
|
|
119
|
+
i ? o(n) : e(t);
|
|
120
|
+
};
|
|
121
|
+
const step = (n, e) => {
|
|
122
|
+
let o;
|
|
123
|
+
// Attribution hooks bracket the synchronous slice of generator body
|
|
124
|
+
// this step runs (up to the next yield): writes inside are the
|
|
125
|
+
// action's. Both sites sit outside the try (attribution-hooks.ts).
|
|
126
|
+
if (attrHooks !== null) attrHooks.actionStepStart(i, t.name || undefined);
|
|
127
|
+
// The body is on the stack between these brackets: flush() is
|
|
128
|
+
// refused inside (FLUSH_IN_ACTION, scheduler.ts).
|
|
129
|
+
enterAction();
|
|
130
|
+
try {
|
|
131
|
+
o = e ? i.throw(n) : i.next(n);
|
|
132
|
+
} catch (t) {
|
|
133
|
+
exitAction();
|
|
134
|
+
if (attrHooks !== null) attrHooks.actionStepEnd(i);
|
|
135
|
+
return done(undefined, t, true);
|
|
136
|
+
}
|
|
137
|
+
exitAction();
|
|
138
|
+
if (attrHooks !== null) attrHooks.actionStepEnd(i);
|
|
139
|
+
// A rejected iterator result (async generators) means the error already
|
|
140
|
+
// escaped the generator body — it is completed, and throwing back in
|
|
141
|
+
// would just reject again forever. Settle instead.
|
|
142
|
+
if (isThenable(o)) return void o.then(run, t => done(undefined, t, true));
|
|
143
|
+
run(o);
|
|
144
|
+
};
|
|
145
|
+
const run = t => {
|
|
146
|
+
if (t.done) return done(t.value);
|
|
147
|
+
// Thenable assimilation can itself throw synchronously (a `then`
|
|
148
|
+
// getter, or a `then()` method that throws — #2918). Match `await`
|
|
149
|
+
// semantics: the failure is thrown back into the generator at the
|
|
150
|
+
// yield point (catchable there); if uncaught, step()'s guard settles
|
|
151
|
+
// the action. The settled flag implements A+ 2.3.3.3.4.1: a throw
|
|
152
|
+
// after the thenable already called a callback is ignored.
|
|
153
|
+
let n = false;
|
|
154
|
+
try {
|
|
155
|
+
if (isThenable(t.value)) return void t.value.then(t => {
|
|
156
|
+
if (n) return;
|
|
157
|
+
n = true;
|
|
158
|
+
inTransaction(r, s, () => step(t));
|
|
159
|
+
}, t => {
|
|
160
|
+
if (n) return;
|
|
161
|
+
n = true;
|
|
162
|
+
inTransaction(r, s, () => step(t, true));
|
|
163
|
+
});
|
|
164
|
+
} catch (t) {
|
|
165
|
+
if (n) return;
|
|
166
|
+
n = true;
|
|
167
|
+
return void inTransaction(r, s, () => step(t, true));
|
|
168
|
+
}
|
|
169
|
+
inTransaction(r, s, () => step(t.value));
|
|
170
|
+
};
|
|
171
|
+
// The first slice's writes are carried by the tick's scheduled flush;
|
|
172
|
+
// the slice itself asks the action's question (its guesses are stamped
|
|
173
|
+
// at the write).
|
|
174
|
+
joinFuture(r);
|
|
175
|
+
const u = question;
|
|
176
|
+
setQuestion(s);
|
|
177
|
+
step();
|
|
178
|
+
setQuestion(u);
|
|
179
|
+
});
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
export { action };
|