@bian-womp/spark-workbench 0.2.38 → 0.2.39

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.
@@ -6,6 +6,8 @@ export * from "./adapters/cli";
6
6
  export * from "./runtime/IGraphRunner";
7
7
  export * from "./runtime/LocalGraphRunner";
8
8
  export * from "./runtime/RemoteGraphRunner";
9
+ export * from "./misc/value";
10
+ export * from "./misc/layout";
9
11
  export * from "./misc/hooks";
10
12
  export * from "./misc/mapping";
11
13
  export * from "./misc/context/WorkbenchContext";
@@ -14,7 +16,5 @@ export * from "./misc/Inspector";
14
16
  export * from "./misc/DefaultNode";
15
17
  export * from "./misc/WorkbenchCanvas";
16
18
  export * from "./misc/WorkbenchStudio";
17
- export * from "./misc/value";
18
19
  export * from "./misc/NodeHandles";
19
- export * from "./misc/layout";
20
20
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,kBAAkB,CAAC;AACjC,cAAc,sBAAsB,CAAC;AACrC,cAAc,0BAA0B,CAAC;AACzC,cAAc,0BAA0B,CAAC;AACzC,cAAc,gBAAgB,CAAC;AAE/B,cAAc,wBAAwB,CAAC;AACvC,cAAc,4BAA4B,CAAC;AAC3C,cAAc,6BAA6B,CAAC;AAE5C,cAAc,cAAc,CAAC;AAC7B,cAAc,gBAAgB,CAAC;AAE/B,cAAc,iCAAiC,CAAC;AAChD,cAAc,0CAA0C,CAAC;AAEzD,cAAc,kBAAkB,CAAC;AACjC,cAAc,oBAAoB,CAAC;AACnC,cAAc,wBAAwB,CAAC;AAEvC,cAAc,wBAAwB,CAAC;AACvC,cAAc,cAAc,CAAC;AAC7B,cAAc,oBAAoB,CAAC;AACnC,cAAc,eAAe,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,kBAAkB,CAAC;AACjC,cAAc,sBAAsB,CAAC;AACrC,cAAc,0BAA0B,CAAC;AACzC,cAAc,0BAA0B,CAAC;AAEzC,cAAc,gBAAgB,CAAC;AAE/B,cAAc,wBAAwB,CAAC;AACvC,cAAc,4BAA4B,CAAC;AAC3C,cAAc,6BAA6B,CAAC;AAE5C,cAAc,cAAc,CAAC;AAC7B,cAAc,eAAe,CAAC;AAC9B,cAAc,cAAc,CAAC;AAC7B,cAAc,gBAAgB,CAAC;AAE/B,cAAc,iCAAiC,CAAC;AAChD,cAAc,0CAA0C,CAAC;AAEzD,cAAc,kBAAkB,CAAC;AACjC,cAAc,oBAAoB,CAAC;AACnC,cAAc,wBAAwB,CAAC;AAEvC,cAAc,wBAAwB,CAAC;AACvC,cAAc,oBAAoB,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"RemoteGraphRunner.d.ts","sourceRoot":"","sources":["../../../../src/runtime/RemoteGraphRunner.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,mBAAmB,EACnB,eAAe,EAChB,MAAM,2BAA2B,CAAC;AACnC,OAAO,EAAU,QAAQ,EAAE,MAAM,wBAAwB,CAAC;AAC1D,OAAO,EACL,gBAAgB,EAGjB,MAAM,yBAAyB,CAAC;AACjC,OAAO,EACL,sBAAsB,EAEtB,aAAa,EACd,MAAM,gBAAgB,CAAC;AACxB,OAAO,EAAE,mBAAmB,EAAE,MAAM,uBAAuB,CAAC;AAE5D,qBAAa,iBAAkB,SAAQ,mBAAmB;IACxD,SAAS,CAAC,OAAO,CAAC,EAAE,eAAe,CAAC;IACpC,SAAS,CAAC,MAAM,CAAC,EAAE,gBAAgB,CAAC;IACpC,OAAO,CAAC,aAAa,CAAC,CAA4B;IAClD,OAAO,CAAC,sBAAsB,CAAC,CAAa;IAC5C,OAAO,CAAC,0BAA0B,CAAC,CAAa;IAChD,OAAO,CAAC,QAAQ,CAAS;IAEzB,OAAO,CAAC,UAAU,CAGd;IACJ,OAAO,CAAC,cAAc,CAAS;IAC/B,OAAO,CAAC,eAAe,CAAS;IAChC,OAAO,CAAC,gBAAgB,CAAS;IACjC,OAAO,CAAC,QAAQ,CAAC,2BAA2B,CAAK;IACjD,OAAO,CAAC,QAAQ,CAAC,sBAAsB,CAAQ;IAE/C;;;OAGG;YACW,aAAa;IA4H3B;;OAEG;IACH,OAAO,CAAC,iBAAiB;IAkBzB;;OAEG;IACH,OAAO,CAAC,wBAAwB;cA2BhB,YAAY,IAAI,OAAO,CAAC,gBAAgB,CAAC;gBAkD7C,QAAQ,EAAE,QAAQ,EAAE,OAAO,EAAE,sBAAsB;IA8D/D,KAAK,CAAC,GAAG,EAAE,eAAe,GAAG,IAAI;IAIjC,MAAM,CAAC,GAAG,EAAE,eAAe,GAAG,IAAI;IAWlC,MAAM,CAAC,GAAG,EAAE,eAAe,EAAE,IAAI,EAAE,aAAa,GAAG,IAAI;IAyDvD;;;;;;OAMG;IACH,cAAc,CAAC,GAAG,EAAE,eAAe,EAAE,IAAI,EAAE,aAAa,GAAG,IAAI;IAoCzD,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC;IAIrB,WAAW,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAIhD,KAAK,IAAI,IAAI;IAIb,eAAe,CAAC,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO,GAAG,IAAI;IAQ/C,MAAM,CAAC,IAAI,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC;IASlE,YAAY;IASZ,iBAAiB,CAAC,OAAO,EAAE,mBAAmB;IASpD;;;;OAIG;IACH,mBAAmB,CAAC,QAAQ,EAAE,mBAAmB,GAAG,IAAI;IAuBxD,cAAc,CAAC,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,IAAI,CAAC,EAAE;QAAE,KAAK,CAAC,EAAE,OAAO,CAAA;KAAE;IAcvE,cAAc,IAAI,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,SAAS;IASrD,UAAU,CAAC,GAAG,EAAE,eAAe,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAoBzE,SAAS,CAAC,GAAG,EAAE,eAAe,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IA6BxE,gBAAgB,CACd,GAAG,EAAE,eAAe,GACnB,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAW1C,OAAO,IAAI,IAAI;CAqChB"}
1
+ {"version":3,"file":"RemoteGraphRunner.d.ts","sourceRoot":"","sources":["../../../../src/runtime/RemoteGraphRunner.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,mBAAmB,EACnB,eAAe,EAChB,MAAM,2BAA2B,CAAC;AACnC,OAAO,EAAU,QAAQ,EAAE,MAAM,wBAAwB,CAAC;AAC1D,OAAO,EACL,gBAAgB,EAGjB,MAAM,yBAAyB,CAAC;AACjC,OAAO,EACL,sBAAsB,EAEtB,aAAa,EACd,MAAM,gBAAgB,CAAC;AACxB,OAAO,EAAE,mBAAmB,EAAE,MAAM,uBAAuB,CAAC;AAE5D,qBAAa,iBAAkB,SAAQ,mBAAmB;IACxD,SAAS,CAAC,OAAO,CAAC,EAAE,eAAe,CAAC;IACpC,SAAS,CAAC,MAAM,CAAC,EAAE,gBAAgB,CAAC;IACpC,OAAO,CAAC,aAAa,CAAC,CAA4B;IAClD,OAAO,CAAC,sBAAsB,CAAC,CAAa;IAC5C,OAAO,CAAC,0BAA0B,CAAC,CAAa;IAChD,OAAO,CAAC,QAAQ,CAAS;IAEzB,OAAO,CAAC,UAAU,CAGd;IACJ,OAAO,CAAC,cAAc,CAAS;IAC/B,OAAO,CAAC,eAAe,CAAS;IAChC,OAAO,CAAC,gBAAgB,CAAS;IACjC,OAAO,CAAC,QAAQ,CAAC,2BAA2B,CAAK;IACjD,OAAO,CAAC,QAAQ,CAAC,sBAAsB,CAAQ;IAE/C;;;OAGG;YACW,aAAa;IA4H3B;;OAEG;IACH,OAAO,CAAC,iBAAiB;IAkBzB;;OAEG;IACH,OAAO,CAAC,wBAAwB;cA2BhB,YAAY,IAAI,OAAO,CAAC,gBAAgB,CAAC;gBAkD7C,QAAQ,EAAE,QAAQ,EAAE,OAAO,EAAE,sBAAsB;IA8D/D,KAAK,CAAC,GAAG,EAAE,eAAe,GAAG,IAAI;IAEjC,MAAM,CAAC,GAAG,EAAE,eAAe,GAAG,IAAI;IAWlC,MAAM,CAAC,GAAG,EAAE,eAAe,EAAE,IAAI,EAAE,aAAa,GAAG,IAAI;IAyDvD;;;;;;OAMG;IACH,cAAc,CAAC,GAAG,EAAE,eAAe,EAAE,IAAI,EAAE,aAAa,GAAG,IAAI;IAoCzD,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC;IAErB,WAAW,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAEhD,KAAK,IAAI,IAAI;IAEb,eAAe,CAAC,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO,GAAG,IAAI;IAQ/C,MAAM,CAAC,IAAI,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC;IASlE,YAAY;IASZ,iBAAiB,CAAC,OAAO,EAAE,mBAAmB;IASpD;;;;OAIG;IACH,mBAAmB,CAAC,QAAQ,EAAE,mBAAmB,GAAG,IAAI;IAuBxD,cAAc,CAAC,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,IAAI,CAAC,EAAE;QAAE,KAAK,CAAC,EAAE,OAAO,CAAA;KAAE;IAcvE,cAAc,IAAI,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,SAAS;IASrD,UAAU,CAAC,GAAG,EAAE,eAAe,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAoBzE,SAAS,CAAC,GAAG,EAAE,eAAe,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IA6BxE,gBAAgB,CACd,GAAG,EAAE,eAAe,GACnB,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAW1C,OAAO,IAAI,IAAI;CAqChB"}
package/lib/esm/index.js CHANGED
@@ -1,7 +1,7 @@
1
1
  import { GraphBuilder, StepEngine, HybridEngine, PullEngine, BatchedEngine, PushEngine, isTypedOutput, getTypedOutputValue, getTypedOutputTypeId, isInputPrivate, getInputTypeId, createSimpleGraphRegistry, createSimpleGraphDef, createAsyncGraphDef, createAsyncGraphRegistry, createProgressGraphDef, createProgressGraphRegistry, createValidationGraphDef, createValidationGraphRegistry } from '@bian-womp/spark-graph';
2
2
  import { RuntimeApiClient } from '@bian-womp/spark-remote';
3
- import React, { useCallback, useState, useRef, useEffect, useMemo, createContext, useContext, useImperativeHandle } from 'react';
4
3
  import { Position, Handle, useUpdateNodeInternals, useReactFlow, ReactFlowProvider, ReactFlow, Background, BackgroundVariant, MiniMap, Controls } from '@xyflow/react';
4
+ import React, { useCallback, useState, useRef, useEffect, useMemo, createContext, useContext, useImperativeHandle } from 'react';
5
5
  import cx from 'classnames';
6
6
  import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
7
7
  import { XCircleIcon, WarningCircleIcon, CopyIcon, TrashIcon, XIcon, ArrowClockwiseIcon, PlugsConnectedIcon, ClockClockwiseIcon, WifiHighIcon, WifiSlashIcon, PlayPauseIcon, LightningIcon, StopIcon, PlayIcon, TreeStructureIcon, CornersOutIcon, DownloadSimpleIcon, DownloadIcon, UploadIcon, BugBeetleIcon, ListBulletsIcon } from '@phosphor-icons/react';
@@ -862,9 +862,7 @@ class RemoteGraphRunner extends AbstractGraphRunner {
862
862
  }
863
863
  });
864
864
  }
865
- build(def) {
866
- console.warn("Unsupported operation for remote runner");
867
- }
865
+ build(def) { }
868
866
  update(def) {
869
867
  // Remote: forward update; ignore errors (fire-and-forget)
870
868
  this.ensureClient().then(async (client) => {
@@ -973,15 +971,9 @@ class RemoteGraphRunner extends AbstractGraphRunner {
973
971
  }
974
972
  });
975
973
  }
976
- async step() {
977
- console.warn("Unsupported operation for remote runner");
978
- }
979
- async computeNode(nodeId) {
980
- console.warn("Unsupported operation for remote runner");
981
- }
982
- flush() {
983
- console.warn("Unsupported operation for remote runner");
984
- }
974
+ async step() { }
975
+ async computeNode(nodeId) { }
976
+ flush() { }
985
977
  triggerExternal(nodeId, event) {
986
978
  this.ensureClient().then(async (client) => {
987
979
  try {
@@ -1158,6 +1150,202 @@ class RemoteGraphRunner extends AbstractGraphRunner {
1158
1150
  }
1159
1151
  }
1160
1152
 
1153
+ function formatDataUrlAsLabel(dataUrl) {
1154
+ try {
1155
+ const semi = dataUrl.indexOf(";");
1156
+ const comma = dataUrl.indexOf(",");
1157
+ const mime = dataUrl.slice(5, semi > 0 ? semi : undefined).toUpperCase();
1158
+ const b64 = comma >= 0 ? dataUrl.slice(comma + 1) : "";
1159
+ const bytes = Math.floor((b64.length * 3) / 4);
1160
+ return `${mime} Data (${bytes} bytes)`;
1161
+ }
1162
+ catch {
1163
+ return dataUrl.length > 64 ? dataUrl.slice(0, 64) + "…" : dataUrl;
1164
+ }
1165
+ }
1166
+ function resolveOutputDisplay(raw, declared) {
1167
+ if (isTypedOutput(raw)) {
1168
+ return {
1169
+ typeId: getTypedOutputTypeId(raw),
1170
+ value: getTypedOutputValue(raw),
1171
+ };
1172
+ }
1173
+ let typeId = undefined;
1174
+ if (Array.isArray(declared)) {
1175
+ typeId = declared.length === 1 ? declared[0] : undefined;
1176
+ }
1177
+ else if (typeof declared === "string") {
1178
+ typeId = declared.includes("|") ? undefined : declared;
1179
+ }
1180
+ return { typeId, value: raw };
1181
+ }
1182
+ function formatDeclaredTypeSignature(declared) {
1183
+ if (Array.isArray(declared))
1184
+ return declared.join(" | ");
1185
+ return declared ?? "";
1186
+ }
1187
+ /**
1188
+ * Formats a handle ID for display in the UI.
1189
+ * For handles with format "prefix:middle:suffix:extra" (4 parts), displays only the middle part.
1190
+ * Otherwise returns the handle ID as-is.
1191
+ */
1192
+ function prettyHandle(id) {
1193
+ try {
1194
+ const parts = String(id).split(":");
1195
+ // If there are exactly 3 colons (4 parts), display only the second part
1196
+ if (parts.length === 4)
1197
+ return parts[1] || id;
1198
+ return id;
1199
+ }
1200
+ catch {
1201
+ return id;
1202
+ }
1203
+ }
1204
+ // Pre-format common structures for display; return undefined to defer to caller
1205
+ function preformatValueForDisplay(typeId, value, registry) {
1206
+ if (value === undefined || value === null)
1207
+ return "";
1208
+ // Unwrap typed outputs
1209
+ if (isTypedOutput(value)) {
1210
+ return preformatValueForDisplay(getTypedOutputTypeId(value), getTypedOutputValue(value), registry);
1211
+ }
1212
+ // Enums
1213
+ if (typeId && typeId.startsWith("enum:") && registry) {
1214
+ const n = Number(value);
1215
+ const label = registry.enums.get(typeId)?.valueToLabel.get(n);
1216
+ if (label)
1217
+ return label;
1218
+ }
1219
+ // Use deep summarization for strings, arrays and nested objects to avoid huge HTML payloads
1220
+ const summarized = summarizeDeep(value);
1221
+ if (typeof summarized === "string")
1222
+ return summarized;
1223
+ // Resource-like objects with url/title (after summarization)
1224
+ if (summarized && typeof summarized === "object") {
1225
+ const urlMaybe = summarized.url;
1226
+ if (typeof urlMaybe === "string") {
1227
+ const title = summarized.title || "";
1228
+ const shortUrl = urlMaybe.length > 32 ? urlMaybe.slice(0, 32) + "…" : urlMaybe;
1229
+ return title ? `${title} (${shortUrl})` : shortUrl;
1230
+ }
1231
+ }
1232
+ return undefined;
1233
+ }
1234
+ function summarizeDeep(value) {
1235
+ // Strings: summarize data URLs and trim extremely long strings
1236
+ if (typeof value === "string") {
1237
+ if (value.startsWith("data:"))
1238
+ return formatDataUrlAsLabel(value);
1239
+ return value.length > 512 ? value.slice(0, 512) + "…" : value;
1240
+ }
1241
+ // Typed output wrapper
1242
+ if (isTypedOutput(value)) {
1243
+ return summarizeDeep(getTypedOutputValue(value));
1244
+ }
1245
+ // Arrays
1246
+ if (Array.isArray(value)) {
1247
+ return value.map((v) => summarizeDeep(v));
1248
+ }
1249
+ // Objects
1250
+ if (value && typeof value === "object") {
1251
+ const obj = value;
1252
+ const out = {};
1253
+ for (const [k, v] of Object.entries(obj)) {
1254
+ // Special-case any 'url' field
1255
+ if (typeof v === "string" &&
1256
+ k.toLowerCase() === "url" &&
1257
+ v.startsWith("data:")) {
1258
+ out[k] = formatDataUrlAsLabel(v);
1259
+ continue;
1260
+ }
1261
+ out[k] = summarizeDeep(v);
1262
+ }
1263
+ return out;
1264
+ }
1265
+ return value;
1266
+ }
1267
+
1268
+ // Shared UI constants for node layout to keep mapping and rendering in sync
1269
+ const NODE_HEADER_HEIGHT_PX = 24;
1270
+ const NODE_ROW_HEIGHT_PX = 22;
1271
+
1272
+ function computeEffectiveHandles(node, registry) {
1273
+ const desc = registry.nodes.get(node.typeId);
1274
+ const resolved = node.resolvedHandles || {};
1275
+ const inputs = { ...desc?.inputs, ...resolved.inputs };
1276
+ const outputs = { ...desc?.outputs, ...resolved.outputs };
1277
+ const inputDefaults = { ...desc?.inputDefaults, ...resolved.inputDefaults };
1278
+ return { inputs, outputs, inputDefaults };
1279
+ }
1280
+ function countVisibleHandles(handles) {
1281
+ const inputIds = Object.keys(handles.inputs).filter((k) => !isInputPrivate(handles.inputs, k));
1282
+ const outputIds = Object.keys(handles.outputs);
1283
+ return { inputsCount: inputIds.length, outputsCount: outputIds.length };
1284
+ }
1285
+ function estimateNodeSize(args) {
1286
+ const { node, registry, showValues, overrides } = args;
1287
+ const { inputs, outputs } = computeEffectiveHandles(node, registry);
1288
+ // Count only non-private inputs for rows on left
1289
+ const { inputsCount, outputsCount } = countVisibleHandles({
1290
+ inputs,
1291
+ outputs,
1292
+ });
1293
+ const rows = Math.max(inputsCount, outputsCount);
1294
+ const baseWidth = showValues ? 320 : 240;
1295
+ const width = overrides?.width ?? baseWidth;
1296
+ const height = overrides?.height ?? NODE_HEADER_HEIGHT_PX + rows * NODE_ROW_HEIGHT_PX;
1297
+ return { width, height, inputsCount, outputsCount, rowCount: rows };
1298
+ }
1299
+ function layoutNode(args) {
1300
+ const { node, registry, showValues, overrides } = args;
1301
+ const { inputs, outputs } = computeEffectiveHandles(node, registry);
1302
+ const inputOrder = Object.keys(inputs).filter((k) => !isInputPrivate(inputs, k));
1303
+ const outputOrder = Object.keys(outputs);
1304
+ const { width, height } = estimateNodeSize({
1305
+ node,
1306
+ registry,
1307
+ showValues,
1308
+ overrides,
1309
+ });
1310
+ const HEADER = NODE_HEADER_HEIGHT_PX;
1311
+ const ROW = NODE_ROW_HEIGHT_PX;
1312
+ const handles = [
1313
+ ...inputOrder.map((id, i) => ({
1314
+ id,
1315
+ type: "target",
1316
+ position: Position.Left,
1317
+ x: 0,
1318
+ y: HEADER + i * ROW,
1319
+ width: 1,
1320
+ height: ROW + 2,
1321
+ })),
1322
+ ...outputOrder.map((id, i) => ({
1323
+ id,
1324
+ type: "source",
1325
+ position: Position.Right,
1326
+ x: width - 1,
1327
+ y: HEADER + i * ROW,
1328
+ width: 1,
1329
+ height: ROW + 2,
1330
+ })),
1331
+ ];
1332
+ const handleLayout = [
1333
+ ...inputOrder.map((id, i) => ({
1334
+ id,
1335
+ type: "target",
1336
+ position: Position.Left,
1337
+ y: HEADER + i * ROW + ROW / 2,
1338
+ })),
1339
+ ...outputOrder.map((id, i) => ({
1340
+ id,
1341
+ type: "source",
1342
+ position: Position.Right,
1343
+ y: HEADER + i * ROW + ROW / 2,
1344
+ })),
1345
+ ];
1346
+ return { width, height, inputOrder, outputOrder, handles, handleLayout };
1347
+ }
1348
+
1161
1349
  function useWorkbenchBridge(wb) {
1162
1350
  const onConnect = useCallback((params) => {
1163
1351
  if (!params.source || !params.target)
@@ -1402,202 +1590,6 @@ function useQueryParamString(key, defaultValue) {
1402
1590
  return [val, set];
1403
1591
  }
1404
1592
 
1405
- function formatDataUrlAsLabel(dataUrl) {
1406
- try {
1407
- const semi = dataUrl.indexOf(";");
1408
- const comma = dataUrl.indexOf(",");
1409
- const mime = dataUrl.slice(5, semi > 0 ? semi : undefined).toUpperCase();
1410
- const b64 = comma >= 0 ? dataUrl.slice(comma + 1) : "";
1411
- const bytes = Math.floor((b64.length * 3) / 4);
1412
- return `${mime} Data (${bytes} bytes)`;
1413
- }
1414
- catch {
1415
- return dataUrl.length > 64 ? dataUrl.slice(0, 64) + "…" : dataUrl;
1416
- }
1417
- }
1418
- function resolveOutputDisplay(raw, declared) {
1419
- if (isTypedOutput(raw)) {
1420
- return {
1421
- typeId: getTypedOutputTypeId(raw),
1422
- value: getTypedOutputValue(raw),
1423
- };
1424
- }
1425
- let typeId = undefined;
1426
- if (Array.isArray(declared)) {
1427
- typeId = declared.length === 1 ? declared[0] : undefined;
1428
- }
1429
- else if (typeof declared === "string") {
1430
- typeId = declared.includes("|") ? undefined : declared;
1431
- }
1432
- return { typeId, value: raw };
1433
- }
1434
- function formatDeclaredTypeSignature(declared) {
1435
- if (Array.isArray(declared))
1436
- return declared.join(" | ");
1437
- return declared ?? "";
1438
- }
1439
- /**
1440
- * Formats a handle ID for display in the UI.
1441
- * For handles with format "prefix:middle:suffix:extra" (4 parts), displays only the middle part.
1442
- * Otherwise returns the handle ID as-is.
1443
- */
1444
- function prettyHandle(id) {
1445
- try {
1446
- const parts = String(id).split(":");
1447
- // If there are exactly 3 colons (4 parts), display only the second part
1448
- if (parts.length === 4)
1449
- return parts[1] || id;
1450
- return id;
1451
- }
1452
- catch {
1453
- return id;
1454
- }
1455
- }
1456
- // Pre-format common structures for display; return undefined to defer to caller
1457
- function preformatValueForDisplay(typeId, value, registry) {
1458
- if (value === undefined || value === null)
1459
- return "";
1460
- // Unwrap typed outputs
1461
- if (isTypedOutput(value)) {
1462
- return preformatValueForDisplay(getTypedOutputTypeId(value), getTypedOutputValue(value), registry);
1463
- }
1464
- // Enums
1465
- if (typeId && typeId.startsWith("enum:") && registry) {
1466
- const n = Number(value);
1467
- const label = registry.enums.get(typeId)?.valueToLabel.get(n);
1468
- if (label)
1469
- return label;
1470
- }
1471
- // Use deep summarization for strings, arrays and nested objects to avoid huge HTML payloads
1472
- const summarized = summarizeDeep(value);
1473
- if (typeof summarized === "string")
1474
- return summarized;
1475
- // Resource-like objects with url/title (after summarization)
1476
- if (summarized && typeof summarized === "object") {
1477
- const urlMaybe = summarized.url;
1478
- if (typeof urlMaybe === "string") {
1479
- const title = summarized.title || "";
1480
- const shortUrl = urlMaybe.length > 32 ? urlMaybe.slice(0, 32) + "…" : urlMaybe;
1481
- return title ? `${title} (${shortUrl})` : shortUrl;
1482
- }
1483
- }
1484
- return undefined;
1485
- }
1486
- function summarizeDeep(value) {
1487
- // Strings: summarize data URLs and trim extremely long strings
1488
- if (typeof value === "string") {
1489
- if (value.startsWith("data:"))
1490
- return formatDataUrlAsLabel(value);
1491
- return value.length > 512 ? value.slice(0, 512) + "…" : value;
1492
- }
1493
- // Typed output wrapper
1494
- if (isTypedOutput(value)) {
1495
- return summarizeDeep(getTypedOutputValue(value));
1496
- }
1497
- // Arrays
1498
- if (Array.isArray(value)) {
1499
- return value.map((v) => summarizeDeep(v));
1500
- }
1501
- // Objects
1502
- if (value && typeof value === "object") {
1503
- const obj = value;
1504
- const out = {};
1505
- for (const [k, v] of Object.entries(obj)) {
1506
- // Special-case any 'url' field
1507
- if (typeof v === "string" &&
1508
- k.toLowerCase() === "url" &&
1509
- v.startsWith("data:")) {
1510
- out[k] = formatDataUrlAsLabel(v);
1511
- continue;
1512
- }
1513
- out[k] = summarizeDeep(v);
1514
- }
1515
- return out;
1516
- }
1517
- return value;
1518
- }
1519
-
1520
- // Shared UI constants for node layout to keep mapping and rendering in sync
1521
- const NODE_HEADER_HEIGHT_PX = 24;
1522
- const NODE_ROW_HEIGHT_PX = 22;
1523
-
1524
- function computeEffectiveHandles(node, registry) {
1525
- const desc = registry.nodes.get(node.typeId);
1526
- const resolved = node.resolvedHandles || {};
1527
- const inputs = { ...desc?.inputs, ...resolved.inputs };
1528
- const outputs = { ...desc?.outputs, ...resolved.outputs };
1529
- const inputDefaults = { ...desc?.inputDefaults, ...resolved.inputDefaults };
1530
- return { inputs, outputs, inputDefaults };
1531
- }
1532
- function countVisibleHandles(handles) {
1533
- const inputIds = Object.keys(handles.inputs).filter((k) => !isInputPrivate(handles.inputs, k));
1534
- const outputIds = Object.keys(handles.outputs);
1535
- return { inputsCount: inputIds.length, outputsCount: outputIds.length };
1536
- }
1537
- function estimateNodeSize(args) {
1538
- const { node, registry, showValues, overrides } = args;
1539
- const { inputs, outputs } = computeEffectiveHandles(node, registry);
1540
- // Count only non-private inputs for rows on left
1541
- const { inputsCount, outputsCount } = countVisibleHandles({
1542
- inputs,
1543
- outputs,
1544
- });
1545
- const rows = Math.max(inputsCount, outputsCount);
1546
- const baseWidth = showValues ? 320 : 240;
1547
- const width = overrides?.width ?? baseWidth;
1548
- const height = overrides?.height ?? NODE_HEADER_HEIGHT_PX + rows * NODE_ROW_HEIGHT_PX;
1549
- return { width, height, inputsCount, outputsCount, rowCount: rows };
1550
- }
1551
- function layoutNode(args) {
1552
- const { node, registry, showValues, overrides } = args;
1553
- const { inputs, outputs } = computeEffectiveHandles(node, registry);
1554
- const inputOrder = Object.keys(inputs).filter((k) => !isInputPrivate(inputs, k));
1555
- const outputOrder = Object.keys(outputs);
1556
- const { width, height } = estimateNodeSize({
1557
- node,
1558
- registry,
1559
- showValues,
1560
- overrides,
1561
- });
1562
- const HEADER = NODE_HEADER_HEIGHT_PX;
1563
- const ROW = NODE_ROW_HEIGHT_PX;
1564
- const handles = [
1565
- ...inputOrder.map((id, i) => ({
1566
- id,
1567
- type: "target",
1568
- position: Position.Left,
1569
- x: 0,
1570
- y: HEADER + i * ROW,
1571
- width: 1,
1572
- height: ROW + 2,
1573
- })),
1574
- ...outputOrder.map((id, i) => ({
1575
- id,
1576
- type: "source",
1577
- position: Position.Right,
1578
- x: width - 1,
1579
- y: HEADER + i * ROW,
1580
- width: 1,
1581
- height: ROW + 2,
1582
- })),
1583
- ];
1584
- const handleLayout = [
1585
- ...inputOrder.map((id, i) => ({
1586
- id,
1587
- type: "target",
1588
- position: Position.Left,
1589
- y: HEADER + i * ROW + ROW / 2,
1590
- })),
1591
- ...outputOrder.map((id, i) => ({
1592
- id,
1593
- type: "source",
1594
- position: Position.Right,
1595
- y: HEADER + i * ROW + ROW / 2,
1596
- })),
1597
- ];
1598
- return { width, height, inputOrder, outputOrder, handles, handleLayout };
1599
- }
1600
-
1601
1593
  function toReactFlow(def, positions, registry, opts) {
1602
1594
  const EDGE_STYLE_MISSING = { stroke: "#f59e0b", strokeWidth: 2 }; // amber-500
1603
1595
  const EDGE_STYLE_ERROR = { stroke: "#ef4444", strokeWidth: 2 };