@bian-womp/spark-graph 0.2.68 → 0.2.70

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/lib/cjs/index.cjs CHANGED
@@ -770,11 +770,11 @@ class GraphRuntime {
770
770
  await node.runtime.onInputsChanged?.(capturedInputs, ctx);
771
771
  }
772
772
  catch (err) {
773
- // Suppress errors caused by expected cancellations (switch)
773
+ // Suppress errors caused by expected cancellations (switch, snapshot)
774
774
  if (controller.signal.aborted) {
775
775
  const reason = controller.signal.reason;
776
- if (reason === "switch") {
777
- return; // ignore switched runs
776
+ if (reason === "switch" || reason === "snapshot") {
777
+ return; // ignore switched/snapshot-cancelled runs
778
778
  }
779
779
  }
780
780
  hadError = true;
@@ -1345,6 +1345,47 @@ class GraphRuntime {
1345
1345
  scheduleInputsChanged(nodeId) {
1346
1346
  this.scheduleInputsChangedInternal(nodeId);
1347
1347
  }
1348
+ cancelNodeRuns(nodeIds) {
1349
+ if (nodeIds.length === 0)
1350
+ return;
1351
+ const toCancel = new Set(nodeIds);
1352
+ const visited = new Set();
1353
+ const queue = [...nodeIds];
1354
+ for (let i = 0; i < queue.length; i++) {
1355
+ const nodeId = queue[i];
1356
+ if (visited.has(nodeId))
1357
+ continue;
1358
+ visited.add(nodeId);
1359
+ for (const edge of this.edges) {
1360
+ if (edge.source.nodeId === nodeId) {
1361
+ const targetId = edge.target.nodeId;
1362
+ if (!visited.has(targetId)) {
1363
+ toCancel.add(targetId);
1364
+ queue.push(targetId);
1365
+ }
1366
+ }
1367
+ }
1368
+ }
1369
+ for (const nodeId of toCancel) {
1370
+ const node = this.nodes.get(nodeId);
1371
+ if (!node)
1372
+ continue;
1373
+ for (const controller of Array.from(node.activeControllers)) {
1374
+ try {
1375
+ controller.abort("snapshot");
1376
+ }
1377
+ catch {
1378
+ // ignore
1379
+ }
1380
+ }
1381
+ node.activeControllers.clear();
1382
+ node.stats.active = 0;
1383
+ node.queue = [];
1384
+ node.runSeq += 1;
1385
+ const now = Date.now();
1386
+ node.latestRunId = `${nodeId}:${node.runSeq}:${now}:snapshot`;
1387
+ }
1388
+ }
1348
1389
  // Hydrate inputs/outputs without triggering computation; optionally re-emit outputs downstream
1349
1390
  hydrate(payload, opts) {
1350
1391
  const prevPaused = this.paused;