@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.
Files changed (198) hide show
  1. package/dist/dev-shared.js +6505 -0
  2. package/dist/dev.attribution.js +3484 -0
  3. package/dist/dev.js +10227 -9508
  4. package/dist/observe/affects-marks.js +86 -0
  5. package/dist/observe/affects.js +112 -0
  6. package/dist/observe/attribution.js +7 -0
  7. package/dist/observe/boundaries.js +696 -0
  8. package/dist/observe/core/action.js +182 -0
  9. package/dist/observe/core/async.js +824 -0
  10. package/dist/observe/core/attribution-costs.js +66 -0
  11. package/dist/observe/core/attribution-feedback.js +280 -0
  12. package/dist/observe/core/attribution-hooks.js +83 -0
  13. package/dist/observe/core/attribution-queries.js +43 -0
  14. package/dist/observe/core/attribution.js +3079 -0
  15. package/dist/observe/core/constants.js +269 -0
  16. package/dist/observe/core/context.js +63 -0
  17. package/dist/observe/core/copies.js +10 -0
  18. package/dist/observe/core/core.js +1707 -0
  19. package/dist/observe/core/dev.js +394 -0
  20. package/dist/observe/core/effect.js +193 -0
  21. package/dist/observe/core/error-hooks.js +71 -0
  22. package/dist/observe/core/error.js +82 -0
  23. package/dist/observe/core/external.js +97 -0
  24. package/dist/observe/core/graph.js +162 -0
  25. package/dist/observe/core/heap.js +124 -0
  26. package/dist/observe/core/identities.js +62 -0
  27. package/dist/observe/core/invariants.js +12 -0
  28. package/dist/observe/core/lanes.js +972 -0
  29. package/dist/observe/core/owner.js +371 -0
  30. package/dist/observe/core/scheduler.js +1157 -0
  31. package/dist/observe/core/truth.js +47 -0
  32. package/dist/observe/core/verdict.js +470 -0
  33. package/dist/observe/deferred.js +186 -0
  34. package/dist/observe/flatten.js +79 -0
  35. package/dist/observe/from.js +248 -0
  36. package/dist/observe/index.js +71 -0
  37. package/dist/observe/map.js +593 -0
  38. package/dist/observe/reveal.js +212 -0
  39. package/dist/observe/signals.js +717 -0
  40. package/dist/observe/store/affects.js +142 -0
  41. package/dist/observe/store/edges.js +39 -0
  42. package/dist/observe/store/hooks.js +16 -0
  43. package/dist/observe/store/index.js +47 -0
  44. package/dist/observe/store/optimistic.js +713 -0
  45. package/dist/observe/store/projection.js +345 -0
  46. package/dist/observe/store/reconcile.js +281 -0
  47. package/dist/observe/store/store.js +2127 -0
  48. package/dist/observe/store/storePath.js +103 -0
  49. package/dist/observe/store/target.js +46 -0
  50. package/dist/observe/store/types.js +83 -0
  51. package/dist/observe/store/utils.js +1063 -0
  52. package/dist/prod/affects-marks.js +86 -0
  53. package/dist/prod/affects.js +98 -112
  54. package/dist/prod/attribution.js +45 -0
  55. package/dist/prod/boundaries.js +578 -468
  56. package/dist/prod/core/action.js +92 -59
  57. package/dist/prod/core/async.js +522 -336
  58. package/dist/prod/core/attribution-hooks.js +3 -0
  59. package/dist/prod/core/constants.js +168 -44
  60. package/dist/prod/core/context.js +12 -16
  61. package/dist/prod/core/copies.js +10 -0
  62. package/dist/prod/core/core.js +1345 -627
  63. package/dist/prod/core/dev.js +123 -1
  64. package/dist/prod/core/effect.js +113 -80
  65. package/dist/prod/core/error-hooks.js +71 -0
  66. package/dist/prod/core/error.js +18 -4
  67. package/dist/prod/core/external.js +6 -7
  68. package/dist/prod/core/graph.js +119 -72
  69. package/dist/prod/core/heap.js +85 -109
  70. package/dist/prod/core/identities.js +62 -0
  71. package/dist/prod/core/invariants.js +1 -32
  72. package/dist/prod/core/lanes.js +931 -132
  73. package/dist/prod/core/owner.js +192 -129
  74. package/dist/prod/core/scheduler.js +948 -642
  75. package/dist/prod/core/truth.js +47 -0
  76. package/dist/prod/core/verdict.js +409 -420
  77. package/dist/prod/deferred.js +184 -0
  78. package/dist/prod/flatten.js +77 -0
  79. package/dist/prod/from.js +248 -0
  80. package/dist/prod/index.js +40 -16
  81. package/dist/prod/map.js +481 -211
  82. package/dist/prod/reveal.js +212 -0
  83. package/dist/prod/signals.js +401 -84
  84. package/dist/prod/store/affects.js +142 -0
  85. package/dist/prod/store/edges.js +39 -0
  86. package/dist/prod/store/hooks.js +16 -0
  87. package/dist/prod/store/index.js +27 -18
  88. package/dist/prod/store/optimistic.js +707 -0
  89. package/dist/prod/store/projection.js +331 -0
  90. package/dist/prod/store/reconcile.js +281 -0
  91. package/dist/prod/store/store.js +1952 -267
  92. package/dist/prod/store/storePath.js +1 -1
  93. package/dist/prod/store/target.js +43 -0
  94. package/dist/prod/store/types.js +83 -0
  95. package/dist/prod/store/utils.js +997 -138
  96. package/dist/types/affects-marks.d.ts +14 -0
  97. package/dist/types/affects.d.ts +12 -30
  98. package/dist/types/attribution.d.ts +19 -0
  99. package/dist/types/attribution.prod.d.ts +22 -0
  100. package/dist/types/boundaries.d.ts +99 -124
  101. package/dist/types/carved.d.ts +1 -0
  102. package/dist/types/core/action.d.ts +23 -9
  103. package/dist/types/core/async.d.ts +34 -6
  104. package/dist/types/core/attribution-costs.d.ts +35 -0
  105. package/dist/types/core/attribution-feedback.d.ts +133 -0
  106. package/dist/types/core/attribution-hooks.d.ts +307 -8
  107. package/dist/types/core/attribution-queries.d.ts +24 -0
  108. package/dist/types/core/attribution.d.ts +802 -72
  109. package/dist/types/core/constants.d.ts +195 -38
  110. package/dist/types/core/copies.d.ts +54 -0
  111. package/dist/types/core/core.d.ts +295 -65
  112. package/dist/types/core/dev.d.ts +509 -22
  113. package/dist/types/core/effect.d.ts +1 -1
  114. package/dist/types/core/error-hooks.d.ts +71 -0
  115. package/dist/types/core/error.d.ts +18 -1
  116. package/dist/types/core/graph.d.ts +40 -1
  117. package/dist/types/core/heap.d.ts +5 -5
  118. package/dist/types/core/identities.d.ts +17 -0
  119. package/dist/types/core/index.d.ts +11 -7
  120. package/dist/types/core/invariants.d.ts +1 -26
  121. package/dist/types/core/lanes.d.ts +74 -43
  122. package/dist/types/core/owner.d.ts +27 -9
  123. package/dist/types/core/scheduler.d.ts +353 -102
  124. package/dist/types/core/truth.d.ts +18 -0
  125. package/dist/types/core/types.d.ts +97 -71
  126. package/dist/types/core/verdict.d.ts +35 -0
  127. package/dist/types/deferred.d.ts +28 -0
  128. package/dist/types/flatten.d.ts +8 -0
  129. package/dist/types/from.d.ts +47 -0
  130. package/dist/types/index.d.ts +33 -7
  131. package/dist/types/map.d.ts +4 -2
  132. package/dist/types/reveal.d.ts +19 -0
  133. package/dist/types/signals.d.ts +196 -45
  134. package/dist/types/store/affects.d.ts +12 -0
  135. package/dist/types/store/edges.d.ts +9 -0
  136. package/dist/types/store/hooks.d.ts +62 -0
  137. package/dist/types/store/index.d.ts +42 -15
  138. package/dist/types/store/optimistic.d.ts +24 -45
  139. package/dist/types/store/projection.d.ts +17 -68
  140. package/dist/types/store/reconcile.d.ts +3 -46
  141. package/dist/types/store/store.d.ts +133 -136
  142. package/dist/types/store/storePath.d.ts +1 -1
  143. package/dist/types/store/target.d.ts +166 -0
  144. package/dist/types/store/types.d.ts +105 -0
  145. package/dist/types/store/utils.d.ts +188 -0
  146. package/package.json +31 -26
  147. package/dist/node.cjs +0 -8745
  148. package/dist/prod/core/optimistic.js +0 -265
  149. package/dist/prod/store/next/optimistic.js +0 -385
  150. package/dist/prod/store/next/projection.js +0 -172
  151. package/dist/prod/store/next/reconcile.js +0 -331
  152. package/dist/prod/store/next/store.js +0 -1499
  153. package/dist/prod/store/next/target.js +0 -20
  154. package/dist/types/core/optimistic.d.ts +0 -6
  155. package/dist/types/store/next/optimistic.d.ts +0 -20
  156. package/dist/types/store/next/projection.d.ts +0 -8
  157. package/dist/types/store/next/reconcile.d.ts +0 -3
  158. package/dist/types/store/next/store.d.ts +0 -77
  159. package/dist/types/store/next/target.d.ts +0 -117
  160. package/dist/types-cjs/affects.d.cts +0 -47
  161. package/dist/types-cjs/boundaries.d.cts +0 -175
  162. package/dist/types-cjs/core/action.d.cts +0 -64
  163. package/dist/types-cjs/core/async.d.cts +0 -21
  164. package/dist/types-cjs/core/attribution-hooks.d.cts +0 -52
  165. package/dist/types-cjs/core/attribution.d.cts +0 -186
  166. package/dist/types-cjs/core/constants.d.cts +0 -97
  167. package/dist/types-cjs/core/context.d.cts +0 -36
  168. package/dist/types-cjs/core/core.d.cts +0 -163
  169. package/dist/types-cjs/core/dev.d.cts +0 -81
  170. package/dist/types-cjs/core/effect.d.cts +0 -30
  171. package/dist/types-cjs/core/error.d.cts +0 -47
  172. package/dist/types-cjs/core/external.d.cts +0 -15
  173. package/dist/types-cjs/core/graph.d.cts +0 -6
  174. package/dist/types-cjs/core/heap.d.cts +0 -22
  175. package/dist/types-cjs/core/index.d.cts +0 -13
  176. package/dist/types-cjs/core/invariants.d.cts +0 -59
  177. package/dist/types-cjs/core/lanes.d.cts +0 -44
  178. package/dist/types-cjs/core/optimistic.d.cts +0 -6
  179. package/dist/types-cjs/core/owner.d.cts +0 -124
  180. package/dist/types-cjs/core/scheduler.d.cts +0 -180
  181. package/dist/types-cjs/core/types.d.cts +0 -192
  182. package/dist/types-cjs/core/verdict.d.cts +0 -2
  183. package/dist/types-cjs/index.d.cts +0 -10
  184. package/dist/types-cjs/map.d.cts +0 -69
  185. package/dist/types-cjs/package.json +0 -3
  186. package/dist/types-cjs/signals.d.cts +0 -624
  187. package/dist/types-cjs/store/index.d.cts +0 -19
  188. package/dist/types-cjs/store/next/optimistic.d.cts +0 -20
  189. package/dist/types-cjs/store/next/projection.d.cts +0 -8
  190. package/dist/types-cjs/store/next/reconcile.d.cts +0 -3
  191. package/dist/types-cjs/store/next/store.d.cts +0 -77
  192. package/dist/types-cjs/store/next/target.d.cts +0 -117
  193. package/dist/types-cjs/store/optimistic.d.cts +0 -45
  194. package/dist/types-cjs/store/projection.d.cts +0 -70
  195. package/dist/types-cjs/store/reconcile.d.cts +0 -46
  196. package/dist/types-cjs/store/store.d.cts +0 -138
  197. package/dist/types-cjs/store/storePath.d.cts +0 -58
  198. 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 };