@johnhenry/math 0.0.0

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 (242) hide show
  1. package/README.md +165 -0
  2. package/dist/Bivector4.d.ts +52 -0
  3. package/dist/Bivector4.d.ts.map +1 -0
  4. package/dist/Bivector4.js +105 -0
  5. package/dist/Bivector4.js.map +1 -0
  6. package/dist/CellGraph.d.ts +259 -0
  7. package/dist/CellGraph.d.ts.map +1 -0
  8. package/dist/CellGraph.js +637 -0
  9. package/dist/CellGraph.js.map +1 -0
  10. package/dist/Clifford4Internal.d.ts +35 -0
  11. package/dist/Clifford4Internal.d.ts.map +1 -0
  12. package/dist/Clifford4Internal.js +86 -0
  13. package/dist/Clifford4Internal.js.map +1 -0
  14. package/dist/Combinatorics.d.ts +61 -0
  15. package/dist/Combinatorics.d.ts.map +1 -0
  16. package/dist/Combinatorics.js +186 -0
  17. package/dist/Combinatorics.js.map +1 -0
  18. package/dist/CombinatoricsGenerators.d.ts +44 -0
  19. package/dist/CombinatoricsGenerators.d.ts.map +1 -0
  20. package/dist/CombinatoricsGenerators.js +148 -0
  21. package/dist/CombinatoricsGenerators.js.map +1 -0
  22. package/dist/ComplexMath.d.ts +46 -0
  23. package/dist/ComplexMath.d.ts.map +1 -0
  24. package/dist/ComplexMath.js +98 -0
  25. package/dist/ComplexMath.js.map +1 -0
  26. package/dist/ComplexNumber.d.ts +174 -0
  27. package/dist/ComplexNumber.d.ts.map +1 -0
  28. package/dist/ComplexNumber.js +443 -0
  29. package/dist/ComplexNumber.js.map +1 -0
  30. package/dist/Cycle.d.ts +42 -0
  31. package/dist/Cycle.d.ts.map +1 -0
  32. package/dist/Cycle.js +120 -0
  33. package/dist/Cycle.js.map +1 -0
  34. package/dist/Decimal.d.ts +45 -0
  35. package/dist/Decimal.d.ts.map +1 -0
  36. package/dist/Decimal.js +135 -0
  37. package/dist/Decimal.js.map +1 -0
  38. package/dist/Distributions.d.ts +55 -0
  39. package/dist/Distributions.d.ts.map +1 -0
  40. package/dist/Distributions.js +222 -0
  41. package/dist/Distributions.js.map +1 -0
  42. package/dist/DualNumber.d.ts +42 -0
  43. package/dist/DualNumber.d.ts.map +1 -0
  44. package/dist/DualNumber.js +91 -0
  45. package/dist/DualNumber.js.map +1 -0
  46. package/dist/Environment.d.ts +44 -0
  47. package/dist/Environment.d.ts.map +1 -0
  48. package/dist/Environment.js +129 -0
  49. package/dist/Environment.js.map +1 -0
  50. package/dist/Expression.d.ts +19 -0
  51. package/dist/Expression.d.ts.map +1 -0
  52. package/dist/Expression.js +43 -0
  53. package/dist/Expression.js.map +1 -0
  54. package/dist/FFT.d.ts +21 -0
  55. package/dist/FFT.d.ts.map +1 -0
  56. package/dist/FFT.js +136 -0
  57. package/dist/FFT.js.map +1 -0
  58. package/dist/GeometricAlgebra4.d.ts +73 -0
  59. package/dist/GeometricAlgebra4.d.ts.map +1 -0
  60. package/dist/GeometricAlgebra4.js +115 -0
  61. package/dist/GeometricAlgebra4.js.map +1 -0
  62. package/dist/Geometry.d.ts +41 -0
  63. package/dist/Geometry.d.ts.map +1 -0
  64. package/dist/Geometry.js +167 -0
  65. package/dist/Geometry.js.map +1 -0
  66. package/dist/Graph.d.ts +72 -0
  67. package/dist/Graph.d.ts.map +1 -0
  68. package/dist/Graph.js +337 -0
  69. package/dist/Graph.js.map +1 -0
  70. package/dist/Graph3DUtils.d.ts +80 -0
  71. package/dist/Graph3DUtils.d.ts.map +1 -0
  72. package/dist/Graph3DUtils.js +156 -0
  73. package/dist/Graph3DUtils.js.map +1 -0
  74. package/dist/GraphUtils.d.ts +67 -0
  75. package/dist/GraphUtils.d.ts.map +1 -0
  76. package/dist/GraphUtils.js +72 -0
  77. package/dist/GraphUtils.js.map +1 -0
  78. package/dist/GroupTheory.d.ts +73 -0
  79. package/dist/GroupTheory.d.ts.map +1 -0
  80. package/dist/GroupTheory.js +194 -0
  81. package/dist/GroupTheory.js.map +1 -0
  82. package/dist/IntUtils.d.ts +33 -0
  83. package/dist/IntUtils.d.ts.map +1 -0
  84. package/dist/IntUtils.js +185 -0
  85. package/dist/IntUtils.js.map +1 -0
  86. package/dist/Interval.d.ts +44 -0
  87. package/dist/Interval.d.ts.map +1 -0
  88. package/dist/Interval.js +165 -0
  89. package/dist/Interval.js.map +1 -0
  90. package/dist/Lattice.d.ts +48 -0
  91. package/dist/Lattice.d.ts.map +1 -0
  92. package/dist/Lattice.js +65 -0
  93. package/dist/Lattice.js.map +1 -0
  94. package/dist/Logic.d.ts +22 -0
  95. package/dist/Logic.d.ts.map +1 -0
  96. package/dist/Logic.js +34 -0
  97. package/dist/Logic.js.map +1 -0
  98. package/dist/MatrixMath.d.ts +71 -0
  99. package/dist/MatrixMath.d.ts.map +1 -0
  100. package/dist/MatrixMath.js +302 -0
  101. package/dist/MatrixMath.js.map +1 -0
  102. package/dist/NumberTheory.d.ts +49 -0
  103. package/dist/NumberTheory.d.ts.map +1 -0
  104. package/dist/NumberTheory.js +230 -0
  105. package/dist/NumberTheory.js.map +1 -0
  106. package/dist/Numerical.d.ts +85 -0
  107. package/dist/Numerical.d.ts.map +1 -0
  108. package/dist/Numerical.js +343 -0
  109. package/dist/Numerical.js.map +1 -0
  110. package/dist/Permutation.d.ts +43 -0
  111. package/dist/Permutation.d.ts.map +1 -0
  112. package/dist/Permutation.js +142 -0
  113. package/dist/Permutation.js.map +1 -0
  114. package/dist/Polygon.d.ts +64 -0
  115. package/dist/Polygon.d.ts.map +1 -0
  116. package/dist/Polygon.js +221 -0
  117. package/dist/Polygon.js.map +1 -0
  118. package/dist/PolynomialRing.d.ts +74 -0
  119. package/dist/PolynomialRing.d.ts.map +1 -0
  120. package/dist/PolynomialRing.js +231 -0
  121. package/dist/PolynomialRing.js.map +1 -0
  122. package/dist/Quaternion.d.ts +37 -0
  123. package/dist/Quaternion.d.ts.map +1 -0
  124. package/dist/Quaternion.js +106 -0
  125. package/dist/Quaternion.js.map +1 -0
  126. package/dist/Rational.d.ts +34 -0
  127. package/dist/Rational.d.ts.map +1 -0
  128. package/dist/Rational.js +136 -0
  129. package/dist/Rational.js.map +1 -0
  130. package/dist/RealMath.d.ts +112 -0
  131. package/dist/RealMath.d.ts.map +1 -0
  132. package/dist/RealMath.js +262 -0
  133. package/dist/RealMath.js.map +1 -0
  134. package/dist/Rotor4.d.ts +180 -0
  135. package/dist/Rotor4.d.ts.map +1 -0
  136. package/dist/Rotor4.js +388 -0
  137. package/dist/Rotor4.js.map +1 -0
  138. package/dist/SpecialFunctions.d.ts +32 -0
  139. package/dist/SpecialFunctions.d.ts.map +1 -0
  140. package/dist/SpecialFunctions.js +161 -0
  141. package/dist/SpecialFunctions.js.map +1 -0
  142. package/dist/SpecialOperator.d.ts +21 -0
  143. package/dist/SpecialOperator.d.ts.map +1 -0
  144. package/dist/SpecialOperator.js +26 -0
  145. package/dist/SpecialOperator.js.map +1 -0
  146. package/dist/Statistics.d.ts +50 -0
  147. package/dist/Statistics.d.ts.map +1 -0
  148. package/dist/Statistics.js +131 -0
  149. package/dist/Statistics.js.map +1 -0
  150. package/dist/StringEvaluator.d.ts +48 -0
  151. package/dist/StringEvaluator.d.ts.map +1 -0
  152. package/dist/StringEvaluator.js +190 -0
  153. package/dist/StringEvaluator.js.map +1 -0
  154. package/dist/Structure.d.ts +130 -0
  155. package/dist/Structure.d.ts.map +1 -0
  156. package/dist/Structure.js +394 -0
  157. package/dist/Structure.js.map +1 -0
  158. package/dist/Symbolic.d.ts +501 -0
  159. package/dist/Symbolic.d.ts.map +1 -0
  160. package/dist/Symbolic.js +4077 -0
  161. package/dist/Symbolic.js.map +1 -0
  162. package/dist/Type.d.ts +31 -0
  163. package/dist/Type.d.ts.map +1 -0
  164. package/dist/Type.js +47 -0
  165. package/dist/Type.js.map +1 -0
  166. package/dist/Utilities.d.ts +27 -0
  167. package/dist/Utilities.d.ts.map +1 -0
  168. package/dist/Utilities.js +47 -0
  169. package/dist/Utilities.js.map +1 -0
  170. package/dist/Vec4.d.ts +39 -0
  171. package/dist/Vec4.d.ts.map +1 -0
  172. package/dist/Vec4.js +82 -0
  173. package/dist/Vec4.js.map +1 -0
  174. package/dist/Vector.d.ts +83 -0
  175. package/dist/Vector.d.ts.map +1 -0
  176. package/dist/Vector.js +173 -0
  177. package/dist/Vector.js.map +1 -0
  178. package/dist/VectorCalculus.d.ts +42 -0
  179. package/dist/VectorCalculus.d.ts.map +1 -0
  180. package/dist/VectorCalculus.js +82 -0
  181. package/dist/VectorCalculus.js.map +1 -0
  182. package/dist/VectorUtils.d.ts +172 -0
  183. package/dist/VectorUtils.d.ts.map +1 -0
  184. package/dist/VectorUtils.js +706 -0
  185. package/dist/VectorUtils.js.map +1 -0
  186. package/dist/differentiation-rules.d.ts +21 -0
  187. package/dist/differentiation-rules.d.ts.map +1 -0
  188. package/dist/differentiation-rules.js +52 -0
  189. package/dist/differentiation-rules.js.map +1 -0
  190. package/dist/index.d.ts +52 -0
  191. package/dist/index.d.ts.map +1 -0
  192. package/dist/index.js +66 -0
  193. package/dist/index.js.map +1 -0
  194. package/package.json +68 -0
  195. package/src/Bivector4.ts +136 -0
  196. package/src/CellGraph.ts +669 -0
  197. package/src/Clifford4Internal.ts +90 -0
  198. package/src/Combinatorics.ts +183 -0
  199. package/src/CombinatoricsGenerators.ts +144 -0
  200. package/src/ComplexMath.ts +162 -0
  201. package/src/ComplexNumber.ts +491 -0
  202. package/src/Cycle.ts +126 -0
  203. package/src/Decimal.ts +145 -0
  204. package/src/Distributions.ts +269 -0
  205. package/src/DualNumber.ts +105 -0
  206. package/src/Environment.ts +127 -0
  207. package/src/Expression.ts +48 -0
  208. package/src/FFT.ts +146 -0
  209. package/src/GeometricAlgebra4.ts +157 -0
  210. package/src/Geometry.ts +173 -0
  211. package/src/Graph.ts +337 -0
  212. package/src/Graph3DUtils.ts +269 -0
  213. package/src/GraphUtils.ts +159 -0
  214. package/src/GroupTheory.ts +214 -0
  215. package/src/IntUtils.ts +200 -0
  216. package/src/Interval.ts +171 -0
  217. package/src/Lattice.ts +87 -0
  218. package/src/Logic.ts +38 -0
  219. package/src/MatrixMath.ts +326 -0
  220. package/src/NumberTheory.ts +228 -0
  221. package/src/Numerical.ts +390 -0
  222. package/src/Permutation.ts +148 -0
  223. package/src/Polygon.ts +229 -0
  224. package/src/PolynomialRing.ts +242 -0
  225. package/src/Quaternion.ts +125 -0
  226. package/src/Rational.ts +148 -0
  227. package/src/RealMath.ts +346 -0
  228. package/src/Rotor4.ts +440 -0
  229. package/src/SpecialFunctions.ts +152 -0
  230. package/src/SpecialOperator.ts +28 -0
  231. package/src/Statistics.ts +170 -0
  232. package/src/StringEvaluator.ts +208 -0
  233. package/src/Structure.ts +481 -0
  234. package/src/Symbolic.ts +4313 -0
  235. package/src/Type.ts +48 -0
  236. package/src/Utilities.ts +49 -0
  237. package/src/Vec4.ts +98 -0
  238. package/src/Vector.ts +189 -0
  239. package/src/VectorCalculus.ts +87 -0
  240. package/src/VectorUtils.ts +797 -0
  241. package/src/differentiation-rules.ts +73 -0
  242. package/src/index.ts +140 -0
@@ -0,0 +1,637 @@
1
+ /**
2
+ * CellGraph — a reactive, pull-based dependency graph. Cells hold typed
3
+ * values (numbers, points, curves, whatever) rather than flattened
4
+ * primitives; a derived cell's `compute` reads other cells via `graph.get`,
5
+ * and the graph records the resulting edges automatically (no manual tag
6
+ * declarations, unlike mcp-query's cache).
7
+ *
8
+ * Writes (`set`) mark transitive dependents dirty and bump their version
9
+ * counters immediately — cheap, no recompute. Recomputation happens lazily,
10
+ * the next time a dirty cell is `get`, and a structural-equality check skips
11
+ * the version bump (and further propagation) when a recompute produces a
12
+ * value that's deep-equal to what was already cached, so unaffected
13
+ * downstream consumers don't re-render.
14
+ *
15
+ * Promoted here from johnhenry/mallory (originally `src/lib/cell-
16
+ * graph.ts`, powering every panel there via `useCell`/`useSyncExternalStore`)
17
+ * once johnhenry/math-grapher became a second consumer of a frozen
18
+ * vendored copy — two consumers is this monorepo's own extract-to-a-package
19
+ * trigger. See johnhenry/math#56. UI-framework-agnostic and dependency-
20
+ * free by design: nothing here references React or any host application.
21
+ */
22
+ export class CircularDependencyError extends Error {
23
+ constructor(path) {
24
+ super(`Circular dependency detected in cell graph: ${path.join(" -> ")}`);
25
+ this.name = "CircularDependencyError";
26
+ }
27
+ }
28
+ export class CellGraph {
29
+ cells = new Map();
30
+ listeners = new Map();
31
+ globalListeners = new Set();
32
+ writeListeners = new Set();
33
+ stack = [];
34
+ emitting = new Set();
35
+ /**
36
+ * Nesting depth of the current "logical write" -- incremented around the
37
+ * body of every top-level mutating entry point ({@link set}, {@link
38
+ * define}, {@link delete}) and decremented in a `finally` when it returns.
39
+ * A single `set()` on a root of a diamond-shaped dependency graph cascades
40
+ * through `propagateDirty` and calls `emit()` once per cell it reaches
41
+ * (root, then each newly-dirtied dependent) -- all of those belong to the
42
+ * SAME logical write and must produce exactly one `subscribeAll`
43
+ * notification, not one per cell. While this is above zero, a request to
44
+ * notify global listeners (see {@link scheduleGlobalNotify}) is deferred
45
+ * instead of firing immediately; it only actually fires once depth
46
+ * unwinds back to zero, i.e. once the outermost `set`/`define`/`delete`
47
+ * call (including any cells it transitively dirtied) has fully finished.
48
+ */
49
+ globalNotifyDepth = 0;
50
+ /** Set by {@link scheduleGlobalNotify} while `globalNotifyDepth > 0`, so the deferred notification isn't lost once depth returns to zero. */
51
+ globalNotifyPending = false;
52
+ /**
53
+ * Guards the global-listener-invocation loop itself against being
54
+ * re-entered while it's already running -- e.g. a global listener that
55
+ * synchronously calls `set()` on a DIFFERENT cell from inside its own
56
+ * callback. Unlike the shared boolean this replaces, a reentrant request
57
+ * that arrives while this is `true` is NOT dropped: it re-arms {@link
58
+ * globalNotifyPending}, which is drained (fired again) right after the
59
+ * in-progress loop finishes -- see {@link flushGlobalNotify}. This is what
60
+ * keeps a reentrant write to a different cell from being silently
61
+ * swallowed (issue #234), while still bounding recursion depth to one
62
+ * extra level per reentrant write, the same way `emitting` bounds it for
63
+ * same-id reentrancy on local listeners.
64
+ */
65
+ notifyingGlobalListeners = false;
66
+ /**
67
+ * Write a raw source-of-truth value (e.g. a slider drag or text input).
68
+ * Structurally, a cell written via `set` (no `compute` fn) is what makes
69
+ * it "free" -- see {@link role}.
70
+ *
71
+ * @param options.auxiliary Marks this cell hidden-by-default in an
72
+ * Algebra-view-style listing (see {@link list}) -- e.g. an internal
73
+ * sampling parameter that isn't itself meaningful to show the user,
74
+ * distinct from a top-level named object. Only applied when the cell
75
+ * doesn't already exist, or is transitioning from a compute-backed
76
+ * (dependent) cell to a free one; an existing free cell's auxiliary flag
77
+ * is left as originally set.
78
+ */
79
+ set(id, value, options) {
80
+ this.runBatched(() => {
81
+ const cell = this.ensure(id);
82
+ const wasCompute = cell.compute !== undefined;
83
+ cell.compute = undefined;
84
+ if (wasCompute) {
85
+ // This cell is transitioning from dependent (had a compute fn) to
86
+ // free -- detach its recorded dependency edges the same way
87
+ // recomputeAndEmit() and delete() already do, so former upstream
88
+ // cells stop spuriously dirtying/emitting a cell they no longer feed
89
+ // into.
90
+ for (const depId of cell.dependencies)
91
+ this.cells.get(depId)?.dependents.delete(id);
92
+ cell.dependencies = new Set();
93
+ }
94
+ if (options?.auxiliary !== undefined && (wasCompute || !cell.hasValue))
95
+ cell.auxiliary = options.auxiliary;
96
+ cell.hasError = false;
97
+ cell.error = undefined;
98
+ const unchanged = cell.hasValue && structuralEqual(cell.value, value);
99
+ cell.dirty = false;
100
+ if (unchanged)
101
+ return;
102
+ // Only replace the cached reference on a real change, so a write that's
103
+ // structurally equal to the old value never disturbs downstream identity.
104
+ cell.value = value;
105
+ cell.hasValue = true;
106
+ cell.version++;
107
+ this.emitWrite(id, value);
108
+ this.emit(id);
109
+ this.propagateDirty(id);
110
+ });
111
+ }
112
+ /**
113
+ * Subscribe to raw `set()` writes -- id plus the new value -- across
114
+ * every cell in the graph (issue #47's live-collaboration groundwork).
115
+ * Deliberately narrower than `subscribeAll`: it fires ONLY for an actual
116
+ * `set()` call with a real (structurally-different) value, never for a
117
+ * `define()`-driven recompute cascade. That's the exact shape a
118
+ * broadcast-to-other-peers use case needs -- each peer re-derives its
119
+ * own dependent cells locally once a base write arrives over the wire
120
+ * and gets applied via `set()` there too, so only the raw user-initiated
121
+ * writes need to cross the network, not every recomputed cell downstream
122
+ * of them.
123
+ */
124
+ subscribeWrites(fn) {
125
+ this.writeListeners.add(fn);
126
+ return () => this.writeListeners.delete(fn);
127
+ }
128
+ emitWrite(id, value) {
129
+ for (const fn of this.writeListeners)
130
+ fn(id, value);
131
+ }
132
+ /**
133
+ * Define (or redefine) a derived cell computed from other cells.
134
+ * Structurally, a cell written via `define` (has a `compute` fn) is what
135
+ * makes it "dependent" -- see {@link role}.
136
+ *
137
+ * @param options.auxiliary See {@link set}'s equivalent option; applied
138
+ * the same way (only on first definition, or a transition from free to
139
+ * dependent).
140
+ */
141
+ define(id, compute, options) {
142
+ this.runBatched(() => this.defineImpl(id, compute, options));
143
+ }
144
+ defineImpl(id, compute, options) {
145
+ const cell = this.ensure(id);
146
+ const wasFree = cell.compute === undefined && cell.hasValue;
147
+ const isRedefine = cell.hasValue;
148
+ if (options?.auxiliary !== undefined && (wasFree || cell.compute === undefined))
149
+ cell.auxiliary = options.auxiliary;
150
+ cell.compute = compute;
151
+ cell.dirty = true;
152
+ cell.hasError = false;
153
+ cell.error = undefined;
154
+ // A cell being defined for the first time (no prior value) is
155
+ // guaranteed to change once computed -- hasValue flips false -> true
156
+ // regardless of what the compute returns -- so it's safe to eagerly
157
+ // bump its version and notify its own subscribers now, same as before,
158
+ // with no need to actually run the compute early.
159
+ //
160
+ // A cell that already has a value is being *redefined*: unlike set(),
161
+ // define() doesn't have the new value in hand to structuralEqual-check
162
+ // synchronously -- only a function. The fix for #15 is NOT "defer the
163
+ // notification to some future get()": nothing guarantees a future
164
+ // get() ever happens. useSyncExternalStore's subscribe callback (see
165
+ // use-cell.ts) is what schedules a component's next render in the
166
+ // first place, and that callback only fires from emit() -- so an
167
+ // un-emitted genuine change would sit invisible until something
168
+ // UNRELATED happens to re-render the same subscribed component. That's
169
+ // a missed update, strictly worse than the unwanted-churn bug #15 set
170
+ // out to fix. Instead, resolve it the same way set() does: eagerly,
171
+ // synchronously, right here -- via recomputeAndEmit, which already
172
+ // implements exactly the "recompute, structuralEqual-gate the version
173
+ // bump/emit" logic this needs (and already detaches/rebuilds
174
+ // `dependencies` correctly as part of that). A throwing new compute is
175
+ // swallowed here (recomputeAndEmit already cached it on the cell via
176
+ // #14's hasError/error fields before rethrowing) so define() keeps its
177
+ // pre-existing never-throws-synchronously contract; the cached error
178
+ // surfaces through the normal get()-throws path on the next read.
179
+ if (isRedefine) {
180
+ try {
181
+ this.recomputeAndEmit(id, cell);
182
+ }
183
+ catch {
184
+ // Cached on the cell already; surfaced via get(), not here.
185
+ }
186
+ }
187
+ else {
188
+ cell.version++;
189
+ this.emit(id);
190
+ }
191
+ this.propagateDirty(id);
192
+ }
193
+ /**
194
+ * Whether `id` is "free" (writable directly via `set`, no `compute` fn --
195
+ * e.g. a slider or text input), "dependent" (computed via `define` from
196
+ * other cells), or "unknown" (`id` has never been `set`/`define`d, only
197
+ * read, or doesn't exist at all).
198
+ */
199
+ role(id) {
200
+ const cell = this.cells.get(id);
201
+ if (!cell?.hasValue)
202
+ return "unknown";
203
+ return cell.compute ? "dependent" : "free";
204
+ }
205
+ /** Whether `id` was marked `auxiliary` (hidden-by-default in an Algebra-view-style listing) -- see {@link set}/{@link define}. */
206
+ isAuxiliary(id) {
207
+ return this.cells.get(id)?.auxiliary ?? false;
208
+ }
209
+ /**
210
+ * Every cell currently in the graph, with its role and auxiliary flag --
211
+ * the basis for an Algebra-view-style listing (GeoGebra's free/dependent/
212
+ * auxiliary object model). Includes cells with no value yet (role
213
+ * "unknown") since a caller may still want to know such an id exists
214
+ * (e.g. was read but never written).
215
+ */
216
+ list() {
217
+ return [...this.cells.entries()].map(([id, cell]) => ({
218
+ id,
219
+ role: this.role(id),
220
+ auxiliary: cell.auxiliary,
221
+ hasValue: cell.hasValue,
222
+ }));
223
+ }
224
+ /** Read a cell's current value, recomputing if stale. Auto-tracks dependency edges. */
225
+ get(id) {
226
+ const cell = this.ensure(id);
227
+ // The cell currently being computed (if any) reads `id` — record the edge.
228
+ const caller = this.stack.at(-1);
229
+ if (caller !== undefined) {
230
+ this.cells.get(caller)?.dependencies.add(id);
231
+ cell.dependents.add(caller);
232
+ }
233
+ if (cell.dirty && cell.compute) {
234
+ if (this.stack.includes(id))
235
+ throw new CircularDependencyError([...this.stack, id]);
236
+ this.recomputeAndEmit(id, cell);
237
+ }
238
+ // A cached compute failure (see recomputeAndEmit's catch) is rethrown
239
+ // here on every subsequent get() -- without re-running the compute --
240
+ // until the same conditions that would invalidate a cached value (a
241
+ // fresh set()/define(), or a real upstream change marking this cell
242
+ // dirty again) clear it.
243
+ if (cell.hasError)
244
+ throw cell.error;
245
+ return cell.value;
246
+ }
247
+ recomputeAndEmit(id, cell) {
248
+ // Dependencies may differ between evaluations (e.g. a conditional
249
+ // expression) — detach from the old set before recomputing fresh.
250
+ for (const depId of cell.dependencies)
251
+ this.cells.get(depId)?.dependents.delete(id);
252
+ cell.dependencies = new Set();
253
+ this.stack.push(id);
254
+ let next;
255
+ try {
256
+ next = cell.compute();
257
+ }
258
+ catch (err) {
259
+ // Cache the failure so a subsequent get() (another render pass, a
260
+ // sibling compute reading this cell again, etc.) rethrows the same
261
+ // cached error instead of re-running a compute that's going to fail
262
+ // identically. `dirty` is still cleared here: this recompute attempt
263
+ // did happen and did resolve (to a failure), and staying dirty would
264
+ // otherwise force every future get() back through the compute anyway.
265
+ cell.dirty = false;
266
+ cell.hasError = true;
267
+ cell.error = err;
268
+ throw err;
269
+ }
270
+ finally {
271
+ this.stack.pop();
272
+ }
273
+ cell.dirty = false;
274
+ cell.hasError = false;
275
+ cell.error = undefined;
276
+ const unchanged = cell.hasValue && structuralEqual(cell.value, next);
277
+ if (!unchanged) {
278
+ // Reassign only on a real change, preserving the old reference on a
279
+ // no-op recompute — this is what lets a downstream Object.is check
280
+ // (e.g. React's useSyncExternalStore, or React.memo) bail out.
281
+ cell.value = next;
282
+ cell.hasValue = true;
283
+ cell.version++;
284
+ this.emit(id);
285
+ }
286
+ }
287
+ /** The value useSyncExternalStore observes for this cell. */
288
+ getVersion(id) {
289
+ return this.cells.get(id)?.version ?? 0;
290
+ }
291
+ /** Subscribe to changes on one cell. Returns an unsubscribe function. */
292
+ subscribe(id, fn) {
293
+ let set = this.listeners.get(id);
294
+ if (!set) {
295
+ set = new Set();
296
+ this.listeners.set(id, set);
297
+ }
298
+ set.add(fn);
299
+ this.ensure(id);
300
+ return () => {
301
+ set.delete(fn);
302
+ if (set.size !== 0)
303
+ return;
304
+ // Last subscriber for this id gone -- drop the now-empty Set instead
305
+ // of leaving it behind forever (an id that's subscribed-to-then-
306
+ // unsubscribed-from many times over a session, e.g. a dynamically
307
+ // created/destroyed notebook row, would otherwise accumulate one dead
308
+ // empty Set per id in `listeners`).
309
+ this.listeners.delete(id);
310
+ // If this cell was never actually given a value or a compute (i.e.
311
+ // the only reason it exists in `cells` at all is the ensure() call a
312
+ // few lines up) and nothing else in the graph references it (no
313
+ // dependents, no recorded dependencies), there's nothing left to
314
+ // justify keeping that phantom record around either -- clean it up
315
+ // too. A genuinely "live" cell (has a real value, is define()d, or
316
+ // participates in the dependency graph as someone's dependency/
317
+ // dependent) is untouched here; only explicit delete() removes those,
318
+ // per its own documented semantics -- this is deliberately narrower
319
+ // than delete() and never fires the "former dependents" notification
320
+ // delete() does, since there's no real removal of live state here.
321
+ const cell = this.cells.get(id);
322
+ if (cell &&
323
+ !cell.hasValue &&
324
+ cell.compute === undefined &&
325
+ cell.dependents.size === 0 &&
326
+ cell.dependencies.size === 0) {
327
+ this.cells.delete(id);
328
+ }
329
+ };
330
+ }
331
+ /** Subscribe to changes on any cell (e.g. to drive a canvas render loop). */
332
+ subscribeAll(fn) {
333
+ this.globalListeners.add(fn);
334
+ return () => this.globalListeners.delete(fn);
335
+ }
336
+ /**
337
+ * Subscribe to changes on a fixed, known set of specific cells -- e.g.
338
+ * every cell a serialized URL fragment reads. Narrower than
339
+ * `subscribeAll`: `fn` fires only for a write on one of `ids`, not for
340
+ * literally any cell in the graph (issue #235 -- several panels' URL-sync
341
+ * effects used `subscribeAll` for exactly this "a handful of specific
342
+ * cells" shape, so they also fired on unrelated high-frequency writes
343
+ * elsewhere in the same graph -- an RAF-driven playback clock, a live
344
+ * drag preview, a per-epoch training metric -- that the listener's own
345
+ * output never actually depended on). Just sugar over one `subscribe`
346
+ * call per id; not appropriate when the relevant id set is itself dynamic
347
+ * (e.g. "every currently-visible row's cells", where the row list can
348
+ * grow/shrink) -- that shape still needs `subscribeAll` (ideally
349
+ * debounced) or per-id `subscribe` calls re-issued as the id set changes.
350
+ */
351
+ subscribeMany(ids, fn) {
352
+ const unsubscribes = ids.map((id) => this.subscribe(id, fn));
353
+ return () => {
354
+ for (const unsubscribe of unsubscribes)
355
+ unsubscribe();
356
+ };
357
+ }
358
+ has(id) {
359
+ return this.cells.has(id);
360
+ }
361
+ /**
362
+ * Whether `id` has a real value yet, as opposed to merely existing as an
363
+ * empty record (`has()` returns true for a cell the instant anything reads
364
+ * it via `get`, even before it's ever been `set` or `define`d -- not a
365
+ * reliable "should I seed this?" check from a post-render effect that runs
366
+ * after a sibling compute has already read-and-thus-created it).
367
+ */
368
+ hasValue(id) {
369
+ return this.cells.get(id)?.hasValue ?? false;
370
+ }
371
+ /**
372
+ * Remove a cell entirely. Former *dependents* are marked dirty and
373
+ * notified (same as a `set()` would), so a compute that read the deleted
374
+ * cell re-runs and can fall back to whatever "this cell doesn't exist"
375
+ * means for it -- without this, a dependent kept its stale cached value
376
+ * forever, AND (because its dependency edges only rebuild during a
377
+ * recompute that never came) writes to its other dependencies stopped
378
+ * reaching it too. The notification happens *after* the cell is gone, so
379
+ * the reentrant recompute a listener may trigger sees the post-delete
380
+ * world: a `get()` on the deleted id re-creates an empty record
381
+ * (`hasValue: false`), exactly the "never existed" semantics callers
382
+ * like ExpressionRow's params compute already handle.
383
+ */
384
+ delete(id) {
385
+ this.runBatched(() => {
386
+ const cell = this.cells.get(id);
387
+ if (!cell)
388
+ return;
389
+ const formerDependents = [...cell.dependents];
390
+ for (const depId of cell.dependencies)
391
+ this.cells.get(depId)?.dependents.delete(id);
392
+ for (const depId of cell.dependents)
393
+ this.cells.get(depId)?.dependencies.delete(id);
394
+ this.cells.delete(id);
395
+ this.listeners.delete(id);
396
+ for (const depId of formerDependents) {
397
+ const dep = this.cells.get(depId);
398
+ if (!dep || dep.dirty)
399
+ continue;
400
+ dep.dirty = true;
401
+ this.emit(depId);
402
+ this.propagateDirty(depId);
403
+ }
404
+ });
405
+ }
406
+ ensure(id) {
407
+ let cell = this.cells.get(id);
408
+ if (!cell) {
409
+ cell = {
410
+ value: undefined,
411
+ hasValue: false,
412
+ version: 0,
413
+ dirty: true,
414
+ dependencies: new Set(),
415
+ dependents: new Set(),
416
+ auxiliary: false,
417
+ hasError: false,
418
+ error: undefined,
419
+ };
420
+ this.cells.set(id, cell);
421
+ }
422
+ return cell;
423
+ }
424
+ propagateDirty(id) {
425
+ const cell = this.cells.get(id);
426
+ if (!cell)
427
+ return;
428
+ // Snapshot before iterating: `emit` below can synchronously trigger a
429
+ // nested recompute (via useSyncExternalStore's listener) that detaches
430
+ // and re-adds an entry to this very `dependents` set. Iterating the live
431
+ // Set would then revisit that re-added entry within the same pass,
432
+ // looping forever between cells that share this dependency.
433
+ for (const depId of [...cell.dependents]) {
434
+ const dep = this.cells.get(depId);
435
+ if (!dep || dep.dirty)
436
+ continue; // already dirty -> already propagated past this point
437
+ dep.dirty = true;
438
+ // Notify listeners so a subscriber (e.g. useSyncExternalStore) re-reads
439
+ // via get(), which lazily recomputes. No version bump here — that only
440
+ // happens in get()/set() once a recompute confirms a real value change,
441
+ // which is what lets an unaffected downstream branch skip its redraw.
442
+ this.emit(depId);
443
+ this.propagateDirty(depId);
444
+ }
445
+ }
446
+ /**
447
+ * Notify `id`'s listeners that it may have changed. Guarded against
448
+ * reentrancy per-id: a `useSyncExternalStore` listener synchronously
449
+ * calls `getSnapshot` (React's own tearing check) as soon as it's
450
+ * notified, which re-enters `get()` and, on a real recompute, calls back
451
+ * into `emit(id)` for the very same id before this call has returned.
452
+ * Without the guard that nested call re-invokes every listener again
453
+ * (including the one currently on the stack), which re-triggers the same
454
+ * reentrant read, forever -- an unbounded synchronous storm that pins the
455
+ * CPU and eventually OOMs the JS heap. It's always safe to drop the
456
+ * nested notification: any consumer notified mid-flight still reads the
457
+ * freshest value the next time it calls `get()`, so no update is lost by
458
+ * collapsing repeat notifications for the same id into one.
459
+ *
460
+ * The global (`subscribeAll`) notification is requested here but not
461
+ * fired directly -- see {@link scheduleGlobalNotify}: a single logical
462
+ * write (e.g. one `set()` on the root of a diamond-shaped dependency
463
+ * graph) calls `emit()` once per cell it transitively dirties, but must
464
+ * still only produce ONE `subscribeAll` notification (issue #234).
465
+ */
466
+ emit(id) {
467
+ if (this.emitting.has(id))
468
+ return;
469
+ this.emitting.add(id);
470
+ try {
471
+ for (const fn of this.listeners.get(id) ?? [])
472
+ fn();
473
+ this.scheduleGlobalNotify();
474
+ }
475
+ finally {
476
+ this.emitting.delete(id);
477
+ }
478
+ }
479
+ /**
480
+ * Run `fn` as one "logical write" for the purposes of global-listener
481
+ * batching -- see {@link globalNotifyDepth}. Reentrant calls (e.g. a
482
+ * `subscribe()` listener triggered mid-cascade that synchronously calls
483
+ * `get()`, which recomputes and dirties further cells) nest transparently:
484
+ * only the outermost call's `finally` can bring the depth back to zero and
485
+ * trigger the deferred flush.
486
+ */
487
+ runBatched(fn) {
488
+ this.globalNotifyDepth++;
489
+ try {
490
+ return fn();
491
+ }
492
+ finally {
493
+ this.globalNotifyDepth--;
494
+ if (this.globalNotifyDepth === 0 && this.globalNotifyPending)
495
+ this.flushGlobalNotify();
496
+ }
497
+ }
498
+ /**
499
+ * Run `fn`, a sequence of otherwise-independent `set`/`define`/`delete`
500
+ * calls, as a SINGLE logical write for `subscribeAll` purposes (see
501
+ * {@link runBatched}/{@link scheduleGlobalNotify}). Without this, a
502
+ * multi-step mutation like a clear-then-replay (#374/#375) fires a
503
+ * `subscribeAll` notification after each individual call, so a listener
504
+ * that reads back across multiple cells (e.g. a canvas redraw walking an
505
+ * object-list cell and dereferencing each entry's point cells) can
506
+ * observe a transient state mid-sequence -- e.g. an id still listed in
507
+ * one cell whose corresponding point cell has already been deleted by an
508
+ * earlier call in the same `fn`. Wrapping the whole sequence here defers
509
+ * every `subscribeAll` notification until `fn` fully returns, so
510
+ * listeners only ever see the state before or after, never in between.
511
+ */
512
+ transaction(fn) {
513
+ return this.runBatched(fn);
514
+ }
515
+ /**
516
+ * Request a `subscribeAll` notification. While a logical write is still
517
+ * in progress ({@link globalNotifyDepth} > 0), the request is only
518
+ * recorded ({@link globalNotifyPending}) -- {@link runBatched} flushes it
519
+ * once that write (including everything it cascaded into) fully unwinds.
520
+ * Outside of any write (e.g. a standalone `get()` that lazily recomputes a
521
+ * dirty cell with no `set`/`define`/`delete` on the stack), there's no
522
+ * outer call to flush later, so it fires immediately.
523
+ */
524
+ scheduleGlobalNotify() {
525
+ this.globalNotifyPending = true;
526
+ if (this.globalNotifyDepth === 0)
527
+ this.flushGlobalNotify();
528
+ }
529
+ /**
530
+ * Actually invoke every `subscribeAll` listener, once, for the batch of
531
+ * cell changes accumulated since the last flush.
532
+ *
533
+ * Guarded against reentering the listener-invocation loop itself --
534
+ * `notifyingGlobalListeners`, scoped to "is a global-listener loop
535
+ * currently on the stack" rather than per-cell-id, because by this point
536
+ * the notification is no longer about any single cell; it's "this batch
537
+ * of writes changed something." A listener that synchronously starts a
538
+ * NEW logical write (e.g. `set()` on a different cell) re-arms {@link
539
+ * globalNotifyPending} instead of recursing into a second, nested
540
+ * invocation of every listener -- that pending flag is drained in the
541
+ * `while` loop below once the in-progress loop returns, so that second
542
+ * write's notification still fires (once), it's just deferred to right
543
+ * after the first finishes rather than dropped. This is what fixes issue
544
+ * #234's bug 2: the previous shared `notifyingGlobal` boolean guard
545
+ * skipped (silently discarded) exactly this case instead of deferring it.
546
+ */
547
+ flushGlobalNotify() {
548
+ if (this.notifyingGlobalListeners)
549
+ return; // already mid-loop; that loop's own drain (below) will pick this up
550
+ this.notifyingGlobalListeners = true;
551
+ try {
552
+ while (this.globalNotifyPending) {
553
+ this.globalNotifyPending = false;
554
+ for (const fn of this.globalListeners)
555
+ fn();
556
+ }
557
+ }
558
+ finally {
559
+ this.notifyingGlobalListeners = false;
560
+ }
561
+ }
562
+ }
563
+ /** Deep structural equality, used to skip redraws when a recompute is a no-op. */
564
+ export function structuralEqual(a, b) {
565
+ return structuralEqualInner(a, b, []);
566
+ }
567
+ // `seen` is the stack of (a, b) pairs currently being compared by an
568
+ // enclosing call on the stack -- used only as a cycle guard, see below.
569
+ function structuralEqualInner(a, b, seen) {
570
+ if (Object.is(a, b))
571
+ return true;
572
+ if (typeof a !== "object" || typeof b !== "object" || a === null || b === null)
573
+ return false;
574
+ // Cycle guard: if this exact (a, b) pair is already being compared by an
575
+ // enclosing (ancestor) call on the stack, it's a cycle -- stop recursing
576
+ // and treat it as equal here rather than looping forever. Any genuine
577
+ // difference elsewhere in the structure is still found by the other,
578
+ // non-cyclic branches of the comparison; this only prevents the recursion
579
+ // itself from being unbounded.
580
+ for (const [sa, sb] of seen) {
581
+ if (sa === a && sb === b)
582
+ return true;
583
+ }
584
+ // Two objects of genuinely different types (Date vs plain object, Map vs
585
+ // Set, etc.) are never equal, regardless of their own-key shape below.
586
+ const aTag = Object.prototype.toString.call(a);
587
+ const bTag = Object.prototype.toString.call(b);
588
+ if (aTag !== bTag)
589
+ return false;
590
+ seen = [...seen, [a, b]];
591
+ if (a instanceof Date)
592
+ return a.getTime() === b.getTime();
593
+ if (a instanceof Map) {
594
+ const bm = b;
595
+ if (a.size !== bm.size)
596
+ return false;
597
+ for (const [k, v] of a) {
598
+ if (!bm.has(k) || !structuralEqualInner(v, bm.get(k), seen))
599
+ return false;
600
+ }
601
+ return true;
602
+ }
603
+ if (a instanceof Set) {
604
+ // Set membership is by identity/SameValueZero, matching the Set's own
605
+ // semantics (not a structural comparison of elements) -- two elements
606
+ // that are merely structurally-equal-but-distinct objects are genuinely
607
+ // different members of a Set.
608
+ const bs = b;
609
+ if (a.size !== bs.size)
610
+ return false;
611
+ for (const v of a)
612
+ if (!bs.has(v))
613
+ return false;
614
+ return true;
615
+ }
616
+ if (Array.isArray(a)) {
617
+ const ba = b;
618
+ if (a.length !== ba.length)
619
+ return false;
620
+ return a.every((v, i) => structuralEqualInner(v, ba[i], seen));
621
+ }
622
+ // Any other exotic built-in (RegExp, DOM nodes, a real Path2D, etc.) that
623
+ // isn't a plain object falls through to here -- treat it as *not* equal
624
+ // by default rather than comparing (typically zero) own enumerable keys,
625
+ // which would otherwise silently treat any two distinct instances as
626
+ // identical. Safe default: this only means an extra recompute, never a
627
+ // missed update.
628
+ if (aTag !== "[object Object]")
629
+ return false;
630
+ const aKeys = Object.keys(a);
631
+ const bKeys = Object.keys(b);
632
+ if (aKeys.length !== bKeys.length)
633
+ return false;
634
+ return aKeys.every((k) => Object.hasOwn(b, k) &&
635
+ structuralEqualInner(a[k], b[k], seen));
636
+ }
637
+ //# sourceMappingURL=CellGraph.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"CellGraph.js","sourceRoot":"","sources":["../src/CellGraph.ts"],"names":[],"mappings":"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"}