@bian-womp/spark-workbench 0.2.92 → 0.2.94
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 +57 -63
- package/lib/cjs/index.cjs.map +1 -1
- package/lib/cjs/src/core/AbstractWorkbench.d.ts +8 -7
- package/lib/cjs/src/core/AbstractWorkbench.d.ts.map +1 -1
- package/lib/cjs/src/core/InMemoryWorkbench.d.ts +4 -2
- package/lib/cjs/src/core/InMemoryWorkbench.d.ts.map +1 -1
- package/lib/cjs/src/core/contracts.d.ts +5 -2
- package/lib/cjs/src/core/contracts.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/context/WorkbenchContext.d.ts +1 -2
- package/lib/cjs/src/misc/context/WorkbenchContext.d.ts.map +1 -1
- package/lib/cjs/src/misc/context/WorkbenchContext.provider.d.ts +1 -4
- package/lib/cjs/src/misc/context/WorkbenchContext.provider.d.ts.map +1 -1
- package/lib/esm/index.js +58 -64
- package/lib/esm/index.js.map +1 -1
- package/lib/esm/src/core/AbstractWorkbench.d.ts +8 -7
- package/lib/esm/src/core/AbstractWorkbench.d.ts.map +1 -1
- package/lib/esm/src/core/InMemoryWorkbench.d.ts +4 -2
- package/lib/esm/src/core/InMemoryWorkbench.d.ts.map +1 -1
- package/lib/esm/src/core/contracts.d.ts +5 -2
- package/lib/esm/src/core/contracts.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/context/WorkbenchContext.d.ts +1 -2
- package/lib/esm/src/misc/context/WorkbenchContext.d.ts.map +1 -1
- package/lib/esm/src/misc/context/WorkbenchContext.provider.d.ts +1 -4
- package/lib/esm/src/misc/context/WorkbenchContext.provider.d.ts.map +1 -1
- package/package.json +4 -4
package/lib/cjs/index.cjs
CHANGED
|
@@ -135,8 +135,8 @@ class AbstractWorkbench {
|
|
|
135
135
|
}
|
|
136
136
|
|
|
137
137
|
class InMemoryWorkbench extends AbstractWorkbench {
|
|
138
|
-
constructor() {
|
|
139
|
-
super(
|
|
138
|
+
constructor(args) {
|
|
139
|
+
super(args);
|
|
140
140
|
this._def = { nodes: [], edges: [] };
|
|
141
141
|
this.listeners = new Map();
|
|
142
142
|
this.positions = {};
|
|
@@ -150,12 +150,17 @@ class InMemoryWorkbench extends AbstractWorkbench {
|
|
|
150
150
|
this.viewport = null;
|
|
151
151
|
this.historyState = undefined;
|
|
152
152
|
this.copiedData = null;
|
|
153
|
+
this._registry = sparkGraph.createSimpleGraphRegistry();
|
|
153
154
|
}
|
|
154
155
|
get def() {
|
|
155
156
|
return this._def;
|
|
156
157
|
}
|
|
158
|
+
get registry() {
|
|
159
|
+
return this._registry;
|
|
160
|
+
}
|
|
157
161
|
setRegistry(registry) {
|
|
158
|
-
this.
|
|
162
|
+
this._registry = registry;
|
|
163
|
+
this.emit("registryChanged", { registry });
|
|
159
164
|
}
|
|
160
165
|
async load(def) {
|
|
161
166
|
this._def = { nodes: [...def.nodes], edges: [...def.edges] };
|
|
@@ -3649,7 +3654,7 @@ function computeInvalidatedFromMetadata(metadata) {
|
|
|
3649
3654
|
const maxInputTime = Math.max(...Object.values(lastInputAt));
|
|
3650
3655
|
return maxInputTime > (lastSuccessAt ?? lastRunAt ?? 0);
|
|
3651
3656
|
}
|
|
3652
|
-
function WorkbenchProvider({ wb, runner,
|
|
3657
|
+
function WorkbenchProvider({ wb, runner, overrides, uiVersion, children, }) {
|
|
3653
3658
|
const [nodeStatus, setNodeStatus] = React.useState({});
|
|
3654
3659
|
const [edgeStatus, setEdgeStatus] = React.useState({});
|
|
3655
3660
|
const [events, setEvents] = React.useState([]);
|
|
@@ -3657,6 +3662,7 @@ function WorkbenchProvider({ wb, runner, registry, setRegistry, overrides, uiVer
|
|
|
3657
3662
|
const [systemErrors, setSystemErrors] = React.useState([]);
|
|
3658
3663
|
const [registryErrors, setRegistryErrors] = React.useState([]);
|
|
3659
3664
|
const [inputValidationErrors, setInputValidationErrors] = React.useState([]);
|
|
3665
|
+
const [registryVersion, setRegistryVersion] = React.useState(0);
|
|
3660
3666
|
const clearSystemErrors = React.useCallback(() => setSystemErrors([]), []);
|
|
3661
3667
|
const clearRegistryErrors = React.useCallback(() => setRegistryErrors([]), []);
|
|
3662
3668
|
const clearInputValidationErrors = React.useCallback(() => setInputValidationErrors([]), []);
|
|
@@ -3723,7 +3729,7 @@ function WorkbenchProvider({ wb, runner, registry, setRegistry, overrides, uiVer
|
|
|
3723
3729
|
const out = {};
|
|
3724
3730
|
// Local: runtimeTypeId is not stored; derive from typed wrapper in outputsMap
|
|
3725
3731
|
for (const n of wb.def.nodes) {
|
|
3726
|
-
const effectiveHandles = computeEffectiveHandles(n, registry);
|
|
3732
|
+
const effectiveHandles = computeEffectiveHandles(n, wb.registry);
|
|
3727
3733
|
const outputsDecl = effectiveHandles.outputs;
|
|
3728
3734
|
const handles = Object.keys(outputsDecl);
|
|
3729
3735
|
const cur = {};
|
|
@@ -3737,7 +3743,7 @@ function WorkbenchProvider({ wb, runner, registry, setRegistry, overrides, uiVer
|
|
|
3737
3743
|
out[n.nodeId] = cur;
|
|
3738
3744
|
}
|
|
3739
3745
|
return out;
|
|
3740
|
-
}, [wb, wb.def, outputsMap, registry]);
|
|
3746
|
+
}, [wb, wb.def, outputsMap, wb.registry, registryVersion]);
|
|
3741
3747
|
// Initialize nodes and derive invalidated status from persisted metadata
|
|
3742
3748
|
React.useEffect(() => {
|
|
3743
3749
|
const workbenchRuntimeState = wb.getRuntimeState() ?? { nodes: {} };
|
|
@@ -3815,7 +3821,7 @@ function WorkbenchProvider({ wb, runner, registry, setRegistry, overrides, uiVer
|
|
|
3815
3821
|
const overrideSize = overrides?.getDefaultNodeSize?.(node.typeId) ?? undefined;
|
|
3816
3822
|
const size = estimateNodeSize({
|
|
3817
3823
|
node,
|
|
3818
|
-
registry,
|
|
3824
|
+
registry: wb.registry,
|
|
3819
3825
|
showValues: true,
|
|
3820
3826
|
overrides: overrideSize,
|
|
3821
3827
|
});
|
|
@@ -3833,7 +3839,7 @@ function WorkbenchProvider({ wb, runner, registry, setRegistry, overrides, uiVer
|
|
|
3833
3839
|
curX += maxWidth + H_GAP;
|
|
3834
3840
|
}
|
|
3835
3841
|
wb.setPositions(pos, { commit: true, reason: "auto-layout" });
|
|
3836
|
-
}, [wb, wb.def, registry, overrides?.getDefaultNodeSize]);
|
|
3842
|
+
}, [wb, wb.def, wb.registry, registryVersion, overrides?.getDefaultNodeSize]);
|
|
3837
3843
|
const updateEdgeType = React.useCallback((edgeId, typeId) => wb.updateEdgeType(edgeId, typeId), [wb]);
|
|
3838
3844
|
const triggerExternal = React.useCallback((nodeId, event) => runner.triggerExternal(nodeId, event), [runner]);
|
|
3839
3845
|
const getNodeDisplayName = React.useCallback((nodeId) => {
|
|
@@ -3843,9 +3849,9 @@ function WorkbenchProvider({ wb, runner, registry, setRegistry, overrides, uiVer
|
|
|
3843
3849
|
const node = wb.def.nodes.find((n) => n.nodeId === nodeId);
|
|
3844
3850
|
if (!node)
|
|
3845
3851
|
return nodeId;
|
|
3846
|
-
const desc = registry.nodes.get(node.typeId);
|
|
3852
|
+
const desc = wb.registry.nodes.get(node.typeId);
|
|
3847
3853
|
return desc?.displayName || node.typeId;
|
|
3848
|
-
}, [wb, registry]);
|
|
3854
|
+
}, [wb, wb.registry, registryVersion]);
|
|
3849
3855
|
const setNodeName = React.useCallback((nodeId, name) => {
|
|
3850
3856
|
wb.setNodeName(nodeId, name, { commit: true, reason: "rename-node" });
|
|
3851
3857
|
}, [wb]);
|
|
@@ -4161,6 +4167,9 @@ function WorkbenchProvider({ wb, runner, registry, setRegistry, overrides, uiVer
|
|
|
4161
4167
|
}
|
|
4162
4168
|
return add("runner", "stats")(s);
|
|
4163
4169
|
});
|
|
4170
|
+
const offWbRegistryChanged = wb.on("registryChanged", (evt) => {
|
|
4171
|
+
setRegistryVersion((v) => v + 1);
|
|
4172
|
+
});
|
|
4164
4173
|
const offWbGraphChanged = wb.on("graphChanged", (event) => {
|
|
4165
4174
|
// Clear validation errors for removed nodes
|
|
4166
4175
|
if (event.change?.type === "removeNode") {
|
|
@@ -4317,8 +4326,8 @@ function WorkbenchProvider({ wb, runner, registry, setRegistry, overrides, uiVer
|
|
|
4317
4326
|
// Registry updates: swap registry and refresh graph validation/UI
|
|
4318
4327
|
const offRunnerRegistry = runner.on("registry", async (newReg) => {
|
|
4319
4328
|
try {
|
|
4320
|
-
setRegistry(newReg);
|
|
4321
4329
|
wb.setRegistry(newReg);
|
|
4330
|
+
// Increment registry version to trigger UI updates
|
|
4322
4331
|
// Trigger a graph update so the UI revalidates with new types/enums/nodes
|
|
4323
4332
|
try {
|
|
4324
4333
|
await runner.update(wb.def);
|
|
@@ -4389,6 +4398,7 @@ function WorkbenchProvider({ wb, runner, registry, setRegistry, overrides, uiVer
|
|
|
4389
4398
|
offRunnerError();
|
|
4390
4399
|
offRunnerInvalidate();
|
|
4391
4400
|
offRunnerStats();
|
|
4401
|
+
offWbRegistryChanged();
|
|
4392
4402
|
offWbGraphChanged();
|
|
4393
4403
|
offWbGraphUiChangedForLog();
|
|
4394
4404
|
offWbGraphUiChanged();
|
|
@@ -4402,7 +4412,7 @@ function WorkbenchProvider({ wb, runner, registry, setRegistry, overrides, uiVer
|
|
|
4402
4412
|
offFlowViewport();
|
|
4403
4413
|
offWbRuntimeMetadataChanged();
|
|
4404
4414
|
};
|
|
4405
|
-
}, [runner, wb
|
|
4415
|
+
}, [runner, wb]);
|
|
4406
4416
|
const isRunning = React.useCallback(() => runner.isRunning(), [runner]);
|
|
4407
4417
|
const engineKind = React.useCallback(() => runner.getRunningEngine(), [runner]);
|
|
4408
4418
|
const start = React.useCallback((engine) => {
|
|
@@ -4480,8 +4490,6 @@ function WorkbenchProvider({ wb, runner, registry, setRegistry, overrides, uiVer
|
|
|
4480
4490
|
const value = React.useMemo(() => ({
|
|
4481
4491
|
wb,
|
|
4482
4492
|
runner,
|
|
4483
|
-
registry,
|
|
4484
|
-
setRegistry,
|
|
4485
4493
|
selectedNodeId,
|
|
4486
4494
|
selectedEdgeId,
|
|
4487
4495
|
setSelection,
|
|
@@ -4516,14 +4524,13 @@ function WorkbenchProvider({ wb, runner, registry, setRegistry, overrides, uiVer
|
|
|
4516
4524
|
updateEdgeType,
|
|
4517
4525
|
triggerExternal,
|
|
4518
4526
|
uiVersion,
|
|
4527
|
+
registryVersion,
|
|
4519
4528
|
overrides,
|
|
4520
4529
|
getNodeDisplayName,
|
|
4521
4530
|
setNodeName,
|
|
4522
4531
|
}), [
|
|
4523
4532
|
wb,
|
|
4524
4533
|
runner,
|
|
4525
|
-
registry,
|
|
4526
|
-
setRegistry,
|
|
4527
4534
|
selectedNodeId,
|
|
4528
4535
|
selectedEdgeId,
|
|
4529
4536
|
setSelection,
|
|
@@ -4557,6 +4564,7 @@ function WorkbenchProvider({ wb, runner, registry, setRegistry, overrides, uiVer
|
|
|
4557
4564
|
wb,
|
|
4558
4565
|
runner,
|
|
4559
4566
|
uiVersion,
|
|
4567
|
+
registryVersion,
|
|
4560
4568
|
overrides,
|
|
4561
4569
|
getNodeDisplayName,
|
|
4562
4570
|
setNodeName,
|
|
@@ -4584,7 +4592,7 @@ function DefaultNodeHeader({ id, typeId, validation, right, showId, onInvalidate
|
|
|
4584
4592
|
const node = ctx.wb.def.nodes.find((n) => n.nodeId === id);
|
|
4585
4593
|
if (!node)
|
|
4586
4594
|
return id;
|
|
4587
|
-
const desc = ctx.registry.nodes.get(node.typeId);
|
|
4595
|
+
const desc = ctx.wb.registry.nodes.get(node.typeId);
|
|
4588
4596
|
return desc?.displayName || node.typeId;
|
|
4589
4597
|
}, [ctx, id, typeId]);
|
|
4590
4598
|
const handleInvalidate = React.useCallback(() => {
|
|
@@ -5043,7 +5051,7 @@ function Inspector({ debug, autoScroll, hideWorkbench, onAutoScrollChange, onHid
|
|
|
5043
5051
|
return String(value ?? "");
|
|
5044
5052
|
}
|
|
5045
5053
|
};
|
|
5046
|
-
const { wb,
|
|
5054
|
+
const { wb, registryVersion, selectedNodeId, selectedEdgeId, inputsMap, inputDefaultsMap, outputsMap, outputTypesMap, nodeStatus, edgeStatus, validationByNode, validationByEdge, validationGlobal, valuesTick, updateEdgeType, systemErrors, registryErrors, inputValidationErrors, clearSystemErrors, clearRegistryErrors, clearInputValidationErrors, removeSystemError, removeRegistryError, removeInputValidationError, } = useWorkbenchContext();
|
|
5047
5055
|
const nodeValidationIssues = validationByNode.issues;
|
|
5048
5056
|
const edgeValidationIssues = validationByEdge.issues;
|
|
5049
5057
|
const nodeValidationHandles = validationByNode;
|
|
@@ -5052,7 +5060,7 @@ function Inspector({ debug, autoScroll, hideWorkbench, onAutoScrollChange, onHid
|
|
|
5052
5060
|
const selectedEdge = wb.def.edges.find((e) => e.id === selectedEdgeId);
|
|
5053
5061
|
// Use computeEffectiveHandles to merge registry defaults with dynamically resolved handles
|
|
5054
5062
|
const effectiveHandles = selectedNode
|
|
5055
|
-
? computeEffectiveHandles(selectedNode, registry)
|
|
5063
|
+
? computeEffectiveHandles(selectedNode, wb.registry)
|
|
5056
5064
|
: { inputs: {}, outputs: {}};
|
|
5057
5065
|
const inputHandles = Object.entries(effectiveHandles.inputs)
|
|
5058
5066
|
.filter(([k]) => !sparkGraph.isInputPrivate(effectiveHandles.inputs, k))
|
|
@@ -5179,7 +5187,7 @@ function Inspector({ debug, autoScroll, hideWorkbench, onAutoScrollChange, onHid
|
|
|
5179
5187
|
setDrafts(nextDrafts);
|
|
5180
5188
|
if (!shallowEqual(originals, nextOriginals))
|
|
5181
5189
|
setOriginals(nextOriginals);
|
|
5182
|
-
}, [selectedNodeId, selectedNode, registry, valuesTick]);
|
|
5190
|
+
}, [selectedNodeId, selectedNode, wb.registry, registryVersion, valuesTick]);
|
|
5183
5191
|
const widthClass = debug ? "w-[480px]" : "w-[320px]";
|
|
5184
5192
|
const deleteEdgeById = (edgeId) => {
|
|
5185
5193
|
if (!edgeId)
|
|
@@ -5199,7 +5207,7 @@ function Inspector({ debug, autoScroll, hideWorkbench, onAutoScrollChange, onHid
|
|
|
5199
5207
|
const v = e.target.value;
|
|
5200
5208
|
const next = v === "" ? undefined : v;
|
|
5201
5209
|
updateEdgeType(selectedEdge.id, next);
|
|
5202
|
-
}, children: [jsxRuntime.jsx("option", { value: "", children: "(infer from source)" }), Array.from(registry.types.keys()).map((tid) => (jsxRuntime.jsx("option", { value: tid, children: tid }, tid)))] })] })] }), selectedEdgeValidation.length > 0 && (jsxRuntime.jsxs("div", { className: "mt-2 text-xs bg-red-50 border border-red-200 rounded px-2 py-1", children: [jsxRuntime.jsx("div", { className: "font-semibold mb-1", children: "Validation" }), jsxRuntime.jsx("ul", { className: "list-disc ml-4", children: selectedEdgeValidation.map((m, i) => (jsxRuntime.jsxs("li", { className: "flex items-center gap-1", children: [jsxRuntime.jsx(IssueBadge, { level: m.level, size: 24, className: "w-6 h-6" }), jsxRuntime.jsx("span", { children: `${m.code}: ${m.message}` }), jsxRuntime.jsx("button", { className: "ml-2 text-[10px] px-1 py-[2px] border border-red-300 rounded text-red-700 hover:bg-red-50", onClick: (e) => {
|
|
5210
|
+
}, children: [jsxRuntime.jsx("option", { value: "", children: "(infer from source)" }), Array.from(wb.registry.types.keys()).map((tid) => (jsxRuntime.jsx("option", { value: tid, children: tid }, tid)))] })] })] }), selectedEdgeValidation.length > 0 && (jsxRuntime.jsxs("div", { className: "mt-2 text-xs bg-red-50 border border-red-200 rounded px-2 py-1", children: [jsxRuntime.jsx("div", { className: "font-semibold mb-1", children: "Validation" }), jsxRuntime.jsx("ul", { className: "list-disc ml-4", children: selectedEdgeValidation.map((m, i) => (jsxRuntime.jsxs("li", { className: "flex items-center gap-1", children: [jsxRuntime.jsx(IssueBadge, { level: m.level, size: 24, className: "w-6 h-6" }), jsxRuntime.jsx("span", { children: `${m.code}: ${m.message}` }), jsxRuntime.jsx("button", { className: "ml-2 text-[10px] px-1 py-[2px] border border-red-300 rounded text-red-700 hover:bg-red-50", onClick: (e) => {
|
|
5203
5211
|
e.stopPropagation();
|
|
5204
5212
|
deleteEdgeById(selectedEdge.id);
|
|
5205
5213
|
}, title: "Delete this edge", children: "Delete edge" })] }, i))) })] }))] })) : (jsxRuntime.jsxs("div", { children: [selectedNode && (jsxRuntime.jsxs("div", { className: "mb-2", children: [jsxRuntime.jsxs("div", { children: ["Node: ", selectedNode.nodeId] }), jsxRuntime.jsxs("div", { children: ["Type: ", selectedNode.typeId] }), !!selectedNodeStatus?.activeRuns &&
|
|
@@ -5269,7 +5277,7 @@ function Inspector({ debug, autoScroll, hideWorkbench, onAutoScrollChange, onHid
|
|
|
5269
5277
|
setOriginals((o) => ({ ...o, [h]: display }));
|
|
5270
5278
|
}, ...commonProps, children: [jsxRuntime.jsx("option", { value: "", children: placeholder
|
|
5271
5279
|
? `Default: ${placeholder}`
|
|
5272
|
-
: "(select)" }), registry.enums
|
|
5280
|
+
: "(select)" }), wb.registry.enums
|
|
5273
5281
|
.get(typeId)
|
|
5274
5282
|
?.options.map((opt) => (jsxRuntime.jsx("option", { value: String(opt.value), children: opt.label }, opt.value)))] }), hasValue && !isLinked && (jsxRuntime.jsx("button", { className: "flex-shrink-0 p-1 hover:bg-gray-100 rounded text-gray-500 hover:text-gray-700", onClick: clearInput, title: "Clear input value", children: jsxRuntime.jsx(react$1.XCircleIcon, { size: 16 }) }))] })) : isLinked ? (jsxRuntime.jsx("div", { className: "flex items-center gap-1 flex-1", children: jsxRuntime.jsx("div", { className: "flex-1 min-w-0", children: renderLinkedInputDisplay(typeId, current) }) })) : (jsxRuntime.jsxs("div", { className: "flex items-center gap-1 flex-1", children: [jsxRuntime.jsx("input", { className: "border border-gray-300 rounded px-2 py-1 focus:outline-none focus:ring-2 focus:ring-blue-500 flex-1 select-text", placeholder: placeholder
|
|
5275
5283
|
? `Default: ${placeholder}`
|
|
@@ -5538,10 +5546,9 @@ function useKeyboardShortcutToast() {
|
|
|
5538
5546
|
}
|
|
5539
5547
|
|
|
5540
5548
|
const WorkbenchCanvas = React.forwardRef(({ showValues, toString, toElement, getDefaultNodeSize }, ref) => {
|
|
5541
|
-
const { wb,
|
|
5549
|
+
const { wb, inputsMap, inputDefaultsMap, outputsMap, outputTypesMap, valuesTick, nodeStatus, edgeStatus, validationByNode, validationByEdge, uiVersion, registryVersion, runner, engineKind, overrides, } = useWorkbenchContext();
|
|
5542
5550
|
const nodeValidation = validationByNode;
|
|
5543
5551
|
const edgeValidation = validationByEdge.errors;
|
|
5544
|
-
const [registryVersion, setRegistryVersion] = React.useState(0);
|
|
5545
5552
|
const [historyState, setHistoryState] = React.useState(wb.getHistory());
|
|
5546
5553
|
const prevNodesRef = React.useRef([]);
|
|
5547
5554
|
const prevEdgesRef = React.useRef([]);
|
|
@@ -5617,7 +5624,7 @@ const WorkbenchCanvas = React.forwardRef(({ showValues, toString, toElement, get
|
|
|
5617
5624
|
// Build nodeTypes map using UI extension registry
|
|
5618
5625
|
const custom = new Map(); // Include all types present in registry AND current graph to avoid timing issues
|
|
5619
5626
|
const ids = new Set([
|
|
5620
|
-
...Array.from(registry.nodes.keys()),
|
|
5627
|
+
...Array.from(wb.registry.nodes.keys()),
|
|
5621
5628
|
...wb.def.nodes.map((n) => n.typeId),
|
|
5622
5629
|
]);
|
|
5623
5630
|
for (const typeId of ids) {
|
|
@@ -5635,7 +5642,8 @@ const WorkbenchCanvas = React.forwardRef(({ showValues, toString, toElement, get
|
|
|
5635
5642
|
const resolver = (nodeTypeId) => custom.has(nodeTypeId) ? `spark-${nodeTypeId}` : "spark-default";
|
|
5636
5643
|
return { nodeTypes: types, resolveNodeType: resolver };
|
|
5637
5644
|
// Include uiVersion to recompute when custom renderers are registered
|
|
5638
|
-
|
|
5645
|
+
// Include registryVersion to recompute when registry enums/types change
|
|
5646
|
+
}, [wb, wb.registry, registryVersion, uiVersion, ui]);
|
|
5639
5647
|
const edgeTypes = React.useMemo(() => {
|
|
5640
5648
|
// Use default edge renderer override if registered, otherwise use DefaultEdge
|
|
5641
5649
|
const customEdgeRenderer = ui.getEdgeRenderer();
|
|
@@ -5661,7 +5669,7 @@ const WorkbenchCanvas = React.forwardRef(({ showValues, toString, toElement, get
|
|
|
5661
5669
|
inputsWithDefaults[n.nodeId] = merged;
|
|
5662
5670
|
}
|
|
5663
5671
|
}
|
|
5664
|
-
const out = toReactFlow(wb.def, wb.getPositions(), wb.getSizes(), registry, {
|
|
5672
|
+
const out = toReactFlow(wb.def, wb.getPositions(), wb.getSizes(), wb.registry, {
|
|
5665
5673
|
showValues,
|
|
5666
5674
|
inputs: inputsWithDefaults,
|
|
5667
5675
|
inputDefaults: inputDefaultsMap,
|
|
@@ -5922,19 +5930,13 @@ const WorkbenchCanvas = React.forwardRef(({ showValues, toString, toElement, get
|
|
|
5922
5930
|
const onCloseSelectionMenu = React.useCallback(() => {
|
|
5923
5931
|
setSelectionMenuOpen(false);
|
|
5924
5932
|
}, []);
|
|
5925
|
-
React.useEffect(() => {
|
|
5926
|
-
const off = runner.on("registry", () => {
|
|
5927
|
-
setRegistryVersion((v) => v + 1);
|
|
5928
|
-
});
|
|
5929
|
-
return () => off();
|
|
5930
|
-
}, [runner]);
|
|
5931
5933
|
React.useEffect(() => {
|
|
5932
5934
|
const off = wb.on("historyChanged", (event) => {
|
|
5933
5935
|
setHistoryState(event.history);
|
|
5934
5936
|
});
|
|
5935
5937
|
return () => off();
|
|
5936
5938
|
}, [wb]);
|
|
5937
|
-
const nodeIds = React.useMemo(() => Array.from(registry.nodes.keys()), [registry, registryVersion]);
|
|
5939
|
+
const nodeIds = React.useMemo(() => Array.from(wb.registry.nodes.keys()), [wb.registry, registryVersion]);
|
|
5938
5940
|
const defaultContextMenuHandlers = React.useMemo(() => {
|
|
5939
5941
|
// Get storage from override or use workbench's internal storage
|
|
5940
5942
|
const storage = overrides?.getCopiedDataStorage
|
|
@@ -5982,7 +5984,7 @@ const WorkbenchCanvas = React.forwardRef(({ showValues, toString, toElement, get
|
|
|
5982
5984
|
get: () => wb.getCopiedData(),
|
|
5983
5985
|
set: (data) => wb.setCopiedData(data),
|
|
5984
5986
|
};
|
|
5985
|
-
const baseHandlers = createNodeContextMenuHandlers(nodeAtMenu, wb, runner, registry, outputsMap, outputTypesMap, onCloseNodeMenu, overrides?.getDefaultNodeSize, (data) => {
|
|
5987
|
+
const baseHandlers = createNodeContextMenuHandlers(nodeAtMenu, wb, runner, wb.registry, outputsMap, outputTypesMap, onCloseNodeMenu, overrides?.getDefaultNodeSize, (data) => {
|
|
5986
5988
|
storage.set(data);
|
|
5987
5989
|
});
|
|
5988
5990
|
if (overrides?.getNodeContextMenuHandlers) {
|
|
@@ -5993,7 +5995,8 @@ const WorkbenchCanvas = React.forwardRef(({ showValues, toString, toElement, get
|
|
|
5993
5995
|
nodeAtMenu,
|
|
5994
5996
|
wb,
|
|
5995
5997
|
runner,
|
|
5996
|
-
registry,
|
|
5998
|
+
wb.registry,
|
|
5999
|
+
registryVersion,
|
|
5997
6000
|
outputsMap,
|
|
5998
6001
|
outputTypesMap,
|
|
5999
6002
|
onCloseNodeMenu,
|
|
@@ -6005,8 +6008,8 @@ const WorkbenchCanvas = React.forwardRef(({ showValues, toString, toElement, get
|
|
|
6005
6008
|
const bakeableOutputs = React.useMemo(() => {
|
|
6006
6009
|
if (!nodeAtMenu)
|
|
6007
6010
|
return [];
|
|
6008
|
-
return getBakeableOutputs(nodeAtMenu, wb, registry, outputTypesMap);
|
|
6009
|
-
}, [nodeAtMenu, wb, registry, outputTypesMap]);
|
|
6011
|
+
return getBakeableOutputs(nodeAtMenu, wb, wb.registry, outputTypesMap);
|
|
6012
|
+
}, [nodeAtMenu, wb, wb.registry, registryVersion, outputTypesMap]);
|
|
6010
6013
|
// Keyboard shortcuts configuration
|
|
6011
6014
|
const enableKeyboardShortcuts = overrides?.enableKeyboardShortcuts !== false; // Default to true
|
|
6012
6015
|
const keyboardShortcuts = overrides?.keyboardShortcuts || {
|
|
@@ -6202,9 +6205,9 @@ const WorkbenchCanvas = React.forwardRef(({ showValues, toString, toElement, get
|
|
|
6202
6205
|
if (savedViewport) {
|
|
6203
6206
|
inst.setViewport(lod.clone(savedViewport));
|
|
6204
6207
|
}
|
|
6205
|
-
}, 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", children: [BackgroundRenderer ? (jsxRuntime.jsx(BackgroundRenderer, {})) : (jsxRuntime.jsx(react.Background, { id: "workbench-canvas-background", variant: react.BackgroundVariant.Dots, gap: 12, size: 1 })), MinimapRenderer ? jsxRuntime.jsx(MinimapRenderer, {}) : jsxRuntime.jsx(react.MiniMap, {}), ControlsRenderer ? jsxRuntime.jsx(ControlsRenderer, {}) : jsxRuntime.jsx(react.Controls, {}), DefaultContextMenuRenderer ? (jsxRuntime.jsx(DefaultContextMenuRenderer, { open: menuOpen, clientPos: menuPos, handlers: defaultContextMenuHandlers, registry: registry, nodeIds: nodeIds, ...(enableKeyboardShortcuts !== false
|
|
6208
|
+
}, 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", children: [BackgroundRenderer ? (jsxRuntime.jsx(BackgroundRenderer, {})) : (jsxRuntime.jsx(react.Background, { id: "workbench-canvas-background", variant: react.BackgroundVariant.Dots, gap: 12, size: 1 })), MinimapRenderer ? jsxRuntime.jsx(MinimapRenderer, {}) : jsxRuntime.jsx(react.MiniMap, {}), ControlsRenderer ? jsxRuntime.jsx(ControlsRenderer, {}) : jsxRuntime.jsx(react.Controls, {}), DefaultContextMenuRenderer ? (jsxRuntime.jsx(DefaultContextMenuRenderer, { open: menuOpen, clientPos: menuPos, handlers: defaultContextMenuHandlers, registry: wb.registry, nodeIds: nodeIds, ...(enableKeyboardShortcuts !== false
|
|
6206
6209
|
? { enableKeyboardShortcuts, keyboardShortcuts }
|
|
6207
|
-
: {}) })) : (jsxRuntime.jsx(DefaultContextMenu, { open: menuOpen, clientPos: menuPos, handlers: defaultContextMenuHandlers, registry: registry, nodeIds: nodeIds, enableKeyboardShortcuts: enableKeyboardShortcuts, keyboardShortcuts: keyboardShortcuts })), !!nodeAtMenu &&
|
|
6210
|
+
: {}) })) : (jsxRuntime.jsx(DefaultContextMenu, { open: menuOpen, clientPos: menuPos, handlers: defaultContextMenuHandlers, registry: wb.registry, nodeIds: nodeIds, enableKeyboardShortcuts: enableKeyboardShortcuts, keyboardShortcuts: keyboardShortcuts })), !!nodeAtMenu &&
|
|
6208
6211
|
nodeContextMenuHandlers &&
|
|
6209
6212
|
(NodeContextMenuRenderer ? (jsxRuntime.jsx(NodeContextMenuRenderer, { open: nodeMenuOpen, clientPos: nodeMenuPos, nodeId: nodeAtMenu, handlers: nodeContextMenuHandlers, canRunPull: canRunPull, bakeableOutputs: bakeableOutputs, ...(enableKeyboardShortcuts !== false
|
|
6210
6213
|
? { enableKeyboardShortcuts, keyboardShortcuts }
|
|
@@ -6213,14 +6216,14 @@ const WorkbenchCanvas = React.forwardRef(({ showValues, toString, toElement, get
|
|
|
6213
6216
|
(SelectionContextMenuRenderer ? (jsxRuntime.jsx(SelectionContextMenuRenderer, { open: selectionMenuOpen, clientPos: selectionMenuPos, handlers: selectionContextMenuHandlers, enableKeyboardShortcuts: enableKeyboardShortcuts, keyboardShortcuts: keyboardShortcuts })) : (jsxRuntime.jsx(SelectionContextMenu, { open: selectionMenuOpen, clientPos: selectionMenuPos, handlers: selectionContextMenuHandlers, enableKeyboardShortcuts: enableKeyboardShortcuts, keyboardShortcuts: keyboardShortcuts })))] }) }), toast && (jsxRuntime.jsx(KeyboardShortcutToast, { message: toast.message, onClose: hideToast }, toast.id))] }));
|
|
6214
6217
|
});
|
|
6215
6218
|
|
|
6216
|
-
function WorkbenchStudioCanvas({
|
|
6217
|
-
const { wb, runner,
|
|
6219
|
+
function WorkbenchStudioCanvas({ autoScroll, onAutoScrollChange, example, onExampleChange, engine, onEngineChange, backendKind, onBackendKindChange, httpBaseUrl, onHttpBaseUrlChange, wsUrl, onWsUrlChange, debug, onDebugChange, showValues, onShowValuesChange, hideWorkbench, onHideWorkbenchChange, overrides, onInit, onChange, }) {
|
|
6220
|
+
const { wb, runner, selectedNodeId, runAutoLayout } = useWorkbenchContext();
|
|
6218
6221
|
const [transportStatus, setTransportStatus] = React.useState({
|
|
6219
6222
|
state: "local",
|
|
6220
6223
|
});
|
|
6221
6224
|
const selectedNode = wb.def.nodes.find((n) => n.nodeId === selectedNodeId);
|
|
6222
6225
|
const effectiveHandles = selectedNode
|
|
6223
|
-
? computeEffectiveHandles(selectedNode, registry)
|
|
6226
|
+
? computeEffectiveHandles(selectedNode, wb.registry)
|
|
6224
6227
|
: { inputs: {}, outputs: {}, inputDefaults: {} };
|
|
6225
6228
|
const [exampleState, setExampleState] = React.useState(example ?? "");
|
|
6226
6229
|
const isGraphRunning = runner.isRunning();
|
|
@@ -6367,7 +6370,6 @@ function WorkbenchStudioCanvas({ setRegistry, autoScroll, onAutoScrollChange, ex
|
|
|
6367
6370
|
// - For remote backend, registry is automatically managed by RemoteGraphRunner
|
|
6368
6371
|
if (backendKind === "local") {
|
|
6369
6372
|
if (r) {
|
|
6370
|
-
setRegistry(r);
|
|
6371
6373
|
wb.setRegistry(r);
|
|
6372
6374
|
}
|
|
6373
6375
|
}
|
|
@@ -6383,15 +6385,7 @@ function WorkbenchStudioCanvas({ setRegistry, autoScroll, onAutoScrollChange, ex
|
|
|
6383
6385
|
runAutoLayout();
|
|
6384
6386
|
setExampleState(key);
|
|
6385
6387
|
onExampleChange?.(key);
|
|
6386
|
-
}, [
|
|
6387
|
-
runner,
|
|
6388
|
-
wb,
|
|
6389
|
-
onExampleChange,
|
|
6390
|
-
runAutoLayout,
|
|
6391
|
-
examples,
|
|
6392
|
-
setRegistry,
|
|
6393
|
-
backendKind,
|
|
6394
|
-
]);
|
|
6388
|
+
}, [runner, wb, onExampleChange, runAutoLayout, examples, backendKind]);
|
|
6395
6389
|
const download$1 = React.useCallback(async () => {
|
|
6396
6390
|
try {
|
|
6397
6391
|
await download(wb, runner);
|
|
@@ -6562,11 +6556,11 @@ function WorkbenchStudioCanvas({ setRegistry, autoScroll, onAutoScrollChange, ex
|
|
|
6562
6556
|
return overrides.setInput(baseSetInput, {
|
|
6563
6557
|
runner,
|
|
6564
6558
|
selectedNodeId,
|
|
6565
|
-
registry,
|
|
6559
|
+
registry: wb.registry,
|
|
6566
6560
|
});
|
|
6567
6561
|
}
|
|
6568
6562
|
return baseSetInput;
|
|
6569
|
-
}, [overrides, baseSetInput, runner, selectedNodeId, registry]);
|
|
6563
|
+
}, [overrides, baseSetInput, runner, selectedNodeId, wb.registry]);
|
|
6570
6564
|
const baseToString = React.useCallback((typeId, value) => {
|
|
6571
6565
|
if (value === undefined || value === null)
|
|
6572
6566
|
return "";
|
|
@@ -6574,7 +6568,7 @@ function WorkbenchStudioCanvas({ setRegistry, autoScroll, onAutoScrollChange, ex
|
|
|
6574
6568
|
if (sparkGraph.isTypedOutput(value)) {
|
|
6575
6569
|
return baseToString(sparkGraph.getTypedOutputTypeId(value), sparkGraph.getTypedOutputValue(value));
|
|
6576
6570
|
}
|
|
6577
|
-
const pre = preformatValueForDisplay(typeId, value, registry);
|
|
6571
|
+
const pre = preformatValueForDisplay(typeId, value, wb.registry);
|
|
6578
6572
|
if (pre !== undefined)
|
|
6579
6573
|
return pre;
|
|
6580
6574
|
if (typeof value === "object" &&
|
|
@@ -6590,7 +6584,7 @@ function WorkbenchStudioCanvas({ setRegistry, autoScroll, onAutoScrollChange, ex
|
|
|
6590
6584
|
}
|
|
6591
6585
|
if (typeId && typeId.startsWith("enum:")) {
|
|
6592
6586
|
const n = Number(value);
|
|
6593
|
-
const label = registry.enums.get(typeId)?.valueToLabel.get(n);
|
|
6587
|
+
const label = wb.registry.enums.get(typeId)?.valueToLabel.get(n);
|
|
6594
6588
|
return label ?? String(n);
|
|
6595
6589
|
}
|
|
6596
6590
|
const round4 = (n) => Math.round(Number(n) * 10000) / 10000;
|
|
@@ -6620,22 +6614,22 @@ function WorkbenchStudioCanvas({ setRegistry, autoScroll, onAutoScrollChange, ex
|
|
|
6620
6614
|
return String(rounded);
|
|
6621
6615
|
}
|
|
6622
6616
|
return String(value);
|
|
6623
|
-
}, [registry]);
|
|
6617
|
+
}, [wb.registry]);
|
|
6624
6618
|
const baseToElement = React.useCallback((typeId, value) => {
|
|
6625
6619
|
return (jsxRuntime.jsx("span", { className: "ml-1 opacity-60", children: baseToString(typeId, value) }));
|
|
6626
6620
|
}, [baseToString]);
|
|
6627
6621
|
const toString = React.useMemo(() => {
|
|
6628
6622
|
if (overrides?.toString)
|
|
6629
|
-
return overrides.toString(baseToString, { registry });
|
|
6623
|
+
return overrides.toString(baseToString, { registry: wb.registry });
|
|
6630
6624
|
return baseToString;
|
|
6631
|
-
}, [overrides, baseToString, registry]);
|
|
6625
|
+
}, [overrides, baseToString, wb.registry]);
|
|
6632
6626
|
// Optional: toElement (not currently consumed by core UI)
|
|
6633
6627
|
// Consumers can access it by passing through their own node renderers.
|
|
6634
6628
|
const toElement = React.useMemo(() => {
|
|
6635
6629
|
if (overrides?.toElement)
|
|
6636
|
-
return overrides.toElement(baseToElement, { registry });
|
|
6630
|
+
return overrides.toElement(baseToElement, { registry: wb.registry });
|
|
6637
6631
|
return baseToElement;
|
|
6638
|
-
}, [overrides, baseToElement, registry]);
|
|
6632
|
+
}, [overrides, baseToElement, wb.registry]);
|
|
6639
6633
|
return (jsxRuntime.jsxs("div", { className: "w-full h-screen flex flex-col", children: [jsxRuntime.jsxs("div", { className: "p-2 border-b border-gray-300 flex gap-2 items-center", children: [isGraphRunning ? (jsxRuntime.jsxs("span", { className: "ml-2 text-sm text-green-700", children: ["Running: ", engineKind] })) : (jsxRuntime.jsx("span", { className: "ml-2 text-sm text-gray-500", children: "Stopped" })), jsxRuntime.jsxs("span", { className: "ml-2 flex items-center gap-1 text-xs", title: transportStatus.kind || undefined, children: [transportStatus.state === "local" && (jsxRuntime.jsx(react$1.PlugsConnectedIcon, { size: 14, className: "text-gray-500" })), transportStatus.state === "connecting" && (jsxRuntime.jsx(react$1.ClockClockwiseIcon, { size: 14, className: "text-amber-600 animate-pulse" })), transportStatus.state === "connected" && (jsxRuntime.jsx(react$1.WifiHighIcon, { size: 14, className: "text-green-600" })), transportStatus.state === "disconnected" && (jsxRuntime.jsx(react$1.WifiSlashIcon, { size: 14, className: "text-red-600" })), transportStatus.state === "retrying" && (jsxRuntime.jsx(react$1.ClockClockwiseIcon, { size: 14, className: "text-amber-700 animate-pulse" }))] }), jsxRuntime.jsxs("select", { className: "border border-gray-300 rounded px-2 py-1", value: exampleState, onChange: (e) => applyExample(e.target.value), disabled: isGraphRunning, title: isGraphRunning ? "Stop engine before switching example" : undefined, children: [jsxRuntime.jsx("option", { value: "", children: "Select Example\u2026" }), examples.map((ex) => (jsxRuntime.jsx("option", { value: ex.id, children: ex.label }, ex.id)))] }), jsxRuntime.jsxs("select", { className: "border border-gray-300 rounded px-2 py-1", value: backendKind, onChange: (e) => onBackendKindChange(e.target.value), disabled: isGraphRunning, title: isGraphRunning ? "Stop engine before switching backend" : undefined, children: [jsxRuntime.jsx("option", { value: "local", children: "Local" }), jsxRuntime.jsx("option", { value: "remote-http", children: "Remote (HTTP)" }), jsxRuntime.jsx("option", { value: "remote-ws", children: "Remote (WebSocket)" })] }), backendKind === "remote-http" && !!onHttpBaseUrlChange && (jsxRuntime.jsx("input", { className: "border border-gray-300 rounded px-2 py-1 w-72", placeholder: "http://127.0.0.1:18080", value: httpBaseUrl, onChange: (e) => onHttpBaseUrlChange(e.target.value) })), backendKind === "remote-ws" && !!onWsUrlChange && (jsxRuntime.jsx("input", { className: "border border-gray-300 rounded px-2 py-1 w-72", placeholder: "ws://127.0.0.1:18081", value: wsUrl, onChange: (e) => onWsUrlChange(e.target.value) })), jsxRuntime.jsxs("select", { className: "border border-gray-300 rounded px-2 py-1", value: engineKind ?? engine ?? "", onChange: async (e) => {
|
|
6640
6634
|
const kind = e.target.value || undefined;
|
|
6641
6635
|
const currentEngine = runner.getRunningEngine();
|
|
@@ -6737,7 +6731,7 @@ function WorkbenchStudio({ engine, onEngineChange, example, onExampleChange, bac
|
|
|
6737
6731
|
runner.dispose();
|
|
6738
6732
|
onBackendKindChange(v);
|
|
6739
6733
|
}, [isGraphRunning]);
|
|
6740
|
-
return (jsxRuntime.jsx(WorkbenchProvider, { wb: wb, runner: runner,
|
|
6734
|
+
return (jsxRuntime.jsx(WorkbenchProvider, { wb: wb, runner: runner, overrides: overrides, uiVersion: uiVersion, children: jsxRuntime.jsx(WorkbenchStudioCanvas, { setRegistry: setRegistry, autoScroll: autoScroll, onAutoScrollChange: onAutoScrollChange, example: example, onExampleChange: onExampleChange, engine: engine, onEngineChange: onEngineChange, backendKind: backendKind, onBackendKindChange: onBackendKindChangeWithDispose, httpBaseUrl: httpBaseUrl, onHttpBaseUrlChange: onHttpBaseUrlChange, wsUrl: wsUrl, onWsUrlChange: onWsUrlChange, debug: debug, onDebugChange: onDebugChange, showValues: showValues, onShowValuesChange: onShowValuesChange, hideWorkbench: hideWorkbench, onHideWorkbenchChange: onHideWorkbenchChange, overrides: overrides, onInit: onInit, onChange: onChange }) }));
|
|
6741
6735
|
}
|
|
6742
6736
|
|
|
6743
6737
|
exports.AbstractWorkbench = AbstractWorkbench;
|