@octaviaflow/core 3.0.18-beta.10 → 3.0.18-beta.12

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.
Files changed (58) hide show
  1. package/dist/chunk-5ARKSRED.js +2951 -0
  2. package/dist/chunk-5ARKSRED.js.map +1 -0
  3. package/dist/chunk-5OSGSJMM.js +2981 -0
  4. package/dist/chunk-5OSGSJMM.js.map +1 -0
  5. package/dist/chunk-5YQQMEF3.js +2981 -0
  6. package/dist/chunk-5YQQMEF3.js.map +1 -0
  7. package/dist/chunk-6QCJK7H7.js +2991 -0
  8. package/dist/chunk-6QCJK7H7.js.map +1 -0
  9. package/dist/chunk-76TP67ED.js +2984 -0
  10. package/dist/chunk-76TP67ED.js.map +1 -0
  11. package/dist/chunk-A6KMO4JV.js +2949 -0
  12. package/dist/chunk-A6KMO4JV.js.map +1 -0
  13. package/dist/chunk-B7FTWSTM.js +2938 -0
  14. package/dist/chunk-B7FTWSTM.js.map +1 -0
  15. package/dist/chunk-BCO6M26F.js +2940 -0
  16. package/dist/chunk-BCO6M26F.js.map +1 -0
  17. package/dist/chunk-ECIHUVU7.js +2986 -0
  18. package/dist/chunk-ECIHUVU7.js.map +1 -0
  19. package/dist/chunk-HDOTOZNA.js +2936 -0
  20. package/dist/chunk-HDOTOZNA.js.map +1 -0
  21. package/dist/chunk-IUIICQU5.js +2946 -0
  22. package/dist/chunk-IUIICQU5.js.map +1 -0
  23. package/dist/chunk-J2UYZI6D.js +2946 -0
  24. package/dist/chunk-J2UYZI6D.js.map +1 -0
  25. package/dist/chunk-K2H7JLQW.js +2952 -0
  26. package/dist/chunk-K2H7JLQW.js.map +1 -0
  27. package/dist/chunk-KUXYBP66.js +2953 -0
  28. package/dist/chunk-KUXYBP66.js.map +1 -0
  29. package/dist/chunk-MMXL343D.js +2974 -0
  30. package/dist/chunk-MMXL343D.js.map +1 -0
  31. package/dist/chunk-MXJL3EPE.js +2986 -0
  32. package/dist/chunk-MXJL3EPE.js.map +1 -0
  33. package/dist/chunk-NTMEYB7B.js +2949 -0
  34. package/dist/chunk-NTMEYB7B.js.map +1 -0
  35. package/dist/chunk-Q6ERDPQR.js +2981 -0
  36. package/dist/chunk-Q6ERDPQR.js.map +1 -0
  37. package/dist/chunk-SLVDAZSX.js +2946 -0
  38. package/dist/chunk-SLVDAZSX.js.map +1 -0
  39. package/dist/chunk-UQBPYONV.js +2991 -0
  40. package/dist/chunk-UQBPYONV.js.map +1 -0
  41. package/dist/chunk-UXMNBS22.js +2955 -0
  42. package/dist/chunk-UXMNBS22.js.map +1 -0
  43. package/dist/chunk-ZRAM6FXB.js +2949 -0
  44. package/dist/chunk-ZRAM6FXB.js.map +1 -0
  45. package/dist/index.cjs +109 -54
  46. package/dist/index.cjs.map +1 -1
  47. package/dist/index.js +1 -1
  48. package/dist/workflow/components/FlowCanvas/FlowCanvas.d.ts +8 -0
  49. package/dist/workflow/components/FlowCanvas/FlowCanvas.d.ts.map +1 -1
  50. package/dist/workflow/components/Handle/Handle.d.ts.map +1 -1
  51. package/dist/workflow/components/Handle/handleRegistry.d.ts +9 -0
  52. package/dist/workflow/components/Handle/handleRegistry.d.ts.map +1 -1
  53. package/dist/workflow/utils/parenting.d.ts +5 -3
  54. package/dist/workflow/utils/parenting.d.ts.map +1 -1
  55. package/dist/workflow.cjs +109 -54
  56. package/dist/workflow.cjs.map +1 -1
  57. package/dist/workflow.js +1 -1
  58. package/package.json +1 -1
package/dist/index.cjs CHANGED
@@ -29749,7 +29749,7 @@ function findContainingGroup(point, nodes, exclude = []) {
29749
29749
  for (let i = nodes.length - 1; i >= 0; i--) {
29750
29750
  const n = nodes[i];
29751
29751
  if (exclude.includes(n.id)) continue;
29752
- if (n.type !== "group") continue;
29752
+ if (n.type !== "group" && n.type !== "forEach") continue;
29753
29753
  if (n.data && typeof n.data === "object" && n.data.collapsed) {
29754
29754
  continue;
29755
29755
  }
@@ -29797,6 +29797,9 @@ function createHandleRegistry() {
29797
29797
  resolve(nodeId, type, handleId) {
29798
29798
  return map.get(key(nodeId, type, handleId));
29799
29799
  },
29800
+ all() {
29801
+ return Array.from(map.values());
29802
+ },
29800
29803
  subscribe(listener) {
29801
29804
  listeners.add(listener);
29802
29805
  return () => {
@@ -30192,10 +30195,12 @@ function Handle({
30192
30195
  type,
30193
30196
  side: position,
30194
30197
  index,
30195
- total
30198
+ total,
30199
+ canStart,
30200
+ canEnd
30196
30201
  });
30197
30202
  return dispose;
30198
- }, [registry, node.id, id, type, position, index, total]);
30203
+ }, [registry, node.id, id, type, position, index, total, canStart, canEnd]);
30199
30204
  const handlePointerDown = (e) => {
30200
30205
  if (!canStart) return;
30201
30206
  e.stopPropagation();
@@ -30920,6 +30925,8 @@ function FlowCanvas2(props) {
30920
30925
  reparentOnDrag = false,
30921
30926
  autoResizeContainers = false,
30922
30927
  containerAutoResizePadding = 32,
30928
+ containerMinWidth = 320,
30929
+ containerMinHeight = 200,
30923
30930
  height = "100%",
30924
30931
  width = "100%",
30925
30932
  className,
@@ -31056,7 +31063,9 @@ function FlowCanvas2(props) {
31056
31063
  id: d.id,
31057
31064
  startPosition: d.position
31058
31065
  }));
31059
- const wantsReparent = altKey || reparentOnDragRef.current;
31066
+ const evaluateReparent = altKey || reparentOnDragRef.current;
31067
+ const hasParent = !!node.parentId;
31068
+ const skipClamp = altKey || reparentOnDragRef.current && !hasParent;
31060
31069
  dragRef.current = {
31061
31070
  pointerId,
31062
31071
  nodeId,
@@ -31064,7 +31073,8 @@ function FlowCanvas2(props) {
31064
31073
  startClientY: clientY,
31065
31074
  startPosition: node.position,
31066
31075
  descendants: kids,
31067
- altDetach: wantsReparent,
31076
+ skipClamp,
31077
+ evaluateReparent,
31068
31078
  rafScheduled: false,
31069
31079
  nextDelta: null
31070
31080
  };
@@ -31124,6 +31134,8 @@ function FlowCanvas2(props) {
31124
31134
  const reparentOnDragRef = (0, import_react154.useRef)(reparentOnDrag);
31125
31135
  const autoResizeContainersRef = (0, import_react154.useRef)(autoResizeContainers);
31126
31136
  const containerAutoResizePaddingRef = (0, import_react154.useRef)(containerAutoResizePadding);
31137
+ const containerMinWidthRef = (0, import_react154.useRef)(containerMinWidth);
31138
+ const containerMinHeightRef = (0, import_react154.useRef)(containerMinHeight);
31127
31139
  (0, import_react154.useEffect)(() => {
31128
31140
  edgesRef.current = edges;
31129
31141
  }, [edges]);
@@ -31157,6 +31169,12 @@ function FlowCanvas2(props) {
31157
31169
  (0, import_react154.useEffect)(() => {
31158
31170
  containerAutoResizePaddingRef.current = containerAutoResizePadding;
31159
31171
  }, [containerAutoResizePadding]);
31172
+ (0, import_react154.useEffect)(() => {
31173
+ containerMinWidthRef.current = containerMinWidth;
31174
+ }, [containerMinWidth]);
31175
+ (0, import_react154.useEffect)(() => {
31176
+ containerMinHeightRef.current = containerMinHeight;
31177
+ }, [containerMinHeight]);
31160
31178
  const onNodesChangeRef = (0, import_react154.useRef)(onNodesChange);
31161
31179
  const onConnectRef = (0, import_react154.useRef)(onConnect);
31162
31180
  const onConnectEndRef = (0, import_react154.useRef)(onConnectEnd);
@@ -31201,7 +31219,7 @@ function FlowCanvas2(props) {
31201
31219
  x: d.startPosition.x + delta.dx,
31202
31220
  y: d.startPosition.y + delta.dy
31203
31221
  };
31204
- const clamped = d.altDetach ? proposed : clampToParentExtent(dragNode, proposed, nodesRef.current);
31222
+ const clamped = d.skipClamp ? proposed : clampToParentExtent(dragNode, proposed, nodesRef.current);
31205
31223
  const isContainer = dragNode.type === "group" || dragNode.type === "forEach";
31206
31224
  const gap = isContainer ? subflowCollisionGapRef.current : nodeCollisionGapRef.current;
31207
31225
  const excludeIds = /* @__PURE__ */ new Set([d.nodeId, ...d.descendants.map((kid) => kid.id)]);
@@ -31253,7 +31271,7 @@ function FlowCanvas2(props) {
31253
31271
  y: Math.round(proposed.y / g) * g
31254
31272
  };
31255
31273
  }
31256
- const clamped = drag.altDetach ? proposed : clampToParentExtent(dragNode, proposed, nodesRef.current);
31274
+ const clamped = drag.skipClamp ? proposed : clampToParentExtent(dragNode, proposed, nodesRef.current);
31257
31275
  const isContainer = dragNode.type === "group" || dragNode.type === "forEach";
31258
31276
  const gap = isContainer ? subflowCollisionGapRef.current : nodeCollisionGapRef.current;
31259
31277
  const excludeIds = /* @__PURE__ */ new Set([
@@ -31276,7 +31294,7 @@ function FlowCanvas2(props) {
31276
31294
  )
31277
31295
  );
31278
31296
  }
31279
- if (drag.altDetach) {
31297
+ if (drag.evaluateReparent) {
31280
31298
  const targetGroup = findContainingGroup(
31281
31299
  {
31282
31300
  x: finalPos.x + (dragNode.width ?? 0) / 2,
@@ -31291,8 +31309,10 @@ function FlowCanvas2(props) {
31291
31309
  ...dragNode,
31292
31310
  position: finalPos,
31293
31311
  parentId: nextParentId,
31294
- // Preserve extent only when staying in a group.
31295
- extent: nextParentId ? dragNode.extent : void 0
31312
+ // Adopting into a container always pins the child with
31313
+ // `extent: 'parent'` so it's clamped from the next drag
31314
+ // on. Detaching clears it.
31315
+ extent: nextParentId ? "parent" : void 0
31296
31316
  };
31297
31317
  changes.push(change.node.replace(drag.nodeId, updated));
31298
31318
  }
@@ -31303,7 +31323,9 @@ function FlowCanvas2(props) {
31303
31323
  // Projected children: apply the position + reparent
31304
31324
  // changes we just built before measuring bboxes.
31305
31325
  changes,
31306
- containerAutoResizePaddingRef.current
31326
+ containerAutoResizePaddingRef.current,
31327
+ containerMinWidthRef.current,
31328
+ containerMinHeightRef.current
31307
31329
  );
31308
31330
  for (const c2 of containerChanges) changes.push(c2);
31309
31331
  }
@@ -31314,49 +31336,54 @@ function FlowCanvas2(props) {
31314
31336
  }
31315
31337
  const c = connRef.current;
31316
31338
  if (c && c.pointerId === e.pointerId) {
31317
- let handleEl = null;
31318
- if (typeof document !== "undefined") {
31319
- const stack = document.elementsFromPoint(e.clientX, e.clientY);
31320
- for (const el of stack) {
31321
- const candidate = el.closest(
31322
- "[data-handle-id]"
31323
- );
31324
- if (!candidate) continue;
31325
- if (candidate.dataset.handleNodeId === c.from.nodeId) continue;
31326
- handleEl = candidate;
31327
- break;
31339
+ const rect = containerRef.current?.getBoundingClientRect();
31340
+ const flowPos = rect ? screenToFlow({ x: e.clientX - rect.left, y: e.clientY - rect.top }, vp) : { x: 0, y: 0 };
31341
+ const snapRadius = 26 / Math.max(0.1, vp.zoom);
31342
+ let bestDesc = null;
31343
+ let bestDist = snapRadius;
31344
+ for (const desc of handleRegistry.all()) {
31345
+ if (desc.nodeId === c.from.nodeId) continue;
31346
+ if (desc.type === c.from.handleType) continue;
31347
+ if (!desc.canEnd) continue;
31348
+ const targetNode = nodesRef.current.find((n) => n.id === desc.nodeId);
31349
+ if (!targetNode || targetNode.hidden) continue;
31350
+ const centre = handleCentre(targetNode, desc.side, desc.index, desc.total);
31351
+ const dist = Math.hypot(centre.x - flowPos.x, centre.y - flowPos.y);
31352
+ if (dist < bestDist) {
31353
+ bestDist = dist;
31354
+ bestDesc = desc;
31328
31355
  }
31329
31356
  }
31330
31357
  let connection = null;
31331
31358
  let connectedTo;
31332
- if (handleEl) {
31333
- const targetNodeId = handleEl.dataset.handleNodeId;
31334
- const targetHandleId = handleEl.dataset.handleId;
31335
- const targetType = handleEl.dataset.handleType;
31336
- const connectableEnd = handleEl.dataset.handleConnectableEnd === "true";
31337
- if (connectableEnd && (targetNodeId !== c.from.nodeId || targetHandleId !== c.from.handleId) && targetType !== c.from.handleType) {
31338
- const source = c.from.handleType === "source" ? c.from : { nodeId: targetNodeId, handleId: targetHandleId, handleType: "source" };
31339
- const target2 = c.from.handleType === "target" ? c.from : { nodeId: targetNodeId, handleId: targetHandleId, handleType: "target" };
31340
- connection = {
31341
- source: source.nodeId,
31342
- sourceHandle: source.handleId,
31343
- target: target2.nodeId,
31344
- targetHandle: target2.handleId
31345
- };
31346
- connectedTo = {
31347
- nodeId: targetNodeId,
31348
- handleId: targetHandleId,
31349
- handleType: targetType
31350
- };
31351
- const validator = isValidConnectionRef.current;
31352
- if (validator && !validator(connection)) {
31353
- connection = null;
31354
- connectedTo = void 0;
31355
- }
31359
+ if (bestDesc) {
31360
+ const source = c.from.handleType === "source" ? c.from : {
31361
+ nodeId: bestDesc.nodeId,
31362
+ handleId: bestDesc.handleId,
31363
+ handleType: "source"
31364
+ };
31365
+ const target2 = c.from.handleType === "target" ? c.from : {
31366
+ nodeId: bestDesc.nodeId,
31367
+ handleId: bestDesc.handleId,
31368
+ handleType: "target"
31369
+ };
31370
+ connection = {
31371
+ source: source.nodeId,
31372
+ sourceHandle: source.handleId,
31373
+ target: target2.nodeId,
31374
+ targetHandle: target2.handleId
31375
+ };
31376
+ connectedTo = {
31377
+ nodeId: bestDesc.nodeId,
31378
+ handleId: bestDesc.handleId,
31379
+ handleType: bestDesc.type
31380
+ };
31381
+ const validator = isValidConnectionRef.current;
31382
+ if (validator && !validator(connection)) {
31383
+ connection = null;
31384
+ connectedTo = void 0;
31356
31385
  }
31357
31386
  }
31358
- const rect = containerRef.current?.getBoundingClientRect();
31359
- const flowPos = rect ? screenToFlow({ x: e.clientX - rect.left, y: e.clientY - rect.top }, vp) : { x: 0, y: 0 };
31360
31387
  const endState = {
31361
31388
  cancelled: !connection,
31362
31389
  position: { x: e.clientX, y: e.clientY },
@@ -31389,6 +31416,25 @@ function FlowCanvas2(props) {
31389
31416
  window.removeEventListener("pointercancel", onPointerCancel);
31390
31417
  };
31391
31418
  }, [store]);
31419
+ (0, import_react154.useEffect)(() => {
31420
+ if (!autoResizeContainers || draggingId) return;
31421
+ const resizeChanges = computeContainerAutoResize(
31422
+ nodes,
31423
+ [],
31424
+ containerAutoResizePadding,
31425
+ containerMinWidth,
31426
+ containerMinHeight
31427
+ );
31428
+ if (resizeChanges.length > 0) onNodesChange?.(resizeChanges);
31429
+ }, [
31430
+ nodes,
31431
+ draggingId,
31432
+ autoResizeContainers,
31433
+ containerAutoResizePadding,
31434
+ containerMinWidth,
31435
+ containerMinHeight,
31436
+ onNodesChange
31437
+ ]);
31392
31438
  const panRef = (0, import_react154.useRef)(null);
31393
31439
  const onCanvasPointerDown = (e) => {
31394
31440
  if (e.button !== 0) return;
@@ -31851,7 +31897,9 @@ function FlowCanvas2(props) {
31851
31897
  function onEdgesChangeRef(id, cb) {
31852
31898
  cb?.([change.edge.remove(id)]);
31853
31899
  }
31854
- function computeContainerAutoResize(nodes, pending, padding) {
31900
+ var CONTAINER_DROP_HEADROOM_W = 220;
31901
+ var CONTAINER_DROP_HEADROOM_H = 2 * 128;
31902
+ function computeContainerAutoResize(nodes, pending, padding, minWidth, minHeight) {
31855
31903
  const projected = /* @__PURE__ */ new Map();
31856
31904
  for (const n of nodes) projected.set(n.id, n);
31857
31905
  for (const c of pending) {
@@ -31872,7 +31920,14 @@ function computeContainerAutoResize(nodes, pending, padding) {
31872
31920
  for (const n of projected.values()) {
31873
31921
  if (n.parentId === parent.id) children.push(n);
31874
31922
  }
31875
- if (children.length === 0) continue;
31923
+ if (children.length === 0) {
31924
+ const curW2 = parent.width ?? 480;
31925
+ const curH2 = parent.height ?? 240;
31926
+ if (curW2 !== minWidth || curH2 !== minHeight) {
31927
+ out.push(change.node.dimensions(parent.id, { width: minWidth, height: minHeight }));
31928
+ }
31929
+ continue;
31930
+ }
31876
31931
  let minX = Number.POSITIVE_INFINITY;
31877
31932
  let minY = Number.POSITIVE_INFINITY;
31878
31933
  let maxX = Number.NEGATIVE_INFINITY;
@@ -31887,12 +31942,12 @@ function computeContainerAutoResize(nodes, pending, padding) {
31887
31942
  }
31888
31943
  const targetX = minX - padding;
31889
31944
  const targetY = minY - padding - HEADER;
31890
- const targetW = maxX - minX + padding * 2;
31891
- const targetH = maxY - minY + padding * 2 + HEADER;
31892
31945
  const curW = parent.width ?? 480;
31893
31946
  const curH = parent.height ?? 240;
31894
- const nextW = Math.max(curW, targetW);
31895
- const nextH = Math.max(curH, targetH);
31947
+ const fitW = maxX - minX + padding * 2 + CONTAINER_DROP_HEADROOM_W;
31948
+ const fitH = maxY - minY + padding * 2 + HEADER + CONTAINER_DROP_HEADROOM_H;
31949
+ const nextW = Math.max(minWidth, fitW);
31950
+ const nextH = Math.max(minHeight, fitH);
31896
31951
  const positionDirty = parent.position.x !== targetX || parent.position.y !== targetY;
31897
31952
  const sizeDirty = curW !== nextW || curH !== nextH;
31898
31953
  if (positionDirty) {