@bian-womp/spark-workbench 0.2.21 → 0.2.22

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
@@ -1420,7 +1420,7 @@ function useWorkbenchContext() {
1420
1420
  return ctx;
1421
1421
  }
1422
1422
 
1423
- function WorkbenchProvider({ wb, runner, registry, setRegistry, children, }) {
1423
+ function WorkbenchProvider({ wb, runner, registry, setRegistry, overrides, children, }) {
1424
1424
  const [nodeStatus, setNodeStatus] = React.useState({});
1425
1425
  const [edgeStatus, setEdgeStatus] = React.useState({});
1426
1426
  const [events, setEvents] = React.useState([]);
@@ -1551,8 +1551,14 @@ function WorkbenchProvider({ wb, runner, registry, setRegistry, children, }) {
1551
1551
  if (!node)
1552
1552
  continue;
1553
1553
  // Prefer showValues sizing similar to node rendering
1554
- // Lazy import to avoid circular deps at module top
1555
- const size = estimateNodeSize({ node, registry, showValues: true });
1554
+ // Consider per-type overrides when available via UI
1555
+ const overrideSize = overrides?.getDefaultNodeSize?.(node.typeId) ?? undefined;
1556
+ const size = estimateNodeSize({
1557
+ node,
1558
+ registry,
1559
+ showValues: true,
1560
+ overrides: overrideSize,
1561
+ });
1556
1562
  heights[id] = size.height;
1557
1563
  if (size.width > maxWidth)
1558
1564
  maxWidth = size.width;
@@ -1567,7 +1573,7 @@ function WorkbenchProvider({ wb, runner, registry, setRegistry, children, }) {
1567
1573
  curX += maxWidth + H_GAP;
1568
1574
  }
1569
1575
  wb.setPositions(pos);
1570
- }, [wb]);
1576
+ }, [wb, registry, overrides?.getDefaultNodeSize]);
1571
1577
  const updateEdgeType = React.useCallback((edgeId, typeId) => wb.updateEdgeType(edgeId, typeId), [wb]);
1572
1578
  const triggerExternal = React.useCallback((nodeId, event) => runner.triggerExternal(nodeId, event), [runner]);
1573
1579
  // Subscribe to runner/workbench events
@@ -2262,6 +2268,18 @@ function DefaultNodeHeader({ id, title, validation, right, showId, onInvalidate,
2262
2268
  }
2263
2269
  function DefaultNodeContent({ data, isConnectable, }) {
2264
2270
  const { showValues, inputValues, outputValues, toString } = data;
2271
+ const prettyHandle = React.useCallback((id) => {
2272
+ try {
2273
+ const parts = String(id).split(":");
2274
+ // If there are exactly 3 colons (4 parts), display only the second part
2275
+ if (parts.length === 4)
2276
+ return parts[1] || id;
2277
+ return id;
2278
+ }
2279
+ catch {
2280
+ return id;
2281
+ }
2282
+ }, []);
2265
2283
  const inputEntries = data.inputHandles ?? [];
2266
2284
  const outputEntries = data.outputHandles ?? [];
2267
2285
  const status = data.status ?? { activeRuns: 0 };
@@ -2297,7 +2315,7 @@ function DefaultNodeContent({ data, isConnectable, }) {
2297
2315
  const txt = toString(resolved.typeId, resolved.value);
2298
2316
  return typeof txt === "string" ? txt : String(txt);
2299
2317
  })();
2300
- return (jsxRuntime.jsxs("span", { className: "flex items-center gap-1 w-full", children: [kind === "output" ? (jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [valueText !== undefined ? (jsxRuntime.jsx("span", { className: "opacity-60 truncate pl-1", style: { flex: 1, minWidth: 0, maxWidth: "100%" }, children: valueText })) : (jsxRuntime.jsx("span", { style: { flex: 1, minWidth: 0, maxWidth: "100%" } })), jsxRuntime.jsx("span", { className: "truncate shrink-0", style: valueText !== undefined ? { maxWidth: "40%" } : {}, children: handleId })] })) : (jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [jsxRuntime.jsx("span", { className: "truncate shrink-0", style: valueText !== undefined ? { maxWidth: "40%" } : {}, children: handleId }), valueText !== undefined && (jsxRuntime.jsx("span", { className: "opacity-60 truncate pr-1", style: { flex: 1, minWidth: 0, maxWidth: "100%" }, children: valueText }))] })), hasAny && (jsxRuntime.jsx(IssueBadge, { level: hasErr ? "error" : "warning", size: 12, className: "shrink-0", title: title }))] }));
2318
+ return (jsxRuntime.jsxs("span", { className: "flex items-center gap-1 w-full", children: [kind === "output" ? (jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [valueText !== undefined ? (jsxRuntime.jsx("span", { className: "opacity-60 truncate pl-1", style: { flex: 1, minWidth: 0, maxWidth: "100%" }, children: valueText })) : (jsxRuntime.jsx("span", { style: { flex: 1, minWidth: 0, maxWidth: "100%" } })), jsxRuntime.jsx("span", { className: "truncate shrink-0", style: valueText !== undefined ? { maxWidth: "40%" } : {}, children: prettyHandle(handleId) })] })) : (jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [jsxRuntime.jsx("span", { className: "truncate shrink-0", style: valueText !== undefined ? { maxWidth: "40%" } : {}, children: prettyHandle(handleId) }), valueText !== undefined && (jsxRuntime.jsx("span", { className: "opacity-60 truncate pr-1", style: { flex: 1, minWidth: 0, maxWidth: "100%" }, children: valueText }))] })), hasAny && (jsxRuntime.jsx(IssueBadge, { level: hasErr ? "error" : "warning", size: 12, className: "shrink-0", title: title }))] }));
2301
2319
  } })] }));
2302
2320
  }
2303
2321
 
@@ -2887,6 +2905,7 @@ function WorkbenchStudioCanvas({ setRegistry, autoScroll, onAutoScrollChange, ex
2887
2905
  return overrides.getExamples(defaultExamples);
2888
2906
  return defaultExamples;
2889
2907
  }, [overrides, defaultExamples]);
2908
+ const [hydrated, setHydrated] = React.useState(false);
2890
2909
  const lastAutoLaunched = React.useRef(undefined);
2891
2910
  const autoLayoutRan = React.useRef(false);
2892
2911
  const canvasRef = React.useRef(null);
@@ -2910,7 +2929,6 @@ function WorkbenchStudioCanvas({ setRegistry, autoScroll, onAutoScrollChange, ex
2910
2929
  runner.setInputs(nodeId, map);
2911
2930
  }
2912
2931
  }
2913
- runAutoLayout();
2914
2932
  };
2915
2933
  onInit({ wb, runner, setInitialGraph });
2916
2934
  }, [onInit, wb, runner, runAutoLayout, registry, setRegistry]);
@@ -3098,7 +3116,7 @@ function WorkbenchStudioCanvas({ setRegistry, autoScroll, onAutoScrollChange, ex
3098
3116
  createRuntime: () => ({
3099
3117
  async onInputsChanged() { },
3100
3118
  }),
3101
- policy: { mode: "push", asyncConcurrency: "switch" },
3119
+ policy: { asyncConcurrency: "switch" },
3102
3120
  };
3103
3121
  r.categories.register(category);
3104
3122
  }
@@ -3167,23 +3185,32 @@ function WorkbenchStudioCanvas({ setRegistry, autoScroll, onAutoScrollChange, ex
3167
3185
  }, [engine, runner, wb, backendKind]);
3168
3186
  // When switching to remote backend, auto-hydrate registry from backend
3169
3187
  React.useEffect(() => {
3188
+ let hydrate;
3170
3189
  if (backendKind === "remote-http" && httpBaseUrl) {
3171
- hydrateFromBackend("remote-http", httpBaseUrl);
3190
+ hydrate = hydrateFromBackend("remote-http", httpBaseUrl);
3172
3191
  }
3173
3192
  else if (backendKind === "remote-ws" && wsUrl) {
3174
- hydrateFromBackend("remote-ws", wsUrl);
3193
+ hydrate = hydrateFromBackend("remote-ws", wsUrl);
3175
3194
  }
3176
- }, [backendKind, httpBaseUrl, wsUrl, hydrateFromBackend]);
3195
+ if (hydrate) {
3196
+ hydrate.then(() => {
3197
+ setHydrated(true);
3198
+ });
3199
+ }
3200
+ }, [backendKind, httpBaseUrl, wsUrl, hydrateFromBackend, setHydrated]);
3177
3201
  React.useEffect(() => {
3178
3202
  if (autoLayoutRan.current)
3179
3203
  return;
3204
+ if (backendKind !== "local" && !hydrated)
3205
+ return;
3180
3206
  const cur = wb.export();
3181
- const allMissing = cur.nodes.every((n) => !wb.getPositions()[n.nodeId]);
3207
+ const positions = wb.getPositions();
3208
+ const allMissing = cur.nodes.every((n) => !positions[n.nodeId]);
3182
3209
  if (allMissing) {
3183
3210
  autoLayoutRan.current = true;
3184
3211
  runAutoLayout();
3185
3212
  }
3186
- }, [wb, runAutoLayout]);
3213
+ }, [wb, runAutoLayout, backendKind, hydrated]);
3187
3214
  const baseSetInput = React.useCallback((handle, raw) => {
3188
3215
  if (!selectedNodeId)
3189
3216
  return;
@@ -3409,7 +3436,7 @@ function WorkbenchStudio({ engine, onEngineChange, example, onExampleChange, bac
3409
3436
  overrides?.registerUI?.(baseRegisterUI, { wb, wbRunner: runner });
3410
3437
  // eslint-disable-next-line react-hooks/exhaustive-deps
3411
3438
  }, [wb, runner, overrides]);
3412
- return (jsxRuntime.jsx(WorkbenchProvider, { wb: wb, runner: runner, registry: registry, setRegistry: setRegistry, children: jsxRuntime.jsx(WorkbenchStudioCanvas, { setRegistry: setRegistry, autoScroll: autoScroll, onAutoScrollChange: onAutoScrollChange, example: example, onExampleChange: onExampleChange, engine: engine, onEngineChange: onEngineChange, backendKind: backendKind, onBackendKindChange: (v) => {
3439
+ return (jsxRuntime.jsx(WorkbenchProvider, { wb: wb, runner: runner, registry: registry, setRegistry: setRegistry, overrides: overrides, children: jsxRuntime.jsx(WorkbenchStudioCanvas, { setRegistry: setRegistry, autoScroll: autoScroll, onAutoScrollChange: onAutoScrollChange, example: example, onExampleChange: onExampleChange, engine: engine, onEngineChange: onEngineChange, backendKind: backendKind, onBackendKindChange: (v) => {
3413
3440
  if (runner.isRunning())
3414
3441
  runner.dispose();
3415
3442
  onBackendKindChange(v);