@bian-womp/spark-workbench 0.3.9 → 0.3.10

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.
Files changed (31) hide show
  1. package/lib/cjs/index.cjs +60 -68
  2. package/lib/cjs/index.cjs.map +1 -1
  3. package/lib/cjs/src/core/InMemoryWorkbench.d.ts.map +1 -1
  4. package/lib/cjs/src/misc/WorkbenchCanvas.d.ts +4 -2
  5. package/lib/cjs/src/misc/WorkbenchCanvas.d.ts.map +1 -1
  6. package/lib/cjs/src/misc/WorkbenchStudio.d.ts.map +1 -1
  7. package/lib/cjs/src/misc/context/WorkbenchContext.provider.d.ts.map +1 -1
  8. package/lib/cjs/src/runtime/AbstractGraphRunner.d.ts +2 -2
  9. package/lib/cjs/src/runtime/AbstractGraphRunner.d.ts.map +1 -1
  10. package/lib/cjs/src/runtime/IGraphRunner.d.ts +1 -1
  11. package/lib/cjs/src/runtime/IGraphRunner.d.ts.map +1 -1
  12. package/lib/cjs/src/runtime/LocalGraphRunner.d.ts +1 -1
  13. package/lib/cjs/src/runtime/LocalGraphRunner.d.ts.map +1 -1
  14. package/lib/cjs/src/runtime/RemoteGraphRunner.d.ts +1 -2
  15. package/lib/cjs/src/runtime/RemoteGraphRunner.d.ts.map +1 -1
  16. package/lib/esm/index.js +61 -70
  17. package/lib/esm/index.js.map +1 -1
  18. package/lib/esm/src/core/InMemoryWorkbench.d.ts.map +1 -1
  19. package/lib/esm/src/misc/WorkbenchCanvas.d.ts +4 -2
  20. package/lib/esm/src/misc/WorkbenchCanvas.d.ts.map +1 -1
  21. package/lib/esm/src/misc/WorkbenchStudio.d.ts.map +1 -1
  22. package/lib/esm/src/misc/context/WorkbenchContext.provider.d.ts.map +1 -1
  23. package/lib/esm/src/runtime/AbstractGraphRunner.d.ts +2 -2
  24. package/lib/esm/src/runtime/AbstractGraphRunner.d.ts.map +1 -1
  25. package/lib/esm/src/runtime/IGraphRunner.d.ts +1 -1
  26. package/lib/esm/src/runtime/IGraphRunner.d.ts.map +1 -1
  27. package/lib/esm/src/runtime/LocalGraphRunner.d.ts +1 -1
  28. package/lib/esm/src/runtime/LocalGraphRunner.d.ts.map +1 -1
  29. package/lib/esm/src/runtime/RemoteGraphRunner.d.ts +1 -2
  30. package/lib/esm/src/runtime/RemoteGraphRunner.d.ts.map +1 -1
  31. package/package.json +4 -4
package/lib/cjs/index.cjs CHANGED
@@ -161,6 +161,7 @@ class InMemoryWorkbench extends AbstractWorkbench {
161
161
  }
162
162
  setRegistry(registry) {
163
163
  this._registry = registry;
164
+ this.refreshValidation();
164
165
  this.emit("registryChanged", { registry });
165
166
  }
166
167
  /**
@@ -1034,12 +1035,12 @@ class CLIWorkbench {
1034
1035
  }
1035
1036
 
1036
1037
  class AbstractGraphRunner {
1037
- constructor(registry, backend) {
1038
- this.registry = registry;
1038
+ constructor(backend, registry) {
1039
1039
  this.backend = backend;
1040
1040
  this.listeners = new Map();
1041
1041
  this.stagedInputs = {};
1042
1042
  this.runnerId = "";
1043
+ this.registry = registry ?? sparkGraph.createSimpleGraphRegistry();
1043
1044
  }
1044
1045
  async whenIdle() {
1045
1046
  await this.engine?.whenIdle();
@@ -1099,7 +1100,7 @@ class AbstractGraphRunner {
1099
1100
  let localRunnerCounter = 0;
1100
1101
  class LocalGraphRunner extends AbstractGraphRunner {
1101
1102
  constructor(registry) {
1102
- super(registry, { kind: "local" });
1103
+ super({ kind: "local" }, registry);
1103
1104
  this.extData = {};
1104
1105
  this.setEnvironment = (env, opts) => {
1105
1106
  if (!this.runtime)
@@ -1600,8 +1601,8 @@ class RemoteGraphRunner extends AbstractGraphRunner {
1600
1601
  })();
1601
1602
  return this.clientPromise;
1602
1603
  }
1603
- constructor(registry, backend) {
1604
- super(registry, backend);
1604
+ constructor(backend) {
1605
+ super(backend);
1605
1606
  this.disposed = false;
1606
1607
  this.valueCache = new Map();
1607
1608
  this.listenersBound = false;
@@ -1890,7 +1891,7 @@ class RemoteGraphRunner extends AbstractGraphRunner {
1890
1891
  return await client.api.snapshotFull();
1891
1892
  }
1892
1893
  catch {
1893
- return { def: undefined, environment: {}, inputs: {}, outputs: {} };
1894
+ return { inputs: {}, outputs: {} };
1894
1895
  }
1895
1896
  }
1896
1897
  async applySnapshotFull(payload, options) {
@@ -4464,7 +4465,6 @@ function WorkbenchProvider({ wb, runner, overrides, uiVersion, children, }) {
4464
4465
  const offRunnerRegistry = runner.on("registry", async (newReg) => {
4465
4466
  try {
4466
4467
  wb.setRegistry(newReg);
4467
- // Increment registry version to trigger UI updates
4468
4468
  // Trigger a graph update so the UI revalidates with new types/enums/nodes
4469
4469
  try {
4470
4470
  await runner.update(wb.def);
@@ -5759,7 +5759,8 @@ const SelectionBoundOverlay = ({ selection, rfInstance }) => {
5759
5759
  } }));
5760
5760
  };
5761
5761
 
5762
- const WorkbenchCanvas = React.forwardRef(({ showValues, toString, toElement, getDefaultNodeSize, reactFlowProps }, ref) => {
5762
+ const WorkbenchCanvasComponent = React.forwardRef((props, ref) => {
5763
+ const { showValues, toString, toElement, getDefaultNodeSize, reactFlowProps, } = props;
5763
5764
  const { wb, inputsMap, inputDefaultsMap, outputsMap, outputTypesMap, valuesTick, nodeStatus, edgeStatus, validationByNode, validationByEdge, uiVersion, registryVersion, runner, overrides, runNode, runFromHere, runMode, } = useWorkbenchContext();
5764
5765
  const nodeValidation = validationByNode;
5765
5766
  const edgeValidation = validationByEdge.errors;
@@ -5842,7 +5843,7 @@ const WorkbenchCanvas = React.forwardRef(({ showValues, toString, toElement, get
5842
5843
  },
5843
5844
  }), []);
5844
5845
  const { onConnect, onNodesChange, onEdgesChange, onEdgesDelete, onNodesDelete, } = useWorkbenchBridge(wb);
5845
- const ui = wb.getUI();
5846
+ const ui = React.useMemo(() => wb.getUI(), [wb, uiVersion]);
5846
5847
  const { nodeTypes, resolveNodeType } = React.useMemo(() => {
5847
5848
  // Build nodeTypes map using UI extension registry
5848
5849
  const custom = new Map(); // Include all types present in registry AND current graph to avoid timing issues
@@ -5872,8 +5873,17 @@ const WorkbenchCanvas = React.forwardRef(({ showValues, toString, toElement, get
5872
5873
  const customEdgeRenderer = ui.getEdgeRenderer();
5873
5874
  return { default: customEdgeRenderer || DefaultEdge };
5874
5875
  }, [uiVersion, ui]);
5875
- const { nodes, edges } = React.useMemo(() => {
5876
- const sel = wb.getSelection();
5876
+ // Track selection state to prevent unnecessary re-renders
5877
+ const [selection, setSelection] = React.useState(() => wb.getSelection());
5878
+ React.useEffect(() => {
5879
+ const off = wb.on("selectionChanged", (sel) => {
5880
+ setSelection({ nodes: sel.nodes, edges: sel.edges });
5881
+ });
5882
+ return () => off();
5883
+ }, [wb]);
5884
+ // Memoize customData to prevent unnecessary recomputations
5885
+ const customData = React.useMemo(() => wb.getCustomData(), [wb]);
5886
+ const rfData = React.useMemo(() => {
5877
5887
  const out = toReactFlow(wb.def, wb.getPositions(), wb.getSizes(), wb.registry, {
5878
5888
  showValues,
5879
5889
  inputs: inputsMap,
@@ -5886,11 +5896,11 @@ const WorkbenchCanvas = React.forwardRef(({ showValues, toString, toElement, get
5886
5896
  edgeStatus,
5887
5897
  nodeValidation,
5888
5898
  edgeValidation,
5889
- selectedNodeIds: new Set(sel.nodes),
5890
- selectedEdgeIds: new Set(sel.edges),
5899
+ selectedNodeIds: new Set(selection.nodes),
5900
+ selectedEdgeIds: new Set(selection.edges),
5891
5901
  getDefaultNodeSize,
5892
5902
  ui,
5893
- customData: wb.getCustomData(),
5903
+ customData,
5894
5904
  });
5895
5905
  // Retain references for unchanged items
5896
5906
  const stableNodes = retainStabilityById(prevNodesRef.current, out.nodes, isSameNode);
@@ -5984,8 +5994,10 @@ const WorkbenchCanvas = React.forwardRef(({ showValues, toString, toElement, get
5984
5994
  }, [
5985
5995
  showValues,
5986
5996
  inputsMap,
5997
+ inputDefaultsMap,
5987
5998
  outputsMap,
5988
5999
  valuesTick,
6000
+ registryVersion,
5989
6001
  toString,
5990
6002
  toElement,
5991
6003
  nodeStatus,
@@ -5993,8 +6005,14 @@ const WorkbenchCanvas = React.forwardRef(({ showValues, toString, toElement, get
5993
6005
  nodeValidation,
5994
6006
  edgeValidation,
5995
6007
  resolveNodeType,
6008
+ selection,
6009
+ customData,
6010
+ ui,
6011
+ getDefaultNodeSize,
6012
+ wb,
6013
+ uiVersion,
5996
6014
  ]);
5997
- const throttled = useThrottledValue({ nodes, edges }, 100);
6015
+ const throttled = useThrottledValue(rfData, 100);
5998
6016
  const [menuState, setMenuState] = React.useState(null);
5999
6017
  // Compute the rectangular screen-space bounds of the current selection
6000
6018
  const getSelectionScreenBounds = () => {
@@ -6205,7 +6223,7 @@ const WorkbenchCanvas = React.forwardRef(({ showValues, toString, toElement, get
6205
6223
  }, [menuState, wb, wb.registry, registryVersion, outputTypesMap]);
6206
6224
  // Keyboard shortcuts configuration
6207
6225
  const enableKeyboardShortcuts = overrides?.enableKeyboardShortcuts !== false; // Default to true
6208
- const keyboardShortcuts = overrides?.keyboardShortcuts || {
6226
+ const keyboardShortcuts = React.useMemo(() => overrides?.keyboardShortcuts || {
6209
6227
  undo: "⌘/Ctrl + Z",
6210
6228
  redo: "⌘/Ctrl + Shift + Z",
6211
6229
  copy: "⌘/Ctrl + C",
@@ -6214,7 +6232,7 @@ const WorkbenchCanvas = React.forwardRef(({ showValues, toString, toElement, get
6214
6232
  duplicateWithEdges: "⌘/Ctrl + Shift + E",
6215
6233
  selectAll: "⌘/Ctrl + A",
6216
6234
  delete: "Delete",
6217
- };
6235
+ }, [overrides?.keyboardShortcuts]);
6218
6236
  // Toast notification for keyboard shortcuts
6219
6237
  const { toast, showToast, hideToast } = useKeyboardShortcutToast();
6220
6238
  // Keyboard shortcut handler
@@ -6272,8 +6290,7 @@ const WorkbenchCanvas = React.forwardRef(({ showValues, toString, toElement, get
6272
6290
  const modKeyLabel = isMac ? "⌘" : "Ctrl";
6273
6291
  showToast(`Copy (${modKeyLabel} + C)`);
6274
6292
  // If single node selected, use node context menu handler; otherwise use selection handler
6275
- if (selection.nodes.length === 1 &&
6276
- nodeContextMenuHandlers?.onCopy) {
6293
+ if (selection.nodes.length === 1 && nodeContextMenuHandlers?.onCopy) {
6277
6294
  nodeContextMenuHandlers.onCopy();
6278
6295
  }
6279
6296
  else if (selectionContextMenuHandlers.onCopy) {
@@ -6411,8 +6428,9 @@ const WorkbenchCanvas = React.forwardRef(({ showValues, toString, toElement, get
6411
6428
  (NodeContextMenuRenderer ? (jsxRuntime.jsx(NodeContextMenuRenderer, { open: true, clientPos: menuState.menuPos, nodeId: menuState.nodeId, handlers: nodeContextMenuHandlers, bakeableOutputs: bakeableOutputs, runMode: runMode, wb: wb, ...(enableKeyboardShortcuts !== false
6412
6429
  ? { enableKeyboardShortcuts, keyboardShortcuts }
6413
6430
  : {}) })) : (jsxRuntime.jsx(NodeContextMenu, { open: true, clientPos: menuState.menuPos, nodeId: menuState.nodeId, handlers: nodeContextMenuHandlers, bakeableOutputs: bakeableOutputs, runMode: runMode }))), menuState?.type === "selection" &&
6414
- (SelectionContextMenuRenderer ? (jsxRuntime.jsx(SelectionContextMenuRenderer, { open: true, clientPos: menuState.menuPos, handlers: selectionContextMenuHandlers, enableKeyboardShortcuts: enableKeyboardShortcuts, keyboardShortcuts: keyboardShortcuts })) : (jsxRuntime.jsx(SelectionContextMenu, { open: true, clientPos: menuState.menuPos, handlers: selectionContextMenuHandlers, enableKeyboardShortcuts: enableKeyboardShortcuts, keyboardShortcuts: keyboardShortcuts })))] }), jsxRuntime.jsx(SelectionBoundOverlay, { selection: wb.getSelection(), rfInstance: rfInstanceRef.current })] }), toast && (jsxRuntime.jsx(KeyboardShortcutToast, { message: toast.message, onClose: hideToast }, toast.id))] }));
6431
+ (SelectionContextMenuRenderer ? (jsxRuntime.jsx(SelectionContextMenuRenderer, { open: true, clientPos: menuState.menuPos, handlers: selectionContextMenuHandlers, enableKeyboardShortcuts: enableKeyboardShortcuts, keyboardShortcuts: keyboardShortcuts })) : (jsxRuntime.jsx(SelectionContextMenu, { open: true, clientPos: menuState.menuPos, handlers: selectionContextMenuHandlers, enableKeyboardShortcuts: enableKeyboardShortcuts, keyboardShortcuts: keyboardShortcuts })))] }), jsxRuntime.jsx(SelectionBoundOverlay, { selection: selection, rfInstance: rfInstanceRef.current })] }), toast && (jsxRuntime.jsx(KeyboardShortcutToast, { message: toast.message, onClose: hideToast }, toast.id))] }));
6415
6432
  });
6433
+ const WorkbenchCanvas = WorkbenchCanvasComponent;
6416
6434
 
6417
6435
  function WorkbenchStudioCanvas({ autoScroll, onAutoScrollChange, example, onExampleChange, backendKind, onBackendKindChange, httpBaseUrl, onHttpBaseUrlChange, wsUrl, onWsUrlChange, debug, onDebugChange, showValues, onShowValuesChange, hideWorkbench, onHideWorkbenchChange, overrides, onInit, onChange, }) {
6418
6436
  const { wb, runner, selectedNodeId, runAutoLayout, runMode, setRunMode, isRunning, } = useWorkbenchContext();
@@ -6439,7 +6457,10 @@ function WorkbenchStudioCanvas({ autoScroll, onAutoScrollChange, example, onExam
6439
6457
  if (isConnecting) {
6440
6458
  return (jsxRuntime.jsxs("button", { className: "border rounded px-2 py-1.5 text-gray-500 border-gray-400 flex items-center gap-1 disabled:opacity-50", disabled: true, title: "Connecting to backend...", children: [jsxRuntime.jsx(react$1.ClockClockwiseIcon, { size: 16, className: "animate-spin" }), jsxRuntime.jsx("span", { className: "font-medium ml-1", children: "Connecting..." })] }));
6441
6459
  }
6442
- return (jsxRuntime.jsxs("button", { className: "border rounded px-2 py-1.5 text-green-700 border-green-600 flex items-center gap-1 disabled:text-gray-400 disabled:border-gray-300 disabled:opacity-50", onClick: (evt) => {
6460
+ if (isGraphRunning) {
6461
+ return (jsxRuntime.jsxs("button", { className: "border rounded px-2 py-1.5 text-white border-none bg-green-500 flex items-center gap-1 cursor-default pointer-events-none", title: "Running", children: [jsxRuntime.jsx(react$1.RocketLaunchIcon, { size: 16, weight: "fill" }), jsxRuntime.jsx("span", { className: "font-medium ml-1", children: "Running" })] }));
6462
+ }
6463
+ return (jsxRuntime.jsxs("button", { className: "border rounded px-2 py-1.5 text-red-700 border-red-600 flex items-center gap-1 disabled:text-gray-400 disabled:border-gray-300 disabled:opacity-50", onClick: (evt) => {
6443
6464
  if (evt.shiftKey && !confirm("Invalidate and re-run graph?"))
6444
6465
  return;
6445
6466
  try {
@@ -6454,7 +6475,7 @@ function WorkbenchStudioCanvas({ autoScroll, onAutoScrollChange, example, onExam
6454
6475
  }
6455
6476
  }, disabled: !canControl, title: !canControl
6456
6477
  ? "Waiting for connection"
6457
- : `Start ${runMode === "manual" ? "manual" : "auto"} mode`, children: [jsxRuntime.jsx(react$1.PlayIcon, { size: 16, weight: "fill" }), jsxRuntime.jsx("span", { className: "font-medium ml-1", children: "Start" })] }));
6478
+ : `Start ${runMode === "manual" ? "manual" : "auto"} mode`, children: [jsxRuntime.jsx(react$1.RocketIcon, { size: 16, weight: "fill" }), jsxRuntime.jsx("span", { className: "font-medium ml-1", children: "Start" })] }));
6458
6479
  }, [transportStatus, isGraphRunning, runner, runMode, wb, backendKind]);
6459
6480
  const defaultExamples = React.useMemo(() => [
6460
6481
  {
@@ -6498,10 +6519,6 @@ function WorkbenchStudioCanvas({ autoScroll, onAutoScrollChange, example, onExam
6498
6519
  const canvasRef = React.useRef(null);
6499
6520
  const canvasContainerRef = React.useRef(null);
6500
6521
  const uploadInputRef = React.useRef(null);
6501
- const [registryReady, setRegistryReady] = React.useState(() => {
6502
- // For local backends, registry is always ready
6503
- return backendKind === "local";
6504
- });
6505
6522
  // Expose init callback with setInitialGraph helper
6506
6523
  // Note: This runs whenever runner changes
6507
6524
  React.useEffect(() => {
@@ -6621,21 +6638,6 @@ function WorkbenchStudioCanvas({ autoScroll, onAutoScrollChange, example, onExam
6621
6638
  const off = runner.on("transport", setTransportStatus);
6622
6639
  return () => off();
6623
6640
  }, [runner]);
6624
- // Track registry readiness for remote backends
6625
- React.useEffect(() => {
6626
- // For local backends, registry is always ready
6627
- if (backendKind === "local") {
6628
- setRegistryReady(true);
6629
- return;
6630
- }
6631
- // Reset readiness when switching to remote backend
6632
- setRegistryReady(false);
6633
- // For remote backends, wait for registry event
6634
- const off = runner.on("registry", () => {
6635
- setRegistryReady(true);
6636
- });
6637
- return () => off();
6638
- }, [runner, backendKind]);
6639
6641
  React.useEffect(() => {
6640
6642
  if (isGraphRunning)
6641
6643
  return;
@@ -6833,56 +6835,45 @@ function WorkbenchStudioCanvas({ autoScroll, onAutoScrollChange, example, onExam
6833
6835
  } }) }), jsxRuntime.jsx(Inspector, { setInput: setInput, debug: debug, autoScroll: autoScroll, hideWorkbench: hideWorkbench, onAutoScrollChange: onAutoScrollChange, onHideWorkbenchChange: onHideWorkbenchChange, toString: toString, contextPanel: overrides?.contextPanel })] })] }));
6834
6836
  }
6835
6837
  function WorkbenchStudio({ example, onExampleChange, backendKind, onBackendKindChange, httpBaseUrl, onHttpBaseUrlChange, wsUrl, onWsUrlChange, debug, onDebugChange, showValues, onShowValuesChange, hideWorkbench, onHideWorkbenchChange, autoScroll, onAutoScrollChange, backendOptions, overrides, onInit, onChange, }) {
6836
- const [registry, setRegistry] = React.useState(sparkGraph.createSimpleGraphRegistry());
6837
6838
  const [wb] = React.useState(() => new InMemoryWorkbench({ ui: new DefaultUIExtensionRegistry() }));
6838
- // Store previous runner for cleanup
6839
- const prevRunnerRef = React.useRef(null);
6839
+ const backendKindToUse = React.useMemo(() => {
6840
+ if (!backendOptions)
6841
+ return "local";
6842
+ return backendKind;
6843
+ }, [backendOptions, backendKind]);
6840
6844
  const runner = React.useMemo(() => {
6841
6845
  let newRunner;
6842
- if (backendKind === "remote-http") {
6846
+ if (backendKindToUse === "remote-http" && backendOptions) {
6843
6847
  const backend = {
6844
6848
  kind: "remote-http",
6845
6849
  baseUrl: httpBaseUrl,
6846
6850
  connectOptions: backendOptions?.connectOptions,
6847
6851
  onCustomEvent: backendOptions?.onCustomEvent,
6848
6852
  };
6849
- newRunner = new RemoteGraphRunner(registry, backend);
6853
+ newRunner = new RemoteGraphRunner(backend);
6850
6854
  }
6851
- else if (backendKind === "remote-ws") {
6855
+ else if (backendKindToUse === "remote-ws" && backendOptions) {
6852
6856
  const backend = {
6853
6857
  kind: "remote-ws",
6854
6858
  url: wsUrl,
6855
6859
  connectOptions: backendOptions?.connectOptions,
6856
6860
  onCustomEvent: backendOptions?.onCustomEvent,
6857
6861
  };
6858
- newRunner = new RemoteGraphRunner(registry, backend);
6862
+ newRunner = new RemoteGraphRunner(backend);
6859
6863
  }
6860
6864
  else {
6861
- newRunner = new LocalGraphRunner(registry);
6865
+ newRunner = new LocalGraphRunner();
6862
6866
  }
6863
6867
  return newRunner;
6864
- }, [registry, backendKind, httpBaseUrl, wsUrl, backendOptions]);
6865
- // Dispose previous runner after commit; dispose current on unmount
6868
+ }, [backendKindToUse, httpBaseUrl, wsUrl, backendOptions]);
6869
+ // Dispose runner when it changes or component unmounts
6866
6870
  React.useEffect(() => {
6867
- const previous = prevRunnerRef.current;
6868
- prevRunnerRef.current = runner;
6869
- if (previous && previous !== runner) {
6871
+ return () => {
6870
6872
  try {
6871
- previous.dispose();
6873
+ runner.dispose();
6872
6874
  }
6873
6875
  catch (err) {
6874
- console.warn("Error disposing previous runner:", err);
6875
- }
6876
- }
6877
- return () => {
6878
- // Only dispose if this runner is still the current one
6879
- if (prevRunnerRef.current === runner) {
6880
- try {
6881
- runner.dispose();
6882
- }
6883
- catch (err) {
6884
- console.warn("Error disposing runner on unmount:", err);
6885
- }
6876
+ console.warn("Error disposing runner:", err);
6886
6877
  }
6887
6878
  };
6888
6879
  }, [runner]);
@@ -6902,7 +6893,7 @@ function WorkbenchStudio({ example, onExampleChange, backendKind, onBackendKindC
6902
6893
  runner.dispose();
6903
6894
  onBackendKindChange(v);
6904
6895
  }, [isGraphRunning]);
6905
- 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, 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 }) }));
6896
+ return (jsxRuntime.jsx(WorkbenchProvider, { wb: wb, runner: runner, overrides: overrides, uiVersion: uiVersion, children: jsxRuntime.jsx(WorkbenchStudioCanvas, { autoScroll: autoScroll, onAutoScrollChange: onAutoScrollChange, example: example, onExampleChange: onExampleChange, backendKind: backendKindToUse, 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 }) }));
6906
6897
  }
6907
6898
 
6908
6899
  exports.AbstractWorkbench = AbstractWorkbench;
@@ -6918,6 +6909,7 @@ exports.LocalGraphRunner = LocalGraphRunner;
6918
6909
  exports.NodeHandles = NodeHandles;
6919
6910
  exports.RemoteGraphRunner = RemoteGraphRunner;
6920
6911
  exports.WorkbenchCanvas = WorkbenchCanvas;
6912
+ exports.WorkbenchCanvasComponent = WorkbenchCanvasComponent;
6921
6913
  exports.WorkbenchContext = WorkbenchContext;
6922
6914
  exports.WorkbenchProvider = WorkbenchProvider;
6923
6915
  exports.WorkbenchStudio = WorkbenchStudio;