@bian-womp/spark-workbench 0.2.50 → 0.2.52
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 +89 -48
- package/lib/cjs/index.cjs.map +1 -1
- package/lib/cjs/src/core/InMemoryWorkbench.d.ts +41 -0
- package/lib/cjs/src/core/InMemoryWorkbench.d.ts.map +1 -1
- package/lib/cjs/src/misc/NodeContextMenu.d.ts.map +1 -1
- package/lib/cjs/src/misc/WorkbenchCanvas.d.ts.map +1 -1
- package/lib/cjs/src/misc/WorkbenchStudio.d.ts.map +1 -1
- package/lib/cjs/src/runtime/AbstractGraphRunner.d.ts +0 -1
- package/lib/cjs/src/runtime/AbstractGraphRunner.d.ts.map +1 -1
- package/lib/cjs/src/runtime/IGraphRunner.d.ts +0 -1
- package/lib/cjs/src/runtime/IGraphRunner.d.ts.map +1 -1
- package/lib/cjs/src/runtime/RemoteGraphRunner.d.ts +1 -0
- package/lib/cjs/src/runtime/RemoteGraphRunner.d.ts.map +1 -1
- package/lib/esm/index.js +89 -48
- package/lib/esm/index.js.map +1 -1
- package/lib/esm/src/core/InMemoryWorkbench.d.ts +41 -0
- package/lib/esm/src/core/InMemoryWorkbench.d.ts.map +1 -1
- package/lib/esm/src/misc/NodeContextMenu.d.ts.map +1 -1
- package/lib/esm/src/misc/WorkbenchCanvas.d.ts.map +1 -1
- package/lib/esm/src/misc/WorkbenchStudio.d.ts.map +1 -1
- package/lib/esm/src/runtime/AbstractGraphRunner.d.ts +0 -1
- package/lib/esm/src/runtime/AbstractGraphRunner.d.ts.map +1 -1
- package/lib/esm/src/runtime/IGraphRunner.d.ts +0 -1
- package/lib/esm/src/runtime/IGraphRunner.d.ts.map +1 -1
- package/lib/esm/src/runtime/RemoteGraphRunner.d.ts +1 -0
- package/lib/esm/src/runtime/RemoteGraphRunner.d.ts.map +1 -1
- package/package.json +4 -4
package/lib/cjs/index.cjs
CHANGED
|
@@ -103,6 +103,7 @@ class InMemoryWorkbench extends AbstractWorkbench {
|
|
|
103
103
|
nodes: [],
|
|
104
104
|
edges: [],
|
|
105
105
|
};
|
|
106
|
+
this.viewport = null;
|
|
106
107
|
}
|
|
107
108
|
setRegistry(registry) {
|
|
108
109
|
this.registry = registry;
|
|
@@ -260,6 +261,43 @@ class InMemoryWorkbench extends AbstractWorkbench {
|
|
|
260
261
|
edges: [...this.selection.edges],
|
|
261
262
|
};
|
|
262
263
|
}
|
|
264
|
+
setViewport(viewport) {
|
|
265
|
+
this.viewport = { ...viewport };
|
|
266
|
+
}
|
|
267
|
+
getViewport() {
|
|
268
|
+
return this.viewport ? { ...this.viewport } : null;
|
|
269
|
+
}
|
|
270
|
+
getUIState() {
|
|
271
|
+
return {
|
|
272
|
+
positions: Object.keys(this.positions).length > 0
|
|
273
|
+
? { ...this.positions }
|
|
274
|
+
: undefined,
|
|
275
|
+
selection: this.selection.nodes.length > 0 || this.selection.edges.length > 0
|
|
276
|
+
? {
|
|
277
|
+
nodes: [...this.selection.nodes],
|
|
278
|
+
edges: [...this.selection.edges],
|
|
279
|
+
}
|
|
280
|
+
: undefined,
|
|
281
|
+
viewport: this.viewport ? { ...this.viewport } : undefined,
|
|
282
|
+
};
|
|
283
|
+
}
|
|
284
|
+
setUIState(ui) {
|
|
285
|
+
if (!ui)
|
|
286
|
+
return;
|
|
287
|
+
if (ui.positions) {
|
|
288
|
+
this.positions = { ...ui.positions };
|
|
289
|
+
}
|
|
290
|
+
if (ui.selection) {
|
|
291
|
+
this.selection = {
|
|
292
|
+
nodes: [...ui.selection.nodes],
|
|
293
|
+
edges: [...ui.selection.edges],
|
|
294
|
+
};
|
|
295
|
+
this.emit("selectionChanged", this.selection);
|
|
296
|
+
}
|
|
297
|
+
if (ui.viewport) {
|
|
298
|
+
this.viewport = { ...ui.viewport };
|
|
299
|
+
}
|
|
300
|
+
}
|
|
263
301
|
on(event, handler) {
|
|
264
302
|
if (!this.listeners.has(event))
|
|
265
303
|
this.listeners.set(event, new Set());
|
|
@@ -342,23 +380,6 @@ class AbstractGraphRunner {
|
|
|
342
380
|
this.stop();
|
|
343
381
|
}
|
|
344
382
|
}
|
|
345
|
-
setInput(nodeId, handle, value) {
|
|
346
|
-
if (!this.stagedInputs[nodeId])
|
|
347
|
-
this.stagedInputs[nodeId] = {};
|
|
348
|
-
if (value === undefined) {
|
|
349
|
-
delete this.stagedInputs[nodeId][handle];
|
|
350
|
-
}
|
|
351
|
-
else {
|
|
352
|
-
this.stagedInputs[nodeId][handle] = value;
|
|
353
|
-
}
|
|
354
|
-
if (this.engine) {
|
|
355
|
-
this.engine.setInput(nodeId, handle, value);
|
|
356
|
-
}
|
|
357
|
-
else {
|
|
358
|
-
// Emit a value event so UI updates even when engine isn't running
|
|
359
|
-
this.emit("value", { nodeId, handle, value, io: "input" });
|
|
360
|
-
}
|
|
361
|
-
}
|
|
362
383
|
triggerExternal(nodeId, event) {
|
|
363
384
|
this.engine?.triggerExternal(nodeId, event);
|
|
364
385
|
}
|
|
@@ -1061,6 +1082,10 @@ class RemoteGraphRunner extends AbstractGraphRunner {
|
|
|
1061
1082
|
return value;
|
|
1062
1083
|
}
|
|
1063
1084
|
}
|
|
1085
|
+
async setExtData(data) {
|
|
1086
|
+
const client = await this.ensureClient();
|
|
1087
|
+
await client.setExtData(data);
|
|
1088
|
+
}
|
|
1064
1089
|
async snapshotFull() {
|
|
1065
1090
|
const client = await this.ensureClient();
|
|
1066
1091
|
try {
|
|
@@ -3288,6 +3313,7 @@ function NodeContextMenu({ open, clientPos, nodeId, onClose, }) {
|
|
|
3288
3313
|
const COLS = 4;
|
|
3289
3314
|
const DX = 180;
|
|
3290
3315
|
const DY = 160;
|
|
3316
|
+
const nodeIds = [];
|
|
3291
3317
|
for (let idx = 0; idx < coercedItems.length; idx++) {
|
|
3292
3318
|
const cv = coercedItems[idx];
|
|
3293
3319
|
const col = idx % COLS;
|
|
@@ -3298,9 +3324,16 @@ function NodeContextMenu({ open, clientPos, nodeId, onClose, }) {
|
|
|
3298
3324
|
params: {},
|
|
3299
3325
|
initialInputs: { [elemTarget.inputHandle]: structuredClone(cv) },
|
|
3300
3326
|
});
|
|
3327
|
+
nodeIds.push(newId);
|
|
3328
|
+
}
|
|
3329
|
+
if (nodeIds.length > 0) {
|
|
3301
3330
|
runner.update(wb.export());
|
|
3302
3331
|
await runner.whenIdle();
|
|
3303
|
-
|
|
3332
|
+
for (let idx = 0; idx < coercedItems.length; idx++) {
|
|
3333
|
+
runner.setInputs(nodeIds[idx], {
|
|
3334
|
+
[elemTarget.inputHandle]: coercedItems[idx],
|
|
3335
|
+
});
|
|
3336
|
+
}
|
|
3304
3337
|
}
|
|
3305
3338
|
return;
|
|
3306
3339
|
}
|
|
@@ -3621,18 +3654,48 @@ const WorkbenchCanvas = React.forwardRef(({ showValues, toString, toElement, get
|
|
|
3621
3654
|
const addNodeAt = React.useCallback((typeId, pos) => {
|
|
3622
3655
|
wb.addNode({ typeId, position: pos });
|
|
3623
3656
|
}, [wb]);
|
|
3624
|
-
React.useCallback((inst) => {
|
|
3625
|
-
rfInstanceRef.current = inst;
|
|
3626
|
-
}, []);
|
|
3627
3657
|
const onCloseMenu = React.useCallback(() => {
|
|
3628
3658
|
setMenuOpen(false);
|
|
3629
3659
|
}, []);
|
|
3630
3660
|
const onCloseNodeMenu = React.useCallback(() => {
|
|
3631
3661
|
setNodeMenuOpen(false);
|
|
3632
3662
|
}, []);
|
|
3663
|
+
const onMoveEnd = React.useCallback(() => {
|
|
3664
|
+
if (rfInstanceRef.current) {
|
|
3665
|
+
const viewport = rfInstanceRef.current.getViewport();
|
|
3666
|
+
wb.setViewport({ x: viewport.x, y: viewport.y, zoom: viewport.zoom });
|
|
3667
|
+
}
|
|
3668
|
+
}, [wb]);
|
|
3669
|
+
const viewportRef = React.useRef(null);
|
|
3670
|
+
React.useEffect(() => {
|
|
3671
|
+
if (!rfInstanceRef.current)
|
|
3672
|
+
return;
|
|
3673
|
+
const currentViewport = wb.getViewport();
|
|
3674
|
+
if (currentViewport &&
|
|
3675
|
+
(!viewportRef.current ||
|
|
3676
|
+
viewportRef.current.x !== currentViewport.x ||
|
|
3677
|
+
viewportRef.current.y !== currentViewport.y ||
|
|
3678
|
+
viewportRef.current.zoom !== currentViewport.zoom)) {
|
|
3679
|
+
viewportRef.current = currentViewport;
|
|
3680
|
+
rfInstanceRef.current.setViewport({
|
|
3681
|
+
x: currentViewport.x,
|
|
3682
|
+
y: currentViewport.y,
|
|
3683
|
+
zoom: currentViewport.zoom,
|
|
3684
|
+
});
|
|
3685
|
+
}
|
|
3686
|
+
});
|
|
3633
3687
|
return (jsxRuntime.jsx("div", { className: "w-full h-full", onContextMenu: onContextMenu, children: jsxRuntime.jsx(react.ReactFlowProvider, { children: jsxRuntime.jsxs(react.ReactFlow, { nodes: throttled.nodes, edges: throttled.edges, nodeTypes: nodeTypes, selectionOnDrag: true, onInit: (inst) => {
|
|
3634
3688
|
rfInstanceRef.current = inst;
|
|
3635
|
-
|
|
3689
|
+
const savedViewport = wb.getViewport();
|
|
3690
|
+
if (savedViewport) {
|
|
3691
|
+
viewportRef.current = savedViewport;
|
|
3692
|
+
inst.setViewport({
|
|
3693
|
+
x: savedViewport.x,
|
|
3694
|
+
y: savedViewport.y,
|
|
3695
|
+
zoom: savedViewport.zoom,
|
|
3696
|
+
});
|
|
3697
|
+
}
|
|
3698
|
+
}, onConnect: onConnect, onEdgesChange: onEdgesChange, onEdgesDelete: onEdgesDelete, onNodesDelete: onNodesDelete, onNodesChange: onNodesChange, onMoveEnd: onMoveEnd, deleteKeyCode: ["Backspace", "Delete"], proOptions: { hideAttribution: true }, noDragClassName: "wb-nodrag", noWheelClassName: "wb-nowheel", noPanClassName: "wb-nopan", fitView: true, children: [jsxRuntime.jsx(react.Background, { id: "workbench-canvas-background", variant: react.BackgroundVariant.Dots, gap: 12, size: 1 }), jsxRuntime.jsx(react.MiniMap, {}), jsxRuntime.jsx(react.Controls, {}), jsxRuntime.jsx(DefaultContextMenu, { open: menuOpen, clientPos: menuPos, onAdd: addNodeAt, onClose: onCloseMenu }), !!nodeAtMenu && (jsxRuntime.jsx(NodeContextMenu, { open: nodeMenuOpen, clientPos: nodeMenuPos, nodeId: nodeAtMenu, onClose: onCloseNodeMenu }))] }) }) }));
|
|
3636
3699
|
});
|
|
3637
3700
|
|
|
3638
3701
|
function WorkbenchStudioCanvas({ setRegistry, autoScroll, onAutoScrollChange, example, onExampleChange, engine, onEngineChange, backendKind, onBackendKindChange, httpBaseUrl, onHttpBaseUrlChange, wsUrl, onWsUrlChange, debug, onDebugChange, showValues, onShowValuesChange, hideWorkbench, onHideWorkbenchChange, overrides, onInit, onChange, }) {
|
|
@@ -3722,8 +3785,6 @@ function WorkbenchStudioCanvas({ setRegistry, autoScroll, onAutoScrollChange, ex
|
|
|
3722
3785
|
return overrides.getExamples(defaultExamples);
|
|
3723
3786
|
return defaultExamples;
|
|
3724
3787
|
}, [overrides, defaultExamples]);
|
|
3725
|
-
const lastAutoLaunched = React.useRef(undefined);
|
|
3726
|
-
const autoLayoutRan = React.useRef(false);
|
|
3727
3788
|
const canvasRef = React.useRef(null);
|
|
3728
3789
|
const uploadInputRef = React.useRef(null);
|
|
3729
3790
|
const [registryReady, setRegistryReady] = React.useState(() => {
|
|
@@ -3748,7 +3809,7 @@ function WorkbenchStudioCanvas({ setRegistry, autoScroll, onAutoScrollChange, ex
|
|
|
3748
3809
|
}
|
|
3749
3810
|
};
|
|
3750
3811
|
onInit({ wb, runner, setInitialGraph });
|
|
3751
|
-
}, [onInit, wb, runner
|
|
3812
|
+
}, [onInit, wb, runner]);
|
|
3752
3813
|
// Expose change callback on graph/value changes
|
|
3753
3814
|
React.useEffect(() => {
|
|
3754
3815
|
if (!onChange)
|
|
@@ -3883,7 +3944,6 @@ function WorkbenchStudioCanvas({ setRegistry, autoScroll, onAutoScrollChange, ex
|
|
|
3883
3944
|
}
|
|
3884
3945
|
}
|
|
3885
3946
|
}
|
|
3886
|
-
runAutoLayout();
|
|
3887
3947
|
}
|
|
3888
3948
|
catch (err) {
|
|
3889
3949
|
const message = err instanceof Error ? err.message : String(err);
|
|
@@ -3894,7 +3954,7 @@ function WorkbenchStudioCanvas({ setRegistry, autoScroll, onAutoScrollChange, ex
|
|
|
3894
3954
|
if (uploadInputRef.current)
|
|
3895
3955
|
uploadInputRef.current.value = "";
|
|
3896
3956
|
}
|
|
3897
|
-
}, [wb, runner
|
|
3957
|
+
}, [wb, runner]);
|
|
3898
3958
|
const triggerUpload = React.useCallback(() => {
|
|
3899
3959
|
uploadInputRef.current?.click();
|
|
3900
3960
|
}, []);
|
|
@@ -3936,32 +3996,13 @@ function WorkbenchStudioCanvas({ setRegistry, autoScroll, onAutoScrollChange, ex
|
|
|
3936
3996
|
const d = wb.export();
|
|
3937
3997
|
if (!d.nodes || d.nodes.length === 0)
|
|
3938
3998
|
return;
|
|
3939
|
-
if (lastAutoLaunched.current === engine)
|
|
3940
|
-
return;
|
|
3941
3999
|
try {
|
|
3942
4000
|
runner.launch(d, { engine: engine });
|
|
3943
|
-
lastAutoLaunched.current = engine;
|
|
3944
4001
|
}
|
|
3945
4002
|
catch {
|
|
3946
4003
|
// ignore
|
|
3947
4004
|
}
|
|
3948
4005
|
}, [engine, runner, isGraphRunning, wb, backendKind]);
|
|
3949
|
-
// Registry is automatically fetched by RemoteGraphRunner when it connects
|
|
3950
|
-
// Run auto layout after registry is hydrated (for remote backends)
|
|
3951
|
-
React.useEffect(() => {
|
|
3952
|
-
if (autoLayoutRan.current)
|
|
3953
|
-
return;
|
|
3954
|
-
// Wait for registry to be ready for remote backends
|
|
3955
|
-
if (backendKind !== "local" && !registryReady)
|
|
3956
|
-
return;
|
|
3957
|
-
const cur = wb.export();
|
|
3958
|
-
const positions = wb.getPositions();
|
|
3959
|
-
const allMissing = cur.nodes.every((n) => !positions[n.nodeId]);
|
|
3960
|
-
if (allMissing) {
|
|
3961
|
-
autoLayoutRan.current = true;
|
|
3962
|
-
runAutoLayout();
|
|
3963
|
-
}
|
|
3964
|
-
}, [wb, runAutoLayout, backendKind, registryReady, registry]);
|
|
3965
4006
|
const baseSetInput = React.useCallback((handle, raw) => {
|
|
3966
4007
|
if (!selectedNodeId)
|
|
3967
4008
|
return;
|
|
@@ -3971,7 +4012,7 @@ function WorkbenchStudioCanvas({ setRegistry, autoScroll, onAutoScrollChange, ex
|
|
|
3971
4012
|
return;
|
|
3972
4013
|
// If raw is undefined, pass it through to delete the input value
|
|
3973
4014
|
if (raw === undefined) {
|
|
3974
|
-
runner.
|
|
4015
|
+
runner.setInputs(selectedNodeId, { [handle]: undefined });
|
|
3975
4016
|
return;
|
|
3976
4017
|
}
|
|
3977
4018
|
const typeId = sparkGraph.getInputTypeId(effectiveHandles.inputs, handle);
|
|
@@ -4050,7 +4091,7 @@ function WorkbenchStudioCanvas({ setRegistry, autoScroll, onAutoScrollChange, ex
|
|
|
4050
4091
|
value = raw;
|
|
4051
4092
|
}
|
|
4052
4093
|
}
|
|
4053
|
-
runner.
|
|
4094
|
+
runner.setInputs(selectedNodeId, { [handle]: value });
|
|
4054
4095
|
}, [selectedNodeId, def.edges, effectiveHandles, runner]);
|
|
4055
4096
|
const setInput = React.useMemo(() => {
|
|
4056
4097
|
if (overrides?.setInput) {
|