@bian-womp/spark-workbench 0.2.71 → 0.2.73

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 CHANGED
@@ -381,6 +381,7 @@ class InMemoryWorkbench extends AbstractWorkbench {
381
381
  }
382
382
  setHistory(history) {
383
383
  this.historyState = history;
384
+ this.emit("historyChanged", { history });
384
385
  }
385
386
  getNodeRuntimeMetadata(nodeId) {
386
387
  return this.runtimeState?.nodes[nodeId];
@@ -2714,8 +2715,8 @@ function WorkbenchProvider({ wb, runner, registry, setRegistry, overrides, uiVer
2714
2715
  }, [wb, registry, overrides?.getDefaultNodeSize]);
2715
2716
  const updateEdgeType = React.useCallback((edgeId, typeId) => wb.updateEdgeType(edgeId, typeId), [wb]);
2716
2717
  const triggerExternal = React.useCallback((nodeId, event) => runner.triggerExternal(nodeId, event), [runner]);
2717
- // Helper to save runtime metadata to extData.runtime and workbench state
2718
- const saveRuntimeMetadata = React.useCallback(async () => {
2718
+ // Helper to save runtime metadata and UI state to extData
2719
+ const saveUiRuntimeMetadata = React.useCallback(async () => {
2719
2720
  try {
2720
2721
  const current = wb.getRuntimeState() ?? { nodes: {} };
2721
2722
  const metadata = { nodes: { ...current.nodes } };
@@ -2728,8 +2729,13 @@ function WorkbenchProvider({ wb, runner, registry, setRegistry, overrides, uiVer
2728
2729
  }
2729
2730
  // Save cleaned metadata to workbench state
2730
2731
  wb.setRuntimeState(metadata);
2731
- // Save to extData.runtime via runner (no snapshotFull)
2732
- await runner.setExtData?.({ runtime: metadata });
2732
+ // Get UI state
2733
+ const uiState = wb.getUIState();
2734
+ // Save both runtime and UI state to extData (merge to preserve both)
2735
+ await runner.setExtData?.({
2736
+ ...(uiState ? { ui: uiState } : {}),
2737
+ runtime: metadata,
2738
+ });
2733
2739
  }
2734
2740
  catch (err) {
2735
2741
  console.warn("[WorkbenchContext] Failed to save runtime metadata:", err);
@@ -3093,7 +3099,7 @@ function WorkbenchProvider({ wb, runner, registry, setRegistry, overrides, uiVer
3093
3099
  }
3094
3100
  if (!runner.isRunning()) {
3095
3101
  if (event.commit) {
3096
- await saveRuntimeMetadata();
3102
+ await saveUiRuntimeMetadata();
3097
3103
  const history = await runner.commit(reason).catch((err) => {
3098
3104
  console.error("[WorkbenchContext] Error committing:", err);
3099
3105
  return undefined;
@@ -3127,7 +3133,7 @@ function WorkbenchProvider({ wb, runner, registry, setRegistry, overrides, uiVer
3127
3133
  await runner.update(event.def, { dry: event.dry });
3128
3134
  }
3129
3135
  if (event.commit) {
3130
- await saveRuntimeMetadata();
3136
+ await saveUiRuntimeMetadata();
3131
3137
  const history = await runner
3132
3138
  .commit(event.reason ?? reason)
3133
3139
  .catch((err) => {
@@ -3148,7 +3154,7 @@ function WorkbenchProvider({ wb, runner, registry, setRegistry, overrides, uiVer
3148
3154
  setSelectedNodeId(sel.nodes?.[0]);
3149
3155
  setSelectedEdgeId(sel.edges?.[0]);
3150
3156
  if (sel.commit) {
3151
- await saveRuntimeMetadata();
3157
+ await saveUiRuntimeMetadata();
3152
3158
  const history = await runner
3153
3159
  .commit(sel.reason ?? "selection")
3154
3160
  .catch((err) => {
@@ -3180,7 +3186,7 @@ function WorkbenchProvider({ wb, runner, registry, setRegistry, overrides, uiVer
3180
3186
  reason = "viewport";
3181
3187
  }
3182
3188
  }
3183
- await saveRuntimeMetadata();
3189
+ await saveUiRuntimeMetadata();
3184
3190
  const history = await runner
3185
3191
  .commit(event.reason ?? reason)
3186
3192
  .catch((err) => {
@@ -4383,6 +4389,7 @@ const WorkbenchCanvas = React.forwardRef(({ showValues, toString, toElement, get
4383
4389
  const nodeValidation = validationByNode;
4384
4390
  const edgeValidation = validationByEdge.errors;
4385
4391
  const [registryVersion, setRegistryVersion] = React.useState(0);
4392
+ const [historyState, setHistoryState] = React.useState(wb.getHistory());
4386
4393
  const prevNodesRef = React.useRef([]);
4387
4394
  const prevEdgesRef = React.useRef([]);
4388
4395
  function retainStabilityById(prev, next, isSame) {
@@ -4728,6 +4735,12 @@ const WorkbenchCanvas = React.forwardRef(({ showValues, toString, toElement, get
4728
4735
  });
4729
4736
  return () => off();
4730
4737
  }, [runner]);
4738
+ React.useEffect(() => {
4739
+ const off = wb.on("historyChanged", (event) => {
4740
+ setHistoryState(event.history);
4741
+ });
4742
+ return () => off();
4743
+ }, [wb]);
4731
4744
  const nodeIds = React.useMemo(() => Array.from(registry.nodes.keys()), [registry, registryVersion]);
4732
4745
  const defaultContextMenuHandlers = React.useMemo(() => {
4733
4746
  // Get storage from override or use workbench's internal storage
@@ -4743,12 +4756,12 @@ const WorkbenchCanvas = React.forwardRef(({ showValues, toString, toElement, get
4743
4756
  return;
4744
4757
  wb.pasteCopiedData(data, position, { commit: true, reason: "paste" });
4745
4758
  onCloseMenu();
4746
- }, runner, () => storage.get(), () => storage.set(null), wb.getHistory());
4759
+ }, runner, () => storage.get(), () => storage.set(null), historyState);
4747
4760
  if (overrides?.getDefaultContextMenuHandlers) {
4748
4761
  return overrides.getDefaultContextMenuHandlers(wb, baseHandlers);
4749
4762
  }
4750
4763
  return baseHandlers;
4751
- }, [addNodeAt, onCloseMenu, overrides, wb, runner]);
4764
+ }, [addNodeAt, onCloseMenu, overrides, wb, runner, historyState]);
4752
4765
  const selectionContextMenuHandlers = React.useMemo(() => {
4753
4766
  // Get storage from override or use workbench's internal storage
4754
4767
  const storage = overrides?.getCopiedDataStorage