@bian-womp/spark-workbench 0.1.11 → 0.1.13
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 +95 -50
- package/lib/cjs/index.cjs.map +1 -1
- package/lib/cjs/src/core/contracts.d.ts +2 -2
- package/lib/cjs/src/core/contracts.d.ts.map +1 -1
- package/lib/cjs/src/misc/context/WorkbenchContext.provider.d.ts.map +1 -1
- package/lib/cjs/src/runtime/GraphRunner.d.ts +1 -0
- package/lib/cjs/src/runtime/GraphRunner.d.ts.map +1 -1
- package/lib/esm/index.js +96 -51
- package/lib/esm/index.js.map +1 -1
- package/lib/esm/src/core/contracts.d.ts +2 -2
- package/lib/esm/src/core/contracts.d.ts.map +1 -1
- package/lib/esm/src/misc/context/WorkbenchContext.provider.d.ts.map +1 -1
- package/lib/esm/src/runtime/GraphRunner.d.ts +1 -0
- package/lib/esm/src/runtime/GraphRunner.d.ts.map +1 -1
- package/package.json +4 -4
- package/lib/cjs/src/adapters/react-flow/index.d.ts +0 -31
- package/lib/cjs/src/adapters/react-flow/index.d.ts.map +0 -1
- package/lib/esm/src/adapters/react-flow/index.d.ts +0 -31
- package/lib/esm/src/adapters/react-flow/index.d.ts.map +0 -1
package/lib/cjs/index.cjs
CHANGED
|
@@ -343,19 +343,9 @@ class GraphRunner {
|
|
|
343
343
|
if (!this.runtime)
|
|
344
344
|
return;
|
|
345
345
|
// Prevent mid-run churn while wiring changes are applied
|
|
346
|
-
|
|
347
|
-
this.runtime.pause();
|
|
348
|
-
}
|
|
349
|
-
catch {
|
|
350
|
-
console.error("Failed to pause runtime");
|
|
351
|
-
}
|
|
346
|
+
this.runtime.pause();
|
|
352
347
|
this.runtime.update(def, this.registry);
|
|
353
|
-
|
|
354
|
-
this.runtime.resume();
|
|
355
|
-
}
|
|
356
|
-
catch {
|
|
357
|
-
console.error("Failed to resume runtime");
|
|
358
|
-
}
|
|
348
|
+
this.runtime.resume();
|
|
359
349
|
this.emit("invalidate", { reason: "graph-updated" });
|
|
360
350
|
return;
|
|
361
351
|
}
|
|
@@ -409,9 +399,7 @@ class GraphRunner {
|
|
|
409
399
|
this.runningKind = opts.engine;
|
|
410
400
|
this.emit("status", { running: true, engine: this.runningKind });
|
|
411
401
|
for (const [nodeId, map] of Object.entries(this.stagedInputs)) {
|
|
412
|
-
|
|
413
|
-
this.engine.setInput(nodeId, handle, value);
|
|
414
|
-
}
|
|
402
|
+
this.engine.setInputs(nodeId, map);
|
|
415
403
|
}
|
|
416
404
|
return;
|
|
417
405
|
}
|
|
@@ -439,9 +427,7 @@ class GraphRunner {
|
|
|
439
427
|
this.runningKind = "push";
|
|
440
428
|
this.emit("status", { running: true, engine: this.runningKind });
|
|
441
429
|
for (const [nodeId, map] of Object.entries(this.stagedInputs)) {
|
|
442
|
-
|
|
443
|
-
this.engine.setInput(nodeId, handle, value);
|
|
444
|
-
}
|
|
430
|
+
this.engine.setInputs(nodeId, map);
|
|
445
431
|
}
|
|
446
432
|
});
|
|
447
433
|
}
|
|
@@ -457,6 +443,51 @@ class GraphRunner {
|
|
|
457
443
|
this.emit("value", { nodeId, handle, value, io: "input" });
|
|
458
444
|
}
|
|
459
445
|
}
|
|
446
|
+
// Batch update multiple inputs on a node and trigger a single run
|
|
447
|
+
setInputs(nodeId, inputs) {
|
|
448
|
+
if (!inputs)
|
|
449
|
+
return;
|
|
450
|
+
if (!this.stagedInputs[nodeId])
|
|
451
|
+
this.stagedInputs[nodeId] = {};
|
|
452
|
+
Object.assign(this.stagedInputs[nodeId], inputs);
|
|
453
|
+
// Local running: pause, set all inputs, resume, schedule a single recompute
|
|
454
|
+
if (this.backend.kind === "local" && this.engine && this.runtime) {
|
|
455
|
+
this.runtime.pause();
|
|
456
|
+
try {
|
|
457
|
+
for (const [handle, value] of Object.entries(inputs)) {
|
|
458
|
+
this.engine.setInput(nodeId, handle, value);
|
|
459
|
+
}
|
|
460
|
+
}
|
|
461
|
+
finally {
|
|
462
|
+
this.runtime.resume();
|
|
463
|
+
try {
|
|
464
|
+
this.runtime.__unsafe_scheduleInputsChanged(nodeId);
|
|
465
|
+
}
|
|
466
|
+
catch { }
|
|
467
|
+
}
|
|
468
|
+
}
|
|
469
|
+
// Remote running: forward inputs individually (no batch API available)
|
|
470
|
+
else if (this.engine && this.backend.kind !== "local") {
|
|
471
|
+
// Prefer batch if supported by remote engine
|
|
472
|
+
if (this.engine instanceof sparkRemote.RemoteEngine) {
|
|
473
|
+
this.engine.setInputs(nodeId, inputs);
|
|
474
|
+
}
|
|
475
|
+
else {
|
|
476
|
+
console.warn("Remote engine does not support setInputs");
|
|
477
|
+
for (const [handle, value] of Object.entries(inputs)) {
|
|
478
|
+
this.engine.setInput(nodeId, handle, value);
|
|
479
|
+
}
|
|
480
|
+
}
|
|
481
|
+
}
|
|
482
|
+
// Not running: emit value events so UI reflects staged values
|
|
483
|
+
else if (!this.engine) {
|
|
484
|
+
// Not running: emit a single synthetic value event per handle; UI will coalesce
|
|
485
|
+
console.warn("Remote engine does not exists");
|
|
486
|
+
for (const [handle, value] of Object.entries(inputs)) {
|
|
487
|
+
this.emit("value", { nodeId, handle, value, io: "input" });
|
|
488
|
+
}
|
|
489
|
+
}
|
|
490
|
+
}
|
|
460
491
|
async step() {
|
|
461
492
|
if (this.backend.kind !== "local")
|
|
462
493
|
return; // unsupported remotely
|
|
@@ -817,7 +848,7 @@ function toReactFlow(def, positions, registry, opts) {
|
|
|
817
848
|
})
|
|
818
849
|
.map((e) => {
|
|
819
850
|
const st = opts.edgeStatus?.[e.id];
|
|
820
|
-
const isRunning = !!st?.
|
|
851
|
+
const isRunning = !!st?.activeRuns;
|
|
821
852
|
const hasError = !!st?.lastError;
|
|
822
853
|
const isInvalidEdge = !!opts.edgeValidation?.[e.id];
|
|
823
854
|
const style = hasError || isInvalidEdge
|
|
@@ -848,7 +879,7 @@ function getNodeBorderClassNames(args) {
|
|
|
848
879
|
const hasError = !!status.lastError;
|
|
849
880
|
const hasValidationError = issues.some((i) => i?.level === "error");
|
|
850
881
|
const hasValidationWarning = !hasValidationError && issues.length > 0;
|
|
851
|
-
const isRunning = !!status.
|
|
882
|
+
const isRunning = !!status.activeRuns;
|
|
852
883
|
const isInvalid = !!status.invalidated && !isRunning && !hasError;
|
|
853
884
|
const borderWidth = selected ? "border-2" : "border";
|
|
854
885
|
const borderStyle = isInvalid ? "border-dashed" : "border-solid";
|
|
@@ -963,7 +994,7 @@ function WorkbenchProvider({ wb, runner, registry, setRegistry, children, }) {
|
|
|
963
994
|
const nodeId = e?.nodeId;
|
|
964
995
|
setNodeStatus((s) => ({
|
|
965
996
|
...s,
|
|
966
|
-
[nodeId]: { ...
|
|
997
|
+
[nodeId]: { ...s[nodeId], invalidated: true },
|
|
967
998
|
}));
|
|
968
999
|
}
|
|
969
1000
|
return add("runner", "value")(e);
|
|
@@ -975,7 +1006,7 @@ function WorkbenchProvider({ wb, runner, registry, setRegistry, children, }) {
|
|
|
975
1006
|
const edgeId = edgeError.edgeId;
|
|
976
1007
|
setEdgeStatus((s) => ({
|
|
977
1008
|
...s,
|
|
978
|
-
[edgeId]: { ...
|
|
1009
|
+
[edgeId]: { ...s[edgeId], lastError: edgeError.err },
|
|
979
1010
|
}));
|
|
980
1011
|
}
|
|
981
1012
|
else if (nodeError.nodeId) {
|
|
@@ -983,7 +1014,7 @@ function WorkbenchProvider({ wb, runner, registry, setRegistry, children, }) {
|
|
|
983
1014
|
setNodeStatus((s) => ({
|
|
984
1015
|
...s,
|
|
985
1016
|
[nodeId]: {
|
|
986
|
-
...
|
|
1017
|
+
...s[nodeId],
|
|
987
1018
|
lastError: nodeError.err,
|
|
988
1019
|
},
|
|
989
1020
|
}));
|
|
@@ -995,7 +1026,7 @@ function WorkbenchProvider({ wb, runner, registry, setRegistry, children, }) {
|
|
|
995
1026
|
setNodeStatus((s) => {
|
|
996
1027
|
const next = {};
|
|
997
1028
|
for (const n of wb.export().nodes) {
|
|
998
|
-
next[n.nodeId] = { ...
|
|
1029
|
+
next[n.nodeId] = { ...s[n.nodeId], invalidated: true };
|
|
999
1030
|
}
|
|
1000
1031
|
return next;
|
|
1001
1032
|
});
|
|
@@ -1007,47 +1038,61 @@ function WorkbenchProvider({ wb, runner, registry, setRegistry, children, }) {
|
|
|
1007
1038
|
return;
|
|
1008
1039
|
if (s.kind === "node-start") {
|
|
1009
1040
|
const id = s.nodeId;
|
|
1010
|
-
setNodeStatus((prev) =>
|
|
1011
|
-
|
|
1012
|
-
|
|
1013
|
-
...
|
|
1014
|
-
|
|
1015
|
-
|
|
1016
|
-
|
|
1017
|
-
|
|
1018
|
-
|
|
1041
|
+
setNodeStatus((prev) => {
|
|
1042
|
+
const current = prev[id]?.activeRuns ?? 0;
|
|
1043
|
+
return {
|
|
1044
|
+
...prev,
|
|
1045
|
+
[id]: {
|
|
1046
|
+
...prev[id],
|
|
1047
|
+
activeRuns: current + 1,
|
|
1048
|
+
progress: 0,
|
|
1049
|
+
invalidated: false,
|
|
1050
|
+
},
|
|
1051
|
+
};
|
|
1052
|
+
});
|
|
1019
1053
|
}
|
|
1020
1054
|
else if (s.kind === "node-progress") {
|
|
1021
1055
|
const id = s.nodeId;
|
|
1022
1056
|
setNodeStatus((prev) => ({
|
|
1023
1057
|
...prev,
|
|
1024
1058
|
[id]: {
|
|
1025
|
-
...
|
|
1026
|
-
running: true,
|
|
1059
|
+
...prev[id],
|
|
1027
1060
|
progress: Number(s.progress) || 0,
|
|
1028
1061
|
},
|
|
1029
1062
|
}));
|
|
1030
1063
|
}
|
|
1031
1064
|
else if (s.kind === "node-done") {
|
|
1032
1065
|
const id = s.nodeId;
|
|
1033
|
-
setNodeStatus((prev) =>
|
|
1034
|
-
|
|
1035
|
-
|
|
1036
|
-
|
|
1066
|
+
setNodeStatus((prev) => {
|
|
1067
|
+
const current = prev[id]?.activeRuns ?? 0;
|
|
1068
|
+
return {
|
|
1069
|
+
...prev,
|
|
1070
|
+
[id]: {
|
|
1071
|
+
...prev[id],
|
|
1072
|
+
activeRuns: current - 1,
|
|
1073
|
+
},
|
|
1074
|
+
};
|
|
1075
|
+
});
|
|
1037
1076
|
}
|
|
1038
1077
|
else if (s.kind === "edge-start") {
|
|
1039
1078
|
const id = s.edgeId;
|
|
1040
|
-
setEdgeStatus((prev) =>
|
|
1041
|
-
|
|
1042
|
-
|
|
1043
|
-
|
|
1079
|
+
setEdgeStatus((prev) => {
|
|
1080
|
+
const current = prev[id]?.activeRuns ?? 0;
|
|
1081
|
+
return {
|
|
1082
|
+
...prev,
|
|
1083
|
+
[id]: { ...prev[id], activeRuns: current + 1 },
|
|
1084
|
+
};
|
|
1085
|
+
});
|
|
1044
1086
|
}
|
|
1045
1087
|
else if (s.kind === "edge-done") {
|
|
1046
1088
|
const id = s.edgeId;
|
|
1047
|
-
setEdgeStatus((prev) =>
|
|
1048
|
-
|
|
1049
|
-
|
|
1050
|
-
|
|
1089
|
+
setEdgeStatus((prev) => {
|
|
1090
|
+
const current = prev[id]?.activeRuns ?? 0;
|
|
1091
|
+
return {
|
|
1092
|
+
...prev,
|
|
1093
|
+
[id]: { ...prev[id], activeRuns: current - 1 },
|
|
1094
|
+
};
|
|
1095
|
+
});
|
|
1051
1096
|
}
|
|
1052
1097
|
return add("runner", "stats")(s);
|
|
1053
1098
|
});
|
|
@@ -1059,7 +1104,7 @@ function WorkbenchProvider({ wb, runner, registry, setRegistry, children, }) {
|
|
|
1059
1104
|
const id = change.nodeId;
|
|
1060
1105
|
setNodeStatus((s) => ({
|
|
1061
1106
|
...s,
|
|
1062
|
-
[id]: { ...
|
|
1107
|
+
[id]: { ...s[id], invalidated: true },
|
|
1063
1108
|
}));
|
|
1064
1109
|
}
|
|
1065
1110
|
});
|
|
@@ -1411,7 +1456,7 @@ const DefaultNode = React.memo(function DefaultNode({ id, data, selected, isConn
|
|
|
1411
1456
|
const { typeId, showValues, inputValues, outputValues, toString } = data;
|
|
1412
1457
|
const inputEntries = data.inputHandles ?? [];
|
|
1413
1458
|
const outputEntries = data.outputHandles ?? [];
|
|
1414
|
-
const status = data.status ?? {};
|
|
1459
|
+
const status = data.status ?? { activeRuns: 0 };
|
|
1415
1460
|
const validation = data.validation ?? {
|
|
1416
1461
|
inputs: [],
|
|
1417
1462
|
outputs: [],
|
|
@@ -1426,7 +1471,7 @@ const DefaultNode = React.memo(function DefaultNode({ id, data, selected, isConn
|
|
|
1426
1471
|
const hasError = !!status.lastError;
|
|
1427
1472
|
const hasValidationError = validation.issues.some((i) => i.level === "error");
|
|
1428
1473
|
const hasValidationWarning = !hasValidationError && validation.issues.length > 0;
|
|
1429
|
-
const isRunning = !!status.
|
|
1474
|
+
const isRunning = !!status.activeRuns;
|
|
1430
1475
|
const isInvalid = !!status.invalidated && !isRunning && !hasError;
|
|
1431
1476
|
// Border color encodes severity; thickness encodes selection; style (dashed) encodes invalidated
|
|
1432
1477
|
const borderWidth = selected ? "border-2" : "border";
|