@solidjs/signals 2.0.0-beta.9 → 2.0.0-rc.1

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 (106) hide show
  1. package/README.md +14 -10
  2. package/dist/dev.js +6740 -2011
  3. package/dist/node.cjs +7927 -3340
  4. package/dist/prod/affects.js +126 -0
  5. package/dist/prod/boundaries.js +572 -0
  6. package/dist/prod/core/action.js +139 -0
  7. package/dist/prod/core/async.js +607 -0
  8. package/dist/prod/core/constants.js +92 -0
  9. package/dist/prod/core/context.js +67 -0
  10. package/dist/prod/core/core.js +828 -0
  11. package/dist/prod/core/dev.js +3 -0
  12. package/dist/prod/core/effect.js +145 -0
  13. package/dist/prod/core/error.js +68 -0
  14. package/dist/prod/core/external.js +98 -0
  15. package/dist/prod/core/graph.js +104 -0
  16. package/dist/prod/core/heap.js +140 -0
  17. package/dist/prod/core/invariants.js +42 -0
  18. package/dist/prod/core/lanes.js +140 -0
  19. package/dist/prod/core/optimistic.js +262 -0
  20. package/dist/prod/core/owner.js +302 -0
  21. package/dist/prod/core/scheduler.js +757 -0
  22. package/dist/prod/core/verdict.js +369 -0
  23. package/dist/prod/index.js +45 -0
  24. package/dist/prod/map.js +319 -0
  25. package/dist/prod/signals.js +394 -0
  26. package/dist/prod/store/index.js +36 -0
  27. package/dist/prod/store/next/optimistic.js +377 -0
  28. package/dist/prod/store/next/projection.js +172 -0
  29. package/dist/prod/store/next/reconcile.js +327 -0
  30. package/dist/prod/store/next/store.js +1232 -0
  31. package/dist/prod/store/next/target.js +20 -0
  32. package/dist/prod/store/store.js +325 -0
  33. package/dist/prod/store/storePath.js +103 -0
  34. package/dist/prod/store/utils.js +201 -0
  35. package/dist/types/affects.d.ts +47 -0
  36. package/dist/types/boundaries.d.ts +60 -13
  37. package/dist/types/core/action.d.ts +35 -6
  38. package/dist/types/core/async.d.ts +16 -1
  39. package/dist/types/core/constants.d.ts +35 -6
  40. package/dist/types/core/context.d.ts +10 -2
  41. package/dist/types/core/core.d.ts +66 -63
  42. package/dist/types/core/dev.d.ts +17 -2
  43. package/dist/types/core/effect.d.ts +1 -2
  44. package/dist/types/core/error.d.ts +33 -0
  45. package/dist/types/core/external.d.ts +0 -11
  46. package/dist/types/core/graph.d.ts +2 -1
  47. package/dist/types/core/heap.d.ts +8 -0
  48. package/dist/types/core/index.d.ts +3 -2
  49. package/dist/types/core/invariants.d.ts +59 -0
  50. package/dist/types/core/lanes.d.ts +2 -0
  51. package/dist/types/core/optimistic.d.ts +6 -0
  52. package/dist/types/core/owner.d.ts +50 -3
  53. package/dist/types/core/scheduler.d.ts +85 -11
  54. package/dist/types/core/types.d.ts +66 -1
  55. package/dist/types/core/verdict.d.ts +2 -0
  56. package/dist/types/index.d.ts +3 -2
  57. package/dist/types/map.d.ts +21 -5
  58. package/dist/types/signals.d.ts +183 -12
  59. package/dist/types/store/index.d.ts +16 -6
  60. package/dist/types/store/next/optimistic.d.ts +20 -0
  61. package/dist/types/store/next/projection.d.ts +24 -0
  62. package/dist/types/store/next/reconcile.d.ts +3 -0
  63. package/dist/types/store/next/store.d.ts +71 -0
  64. package/dist/types/store/next/target.d.ts +99 -0
  65. package/dist/types/store/optimistic.d.ts +3 -3
  66. package/dist/types/store/projection.d.ts +10 -6
  67. package/dist/types/store/reconcile.d.ts +31 -8
  68. package/dist/types/store/store.d.ts +91 -71
  69. package/dist/types/store/utils.d.ts +0 -40
  70. package/dist/types-cjs/affects.d.cts +47 -0
  71. package/dist/types-cjs/boundaries.d.cts +60 -13
  72. package/dist/types-cjs/core/action.d.cts +35 -6
  73. package/dist/types-cjs/core/async.d.cts +16 -1
  74. package/dist/types-cjs/core/constants.d.cts +35 -6
  75. package/dist/types-cjs/core/context.d.cts +10 -2
  76. package/dist/types-cjs/core/core.d.cts +66 -63
  77. package/dist/types-cjs/core/dev.d.cts +17 -2
  78. package/dist/types-cjs/core/effect.d.cts +1 -2
  79. package/dist/types-cjs/core/error.d.cts +33 -0
  80. package/dist/types-cjs/core/external.d.cts +0 -11
  81. package/dist/types-cjs/core/graph.d.cts +2 -1
  82. package/dist/types-cjs/core/heap.d.cts +8 -0
  83. package/dist/types-cjs/core/index.d.cts +3 -2
  84. package/dist/types-cjs/core/invariants.d.cts +59 -0
  85. package/dist/types-cjs/core/lanes.d.cts +2 -0
  86. package/dist/types-cjs/core/optimistic.d.cts +6 -0
  87. package/dist/types-cjs/core/owner.d.cts +50 -3
  88. package/dist/types-cjs/core/scheduler.d.cts +85 -11
  89. package/dist/types-cjs/core/types.d.cts +66 -1
  90. package/dist/types-cjs/core/verdict.d.cts +2 -0
  91. package/dist/types-cjs/index.d.cts +3 -2
  92. package/dist/types-cjs/map.d.cts +21 -5
  93. package/dist/types-cjs/signals.d.cts +183 -12
  94. package/dist/types-cjs/store/index.d.cts +16 -6
  95. package/dist/types-cjs/store/next/optimistic.d.cts +20 -0
  96. package/dist/types-cjs/store/next/projection.d.cts +24 -0
  97. package/dist/types-cjs/store/next/reconcile.d.cts +3 -0
  98. package/dist/types-cjs/store/next/store.d.cts +71 -0
  99. package/dist/types-cjs/store/next/target.d.cts +99 -0
  100. package/dist/types-cjs/store/optimistic.d.cts +3 -3
  101. package/dist/types-cjs/store/projection.d.cts +10 -6
  102. package/dist/types-cjs/store/reconcile.d.cts +31 -8
  103. package/dist/types-cjs/store/store.d.cts +91 -71
  104. package/dist/types-cjs/store/utils.d.cts +0 -40
  105. package/package.json +12 -9
  106. package/dist/prod.js +0 -3627
@@ -0,0 +1,139 @@
1
+ import { globalQueue, activeTransition, currentTransition, schedule, flush } from "./scheduler.js";
2
+
3
+ import { isThenable } from "./async.js";
4
+
5
+ import "./core.js";
6
+
7
+ function restoreTransition(e, r) {
8
+ globalQueue.initTransition(e);
9
+ const t = r();
10
+ flush();
11
+ return t;
12
+ }
13
+
14
+ /**
15
+ * The primitive for mutations: imperative async workflows whose *writes span
16
+ * an async gap* — optimistic write, server round-trip, reconciling write —
17
+ * where intermediate state must not leak and failure must revert cleanly
18
+ * (pair with `createOptimistic` / `createOptimisticStore`).
19
+ *
20
+ * Navigation-shaped updates do not need an action. A plain setter call is
21
+ * enough: reads pull the async, and downstream async computeds hold their
22
+ * previous values per-node until the new ones are ready (`isPending` /
23
+ * `latest` expose the in-flight state). Reach for `action` only when writes
24
+ * happen *after* async work, not merely upstream of it.
25
+ *
26
+ * Framework-level actions (router form actions, server actions) are
27
+ * specializations of this primitive: they are actions in exactly this sense —
28
+ * the same transactional semantics — with form binding, serialization, and
29
+ * submission tracking layered on top. The shared name is deliberate.
30
+ *
31
+ * Wraps a generator function so each invocation runs as a single transaction
32
+ * (a "transition") that batches every signal/store write between yields. The
33
+ * surrounding UI sees one atomic update per yielded step; nothing is committed
34
+ * until the action either completes or the next `yield` resolves.
35
+ *
36
+ * `yield` is the transaction-safe suspension point: the action waits for a
37
+ * yielded promise and re-enters the transaction before running the code after
38
+ * it. A plain `await` does NOT — the runtime has no hook into an async
39
+ * generator's internal await continuations, so writes to fresh signals
40
+ * between an `await` and the next `yield` escape the transaction and commit
41
+ * immediately. `await` is still the ergonomic choice for typed results; just
42
+ * put a bare `yield` before any writes that follow it:
43
+ *
44
+ * ```ts
45
+ * const saved = await api.createTodo(text); // typed result
46
+ * yield; // re-enter the transaction before writing
47
+ * setTodos(t => { ... });
48
+ * ```
49
+ *
50
+ * (For the same reason, don't call `flush()` inside an action body — it
51
+ * drains the transaction mid-step.)
52
+ *
53
+ * Each call returns a `Promise` that resolves with the generator's return
54
+ * value, or rejects if it throws. Pair with `createOptimistic` /
55
+ * `createOptimisticStore` to apply tentative writes that auto-revert if the
56
+ * action fails.
57
+ *
58
+ * @example
59
+ * ```ts
60
+ * const [todos, setTodos] = createOptimisticStore<Todo[]>([]);
61
+ *
62
+ * const addTodo = action(async function* (text: string) {
63
+ * const tempId = crypto.randomUUID();
64
+ * setTodos(t => { t.push({ id: tempId, text, pending: true }); }); // optimistic
65
+ * const saved = await api.createTodo(text); // network round-trip, typed
66
+ * yield; // re-enter the transaction
67
+ * setTodos(t => {
68
+ * const i = t.findIndex(x => x.id === tempId);
69
+ * if (i >= 0) t[i] = saved;
70
+ * });
71
+ * return saved;
72
+ * });
73
+ *
74
+ * await addTodo("buy milk");
75
+ * ```
76
+ */ function action(e) {
77
+ return (...r) => new Promise((t, n) => {
78
+ const i = e(...r);
79
+ globalQueue.initTransition();
80
+ let o = activeTransition;
81
+ o.ie.push(i);
82
+ const done = (e, r, u = false) => {
83
+ o = currentTransition(o);
84
+ const s = o.ie.indexOf(i);
85
+ if (s >= 0) o.ie.splice(s, 1);
86
+ // Re-adopt through initTransition like every other resumption site:
87
+ // a bare setActiveTransition leaves globalQueue._batch as a detached
88
+ // ambient batch, and anything registered before the scheduled flush
89
+ // (held writes on a merging transition, optimistic overrides,
90
+ // affects() marks) lands there with nothing to ever finalize it.
91
+ globalQueue.initTransition(o);
92
+ schedule();
93
+ u ? n(r) : t(e);
94
+ };
95
+ const step = (e, r) => {
96
+ let t;
97
+ try {
98
+ t = r ? i.throw(e) : i.next(e);
99
+ } catch (e) {
100
+ return done(undefined, e, true);
101
+ }
102
+ // A rejected iterator result (async generators) means the error already
103
+ // escaped the generator body — it is completed, and throwing back in
104
+ // would just reject again forever. Settle instead.
105
+ if (isThenable(t)) return void t.then(run, e => done(undefined, e, true));
106
+ run(t);
107
+ };
108
+ const run = e => {
109
+ if (e.done) return done(e.value);
110
+ // Thenable assimilation can itself throw synchronously (a `then`
111
+ // getter, or a `then()` method that throws — #2918). Match `await`
112
+ // semantics: the failure is thrown back into the generator at the
113
+ // yield point (catchable there); if uncaught, step()'s guard settles
114
+ // the action so its iterator never leaks in the transition. The
115
+ // settled flag implements A+ 2.3.3.3.4.1: a throw after the thenable
116
+ // already called a callback is ignored.
117
+ let r = false;
118
+ try {
119
+ if (isThenable(e.value)) return void e.value.then(e => {
120
+ if (r) return;
121
+ r = true;
122
+ restoreTransition(o, () => step(e));
123
+ }, e => {
124
+ if (r) return;
125
+ r = true;
126
+ restoreTransition(o, () => step(e, true));
127
+ });
128
+ } catch (e) {
129
+ if (r) return;
130
+ r = true;
131
+ return void restoreTransition(o, () => step(e, true));
132
+ }
133
+ restoreTransition(o, () => step(e.value));
134
+ };
135
+ step();
136
+ });
137
+ }
138
+
139
+ export { action };