@bian-womp/spark-workbench 0.1.22 → 0.1.23

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
@@ -873,7 +873,7 @@ function preformatValueForDisplay(typeId, value, registry) {
873
873
  return preformatValueForDisplay(sparkGraph.getTypedOutputTypeId(value), sparkGraph.getTypedOutputValue(value), registry);
874
874
  }
875
875
  // Enums
876
- if (typeId && typeId.includes("enum:") && registry) {
876
+ if (typeId && typeId.startsWith("enum:") && registry) {
877
877
  const n = Number(value);
878
878
  const label = registry.enums.get(typeId)?.valueToLabel.get(n);
879
879
  if (label)
@@ -1640,7 +1640,7 @@ function Inspector({ debug, autoScroll, hideWorkbench, onAutoScrollChange, onHid
1640
1640
  const orig = originals[h] ?? safeToString(typeId, current);
1641
1641
  setDrafts((d) => ({ ...d, [h]: orig }));
1642
1642
  };
1643
- const isEnum = typeId?.includes("enum:");
1643
+ const isEnum = typeId?.startsWith("enum:");
1644
1644
  const inIssues = selectedNodeHandleValidation.inputs.filter((m) => m.handle === h);
1645
1645
  const hasValidation = inIssues.length > 0;
1646
1646
  const hasErr = inIssues.some((m) => m.level === "error");
@@ -1756,16 +1756,18 @@ function DefaultContextMenu({ open, clientPos, onAdd, onClose, }) {
1756
1756
  const { registry } = useWorkbenchContext();
1757
1757
  const rf = ReactFlow.useReactFlow();
1758
1758
  const ids = Array.from(registry.nodes.keys());
1759
- // Group node ids by the segment before the first '.'
1760
- const grouped = {};
1759
+ const root = { __children: {} };
1761
1760
  for (const id of ids) {
1762
1761
  const parts = id.split(".");
1763
- const cat = parts.length > 1 ? parts[0] : "other";
1764
- const label = parts.length > 1 ? parts.slice(1).join(".") : id;
1765
- (grouped[cat] = grouped[cat] || []).push({ id, label });
1762
+ let node = root;
1763
+ for (let i = 0; i < parts.length; i++) {
1764
+ const key = parts[i];
1765
+ node.__children[key] = node.__children[key] || { __children: {} };
1766
+ node = node.__children[key];
1767
+ if (i === parts.length - 1)
1768
+ node.__self = id;
1769
+ }
1766
1770
  }
1767
- const cats = Object.keys(grouped).sort((a, b) => a.localeCompare(b));
1768
- cats.forEach((c) => grouped[c].sort((a, b) => a.label.localeCompare(b.label)));
1769
1771
  const totalCount = ids.length;
1770
1772
  // Ref for focus/outside click handling
1771
1773
  const ref = React.useRef(null);
@@ -1809,10 +1811,19 @@ function DefaultContextMenu({ open, clientPos, onAdd, onClose, }) {
1809
1811
  onAdd(typeId, p);
1810
1812
  onClose();
1811
1813
  };
1814
+ const renderTree = (tree, path = []) => {
1815
+ const entries = Object.entries(tree.__children).sort((a, b) => a[0].localeCompare(b[0]));
1816
+ return (jsxRuntime.jsx("div", { children: entries.map(([key, child]) => {
1817
+ const label = key;
1818
+ const hasChildren = Object.keys(child.__children).length > 0;
1819
+ !!child.__self && !hasChildren;
1820
+ return (jsxRuntime.jsxs("div", { children: [jsxRuntime.jsx("div", { className: "px-2 py-1 text-[11px] uppercase tracking-wide text-gray-400", children: label }), child.__self && (jsxRuntime.jsx("button", { onClick: () => handleClick(child.__self), className: "block w-full text-left px-3 py-1 hover:bg-gray-100 cursor-pointer", title: child.__self, children: child.__self.split(".").slice(-1)[0] })), hasChildren && (jsxRuntime.jsx("div", { className: "pl-2 border-l border-gray-200 ml-2", children: renderTree(child, [...path, key]) }))] }, [...path, key].join(".")));
1821
+ }) }));
1822
+ };
1812
1823
  return (jsxRuntime.jsxs("div", { ref: ref, tabIndex: -1, className: "fixed z-[1000] bg-white border border-gray-300 rounded-none shadow-lg p-1 min-w-[180px] text-sm text-gray-700", style: { left: x, top: y }, onClick: (e) => e.stopPropagation(), onMouseDown: (e) => e.stopPropagation(), onWheel: (e) => e.stopPropagation(), onContextMenu: (e) => {
1813
1824
  e.preventDefault();
1814
1825
  e.stopPropagation();
1815
- }, children: [jsxRuntime.jsxs("div", { className: "px-2 py-1 font-semibold text-gray-700", children: ["Add Node ", jsxRuntime.jsxs("span", { className: "text-gray-500 font-normal", children: ["(", totalCount, ")"] })] }), jsxRuntime.jsx("div", { className: "max-h-60 overflow-auto", children: cats.map((cat) => (jsxRuntime.jsxs("div", { className: "py-1", children: [jsxRuntime.jsxs("div", { className: "px-2 py-1 text-[11px] uppercase tracking-wide text-gray-400", children: [cat, " ", jsxRuntime.jsxs("span", { className: "opacity-60 normal-case", children: ["(", grouped[cat].length, ")"] })] }), grouped[cat].map(({ id, label }) => (jsxRuntime.jsx("button", { onClick: () => handleClick(id), className: "block w-full text-left px-3 py-1 hover:bg-gray-100 cursor-pointer", title: id, children: label }, id)))] }, cat))) })] }));
1826
+ }, children: [jsxRuntime.jsxs("div", { className: "px-2 py-1 font-semibold text-gray-700", children: ["Add Node ", jsxRuntime.jsxs("span", { className: "text-gray-500 font-normal", children: ["(", totalCount, ")"] })] }), jsxRuntime.jsx("div", { className: "max-h-60 overflow-auto", children: renderTree(root) })] }));
1816
1827
  }
1817
1828
 
1818
1829
  function NodeContextMenu({ open, clientPos, nodeId, onClose, }) {
@@ -2347,7 +2358,7 @@ function WorkbenchStudioCanvas({ setRegistry, autoScroll, onAutoScrollChange, ex
2347
2358
  // value.ts handles data URL formatting
2348
2359
  return title || url.slice(0, 32) + (url.length > 32 ? "…" : "");
2349
2360
  }
2350
- if (typeId && typeId.includes("enum:")) {
2361
+ if (typeId && typeId.startsWith("enum:")) {
2351
2362
  const n = Number(value);
2352
2363
  const label = registry.enums.get(typeId)?.valueToLabel.get(n);
2353
2364
  return label ?? String(n);