@bian-womp/spark-workbench 0.2.53 → 0.2.54
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 +149 -108
- package/lib/cjs/index.cjs.map +1 -1
- package/lib/cjs/src/core/InMemoryWorkbench.d.ts +9 -1
- package/lib/cjs/src/core/InMemoryWorkbench.d.ts.map +1 -1
- package/lib/cjs/src/core/contracts.d.ts +3 -0
- package/lib/cjs/src/core/contracts.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/misc/WorkbenchCanvas.d.ts.map +1 -1
- package/lib/cjs/src/misc/WorkbenchStudio.d.ts.map +1 -1
- package/lib/cjs/src/misc/load.d.ts +5 -0
- package/lib/cjs/src/misc/load.d.ts.map +1 -0
- package/lib/cjs/src/runtime/RemoteGraphRunner.d.ts.map +1 -1
- package/lib/esm/index.js +149 -110
- package/lib/esm/index.js.map +1 -1
- package/lib/esm/src/core/InMemoryWorkbench.d.ts +9 -1
- package/lib/esm/src/core/InMemoryWorkbench.d.ts.map +1 -1
- package/lib/esm/src/core/contracts.d.ts +3 -0
- package/lib/esm/src/core/contracts.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/misc/WorkbenchCanvas.d.ts.map +1 -1
- package/lib/esm/src/misc/WorkbenchStudio.d.ts.map +1 -1
- package/lib/esm/src/misc/load.d.ts +5 -0
- package/lib/esm/src/misc/load.d.ts.map +1 -0
- package/lib/esm/src/runtime/RemoteGraphRunner.d.ts.map +1 -1
- package/package.json +4 -4
package/lib/cjs/index.cjs
CHANGED
|
@@ -114,6 +114,13 @@ class InMemoryWorkbench extends AbstractWorkbench {
|
|
|
114
114
|
const { positions } = await this.layout.layout(this.def);
|
|
115
115
|
this.positions = positions;
|
|
116
116
|
}
|
|
117
|
+
const defNodeIds = new Set(this.def.nodes.map((n) => n.nodeId));
|
|
118
|
+
const defEdgeIds = new Set(this.def.edges.map((e) => e.id));
|
|
119
|
+
const filteredPositions = Object.fromEntries(Object.entries(this.positions).filter(([id]) => defNodeIds.has(id)));
|
|
120
|
+
const filteredNodes = this.selection.nodes.filter((id) => defNodeIds.has(id));
|
|
121
|
+
const filteredEdges = this.selection.edges.filter((id) => defEdgeIds.has(id));
|
|
122
|
+
this.positions = filteredPositions;
|
|
123
|
+
this.selection = { nodes: filteredNodes, edges: filteredEdges };
|
|
117
124
|
this.emit("graphChanged", { def: this.def });
|
|
118
125
|
this.refreshValidation();
|
|
119
126
|
}
|
|
@@ -230,29 +237,32 @@ class InMemoryWorkbench extends AbstractWorkbench {
|
|
|
230
237
|
});
|
|
231
238
|
}
|
|
232
239
|
// Position and selection APIs for React Flow bridge
|
|
233
|
-
setPosition(nodeId, pos) {
|
|
240
|
+
setPosition(nodeId, pos, opts) {
|
|
234
241
|
this.positions[nodeId] = pos;
|
|
235
242
|
this.emit("graphUiChanged", {
|
|
236
243
|
def: this.def,
|
|
237
244
|
change: { type: "moveNode", nodeId, pos },
|
|
245
|
+
commit: !!opts?.commit === true,
|
|
238
246
|
});
|
|
239
247
|
}
|
|
240
|
-
setPositions(map) {
|
|
248
|
+
setPositions(map, opts) {
|
|
241
249
|
this.positions = { ...map };
|
|
242
250
|
this.emit("graphUiChanged", {
|
|
243
251
|
def: this.def,
|
|
244
252
|
change: { type: "moveNodes" },
|
|
253
|
+
commit: opts?.commit,
|
|
245
254
|
});
|
|
246
255
|
}
|
|
247
256
|
getPositions() {
|
|
248
257
|
return { ...this.positions };
|
|
249
258
|
}
|
|
250
|
-
setSelection(sel) {
|
|
259
|
+
setSelection(sel, opts) {
|
|
251
260
|
this.selection = { nodes: [...sel.nodes], edges: [...sel.edges] };
|
|
252
261
|
this.emit("selectionChanged", this.selection);
|
|
253
262
|
this.emit("graphUiChanged", {
|
|
254
263
|
def: this.def,
|
|
255
264
|
change: { type: "selection" },
|
|
265
|
+
commit: opts?.commit,
|
|
256
266
|
});
|
|
257
267
|
}
|
|
258
268
|
getSelection() {
|
|
@@ -261,21 +271,31 @@ class InMemoryWorkbench extends AbstractWorkbench {
|
|
|
261
271
|
edges: [...this.selection.edges],
|
|
262
272
|
};
|
|
263
273
|
}
|
|
264
|
-
setViewport(viewport) {
|
|
274
|
+
setViewport(viewport, opts) {
|
|
265
275
|
this.viewport = { ...viewport };
|
|
276
|
+
this.emit("graphUiChanged", {
|
|
277
|
+
def: this.def,
|
|
278
|
+
change: { type: "viewport" },
|
|
279
|
+
commit: opts?.commit,
|
|
280
|
+
});
|
|
266
281
|
}
|
|
267
282
|
getViewport() {
|
|
268
283
|
return this.viewport ? { ...this.viewport } : null;
|
|
269
284
|
}
|
|
270
285
|
getUIState() {
|
|
286
|
+
const defNodeIds = new Set(this.def.nodes.map((n) => n.nodeId));
|
|
287
|
+
const defEdgeIds = new Set(this.def.edges.map((e) => e.id));
|
|
288
|
+
const filteredPositions = Object.fromEntries(Object.entries(this.positions).filter(([id]) => defNodeIds.has(id)));
|
|
289
|
+
const filteredNodes = this.selection.nodes.filter((id) => defNodeIds.has(id));
|
|
290
|
+
const filteredEdges = this.selection.edges.filter((id) => defEdgeIds.has(id));
|
|
271
291
|
return {
|
|
272
|
-
positions: Object.keys(
|
|
273
|
-
?
|
|
292
|
+
positions: Object.keys(filteredPositions).length > 0
|
|
293
|
+
? filteredPositions
|
|
274
294
|
: undefined,
|
|
275
|
-
selection:
|
|
295
|
+
selection: filteredNodes.length > 0 || filteredEdges.length > 0
|
|
276
296
|
? {
|
|
277
|
-
nodes:
|
|
278
|
-
edges:
|
|
297
|
+
nodes: filteredNodes,
|
|
298
|
+
edges: filteredEdges,
|
|
279
299
|
}
|
|
280
300
|
: undefined,
|
|
281
301
|
viewport: this.viewport ? { ...this.viewport } : undefined,
|
|
@@ -842,10 +862,13 @@ class RemoteGraphRunner extends AbstractGraphRunner {
|
|
|
842
862
|
// Auto-fetch registry on first connection (only once)
|
|
843
863
|
if (!this.registryFetched && !this.registryFetching) {
|
|
844
864
|
// Log loading state (UI can listen to transport status for loading indication)
|
|
845
|
-
console.info("Loading registry from remote...");
|
|
846
|
-
this.fetchRegistry(client)
|
|
865
|
+
console.info("[RemoteGraphRunner] Loading registry from remote...");
|
|
866
|
+
this.fetchRegistry(client)
|
|
867
|
+
.then(() => {
|
|
868
|
+
console.info("[RemoteGraphRunner] Loaded registry from remote");
|
|
869
|
+
})
|
|
870
|
+
.catch((err) => {
|
|
847
871
|
console.error("[RemoteGraphRunner] Failed to fetch registry:", err);
|
|
848
|
-
// Error handling is done inside fetchRegistry, but we catch unhandled rejections
|
|
849
872
|
});
|
|
850
873
|
}
|
|
851
874
|
// Clear promise on success
|
|
@@ -1479,10 +1502,10 @@ function useWorkbenchBridge(wb) {
|
|
|
1479
1502
|
});
|
|
1480
1503
|
}, [wb]);
|
|
1481
1504
|
const onNodesChange = React.useCallback((changes) => {
|
|
1482
|
-
// Apply position updates
|
|
1505
|
+
// Apply position updates continuously, but mark commit only on drag end
|
|
1483
1506
|
changes.forEach((c) => {
|
|
1484
1507
|
if (c.type === "position" && c.position) {
|
|
1485
|
-
wb.setPosition(c.id, c.position);
|
|
1508
|
+
wb.setPosition(c.id, c.position, { commit: !c.dragging });
|
|
1486
1509
|
}
|
|
1487
1510
|
});
|
|
1488
1511
|
// Derive next node selection from change set
|
|
@@ -1956,6 +1979,99 @@ function getHandleClassName(args) {
|
|
|
1956
1979
|
return cx("!w-3 !h-3 !bg-white !dark:bg-stone-900", borderColor, kind === "output" && "!rounded-none");
|
|
1957
1980
|
}
|
|
1958
1981
|
|
|
1982
|
+
function generateTimestamp() {
|
|
1983
|
+
const d = new Date();
|
|
1984
|
+
const pad = (n) => String(n).padStart(2, "0");
|
|
1985
|
+
return `${pad(d.getMonth() + 1)}${pad(d.getDate())}-${pad(d.getHours())}${pad(d.getMinutes())}`;
|
|
1986
|
+
}
|
|
1987
|
+
function downloadJSON(payload, filename) {
|
|
1988
|
+
const pretty = JSON.stringify(payload, null, 2);
|
|
1989
|
+
const blob = new Blob([pretty], { type: "application/json" });
|
|
1990
|
+
const url = URL.createObjectURL(blob);
|
|
1991
|
+
const a = document.createElement("a");
|
|
1992
|
+
a.href = url;
|
|
1993
|
+
a.download = filename;
|
|
1994
|
+
document.body.appendChild(a);
|
|
1995
|
+
a.click();
|
|
1996
|
+
a.remove();
|
|
1997
|
+
URL.revokeObjectURL(url);
|
|
1998
|
+
}
|
|
1999
|
+
function isSnapshotPayload(parsed) {
|
|
2000
|
+
return (parsed !== null &&
|
|
2001
|
+
typeof parsed === "object" &&
|
|
2002
|
+
("def" in parsed ||
|
|
2003
|
+
"inputs" in parsed ||
|
|
2004
|
+
"outputs" in parsed ||
|
|
2005
|
+
"environment" in parsed));
|
|
2006
|
+
}
|
|
2007
|
+
async function download(wb, runner) {
|
|
2008
|
+
try {
|
|
2009
|
+
const def = wb.export();
|
|
2010
|
+
const uiState = wb.getUIState();
|
|
2011
|
+
let snapshot;
|
|
2012
|
+
if (runner.isRunning()) {
|
|
2013
|
+
const fullSnapshot = await runner.snapshotFull();
|
|
2014
|
+
snapshot = {
|
|
2015
|
+
...fullSnapshot,
|
|
2016
|
+
def,
|
|
2017
|
+
extData: {
|
|
2018
|
+
...(fullSnapshot.extData || {}),
|
|
2019
|
+
ui: uiState,
|
|
2020
|
+
},
|
|
2021
|
+
};
|
|
2022
|
+
}
|
|
2023
|
+
else {
|
|
2024
|
+
const inputs = runner.getInputs(def);
|
|
2025
|
+
snapshot = {
|
|
2026
|
+
def,
|
|
2027
|
+
inputs,
|
|
2028
|
+
outputs: {},
|
|
2029
|
+
environment: {},
|
|
2030
|
+
extData: { ui: uiState },
|
|
2031
|
+
};
|
|
2032
|
+
}
|
|
2033
|
+
downloadJSON(snapshot, `spark-snapshot-${generateTimestamp()}.json`);
|
|
2034
|
+
}
|
|
2035
|
+
catch (err) {
|
|
2036
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
2037
|
+
throw new Error(`Failed to download snapshot: ${message}`);
|
|
2038
|
+
}
|
|
2039
|
+
}
|
|
2040
|
+
async function upload(parsed, wb, runner) {
|
|
2041
|
+
if (!isSnapshotPayload(parsed)) {
|
|
2042
|
+
throw new Error("Invalid snapshot format - expected RuntimeSnapshotFull");
|
|
2043
|
+
}
|
|
2044
|
+
const def = parsed.def;
|
|
2045
|
+
const environment = parsed.environment || {};
|
|
2046
|
+
const inputs = parsed.inputs || {};
|
|
2047
|
+
const outputs = parsed.outputs || {};
|
|
2048
|
+
const extData = parsed.extData || {};
|
|
2049
|
+
if (!def) {
|
|
2050
|
+
throw new Error("Graph definition is empty");
|
|
2051
|
+
}
|
|
2052
|
+
await wb.load(def);
|
|
2053
|
+
if (extData.ui && typeof extData.ui === "object") {
|
|
2054
|
+
wb.setUIState(extData.ui);
|
|
2055
|
+
}
|
|
2056
|
+
if (runner.isRunning()) {
|
|
2057
|
+
await runner.applySnapshotFull({
|
|
2058
|
+
def,
|
|
2059
|
+
environment,
|
|
2060
|
+
inputs,
|
|
2061
|
+
outputs,
|
|
2062
|
+
extData,
|
|
2063
|
+
});
|
|
2064
|
+
}
|
|
2065
|
+
else {
|
|
2066
|
+
runner.build(wb.export());
|
|
2067
|
+
if (inputs && typeof inputs === "object") {
|
|
2068
|
+
for (const [nodeId, map] of Object.entries(inputs)) {
|
|
2069
|
+
runner.setInputs(nodeId, map);
|
|
2070
|
+
}
|
|
2071
|
+
}
|
|
2072
|
+
}
|
|
2073
|
+
}
|
|
2074
|
+
|
|
1959
2075
|
const WorkbenchContext = React.createContext(null);
|
|
1960
2076
|
function useWorkbenchContext() {
|
|
1961
2077
|
const ctx = React.useContext(WorkbenchContext);
|
|
@@ -2141,7 +2257,7 @@ function WorkbenchProvider({ wb, runner, registry, setRegistry, overrides, uiVer
|
|
|
2141
2257
|
}
|
|
2142
2258
|
curX += maxWidth + H_GAP;
|
|
2143
2259
|
}
|
|
2144
|
-
wb.setPositions(pos);
|
|
2260
|
+
wb.setPositions(pos, { commit: true });
|
|
2145
2261
|
}, [wb, registry, overrides?.getDefaultNodeSize]);
|
|
2146
2262
|
const updateEdgeType = React.useCallback((edgeId, typeId) => wb.updateEdgeType(edgeId, typeId), [wb]);
|
|
2147
2263
|
const triggerExternal = React.useCallback((nodeId, event) => runner.triggerExternal(nodeId, event), [runner]);
|
|
@@ -3663,7 +3779,7 @@ const WorkbenchCanvas = React.forwardRef(({ showValues, toString, toElement, get
|
|
|
3663
3779
|
const onMoveEnd = React.useCallback(() => {
|
|
3664
3780
|
if (rfInstanceRef.current) {
|
|
3665
3781
|
const viewport = rfInstanceRef.current.getViewport();
|
|
3666
|
-
wb.setViewport({ x: viewport.x, y: viewport.y, zoom: viewport.zoom });
|
|
3782
|
+
wb.setViewport({ x: viewport.x, y: viewport.y, zoom: viewport.zoom }, { commit: true });
|
|
3667
3783
|
}
|
|
3668
3784
|
}, [wb]);
|
|
3669
3785
|
const viewportRef = React.useRef(null);
|
|
@@ -3830,9 +3946,20 @@ function WorkbenchStudioCanvas({ setRegistry, autoScroll, onAutoScrollChange, ex
|
|
|
3830
3946
|
}
|
|
3831
3947
|
catch { }
|
|
3832
3948
|
});
|
|
3949
|
+
const off3 = wb.on("graphUiChanged", (evt) => {
|
|
3950
|
+
if (!evt.commit)
|
|
3951
|
+
return;
|
|
3952
|
+
try {
|
|
3953
|
+
const cur = wb.export();
|
|
3954
|
+
const inputs = runner.getInputs(cur);
|
|
3955
|
+
onChange({ def: cur, inputs });
|
|
3956
|
+
}
|
|
3957
|
+
catch { }
|
|
3958
|
+
});
|
|
3833
3959
|
return () => {
|
|
3834
3960
|
off1();
|
|
3835
3961
|
off2();
|
|
3962
|
+
off3();
|
|
3836
3963
|
};
|
|
3837
3964
|
}, [wb, runner, onChange]);
|
|
3838
3965
|
const applyExample = React.useCallback(async (key) => {
|
|
@@ -3868,24 +3995,9 @@ function WorkbenchStudioCanvas({ setRegistry, autoScroll, onAutoScrollChange, ex
|
|
|
3868
3995
|
setRegistry,
|
|
3869
3996
|
backendKind,
|
|
3870
3997
|
]);
|
|
3871
|
-
const
|
|
3998
|
+
const download$1 = React.useCallback(async () => {
|
|
3872
3999
|
try {
|
|
3873
|
-
|
|
3874
|
-
const inputs = runner.getInputs(def);
|
|
3875
|
-
const payload = { def, inputs };
|
|
3876
|
-
const pretty = JSON.stringify(payload, null, 2);
|
|
3877
|
-
const blob = new Blob([pretty], { type: "application/json" });
|
|
3878
|
-
const url = URL.createObjectURL(blob);
|
|
3879
|
-
const a = document.createElement("a");
|
|
3880
|
-
const d = new Date();
|
|
3881
|
-
const pad = (n) => String(n).padStart(2, "0");
|
|
3882
|
-
const ts = `${pad(d.getMonth() + 1)}${pad(d.getDate())}-${pad(d.getHours())}${pad(d.getMinutes())}`;
|
|
3883
|
-
a.href = url;
|
|
3884
|
-
a.download = `spark-graph-${ts}.json`;
|
|
3885
|
-
document.body.appendChild(a);
|
|
3886
|
-
a.click();
|
|
3887
|
-
a.remove();
|
|
3888
|
-
URL.revokeObjectURL(url);
|
|
4000
|
+
await download(wb, runner);
|
|
3889
4001
|
}
|
|
3890
4002
|
catch (err) {
|
|
3891
4003
|
const message = err instanceof Error ? err.message : String(err);
|
|
@@ -3899,51 +4011,7 @@ function WorkbenchStudioCanvas({ setRegistry, autoScroll, onAutoScrollChange, ex
|
|
|
3899
4011
|
return;
|
|
3900
4012
|
const text = await file.text();
|
|
3901
4013
|
const parsed = JSON.parse(text);
|
|
3902
|
-
|
|
3903
|
-
const isSnapshot = parsed &&
|
|
3904
|
-
typeof parsed === "object" &&
|
|
3905
|
-
(parsed.def || parsed.inputs || parsed.outputs || parsed.environment);
|
|
3906
|
-
if (isSnapshot) {
|
|
3907
|
-
const def = parsed.def;
|
|
3908
|
-
const positions = parsed.positions || {};
|
|
3909
|
-
const environment = parsed.environment || {};
|
|
3910
|
-
const inputs = parsed.inputs || {};
|
|
3911
|
-
if (def && runner.isRunning()) {
|
|
3912
|
-
// Remote exact restore path
|
|
3913
|
-
await runner.applySnapshotFull({
|
|
3914
|
-
def,
|
|
3915
|
-
environment,
|
|
3916
|
-
inputs,
|
|
3917
|
-
outputs: parsed.outputs || {},
|
|
3918
|
-
});
|
|
3919
|
-
await wb.load(def);
|
|
3920
|
-
if (positions && typeof positions === "object")
|
|
3921
|
-
wb.setPositions(positions);
|
|
3922
|
-
}
|
|
3923
|
-
else if (!runner.isRunning()) {
|
|
3924
|
-
alert("Engine is not running");
|
|
3925
|
-
}
|
|
3926
|
-
else {
|
|
3927
|
-
alert("Graph definition is empty");
|
|
3928
|
-
}
|
|
3929
|
-
}
|
|
3930
|
-
else {
|
|
3931
|
-
const def = parsed?.def ?? parsed;
|
|
3932
|
-
const inputs = parsed?.inputs ?? {};
|
|
3933
|
-
await wb.load(def);
|
|
3934
|
-
try {
|
|
3935
|
-
runner.build(wb.export());
|
|
3936
|
-
}
|
|
3937
|
-
catch { }
|
|
3938
|
-
if (inputs && typeof inputs === "object") {
|
|
3939
|
-
for (const [nodeId, map] of Object.entries(inputs)) {
|
|
3940
|
-
try {
|
|
3941
|
-
runner.setInputs(nodeId, map);
|
|
3942
|
-
}
|
|
3943
|
-
catch { }
|
|
3944
|
-
}
|
|
3945
|
-
}
|
|
3946
|
-
}
|
|
4014
|
+
await upload(parsed, wb, runner);
|
|
3947
4015
|
}
|
|
3948
4016
|
catch (err) {
|
|
3949
4017
|
const message = err instanceof Error ? err.message : String(err);
|
|
@@ -4199,36 +4267,7 @@ function WorkbenchStudioCanvas({ setRegistry, autoScroll, onAutoScrollChange, ex
|
|
|
4199
4267
|
// Normal change when not running
|
|
4200
4268
|
onEngineChange?.(kind);
|
|
4201
4269
|
}
|
|
4202
|
-
}, children: [jsxRuntime.jsx("option", { value: "", children: "Select Engine\u2026" }), jsxRuntime.jsx("option", { value: "push", children: "Push" }), jsxRuntime.jsx("option", { value: "batched", children: "Batched" }), jsxRuntime.jsx("option", { value: "pull", children: "Pull" }), jsxRuntime.jsx("option", { value: "hybrid", children: "Hybrid" }), jsxRuntime.jsx("option", { value: "step", children: "Step" })] }), engineKind === "step" && (jsxRuntime.jsx("button", { className: "border border-gray-300 rounded p-1", onClick: () => runner.step(), disabled: !isGraphRunning, title: "Step", children: jsxRuntime.jsx(react$1.PlayPauseIcon, { size: 24 }) })), engineKind === "batched" && (jsxRuntime.jsx("button", { className: "border border-gray-300 rounded p-1", onClick: () => runner.flush(), disabled: !isGraphRunning, title: "Flush", children: jsxRuntime.jsx(react$1.LightningIcon, { size: 24 }) })), renderStartStopButton(), jsxRuntime.jsx("button", { className: "border border-gray-300 rounded p-1", onClick: runAutoLayout, children: jsxRuntime.jsx(react$1.TreeStructureIcon, { size: 24 }) }), jsxRuntime.jsx("button", { className: "border border-gray-300 rounded p-1", onClick: () => canvasRef.current?.fitView?.(), title: "Fit View", children: jsxRuntime.jsx(react$1.CornersOutIcon, { size: 24 }) }), jsxRuntime.jsx("button", { className: "border border-gray-300 rounded p-1", onClick:
|
|
4203
|
-
try {
|
|
4204
|
-
const def = wb.export();
|
|
4205
|
-
const positions = wb.getPositions();
|
|
4206
|
-
const snapshot = await runner.snapshotFull();
|
|
4207
|
-
const payload = {
|
|
4208
|
-
...snapshot,
|
|
4209
|
-
def,
|
|
4210
|
-
positions,
|
|
4211
|
-
schemaVersion: 1,
|
|
4212
|
-
};
|
|
4213
|
-
const pretty = JSON.stringify(payload, null, 2);
|
|
4214
|
-
const blob = new Blob([pretty], { type: "application/json" });
|
|
4215
|
-
const url = URL.createObjectURL(blob);
|
|
4216
|
-
const a = document.createElement("a");
|
|
4217
|
-
const d = new Date();
|
|
4218
|
-
const pad = (n) => String(n).padStart(2, "0");
|
|
4219
|
-
const ts = `${pad(d.getMonth() + 1)}${pad(d.getDate())}-${pad(d.getHours())}${pad(d.getMinutes())}`;
|
|
4220
|
-
a.href = url;
|
|
4221
|
-
a.download = `spark-snapshot-${ts}.json`;
|
|
4222
|
-
document.body.appendChild(a);
|
|
4223
|
-
a.click();
|
|
4224
|
-
a.remove();
|
|
4225
|
-
URL.revokeObjectURL(url);
|
|
4226
|
-
}
|
|
4227
|
-
catch (err) {
|
|
4228
|
-
const message = err instanceof Error ? err.message : String(err);
|
|
4229
|
-
alert(message);
|
|
4230
|
-
}
|
|
4231
|
-
}, children: jsxRuntime.jsx(react$1.DownloadIcon, { size: 24 }) }), jsxRuntime.jsx("input", { ref: uploadInputRef, type: "file", accept: "application/json,.json", className: "hidden", onChange: onUploadPicked }), jsxRuntime.jsx("button", { className: "border border-gray-300 rounded p-1", onClick: triggerUpload, children: jsxRuntime.jsx(react$1.UploadIcon, { size: 24 }) }), jsxRuntime.jsxs("label", { className: "flex items-center gap-1", children: [jsxRuntime.jsx("input", { type: "checkbox", checked: debug, onChange: (e) => onDebugChange(e.target.checked) }), jsxRuntime.jsx(react$1.BugBeetleIcon, { size: 24, weight: debug ? "fill" : undefined })] }), jsxRuntime.jsxs("label", { className: "flex items-center gap-1", children: [jsxRuntime.jsx("input", { type: "checkbox", checked: showValues, onChange: (e) => onShowValuesChange(e.target.checked) }), jsxRuntime.jsx(react$1.ListBulletsIcon, { size: 24, weight: showValues ? "fill" : undefined })] })] }), jsxRuntime.jsxs("div", { className: "flex flex-1 min-h-0", children: [jsxRuntime.jsx("div", { className: "flex-1 min-w-0", children: jsxRuntime.jsx(WorkbenchCanvas, { ref: canvasRef, showValues: showValues, toString: toString, toElement: toElement, getDefaultNodeSize: overrides?.getDefaultNodeSize }) }), jsxRuntime.jsx(Inspector, { setInput: setInput, debug: debug, autoScroll: autoScroll, hideWorkbench: hideWorkbench, onAutoScrollChange: onAutoScrollChange, onHideWorkbenchChange: onHideWorkbenchChange, toString: toString, contextPanel: overrides?.contextPanel })] })] }));
|
|
4270
|
+
}, children: [jsxRuntime.jsx("option", { value: "", children: "Select Engine\u2026" }), jsxRuntime.jsx("option", { value: "push", children: "Push" }), jsxRuntime.jsx("option", { value: "batched", children: "Batched" }), jsxRuntime.jsx("option", { value: "pull", children: "Pull" }), jsxRuntime.jsx("option", { value: "hybrid", children: "Hybrid" }), jsxRuntime.jsx("option", { value: "step", children: "Step" })] }), engineKind === "step" && (jsxRuntime.jsx("button", { className: "border border-gray-300 rounded p-1", onClick: () => runner.step(), disabled: !isGraphRunning, title: "Step", children: jsxRuntime.jsx(react$1.PlayPauseIcon, { size: 24 }) })), engineKind === "batched" && (jsxRuntime.jsx("button", { className: "border border-gray-300 rounded p-1", onClick: () => runner.flush(), disabled: !isGraphRunning, title: "Flush", children: jsxRuntime.jsx(react$1.LightningIcon, { size: 24 }) })), renderStartStopButton(), jsxRuntime.jsx("button", { className: "border border-gray-300 rounded p-1", onClick: runAutoLayout, children: jsxRuntime.jsx(react$1.TreeStructureIcon, { size: 24 }) }), jsxRuntime.jsx("button", { className: "border border-gray-300 rounded p-1", onClick: () => canvasRef.current?.fitView?.(), title: "Fit View", children: jsxRuntime.jsx(react$1.CornersOutIcon, { size: 24 }) }), jsxRuntime.jsx("button", { className: "border border-gray-300 rounded p-1", onClick: download$1, children: jsxRuntime.jsx(react$1.DownloadIcon, { size: 24 }) }), jsxRuntime.jsx("input", { ref: uploadInputRef, type: "file", accept: "application/json,.json", className: "hidden", onChange: onUploadPicked }), jsxRuntime.jsx("button", { className: "border border-gray-300 rounded p-1", onClick: triggerUpload, children: jsxRuntime.jsx(react$1.UploadIcon, { size: 24 }) }), jsxRuntime.jsxs("label", { className: "flex items-center gap-1", children: [jsxRuntime.jsx("input", { type: "checkbox", checked: debug, onChange: (e) => onDebugChange(e.target.checked) }), jsxRuntime.jsx(react$1.BugBeetleIcon, { size: 24, weight: debug ? "fill" : undefined })] }), jsxRuntime.jsxs("label", { className: "flex items-center gap-1", children: [jsxRuntime.jsx("input", { type: "checkbox", checked: showValues, onChange: (e) => onShowValuesChange(e.target.checked) }), jsxRuntime.jsx(react$1.ListBulletsIcon, { size: 24, weight: showValues ? "fill" : undefined })] })] }), jsxRuntime.jsxs("div", { className: "flex flex-1 min-h-0", children: [jsxRuntime.jsx("div", { className: "flex-1 min-w-0", children: jsxRuntime.jsx(WorkbenchCanvas, { ref: canvasRef, showValues: showValues, toString: toString, toElement: toElement, getDefaultNodeSize: overrides?.getDefaultNodeSize }) }), jsxRuntime.jsx(Inspector, { setInput: setInput, debug: debug, autoScroll: autoScroll, hideWorkbench: hideWorkbench, onAutoScrollChange: onAutoScrollChange, onHideWorkbenchChange: onHideWorkbenchChange, toString: toString, contextPanel: overrides?.contextPanel })] })] }));
|
|
4232
4271
|
}
|
|
4233
4272
|
function WorkbenchStudio({ engine, onEngineChange, example, onExampleChange, backendKind, onBackendKindChange, httpBaseUrl, onHttpBaseUrlChange, wsUrl, onWsUrlChange, debug, onDebugChange, showValues, onShowValuesChange, hideWorkbench, onHideWorkbenchChange, autoScroll, onAutoScrollChange, backendOptions, overrides, onInit, onChange, }) {
|
|
4234
4273
|
const [registry, setRegistry] = React.useState(sparkGraph.createSimpleGraphRegistry());
|
|
@@ -4320,6 +4359,7 @@ exports.WorkbenchProvider = WorkbenchProvider;
|
|
|
4320
4359
|
exports.WorkbenchStudio = WorkbenchStudio;
|
|
4321
4360
|
exports.computeEffectiveHandles = computeEffectiveHandles;
|
|
4322
4361
|
exports.countVisibleHandles = countVisibleHandles;
|
|
4362
|
+
exports.download = download;
|
|
4323
4363
|
exports.estimateNodeSize = estimateNodeSize;
|
|
4324
4364
|
exports.formatDataUrlAsLabel = formatDataUrlAsLabel;
|
|
4325
4365
|
exports.formatDeclaredTypeSignature = formatDeclaredTypeSignature;
|
|
@@ -4331,6 +4371,7 @@ exports.prettyHandle = prettyHandle;
|
|
|
4331
4371
|
exports.resolveOutputDisplay = resolveOutputDisplay;
|
|
4332
4372
|
exports.summarizeDeep = summarizeDeep;
|
|
4333
4373
|
exports.toReactFlow = toReactFlow;
|
|
4374
|
+
exports.upload = upload;
|
|
4334
4375
|
exports.useQueryParamBoolean = useQueryParamBoolean;
|
|
4335
4376
|
exports.useQueryParamString = useQueryParamString;
|
|
4336
4377
|
exports.useThrottledValue = useThrottledValue;
|