@bian-womp/spark-workbench 0.2.17 → 0.2.19
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 +155 -84
- package/lib/cjs/index.cjs.map +1 -1
- package/lib/cjs/src/core/contracts.d.ts +2 -4
- package/lib/cjs/src/core/contracts.d.ts.map +1 -1
- package/lib/cjs/src/misc/Inspector.d.ts.map +1 -1
- package/lib/cjs/src/misc/context/WorkbenchContext.d.ts +5 -5
- package/lib/cjs/src/misc/context/WorkbenchContext.d.ts.map +1 -1
- package/lib/cjs/src/misc/context/WorkbenchContext.provider.d.ts.map +1 -1
- package/lib/cjs/src/misc/layout.d.ts +53 -0
- package/lib/cjs/src/misc/layout.d.ts.map +1 -0
- package/lib/cjs/src/misc/mapping.d.ts +6 -6
- package/lib/cjs/src/misc/mapping.d.ts.map +1 -1
- package/lib/esm/index.js +155 -84
- package/lib/esm/index.js.map +1 -1
- package/lib/esm/src/core/contracts.d.ts +2 -4
- package/lib/esm/src/core/contracts.d.ts.map +1 -1
- package/lib/esm/src/misc/Inspector.d.ts.map +1 -1
- package/lib/esm/src/misc/context/WorkbenchContext.d.ts +5 -5
- package/lib/esm/src/misc/context/WorkbenchContext.d.ts.map +1 -1
- package/lib/esm/src/misc/context/WorkbenchContext.provider.d.ts.map +1 -1
- package/lib/esm/src/misc/layout.d.ts +53 -0
- package/lib/esm/src/misc/layout.d.ts.map +1 -0
- package/lib/esm/src/misc/mapping.d.ts +6 -6
- package/lib/esm/src/misc/mapping.d.ts.map +1 -1
- package/package.json +4 -4
package/lib/cjs/index.cjs
CHANGED
|
@@ -1183,6 +1183,83 @@ function summarizeDeep(value) {
|
|
|
1183
1183
|
const NODE_HEADER_HEIGHT_PX = 24;
|
|
1184
1184
|
const NODE_ROW_HEIGHT_PX = 22;
|
|
1185
1185
|
|
|
1186
|
+
function computeEffectiveHandles(node, registry) {
|
|
1187
|
+
const desc = registry.nodes.get(node.typeId);
|
|
1188
|
+
const resolved = node.resolvedHandles || {};
|
|
1189
|
+
const inputs = { ...desc?.inputs, ...resolved.inputs };
|
|
1190
|
+
const outputs = { ...desc?.outputs, ...resolved.outputs };
|
|
1191
|
+
const inputDefaults = { ...desc?.inputDefaults, ...resolved.inputDefaults };
|
|
1192
|
+
return { inputs, outputs, inputDefaults };
|
|
1193
|
+
}
|
|
1194
|
+
function countVisibleHandles(handles) {
|
|
1195
|
+
const inputIds = Object.keys(handles.inputs).filter((k) => !sparkGraph.isInputPrivate(handles.inputs, k));
|
|
1196
|
+
const outputIds = Object.keys(handles.outputs);
|
|
1197
|
+
return { inputsCount: inputIds.length, outputsCount: outputIds.length };
|
|
1198
|
+
}
|
|
1199
|
+
function estimateNodeSize(args) {
|
|
1200
|
+
const { node, registry, showValues, overrides } = args;
|
|
1201
|
+
const { inputs, outputs } = computeEffectiveHandles(node, registry);
|
|
1202
|
+
// Count only non-private inputs for rows on left
|
|
1203
|
+
const { inputsCount, outputsCount } = countVisibleHandles({
|
|
1204
|
+
inputs,
|
|
1205
|
+
outputs,
|
|
1206
|
+
});
|
|
1207
|
+
const rows = Math.max(inputsCount, outputsCount);
|
|
1208
|
+
const baseWidth = showValues ? 320 : 240;
|
|
1209
|
+
const width = overrides?.width ?? baseWidth;
|
|
1210
|
+
const height = overrides?.height ?? NODE_HEADER_HEIGHT_PX + rows * NODE_ROW_HEIGHT_PX;
|
|
1211
|
+
return { width, height, inputsCount, outputsCount, rowCount: rows };
|
|
1212
|
+
}
|
|
1213
|
+
function layoutNode(args) {
|
|
1214
|
+
const { node, registry, showValues, overrides } = args;
|
|
1215
|
+
const { inputs, outputs } = computeEffectiveHandles(node, registry);
|
|
1216
|
+
const inputOrder = Object.keys(inputs).filter((k) => !sparkGraph.isInputPrivate(inputs, k));
|
|
1217
|
+
const outputOrder = Object.keys(outputs);
|
|
1218
|
+
const { width, height } = estimateNodeSize({
|
|
1219
|
+
node,
|
|
1220
|
+
registry,
|
|
1221
|
+
showValues,
|
|
1222
|
+
overrides,
|
|
1223
|
+
});
|
|
1224
|
+
const HEADER = NODE_HEADER_HEIGHT_PX;
|
|
1225
|
+
const ROW = NODE_ROW_HEIGHT_PX;
|
|
1226
|
+
const handles = [
|
|
1227
|
+
...inputOrder.map((id, i) => ({
|
|
1228
|
+
id,
|
|
1229
|
+
type: "target",
|
|
1230
|
+
position: react.Position.Left,
|
|
1231
|
+
x: 0,
|
|
1232
|
+
y: HEADER + i * ROW,
|
|
1233
|
+
width: 1,
|
|
1234
|
+
height: ROW + 2,
|
|
1235
|
+
})),
|
|
1236
|
+
...outputOrder.map((id, i) => ({
|
|
1237
|
+
id,
|
|
1238
|
+
type: "source",
|
|
1239
|
+
position: react.Position.Right,
|
|
1240
|
+
x: width - 1,
|
|
1241
|
+
y: HEADER + i * ROW,
|
|
1242
|
+
width: 1,
|
|
1243
|
+
height: ROW + 2,
|
|
1244
|
+
})),
|
|
1245
|
+
];
|
|
1246
|
+
const handleLayout = [
|
|
1247
|
+
...inputOrder.map((id, i) => ({
|
|
1248
|
+
id,
|
|
1249
|
+
type: "target",
|
|
1250
|
+
position: react.Position.Left,
|
|
1251
|
+
y: HEADER + i * ROW + ROW / 2,
|
|
1252
|
+
})),
|
|
1253
|
+
...outputOrder.map((id, i) => ({
|
|
1254
|
+
id,
|
|
1255
|
+
type: "source",
|
|
1256
|
+
position: react.Position.Right,
|
|
1257
|
+
y: HEADER + i * ROW + ROW / 2,
|
|
1258
|
+
})),
|
|
1259
|
+
];
|
|
1260
|
+
return { width, height, inputOrder, outputOrder, handles, handleLayout };
|
|
1261
|
+
}
|
|
1262
|
+
|
|
1186
1263
|
function toReactFlow(def, positions, registry, opts) {
|
|
1187
1264
|
const EDGE_STYLE_ERROR = { stroke: "#ef4444", strokeWidth: 2 };
|
|
1188
1265
|
const EDGE_STYLE_RUNNING = { stroke: "#3b82f6" };
|
|
@@ -1197,54 +1274,31 @@ function toReactFlow(def, positions, registry, opts) {
|
|
|
1197
1274
|
connectedInputs[nid].add(hid);
|
|
1198
1275
|
}
|
|
1199
1276
|
const nodes = def.nodes.map((n) => {
|
|
1200
|
-
const
|
|
1201
|
-
|
|
1202
|
-
const
|
|
1203
|
-
|
|
1204
|
-
|
|
1205
|
-
|
|
1206
|
-
|
|
1207
|
-
|
|
1208
|
-
|
|
1209
|
-
|
|
1277
|
+
const { inputs: inputSource, outputs: outputSource } = computeEffectiveHandles(n, registry);
|
|
1278
|
+
const overrideSize = opts.getDefaultNodeSize?.(n.typeId);
|
|
1279
|
+
const geom = layoutNode({
|
|
1280
|
+
node: n,
|
|
1281
|
+
registry,
|
|
1282
|
+
showValues: opts.showValues,
|
|
1283
|
+
overrides: overrideSize,
|
|
1284
|
+
});
|
|
1285
|
+
const inputHandles = geom.inputOrder.map((id) => ({
|
|
1286
|
+
id,
|
|
1287
|
+
typeId: sparkGraph.getInputTypeId(inputSource, id),
|
|
1288
|
+
}));
|
|
1289
|
+
const outputHandles = geom.outputOrder.map((id) => ({
|
|
1210
1290
|
id,
|
|
1211
|
-
typeId: formatDeclaredTypeSignature(
|
|
1291
|
+
typeId: formatDeclaredTypeSignature(outputSource[id]),
|
|
1212
1292
|
}));
|
|
1213
1293
|
nodeHandleMap[n.nodeId] = {
|
|
1214
1294
|
inputs: new Set(inputHandles.map((h) => h.id)),
|
|
1215
1295
|
outputs: new Set(outputHandles.map((h) => h.id)),
|
|
1216
1296
|
};
|
|
1217
|
-
//
|
|
1218
|
-
const
|
|
1219
|
-
const
|
|
1220
|
-
const maxRows = Math.max(inputHandles.length, outputHandles.length);
|
|
1221
|
-
// Allow external override to dictate initial size
|
|
1222
|
-
const overrideSize = opts.getDefaultNodeSize?.(n.typeId);
|
|
1223
|
-
const initialWidth = overrideSize?.width ?? (opts.showValues ? 320 : 240);
|
|
1224
|
-
const initialHeight = overrideSize?.height ?? HEADER_SIZE + maxRows * ROW_SIZE;
|
|
1297
|
+
// Shared sizing
|
|
1298
|
+
const initialWidth = geom.width;
|
|
1299
|
+
const initialHeight = geom.height;
|
|
1225
1300
|
// Precompute handle bounds so edges can render immediately without waiting for measurement
|
|
1226
|
-
const handles =
|
|
1227
|
-
// Inputs on the left as targets
|
|
1228
|
-
...inputHandles.map((h, i) => ({
|
|
1229
|
-
id: h.id,
|
|
1230
|
-
type: "target",
|
|
1231
|
-
position: react.Position.Left,
|
|
1232
|
-
x: 0,
|
|
1233
|
-
y: HEADER_SIZE + i * ROW_SIZE,
|
|
1234
|
-
width: 1,
|
|
1235
|
-
height: ROW_SIZE + 2,
|
|
1236
|
-
})),
|
|
1237
|
-
// Outputs on the right as sources
|
|
1238
|
-
...outputHandles.map((h, i) => ({
|
|
1239
|
-
id: h.id,
|
|
1240
|
-
type: "source",
|
|
1241
|
-
position: react.Position.Right,
|
|
1242
|
-
x: initialWidth - 1,
|
|
1243
|
-
y: HEADER_SIZE + i * ROW_SIZE,
|
|
1244
|
-
width: 1,
|
|
1245
|
-
height: ROW_SIZE + 2,
|
|
1246
|
-
})),
|
|
1247
|
-
];
|
|
1301
|
+
const handles = geom.handles;
|
|
1248
1302
|
return {
|
|
1249
1303
|
id: n.nodeId,
|
|
1250
1304
|
data: {
|
|
@@ -1256,20 +1310,7 @@ function toReactFlow(def, positions, registry, opts) {
|
|
|
1256
1310
|
h.id,
|
|
1257
1311
|
!!connectedInputs[n.nodeId]?.has(h.id),
|
|
1258
1312
|
])),
|
|
1259
|
-
handleLayout:
|
|
1260
|
-
...inputHandles.map((h, i) => ({
|
|
1261
|
-
id: h.id,
|
|
1262
|
-
type: "target",
|
|
1263
|
-
position: react.Position.Left,
|
|
1264
|
-
y: HEADER_SIZE + i * ROW_SIZE + ROW_SIZE / 2,
|
|
1265
|
-
})),
|
|
1266
|
-
...outputHandles.map((h, i) => ({
|
|
1267
|
-
id: h.id,
|
|
1268
|
-
type: "source",
|
|
1269
|
-
position: react.Position.Right,
|
|
1270
|
-
y: HEADER_SIZE + i * ROW_SIZE + ROW_SIZE / 2,
|
|
1271
|
-
})),
|
|
1272
|
-
],
|
|
1313
|
+
handleLayout: geom.handleLayout,
|
|
1273
1314
|
showValues: opts.showValues,
|
|
1274
1315
|
renderWidth: initialWidth,
|
|
1275
1316
|
renderHeight: initialHeight,
|
|
@@ -1468,6 +1509,7 @@ function WorkbenchProvider({ wb, runner, registry, setRegistry, children, }) {
|
|
|
1468
1509
|
// Auto layout (simple layered layout)
|
|
1469
1510
|
const runAutoLayout = React.useCallback(() => {
|
|
1470
1511
|
const cur = wb.export();
|
|
1512
|
+
// Build DAG layers by indegree
|
|
1471
1513
|
const indegree = {};
|
|
1472
1514
|
const adj = {};
|
|
1473
1515
|
for (const n of cur.nodes) {
|
|
@@ -1494,14 +1536,36 @@ function WorkbenchProvider({ wb, runner, registry, setRegistry, children, }) {
|
|
|
1494
1536
|
layers.push(layer);
|
|
1495
1537
|
q.splice(0, q.length, ...next);
|
|
1496
1538
|
}
|
|
1497
|
-
|
|
1498
|
-
|
|
1539
|
+
// Size-aware placement: columns by layer, stacking nodes vertically in each column
|
|
1540
|
+
// Use the same sizing heuristic as mapping via estimateNodeSize
|
|
1541
|
+
const H_GAP = 160;
|
|
1542
|
+
const V_GAP = 24;
|
|
1499
1543
|
const pos = {};
|
|
1500
|
-
|
|
1501
|
-
|
|
1502
|
-
|
|
1503
|
-
|
|
1504
|
-
|
|
1544
|
+
let curX = 0;
|
|
1545
|
+
for (const layer of layers) {
|
|
1546
|
+
// Compute max width in this layer and individual heights
|
|
1547
|
+
let maxWidth = 0;
|
|
1548
|
+
const heights = {};
|
|
1549
|
+
for (const id of layer) {
|
|
1550
|
+
const node = cur.nodes.find((n) => n.nodeId === id);
|
|
1551
|
+
if (!node)
|
|
1552
|
+
continue;
|
|
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 });
|
|
1556
|
+
heights[id] = size.height;
|
|
1557
|
+
if (size.width > maxWidth)
|
|
1558
|
+
maxWidth = size.width;
|
|
1559
|
+
}
|
|
1560
|
+
// Place nodes in this column
|
|
1561
|
+
let curY = 0;
|
|
1562
|
+
for (const id of layer) {
|
|
1563
|
+
const h = heights[id] ?? 0;
|
|
1564
|
+
pos[id] = { x: curX, y: curY };
|
|
1565
|
+
curY += h + V_GAP;
|
|
1566
|
+
}
|
|
1567
|
+
curX += maxWidth + H_GAP;
|
|
1568
|
+
}
|
|
1505
1569
|
wb.setPositions(pos);
|
|
1506
1570
|
}, [wb]);
|
|
1507
1571
|
const updateEdgeType = React.useCallback((edgeId, typeId) => wb.updateEdgeType(edgeId, typeId), [wb]);
|
|
@@ -1597,15 +1661,6 @@ function WorkbenchProvider({ wb, runner, registry, setRegistry, children, }) {
|
|
|
1597
1661
|
return add("runner", "error")(e);
|
|
1598
1662
|
});
|
|
1599
1663
|
const off3 = runner.on("invalidate", (e) => {
|
|
1600
|
-
if (e?.reason === "graph-updated") {
|
|
1601
|
-
setNodeStatus((s) => {
|
|
1602
|
-
const next = {};
|
|
1603
|
-
for (const n of wb.export().nodes) {
|
|
1604
|
-
next[n.nodeId] = { ...s[n.nodeId], invalidated: true };
|
|
1605
|
-
}
|
|
1606
|
-
return next;
|
|
1607
|
-
});
|
|
1608
|
-
}
|
|
1609
1664
|
// After build/update, pull resolved handles and merge in-place (no graphChanged)
|
|
1610
1665
|
if (e?.reason === "graph-updated" || e?.reason === "graph-built") {
|
|
1611
1666
|
refreshResolvedHandles();
|
|
@@ -1774,17 +1829,17 @@ function WorkbenchProvider({ wb, runner, registry, setRegistry, children, }) {
|
|
|
1774
1829
|
const arr = inputs[d.nodeId] ?? (inputs[d.nodeId] = []);
|
|
1775
1830
|
arr.push({ handle: String(d.input), level, message, code });
|
|
1776
1831
|
const nodeArr = issues[d.nodeId] ?? (issues[d.nodeId] = []);
|
|
1777
|
-
nodeArr.push(
|
|
1832
|
+
nodeArr.push(is);
|
|
1778
1833
|
}
|
|
1779
1834
|
if (d.output) {
|
|
1780
1835
|
const arr = outputs[d.nodeId] ?? (outputs[d.nodeId] = []);
|
|
1781
1836
|
arr.push({ handle: String(d.output), level, message, code });
|
|
1782
1837
|
const nodeArr = issues[d.nodeId] ?? (issues[d.nodeId] = []);
|
|
1783
|
-
nodeArr.push(
|
|
1838
|
+
nodeArr.push(is);
|
|
1784
1839
|
}
|
|
1785
1840
|
if (!d.input && !d.output) {
|
|
1786
1841
|
const arr = issues[d.nodeId] ?? (issues[d.nodeId] = []);
|
|
1787
|
-
arr.push(
|
|
1842
|
+
arr.push(is);
|
|
1788
1843
|
}
|
|
1789
1844
|
}
|
|
1790
1845
|
}
|
|
@@ -1796,11 +1851,8 @@ function WorkbenchProvider({ wb, runner, registry, setRegistry, children, }) {
|
|
|
1796
1851
|
return list;
|
|
1797
1852
|
for (const is of validation.issues ?? []) {
|
|
1798
1853
|
const d = is.data;
|
|
1799
|
-
const level = is.level;
|
|
1800
|
-
const code = String(is.code ?? "");
|
|
1801
|
-
const message = String(is.message ?? code);
|
|
1802
1854
|
if (!d || (!d.nodeId && !d.edgeId)) {
|
|
1803
|
-
list.push(
|
|
1855
|
+
list.push(is);
|
|
1804
1856
|
}
|
|
1805
1857
|
}
|
|
1806
1858
|
return list;
|
|
@@ -1813,13 +1865,11 @@ function WorkbenchProvider({ wb, runner, registry, setRegistry, children, }) {
|
|
|
1813
1865
|
for (const is of validation.issues ?? []) {
|
|
1814
1866
|
const d = is.data;
|
|
1815
1867
|
const level = is.level;
|
|
1816
|
-
const code = String(is.code ?? "");
|
|
1817
|
-
const message = String(is.message ?? code);
|
|
1818
1868
|
if (d?.edgeId) {
|
|
1819
1869
|
if (level === "error")
|
|
1820
1870
|
errors[d.edgeId] = true;
|
|
1821
1871
|
const arr = issues[d.edgeId] ?? (issues[d.edgeId] = []);
|
|
1822
|
-
arr.push(
|
|
1872
|
+
arr.push(is);
|
|
1823
1873
|
}
|
|
1824
1874
|
}
|
|
1825
1875
|
return { errors, issues };
|
|
@@ -2019,11 +2069,29 @@ function Inspector({ debug, autoScroll, hideWorkbench, onAutoScrollChange, onHid
|
|
|
2019
2069
|
setOriginals(nextOriginals);
|
|
2020
2070
|
}, [selectedNodeId, selectedDesc, valuesTick]);
|
|
2021
2071
|
const widthClass = debug ? "w-[480px]" : "w-[320px]";
|
|
2022
|
-
|
|
2072
|
+
const { wb } = useWorkbenchContext();
|
|
2073
|
+
const deleteEdgeById = (edgeId) => {
|
|
2074
|
+
if (!edgeId)
|
|
2075
|
+
return;
|
|
2076
|
+
try {
|
|
2077
|
+
wb.disconnect(edgeId);
|
|
2078
|
+
}
|
|
2079
|
+
catch { }
|
|
2080
|
+
};
|
|
2081
|
+
return (jsxRuntime.jsxs("div", { className: `${widthClass} border-l border-gray-300 p-3 flex flex-col h-full min-h-0 overflow-hidden`, children: [contextPanel && jsxRuntime.jsx("div", { className: "mb-2", children: contextPanel }), jsxRuntime.jsx("div", { className: "font-semibold mb-2", children: "Inspector" }), jsxRuntime.jsxs("div", { className: "text-xs text-gray-500 mb-2", children: ["valuesTick: ", valuesTick] }), jsxRuntime.jsx("div", { className: "flex-1 overflow-auto", children: !selectedNode && !selectedEdge ? (jsxRuntime.jsxs("div", { children: [jsxRuntime.jsx("div", { className: "text-gray-500", children: "Select a node or edge." }), globalValidationIssues && globalValidationIssues.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: globalValidationIssues.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}` }), !!m.data?.edgeId && (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) => {
|
|
2082
|
+
e.stopPropagation();
|
|
2083
|
+
deleteEdgeById(m.data?.edgeId);
|
|
2084
|
+
}, title: "Delete referenced edge", children: "Delete edge" }))] }, i))) })] }))] })) : selectedEdge ? (jsxRuntime.jsxs("div", { children: [jsxRuntime.jsxs("div", { className: "mb-2", children: [jsxRuntime.jsxs("div", { children: ["Edge: ", selectedEdge.id] }), jsxRuntime.jsxs("div", { children: [selectedEdge.source.nodeId, ".", selectedEdge.source.handle, " \u2192", " ", selectedEdge.target.nodeId, ".", selectedEdge.target.handle] }), jsxRuntime.jsx("div", { className: "mt-1", children: jsxRuntime.jsx("button", { className: "text-xs px-2 py-1 border border-red-300 rounded text-red-700 hover:bg-red-50", onClick: (e) => {
|
|
2085
|
+
e.stopPropagation();
|
|
2086
|
+
deleteEdgeById(selectedEdge.id);
|
|
2087
|
+
}, title: "Delete this edge", children: "Delete edge" }) }), jsxRuntime.jsxs("div", { className: "flex items-center gap-2 mt-1", children: [jsxRuntime.jsxs("label", { className: "w-20 flex flex-col", children: [jsxRuntime.jsx("span", { children: "Type" }), jsxRuntime.jsx("span", { className: "text-gray-500 text-[11px]", children: "DataTypeId" })] }), jsxRuntime.jsxs("select", { className: "border border-gray-300 rounded px-2 py-1 focus:outline-none focus:ring-2 focus:ring-blue-500 w-full", value: selectedEdge.typeId ?? "", onChange: (e) => {
|
|
2023
2088
|
const v = e.target.value;
|
|
2024
2089
|
const next = v === "" ? undefined : v;
|
|
2025
2090
|
updateEdgeType(selectedEdge.id, next);
|
|
2026
|
-
}, 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}` })
|
|
2091
|
+
}, 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) => {
|
|
2092
|
+
e.stopPropagation();
|
|
2093
|
+
deleteEdgeById(selectedEdge.id);
|
|
2094
|
+
}, 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?.lastError && (jsxRuntime.jsx("div", { className: "mt-2 text-sm text-red-700 bg-red-50 border border-red-200 rounded px-2 py-1 break-words", children: String(selectedNodeStatus.lastError?.message ??
|
|
2027
2095
|
selectedNodeStatus.lastError) }))] })), jsxRuntime.jsxs("div", { className: "mb-2", children: [jsxRuntime.jsx("div", { className: "font-semibold mb-1", children: "Inputs" }), inputHandles.length === 0 ? (jsxRuntime.jsx("div", { className: "text-gray-500", children: "No inputs" })) : (inputHandles.map((h) => {
|
|
2028
2096
|
const typeId = sparkGraph.getInputTypeId(selectedDesc?.inputs, h);
|
|
2029
2097
|
const isLinked = def.edges.some((e) => e.target.nodeId === selectedNodeId &&
|
|
@@ -2081,7 +2149,10 @@ function Inspector({ debug, autoScroll, hideWorkbench, onAutoScrollChange, onHid
|
|
|
2081
2149
|
.map((v) => `${v.code}: ${v.message}`)
|
|
2082
2150
|
.join("; ");
|
|
2083
2151
|
return (jsxRuntime.jsx(IssueBadge, { level: outErr ? "error" : "warning", size: 24, className: "ml-1 w-6 h-6", title: outTitle }));
|
|
2084
|
-
})()] }, h))))] }), selectedNodeValidation.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: selectedNodeValidation.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}` })
|
|
2152
|
+
})()] }, h))))] }), selectedNodeValidation.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: selectedNodeValidation.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}` }), !!m.data?.edgeId && (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) => {
|
|
2153
|
+
e.stopPropagation();
|
|
2154
|
+
deleteEdgeById(m.data?.edgeId);
|
|
2155
|
+
}, title: "Delete referenced edge", children: "Delete edge" }))] }, i))) })] }))] })) }), debug && (jsxRuntime.jsx("div", { className: "mt-3 flex-none min-h-0 h-[50%]", children: jsxRuntime.jsx(DebugEvents, { autoScroll: !!autoScroll, hideWorkbench: !!hideWorkbench, onAutoScrollChange: onAutoScrollChange, onHideWorkbenchChange: onHideWorkbenchChange }) }))] }));
|
|
2085
2156
|
}
|
|
2086
2157
|
|
|
2087
2158
|
function NodeHandles({ data, isConnectable, inputClassName = "!w-2 !h-2 !bg-gray-600", outputClassName = "!w-2 !h-2 !bg-gray-600", getClassName, renderLabel, labelClassName = "absolute text-[11px] text-gray-700 dark:text-gray-300 pointer-events-none", }) {
|