@bian-womp/spark-graph 0.2.46 → 0.2.48
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 +86 -42
- package/lib/cjs/index.cjs.map +1 -1
- package/lib/cjs/src/core/types.d.ts +2 -1
- package/lib/cjs/src/core/types.d.ts.map +1 -1
- package/lib/cjs/src/index.d.ts +1 -0
- package/lib/cjs/src/index.d.ts.map +1 -1
- package/lib/cjs/src/runtime/EngineFactory.d.ts +10 -0
- package/lib/cjs/src/runtime/EngineFactory.d.ts.map +1 -0
- package/lib/cjs/src/runtime/GraphRuntime.d.ts +5 -4
- package/lib/cjs/src/runtime/GraphRuntime.d.ts.map +1 -1
- package/lib/cjs/src/runtime/HybridEngine.d.ts.map +1 -1
- package/lib/esm/index.js +86 -43
- package/lib/esm/index.js.map +1 -1
- package/lib/esm/src/core/types.d.ts +2 -1
- package/lib/esm/src/core/types.d.ts.map +1 -1
- package/lib/esm/src/index.d.ts +1 -0
- package/lib/esm/src/index.d.ts.map +1 -1
- package/lib/esm/src/runtime/EngineFactory.d.ts +10 -0
- package/lib/esm/src/runtime/EngineFactory.d.ts.map +1 -0
- package/lib/esm/src/runtime/GraphRuntime.d.ts +5 -4
- package/lib/esm/src/runtime/GraphRuntime.d.ts.map +1 -1
- package/lib/esm/src/runtime/HybridEngine.d.ts.map +1 -1
- package/package.json +2 -2
package/lib/cjs/index.cjs
CHANGED
|
@@ -566,7 +566,7 @@ class GraphRuntime {
|
|
|
566
566
|
if (!this.paused) {
|
|
567
567
|
// Only schedule if all inbound inputs are present (or there are none)
|
|
568
568
|
if (anyChanged && this.allInboundHaveValue(nodeId))
|
|
569
|
-
this.
|
|
569
|
+
this.scheduleInputsChangedInternal(nodeId);
|
|
570
570
|
// Recompute dynamic handles for this node when its direct inputs change
|
|
571
571
|
if (anyChanged)
|
|
572
572
|
this.scheduleRecomputeHandles(nodeId);
|
|
@@ -639,7 +639,31 @@ class GraphRuntime {
|
|
|
639
639
|
},
|
|
640
640
|
};
|
|
641
641
|
}
|
|
642
|
-
|
|
642
|
+
createExecutionContext(nodeId, node, inputs, runId, abortSignal, options) {
|
|
643
|
+
const emitHandler = options?.emitHandler ??
|
|
644
|
+
((handle, value) => this.propagate(nodeId, handle, value));
|
|
645
|
+
const reportProgress = options?.reportProgress ??
|
|
646
|
+
((p) => {
|
|
647
|
+
node.stats.progress = Math.max(0, Math.min(1, Number(p) || 0));
|
|
648
|
+
});
|
|
649
|
+
return {
|
|
650
|
+
state: node.state,
|
|
651
|
+
setState: (next) => Object.assign(node.state, next),
|
|
652
|
+
emit: emitHandler,
|
|
653
|
+
invalidateDownstream: () => this.invalidateDownstreamInternal(nodeId),
|
|
654
|
+
scheduleInputsChanged: () => {
|
|
655
|
+
if (this.allInboundHaveValue(nodeId)) {
|
|
656
|
+
this.scheduleInputsChangedInternal(nodeId);
|
|
657
|
+
}
|
|
658
|
+
},
|
|
659
|
+
getInput: (handle) => inputs[handle],
|
|
660
|
+
environment: this.environment,
|
|
661
|
+
runId,
|
|
662
|
+
abortSignal,
|
|
663
|
+
reportProgress,
|
|
664
|
+
};
|
|
665
|
+
}
|
|
666
|
+
scheduleInputsChangedInternal(nodeId) {
|
|
643
667
|
const node = this.nodes.get(nodeId);
|
|
644
668
|
if (!node)
|
|
645
669
|
return;
|
|
@@ -681,24 +705,13 @@ class GraphRuntime {
|
|
|
681
705
|
if (policy.timeoutMs && policy.timeoutMs > 0) {
|
|
682
706
|
timeoutId = setTimeout(() => controller.abort("timeout"), policy.timeoutMs);
|
|
683
707
|
}
|
|
684
|
-
const ctx = {
|
|
685
|
-
|
|
686
|
-
environment: this.environment,
|
|
687
|
-
runId,
|
|
688
|
-
abortSignal: controller.signal,
|
|
689
|
-
setState: (next) => Object.assign(node.state, next),
|
|
690
|
-
emit: (handle, value) => {
|
|
708
|
+
const ctx = this.createExecutionContext(nodeId, node, capturedInputs, runId, controller.signal, {
|
|
709
|
+
emitHandler: (handle, value) => {
|
|
691
710
|
const m = policy.asyncConcurrency ?? "switch";
|
|
692
711
|
if (m !== "merge" && runId !== node.latestRunId)
|
|
693
712
|
return;
|
|
694
713
|
this.propagate(nodeId, handle, value);
|
|
695
714
|
},
|
|
696
|
-
invalidateDownstream: () => this.invalidateDownstream(nodeId),
|
|
697
|
-
scheduleInputsChanged: () => {
|
|
698
|
-
if (this.allInboundHaveValue(nodeId)) {
|
|
699
|
-
this.scheduleInputsChanged(nodeId);
|
|
700
|
-
}
|
|
701
|
-
},
|
|
702
715
|
reportProgress: (p) => {
|
|
703
716
|
node.stats.progress = Math.max(0, Math.min(1, Number(p) || 0));
|
|
704
717
|
this.emit("stats", {
|
|
@@ -708,10 +721,11 @@ class GraphRuntime {
|
|
|
708
721
|
progress: node.stats.progress,
|
|
709
722
|
});
|
|
710
723
|
},
|
|
711
|
-
};
|
|
724
|
+
});
|
|
712
725
|
const exec = async (attempt) => {
|
|
713
726
|
let hadError = false;
|
|
714
727
|
try {
|
|
728
|
+
node.lifecycle?.prepare?.(node.params ?? {}, ctx);
|
|
715
729
|
await node.runtime.onInputsChanged?.(capturedInputs, ctx);
|
|
716
730
|
}
|
|
717
731
|
catch (err) {
|
|
@@ -853,7 +867,7 @@ class GraphRuntime {
|
|
|
853
867
|
}
|
|
854
868
|
return effective;
|
|
855
869
|
}
|
|
856
|
-
|
|
870
|
+
invalidateDownstreamInternal(nodeId) {
|
|
857
871
|
// Notifies dependents; for now we propagate current outputs
|
|
858
872
|
for (const e of this.edges.filter((e) => e.source.nodeId === nodeId)) {
|
|
859
873
|
const value = this.getOutput(nodeId, e.source.handle);
|
|
@@ -946,7 +960,7 @@ class GraphRuntime {
|
|
|
946
960
|
// Recompute dynamic handles for the destination node on input change
|
|
947
961
|
this.scheduleRecomputeHandles(e.target.nodeId);
|
|
948
962
|
if (!this.paused && this.allInboundHaveValue(e.target.nodeId))
|
|
949
|
-
this.
|
|
963
|
+
this.scheduleInputsChangedInternal(e.target.nodeId);
|
|
950
964
|
}
|
|
951
965
|
};
|
|
952
966
|
if (e.convertAsync) {
|
|
@@ -1148,22 +1162,22 @@ class GraphRuntime {
|
|
|
1148
1162
|
}
|
|
1149
1163
|
}
|
|
1150
1164
|
// Invalidate downstream for this node so UI refreshes
|
|
1151
|
-
this.
|
|
1165
|
+
this.invalidateDownstreamInternal(nodeId);
|
|
1152
1166
|
}
|
|
1153
1167
|
launch(invalidate = false) {
|
|
1154
1168
|
// call onActivated for nodes that implement it
|
|
1155
1169
|
for (const node of this.nodes.values()) {
|
|
1156
|
-
|
|
1157
|
-
|
|
1158
|
-
|
|
1159
|
-
});
|
|
1170
|
+
const effectiveInputs = this.getEffectiveInputs(node.nodeId);
|
|
1171
|
+
const ctrl = new AbortController();
|
|
1172
|
+
const ctx = this.createExecutionContext(node.nodeId, node, effectiveInputs, `${node.nodeId}:init`, ctrl.signal);
|
|
1173
|
+
node.lifecycle?.prepare?.(node.params ?? {}, ctx);
|
|
1160
1174
|
node.runtime.onActivated?.();
|
|
1161
1175
|
}
|
|
1162
1176
|
if (invalidate) {
|
|
1163
1177
|
// After activation, schedule nodes that have all inbound inputs present
|
|
1164
1178
|
for (const nodeId of this.nodes.keys()) {
|
|
1165
1179
|
if (this.allInboundHaveValue(nodeId))
|
|
1166
|
-
this.
|
|
1180
|
+
this.scheduleInputsChangedInternal(nodeId);
|
|
1167
1181
|
}
|
|
1168
1182
|
}
|
|
1169
1183
|
}
|
|
@@ -1176,9 +1190,9 @@ class GraphRuntime {
|
|
|
1176
1190
|
typeof event === "object" &&
|
|
1177
1191
|
event.type === "invalidate") {
|
|
1178
1192
|
if (this.allInboundHaveValue(nodeId))
|
|
1179
|
-
this.
|
|
1193
|
+
this.scheduleInputsChangedInternal(nodeId);
|
|
1180
1194
|
else
|
|
1181
|
-
this.
|
|
1195
|
+
this.invalidateDownstreamInternal(nodeId);
|
|
1182
1196
|
}
|
|
1183
1197
|
else {
|
|
1184
1198
|
node.runtime.onExternalEvent?.(event, node.state);
|
|
@@ -1281,11 +1295,11 @@ class GraphRuntime {
|
|
|
1281
1295
|
resume() {
|
|
1282
1296
|
this.paused = false;
|
|
1283
1297
|
}
|
|
1284
|
-
|
|
1285
|
-
this.
|
|
1298
|
+
invalidateDownstream(nodeId) {
|
|
1299
|
+
this.invalidateDownstreamInternal(nodeId);
|
|
1286
1300
|
}
|
|
1287
|
-
|
|
1288
|
-
this.
|
|
1301
|
+
scheduleInputsChanged(nodeId) {
|
|
1302
|
+
this.scheduleInputsChangedInternal(nodeId);
|
|
1289
1303
|
}
|
|
1290
1304
|
// Hydrate inputs/outputs without triggering computation; optionally re-emit outputs downstream
|
|
1291
1305
|
hydrate(payload, opts) {
|
|
@@ -1399,10 +1413,10 @@ class GraphRuntime {
|
|
|
1399
1413
|
};
|
|
1400
1414
|
this.nodes.set(n.nodeId, rn);
|
|
1401
1415
|
// Activate new node
|
|
1402
|
-
|
|
1403
|
-
|
|
1404
|
-
|
|
1405
|
-
});
|
|
1416
|
+
const effectiveInputs = this.getEffectiveInputs(rn.nodeId);
|
|
1417
|
+
const ctrl = new AbortController();
|
|
1418
|
+
const ctx = this.createExecutionContext(rn.nodeId, rn, effectiveInputs, `${rn.nodeId}:init`, ctrl.signal);
|
|
1419
|
+
rn.lifecycle?.prepare?.(rn.params ?? {}, ctx);
|
|
1406
1420
|
rn.runtime.onActivated?.();
|
|
1407
1421
|
}
|
|
1408
1422
|
else {
|
|
@@ -1482,7 +1496,7 @@ class GraphRuntime {
|
|
|
1482
1496
|
if (bucketsForNode.size === 0)
|
|
1483
1497
|
this.arrayInputBuckets.delete(nodeId);
|
|
1484
1498
|
}
|
|
1485
|
-
this.
|
|
1499
|
+
this.scheduleInputsChangedInternal(nodeId);
|
|
1486
1500
|
}
|
|
1487
1501
|
}
|
|
1488
1502
|
// Re-emit outputs when per-handle target sets change (precise and simple)
|
|
@@ -1525,7 +1539,7 @@ class GraphRuntime {
|
|
|
1525
1539
|
if (val !== undefined)
|
|
1526
1540
|
this.propagate(nodeId, handle, val);
|
|
1527
1541
|
else if (this.allInboundHaveValue(nodeId))
|
|
1528
|
-
this.
|
|
1542
|
+
this.scheduleInputsChangedInternal(nodeId);
|
|
1529
1543
|
}
|
|
1530
1544
|
}
|
|
1531
1545
|
}
|
|
@@ -1905,7 +1919,7 @@ class BatchedEngine extends AbstractEngine {
|
|
|
1905
1919
|
this.dirtyNodes.clear();
|
|
1906
1920
|
this.graphRuntime.resume();
|
|
1907
1921
|
for (const n of nodes)
|
|
1908
|
-
this.graphRuntime.
|
|
1922
|
+
this.graphRuntime.scheduleInputsChanged(n);
|
|
1909
1923
|
await this.graphRuntime.whenIdle();
|
|
1910
1924
|
this.graphRuntime.pause();
|
|
1911
1925
|
}
|
|
@@ -1926,7 +1940,7 @@ class PullEngine extends AbstractEngine {
|
|
|
1926
1940
|
// Pull API
|
|
1927
1941
|
async computeNode(nodeId) {
|
|
1928
1942
|
this.graphRuntime.resume();
|
|
1929
|
-
this.graphRuntime.
|
|
1943
|
+
this.graphRuntime.scheduleInputsChanged(nodeId);
|
|
1930
1944
|
await this.graphRuntime.whenIdle();
|
|
1931
1945
|
this.graphRuntime.pause();
|
|
1932
1946
|
}
|
|
@@ -1955,7 +1969,7 @@ class HybridEngine extends AbstractEngine {
|
|
|
1955
1969
|
const nodes = Array.from(this.dirtyNodes);
|
|
1956
1970
|
this.dirtyNodes.clear();
|
|
1957
1971
|
for (const n of nodes)
|
|
1958
|
-
this.graphRuntime.
|
|
1972
|
+
this.graphRuntime.scheduleInputsChanged(n);
|
|
1959
1973
|
if (this.flushTimer) {
|
|
1960
1974
|
clearTimeout(this.flushTimer);
|
|
1961
1975
|
this.flushTimer = undefined;
|
|
@@ -1985,14 +1999,14 @@ class HybridEngine extends AbstractEngine {
|
|
|
1985
1999
|
const nodes = Array.from(this.dirtyNodes);
|
|
1986
2000
|
this.dirtyNodes.clear();
|
|
1987
2001
|
for (const n of nodes)
|
|
1988
|
-
this.graphRuntime.
|
|
2002
|
+
this.graphRuntime.scheduleInputsChanged(n);
|
|
1989
2003
|
this.flushTimer = undefined;
|
|
1990
2004
|
}, windowMs);
|
|
1991
2005
|
}
|
|
1992
2006
|
super.setInputs(nodeId, inputs);
|
|
1993
2007
|
this.dirtyNodes.add(nodeId);
|
|
1994
2008
|
if (!this.batching)
|
|
1995
|
-
this.graphRuntime.
|
|
2009
|
+
this.graphRuntime.scheduleInputsChanged(nodeId);
|
|
1996
2010
|
}
|
|
1997
2011
|
triggerExternal(nodeId, event) {
|
|
1998
2012
|
super.triggerExternal(nodeId, event);
|
|
@@ -2029,12 +2043,41 @@ class StepEngine extends AbstractEngine {
|
|
|
2029
2043
|
this.dirtyNodes.clear();
|
|
2030
2044
|
this.graphRuntime.resume();
|
|
2031
2045
|
for (const n of nodes)
|
|
2032
|
-
this.graphRuntime.
|
|
2046
|
+
this.graphRuntime.scheduleInputsChanged(n);
|
|
2033
2047
|
await this.graphRuntime.whenIdle();
|
|
2034
2048
|
this.graphRuntime.pause();
|
|
2035
2049
|
}
|
|
2036
2050
|
}
|
|
2037
2051
|
|
|
2052
|
+
/**
|
|
2053
|
+
* Creates an Engine instance for the given GraphRuntime based on engine configuration.
|
|
2054
|
+
* This is the single source of truth for engine creation, used by both local and remote runners.
|
|
2055
|
+
*/
|
|
2056
|
+
function createEngine(runtime, config) {
|
|
2057
|
+
const engineKind = config?.engine ?? "push";
|
|
2058
|
+
const batched = config?.batched ?? { flushIntervalMs: 0 };
|
|
2059
|
+
const hybrid = config?.hybrid ?? { windowMs: 250, batchThreshold: 3 };
|
|
2060
|
+
switch (engineKind) {
|
|
2061
|
+
case "push":
|
|
2062
|
+
return new PushEngine(runtime);
|
|
2063
|
+
case "batched":
|
|
2064
|
+
return new BatchedEngine(runtime, {
|
|
2065
|
+
flushIntervalMs: batched.flushIntervalMs,
|
|
2066
|
+
});
|
|
2067
|
+
case "pull":
|
|
2068
|
+
return new PullEngine(runtime);
|
|
2069
|
+
case "hybrid":
|
|
2070
|
+
return new HybridEngine(runtime, {
|
|
2071
|
+
windowMs: hybrid.windowMs,
|
|
2072
|
+
batchThreshold: hybrid.batchThreshold,
|
|
2073
|
+
});
|
|
2074
|
+
case "step":
|
|
2075
|
+
return new StepEngine(runtime);
|
|
2076
|
+
default:
|
|
2077
|
+
throw new Error(`Unknown engine kind: ${engineKind}`);
|
|
2078
|
+
}
|
|
2079
|
+
}
|
|
2080
|
+
|
|
2038
2081
|
const ComputeCategory = {
|
|
2039
2082
|
id: "compute",
|
|
2040
2083
|
displayName: "Compute",
|
|
@@ -3446,6 +3489,7 @@ exports.Registry = Registry;
|
|
|
3446
3489
|
exports.StepEngine = StepEngine;
|
|
3447
3490
|
exports.createAsyncGraphDef = createAsyncGraphDef;
|
|
3448
3491
|
exports.createAsyncGraphRegistry = createAsyncGraphRegistry;
|
|
3492
|
+
exports.createEngine = createEngine;
|
|
3449
3493
|
exports.createProgressGraphDef = createProgressGraphDef;
|
|
3450
3494
|
exports.createProgressGraphRegistry = createProgressGraphRegistry;
|
|
3451
3495
|
exports.createSimpleGraphDef = createSimpleGraphDef;
|