@bian-womp/spark-graph 0.2.87 → 0.2.89
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 +74 -32
- package/lib/cjs/index.cjs.map +1 -1
- package/lib/cjs/src/runtime/GraphRuntime.d.ts +6 -0
- package/lib/cjs/src/runtime/GraphRuntime.d.ts.map +1 -1
- package/lib/esm/index.js +74 -32
- package/lib/esm/index.js.map +1 -1
- package/lib/esm/src/runtime/GraphRuntime.d.ts +6 -0
- package/lib/esm/src/runtime/GraphRuntime.d.ts.map +1 -1
- package/package.json +2 -2
package/lib/cjs/index.cjs
CHANGED
|
@@ -760,6 +760,7 @@ class GraphRuntime {
|
|
|
760
760
|
this.emit("stats", {
|
|
761
761
|
kind: "node-progress",
|
|
762
762
|
nodeId,
|
|
763
|
+
typeId: node.typeId,
|
|
763
764
|
runId,
|
|
764
765
|
progress: node.stats.progress,
|
|
765
766
|
});
|
|
@@ -776,15 +777,16 @@ class GraphRuntime {
|
|
|
776
777
|
await node.runtime.onInputsChanged?.(capturedInputs, ctx);
|
|
777
778
|
}
|
|
778
779
|
catch (err) {
|
|
779
|
-
// Suppress errors caused by expected cancellations
|
|
780
|
+
// Suppress errors caused by expected cancellations
|
|
780
781
|
if (controller.signal.aborted) {
|
|
781
782
|
const reason = controller.signal.reason;
|
|
782
|
-
if (reason === "switch" ||
|
|
783
|
-
|
|
783
|
+
if (reason === "switch" ||
|
|
784
|
+
reason === "snapshot" ||
|
|
785
|
+
reason === "node-deleted") {
|
|
786
|
+
return; // Cancellation events are emitted separately, skip error handling
|
|
784
787
|
}
|
|
785
788
|
}
|
|
786
789
|
hadError = true;
|
|
787
|
-
// Record last error for node
|
|
788
790
|
node.stats.lastError = err;
|
|
789
791
|
const retry = policy.retry;
|
|
790
792
|
if (retry && attempt < (retry.attempts ?? 0)) {
|
|
@@ -795,6 +797,10 @@ class GraphRuntime {
|
|
|
795
797
|
this.emit("error", { kind: "node-run", nodeId, runId, err });
|
|
796
798
|
}
|
|
797
799
|
finally {
|
|
800
|
+
// Skip cleanup if node was deleted (cleanup already handled)
|
|
801
|
+
if (!this.nodes.has(nodeId)) {
|
|
802
|
+
return;
|
|
803
|
+
}
|
|
798
804
|
if (timeoutId)
|
|
799
805
|
clearTimeout(timeoutId);
|
|
800
806
|
node.activeControllers.delete(controller);
|
|
@@ -805,15 +811,21 @@ class GraphRuntime {
|
|
|
805
811
|
node.stats.lastStartAt && node.stats.lastEndAt
|
|
806
812
|
? node.stats.lastEndAt - node.stats.lastStartAt
|
|
807
813
|
: undefined;
|
|
808
|
-
// Clear lastError upon successful completion
|
|
809
814
|
if (!hadError)
|
|
810
815
|
node.stats.lastError = undefined;
|
|
811
|
-
|
|
812
|
-
|
|
813
|
-
|
|
814
|
-
|
|
815
|
-
|
|
816
|
-
|
|
816
|
+
// Only emit node-done if not cancelled (cancellation events emitted separately)
|
|
817
|
+
const isCancelled = controller.signal.aborted &&
|
|
818
|
+
(controller.signal.reason === "snapshot" ||
|
|
819
|
+
controller.signal.reason === "node-deleted");
|
|
820
|
+
if (!isCancelled) {
|
|
821
|
+
this.emit("stats", {
|
|
822
|
+
kind: "node-done",
|
|
823
|
+
nodeId,
|
|
824
|
+
typeId: node.typeId,
|
|
825
|
+
runId,
|
|
826
|
+
durationMs: node.stats.lastDurationMs,
|
|
827
|
+
});
|
|
828
|
+
}
|
|
817
829
|
ctx.log("debug", "node-done", {
|
|
818
830
|
durationMs: node.stats.lastDurationMs,
|
|
819
831
|
hadError,
|
|
@@ -823,7 +835,12 @@ class GraphRuntime {
|
|
|
823
835
|
}
|
|
824
836
|
};
|
|
825
837
|
// fire node-start event
|
|
826
|
-
this.emit("stats", {
|
|
838
|
+
this.emit("stats", {
|
|
839
|
+
kind: "node-start",
|
|
840
|
+
nodeId,
|
|
841
|
+
typeId: node.typeId,
|
|
842
|
+
runId,
|
|
843
|
+
});
|
|
827
844
|
ctx.log("debug", "node-start");
|
|
828
845
|
exec(0);
|
|
829
846
|
};
|
|
@@ -1019,6 +1036,7 @@ class GraphRuntime {
|
|
|
1019
1036
|
this.emit("stats", {
|
|
1020
1037
|
kind: "edge-start",
|
|
1021
1038
|
edgeId: e.id,
|
|
1039
|
+
typeId: e.typeId,
|
|
1022
1040
|
source: { nodeId: e.source.nodeId, handle: e.source.handle },
|
|
1023
1041
|
target: { nodeId: e.target.nodeId, handle: e.target.handle },
|
|
1024
1042
|
});
|
|
@@ -1039,6 +1057,7 @@ class GraphRuntime {
|
|
|
1039
1057
|
this.emit("stats", {
|
|
1040
1058
|
kind: "edge-done",
|
|
1041
1059
|
edgeId: e.id,
|
|
1060
|
+
typeId: e.typeId,
|
|
1042
1061
|
source: { nodeId: e.source.nodeId, handle: e.source.handle },
|
|
1043
1062
|
target: { nodeId: e.target.nodeId, handle: e.target.handle },
|
|
1044
1063
|
durationMs: e.stats.lastDurationMs,
|
|
@@ -1352,12 +1371,50 @@ class GraphRuntime {
|
|
|
1352
1371
|
scheduleInputsChanged(nodeId) {
|
|
1353
1372
|
this.scheduleInputsChangedInternal(nodeId);
|
|
1354
1373
|
}
|
|
1374
|
+
/**
|
|
1375
|
+
* Cancel all active runs for a node and emit cancellation events
|
|
1376
|
+
* @param node - The node to cancel runs for
|
|
1377
|
+
* @param reason - The cancellation reason ("snapshot" | "node-deleted")
|
|
1378
|
+
*/
|
|
1379
|
+
cancelNodeActiveRuns(node, reason) {
|
|
1380
|
+
for (const controller of Array.from(node.activeControllers)) {
|
|
1381
|
+
const runId = node.controllerRunIds.get(controller);
|
|
1382
|
+
if (runId) {
|
|
1383
|
+
// Track cancelled runIds for snapshot operations
|
|
1384
|
+
if (reason === "snapshot") {
|
|
1385
|
+
if (!node.snapshotCancelledRunIds) {
|
|
1386
|
+
node.snapshotCancelledRunIds = new Set();
|
|
1387
|
+
}
|
|
1388
|
+
node.snapshotCancelledRunIds.add(runId);
|
|
1389
|
+
}
|
|
1390
|
+
// Emit cancellation event
|
|
1391
|
+
this.emit("stats", {
|
|
1392
|
+
kind: "node-done",
|
|
1393
|
+
nodeId: node.nodeId,
|
|
1394
|
+
typeId: node.typeId,
|
|
1395
|
+
runId,
|
|
1396
|
+
cancelled: true,
|
|
1397
|
+
});
|
|
1398
|
+
}
|
|
1399
|
+
try {
|
|
1400
|
+
controller.abort(reason);
|
|
1401
|
+
}
|
|
1402
|
+
catch {
|
|
1403
|
+
// ignore abort errors
|
|
1404
|
+
}
|
|
1405
|
+
}
|
|
1406
|
+
node.activeControllers.clear();
|
|
1407
|
+
node.controllerRunIds.clear();
|
|
1408
|
+
node.stats.active = 0;
|
|
1409
|
+
node.queue = [];
|
|
1410
|
+
}
|
|
1355
1411
|
cancelNodeRuns(nodeIds) {
|
|
1356
1412
|
if (nodeIds.length === 0)
|
|
1357
1413
|
return;
|
|
1358
1414
|
const toCancel = new Set(nodeIds);
|
|
1359
1415
|
const visited = new Set();
|
|
1360
1416
|
const queue = [...nodeIds];
|
|
1417
|
+
// Collect all downstream nodes to cancel
|
|
1361
1418
|
for (let i = 0; i < queue.length; i++) {
|
|
1362
1419
|
const nodeId = queue[i];
|
|
1363
1420
|
if (visited.has(nodeId))
|
|
@@ -1373,29 +1430,12 @@ class GraphRuntime {
|
|
|
1373
1430
|
}
|
|
1374
1431
|
}
|
|
1375
1432
|
}
|
|
1433
|
+
// Cancel runs for all affected nodes
|
|
1376
1434
|
for (const nodeId of toCancel) {
|
|
1377
1435
|
const node = this.nodes.get(nodeId);
|
|
1378
1436
|
if (!node)
|
|
1379
1437
|
continue;
|
|
1380
|
-
|
|
1381
|
-
node.snapshotCancelledRunIds = new Set();
|
|
1382
|
-
}
|
|
1383
|
-
for (const controller of Array.from(node.activeControllers)) {
|
|
1384
|
-
const rid = node.controllerRunIds.get(controller);
|
|
1385
|
-
if (rid) {
|
|
1386
|
-
node.snapshotCancelledRunIds.add(rid);
|
|
1387
|
-
}
|
|
1388
|
-
try {
|
|
1389
|
-
controller.abort("snapshot");
|
|
1390
|
-
}
|
|
1391
|
-
catch {
|
|
1392
|
-
// ignore
|
|
1393
|
-
}
|
|
1394
|
-
}
|
|
1395
|
-
node.activeControllers.clear();
|
|
1396
|
-
node.controllerRunIds.clear();
|
|
1397
|
-
node.stats.active = 0;
|
|
1398
|
-
node.queue = [];
|
|
1438
|
+
this.cancelNodeActiveRuns(node, "snapshot");
|
|
1399
1439
|
node.runSeq += 1;
|
|
1400
1440
|
const now = Date.now();
|
|
1401
1441
|
node.latestRunId = `${nodeId}:${node.runSeq}:${now}:snapshot`;
|
|
@@ -1458,6 +1498,9 @@ class GraphRuntime {
|
|
|
1458
1498
|
for (const nodeId of Array.from(currentIds)) {
|
|
1459
1499
|
if (!desiredIds.has(nodeId)) {
|
|
1460
1500
|
const node = this.nodes.get(nodeId);
|
|
1501
|
+
// Cancel all active runs and emit cancellation events
|
|
1502
|
+
this.cancelNodeActiveRuns(node, "node-deleted");
|
|
1503
|
+
// Cleanup node resources
|
|
1461
1504
|
node.runtime.onDeactivated?.();
|
|
1462
1505
|
node.runtime.dispose?.();
|
|
1463
1506
|
node.lifecycle?.dispose?.({
|
|
@@ -1465,7 +1508,6 @@ class GraphRuntime {
|
|
|
1465
1508
|
setState: (next) => Object.assign(node.state, next),
|
|
1466
1509
|
});
|
|
1467
1510
|
this.nodes.delete(nodeId);
|
|
1468
|
-
// Clear any array buckets for this node
|
|
1469
1511
|
this.arrayInputBuckets.delete(nodeId);
|
|
1470
1512
|
}
|
|
1471
1513
|
}
|