@danielsimonjr/mathts-workbook 0.5.0 → 0.5.2

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/cli.d.ts.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":";AACA;;;;;;;GAOG;AAsCH;;;;GAIG;AACH,MAAM,WAAW,aAAa;IAC5B,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,MAAM,CAAC;CAClB;AA8OD;;;;;;;;;;;;GAYG;AACH,wBAAsB,UAAU,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,aAAa,CAAC,CAqHvE;AAqDD;;;;;;;GAOG;AACH,wBAAgB,eAAe,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,aAAa,CAoC7D;AAED;;;;;;;GAOG;AACH,wBAAgB,eAAe,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,aAAa,CA+C7D;AAkBD;;;;;;GAMG;AACH,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,aAAa,CASjE;AAED;;;;;GAKG;AACH,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,aAAa,CAO9D;AAED;;;;;;GAMG;AACH,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,aAAa,CAO9D;AAED;;;;;;;;;GASG;AACH,wBAAgB,WAAW,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,aAAa,CA2DzD;AAoFD;;;;;;;;;;;GAWG;AACH,wBAAsB,aAAa,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,aAAa,CAAC,CA8H1E;AAED;;;;GAIG;AACH,wBAAgB,SAAS,CACvB,KAAK,GAAE,MAAM,CAAC,cAA8B,EAC5C,MAAM,GAAE,MAAM,CAAC,cAA+B,GAC7C,OAAO,CAAC,IAAI,CAAC,CAuEf;AAED;;;;;GAKG;AACH,wBAAsB,YAAY,IAAI,OAAO,CAAC,aAAa,CAAC,CAG3D;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,YAAY,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,aAAa,CAsC1D;AAED;;;;;;;GAOG;AACH,wBAAgB,YAAY,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,aAAa,CA0B1D;AAuDD;;;;;;;;;;;;GAYG;AACH,wBAAgB,UAAU,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,aAAa,CAqFxD;AAED;;;;;;;;GAQG;AACH,wBAAgB,aAAa,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,aAAa,CAiD3D;AAyED;;;;;;;;;;GAUG;AACH,wBAAgB,WAAW,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,aAAa,CA4HzD;AAED;;GAEG;AACH,wBAAsB,QAAQ,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,aAAa,CAAC,CAuDrE"}
1
+ {"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":";AACA;;;;;;;GAOG;AAsCH;;;;GAIG;AACH,MAAM,WAAW,aAAa;IAC5B,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,MAAM,CAAC;CAClB;AAmPD;;;;;;;;;;;;GAYG;AACH,wBAAsB,UAAU,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,aAAa,CAAC,CAqHvE;AAqDD;;;;;;;GAOG;AACH,wBAAgB,eAAe,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,aAAa,CAoC7D;AAED;;;;;;;GAOG;AACH,wBAAgB,eAAe,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,aAAa,CA+C7D;AAkBD;;;;;;GAMG;AACH,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,aAAa,CASjE;AAED;;;;;GAKG;AACH,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,aAAa,CAO9D;AAED;;;;;;GAMG;AACH,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,aAAa,CAO9D;AAED;;;;;;;;;GASG;AACH,wBAAgB,WAAW,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,aAAa,CA2DzD;AAoFD;;;;;;;;;;;GAWG;AACH,wBAAsB,aAAa,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,aAAa,CAAC,CA8H1E;AAED;;;;GAIG;AACH,wBAAgB,SAAS,CACvB,KAAK,GAAE,MAAM,CAAC,cAA8B,EAC5C,MAAM,GAAE,MAAM,CAAC,cAA+B,GAC7C,OAAO,CAAC,IAAI,CAAC,CAuEf;AAED;;;;;GAKG;AACH,wBAAsB,YAAY,IAAI,OAAO,CAAC,aAAa,CAAC,CAG3D;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,YAAY,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,aAAa,CAsC1D;AAED;;;;;;;GAOG;AACH,wBAAgB,YAAY,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,aAAa,CA0B1D;AAuDD;;;;;;;;;;;;GAYG;AACH,wBAAgB,UAAU,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,aAAa,CAqFxD;AAED;;;;;;;;GAQG;AACH,wBAAgB,aAAa,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,aAAa,CAiD3D;AAyED;;;;;;;;;;GAUG;AACH,wBAAgB,WAAW,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,aAAa,CA4HzD;AAED;;GAEG;AACH,wBAAsB,QAAQ,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,aAAa,CAAC,CAuDrE"}
package/dist/cli.js CHANGED
@@ -1,6 +1,6 @@
1
1
  #!/usr/bin/env node
2
- import { c as parseWorkbook, d as buildDependencyGraph, f as detectCycles, g as toMermaid, h as toDOT, l as serializeWorkbook, o as importWorkbook, r as createExecutor, t as formatResult, u as stripOutputs, v as parseYamlSafe } from "./formatter-Dwrza-un.js";
3
- import { _ as toTeX, a as capabilitiesInfo, c as writeFileAtomic, d as addCell, f as editCell, g as setMetadata, h as renameCell, i as describeData, l as SCHEMA_VERSION, m as removeCell, n as runWorkbookWithTimeout, o as listFunctions, p as moveCell, r as handleRequest, s as Session, u as VERSION, v as markdownToHtml, y as renderChart } from "./timeout-runner-C249B3OS.js";
2
+ import { _ as toMermaid, c as parseWorkbook, d as buildDependencyGraph, f as detectCycles, g as toDOT, l as serializeWorkbook, o as importWorkbook, r as createExecutor, t as formatResult, u as stripOutputs, y as parseYamlSafe } from "./formatter-ssmPX0Ap.js";
3
+ import { _ as toTeX, a as capabilitiesInfo, c as writeFileAtomic, d as addCell, f as editCell, g as setMetadata, h as renameCell, i as describeData, l as SCHEMA_VERSION, m as removeCell, n as runWorkbookWithTimeout, o as listFunctions, p as moveCell, r as handleRequest, s as Session, u as VERSION, v as markdownToHtml, y as renderChart } from "./timeout-runner--KC7NTAV.js";
4
4
  import * as mathFunctions from "@danielsimonjr/mathts-functions";
5
5
  import { lstatSync, readFileSync, realpathSync, writeFileSync } from "node:fs";
6
6
  import { createHash } from "node:crypto";
@@ -280,12 +280,13 @@ Notes:
280
280
  valid identifiers ([A-Za-z_][A-Za-z0-9_]*).
281
281
  `.trimStart();
282
282
  function jsonEnvelope(command, ok, data, problems = []) {
283
- const seen = /* @__PURE__ */ new WeakSet();
284
- const replacer = (_key, value) => {
283
+ const ancestors = [];
284
+ const replacer = function(_key, value) {
285
285
  if (typeof value === "bigint") return `${value}n`;
286
286
  if (value !== null && typeof value === "object") {
287
- if (seen.has(value)) return "[Circular]";
288
- seen.add(value);
287
+ while (ancestors.length > 0 && ancestors[ancestors.length - 1] !== this) ancestors.pop();
288
+ if (ancestors.includes(value)) return "[Circular]";
289
+ ancestors.push(value);
289
290
  }
290
291
  return value;
291
292
  };
@@ -12,6 +12,7 @@ type EventHandler = (event: WorkbookEvent) => void;
12
12
  export declare class WorkbookExecutor {
13
13
  private workbook;
14
14
  private graph;
15
+ private cellsById;
15
16
  private outputs;
16
17
  private handlers;
17
18
  constructor(workbook: Workbook);
@@ -31,6 +32,12 @@ export declare class WorkbookExecutor {
31
32
  * Run a specific cell
32
33
  */
33
34
  runCell(cellId: string): Promise<unknown>;
35
+ /**
36
+ * Run a cell. `pending` (internal) holds cells still scheduled later in the
37
+ * current batch run; in reactive mode they are about to be recomputed anyway,
38
+ * so no `cell:stale` is emitted for them. Omitted for a standalone runCell.
39
+ */
40
+ private runCellScheduled;
34
41
  /**
35
42
  * Execute a single cell
36
43
  */
@@ -1 +1 @@
1
- {"version":3,"file":"executor.d.ts","sourceRoot":"","sources":["../src/executor.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,KAAK,EACV,QAAQ,EAER,aAAa,EAGb,SAAS,EACV,MAAM,YAAY,CAAC;AAKpB;;GAEG;AACH,KAAK,YAAY,GAAG,CAAC,KAAK,EAAE,aAAa,KAAK,IAAI,CAAC;AAEnD;;GAEG;AACH,qBAAa,gBAAgB;IAC3B,OAAO,CAAC,QAAQ,CAAW;IAC3B,OAAO,CAAC,KAAK,CAAkB;IAC/B,OAAO,CAAC,OAAO,CAAmC;IAClD,OAAO,CAAC,QAAQ,CAAsB;IAEtC,YAAY,QAAQ,EAAE,QAAQ,EAG7B;IAED;;OAEG;IACH,EAAE,CAAC,OAAO,EAAE,YAAY,GAAG,MAAM,IAAI,CAQpC;IAED;;OAEG;IACH,OAAO,CAAC,IAAI;IAMZ;;OAEG;IACG,MAAM,IAAI,OAAO,CAAC,IAAI,CAAC,CAS5B;IAED;;OAEG;IACG,OAAO,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAgD9C;IAED;;OAEG;YACW,WAAW;IAiBzB;;;;;;;;OAQG;IACH,OAAO,CAAC,UAAU;IAelB;;;;;;OAMG;YACW,WAAW;IAIzB;;;;;OAKG;YACW,WAAW;IAQzB;;;;OAIG;YACW,WAAW;IAKzB;;;;;;;;OAQG;IACH;;;;OAIG;IACH,WAAW,CAAC,OAAO,EAAE,GAAG,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,CAE/C;IAEK,SAAS,CAAC,OAAO,GAAE;QAAE,IAAI,CAAC,EAAE,MAAM,CAAC;QAAC,MAAM,CAAC,EAAE,GAAG,CAAC,MAAM,CAAC,CAAA;KAAO,GAAG,OAAO,CAAC,SAAS,CAAC,CAwDzF;IAED;;OAEG;IACH,SAAS,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAEjC;CACF;AAED;;GAEG;AACH,wBAAgB,cAAc,CAAC,QAAQ,EAAE,QAAQ,GAAG,gBAAgB,CAEnE"}
1
+ {"version":3,"file":"executor.d.ts","sourceRoot":"","sources":["../src/executor.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,KAAK,EACV,QAAQ,EAER,aAAa,EAGb,SAAS,EACV,MAAM,YAAY,CAAC;AAKpB;;GAEG;AACH,KAAK,YAAY,GAAG,CAAC,KAAK,EAAE,aAAa,KAAK,IAAI,CAAC;AAEnD;;GAEG;AACH,qBAAa,gBAAgB;IAC3B,OAAO,CAAC,QAAQ,CAAW;IAC3B,OAAO,CAAC,KAAK,CAAkB;IAC/B,OAAO,CAAC,SAAS,CAAoB;IACrC,OAAO,CAAC,OAAO,CAAmC;IAClD,OAAO,CAAC,QAAQ,CAAsB;IAEtC,YAAY,QAAQ,EAAE,QAAQ,EAI7B;IAED;;OAEG;IACH,EAAE,CAAC,OAAO,EAAE,YAAY,GAAG,MAAM,IAAI,CAQpC;IAED;;OAEG;IACH,OAAO,CAAC,IAAI;IAMZ;;OAEG;IACG,MAAM,IAAI,OAAO,CAAC,IAAI,CAAC,CA+B5B;IAED;;OAEG;IACG,OAAO,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAE9C;IAED;;;;OAIG;YACW,gBAAgB;IAsD9B;;OAEG;YACW,WAAW;IAiBzB;;;;;;;;OAQG;IACH,OAAO,CAAC,UAAU;IAelB;;;;;;OAMG;YACW,WAAW;IAIzB;;;;;OAKG;YACW,WAAW;IAQzB;;;;OAIG;YACW,WAAW;IAKzB;;;;;;;;OAQG;IACH;;;;OAIG;IACH,WAAW,CAAC,OAAO,EAAE,GAAG,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,CAE/C;IAEK,SAAS,CAAC,OAAO,GAAE;QAAE,IAAI,CAAC,EAAE,MAAM,CAAC;QAAC,MAAM,CAAC,EAAE,GAAG,CAAC,MAAM,CAAC,CAAA;KAAO,GAAG,OAAO,CAAC,SAAS,CAAC,CAgEzF;IAED;;OAEG;IACH,SAAS,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAEjC;CACF;AAED;;GAEG;AACH,wBAAgB,cAAc,CAAC,QAAQ,EAAE,QAAQ,GAAG,gBAAgB,CAEnE"}
@@ -65,41 +65,77 @@ function buildDependencyGraph(cells) {
65
65
  function topologicalSort(nodes) {
66
66
  const visited = /* @__PURE__ */ new Set();
67
67
  const result = [];
68
- function visit(id) {
69
- if (visited.has(id)) return;
70
- visited.add(id);
71
- const node = nodes.get(id);
72
- if (node) for (const depId of node.dependencies) visit(depId);
73
- result.push(id);
68
+ for (const root of nodes.keys()) {
69
+ if (visited.has(root)) continue;
70
+ visited.add(root);
71
+ const stack = [{
72
+ id: root,
73
+ deps: nodes.get(root)?.dependencies ?? [],
74
+ i: 0
75
+ }];
76
+ while (stack.length > 0) {
77
+ const frame = stack[stack.length - 1];
78
+ if (frame.i < frame.deps.length) {
79
+ const depId = frame.deps[frame.i++];
80
+ if (!visited.has(depId)) {
81
+ visited.add(depId);
82
+ stack.push({
83
+ id: depId,
84
+ deps: nodes.get(depId)?.dependencies ?? [],
85
+ i: 0
86
+ });
87
+ }
88
+ } else {
89
+ result.push(frame.id);
90
+ stack.pop();
91
+ }
92
+ }
74
93
  }
75
- for (const id of nodes.keys()) visit(id);
76
94
  return result;
77
95
  }
78
96
  function getDependents(graph, cellId) {
97
+ return getDependentsOfMany(graph, [cellId]);
98
+ }
99
+ function getDependentsOfMany(graph, cellIds) {
79
100
  const result = [];
80
101
  const visited = /* @__PURE__ */ new Set();
81
- function collect(id) {
82
- const node = graph.nodes.get(id);
83
- if (!node) return;
84
- for (const depId of node.dependents) if (!visited.has(depId)) {
102
+ for (const source of cellIds) {
103
+ const first = graph.nodes.get(source);
104
+ if (!first) continue;
105
+ const stack = [{
106
+ deps: first.dependents,
107
+ i: 0
108
+ }];
109
+ while (stack.length > 0) {
110
+ const frame = stack[stack.length - 1];
111
+ if (frame.i >= frame.deps.length) {
112
+ stack.pop();
113
+ continue;
114
+ }
115
+ const depId = frame.deps[frame.i++];
116
+ if (visited.has(depId)) continue;
85
117
  visited.add(depId);
86
118
  result.push(depId);
87
- collect(depId);
119
+ const node = graph.nodes.get(depId);
120
+ if (node) stack.push({
121
+ deps: node.dependents,
122
+ i: 0
123
+ });
88
124
  }
89
125
  }
90
- collect(cellId);
91
126
  return result;
92
127
  }
93
128
  function getAncestors(graph, id) {
94
129
  const result = /* @__PURE__ */ new Set();
95
- function visit(nodeId) {
96
- if (result.has(nodeId)) return;
130
+ const stack = [id];
131
+ while (stack.length > 0) {
132
+ const nodeId = stack.pop();
133
+ if (result.has(nodeId)) continue;
97
134
  const node = graph.nodes.get(nodeId);
98
- if (!node) return;
135
+ if (!node) continue;
99
136
  result.add(nodeId);
100
- for (const dep of node.dependencies) visit(dep);
137
+ for (const dep of node.dependencies) stack.push(dep);
101
138
  }
102
- visit(id);
103
139
  return graph.executionOrder.filter((nodeId) => result.has(nodeId));
104
140
  }
105
141
  function renderDependencyGraph(graph, format) {
@@ -409,11 +445,13 @@ function importWorkbook(input) {
409
445
  var WorkbookExecutor = class {
410
446
  workbook;
411
447
  graph;
448
+ cellsById;
412
449
  outputs = /* @__PURE__ */ new Map();
413
450
  handlers = [];
414
451
  constructor(workbook) {
415
452
  this.workbook = workbook;
416
453
  this.graph = buildDependencyGraph(workbook.cells);
454
+ this.cellsById = new Map(workbook.cells.map((c) => [c.id, c]));
417
455
  }
418
456
  on(handler) {
419
457
  this.handlers.push(handler);
@@ -426,14 +464,36 @@ var WorkbookExecutor = class {
426
464
  for (const handler of this.handlers) handler(event);
427
465
  }
428
466
  async runAll() {
429
- for (const cellId of this.graph.executionOrder) await this.runCell(cellId);
467
+ const pending = new Set(this.graph.executionOrder);
468
+ const completed = [];
469
+ for (const cellId of this.graph.executionOrder) {
470
+ pending.delete(cellId);
471
+ try {
472
+ await this.runCellScheduled(cellId, pending);
473
+ } catch (error) {
474
+ if (this.workbook.runtime.execution === "reactive") {
475
+ const stale = /* @__PURE__ */ new Set();
476
+ for (const done of completed) for (const depId of getDependents(this.graph, done)) if (pending.has(depId)) stale.add(depId);
477
+ for (const depId of stale) this.emit({
478
+ type: "cell:stale",
479
+ cellId: depId,
480
+ timestamp: Date.now()
481
+ });
482
+ }
483
+ throw error;
484
+ }
485
+ completed.push(cellId);
486
+ }
430
487
  this.emit({
431
488
  type: "workbook:complete",
432
489
  timestamp: Date.now()
433
490
  });
434
491
  }
435
492
  async runCell(cellId) {
436
- const cell = this.workbook.cells.find((c) => c.id === cellId);
493
+ return this.runCellScheduled(cellId, void 0);
494
+ }
495
+ async runCellScheduled(cellId, pending) {
496
+ const cell = this.cellsById.get(cellId);
437
497
  if (!cell) throw new Error(`Cell not found: ${cellId}`);
438
498
  this.emit({
439
499
  type: "cell:start",
@@ -451,11 +511,14 @@ var WorkbookExecutor = class {
451
511
  });
452
512
  if (this.workbook.runtime.execution === "reactive") {
453
513
  const dependents = getDependents(this.graph, cellId);
454
- for (const depId of dependents) this.emit({
455
- type: "cell:stale",
456
- cellId: depId,
457
- timestamp: Date.now()
458
- });
514
+ for (const depId of dependents) {
515
+ if (pending?.has(depId)) continue;
516
+ this.emit({
517
+ type: "cell:stale",
518
+ cellId: depId,
519
+ timestamp: Date.now()
520
+ });
521
+ }
459
522
  }
460
523
  return output;
461
524
  } catch (error) {
@@ -522,12 +585,14 @@ var WorkbookExecutor = class {
522
585
  const allowed = new Set(getAncestors(this.graph, options.only));
523
586
  order = order.filter((id) => allowed.has(id));
524
587
  }
588
+ const pending = new Set(order.filter((id) => (options.runIds ? options.runIds.has(id) : true) && this.cellsById.has(id)));
525
589
  for (const cellId of order) {
526
590
  if (options.runIds && !options.runIds.has(cellId)) continue;
527
- const cell = this.workbook.cells.find((c) => c.id === cellId);
591
+ const cell = this.cellsById.get(cellId);
528
592
  if (!cell) continue;
593
+ pending.delete(cellId);
529
594
  try {
530
- const output = await this.runCell(cellId);
595
+ const output = await this.runCellScheduled(cellId, pending);
531
596
  if (cell.type === "test") {
532
597
  const passed = output === true;
533
598
  cells.push({
@@ -615,4 +680,4 @@ function formatResult(value) {
615
680
  }
616
681
  }
617
682
  //#endregion
618
- export { topologicalSort as _, detectCellType as a, parseWorkbook as c, buildDependencyGraph as d, detectCycles as f, toMermaid as g, toDOT as h, SUPPORTED_CELL_TYPES as i, serializeWorkbook as l, getDependents as m, WorkbookExecutor as n, importWorkbook as o, getAncestors as p, createExecutor as r, isValidIdentifier as s, formatResult as t, stripOutputs as u, parseYamlSafe as v };
683
+ export { toMermaid as _, detectCellType as a, parseWorkbook as c, buildDependencyGraph as d, detectCycles as f, toDOT as g, getDependentsOfMany as h, SUPPORTED_CELL_TYPES as i, serializeWorkbook as l, getDependents as m, WorkbookExecutor as n, importWorkbook as o, getAncestors as p, createExecutor as r, isValidIdentifier as s, formatResult as t, stripOutputs as u, topologicalSort as v, parseYamlSafe as y };
package/dist/graph.d.ts CHANGED
@@ -11,9 +11,15 @@ export declare function buildDependencyGraph(cells: Cell[]): DependencyGraph;
11
11
  */
12
12
  export declare function topologicalSort(nodes: Map<string, DependencyNode>): string[];
13
13
  /**
14
- * Get all cells that depend on a given cell
14
+ * Get all cells that depend on a given cell (depth-first pre-order, iterative).
15
15
  */
16
16
  export declare function getDependents(graph: DependencyGraph, cellId: string): string[];
17
+ /**
18
+ * Multi-source variant of {@link getDependents}: every cell that transitively
19
+ * depends on any of `cellIds`, in one traversal (shared visited set). The
20
+ * sources themselves are only included if reachable from another source.
21
+ */
22
+ export declare function getDependentsOfMany(graph: DependencyGraph, cellIds: Iterable<string>): string[];
17
23
  /**
18
24
  * All transitive dependencies of `id` plus `id` itself (its ancestor closure).
19
25
  * Used to run a single cell together with everything it needs. Cycle-safe via
@@ -1 +1 @@
1
- {"version":3,"file":"graph.d.ts","sourceRoot":"","sources":["../src/graph.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,KAAK,EAAE,IAAI,EAAE,eAAe,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAExE;;GAEG;AACH,wBAAgB,oBAAoB,CAAC,KAAK,EAAE,IAAI,EAAE,GAAG,eAAe,CA0BnE;AAED;;GAEG;AACH,wBAAgB,eAAe,CAAC,KAAK,EAAE,GAAG,CAAC,MAAM,EAAE,cAAc,CAAC,GAAG,MAAM,EAAE,CAuB5E;AAED;;GAEG;AACH,wBAAgB,aAAa,CAAC,KAAK,EAAE,eAAe,EAAE,MAAM,EAAE,MAAM,GAAG,MAAM,EAAE,CAmB9E;AAED;;;;GAIG;AACH,wBAAgB,YAAY,CAAC,KAAK,EAAE,eAAe,EAAE,EAAE,EAAE,MAAM,GAAG,MAAM,EAAE,CAezE;AAkCD;;;;;;GAMG;AACH,wBAAgB,SAAS,CAAC,KAAK,EAAE,eAAe,GAAG,MAAM,CAMxD;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,KAAK,CAAC,KAAK,EAAE,eAAe,GAAG,MAAM,CAOpD;AAED;;GAEG;AACH,wBAAgB,YAAY,CAAC,KAAK,EAAE,eAAe,GAAG,MAAM,EAAE,EAAE,CAoC/D"}
1
+ {"version":3,"file":"graph.d.ts","sourceRoot":"","sources":["../src/graph.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,KAAK,EAAE,IAAI,EAAE,eAAe,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAExE;;GAEG;AACH,wBAAgB,oBAAoB,CAAC,KAAK,EAAE,IAAI,EAAE,GAAG,eAAe,CA0BnE;AAED;;GAEG;AACH,wBAAgB,eAAe,CAAC,KAAK,EAAE,GAAG,CAAC,MAAM,EAAE,cAAc,CAAC,GAAG,MAAM,EAAE,CA2B5E;AAED;;GAEG;AACH,wBAAgB,aAAa,CAAC,KAAK,EAAE,eAAe,EAAE,MAAM,EAAE,MAAM,GAAG,MAAM,EAAE,CAE9E;AAED;;;;GAIG;AACH,wBAAgB,mBAAmB,CAAC,KAAK,EAAE,eAAe,EAAE,OAAO,EAAE,QAAQ,CAAC,MAAM,CAAC,GAAG,MAAM,EAAE,CAwB/F;AAED;;;;GAIG;AACH,wBAAgB,YAAY,CAAC,KAAK,EAAE,eAAe,EAAE,EAAE,EAAE,MAAM,GAAG,MAAM,EAAE,CAgBzE;AAkCD;;;;;;GAMG;AACH,wBAAgB,SAAS,CAAC,KAAK,EAAE,eAAe,GAAG,MAAM,CAMxD;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,KAAK,CAAC,KAAK,EAAE,eAAe,GAAG,MAAM,CAOpD;AAED;;GAEG;AACH,wBAAgB,YAAY,CAAC,KAAK,EAAE,eAAe,GAAG,MAAM,EAAE,EAAE,CAoC/D"}
package/dist/index.js CHANGED
@@ -1,5 +1,5 @@
1
- import { _ as topologicalSort, a as detectCellType, c as parseWorkbook, d as buildDependencyGraph, f as detectCycles, g as toMermaid, h as toDOT, l as serializeWorkbook, m as getDependents, n as WorkbookExecutor, p as getAncestors, r as createExecutor, t as formatResult, u as stripOutputs } from "./formatter-Dwrza-un.js";
2
- import { _ as toTeX, d as addCell, f as editCell, g as setMetadata, h as renameCell, l as SCHEMA_VERSION, m as removeCell, n as runWorkbookWithTimeout, p as moveCell, r as handleRequest, s as Session, t as WorkbookTimeoutError, u as VERSION } from "./timeout-runner-C249B3OS.js";
1
+ import { _ as toMermaid, a as detectCellType, c as parseWorkbook, d as buildDependencyGraph, f as detectCycles, g as toDOT, l as serializeWorkbook, m as getDependents, n as WorkbookExecutor, p as getAncestors, r as createExecutor, t as formatResult, u as stripOutputs, v as topologicalSort } from "./formatter-ssmPX0Ap.js";
2
+ import { _ as toTeX, d as addCell, f as editCell, g as setMetadata, h as renameCell, l as SCHEMA_VERSION, m as removeCell, n as runWorkbookWithTimeout, p as moveCell, r as handleRequest, s as Session, t as WorkbookTimeoutError, u as VERSION } from "./timeout-runner--KC7NTAV.js";
3
3
  //#region src/svg-math.ts
4
4
  function mathMLToSVG(mathml, options = {}) {
5
5
  const display = options.display ?? "block";
@@ -1,4 +1,4 @@
1
- import { c as parseWorkbook, r as createExecutor, t as formatResult } from "./formatter-Dwrza-un.js";
1
+ import { c as parseWorkbook, r as createExecutor, t as formatResult } from "./formatter-ssmPX0Ap.js";
2
2
  import { parentPort, workerData } from "node:worker_threads";
3
3
  //#region src/run-worker.ts
4
4
  async function main() {
package/dist/session.d.ts CHANGED
@@ -24,6 +24,9 @@ export declare class Session {
24
24
  private cache;
25
25
  private stale;
26
26
  private require;
27
+ /** Memoized dependency graph for the current workbook object (edits yield a new object). */
28
+ private graphCache;
29
+ private graphFor;
27
30
  /** A cell has a usable, up-to-date result (the basis for "not stale"). */
28
31
  private hasValidResult;
29
32
  /** Load a workbook file into the session. Refuses to discard unsaved edits. */
@@ -1 +1 @@
1
- {"version":3,"file":"session.d.ts","sourceRoot":"","sources":["../src/session.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAGH,OAAO,KAAK,EAAE,QAAQ,EAAoB,SAAS,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AAKlF,OAAO,KAAK,IAAI,MAAM,WAAW,CAAC;AAWlC;;;;;;;;GAQG;AACH,qBAAa,OAAO;IAClB,QAAQ,EAAE,QAAQ,GAAG,IAAI,CAAQ;IACjC,IAAI,EAAE,MAAM,GAAG,IAAI,CAAQ;IAC3B,KAAK,UAAS;IACd,OAAO,CAAC,KAAK,CAAiC;IAC9C,OAAO,CAAC,KAAK,CAAqB;IAElC,OAAO,CAAC,OAAO;IAKf,0EAA0E;IAC1E,OAAO,CAAC,cAAc;IAKtB,+EAA+E;IAC/E,IAAI,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE;QAAE,KAAK,CAAC,EAAE,OAAO,CAAA;KAAE,GAAG,IAAI,CActD;IAED,8EAA8E;IAC9E,OAAO,CAAC,MAAM;IAgCd,OAAO,CACL,IAAI,EAAE;QAAE,EAAE,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,QAAQ,CAAC;QAAC,OAAO,CAAC,EAAE,MAAM,CAAC;QAAC,SAAS,CAAC,EAAE,MAAM,EAAE,CAAA;KAAE,EAC5E,QAAQ,CAAC,EAAE,IAAI,CAAC,YAAY,GAC3B,IAAI,CAEN;IACD,QAAQ,CAAC,EAAE,EAAE,MAAM,EAAE,OAAO,EAAE;QAAE,OAAO,CAAC,EAAE,MAAM,CAAC;QAAC,IAAI,CAAC,EAAE,QAAQ,CAAC;QAAC,SAAS,CAAC,EAAE,MAAM,EAAE,CAAA;KAAE,GAAG,IAAI,CAE/F;IACD,UAAU,CAAC,EAAE,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE;QAAE,KAAK,CAAC,EAAE,OAAO,CAAA;KAAE,GAAG,MAAM,EAAE,CAI9D;IACD,QAAQ,CAAC,EAAE,EAAE,MAAM,EAAE,QAAQ,EAAE,IAAI,CAAC,YAAY,GAAG,IAAI,CAEtD;IACD,UAAU,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,IAAI,CAE7C;IACD,WAAW,CAAC,OAAO,EAAE;QACnB,KAAK,CAAC,EAAE,MAAM,CAAC;QACf,MAAM,CAAC,EAAE,MAAM,CAAC;QAChB,WAAW,CAAC,EAAE,MAAM,CAAC;QACrB,IAAI,CAAC,EAAE,MAAM,EAAE,CAAC;KACjB,GAAG,IAAI,CAEP;IAED;;;;OAIG;IACG,GAAG,CAAC,IAAI,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC;QAAE,MAAM,EAAE,SAAS,CAAC;QAAC,MAAM,EAAE,iBAAiB,EAAE,CAAA;KAAE,CAAC,CAwCpF;IAED,gDAAgD;IAChD,QAAQ,IAAI,MAAM,EAAE,CAEnB;IAED,8DAA8D;IAC9D,IAAI,CAAC,IAAI,CAAC,EAAE,MAAM,GAAG,MAAM,CAQ1B;CACF;AAED,mFAAmF;AACnF,MAAM,WAAW,iBAAiB;IAChC,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB"}
1
+ {"version":3,"file":"session.d.ts","sourceRoot":"","sources":["../src/session.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAGH,OAAO,KAAK,EAAE,QAAQ,EAAqC,SAAS,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AAKnG,OAAO,KAAK,IAAI,MAAM,WAAW,CAAC;AAWlC;;;;;;;;GAQG;AACH,qBAAa,OAAO;IAClB,QAAQ,EAAE,QAAQ,GAAG,IAAI,CAAQ;IACjC,IAAI,EAAE,MAAM,GAAG,IAAI,CAAQ;IAC3B,KAAK,UAAS;IACd,OAAO,CAAC,KAAK,CAAiC;IAC9C,OAAO,CAAC,KAAK,CAAqB;IAElC,OAAO,CAAC,OAAO;IAKf,4FAA4F;IAC5F,OAAO,CAAC,UAAU,CAAuD;IAEzE,OAAO,CAAC,QAAQ;IAKhB,0EAA0E;IAC1E,OAAO,CAAC,cAAc;IAKtB,+EAA+E;IAC/E,IAAI,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE;QAAE,KAAK,CAAC,EAAE,OAAO,CAAA;KAAE,GAAG,IAAI,CActD;IAED,8EAA8E;IAC9E,OAAO,CAAC,MAAM;IA8Bd,OAAO,CACL,IAAI,EAAE;QAAE,EAAE,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,QAAQ,CAAC;QAAC,OAAO,CAAC,EAAE,MAAM,CAAC;QAAC,SAAS,CAAC,EAAE,MAAM,EAAE,CAAA;KAAE,EAC5E,QAAQ,CAAC,EAAE,IAAI,CAAC,YAAY,GAC3B,IAAI,CAEN;IACD,QAAQ,CAAC,EAAE,EAAE,MAAM,EAAE,OAAO,EAAE;QAAE,OAAO,CAAC,EAAE,MAAM,CAAC;QAAC,IAAI,CAAC,EAAE,QAAQ,CAAC;QAAC,SAAS,CAAC,EAAE,MAAM,EAAE,CAAA;KAAE,GAAG,IAAI,CAE/F;IACD,UAAU,CAAC,EAAE,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE;QAAE,KAAK,CAAC,EAAE,OAAO,CAAA;KAAE,GAAG,MAAM,EAAE,CAI9D;IACD,QAAQ,CAAC,EAAE,EAAE,MAAM,EAAE,QAAQ,EAAE,IAAI,CAAC,YAAY,GAAG,IAAI,CAEtD;IACD,UAAU,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,IAAI,CAE7C;IACD,WAAW,CAAC,OAAO,EAAE;QACnB,KAAK,CAAC,EAAE,MAAM,CAAC;QACf,MAAM,CAAC,EAAE,MAAM,CAAC;QAChB,WAAW,CAAC,EAAE,MAAM,CAAC;QACrB,IAAI,CAAC,EAAE,MAAM,EAAE,CAAC;KACjB,GAAG,IAAI,CAEP;IAED;;;;OAIG;IACG,GAAG,CAAC,IAAI,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC;QAAE,MAAM,EAAE,SAAS,CAAC;QAAC,MAAM,EAAE,iBAAiB,EAAE,CAAA;KAAE,CAAC,CAwCpF;IAED,gDAAgD;IAChD,QAAQ,IAAI,MAAM,EAAE,CAEnB;IAED,8DAA8D;IAC9D,IAAI,CAAC,IAAI,CAAC,EAAE,MAAM,GAAG,MAAM,CAQ1B;CACF;AAED,mFAAmF;AACnF,MAAM,WAAW,iBAAiB;IAChC,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB"}
@@ -1,4 +1,4 @@
1
- import { c as parseWorkbook, d as buildDependencyGraph, f as detectCycles, i as SUPPORTED_CELL_TYPES, l as serializeWorkbook, m as getDependents, n as WorkbookExecutor, p as getAncestors, s as isValidIdentifier } from "./formatter-Dwrza-un.js";
1
+ import { c as parseWorkbook, d as buildDependencyGraph, f as detectCycles, h as getDependentsOfMany, i as SUPPORTED_CELL_TYPES, l as serializeWorkbook, n as WorkbookExecutor, p as getAncestors, s as isValidIdentifier } from "./formatter-ssmPX0Ap.js";
2
2
  import * as mathFunctions from "@danielsimonjr/mathts-functions";
3
3
  import { bar, line, scatter } from "@danielsimonjr/mathts-plot";
4
4
  import { readFileSync, renameSync, unlinkSync, writeFileSync } from "node:fs";
@@ -456,7 +456,7 @@ const SCHEMA_VERSION = {
456
456
  major: 1,
457
457
  minor: 0
458
458
  };
459
- const VERSION = "0.5.0";
459
+ const VERSION = "0.5.2";
460
460
  const COMMAND_NAMES = [
461
461
  "run",
462
462
  "describe",
@@ -532,6 +532,14 @@ var Session = class {
532
532
  if (!this.workbook) throw new Error("No workbook open");
533
533
  return this.workbook;
534
534
  }
535
+ graphCache;
536
+ graphFor(wb) {
537
+ if (this.graphCache?.wb !== wb) this.graphCache = {
538
+ wb,
539
+ graph: buildDependencyGraph(wb.cells)
540
+ };
541
+ return this.graphCache.graph;
542
+ }
535
543
  hasValidResult(id) {
536
544
  const r = this.cache.get(id);
537
545
  return r !== void 0 && (r.status === "success" || r.status === "pass");
@@ -555,9 +563,9 @@ var Session = class {
555
563
  const prev = oldCanonical.get(cell.id);
556
564
  if (prev === void 0 || prev !== canonicalCell(cell)) changed.add(cell.id);
557
565
  }
558
- const graph = buildDependencyGraph(next.cells);
566
+ const graph = this.graphFor(next);
559
567
  const affected = new Set(changed);
560
- for (const id of changed) for (const dep of getDependents(graph, id)) affected.add(dep);
568
+ for (const dep of getDependentsOfMany(graph, changed)) affected.add(dep);
561
569
  const survivingIds = new Set(next.cells.map((c) => c.id));
562
570
  for (const id of [...this.cache.keys()]) if (!survivingIds.has(id) || affected.has(id)) this.cache.delete(id);
563
571
  this.stale = new Set(next.cells.map((c) => c.id).filter((id) => !this.hasValidResult(id)));
@@ -586,7 +594,7 @@ var Session = class {
586
594
  }
587
595
  async run(only) {
588
596
  const wb = this.require();
589
- const graph = buildDependencyGraph(wb.cells);
597
+ const graph = this.graphFor(wb);
590
598
  const target = only ? new Set(getAncestors(graph, only)) : new Set(wb.cells.map((c) => c.id));
591
599
  const toRun = new Set([...this.stale].filter((id) => target.has(id)));
592
600
  const executor = new WorkbookExecutor(wb);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@danielsimonjr/mathts-workbook",
3
- "version": "0.5.0",
3
+ "version": "0.5.2",
4
4
  "description": "Scientific workbook runtime for MathTS (.mtsw format)",
5
5
  "author": "Daniel Simon Jr.",
6
6
  "license": "MIT",
@@ -34,10 +34,10 @@
34
34
  "build:prod": "tsdown --minify && tsc -p tsconfig.dts.json"
35
35
  },
36
36
  "dependencies": {
37
- "@danielsimonjr/mathts-core": "^0.20.0",
38
- "@danielsimonjr/mathts-expression": "^0.11.0",
39
- "@danielsimonjr/mathts-functions": "^0.70.0",
40
- "@danielsimonjr/mathts-plot": "^0.4.14",
37
+ "@danielsimonjr/mathts-core": "^0.21.1",
38
+ "@danielsimonjr/mathts-expression": "^0.12.0",
39
+ "@danielsimonjr/mathts-functions": "^0.71.0",
40
+ "@danielsimonjr/mathts-plot": "^0.4.16",
41
41
  "yaml": "^2.3.0"
42
42
  },
43
43
  "devDependencies": {