@octaviaflow/core 3.0.18-beta.2 → 3.0.18-beta.3

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/dist/index.js CHANGED
@@ -11905,7 +11905,7 @@ Drawer.displayName = "Drawer";
11905
11905
 
11906
11906
  // src/components/DropdownMenu/DropdownMenu.tsx
11907
11907
  import { AnimatePresence as AnimatePresence13, motion as motion18 } from "framer-motion";
11908
- import { useEffect as useEffect17, useRef as useRef22 } from "react";
11908
+ import { useEffect as useEffect17, useMemo as useMemo13, useRef as useRef22 } from "react";
11909
11909
  import { useButton as useButton4, useMenu, useMenuItem, useMenuTrigger } from "react-aria";
11910
11910
  import { createPortal as createPortal8 } from "react-dom";
11911
11911
  import { Fragment as Fragment21, jsx as jsx41, jsxs as jsxs40 } from "react/jsx-runtime";
@@ -11980,14 +11980,36 @@ function MenuPopup({
11980
11980
  nonSepItems[idx]?.onClick?.();
11981
11981
  state.close();
11982
11982
  };
11983
+ const ESTIMATED_ITEM_H = 34;
11984
+ const ESTIMATED_SEPARATOR_H = 9;
11985
+ const POPUP_PADDING_V = 8;
11986
+ const VIEWPORT_MARGIN = 8;
11987
+ const estimatedHeight = useMemo13(() => {
11988
+ const itemsTotal = menuItems.reduce(
11989
+ (acc, item) => acc + (item.separator ? ESTIMATED_SEPARATOR_H : ESTIMATED_ITEM_H),
11990
+ 0
11991
+ );
11992
+ return itemsTotal + POPUP_PADDING_V * 2;
11993
+ }, [menuItems]);
11983
11994
  const getStyle = () => {
11984
11995
  if (!triggerRef.current) return {};
11985
11996
  const rect = triggerRef.current.getBoundingClientRect();
11997
+ const viewportH = window.innerHeight;
11998
+ const spaceBelow = viewportH - rect.bottom;
11999
+ const spaceAbove = rect.top;
12000
+ const openUp = spaceBelow < estimatedHeight && spaceAbove > spaceBelow;
11986
12001
  const style = {
11987
12002
  position: "fixed",
11988
12003
  zIndex: 1200,
11989
- top: rect.bottom + 4
12004
+ // Cap the menu so it never spills beyond the viewport — pairs
12005
+ // with overflow-y:auto on the popup itself (set in CSS).
12006
+ maxHeight: Math.max(120, (openUp ? spaceAbove : spaceBelow) - VIEWPORT_MARGIN)
11990
12007
  };
12008
+ if (openUp) {
12009
+ style.bottom = viewportH - rect.top + 4;
12010
+ } else {
12011
+ style.top = rect.bottom + 4;
12012
+ }
11991
12013
  if (align === "end") {
11992
12014
  style.right = window.innerWidth - rect.right;
11993
12015
  } else {
@@ -12130,7 +12152,7 @@ EmptyState.displayName = "EmptyState";
12130
12152
 
12131
12153
  // src/components/ExecutionConsole/ExecutionConsole.tsx
12132
12154
  import { motion as motion19 } from "framer-motion";
12133
- import { useEffect as useEffect18, useMemo as useMemo13, useRef as useRef23, useState as useState20 } from "react";
12155
+ import { useEffect as useEffect18, useMemo as useMemo14, useRef as useRef23, useState as useState20 } from "react";
12134
12156
  import { Fragment as Fragment22, jsx as jsx43, jsxs as jsxs42 } from "react/jsx-runtime";
12135
12157
  var iconProps = {
12136
12158
  xmlns: "http://www.w3.org/2000/svg",
@@ -12202,7 +12224,7 @@ function ExecutionConsole({
12202
12224
  const [autoScroll, setAutoScroll] = useState20(true);
12203
12225
  const [expandedLines, setExpandedLines] = useState20(/* @__PURE__ */ new Set());
12204
12226
  const [exportMenuOpen, setExportMenuOpen] = useState20(false);
12205
- const nodeOptions = useMemo13(() => {
12227
+ const nodeOptions = useMemo14(() => {
12206
12228
  const seen = /* @__PURE__ */ new Map();
12207
12229
  for (const log of logs) {
12208
12230
  if (log.nodeId && !seen.has(log.nodeId)) {
@@ -12211,7 +12233,7 @@ function ExecutionConsole({
12211
12233
  }
12212
12234
  return Array.from(seen.entries()).map(([id, label]) => ({ id, label }));
12213
12235
  }, [logs]);
12214
- const filteredLogs = useMemo13(() => {
12236
+ const filteredLogs = useMemo14(() => {
12215
12237
  const q2 = query.trim().toLowerCase();
12216
12238
  return logs.filter((log) => {
12217
12239
  if (!activeLevels.has(log.level)) return false;
@@ -12283,7 +12305,7 @@ function ExecutionConsole({
12283
12305
  document.body.removeChild(a);
12284
12306
  URL.revokeObjectURL(url);
12285
12307
  };
12286
- const levelCounts = useMemo13(() => {
12308
+ const levelCounts = useMemo14(() => {
12287
12309
  const counts = {
12288
12310
  info: 0,
12289
12311
  warn: 0,
@@ -13833,7 +13855,7 @@ function FlowCanvas2({
13833
13855
  import {
13834
13856
  useCallback as useCallback20,
13835
13857
  useEffect as useEffect21,
13836
- useMemo as useMemo14,
13858
+ useMemo as useMemo15,
13837
13859
  useRef as useRef27,
13838
13860
  useState as useState24
13839
13861
  } from "react";
@@ -13852,7 +13874,7 @@ function FlowMinimap({
13852
13874
  }) {
13853
13875
  const scaleX = MINIMAP_WIDTH / totalWidth;
13854
13876
  const scaleY = MINIMAP_HEIGHT / totalHeight;
13855
- const scaledNodes = useMemo14(
13877
+ const scaledNodes = useMemo15(
13856
13878
  () => nodes.map((n) => ({
13857
13879
  ...n,
13858
13880
  sx: n.x * scaleX,
@@ -13862,7 +13884,7 @@ function FlowMinimap({
13862
13884
  })),
13863
13885
  [nodes, scaleX, scaleY]
13864
13886
  );
13865
- const scaledEdges = useMemo14(
13887
+ const scaledEdges = useMemo15(
13866
13888
  () => edges.map((e) => ({
13867
13889
  x1: e.from.x * scaleX,
13868
13890
  y1: e.from.y * scaleY,
@@ -13871,7 +13893,7 @@ function FlowMinimap({
13871
13893
  })),
13872
13894
  [edges, scaleX, scaleY]
13873
13895
  );
13874
- const scaledViewport = useMemo14(() => {
13896
+ const scaledViewport = useMemo15(() => {
13875
13897
  if (!viewportRect) return null;
13876
13898
  return {
13877
13899
  x: viewportRect.x * scaleX,
@@ -14546,7 +14568,7 @@ import { motion as motion21 } from "framer-motion";
14546
14568
  import {
14547
14569
  forwardRef as forwardRef43,
14548
14570
  useId as useId24,
14549
- useMemo as useMemo15
14571
+ useMemo as useMemo16
14550
14572
  } from "react";
14551
14573
  import { jsx as jsx53, jsxs as jsxs51 } from "react/jsx-runtime";
14552
14574
  var defaultFormat3 = (n) => {
@@ -14585,7 +14607,7 @@ var Gauge = forwardRef43(function Gauge2({
14585
14607
  const clamped = Math.max(min, Math.min(max, value));
14586
14608
  const pct = (clamped - min) / Math.max(1e-6, max - min);
14587
14609
  const fillColor = resolveBandColor(clamped, bands, color);
14588
- const resolvedAriaLabel = useMemo15(() => {
14610
+ const resolvedAriaLabel = useMemo16(() => {
14589
14611
  if (ariaLabel) return ariaLabel;
14590
14612
  const t = typeof title === "string" ? title : "Gauge";
14591
14613
  return `${t} \u2014 ${formatValue(clamped)} of ${formatValue(max)}`;
@@ -14932,7 +14954,7 @@ import {
14932
14954
  forwardRef as forwardRef45,
14933
14955
  useCallback as useCallback21,
14934
14956
  useId as useId25,
14935
- useMemo as useMemo16,
14957
+ useMemo as useMemo17,
14936
14958
  useState as useState26
14937
14959
  } from "react";
14938
14960
  import { jsx as jsx55, jsxs as jsxs52 } from "react/jsx-runtime";
@@ -14985,24 +15007,24 @@ var Heatmap = forwardRef45(
14985
15007
  ...rest
14986
15008
  }, ref) {
14987
15009
  const reactId = useId25();
14988
- const xs = useMemo16(() => {
15010
+ const xs = useMemo17(() => {
14989
15011
  if (xLabels) return xLabels;
14990
15012
  return Array.from(new Set(data.map((d) => d.x)));
14991
15013
  }, [xLabels, data]);
14992
- const ys = useMemo16(() => {
15014
+ const ys = useMemo17(() => {
14993
15015
  if (yLabels) return yLabels;
14994
15016
  return Array.from(new Set(data.map((d) => d.y)));
14995
15017
  }, [yLabels, data]);
14996
- const cellMap = useMemo16(() => {
15018
+ const cellMap = useMemo17(() => {
14997
15019
  const m = /* @__PURE__ */ new Map();
14998
15020
  for (const c of data) m.set(`${c.x}|${c.y}`, c);
14999
15021
  return m;
15000
15022
  }, [data]);
15001
- const vMin = useMemo16(
15023
+ const vMin = useMemo17(
15002
15024
  () => domainMin ?? (data.length ? Math.min(...data.map((d) => d.value)) : 0),
15003
15025
  [domainMin, data]
15004
15026
  );
15005
- const vMax = useMemo16(
15027
+ const vMax = useMemo17(
15006
15028
  () => domainMax ?? (data.length ? Math.max(...data.map((d) => d.value)) : 1),
15007
15029
  [domainMax, data]
15008
15030
  );
@@ -15024,7 +15046,7 @@ var Heatmap = forwardRef45(
15024
15046
  },
15025
15047
  [onCellClick]
15026
15048
  );
15027
- const resolvedAriaLabel = useMemo16(() => {
15049
+ const resolvedAriaLabel = useMemo17(() => {
15028
15050
  if (ariaLabel) return ariaLabel;
15029
15051
  const t = typeof title === "string" ? title : "Heatmap";
15030
15052
  return `${t} \u2014 ${xs.length}\xD7${ys.length} grid, ${data.length} cells, range ${formatValue(vMin)} to ${formatValue(vMax)}`;
@@ -15814,7 +15836,7 @@ IntegrationCard.displayName = "IntegrationCard";
15814
15836
  import { CheckmarkIcon as CheckmarkIcon6, ChevronRightIcon as ChevronRightIcon3, CopyIcon as CopyIcon3 } from "@octaviaflow/icons";
15815
15837
  import {
15816
15838
  forwardRef as forwardRef50,
15817
- useMemo as useMemo17,
15839
+ useMemo as useMemo18,
15818
15840
  useState as useState28
15819
15841
  } from "react";
15820
15842
  import { Fragment as Fragment28, jsx as jsx61, jsxs as jsxs58 } from "react/jsx-runtime";
@@ -15867,7 +15889,7 @@ function JsonNode({
15867
15889
  const isObject = value !== null && typeof value === "object" && !Array.isArray(value);
15868
15890
  const isArray = Array.isArray(value);
15869
15891
  const isContainer = isObject || isArray;
15870
- const renderKey = useMemo17(() => {
15892
+ const renderKey = useMemo18(() => {
15871
15893
  if (name === void 0) return null;
15872
15894
  if (typeof name === "number") {
15873
15895
  return showIndexes ? /* @__PURE__ */ jsx61("span", { className: "ods-json-viewer__key ods-json-viewer__key--index", children: name }) : null;
@@ -16206,7 +16228,7 @@ import {
16206
16228
  useCallback as useCallback23,
16207
16229
  useEffect as useEffect24,
16208
16230
  useId as useId30,
16209
- useMemo as useMemo18,
16231
+ useMemo as useMemo19,
16210
16232
  useRef as useRef31,
16211
16233
  useState as useState29
16212
16234
  } from "react";
@@ -16274,7 +16296,7 @@ var LineChart = forwardRef53(
16274
16296
  ...rest
16275
16297
  }, ref) {
16276
16298
  const reactId = useId30();
16277
- const allLines = useMemo18(() => {
16299
+ const allLines = useMemo19(() => {
16278
16300
  if (series && series.length > 0) return series;
16279
16301
  return [
16280
16302
  {
@@ -16291,20 +16313,20 @@ var LineChart = forwardRef53(
16291
16313
  );
16292
16314
  const totalX = allLines[0]?.data.length ?? 0;
16293
16315
  const visibleRange = zoom ?? { start: 0, end: Math.max(0, totalX - 1) };
16294
- const lines = useMemo18(
16316
+ const lines = useMemo19(
16295
16317
  () => allLines.map((s) => ({
16296
16318
  ...s,
16297
16319
  data: s.data.slice(visibleRange.start, visibleRange.end + 1)
16298
16320
  })),
16299
16321
  [allLines, visibleRange.start, visibleRange.end]
16300
16322
  );
16301
- const xLabels = useMemo18(
16323
+ const xLabels = useMemo19(
16302
16324
  () => lines[0]?.data.map((p) => p.x) ?? [],
16303
16325
  [lines]
16304
16326
  );
16305
16327
  const xCount = xLabels.length;
16306
16328
  const stepX = (W - PAD * 2) / Math.max(1, xCount - 1);
16307
- const allYs = useMemo18(
16329
+ const allYs = useMemo19(
16308
16330
  () => lines.flatMap((s) => s.data.map((p) => p.y)),
16309
16331
  [lines]
16310
16332
  );
@@ -16312,7 +16334,7 @@ var LineChart = forwardRef53(
16312
16334
  const dataMax = allYs.length ? Math.max(...allYs) : 1;
16313
16335
  const lo = yMin ?? Math.min(0, dataMin);
16314
16336
  const hi = Math.max(lo + 1, yMax ?? dataMax);
16315
- const projected = useMemo18(
16337
+ const projected = useMemo19(
16316
16338
  () => lines.map(
16317
16339
  (s) => s.data.map(
16318
16340
  (p, i) => [
@@ -16323,7 +16345,7 @@ var LineChart = forwardRef53(
16323
16345
  ),
16324
16346
  [lines, stepX, lo, hi]
16325
16347
  );
16326
- const ticks = useMemo18(
16348
+ const ticks = useMemo19(
16327
16349
  () => buildTicks2(lo, hi, Math.max(2, yTicks)),
16328
16350
  [lo, hi, yTicks]
16329
16351
  );
@@ -16420,7 +16442,7 @@ var LineChart = forwardRef53(
16420
16442
  const p = s?.data[hoveredIdx];
16421
16443
  if (p) onPointClick(p, s.id, visibleRange.start + hoveredIdx);
16422
16444
  }, [hoveredIdx, lines, onPointClick, visibleRange.start]);
16423
- const resolvedAriaLabel = useMemo18(() => {
16445
+ const resolvedAriaLabel = useMemo19(() => {
16424
16446
  if (ariaLabel) return ariaLabel;
16425
16447
  const titleText = typeof title === "string" ? title : "";
16426
16448
  const summary = lines.map((s) => {
@@ -16927,7 +16949,7 @@ import { motion as motion24 } from "framer-motion";
16927
16949
  import {
16928
16950
  forwardRef as forwardRef56,
16929
16951
  useId as useId31,
16930
- useMemo as useMemo19
16952
+ useMemo as useMemo20
16931
16953
  } from "react";
16932
16954
  import { Fragment as Fragment30, jsx as jsx66, jsxs as jsxs64 } from "react/jsx-runtime";
16933
16955
  var defaultFormat6 = (n) => {
@@ -16980,7 +17002,7 @@ var Sparkline = forwardRef56(
16980
17002
  const PAD2 = 1;
16981
17003
  const hasData = data.length > 0;
16982
17004
  const canDrawLine = variant === "line" ? data.length >= 2 : hasData;
16983
- const resolvedAriaLabel = useMemo19(() => {
17005
+ const resolvedAriaLabel = useMemo20(() => {
16984
17006
  if (ariaLabel) return ariaLabel;
16985
17007
  if (!hasData) return "Sparkline \u2014 no data";
16986
17008
  const first = formatValue(data[0]);
@@ -17467,7 +17489,7 @@ import {
17467
17489
  useEffect as useEffect26,
17468
17490
  useId as useId33,
17469
17491
  useLayoutEffect as useLayoutEffect6,
17470
- useMemo as useMemo20,
17492
+ useMemo as useMemo21,
17471
17493
  useRef as useRef33,
17472
17494
  useState as useState31
17473
17495
  } from "react";
@@ -17537,11 +17559,11 @@ var MultiSelect = forwardRef58(
17537
17559
  },
17538
17560
  [controlledValue, onChange]
17539
17561
  );
17540
- const selectedSet = useMemo20(
17562
+ const selectedSet = useMemo21(
17541
17563
  () => new Set(selectedValues),
17542
17564
  [selectedValues]
17543
17565
  );
17544
- const filteredOptions = useMemo20(() => {
17566
+ const filteredOptions = useMemo21(() => {
17545
17567
  const base = hideSelected ? options.filter((o) => !selectedSet.has(o.value)) : options;
17546
17568
  if (!query.trim()) return base;
17547
17569
  const q2 = query.trim().toLowerCase();
@@ -18255,7 +18277,7 @@ import {
18255
18277
  forwardRef as forwardRef61,
18256
18278
  useCallback as useCallback27,
18257
18279
  useId as useId36,
18258
- useMemo as useMemo21,
18280
+ useMemo as useMemo22,
18259
18281
  useState as useState32
18260
18282
  } from "react";
18261
18283
  import { jsx as jsx72, jsxs as jsxs70 } from "react/jsx-runtime";
@@ -18349,7 +18371,7 @@ var Pagination = forwardRef61(
18349
18371
  },
18350
18372
  [currentPage, isControlled, onPageChange, totalPages]
18351
18373
  );
18352
- const pages = useMemo21(
18374
+ const pages = useMemo22(
18353
18375
  () => buildPageRange(totalPages, currentPage, siblingCount, boundaryCount),
18354
18376
  [totalPages, currentPage, siblingCount, boundaryCount]
18355
18377
  );
@@ -18545,7 +18567,7 @@ import {
18545
18567
  import { CheckmarkIcon as CheckmarkIcon7, ViewIcon, ViewOffIcon } from "@octaviaflow/icons";
18546
18568
 
18547
18569
  // src/hooks/usePasswordStrength.ts
18548
- import { useMemo as useMemo22 } from "react";
18570
+ import { useMemo as useMemo23 } from "react";
18549
18571
  var DEFAULT_PASSWORD_RULES = [
18550
18572
  { id: "length-8", label: "At least 8 characters", test: /.{8,}/ },
18551
18573
  { id: "lowercase", label: "A lower-case letter", test: /[a-z]/ },
@@ -18553,7 +18575,7 @@ var DEFAULT_PASSWORD_RULES = [
18553
18575
  { id: "digit", label: "A digit", test: /\d/ }
18554
18576
  ];
18555
18577
  function usePasswordStrength(value, rules = DEFAULT_PASSWORD_RULES) {
18556
- return useMemo22(() => {
18578
+ return useMemo23(() => {
18557
18579
  const evaluated = rules.map((r) => ({
18558
18580
  id: r.id,
18559
18581
  label: r.label,
@@ -23436,7 +23458,7 @@ import {
23436
23458
  useCallback as useCallback35,
23437
23459
  useEffect as useEffect34,
23438
23460
  useLayoutEffect as useLayoutEffect9,
23439
- useMemo as useMemo23,
23461
+ useMemo as useMemo24,
23440
23462
  useState as useState42
23441
23463
  } from "react";
23442
23464
  import { createPortal as createPortal14 } from "react-dom";
@@ -23463,7 +23485,7 @@ var Spotlight = forwardRef85(
23463
23485
  width: typeof window !== "undefined" ? window.innerWidth : 0,
23464
23486
  height: typeof window !== "undefined" ? window.innerHeight : 0
23465
23487
  }));
23466
- const maskId = useMemo23(
23488
+ const maskId = useMemo24(
23467
23489
  () => `ods-spotlight-${Math.random().toString(36).slice(2, 9)}`,
23468
23490
  []
23469
23491
  );
@@ -23640,7 +23662,7 @@ import {
23640
23662
  forwardRef as forwardRef87,
23641
23663
  useCallback as useCallback36,
23642
23664
  useId as useId48,
23643
- useMemo as useMemo24,
23665
+ useMemo as useMemo25,
23644
23666
  useState as useState43
23645
23667
  } from "react";
23646
23668
  import { jsx as jsx104, jsxs as jsxs98 } from "react/jsx-runtime";
@@ -23678,7 +23700,7 @@ var StatusTiles = forwardRef87(
23678
23700
  ...rest
23679
23701
  }, ref) {
23680
23702
  const reactId = useId48();
23681
- const visible = useMemo24(
23703
+ const visible = useMemo25(
23682
23704
  () => max < data.length ? data.slice(data.length - max) : data,
23683
23705
  [data, max]
23684
23706
  );
@@ -23705,7 +23727,7 @@ var StatusTiles = forwardRef87(
23705
23727
  },
23706
23728
  [visible, onTileClick]
23707
23729
  );
23708
- const resolvedAriaLabel = useMemo24(() => {
23730
+ const resolvedAriaLabel = useMemo25(() => {
23709
23731
  if (ariaLabel) return ariaLabel;
23710
23732
  const t = typeof title === "string" ? title : "Status";
23711
23733
  const tally = {};
@@ -23960,7 +23982,7 @@ import {
23960
23982
  forwardRef as forwardRef89,
23961
23983
  useCallback as useCallback37,
23962
23984
  useId as useId50,
23963
- useMemo as useMemo25,
23985
+ useMemo as useMemo26,
23964
23986
  useState as useState44
23965
23987
  } from "react";
23966
23988
  import { jsx as jsx106, jsxs as jsxs100 } from "react/jsx-runtime";
@@ -24025,12 +24047,12 @@ var Sankey = forwardRef89(function Sankey2({
24025
24047
  ...rest
24026
24048
  }, ref) {
24027
24049
  const reactId = useId50();
24028
- const columnMap = useMemo25(
24050
+ const columnMap = useMemo26(
24029
24051
  () => assignColumns(nodes, links),
24030
24052
  [nodes, links]
24031
24053
  );
24032
24054
  const columnCount = Math.max(0, ...Array.from(columnMap.values())) + 1;
24033
- const flows = useMemo25(() => {
24055
+ const flows = useMemo26(() => {
24034
24056
  const inFlow = /* @__PURE__ */ new Map();
24035
24057
  const outFlow = /* @__PURE__ */ new Map();
24036
24058
  for (const n of nodes) {
@@ -24043,7 +24065,7 @@ var Sankey = forwardRef89(function Sankey2({
24043
24065
  }
24044
24066
  return { inFlow, outFlow };
24045
24067
  }, [nodes, links]);
24046
- const columns = useMemo25(() => {
24068
+ const columns = useMemo26(() => {
24047
24069
  const grouped = Array.from(
24048
24070
  { length: columnCount },
24049
24071
  () => []
@@ -24054,7 +24076,7 @@ var Sankey = forwardRef89(function Sankey2({
24054
24076
  }
24055
24077
  return grouped;
24056
24078
  }, [nodes, columnMap, columnCount]);
24057
- const columnFlows = useMemo25(
24079
+ const columnFlows = useMemo26(
24058
24080
  () => columns.map(
24059
24081
  (col) => col.reduce((s, n) => {
24060
24082
  const f = Math.max(
@@ -24068,11 +24090,11 @@ var Sankey = forwardRef89(function Sankey2({
24068
24090
  );
24069
24091
  const maxColumnFlow = Math.max(1, ...columnFlows);
24070
24092
  const colAvail = (col) => height - Math.max(0, col.length - 1) * nodeGap;
24071
- const scale = useMemo25(() => {
24093
+ const scale = useMemo26(() => {
24072
24094
  const avail = Math.min(...columns.map(colAvail));
24073
24095
  return avail / maxColumnFlow;
24074
24096
  }, [columns, height, nodeGap, maxColumnFlow]);
24075
- const layoutNodes = useMemo25(() => {
24097
+ const layoutNodes = useMemo26(() => {
24076
24098
  const m = /* @__PURE__ */ new Map();
24077
24099
  const colX = (c) => {
24078
24100
  if (columnCount <= 1) return 0;
@@ -24113,7 +24135,7 @@ var Sankey = forwardRef89(function Sankey2({
24113
24135
  }
24114
24136
  return m;
24115
24137
  }, [columns, columnCount, width, nodeWidth, flows, scale, height, nodeGap]);
24116
- const layoutLinks = useMemo25(() => {
24138
+ const layoutLinks = useMemo26(() => {
24117
24139
  const sourceOffset = /* @__PURE__ */ new Map();
24118
24140
  const targetOffset = /* @__PURE__ */ new Map();
24119
24141
  for (const n of nodes) {
@@ -24182,7 +24204,7 @@ var Sankey = forwardRef89(function Sankey2({
24182
24204
  },
24183
24205
  [onNodeClick]
24184
24206
  );
24185
- const resolvedAriaLabel = useMemo25(() => {
24207
+ const resolvedAriaLabel = useMemo26(() => {
24186
24208
  if (ariaLabel) return ariaLabel;
24187
24209
  const t = typeof title === "string" ? title : "Sankey";
24188
24210
  return `${t} \u2014 ${nodes.length} nodes, ${links.length} flows`;
@@ -24590,7 +24612,7 @@ function TableRow({
24590
24612
 
24591
24613
  // src/components/Tabs/Tabs.tsx
24592
24614
  import { motion as motion33 } from "framer-motion";
24593
- import { useCallback as useCallback39, useEffect as useEffect35, useId as useId51, useMemo as useMemo26, useRef as useRef45, useState as useState46 } from "react";
24615
+ import { useCallback as useCallback39, useEffect as useEffect35, useId as useId51, useMemo as useMemo27, useRef as useRef45, useState as useState46 } from "react";
24594
24616
  import { useTab, useTabList, useTabPanel } from "react-aria";
24595
24617
  import { jsx as jsx109, jsxs as jsxs103 } from "react/jsx-runtime";
24596
24618
  function TabButton({
@@ -24651,7 +24673,7 @@ function Tabs({
24651
24673
  if (!value) setInternalValue(keyStr);
24652
24674
  onChange?.(keyStr);
24653
24675
  };
24654
- const panelContentMap = useMemo26(() => {
24676
+ const panelContentMap = useMemo27(() => {
24655
24677
  const map = /* @__PURE__ */ new Map();
24656
24678
  items.forEach((item) => {
24657
24679
  map.set(item.value, item.children);
@@ -25253,7 +25275,7 @@ import { CopyIcon as CopyIcon4, CutIcon } from "@octaviaflow/icons";
25253
25275
  import {
25254
25276
  useCallback as useCallback40,
25255
25277
  useEffect as useEffect36,
25256
- useMemo as useMemo27,
25278
+ useMemo as useMemo28,
25257
25279
  useRef as useRef46,
25258
25280
  useState as useState48
25259
25281
  } from "react";
@@ -25342,7 +25364,7 @@ function useTextareaCommands({
25342
25364
  const dismissedAtRef = useRef46(
25343
25365
  null
25344
25366
  );
25345
- const items = useMemo27(() => {
25367
+ const items = useMemo28(() => {
25346
25368
  const q2 = query.trim().toLowerCase();
25347
25369
  if (!q2) return commands.slice(0, maxItems);
25348
25370
  return commands.filter((c) => {
@@ -25635,7 +25657,7 @@ import {
25635
25657
  TextStrikethroughIcon,
25636
25658
  UndoIcon
25637
25659
  } from "@octaviaflow/icons";
25638
- import { useCallback as useCallback42, useMemo as useMemo28, useRef as useRef47 } from "react";
25660
+ import { useCallback as useCallback42, useMemo as useMemo29, useRef as useRef47 } from "react";
25639
25661
  import { jsx as jsx113 } from "react/jsx-runtime";
25640
25662
  function useTextareaTools({
25641
25663
  textareaRef,
@@ -25645,7 +25667,7 @@ function useTextareaTools({
25645
25667
  }) {
25646
25668
  const valueRef = useRef47(value);
25647
25669
  valueRef.current = value;
25648
- const helpers = useMemo28(() => {
25670
+ const helpers = useMemo29(() => {
25649
25671
  const getTa = () => textareaRef.current;
25650
25672
  const getSelection = () => {
25651
25673
  const ta = getTa();
@@ -25743,7 +25765,7 @@ function useTextareaTools({
25743
25765
  getTextarea: getTa
25744
25766
  };
25745
25767
  }, [textareaRef, onChange]);
25746
- const visibleTools = useMemo28(
25768
+ const visibleTools = useMemo29(
25747
25769
  () => tools.filter((t) => t.isVisible ? t.isVisible(helpers) : true),
25748
25770
  [tools, helpers]
25749
25771
  );
@@ -26711,7 +26733,7 @@ import {
26711
26733
  useCallback as useCallback44,
26712
26734
  useEffect as useEffect40,
26713
26735
  useId as useId57,
26714
- useMemo as useMemo29,
26736
+ useMemo as useMemo30,
26715
26737
  useRef as useRef50,
26716
26738
  useState as useState52
26717
26739
  } from "react";
@@ -26773,11 +26795,11 @@ var TimezonePicker = forwardRef98(
26773
26795
  else if (forwardedRef)
26774
26796
  forwardedRef.current = node;
26775
26797
  };
26776
- const selected = useMemo29(
26798
+ const selected = useMemo30(
26777
26799
  () => options.find((o) => o.iana === value),
26778
26800
  [options, value]
26779
26801
  );
26780
- const filtered = useMemo29(() => {
26802
+ const filtered = useMemo30(() => {
26781
26803
  if (!query.trim()) return options;
26782
26804
  const q2 = query.trim().toLowerCase();
26783
26805
  return options.filter(
@@ -27020,7 +27042,7 @@ import {
27020
27042
  createContext as createContext2,
27021
27043
  useCallback as useCallback45,
27022
27044
  useContext as useContext2,
27023
- useMemo as useMemo30,
27045
+ useMemo as useMemo31,
27024
27046
  useRef as useRef51,
27025
27047
  useState as useState53
27026
27048
  } from "react";
@@ -27174,7 +27196,7 @@ function PositionStack({ items, position, onDismiss, maxStack }) {
27174
27196
  const [hovered, setHovered] = useState53(false);
27175
27197
  const [pinned, setPinned] = useState53(false);
27176
27198
  const expanded = hovered || pinned;
27177
- const ordered = useMemo30(() => [...items].reverse(), [items]);
27199
+ const ordered = useMemo31(() => [...items].reverse(), [items]);
27178
27200
  const isBottom = position.startsWith("bottom");
27179
27201
  const dir = isBottom ? -1 : 1;
27180
27202
  if (pinned && items.length === 0) setPinned(false);
@@ -27325,7 +27347,7 @@ function ToastProvider({
27325
27347
  },
27326
27348
  [dismiss, defaultPosition]
27327
27349
  );
27328
- const groups = useMemo30(() => {
27350
+ const groups = useMemo31(() => {
27329
27351
  const out = {
27330
27352
  "top-left": [],
27331
27353
  "top-center": [],
@@ -27986,7 +28008,7 @@ import {
27986
28008
  useCallback as useCallback48,
27987
28009
  useEffect as useEffect41,
27988
28010
  useId as useId61,
27989
- useMemo as useMemo31,
28011
+ useMemo as useMemo32,
27990
28012
  useState as useState55
27991
28013
  } from "react";
27992
28014
  import { jsx as jsx124, jsxs as jsxs117 } from "react/jsx-runtime";
@@ -28033,7 +28055,7 @@ var TreeView = forwardRef101(
28033
28055
  (node) => node.children ?? loaded[node.id],
28034
28056
  [loaded]
28035
28057
  );
28036
- const resolvedNodes = useMemo31(() => {
28058
+ const resolvedNodes = useMemo32(() => {
28037
28059
  const walk = (ns) => ns.map((n) => {
28038
28060
  const kids = resolveChildren(n);
28039
28061
  if (kids) return { ...n, children: walk(kids) };
@@ -28041,7 +28063,7 @@ var TreeView = forwardRef101(
28041
28063
  });
28042
28064
  return walk(nodes);
28043
28065
  }, [nodes, resolveChildren]);
28044
- const visibleList = useMemo31(
28066
+ const visibleList = useMemo32(
28045
28067
  () => buildVisibleList(resolvedNodes, expandedSet),
28046
28068
  [resolvedNodes, expandedSet]
28047
28069
  );
@@ -28406,10 +28428,10 @@ var UserCard = forwardRef102(
28406
28428
  UserCard.displayName = "UserCard";
28407
28429
 
28408
28430
  // src/components/WorkflowEditor/WorkflowEditor.tsx
28409
- import { useCallback as useCallback50, useMemo as useMemo33, useState as useState56 } from "react";
28431
+ import { useCallback as useCallback50, useMemo as useMemo34, useState as useState56 } from "react";
28410
28432
 
28411
28433
  // src/hooks/useWorkflow.ts
28412
- import { useCallback as useCallback49, useMemo as useMemo32, useReducer } from "react";
28434
+ import { useCallback as useCallback49, useMemo as useMemo33, useReducer } from "react";
28413
28435
 
28414
28436
  // src/workflow/types.ts
28415
28437
  var types_exports = {};
@@ -28889,7 +28911,7 @@ function genId(prefix) {
28889
28911
  return `${prefix}_${Date.now().toString(36)}_${idCounter}`;
28890
28912
  }
28891
28913
  function useWorkflow(options = {}) {
28892
- const initial = useMemo32(
28914
+ const initial = useMemo33(
28893
28915
  () => buildInitialWorkflow({
28894
28916
  metadata: options.metadata ? { ...options.metadata } : void 0,
28895
28917
  canvas: {
@@ -29206,11 +29228,11 @@ function WorkflowEditor({
29206
29228
  if (onReset) onReset();
29207
29229
  else dispatch({ type: "RESET" });
29208
29230
  }, [onReset, dispatch]);
29209
- const nextNodes = useMemo33(
29231
+ const nextNodes = useMemo34(
29210
29232
  () => workflow.canvas.nodes.map(toNextNode),
29211
29233
  [workflow.canvas.nodes]
29212
29234
  );
29213
- const nextEdges = useMemo33(() => workflow.canvas.edges.map(toNextEdge), [workflow.canvas.edges]);
29235
+ const nextEdges = useMemo34(() => workflow.canvas.edges.map(toNextEdge), [workflow.canvas.edges]);
29214
29236
  const onNodesChange = useCallback50(
29215
29237
  (changes) => {
29216
29238
  const reduced = applyNodeChanges(
@@ -29301,7 +29323,7 @@ function WorkflowEditor({
29301
29323
  const cy = (minY + maxY) / 2;
29302
29324
  wf.setViewport({ x: cw / 2 - cx * zoom, y: ch / 2 - cy * zoom, zoom });
29303
29325
  }, [workflow.canvas.nodes, canvasSize, wf]);
29304
- const defaultToolbar = useMemo33(
29326
+ const defaultToolbar = useMemo34(
29305
29327
  () => /* @__PURE__ */ jsxs119(FlowToolbar, { placement: "left", children: [
29306
29328
  onSave && /* @__PURE__ */ jsx126(
29307
29329
  FlowToolbarButton,
@@ -29516,7 +29538,7 @@ import {
29516
29538
  forwardRef as forwardRef103,
29517
29539
  useCallback as useCallback51,
29518
29540
  useId as useId63,
29519
- useMemo as useMemo34,
29541
+ useMemo as useMemo35,
29520
29542
  useState as useState57
29521
29543
  } from "react";
29522
29544
  import { Fragment as Fragment48, jsx as jsx127, jsxs as jsxs120 } from "react/jsx-runtime";
@@ -29603,7 +29625,7 @@ var XmlViewer = forwardRef103(
29603
29625
  }, ref) {
29604
29626
  const reactId = useId63();
29605
29627
  const baseId = providedId ?? `ods-xml-viewer-${reactId}`;
29606
- const parsed = useMemo34(() => parseXml(data), [data]);
29628
+ const parsed = useMemo35(() => parseXml(data), [data]);
29607
29629
  const bodyStyle = height !== void 0 ? { height: typeof height === "number" ? `${height}px` : height } : maxHeight !== void 0 ? {
29608
29630
  maxHeight: typeof maxHeight === "number" ? `${maxHeight}px` : maxHeight
29609
29631
  } : void 0;
@@ -29795,7 +29817,7 @@ import {
29795
29817
  forwardRef as forwardRef104,
29796
29818
  useCallback as useCallback52,
29797
29819
  useId as useId64,
29798
- useMemo as useMemo35,
29820
+ useMemo as useMemo36,
29799
29821
  useState as useState58
29800
29822
  } from "react";
29801
29823
  import { Fragment as Fragment49, jsx as jsx128, jsxs as jsxs121 } from "react/jsx-runtime";
@@ -29940,7 +29962,7 @@ var YamlViewer = forwardRef104(
29940
29962
  }, ref) {
29941
29963
  const reactId = useId64();
29942
29964
  const baseId = providedId ?? `ods-yaml-viewer-${reactId}`;
29943
- const text = useMemo35(() => {
29965
+ const text = useMemo36(() => {
29944
29966
  if (typeof data === "string") return data;
29945
29967
  try {
29946
29968
  return toYaml(data);
@@ -29948,7 +29970,7 @@ var YamlViewer = forwardRef104(
29948
29970
  return JSON.stringify(data, null, 2);
29949
29971
  }
29950
29972
  }, [data]);
29951
- const tokens = useMemo35(() => tokenizeYaml(text), [text]);
29973
+ const tokens = useMemo36(() => tokenizeYaml(text), [text]);
29952
29974
  const [collapsed, setCollapsed] = useState58(() => {
29953
29975
  const s = /* @__PURE__ */ new Set();
29954
29976
  tokens.forEach((t) => {
@@ -29964,7 +29986,7 @@ var YamlViewer = forwardRef104(
29964
29986
  return next;
29965
29987
  });
29966
29988
  }, []);
29967
- const hidden = useMemo35(() => {
29989
+ const hidden = useMemo36(() => {
29968
29990
  const hide = /* @__PURE__ */ new Set();
29969
29991
  for (let i = 0; i < tokens.length; i++) {
29970
29992
  const t = tokens[i];
@@ -30513,12 +30535,12 @@ function useTraceTimeline({
30513
30535
 
30514
30536
  // src/provider/OdsProvider.tsx
30515
30537
  import { generateCssVars, resolveConfig } from "@octaviaflow/config";
30516
- import { createContext as createContext3, useContext as useContext3, useEffect as useEffect44, useMemo as useMemo36 } from "react";
30538
+ import { createContext as createContext3, useContext as useContext3, useEffect as useEffect44, useMemo as useMemo37 } from "react";
30517
30539
  import { OverlayProvider as OverlayProvider3 } from "react-aria";
30518
30540
  import { jsx as jsx129 } from "react/jsx-runtime";
30519
30541
  var OdsContext = createContext3(null);
30520
30542
  function OdsProvider({ config: userConfig, children }) {
30521
- const resolved = useMemo36(() => resolveConfig(userConfig), [userConfig]);
30543
+ const resolved = useMemo37(() => resolveConfig(userConfig), [userConfig]);
30522
30544
  useEffect44(() => {
30523
30545
  const cssVarsBlock = generateCssVars(resolved);
30524
30546
  const match = cssVarsBlock.match(/:root\s*\{([\s\S]*)\}/);
@@ -30535,7 +30557,7 @@ function OdsProvider({ config: userConfig, children }) {
30535
30557
  }
30536
30558
  }
30537
30559
  }, [resolved]);
30538
- const contextValue = useMemo36(() => ({ config: resolved }), [resolved]);
30560
+ const contextValue = useMemo37(() => ({ config: resolved }), [resolved]);
30539
30561
  return /* @__PURE__ */ jsx129(OdsContext.Provider, { value: contextValue, children: /* @__PURE__ */ jsx129(OverlayProvider3, { children }) });
30540
30562
  }
30541
30563
  function useOds() {
@@ -30555,7 +30577,7 @@ var emptyMotion = {
30555
30577
  };
30556
30578
  function useOdsMotion() {
30557
30579
  const config = useOds();
30558
- return useMemo36(() => {
30580
+ return useMemo37(() => {
30559
30581
  if (!config.motion.enabled) {
30560
30582
  return emptyMotion;
30561
30583
  }