@bian-womp/spark-workbench 0.2.38 → 0.2.40

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
@@ -2,8 +2,8 @@
2
2
 
3
3
  var sparkGraph = require('@bian-womp/spark-graph');
4
4
  var sparkRemote = require('@bian-womp/spark-remote');
5
- var React = require('react');
6
5
  var react = require('@xyflow/react');
6
+ var React = require('react');
7
7
  var cx = require('classnames');
8
8
  var jsxRuntime = require('react/jsx-runtime');
9
9
  var react$1 = require('@phosphor-icons/react');
@@ -864,9 +864,7 @@ class RemoteGraphRunner extends AbstractGraphRunner {
864
864
  }
865
865
  });
866
866
  }
867
- build(def) {
868
- console.warn("Unsupported operation for remote runner");
869
- }
867
+ build(def) { }
870
868
  update(def) {
871
869
  // Remote: forward update; ignore errors (fire-and-forget)
872
870
  this.ensureClient().then(async (client) => {
@@ -975,15 +973,9 @@ class RemoteGraphRunner extends AbstractGraphRunner {
975
973
  }
976
974
  });
977
975
  }
978
- async step() {
979
- console.warn("Unsupported operation for remote runner");
980
- }
981
- async computeNode(nodeId) {
982
- console.warn("Unsupported operation for remote runner");
983
- }
984
- flush() {
985
- console.warn("Unsupported operation for remote runner");
986
- }
976
+ async step() { }
977
+ async computeNode(nodeId) { }
978
+ flush() { }
987
979
  triggerExternal(nodeId, event) {
988
980
  this.ensureClient().then(async (client) => {
989
981
  try {
@@ -1160,6 +1152,202 @@ class RemoteGraphRunner extends AbstractGraphRunner {
1160
1152
  }
1161
1153
  }
1162
1154
 
1155
+ function formatDataUrlAsLabel(dataUrl) {
1156
+ try {
1157
+ const semi = dataUrl.indexOf(";");
1158
+ const comma = dataUrl.indexOf(",");
1159
+ const mime = dataUrl.slice(5, semi > 0 ? semi : undefined).toUpperCase();
1160
+ const b64 = comma >= 0 ? dataUrl.slice(comma + 1) : "";
1161
+ const bytes = Math.floor((b64.length * 3) / 4);
1162
+ return `${mime} Data (${bytes} bytes)`;
1163
+ }
1164
+ catch {
1165
+ return dataUrl.length > 64 ? dataUrl.slice(0, 64) + "…" : dataUrl;
1166
+ }
1167
+ }
1168
+ function resolveOutputDisplay(raw, declared) {
1169
+ if (sparkGraph.isTypedOutput(raw)) {
1170
+ return {
1171
+ typeId: sparkGraph.getTypedOutputTypeId(raw),
1172
+ value: sparkGraph.getTypedOutputValue(raw),
1173
+ };
1174
+ }
1175
+ let typeId = undefined;
1176
+ if (Array.isArray(declared)) {
1177
+ typeId = declared.length === 1 ? declared[0] : undefined;
1178
+ }
1179
+ else if (typeof declared === "string") {
1180
+ typeId = declared.includes("|") ? undefined : declared;
1181
+ }
1182
+ return { typeId, value: raw };
1183
+ }
1184
+ function formatDeclaredTypeSignature(declared) {
1185
+ if (Array.isArray(declared))
1186
+ return declared.join(" | ");
1187
+ return declared ?? "";
1188
+ }
1189
+ /**
1190
+ * Formats a handle ID for display in the UI.
1191
+ * For handles with format "prefix:middle:suffix:extra" (4 parts), displays only the middle part.
1192
+ * Otherwise returns the handle ID as-is.
1193
+ */
1194
+ function prettyHandle(id) {
1195
+ try {
1196
+ const parts = String(id).split(":");
1197
+ // If there are exactly 3 colons (4 parts), display only the second part
1198
+ if (parts.length === 4)
1199
+ return parts[1] || id;
1200
+ return id;
1201
+ }
1202
+ catch {
1203
+ return id;
1204
+ }
1205
+ }
1206
+ // Pre-format common structures for display; return undefined to defer to caller
1207
+ function preformatValueForDisplay(typeId, value, registry) {
1208
+ if (value === undefined || value === null)
1209
+ return "";
1210
+ // Unwrap typed outputs
1211
+ if (sparkGraph.isTypedOutput(value)) {
1212
+ return preformatValueForDisplay(sparkGraph.getTypedOutputTypeId(value), sparkGraph.getTypedOutputValue(value), registry);
1213
+ }
1214
+ // Enums
1215
+ if (typeId && typeId.startsWith("enum:") && registry) {
1216
+ const n = Number(value);
1217
+ const label = registry.enums.get(typeId)?.valueToLabel.get(n);
1218
+ if (label)
1219
+ return label;
1220
+ }
1221
+ // Use deep summarization for strings, arrays and nested objects to avoid huge HTML payloads
1222
+ const summarized = summarizeDeep(value);
1223
+ if (typeof summarized === "string")
1224
+ return summarized;
1225
+ // Resource-like objects with url/title (after summarization)
1226
+ if (summarized && typeof summarized === "object") {
1227
+ const urlMaybe = summarized.url;
1228
+ if (typeof urlMaybe === "string") {
1229
+ const title = summarized.title || "";
1230
+ const shortUrl = urlMaybe.length > 32 ? urlMaybe.slice(0, 32) + "…" : urlMaybe;
1231
+ return title ? `${title} (${shortUrl})` : shortUrl;
1232
+ }
1233
+ }
1234
+ return undefined;
1235
+ }
1236
+ function summarizeDeep(value) {
1237
+ // Strings: summarize data URLs and trim extremely long strings
1238
+ if (typeof value === "string") {
1239
+ if (value.startsWith("data:"))
1240
+ return formatDataUrlAsLabel(value);
1241
+ return value.length > 512 ? value.slice(0, 512) + "…" : value;
1242
+ }
1243
+ // Typed output wrapper
1244
+ if (sparkGraph.isTypedOutput(value)) {
1245
+ return summarizeDeep(sparkGraph.getTypedOutputValue(value));
1246
+ }
1247
+ // Arrays
1248
+ if (Array.isArray(value)) {
1249
+ return value.map((v) => summarizeDeep(v));
1250
+ }
1251
+ // Objects
1252
+ if (value && typeof value === "object") {
1253
+ const obj = value;
1254
+ const out = {};
1255
+ for (const [k, v] of Object.entries(obj)) {
1256
+ // Special-case any 'url' field
1257
+ if (typeof v === "string" &&
1258
+ k.toLowerCase() === "url" &&
1259
+ v.startsWith("data:")) {
1260
+ out[k] = formatDataUrlAsLabel(v);
1261
+ continue;
1262
+ }
1263
+ out[k] = summarizeDeep(v);
1264
+ }
1265
+ return out;
1266
+ }
1267
+ return value;
1268
+ }
1269
+
1270
+ // Shared UI constants for node layout to keep mapping and rendering in sync
1271
+ const NODE_HEADER_HEIGHT_PX = 24;
1272
+ const NODE_ROW_HEIGHT_PX = 22;
1273
+
1274
+ function computeEffectiveHandles(node, registry) {
1275
+ const desc = registry.nodes.get(node.typeId);
1276
+ const resolved = node.resolvedHandles || {};
1277
+ const inputs = { ...desc?.inputs, ...resolved.inputs };
1278
+ const outputs = { ...desc?.outputs, ...resolved.outputs };
1279
+ const inputDefaults = { ...desc?.inputDefaults, ...resolved.inputDefaults };
1280
+ return { inputs, outputs, inputDefaults };
1281
+ }
1282
+ function countVisibleHandles(handles) {
1283
+ const inputIds = Object.keys(handles.inputs).filter((k) => !sparkGraph.isInputPrivate(handles.inputs, k));
1284
+ const outputIds = Object.keys(handles.outputs);
1285
+ return { inputsCount: inputIds.length, outputsCount: outputIds.length };
1286
+ }
1287
+ function estimateNodeSize(args) {
1288
+ const { node, registry, showValues, overrides } = args;
1289
+ const { inputs, outputs } = computeEffectiveHandles(node, registry);
1290
+ // Count only non-private inputs for rows on left
1291
+ const { inputsCount, outputsCount } = countVisibleHandles({
1292
+ inputs,
1293
+ outputs,
1294
+ });
1295
+ const rows = Math.max(inputsCount, outputsCount);
1296
+ const baseWidth = showValues ? 320 : 240;
1297
+ const width = overrides?.width ?? baseWidth;
1298
+ const height = overrides?.height ?? NODE_HEADER_HEIGHT_PX + rows * NODE_ROW_HEIGHT_PX;
1299
+ return { width, height, inputsCount, outputsCount, rowCount: rows };
1300
+ }
1301
+ function layoutNode(args) {
1302
+ const { node, registry, showValues, overrides } = args;
1303
+ const { inputs, outputs } = computeEffectiveHandles(node, registry);
1304
+ const inputOrder = Object.keys(inputs).filter((k) => !sparkGraph.isInputPrivate(inputs, k));
1305
+ const outputOrder = Object.keys(outputs);
1306
+ const { width, height } = estimateNodeSize({
1307
+ node,
1308
+ registry,
1309
+ showValues,
1310
+ overrides,
1311
+ });
1312
+ const HEADER = NODE_HEADER_HEIGHT_PX;
1313
+ const ROW = NODE_ROW_HEIGHT_PX;
1314
+ const handles = [
1315
+ ...inputOrder.map((id, i) => ({
1316
+ id,
1317
+ type: "target",
1318
+ position: react.Position.Left,
1319
+ x: 0,
1320
+ y: HEADER + i * ROW,
1321
+ width: 1,
1322
+ height: ROW + 2,
1323
+ })),
1324
+ ...outputOrder.map((id, i) => ({
1325
+ id,
1326
+ type: "source",
1327
+ position: react.Position.Right,
1328
+ x: width - 1,
1329
+ y: HEADER + i * ROW,
1330
+ width: 1,
1331
+ height: ROW + 2,
1332
+ })),
1333
+ ];
1334
+ const handleLayout = [
1335
+ ...inputOrder.map((id, i) => ({
1336
+ id,
1337
+ type: "target",
1338
+ position: react.Position.Left,
1339
+ y: HEADER + i * ROW + ROW / 2,
1340
+ })),
1341
+ ...outputOrder.map((id, i) => ({
1342
+ id,
1343
+ type: "source",
1344
+ position: react.Position.Right,
1345
+ y: HEADER + i * ROW + ROW / 2,
1346
+ })),
1347
+ ];
1348
+ return { width, height, inputOrder, outputOrder, handles, handleLayout };
1349
+ }
1350
+
1163
1351
  function useWorkbenchBridge(wb) {
1164
1352
  const onConnect = React.useCallback((params) => {
1165
1353
  if (!params.source || !params.target)
@@ -1404,202 +1592,6 @@ function useQueryParamString(key, defaultValue) {
1404
1592
  return [val, set];
1405
1593
  }
1406
1594
 
1407
- function formatDataUrlAsLabel(dataUrl) {
1408
- try {
1409
- const semi = dataUrl.indexOf(";");
1410
- const comma = dataUrl.indexOf(",");
1411
- const mime = dataUrl.slice(5, semi > 0 ? semi : undefined).toUpperCase();
1412
- const b64 = comma >= 0 ? dataUrl.slice(comma + 1) : "";
1413
- const bytes = Math.floor((b64.length * 3) / 4);
1414
- return `${mime} Data (${bytes} bytes)`;
1415
- }
1416
- catch {
1417
- return dataUrl.length > 64 ? dataUrl.slice(0, 64) + "…" : dataUrl;
1418
- }
1419
- }
1420
- function resolveOutputDisplay(raw, declared) {
1421
- if (sparkGraph.isTypedOutput(raw)) {
1422
- return {
1423
- typeId: sparkGraph.getTypedOutputTypeId(raw),
1424
- value: sparkGraph.getTypedOutputValue(raw),
1425
- };
1426
- }
1427
- let typeId = undefined;
1428
- if (Array.isArray(declared)) {
1429
- typeId = declared.length === 1 ? declared[0] : undefined;
1430
- }
1431
- else if (typeof declared === "string") {
1432
- typeId = declared.includes("|") ? undefined : declared;
1433
- }
1434
- return { typeId, value: raw };
1435
- }
1436
- function formatDeclaredTypeSignature(declared) {
1437
- if (Array.isArray(declared))
1438
- return declared.join(" | ");
1439
- return declared ?? "";
1440
- }
1441
- /**
1442
- * Formats a handle ID for display in the UI.
1443
- * For handles with format "prefix:middle:suffix:extra" (4 parts), displays only the middle part.
1444
- * Otherwise returns the handle ID as-is.
1445
- */
1446
- function prettyHandle(id) {
1447
- try {
1448
- const parts = String(id).split(":");
1449
- // If there are exactly 3 colons (4 parts), display only the second part
1450
- if (parts.length === 4)
1451
- return parts[1] || id;
1452
- return id;
1453
- }
1454
- catch {
1455
- return id;
1456
- }
1457
- }
1458
- // Pre-format common structures for display; return undefined to defer to caller
1459
- function preformatValueForDisplay(typeId, value, registry) {
1460
- if (value === undefined || value === null)
1461
- return "";
1462
- // Unwrap typed outputs
1463
- if (sparkGraph.isTypedOutput(value)) {
1464
- return preformatValueForDisplay(sparkGraph.getTypedOutputTypeId(value), sparkGraph.getTypedOutputValue(value), registry);
1465
- }
1466
- // Enums
1467
- if (typeId && typeId.startsWith("enum:") && registry) {
1468
- const n = Number(value);
1469
- const label = registry.enums.get(typeId)?.valueToLabel.get(n);
1470
- if (label)
1471
- return label;
1472
- }
1473
- // Use deep summarization for strings, arrays and nested objects to avoid huge HTML payloads
1474
- const summarized = summarizeDeep(value);
1475
- if (typeof summarized === "string")
1476
- return summarized;
1477
- // Resource-like objects with url/title (after summarization)
1478
- if (summarized && typeof summarized === "object") {
1479
- const urlMaybe = summarized.url;
1480
- if (typeof urlMaybe === "string") {
1481
- const title = summarized.title || "";
1482
- const shortUrl = urlMaybe.length > 32 ? urlMaybe.slice(0, 32) + "…" : urlMaybe;
1483
- return title ? `${title} (${shortUrl})` : shortUrl;
1484
- }
1485
- }
1486
- return undefined;
1487
- }
1488
- function summarizeDeep(value) {
1489
- // Strings: summarize data URLs and trim extremely long strings
1490
- if (typeof value === "string") {
1491
- if (value.startsWith("data:"))
1492
- return formatDataUrlAsLabel(value);
1493
- return value.length > 512 ? value.slice(0, 512) + "…" : value;
1494
- }
1495
- // Typed output wrapper
1496
- if (sparkGraph.isTypedOutput(value)) {
1497
- return summarizeDeep(sparkGraph.getTypedOutputValue(value));
1498
- }
1499
- // Arrays
1500
- if (Array.isArray(value)) {
1501
- return value.map((v) => summarizeDeep(v));
1502
- }
1503
- // Objects
1504
- if (value && typeof value === "object") {
1505
- const obj = value;
1506
- const out = {};
1507
- for (const [k, v] of Object.entries(obj)) {
1508
- // Special-case any 'url' field
1509
- if (typeof v === "string" &&
1510
- k.toLowerCase() === "url" &&
1511
- v.startsWith("data:")) {
1512
- out[k] = formatDataUrlAsLabel(v);
1513
- continue;
1514
- }
1515
- out[k] = summarizeDeep(v);
1516
- }
1517
- return out;
1518
- }
1519
- return value;
1520
- }
1521
-
1522
- // Shared UI constants for node layout to keep mapping and rendering in sync
1523
- const NODE_HEADER_HEIGHT_PX = 24;
1524
- const NODE_ROW_HEIGHT_PX = 22;
1525
-
1526
- function computeEffectiveHandles(node, registry) {
1527
- const desc = registry.nodes.get(node.typeId);
1528
- const resolved = node.resolvedHandles || {};
1529
- const inputs = { ...desc?.inputs, ...resolved.inputs };
1530
- const outputs = { ...desc?.outputs, ...resolved.outputs };
1531
- const inputDefaults = { ...desc?.inputDefaults, ...resolved.inputDefaults };
1532
- return { inputs, outputs, inputDefaults };
1533
- }
1534
- function countVisibleHandles(handles) {
1535
- const inputIds = Object.keys(handles.inputs).filter((k) => !sparkGraph.isInputPrivate(handles.inputs, k));
1536
- const outputIds = Object.keys(handles.outputs);
1537
- return { inputsCount: inputIds.length, outputsCount: outputIds.length };
1538
- }
1539
- function estimateNodeSize(args) {
1540
- const { node, registry, showValues, overrides } = args;
1541
- const { inputs, outputs } = computeEffectiveHandles(node, registry);
1542
- // Count only non-private inputs for rows on left
1543
- const { inputsCount, outputsCount } = countVisibleHandles({
1544
- inputs,
1545
- outputs,
1546
- });
1547
- const rows = Math.max(inputsCount, outputsCount);
1548
- const baseWidth = showValues ? 320 : 240;
1549
- const width = overrides?.width ?? baseWidth;
1550
- const height = overrides?.height ?? NODE_HEADER_HEIGHT_PX + rows * NODE_ROW_HEIGHT_PX;
1551
- return { width, height, inputsCount, outputsCount, rowCount: rows };
1552
- }
1553
- function layoutNode(args) {
1554
- const { node, registry, showValues, overrides } = args;
1555
- const { inputs, outputs } = computeEffectiveHandles(node, registry);
1556
- const inputOrder = Object.keys(inputs).filter((k) => !sparkGraph.isInputPrivate(inputs, k));
1557
- const outputOrder = Object.keys(outputs);
1558
- const { width, height } = estimateNodeSize({
1559
- node,
1560
- registry,
1561
- showValues,
1562
- overrides,
1563
- });
1564
- const HEADER = NODE_HEADER_HEIGHT_PX;
1565
- const ROW = NODE_ROW_HEIGHT_PX;
1566
- const handles = [
1567
- ...inputOrder.map((id, i) => ({
1568
- id,
1569
- type: "target",
1570
- position: react.Position.Left,
1571
- x: 0,
1572
- y: HEADER + i * ROW,
1573
- width: 1,
1574
- height: ROW + 2,
1575
- })),
1576
- ...outputOrder.map((id, i) => ({
1577
- id,
1578
- type: "source",
1579
- position: react.Position.Right,
1580
- x: width - 1,
1581
- y: HEADER + i * ROW,
1582
- width: 1,
1583
- height: ROW + 2,
1584
- })),
1585
- ];
1586
- const handleLayout = [
1587
- ...inputOrder.map((id, i) => ({
1588
- id,
1589
- type: "target",
1590
- position: react.Position.Left,
1591
- y: HEADER + i * ROW + ROW / 2,
1592
- })),
1593
- ...outputOrder.map((id, i) => ({
1594
- id,
1595
- type: "source",
1596
- position: react.Position.Right,
1597
- y: HEADER + i * ROW + ROW / 2,
1598
- })),
1599
- ];
1600
- return { width, height, inputOrder, outputOrder, handles, handleLayout };
1601
- }
1602
-
1603
1595
  function toReactFlow(def, positions, registry, opts) {
1604
1596
  const EDGE_STYLE_MISSING = { stroke: "#f59e0b", strokeWidth: 2 }; // amber-500
1605
1597
  const EDGE_STYLE_ERROR = { stroke: "#ef4444", strokeWidth: 2 };