@tduniec/plugin-template-designer-foundation 0.1.1 → 0.1.2

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/CHANGELOG.md CHANGED
@@ -1,3 +1,11 @@
1
+ ## [0.1.2](https://github.com/tduniec/template-designer-plugin/compare/template-designer-foundation-v0.1.1...template-designer-foundation-v0.1.2) (2025-12-21)
2
+
3
+
4
+ ### Bug Fixes
5
+
6
+ * **template-designer-foundation:** output notation change && node outputs render bringed back ([76bb9e8](https://github.com/tduniec/template-designer-plugin/commit/76bb9e8aedcfa5a152b9f66c5d29428c98bc84b5))
7
+ * **template-designer-foundation:** parameterNodes alignement ([074dceb](https://github.com/tduniec/template-designer-plugin/commit/074dceb1be0fe9479540349564a8379b980df107))
8
+
1
9
  ## [0.1.1](https://github.com/tduniec/template-designer-plugin/compare/template-designer-foundation-v0.1.0...template-designer-foundation-v0.1.1) (2025-12-20)
2
10
 
3
11
 
@@ -1,6 +1,6 @@
1
- import { jsxs, jsx } from 'react/jsx-runtime';
2
- import { NodeToolbar, Position, Handle } from '@xyflow/react';
3
- import { memo } from 'react';
1
+ import { jsx, jsxs } from 'react/jsx-runtime';
2
+ import { useReactFlow, NodeToolbar, Position, Handle } from '@xyflow/react';
3
+ import { memo, useRef, useLayoutEffect } from 'react';
4
4
  import { styled, alpha, useTheme } from '@material-ui/core/styles';
5
5
  import { Box, Typography, Chip, Button } from '@material-ui/core';
6
6
  import SettingsIcon from '@material-ui/icons/Settings';
@@ -66,6 +66,9 @@ const ParametersNodeComponent = ({
66
66
  }
67
67
  const theme = useTheme();
68
68
  const paletteMode = resolvePaletteMode(theme);
69
+ const cardRef = useRef(null);
70
+ const heightRef = useRef(null);
71
+ const { setNodes } = useReactFlow();
69
72
  const {
70
73
  sections,
71
74
  handleSectionUpdate,
@@ -76,7 +79,42 @@ const ParametersNodeComponent = ({
76
79
  handleMoveField
77
80
  } = useParameterSectionsController(data);
78
81
  const stopAll = createStopNodeInteraction();
79
- return /* @__PURE__ */ jsxs(Card, { children: [
82
+ useLayoutEffect(() => {
83
+ const element = cardRef.current;
84
+ if (!element) {
85
+ return void 0;
86
+ }
87
+ let raf = null;
88
+ const observer = new ResizeObserver(([entry]) => {
89
+ const nextHeight = entry.contentRect.height;
90
+ const previousHeight = heightRef.current ?? nextHeight;
91
+ if (Math.abs(previousHeight - nextHeight) < 1) {
92
+ return;
93
+ }
94
+ heightRef.current = nextHeight;
95
+ if (raf) {
96
+ cancelAnimationFrame(raf);
97
+ }
98
+ raf = requestAnimationFrame(() => {
99
+ setNodes(
100
+ (nodes) => nodes.map(
101
+ (node) => node.id === data.rfId ? {
102
+ ...node,
103
+ data: { ...node.data, measuredHeight: nextHeight }
104
+ } : node
105
+ )
106
+ );
107
+ });
108
+ });
109
+ observer.observe(element);
110
+ return () => {
111
+ if (raf) {
112
+ cancelAnimationFrame(raf);
113
+ }
114
+ observer.disconnect();
115
+ };
116
+ }, [data.rfId, setNodes]);
117
+ return /* @__PURE__ */ jsx("div", { ref: cardRef, children: /* @__PURE__ */ jsxs(Card, { children: [
80
118
  /* @__PURE__ */ jsxs(Header, { children: [
81
119
  /* @__PURE__ */ jsxs(
82
120
  Box,
@@ -139,7 +177,7 @@ const ParametersNodeComponent = ({
139
177
  }
140
178
  ) }),
141
179
  /* @__PURE__ */ jsx(Handle, { type: "source", position: Position.Bottom })
142
- ] });
180
+ ] }) });
143
181
  };
144
182
  const ParametersNode = memo(ParametersNodeComponent);
145
183
 
@@ -1 +1 @@
1
- {"version":3,"file":"ParametersNode.esm.js","sources":["../../../src/components/Nodes/ParametersNode.tsx"],"sourcesContent":["import type { FC } from \"react\";\nimport { Handle, NodeToolbar, Position } from \"@xyflow/react\";\nimport { memo } from \"react\";\nimport { alpha, styled, useTheme } from \"@material-ui/core/styles\";\nimport { Box, Button, Chip, Typography } from \"@material-ui/core\";\nimport SettingsIcon from \"@material-ui/icons/Settings\";\nimport AddIcon from \"@material-ui/icons/Add\";\nimport type { ParametersNodeData } from \"../../types/flowNodes\";\nimport { createStopNodeInteraction } from \"./common/nodeInteraction\";\nimport { useParameterSectionsController } from \"../../state/useParameterSections\";\nimport { ParameterTitlesNode } from \"./ParameterTitlesNode\";\n\nconst resolvePaletteMode = (theme: { palette: { type?: string } }) =>\n (theme.palette as { mode?: \"light\" | \"dark\" }).mode ??\n theme.palette.type ??\n \"light\";\n\nconst Card = styled(Box)(({ theme }) => {\n const paletteMode = resolvePaletteMode(theme);\n return {\n position: \"relative\",\n background: alpha(\n theme.palette.warning.main,\n paletteMode === \"dark\" ? 0.18 : 0.12\n ),\n border: `1px solid ${alpha(theme.palette.warning.main, 0.35)}`,\n borderRadius: 12,\n width: 760,\n padding: theme.spacing(1.5),\n boxShadow: theme.shadows[2],\n color: theme.palette.text.primary,\n overflow: \"hidden\",\n \"&::before\": {\n content: '\"\"',\n position: \"absolute\",\n inset: 0,\n background: `linear-gradient(135deg, ${alpha(\n theme.palette.warning.light,\n paletteMode === \"dark\" ? 0.28 : 0.18\n )}, transparent 65%)`,\n pointerEvents: \"none\",\n zIndex: 0,\n },\n \"& > *\": {\n position: \"relative\",\n zIndex: 1,\n },\n };\n});\n\nconst Header = styled(Box)(({ theme }) => {\n const paletteMode = resolvePaletteMode(theme);\n return {\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"space-between\",\n padding: theme.spacing(1),\n marginBottom: theme.spacing(1),\n borderRadius: 8,\n backgroundColor: alpha(\n theme.palette.warning.main,\n paletteMode === \"dark\" ? 0.24 : 0.14\n ),\n border: `1px solid ${alpha(theme.palette.warning.main, 0.4)}`,\n };\n});\n\nconst ParametersNodeComponent: FC<{ data: ParametersNodeData }> = ({\n data,\n}) => {\n if (process.env.NODE_ENV === \"development\") {\n // Quick dev-only visibility into unnecessary renders per node.\n // eslint-disable-next-line no-console\n console.debug(\"[DesignerFlow] render ParametersNode\", data.rfId);\n }\n const theme = useTheme();\n const paletteMode = resolvePaletteMode(theme);\n const {\n sections,\n handleSectionUpdate,\n handleFieldUpdate,\n handleAddSection,\n handleMoveSection,\n handleAddField,\n handleMoveField,\n } = useParameterSectionsController(data);\n\n const stopAll = createStopNodeInteraction();\n\n return (\n <Card>\n <Header>\n <Box\n display=\"flex\"\n alignItems=\"center\"\n style={{ gap: theme.spacing(1) }}\n >\n <SettingsIcon\n fontSize=\"small\"\n htmlColor={theme.palette.warning.dark}\n />\n <Typography variant=\"subtitle2\" noWrap>\n Parameters\n </Typography>\n </Box>\n <Chip\n size=\"small\"\n variant=\"outlined\"\n label=\"parameters\"\n style={{\n borderColor: theme.palette.warning.dark,\n color:\n paletteMode === \"dark\"\n ? theme.palette.warning.light\n : theme.palette.warning.dark,\n textTransform: \"uppercase\",\n }}\n />\n </Header>\n\n <Box mt={2}>\n <ParameterTitlesNode\n sections={sections}\n onSectionUpdate={handleSectionUpdate}\n onFieldUpdate={handleFieldUpdate}\n onAddSection={handleAddSection}\n onMoveSection={handleMoveSection}\n onAddField={handleAddField}\n onMoveField={handleMoveField}\n />\n </Box>\n\n <NodeToolbar position={Position.Bottom}>\n <Button\n variant=\"outlined\"\n size=\"small\"\n startIcon={<AddIcon fontSize=\"small\" />}\n onClick={() =>\n data.onAddNode?.({\n afterRfId: data.rfId,\n type: \"actionNode\",\n })\n }\n className=\"nodrag nowheel\"\n onPointerDown={stopAll.onPointerDown}\n onKeyDown={stopAll.onKeyDown}\n >\n Add First Action\n </Button>\n </NodeToolbar>\n\n <Handle type=\"source\" position={Position.Bottom} />\n </Card>\n );\n};\n\nexport const ParametersNode = memo(ParametersNodeComponent);\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"ParametersNode.esm.js","sources":["../../../src/components/Nodes/ParametersNode.tsx"],"sourcesContent":["import type { FC } from \"react\";\nimport { Handle, NodeToolbar, Position, useReactFlow } from \"@xyflow/react\";\nimport { memo, useLayoutEffect, useRef } from \"react\";\nimport { alpha, styled, useTheme } from \"@material-ui/core/styles\";\nimport { Box, Button, Chip, Typography } from \"@material-ui/core\";\nimport SettingsIcon from \"@material-ui/icons/Settings\";\nimport AddIcon from \"@material-ui/icons/Add\";\nimport type { ParametersNodeData } from \"../../types/flowNodes\";\nimport { createStopNodeInteraction } from \"./common/nodeInteraction\";\nimport { useParameterSectionsController } from \"../../state/useParameterSections\";\nimport { ParameterTitlesNode } from \"./ParameterTitlesNode\";\n\nconst resolvePaletteMode = (theme: { palette: { type?: string } }) =>\n (theme.palette as { mode?: \"light\" | \"dark\" }).mode ??\n theme.palette.type ??\n \"light\";\n\nconst Card = styled(Box)(({ theme }) => {\n const paletteMode = resolvePaletteMode(theme);\n return {\n position: \"relative\",\n background: alpha(\n theme.palette.warning.main,\n paletteMode === \"dark\" ? 0.18 : 0.12\n ),\n border: `1px solid ${alpha(theme.palette.warning.main, 0.35)}`,\n borderRadius: 12,\n width: 760,\n padding: theme.spacing(1.5),\n boxShadow: theme.shadows[2],\n color: theme.palette.text.primary,\n overflow: \"hidden\",\n \"&::before\": {\n content: '\"\"',\n position: \"absolute\",\n inset: 0,\n background: `linear-gradient(135deg, ${alpha(\n theme.palette.warning.light,\n paletteMode === \"dark\" ? 0.28 : 0.18\n )}, transparent 65%)`,\n pointerEvents: \"none\",\n zIndex: 0,\n },\n \"& > *\": {\n position: \"relative\",\n zIndex: 1,\n },\n };\n});\n\nconst Header = styled(Box)(({ theme }) => {\n const paletteMode = resolvePaletteMode(theme);\n return {\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"space-between\",\n padding: theme.spacing(1),\n marginBottom: theme.spacing(1),\n borderRadius: 8,\n backgroundColor: alpha(\n theme.palette.warning.main,\n paletteMode === \"dark\" ? 0.24 : 0.14\n ),\n border: `1px solid ${alpha(theme.palette.warning.main, 0.4)}`,\n };\n});\n\nconst ParametersNodeComponent: FC<{ data: ParametersNodeData }> = ({\n data,\n}) => {\n if (process.env.NODE_ENV === \"development\") {\n // Quick dev-only visibility into unnecessary renders per node.\n // eslint-disable-next-line no-console\n console.debug(\"[DesignerFlow] render ParametersNode\", data.rfId);\n }\n const theme = useTheme();\n const paletteMode = resolvePaletteMode(theme);\n const cardRef = useRef<HTMLDivElement | null>(null);\n const heightRef = useRef<number | null>(null);\n const { setNodes } = useReactFlow();\n const {\n sections,\n handleSectionUpdate,\n handleFieldUpdate,\n handleAddSection,\n handleMoveSection,\n handleAddField,\n handleMoveField,\n } = useParameterSectionsController(data);\n\n const stopAll = createStopNodeInteraction();\n\n useLayoutEffect(() => {\n const element = cardRef.current;\n if (!element) {\n return undefined;\n }\n let raf: number | null = null;\n const observer = new ResizeObserver(([entry]) => {\n const nextHeight = entry.contentRect.height;\n const previousHeight = heightRef.current ?? nextHeight;\n if (Math.abs(previousHeight - nextHeight) < 1) {\n return;\n }\n heightRef.current = nextHeight;\n if (raf) {\n cancelAnimationFrame(raf);\n }\n raf = requestAnimationFrame(() => {\n setNodes((nodes) =>\n nodes.map((node) =>\n node.id === data.rfId\n ? {\n ...node,\n data: { ...(node.data as any), measuredHeight: nextHeight },\n }\n : node\n )\n );\n });\n });\n observer.observe(element);\n return () => {\n if (raf) {\n cancelAnimationFrame(raf);\n }\n observer.disconnect();\n };\n }, [data.rfId, setNodes]);\n\n return (\n <div ref={cardRef}>\n <Card>\n <Header>\n <Box\n display=\"flex\"\n alignItems=\"center\"\n style={{ gap: theme.spacing(1) }}\n >\n <SettingsIcon\n fontSize=\"small\"\n htmlColor={theme.palette.warning.dark}\n />\n <Typography variant=\"subtitle2\" noWrap>\n Parameters\n </Typography>\n </Box>\n <Chip\n size=\"small\"\n variant=\"outlined\"\n label=\"parameters\"\n style={{\n borderColor: theme.palette.warning.dark,\n color:\n paletteMode === \"dark\"\n ? theme.palette.warning.light\n : theme.palette.warning.dark,\n textTransform: \"uppercase\",\n }}\n />\n </Header>\n\n <Box mt={2}>\n <ParameterTitlesNode\n sections={sections}\n onSectionUpdate={handleSectionUpdate}\n onFieldUpdate={handleFieldUpdate}\n onAddSection={handleAddSection}\n onMoveSection={handleMoveSection}\n onAddField={handleAddField}\n onMoveField={handleMoveField}\n />\n </Box>\n\n <NodeToolbar position={Position.Bottom}>\n <Button\n variant=\"outlined\"\n size=\"small\"\n startIcon={<AddIcon fontSize=\"small\" />}\n onClick={() =>\n data.onAddNode?.({\n afterRfId: data.rfId,\n type: \"actionNode\",\n })\n }\n className=\"nodrag nowheel\"\n onPointerDown={stopAll.onPointerDown}\n onKeyDown={stopAll.onKeyDown}\n >\n Add First Action\n </Button>\n </NodeToolbar>\n\n <Handle type=\"source\" position={Position.Bottom} />\n </Card>\n </div>\n );\n};\n\nexport const ParametersNode = memo(ParametersNodeComponent);\n"],"names":[],"mappings":"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"}
@@ -7,7 +7,7 @@ import { createSequentialEdges } from '../utils/createSequentialEdges.esm.js';
7
7
  import { buildNodeHashMap, buildEdgeHashMap, mergeNodesWithStability, mergeEdgesWithStability } from './utils/stableComparators.esm.js';
8
8
  import { createHandleReorderAndAlignNodes, createHandleUpdateField, createHandleUpdateInput, createHandleRemoveInputKey, createHandleUpdateOutput, createHandleUpdateSections, createHandleAddNode, createHandleRemoveNode } from './handlers.esm.js';
9
9
  import { resolveNodeHeightForTracking, alignNodes } from './nodeLayout.esm.js';
10
- import { nodeDefaults, FLOW_LAYOUT } from '../components/designerFlowConfig.esm.js';
10
+ import { FLOW_LAYOUT, nodeDefaults } from '../components/designerFlowConfig.esm.js';
11
11
  import { useScaffolderActions } from '../api/useScaffolderActions.esm.js';
12
12
 
13
13
  const EMPTY_EDGES = [];
@@ -225,6 +225,7 @@ function DesignerFlow({
225
225
  }, []);
226
226
  useEffect(() => {
227
227
  const isCacheChanged = cacheFingerprint !== lastCacheFingerprintRef.current;
228
+ const prevAppliedModelHash = lastAppliedModelHashRef.current;
228
229
  if (modelHash === lastAppliedModelHashRef.current && !isCacheChanged) {
229
230
  return;
230
231
  }
@@ -241,25 +242,25 @@ function DesignerFlow({
241
242
  );
242
243
  const nextNodes = decorateNodes ? decorateNodes(builtNodes) : builtNodes;
243
244
  const isInitialMount = !hasMountedRef.current;
245
+ const shouldReplaceNodes = prevAppliedModelHash !== modelHash || isInitialMount;
244
246
  lastAppliedModelHashRef.current = modelHash;
245
247
  lastCacheFingerprintRef.current = cacheFingerprint;
246
248
  lastEmittedModelHashRef.current = modelHash;
247
249
  setNodes((currentNodes) => {
248
- const merged = mergeNodesWithStability(
249
- currentNodes,
250
- nextNodes,
251
- nodeDataHashRef
252
- );
253
- return merged;
250
+ if (shouldReplaceNodes) {
251
+ nodeDataHashRef.current = buildNodeHashMap(nextNodes);
252
+ nodeHeightsRef.current = {};
253
+ return nextNodes;
254
+ }
255
+ return mergeNodesWithStability(currentNodes, nextNodes, nodeDataHashRef);
254
256
  });
255
257
  setEdges((currentEdges) => {
256
258
  const newEdges = decorateEdges ? decorateEdges(createSequentialEdges(nextNodes), nextNodes) : createSequentialEdges(nextNodes);
257
- const merged = mergeEdgesWithStability(
258
- currentEdges,
259
- newEdges,
260
- edgeDataHashRef
261
- );
262
- return merged;
259
+ if (shouldReplaceNodes) {
260
+ edgeDataHashRef.current = buildEdgeHashMap(newEdges);
261
+ return newEdges;
262
+ }
263
+ return mergeEdgesWithStability(currentEdges, newEdges, edgeDataHashRef);
263
264
  });
264
265
  hasMountedRef.current = true;
265
266
  lastNodeCountRef.current = nextNodes.length;
@@ -281,6 +282,7 @@ function DesignerFlow({
281
282
  setNodes,
282
283
  setEdges
283
284
  ]);
285
+ const lastParameterResizeRef = useRef(null);
284
286
  useEffect(() => {
285
287
  if (!nodes.length) {
286
288
  return;
@@ -290,6 +292,7 @@ function DesignerFlow({
290
292
  }
291
293
  const activeNodeIds = /* @__PURE__ */ new Set();
292
294
  let hasMeasuredChange = false;
295
+ let parameterResize = null;
293
296
  nodes.forEach((node) => {
294
297
  activeNodeIds.add(node.id);
295
298
  const measuredHeight = resolveNodeHeightForTracking(node);
@@ -297,12 +300,19 @@ function DesignerFlow({
297
300
  return;
298
301
  }
299
302
  const previousHeight = nodeHeightsRef.current[node.id];
300
- const heightDelta = Math.abs(
301
- (previousHeight ?? measuredHeight) - measuredHeight
302
- );
303
+ const heightDelta = previousHeight === void 0 ? Number.POSITIVE_INFINITY : Math.abs(previousHeight - measuredHeight);
303
304
  if (heightDelta >= 1) {
305
+ if (node.type === "parametersNode") {
306
+ parameterResize = {
307
+ id: node.id,
308
+ prevHeight: previousHeight ?? measuredHeight,
309
+ nextHeight: measuredHeight
310
+ };
311
+ }
304
312
  nodeHeightsRef.current[node.id] = measuredHeight;
305
313
  hasMeasuredChange = true;
314
+ } else if (previousHeight === void 0) {
315
+ nodeHeightsRef.current[node.id] = measuredHeight;
306
316
  }
307
317
  });
308
318
  Object.keys(nodeHeightsRef.current).forEach((id) => {
@@ -317,14 +327,39 @@ function DesignerFlow({
317
327
  layoutInitializedRef.current = true;
318
328
  return;
319
329
  }
330
+ lastParameterResizeRef.current = parameterResize;
320
331
  if (alignDebounceRef.current) {
321
332
  clearTimeout(alignDebounceRef.current);
322
333
  }
323
334
  alignDebounceRef.current = setTimeout(() => {
324
335
  alignDebounceRef.current = null;
325
336
  setNodes((currentNodes) => {
337
+ const resize = lastParameterResizeRef.current;
338
+ const updated = currentNodes.map((node) => {
339
+ if (node.type !== "parametersNode") {
340
+ return node;
341
+ }
342
+ if (!resize || resize.id !== node.id) {
343
+ return {
344
+ ...node,
345
+ position: { ...node.position, x: FIXED_X_POSITION }
346
+ };
347
+ }
348
+ const prevBottom = node.position.y + resize.prevHeight;
349
+ const nextY = Math.max(0, prevBottom - resize.nextHeight);
350
+ if (node.position.y === nextY) {
351
+ return {
352
+ ...node,
353
+ position: { ...node.position, x: FIXED_X_POSITION }
354
+ };
355
+ }
356
+ return {
357
+ ...node,
358
+ position: { x: FIXED_X_POSITION, y: nextY }
359
+ };
360
+ });
326
361
  const alignedNodes = alignNodes(
327
- currentNodes,
362
+ updated,
328
363
  FIXED_X_POSITION,
329
364
  VERTICAL_SPACING
330
365
  );
@@ -1 +1 @@
1
- {"version":3,"file":"DesignerFlow.esm.js","sources":["../../src/designerFlow/DesignerFlow.tsx"],"sourcesContent":["import {\n useCallback,\n useEffect,\n useMemo,\n useRef,\n useState,\n ComponentType,\n createElement,\n} from \"react\";\nimport type { MouseEvent as ReactMouseEvent } from \"react\";\nimport {\n ReactFlow,\n applyNodeChanges,\n applyEdgeChanges,\n addEdge,\n Node,\n Edge,\n NodeChange,\n EdgeChange,\n useNodesState,\n ReactFlowInstance,\n NodeProps,\n NodeTypes,\n Viewport,\n OnMoveEnd,\n OnMove,\n} from \"@xyflow/react\";\nimport \"@xyflow/react/dist/style.css\";\nimport type {\n ScaffolderTaskOutput,\n TaskStep,\n} from \"@backstage/plugin-scaffolder-common\";\nimport type {\n ActionNodeData,\n OutputNodeData,\n ParametersNodeData,\n TemplateParametersValue,\n} from \"../types/flowNodes\";\nimport {\n buildNodesFromModel,\n collectParameterReferences,\n collectStepOutputReferences,\n stableStringify,\n extractStepsFromNodes,\n extractParametersFromNodes,\n extractOutputFromNodes,\n} from \"./model\";\nimport { createSequentialEdges } from \"../utils/createSequentialEdges\";\nimport {\n buildEdgeHashMap,\n buildNodeHashMap,\n mergeEdgesWithStability,\n mergeNodesWithStability,\n} from \"./utils/stableComparators\";\nimport {\n createHandleAddNode,\n createHandleRemoveNode,\n createHandleRemoveInputKey,\n createHandleReorderAndAlignNodes,\n createHandleUpdateField,\n createHandleUpdateInput,\n createHandleUpdateOutput,\n createHandleUpdateSections,\n} from \"./handlers\";\nimport { alignNodes, resolveNodeHeightForTracking } from \"./nodeLayout\";\nimport {\n FLOW_LAYOUT,\n nodeDefaults as baseNodeDefaults,\n} from \"../components/designerFlowConfig\";\nimport { useScaffolderActions } from \"../api/useScaffolderActions\";\n\nconst EMPTY_EDGES: Edge[] = [];\nconst EMIT_DEBOUNCE_MS = 1200; // Emit only after user pauses typing for a bit (more relaxed UX).\nconst VIEWPORT_TUNING = {\n alignDebounceMs: 120, // Debounce view/align updates so typing isn't interrupted by layout thrash.\n centerDurationMs: 280,\n fitFallbackDelayMs: 50,\n};\n\n// Prevent benign ResizeObserver loop errors from bubbling to the dev overlay.\nif (\n typeof window !== \"undefined\" &&\n !(window as any).__rfResizeObserverPatched\n) {\n (window as any).__rfResizeObserverPatched = true;\n // Wrap ResizeObserver callbacks in rAF to avoid sync measurement loops that trigger the warning.\n if (typeof window.ResizeObserver === \"function\") {\n const OriginalResizeObserver = window.ResizeObserver;\n window.ResizeObserver = class extends OriginalResizeObserver {\n constructor(callback: ResizeObserverCallback) {\n super((entries, observer) => {\n window.requestAnimationFrame(() => callback(entries, observer));\n });\n }\n } as typeof ResizeObserver;\n }\n const shouldSwallow = (message: unknown) =>\n typeof message === \"string\" &&\n message.includes(\"ResizeObserver loop completed with undelivered\");\n const swallowResizeObserverError = (event: ErrorEvent) => {\n const message =\n event?.message || (event as any)?.error?.message || String(event);\n if (shouldSwallow(message)) {\n event.preventDefault();\n event.stopImmediatePropagation();\n return true;\n }\n return undefined;\n };\n const swallowResizeObserverRejection = (event: PromiseRejectionEvent) => {\n const message = (event.reason as any)?.message ?? String(event.reason);\n if (shouldSwallow(message)) {\n event.preventDefault();\n event.stopImmediatePropagation();\n return true;\n }\n return undefined;\n };\n const swallowLoopEvent = (event: Event) => {\n event.preventDefault();\n event.stopImmediatePropagation();\n };\n const originalOnError = window.onerror;\n window.onerror = function handleResizeObserverOnError(\n message,\n source,\n lineno,\n colno,\n error\n ): boolean | void {\n if (\n shouldSwallow(\n typeof message === \"string\"\n ? message\n : (error as any)?.message ?? String(message)\n )\n ) {\n return true;\n }\n if (typeof originalOnError === \"function\") {\n return originalOnError(message, source, lineno, colno, error);\n }\n return undefined;\n };\n const originalOnUnhandledRejection = window.onunhandledrejection;\n window.onunhandledrejection = function handleResizeObserverOnUnhandled(\n event\n ) {\n const reason = (event as any)?.reason;\n const message =\n (reason as any)?.message ?? (typeof reason === \"string\" ? reason : \"\");\n if (shouldSwallow(message)) {\n return true;\n }\n if (typeof originalOnUnhandledRejection === \"function\") {\n return (originalOnUnhandledRejection as any)(event);\n }\n return undefined;\n };\n window.addEventListener(\"error\", swallowResizeObserverError, true);\n window.addEventListener(\n \"unhandledrejection\",\n swallowResizeObserverRejection,\n true\n );\n window.addEventListener(\n \"resizeobserverlooperror\" as any,\n swallowLoopEvent,\n true\n );\n}\n\nconst shallowArrayEqual = (a?: string[], b?: string[]) => {\n if (a === b) {\n return true;\n }\n if (!a || !b || a.length !== b.length) {\n return false;\n }\n for (let i = 0; i < a.length; i += 1) {\n if (a[i] !== b[i]) {\n return false;\n }\n }\n return true;\n};\n\n// Main orchestration component that renders and synchronizes the Designer flow.\n\nconst FIXED_X_POSITION = FLOW_LAYOUT.fixedXPosition;\nconst VERTICAL_SPACING = FLOW_LAYOUT.verticalSpacing;\n\nexport type DesignerFlowProps = {\n steps?: TaskStep[];\n parameters?: TemplateParametersValue;\n output?: ScaffolderTaskOutput | null;\n onStepsChange?: (steps: TaskStep[]) => void;\n onParametersChange?: (parameters: TemplateParametersValue) => void;\n onOutputChange?: (output: ScaffolderTaskOutput | undefined) => void;\n actionNodeComponent: ComponentType<{ data: ActionNodeData }>;\n parametersNodeComponent: ComponentType<{ data: ParametersNodeData }>;\n outputNodeComponent: ComponentType<{ data: OutputNodeData }>;\n decorateNodes?: (nodes: Node[]) => Node[];\n decorateEdges?: (edges: Edge[], nodes: Node[]) => Edge[];\n nodeDefaults?: Partial<Node>;\n};\n\nexport default function DesignerFlow({\n steps = [],\n parameters,\n output,\n onStepsChange,\n onParametersChange,\n onOutputChange,\n actionNodeComponent,\n parametersNodeComponent,\n outputNodeComponent,\n decorateNodes,\n decorateEdges,\n nodeDefaults = baseNodeDefaults,\n}: DesignerFlowProps) {\n const nodeDataHashRef = useRef<Record<string, string>>({});\n const edgeDataHashRef = useRef<Record<string, string>>({});\n const scaffolderActionsCache = useScaffolderActions();\n\n const {\n ids: scaffolderActionIds,\n inputsById: scaffolderActionInputsById,\n outputsById: scaffolderActionOutputsById,\n inputRequiredById: scaffolderActionInputRequiredById,\n } = scaffolderActionsCache;\n\n const normalizedParametersProp = parameters ?? undefined;\n const normalizedOutputProp = output ?? null;\n const pendingFocusNodeIdRef = useRef<string | null>(null);\n const hasMountedRef = useRef(false);\n const lastNodeCountRef = useRef(0);\n\n const initialNodes = useMemo(() => {\n const built = buildNodesFromModel(\n steps,\n normalizedParametersProp,\n normalizedOutputProp,\n {\n scaffolderActionIds,\n scaffolderActionInputsById,\n scaffolderActionOutputsById,\n scaffolderActionInputRequiredById,\n }\n );\n const nodes = decorateNodes ? decorateNodes(built) : built;\n nodeDataHashRef.current = buildNodeHashMap(nodes);\n return nodes;\n }, [\n steps,\n normalizedParametersProp,\n normalizedOutputProp,\n scaffolderActionIds,\n scaffolderActionInputsById,\n scaffolderActionOutputsById,\n scaffolderActionInputRequiredById,\n decorateNodes,\n ]);\n\n const [nodes, setNodes] = useNodesState(initialNodes);\n const initialEdges = useMemo(() => {\n const edges = decorateEdges\n ? decorateEdges(createSequentialEdges(initialNodes), initialNodes)\n : createSequentialEdges(initialNodes);\n edgeDataHashRef.current = buildEdgeHashMap(edges);\n lastNodeCountRef.current = initialNodes.length;\n return edges;\n }, [decorateEdges, initialNodes]);\n\n const [edges, setEdges] = useState<Edge[]>(initialEdges);\n\n const modelHash = useMemo(\n () =>\n stableStringify({\n steps,\n parameters: normalizedParametersProp,\n output: normalizedOutputProp,\n }),\n [steps, normalizedParametersProp, normalizedOutputProp]\n );\n\n const cacheFingerprint = useMemo(\n () =>\n stableStringify({\n ids: scaffolderActionIds,\n inputs: scaffolderActionInputsById,\n outputs: scaffolderActionOutputsById,\n inputRequired: scaffolderActionInputRequiredById,\n }),\n [\n scaffolderActionIds,\n scaffolderActionInputsById,\n scaffolderActionOutputsById,\n scaffolderActionInputRequiredById,\n ]\n );\n\n const lastAppliedModelHashRef = useRef<string | null>(null);\n const lastEmittedModelHashRef = useRef<string | null>(null);\n const lastCacheFingerprintRef = useRef<string | null>(null);\n const nodeHeightsRef = useRef<Record<string, number>>({});\n const lastViewportRef = useRef<Viewport | null>(null);\n const emitDebounceRef = useRef<ReturnType<typeof setTimeout> | null>(null);\n const isDraggingRef = useRef(false);\n const [isDragging, setIsDragging] = useState(false);\n const emitAfterDragRef = useRef(false);\n const pendingInitialFitRef = useRef(true);\n const userMovedViewportRef = useRef(false);\n const layoutInitializedRef = useRef(false);\n const [viewport, setViewport] = useState<Viewport | null>(() => {\n const existing = lastViewportRef.current;\n if (existing) {\n return existing;\n }\n const fallback = { x: 0, y: 0, zoom: 1 };\n lastViewportRef.current = fallback;\n return fallback;\n });\n const fitViewRafRef = useRef<number | null>(null);\n const fitViewTimeoutRef = useRef<ReturnType<typeof setTimeout> | null>(null);\n const alignDebounceRef = useRef<ReturnType<typeof setTimeout> | null>(null);\n\n const setViewportIfChanged = useCallback((next: Viewport | null) => {\n if (!next) {\n return;\n }\n const prev = lastViewportRef.current;\n if (\n prev &&\n prev.x === next.x &&\n prev.y === next.y &&\n prev.zoom === next.zoom\n ) {\n return;\n }\n lastViewportRef.current = next;\n setViewport(next);\n }, []);\n useEffect(() => {\n const isCacheChanged = cacheFingerprint !== lastCacheFingerprintRef.current;\n\n if (modelHash === lastAppliedModelHashRef.current && !isCacheChanged) {\n return;\n }\n\n const builtNodes = buildNodesFromModel(\n steps,\n normalizedParametersProp,\n normalizedOutputProp,\n {\n scaffolderActionIds,\n scaffolderActionInputsById,\n scaffolderActionOutputsById,\n scaffolderActionInputRequiredById,\n }\n );\n\n const nextNodes = decorateNodes ? decorateNodes(builtNodes) : builtNodes;\n const isInitialMount = !hasMountedRef.current;\n\n lastAppliedModelHashRef.current = modelHash;\n lastCacheFingerprintRef.current = cacheFingerprint;\n lastEmittedModelHashRef.current = modelHash;\n\n setNodes((currentNodes) => {\n const merged = mergeNodesWithStability(\n currentNodes,\n nextNodes,\n nodeDataHashRef\n );\n return merged;\n });\n setEdges((currentEdges) => {\n const newEdges = decorateEdges\n ? decorateEdges(createSequentialEdges(nextNodes), nextNodes)\n : createSequentialEdges(nextNodes);\n const merged = mergeEdgesWithStability(\n currentEdges,\n newEdges,\n edgeDataHashRef\n );\n return merged;\n });\n hasMountedRef.current = true;\n lastNodeCountRef.current = nextNodes.length;\n if (isInitialMount) {\n pendingInitialFitRef.current = true;\n }\n }, [\n steps,\n normalizedParametersProp,\n normalizedOutputProp,\n modelHash,\n cacheFingerprint,\n scaffolderActionIds,\n scaffolderActionInputsById,\n scaffolderActionOutputsById,\n scaffolderActionInputRequiredById,\n decorateNodes,\n decorateEdges,\n setNodes,\n setEdges,\n ]);\n\n useEffect(() => {\n if (!nodes.length) {\n return;\n }\n\n if (nodes.some((node) => node.dragging)) {\n return;\n }\n\n const activeNodeIds = new Set<string>();\n let hasMeasuredChange = false;\n\n nodes.forEach((node) => {\n activeNodeIds.add(node.id);\n const measuredHeight = resolveNodeHeightForTracking(node);\n if (typeof measuredHeight !== \"number\") {\n return;\n }\n const previousHeight = nodeHeightsRef.current[node.id];\n const heightDelta = Math.abs(\n (previousHeight ?? measuredHeight) - measuredHeight\n );\n if (heightDelta >= 1) {\n // Ignore tiny size jitter; only react when node height meaningfully changes.\n nodeHeightsRef.current[node.id] = measuredHeight;\n hasMeasuredChange = true;\n }\n });\n\n Object.keys(nodeHeightsRef.current).forEach((id) => {\n if (!activeNodeIds.has(id)) {\n delete nodeHeightsRef.current[id];\n }\n });\n\n if (!hasMeasuredChange) {\n return;\n }\n\n if (!layoutInitializedRef.current) {\n // Skip the first post-measure align to avoid initial jump; positions are already close to target.\n layoutInitializedRef.current = true;\n return;\n }\n\n if (alignDebounceRef.current) {\n clearTimeout(alignDebounceRef.current);\n }\n alignDebounceRef.current = setTimeout(() => {\n alignDebounceRef.current = null;\n setNodes((currentNodes) => {\n const alignedNodes = alignNodes(\n currentNodes,\n FIXED_X_POSITION,\n VERTICAL_SPACING\n );\n const positionsChanged = alignedNodes.some((node, index) => {\n const previousNode = currentNodes[index];\n if (!previousNode) {\n return true;\n }\n return (\n node.position.x !== previousNode.position.x ||\n node.position.y !== previousNode.position.y\n );\n });\n\n return positionsChanged ? alignedNodes : currentNodes;\n });\n }, VIEWPORT_TUNING.alignDebounceMs);\n }, [nodes, setNodes]);\n\n const parameterReferences = useMemo(\n () => collectParameterReferences(normalizedParametersProp),\n [normalizedParametersProp]\n );\n\n const stepOutputReferencesByNode = useMemo(\n () => collectStepOutputReferences(nodes, parameterReferences),\n [nodes, parameterReferences]\n );\n\n const onNodesChange = useCallback(\n (changes: NodeChange<Node>[]) =>\n setNodes((ns) => {\n if (\n changes.some(\n (change) => change.type === \"position\" && change.dragging\n )\n ) {\n isDraggingRef.current = true;\n setIsDragging(true);\n } else if (\n changes.some(\n (change) => change.type === \"position\" && change.dragging === false\n )\n ) {\n const stillDragging = ns.some((node) => node.dragging);\n isDraggingRef.current = stillDragging;\n setIsDragging(stillDragging);\n }\n return applyNodeChanges(changes, ns);\n }),\n [setNodes]\n );\n\n const onEdgesChange = useCallback(\n (changes: EdgeChange<Edge>[]) =>\n setEdges((es) => applyEdgeChanges(changes, es)),\n [setEdges]\n );\n\n const resolvedNodeTypes = useMemo<NodeTypes>(\n () => ({\n parametersNode: ((props: NodeProps) =>\n createElement(parametersNodeComponent, {\n data: props.data as ParametersNodeData,\n })) as ComponentType<NodeProps>,\n actionNode: ((props: NodeProps) =>\n createElement(actionNodeComponent, {\n data: props.data as ActionNodeData,\n })) as ComponentType<NodeProps>,\n outputNode: ((props: NodeProps) =>\n createElement(outputNodeComponent, {\n data: props.data as OutputNodeData,\n })) as ComponentType<NodeProps>,\n }),\n [actionNodeComponent, outputNodeComponent, parametersNodeComponent]\n );\n\n const onConnect = useCallback(\n (params: any) => setEdges((es) => addEdge(params, es)),\n [setEdges]\n );\n\n const reorderAndAlignNodes = useMemo(\n () =>\n createHandleReorderAndAlignNodes(setNodes, setEdges, {\n fixedXPosition: FIXED_X_POSITION,\n verticalSpacing: VERTICAL_SPACING,\n }),\n [setNodes, setEdges]\n );\n\n const onNodeDragStop = useCallback(\n (_: ReactMouseEvent, node: Node) => {\n isDraggingRef.current = false;\n setIsDragging(false);\n reorderAndAlignNodes(node);\n },\n [reorderAndAlignNodes]\n );\n\n const onUpdateField = useMemo(\n () => createHandleUpdateField(setNodes),\n [setNodes]\n );\n\n const onUpdateInput = useMemo(\n () => createHandleUpdateInput(setNodes),\n [setNodes]\n );\n\n const onRemoveInputKey = useMemo(\n () => createHandleRemoveInputKey(setNodes),\n [setNodes]\n );\n\n const onUpdateOutput = useMemo(\n () => createHandleUpdateOutput(setNodes),\n [setNodes]\n );\n\n const onUpdateSections = useMemo(\n () => createHandleUpdateSections(setNodes),\n [setNodes]\n );\n\n const handleAddNode = useMemo(\n () =>\n createHandleAddNode(setNodes, setEdges, {\n fixedXPosition: FIXED_X_POSITION,\n verticalSpacing: VERTICAL_SPACING,\n nodeDefaults,\n scaffolderActionIds,\n scaffolderActionInputsById,\n scaffolderActionInputRequiredById,\n scaffolderActionOutputsById,\n onNodeAdded: (rfId: string) => {\n pendingFocusNodeIdRef.current = rfId;\n // Keep current zoom/viewport; focus will center on the new node.\n pendingInitialFitRef.current = false;\n },\n }),\n [\n scaffolderActionIds,\n scaffolderActionInputsById,\n scaffolderActionOutputsById,\n scaffolderActionInputRequiredById,\n nodeDefaults,\n setNodes,\n setEdges,\n ]\n );\n\n const handleRemoveNode = useMemo(\n () =>\n createHandleRemoveNode(setNodes, setEdges, {\n fixedXPosition: FIXED_X_POSITION,\n verticalSpacing: VERTICAL_SPACING,\n }),\n [setNodes, setEdges]\n );\n\n const emitChanges = useCallback(() => {\n if (!onStepsChange && !onParametersChange && !onOutputChange) {\n return;\n }\n const stepsFromNodes = extractStepsFromNodes(nodes);\n const parametersFromNodes = extractParametersFromNodes(nodes);\n const outputFromNodes = extractOutputFromNodes(nodes);\n\n const nextHash = stableStringify({\n steps: stepsFromNodes,\n parameters: parametersFromNodes,\n output: outputFromNodes,\n });\n\n if (nextHash === lastEmittedModelHashRef.current) {\n return;\n }\n\n lastEmittedModelHashRef.current = nextHash;\n onStepsChange?.(stepsFromNodes);\n onParametersChange?.(parametersFromNodes);\n onOutputChange?.(outputFromNodes);\n }, [\n nodes,\n onOutputChange,\n onParametersChange,\n onStepsChange,\n lastEmittedModelHashRef,\n ]);\n\n const emitChangesDeferred = useCallback(() => {\n if (emitDebounceRef.current) {\n clearTimeout(emitDebounceRef.current);\n }\n emitDebounceRef.current = setTimeout(() => {\n emitChanges();\n emitDebounceRef.current = null;\n }, EMIT_DEBOUNCE_MS);\n }, [emitChanges]);\n\n const flushPendingEmit = useCallback(() => {\n if (emitDebounceRef.current) {\n clearTimeout(emitDebounceRef.current);\n emitDebounceRef.current = null;\n }\n emitChanges();\n }, [emitChanges]);\n\n // Hoist handler/data refs into state so ReactFlow sees unchanged node objects when nothing relevant changed.\n const ensureNodeDataStability = useCallback(\n (node: Node): Node => {\n if (node.type === \"actionNode\") {\n const data = node.data as ActionNodeData;\n const nextRefs =\n stepOutputReferencesByNode[node.id] ?? data.stepOutputReferences;\n const refsUnchanged = shallowArrayEqual(\n data.stepOutputReferences,\n nextRefs\n );\n\n const hasSameHandlers =\n data.onAddNode === handleAddNode &&\n data.onRemoveNode === handleRemoveNode &&\n data.onUpdateField === onUpdateField &&\n data.onUpdateInput === onUpdateInput &&\n data.onRemoveInputKey === onRemoveInputKey;\n const hasSameCaches =\n data.scaffolderActionIds === scaffolderActionIds &&\n data.scaffolderActionInputsById === scaffolderActionInputsById &&\n data.scaffolderActionOutputsById === scaffolderActionOutputsById &&\n data.scaffolderActionInputRequiredById ===\n scaffolderActionInputRequiredById;\n\n if (hasSameHandlers && hasSameCaches && refsUnchanged) {\n return node;\n }\n\n return {\n ...node,\n data: {\n ...data,\n onAddNode: handleAddNode,\n onRemoveNode: handleRemoveNode,\n onUpdateField,\n onUpdateInput,\n onRemoveInputKey,\n scaffolderActionIds,\n scaffolderActionInputsById,\n scaffolderActionOutputsById,\n scaffolderActionInputRequiredById,\n stepOutputReferences: refsUnchanged\n ? data.stepOutputReferences\n : nextRefs,\n },\n };\n }\n\n if (node.type === \"outputNode\") {\n const data = node.data as OutputNodeData;\n const nextRefs =\n stepOutputReferencesByNode[node.id] ?? data.stepOutputReferences;\n const refsUnchanged = shallowArrayEqual(\n data.stepOutputReferences,\n nextRefs\n );\n const hasSameHandlers =\n data.onUpdateOutput === onUpdateOutput &&\n data.onRemoveNode === handleRemoveNode &&\n data.onAddNode === handleAddNode;\n\n const hasSameCaches =\n data.scaffolderActionIds === scaffolderActionIds &&\n data.scaffolderActionInputsById === scaffolderActionInputsById &&\n data.scaffolderActionOutputsById === scaffolderActionOutputsById &&\n data.scaffolderActionInputRequiredById ===\n scaffolderActionInputRequiredById;\n\n if (hasSameHandlers && hasSameCaches && refsUnchanged) {\n return node;\n }\n\n return {\n ...node,\n data: {\n ...data,\n onUpdateOutput,\n onRemoveNode: handleRemoveNode,\n onAddNode: handleAddNode,\n scaffolderActionIds,\n scaffolderActionInputsById,\n scaffolderActionOutputsById,\n scaffolderActionInputRequiredById,\n stepOutputReferences: refsUnchanged\n ? data.stepOutputReferences\n : nextRefs,\n },\n };\n }\n\n if (node.type === \"parametersNode\") {\n const data = node.data as ParametersNodeData;\n const hasSameHandlers =\n data.onUpdateSections === onUpdateSections &&\n data.onRemoveNode === handleRemoveNode &&\n data.onAddNode === handleAddNode;\n const hasSameCaches =\n data.scaffolderActionIds === scaffolderActionIds &&\n data.scaffolderActionInputsById === scaffolderActionInputsById &&\n data.scaffolderActionOutputsById === scaffolderActionOutputsById &&\n data.scaffolderActionInputRequiredById ===\n scaffolderActionInputRequiredById;\n\n if (hasSameHandlers && hasSameCaches) {\n return node;\n }\n\n return {\n ...node,\n data: {\n ...data,\n onUpdateSections,\n onRemoveNode: handleRemoveNode,\n onAddNode: handleAddNode,\n scaffolderActionIds,\n scaffolderActionInputsById,\n scaffolderActionOutputsById,\n scaffolderActionInputRequiredById,\n },\n };\n }\n\n return node;\n },\n [\n handleAddNode,\n handleRemoveNode,\n onUpdateField,\n onUpdateInput,\n onRemoveInputKey,\n onUpdateOutput,\n onUpdateSections,\n scaffolderActionIds,\n scaffolderActionInputsById,\n scaffolderActionOutputsById,\n scaffolderActionInputRequiredById,\n stepOutputReferencesByNode,\n ]\n );\n\n useEffect(() => {\n setNodes((currentNodes) => {\n let changed = false;\n const nextNodes = currentNodes.map((node) => {\n const updated = ensureNodeDataStability(node);\n if (updated !== node) {\n changed = true;\n }\n return updated;\n });\n\n // Returning the same array keeps ReactFlow nodes prop stable unless something truly changed.\n return changed ? nextNodes : currentNodes;\n });\n }, [ensureNodeDataStability, setNodes]);\n\n useEffect(() => {\n emitChangesDeferred();\n }, [nodes, emitChangesDeferred]);\n\n useEffect(() => {\n // Force next emit to run even if hash matches, so input edits flush to YAML.\n lastEmittedModelHashRef.current = null;\n }, [nodes]);\n\n useEffect(() => {\n if (!nodes.length) {\n return;\n }\n emitChangesDeferred();\n }, [emitChangesDeferred, modelHash, nodes]);\n\n useEffect(() => {\n return () => {\n if (emitDebounceRef.current) {\n clearTimeout(emitDebounceRef.current);\n }\n if (fitViewRafRef.current !== null) {\n cancelAnimationFrame(fitViewRafRef.current);\n fitViewRafRef.current = null;\n }\n if (fitViewTimeoutRef.current) {\n clearTimeout(fitViewTimeoutRef.current);\n fitViewTimeoutRef.current = null;\n }\n if (alignDebounceRef.current) {\n clearTimeout(alignDebounceRef.current);\n }\n flushPendingEmit();\n };\n }, [flushPendingEmit]);\n\n const [reactFlowInstance, setReactFlowInstance] =\n useState<ReactFlowInstance | null>(null);\n const fitFlowToView = useCallback(() => {\n if (!reactFlowInstance || !nodes.length) {\n return;\n }\n if (fitViewRafRef.current !== null) {\n return;\n }\n if (userMovedViewportRef.current && !pendingInitialFitRef.current) {\n // Respect user navigation; don't snap back after they moved the camera.\n return;\n }\n const nodeWithWidth = nodes.find((node) => node.width);\n const nodeWidth = nodeWithWidth?.width ?? 760;\n const padding = Math.max((window.innerWidth - nodeWidth) / 2 - 24, 60);\n const viewOptions = {\n padding,\n minZoom: 0.2,\n };\n // Delay fitView to the next frame to avoid ResizeObserver loops while nodes mount/measure.\n fitViewRafRef.current = window.requestAnimationFrame(() => {\n fitViewRafRef.current = null;\n try {\n reactFlowInstance.fitView(viewOptions);\n setViewportIfChanged(reactFlowInstance.getViewport());\n } catch {\n // Swallow rare layout timing errors; the next change will try again.\n }\n });\n // Fallback in case RAF is skipped (tab in background).\n if (fitViewTimeoutRef.current) {\n clearTimeout(fitViewTimeoutRef.current);\n }\n fitViewTimeoutRef.current = setTimeout(() => {\n fitViewTimeoutRef.current = null;\n try {\n reactFlowInstance.fitView(viewOptions);\n setViewportIfChanged(reactFlowInstance.getViewport());\n } catch {\n // Ignore; typically triggered only during tab throttling.\n }\n }, VIEWPORT_TUNING.fitFallbackDelayMs);\n }, [nodes, reactFlowInstance, setViewportIfChanged]);\n\n useEffect(() => {\n if (!reactFlowInstance) {\n return;\n }\n if (viewport === null) {\n setViewportIfChanged(viewport);\n }\n if (!pendingInitialFitRef.current) {\n return;\n }\n pendingInitialFitRef.current = false;\n fitFlowToView();\n }, [\n fitFlowToView,\n nodes,\n edges,\n reactFlowInstance,\n viewport,\n setViewportIfChanged,\n ]);\n\n useEffect(() => {\n const swallowResizeObserverError = (event: ErrorEvent) => {\n const message =\n event?.message || (event as any)?.error?.message || String(event);\n if (\n typeof message === \"string\" &&\n message.includes(\"ResizeObserver loop\")\n ) {\n // Prevent dev overlay noise for benign ResizeObserver timing loops that appear after fitView/layout.\n event.preventDefault();\n event.stopImmediatePropagation();\n }\n };\n const swallowResizeObserverRejection = (event: PromiseRejectionEvent) => {\n const message = (event.reason as any)?.message ?? String(event.reason);\n if (\n typeof message === \"string\" &&\n message.includes(\"ResizeObserver loop\")\n ) {\n event.preventDefault();\n event.stopImmediatePropagation();\n }\n };\n window.addEventListener(\"error\", swallowResizeObserverError, true);\n window.addEventListener(\n \"unhandledrejection\",\n swallowResizeObserverRejection,\n true\n );\n // Chrome/FF dispatch a dedicated event for this condition; capture it to prevent overlay noise.\n const swallowLoopErrorEvent = (event: Event) => {\n event.preventDefault();\n event.stopImmediatePropagation();\n };\n window.addEventListener(\n \"resizeobserverlooperror\" as any,\n swallowLoopErrorEvent,\n true\n );\n return () => {\n window.removeEventListener(\"error\", swallowResizeObserverError, true);\n window.removeEventListener(\n \"unhandledrejection\",\n swallowResizeObserverRejection,\n true\n );\n window.removeEventListener(\n \"resizeobserverlooperror\" as any,\n swallowLoopErrorEvent,\n true\n );\n };\n }, []);\n\n useEffect(() => {\n if (!reactFlowInstance) {\n return undefined;\n }\n window.addEventListener(\"resize\", fitFlowToView);\n return () => {\n window.removeEventListener(\"resize\", fitFlowToView);\n };\n }, [fitFlowToView, reactFlowInstance]);\n\n useEffect(() => {\n if (!isDragging) {\n if (emitAfterDragRef.current) {\n emitAfterDragRef.current = false;\n lastEmittedModelHashRef.current = null;\n }\n // Trigger emit cycle after drag ends so external state is up to date.\n lastEmittedModelHashRef.current = null;\n }\n }, [isDragging]);\n\n const handleMoveEnd: OnMoveEnd = useCallback(\n (_event, nextViewport: Viewport) => {\n // Keep zoom stable to optionally cull edges when zoomed out.\n setViewportIfChanged(nextViewport);\n },\n [setViewportIfChanged]\n );\n\n const handleMove: OnMove = useCallback(\n (_, nextViewport) => {\n userMovedViewportRef.current = true;\n setViewportIfChanged(nextViewport);\n },\n [setViewportIfChanged]\n );\n\n const shouldCullEdges =\n edges.length > 300 && (viewport?.zoom ?? 1) < 0.3 && !isDragging;\n const renderedEdges = useMemo(\n () =>\n shouldCullEdges\n ? EMPTY_EDGES // Dropping edges when zoomed out keeps canvas responsive with huge graphs.\n : edges,\n [edges, shouldCullEdges]\n );\n\n useEffect(() => {\n if (!reactFlowInstance) {\n return;\n }\n const pendingId = pendingFocusNodeIdRef.current;\n if (!pendingId) {\n return;\n }\n const target = nodes.find((node) => node.id === pendingId);\n if (!target) {\n return;\n }\n pendingFocusNodeIdRef.current = null;\n const nodeCenterX = target.position.x + (target.width ?? 0) / 2;\n const nodeCenterY = target.position.y + (target.height ?? 0) / 2;\n const zoom = viewport?.zoom ?? lastViewportRef.current?.zoom ?? undefined;\n try {\n reactFlowInstance.setCenter(nodeCenterX, nodeCenterY, {\n zoom,\n duration: VIEWPORT_TUNING.centerDurationMs,\n });\n window.requestAnimationFrame(() => {\n setViewportIfChanged(reactFlowInstance.getViewport());\n });\n } catch {\n // ignore\n }\n }, [nodes, reactFlowInstance, viewport, setViewportIfChanged]);\n\n return (\n <div style={{ width: \"100%\", height: \"100%\", minHeight: \"100%\" }}>\n <ReactFlow\n nodes={nodes}\n edges={renderedEdges}\n nodeTypes={resolvedNodeTypes}\n defaultViewport={\n viewport ?? {\n x: 0,\n y: 0,\n zoom: 1,\n }\n }\n viewport={viewport ?? undefined}\n onNodesChange={onNodesChange}\n onEdgesChange={onEdgesChange}\n onNodeDragStop={onNodeDragStop}\n onConnect={onConnect}\n onMove={handleMove}\n onlyRenderVisibleElements\n onInit={setReactFlowInstance}\n onMoveEnd={handleMoveEnd}\n />\n </div>\n );\n}\n"],"names":["nodeDefaults","baseNodeDefaults","nodes","edges"],"mappings":"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"}
1
+ {"version":3,"file":"DesignerFlow.esm.js","sources":["../../src/designerFlow/DesignerFlow.tsx"],"sourcesContent":["import {\n useCallback,\n useEffect,\n useMemo,\n useRef,\n useState,\n ComponentType,\n createElement,\n} from \"react\";\nimport type { MouseEvent as ReactMouseEvent } from \"react\";\nimport {\n ReactFlow,\n applyNodeChanges,\n applyEdgeChanges,\n addEdge,\n Node,\n Edge,\n NodeChange,\n EdgeChange,\n useNodesState,\n ReactFlowInstance,\n NodeProps,\n NodeTypes,\n Viewport,\n OnMoveEnd,\n OnMove,\n} from \"@xyflow/react\";\nimport \"@xyflow/react/dist/style.css\";\nimport type {\n ScaffolderTaskOutput,\n TaskStep,\n} from \"@backstage/plugin-scaffolder-common\";\nimport type {\n ActionNodeData,\n OutputNodeData,\n ParametersNodeData,\n TemplateParametersValue,\n} from \"../types/flowNodes\";\nimport {\n buildNodesFromModel,\n collectParameterReferences,\n collectStepOutputReferences,\n stableStringify,\n extractStepsFromNodes,\n extractParametersFromNodes,\n extractOutputFromNodes,\n} from \"./model\";\nimport { createSequentialEdges } from \"../utils/createSequentialEdges\";\nimport {\n buildEdgeHashMap,\n buildNodeHashMap,\n mergeEdgesWithStability,\n mergeNodesWithStability,\n} from \"./utils/stableComparators\";\nimport {\n createHandleAddNode,\n createHandleRemoveNode,\n createHandleRemoveInputKey,\n createHandleReorderAndAlignNodes,\n createHandleUpdateField,\n createHandleUpdateInput,\n createHandleUpdateOutput,\n createHandleUpdateSections,\n} from \"./handlers\";\nimport { alignNodes, resolveNodeHeightForTracking } from \"./nodeLayout\";\nimport {\n FLOW_LAYOUT,\n nodeDefaults as baseNodeDefaults,\n} from \"../components/designerFlowConfig\";\nimport { useScaffolderActions } from \"../api/useScaffolderActions\";\n\nconst EMPTY_EDGES: Edge[] = [];\nconst EMIT_DEBOUNCE_MS = 1200; // Emit only after user pauses typing for a bit (more relaxed UX).\nconst VIEWPORT_TUNING = {\n alignDebounceMs: 120, // Debounce view/align updates so typing isn't interrupted by layout thrash.\n centerDurationMs: 280,\n fitFallbackDelayMs: 50,\n};\n\n// Prevent benign ResizeObserver loop errors from bubbling to the dev overlay.\nif (\n typeof window !== \"undefined\" &&\n !(window as any).__rfResizeObserverPatched\n) {\n (window as any).__rfResizeObserverPatched = true;\n // Wrap ResizeObserver callbacks in rAF to avoid sync measurement loops that trigger the warning.\n if (typeof window.ResizeObserver === \"function\") {\n const OriginalResizeObserver = window.ResizeObserver;\n window.ResizeObserver = class extends OriginalResizeObserver {\n constructor(callback: ResizeObserverCallback) {\n super((entries, observer) => {\n window.requestAnimationFrame(() => callback(entries, observer));\n });\n }\n } as typeof ResizeObserver;\n }\n const shouldSwallow = (message: unknown) =>\n typeof message === \"string\" &&\n message.includes(\"ResizeObserver loop completed with undelivered\");\n const swallowResizeObserverError = (event: ErrorEvent) => {\n const message =\n event?.message || (event as any)?.error?.message || String(event);\n if (shouldSwallow(message)) {\n event.preventDefault();\n event.stopImmediatePropagation();\n return true;\n }\n return undefined;\n };\n const swallowResizeObserverRejection = (event: PromiseRejectionEvent) => {\n const message = (event.reason as any)?.message ?? String(event.reason);\n if (shouldSwallow(message)) {\n event.preventDefault();\n event.stopImmediatePropagation();\n return true;\n }\n return undefined;\n };\n const swallowLoopEvent = (event: Event) => {\n event.preventDefault();\n event.stopImmediatePropagation();\n };\n const originalOnError = window.onerror;\n window.onerror = function handleResizeObserverOnError(\n message,\n source,\n lineno,\n colno,\n error\n ): boolean | void {\n if (\n shouldSwallow(\n typeof message === \"string\"\n ? message\n : (error as any)?.message ?? String(message)\n )\n ) {\n return true;\n }\n if (typeof originalOnError === \"function\") {\n return originalOnError(message, source, lineno, colno, error);\n }\n return undefined;\n };\n const originalOnUnhandledRejection = window.onunhandledrejection;\n window.onunhandledrejection = function handleResizeObserverOnUnhandled(\n event\n ) {\n const reason = (event as any)?.reason;\n const message =\n (reason as any)?.message ?? (typeof reason === \"string\" ? reason : \"\");\n if (shouldSwallow(message)) {\n return true;\n }\n if (typeof originalOnUnhandledRejection === \"function\") {\n return (originalOnUnhandledRejection as any)(event);\n }\n return undefined;\n };\n window.addEventListener(\"error\", swallowResizeObserverError, true);\n window.addEventListener(\n \"unhandledrejection\",\n swallowResizeObserverRejection,\n true\n );\n window.addEventListener(\n \"resizeobserverlooperror\" as any,\n swallowLoopEvent,\n true\n );\n}\n\nconst shallowArrayEqual = (a?: string[], b?: string[]) => {\n if (a === b) {\n return true;\n }\n if (!a || !b || a.length !== b.length) {\n return false;\n }\n for (let i = 0; i < a.length; i += 1) {\n if (a[i] !== b[i]) {\n return false;\n }\n }\n return true;\n};\n\n// Main orchestration component that renders and synchronizes the Designer flow.\n\nconst FIXED_X_POSITION = FLOW_LAYOUT.fixedXPosition;\nconst VERTICAL_SPACING = FLOW_LAYOUT.verticalSpacing;\n\nexport type DesignerFlowProps = {\n steps?: TaskStep[];\n parameters?: TemplateParametersValue;\n output?: ScaffolderTaskOutput | null;\n onStepsChange?: (steps: TaskStep[]) => void;\n onParametersChange?: (parameters: TemplateParametersValue) => void;\n onOutputChange?: (output: ScaffolderTaskOutput | undefined) => void;\n actionNodeComponent: ComponentType<{ data: ActionNodeData }>;\n parametersNodeComponent: ComponentType<{ data: ParametersNodeData }>;\n outputNodeComponent: ComponentType<{ data: OutputNodeData }>;\n decorateNodes?: (nodes: Node[]) => Node[];\n decorateEdges?: (edges: Edge[], nodes: Node[]) => Edge[];\n nodeDefaults?: Partial<Node>;\n};\n\nexport default function DesignerFlow({\n steps = [],\n parameters,\n output,\n onStepsChange,\n onParametersChange,\n onOutputChange,\n actionNodeComponent,\n parametersNodeComponent,\n outputNodeComponent,\n decorateNodes,\n decorateEdges,\n nodeDefaults = baseNodeDefaults,\n}: DesignerFlowProps) {\n const nodeDataHashRef = useRef<Record<string, string>>({});\n const edgeDataHashRef = useRef<Record<string, string>>({});\n const scaffolderActionsCache = useScaffolderActions();\n\n const {\n ids: scaffolderActionIds,\n inputsById: scaffolderActionInputsById,\n outputsById: scaffolderActionOutputsById,\n inputRequiredById: scaffolderActionInputRequiredById,\n } = scaffolderActionsCache;\n\n const normalizedParametersProp = parameters ?? undefined;\n const normalizedOutputProp = output ?? null;\n const pendingFocusNodeIdRef = useRef<string | null>(null);\n const hasMountedRef = useRef(false);\n const lastNodeCountRef = useRef(0);\n\n const initialNodes = useMemo(() => {\n const built = buildNodesFromModel(\n steps,\n normalizedParametersProp,\n normalizedOutputProp,\n {\n scaffolderActionIds,\n scaffolderActionInputsById,\n scaffolderActionOutputsById,\n scaffolderActionInputRequiredById,\n }\n );\n const nodes = decorateNodes ? decorateNodes(built) : built;\n nodeDataHashRef.current = buildNodeHashMap(nodes);\n return nodes;\n }, [\n steps,\n normalizedParametersProp,\n normalizedOutputProp,\n scaffolderActionIds,\n scaffolderActionInputsById,\n scaffolderActionOutputsById,\n scaffolderActionInputRequiredById,\n decorateNodes,\n ]);\n\n const [nodes, setNodes] = useNodesState(initialNodes);\n const initialEdges = useMemo(() => {\n const edges = decorateEdges\n ? decorateEdges(createSequentialEdges(initialNodes), initialNodes)\n : createSequentialEdges(initialNodes);\n edgeDataHashRef.current = buildEdgeHashMap(edges);\n lastNodeCountRef.current = initialNodes.length;\n return edges;\n }, [decorateEdges, initialNodes]);\n\n const [edges, setEdges] = useState<Edge[]>(initialEdges);\n\n const modelHash = useMemo(\n () =>\n stableStringify({\n steps,\n parameters: normalizedParametersProp,\n output: normalizedOutputProp,\n }),\n [steps, normalizedParametersProp, normalizedOutputProp]\n );\n\n const cacheFingerprint = useMemo(\n () =>\n stableStringify({\n ids: scaffolderActionIds,\n inputs: scaffolderActionInputsById,\n outputs: scaffolderActionOutputsById,\n inputRequired: scaffolderActionInputRequiredById,\n }),\n [\n scaffolderActionIds,\n scaffolderActionInputsById,\n scaffolderActionOutputsById,\n scaffolderActionInputRequiredById,\n ]\n );\n\n const lastAppliedModelHashRef = useRef<string | null>(null);\n const lastEmittedModelHashRef = useRef<string | null>(null);\n const lastCacheFingerprintRef = useRef<string | null>(null);\n const nodeHeightsRef = useRef<Record<string, number>>({});\n const lastViewportRef = useRef<Viewport | null>(null);\n const emitDebounceRef = useRef<ReturnType<typeof setTimeout> | null>(null);\n const isDraggingRef = useRef(false);\n const [isDragging, setIsDragging] = useState(false);\n const emitAfterDragRef = useRef(false);\n const pendingInitialFitRef = useRef(true);\n const userMovedViewportRef = useRef(false);\n const layoutInitializedRef = useRef(false);\n const [viewport, setViewport] = useState<Viewport | null>(() => {\n const existing = lastViewportRef.current;\n if (existing) {\n return existing;\n }\n const fallback = { x: 0, y: 0, zoom: 1 };\n lastViewportRef.current = fallback;\n return fallback;\n });\n const fitViewRafRef = useRef<number | null>(null);\n const fitViewTimeoutRef = useRef<ReturnType<typeof setTimeout> | null>(null);\n const alignDebounceRef = useRef<ReturnType<typeof setTimeout> | null>(null);\n\n const setViewportIfChanged = useCallback((next: Viewport | null) => {\n if (!next) {\n return;\n }\n const prev = lastViewportRef.current;\n if (\n prev &&\n prev.x === next.x &&\n prev.y === next.y &&\n prev.zoom === next.zoom\n ) {\n return;\n }\n lastViewportRef.current = next;\n setViewport(next);\n }, []);\n useEffect(() => {\n const isCacheChanged = cacheFingerprint !== lastCacheFingerprintRef.current;\n const prevAppliedModelHash = lastAppliedModelHashRef.current;\n\n if (modelHash === lastAppliedModelHashRef.current && !isCacheChanged) {\n return;\n }\n\n const builtNodes = buildNodesFromModel(\n steps,\n normalizedParametersProp,\n normalizedOutputProp,\n {\n scaffolderActionIds,\n scaffolderActionInputsById,\n scaffolderActionOutputsById,\n scaffolderActionInputRequiredById,\n }\n );\n\n const nextNodes = decorateNodes ? decorateNodes(builtNodes) : builtNodes;\n const isInitialMount = !hasMountedRef.current;\n const shouldReplaceNodes =\n prevAppliedModelHash !== modelHash || isInitialMount;\n\n lastAppliedModelHashRef.current = modelHash;\n lastCacheFingerprintRef.current = cacheFingerprint;\n lastEmittedModelHashRef.current = modelHash;\n\n setNodes((currentNodes) => {\n if (shouldReplaceNodes) {\n nodeDataHashRef.current = buildNodeHashMap(nextNodes);\n nodeHeightsRef.current = {};\n return nextNodes;\n }\n return mergeNodesWithStability(currentNodes, nextNodes, nodeDataHashRef);\n });\n setEdges((currentEdges) => {\n const newEdges = decorateEdges\n ? decorateEdges(createSequentialEdges(nextNodes), nextNodes)\n : createSequentialEdges(nextNodes);\n if (shouldReplaceNodes) {\n edgeDataHashRef.current = buildEdgeHashMap(newEdges);\n return newEdges;\n }\n return mergeEdgesWithStability(currentEdges, newEdges, edgeDataHashRef);\n });\n hasMountedRef.current = true;\n lastNodeCountRef.current = nextNodes.length;\n if (isInitialMount) {\n pendingInitialFitRef.current = true;\n }\n }, [\n steps,\n normalizedParametersProp,\n normalizedOutputProp,\n modelHash,\n cacheFingerprint,\n scaffolderActionIds,\n scaffolderActionInputsById,\n scaffolderActionOutputsById,\n scaffolderActionInputRequiredById,\n decorateNodes,\n decorateEdges,\n setNodes,\n setEdges,\n ]);\n\n const lastParameterResizeRef = useRef<{\n id: string;\n prevHeight: number;\n nextHeight: number;\n } | null>(null);\n\n useEffect(() => {\n if (!nodes.length) {\n return;\n }\n\n if (nodes.some((node) => node.dragging)) {\n return;\n }\n\n const activeNodeIds = new Set<string>();\n let hasMeasuredChange = false;\n let parameterResize: {\n id: string;\n prevHeight: number;\n nextHeight: number;\n } | null = null;\n\n nodes.forEach((node) => {\n activeNodeIds.add(node.id);\n const measuredHeight = resolveNodeHeightForTracking(node);\n if (typeof measuredHeight !== \"number\") {\n return;\n }\n const previousHeight = nodeHeightsRef.current[node.id];\n const heightDelta =\n previousHeight === undefined\n ? Number.POSITIVE_INFINITY\n : Math.abs(previousHeight - measuredHeight);\n if (heightDelta >= 1) {\n if (node.type === \"parametersNode\") {\n parameterResize = {\n id: node.id,\n prevHeight: previousHeight ?? measuredHeight,\n nextHeight: measuredHeight,\n };\n }\n nodeHeightsRef.current[node.id] = measuredHeight;\n hasMeasuredChange = true;\n } else if (previousHeight === undefined) {\n // Initialize tracking even if we consider the change too small to react to layout.\n nodeHeightsRef.current[node.id] = measuredHeight;\n }\n });\n\n Object.keys(nodeHeightsRef.current).forEach((id) => {\n if (!activeNodeIds.has(id)) {\n delete nodeHeightsRef.current[id];\n }\n });\n\n if (!hasMeasuredChange) {\n return;\n }\n\n if (!layoutInitializedRef.current) {\n // Skip the first post-measure align to avoid initial jump; positions are already close to target.\n layoutInitializedRef.current = true;\n return;\n }\n\n lastParameterResizeRef.current = parameterResize;\n\n if (alignDebounceRef.current) {\n clearTimeout(alignDebounceRef.current);\n }\n alignDebounceRef.current = setTimeout(() => {\n alignDebounceRef.current = null;\n setNodes((currentNodes) => {\n const resize = lastParameterResizeRef.current;\n const updated = currentNodes.map((node) => {\n if (node.type !== \"parametersNode\") {\n return node;\n }\n if (!resize || resize.id !== node.id) {\n // Keep x locked even if there was no measured change.\n return {\n ...node,\n position: { ...node.position, x: FIXED_X_POSITION },\n };\n }\n const prevBottom = node.position.y + resize.prevHeight;\n const nextY = Math.max(0, prevBottom - resize.nextHeight);\n if (node.position.y === nextY) {\n return {\n ...node,\n position: { ...node.position, x: FIXED_X_POSITION },\n };\n }\n return {\n ...node,\n position: { x: FIXED_X_POSITION, y: nextY },\n };\n });\n\n const alignedNodes = alignNodes(\n updated,\n FIXED_X_POSITION,\n VERTICAL_SPACING\n );\n const positionsChanged = alignedNodes.some((node, index) => {\n const previousNode = currentNodes[index];\n if (!previousNode) {\n return true;\n }\n return (\n node.position.x !== previousNode.position.x ||\n node.position.y !== previousNode.position.y\n );\n });\n\n return positionsChanged ? alignedNodes : currentNodes;\n });\n }, VIEWPORT_TUNING.alignDebounceMs);\n }, [nodes, setNodes]);\n\n const parameterReferences = useMemo(\n () => collectParameterReferences(normalizedParametersProp),\n [normalizedParametersProp]\n );\n\n const stepOutputReferencesByNode = useMemo(\n () => collectStepOutputReferences(nodes, parameterReferences),\n [nodes, parameterReferences]\n );\n\n const onNodesChange = useCallback(\n (changes: NodeChange<Node>[]) =>\n setNodes((ns) => {\n if (\n changes.some(\n (change) => change.type === \"position\" && change.dragging\n )\n ) {\n isDraggingRef.current = true;\n setIsDragging(true);\n } else if (\n changes.some(\n (change) => change.type === \"position\" && change.dragging === false\n )\n ) {\n const stillDragging = ns.some((node) => node.dragging);\n isDraggingRef.current = stillDragging;\n setIsDragging(stillDragging);\n }\n return applyNodeChanges(changes, ns);\n }),\n [setNodes]\n );\n\n const onEdgesChange = useCallback(\n (changes: EdgeChange<Edge>[]) =>\n setEdges((es) => applyEdgeChanges(changes, es)),\n [setEdges]\n );\n\n const resolvedNodeTypes = useMemo<NodeTypes>(\n () => ({\n parametersNode: ((props: NodeProps) =>\n createElement(parametersNodeComponent, {\n data: props.data as ParametersNodeData,\n })) as ComponentType<NodeProps>,\n actionNode: ((props: NodeProps) =>\n createElement(actionNodeComponent, {\n data: props.data as ActionNodeData,\n })) as ComponentType<NodeProps>,\n outputNode: ((props: NodeProps) =>\n createElement(outputNodeComponent, {\n data: props.data as OutputNodeData,\n })) as ComponentType<NodeProps>,\n }),\n [actionNodeComponent, outputNodeComponent, parametersNodeComponent]\n );\n\n const onConnect = useCallback(\n (params: any) => setEdges((es) => addEdge(params, es)),\n [setEdges]\n );\n\n const reorderAndAlignNodes = useMemo(\n () =>\n createHandleReorderAndAlignNodes(setNodes, setEdges, {\n fixedXPosition: FIXED_X_POSITION,\n verticalSpacing: VERTICAL_SPACING,\n }),\n [setNodes, setEdges]\n );\n\n const onNodeDragStop = useCallback(\n (_: ReactMouseEvent, node: Node) => {\n isDraggingRef.current = false;\n setIsDragging(false);\n reorderAndAlignNodes(node);\n },\n [reorderAndAlignNodes]\n );\n\n const onUpdateField = useMemo(\n () => createHandleUpdateField(setNodes),\n [setNodes]\n );\n\n const onUpdateInput = useMemo(\n () => createHandleUpdateInput(setNodes),\n [setNodes]\n );\n\n const onRemoveInputKey = useMemo(\n () => createHandleRemoveInputKey(setNodes),\n [setNodes]\n );\n\n const onUpdateOutput = useMemo(\n () => createHandleUpdateOutput(setNodes),\n [setNodes]\n );\n\n const onUpdateSections = useMemo(\n () => createHandleUpdateSections(setNodes),\n [setNodes]\n );\n\n const handleAddNode = useMemo(\n () =>\n createHandleAddNode(setNodes, setEdges, {\n fixedXPosition: FIXED_X_POSITION,\n verticalSpacing: VERTICAL_SPACING,\n nodeDefaults,\n scaffolderActionIds,\n scaffolderActionInputsById,\n scaffolderActionInputRequiredById,\n scaffolderActionOutputsById,\n onNodeAdded: (rfId: string) => {\n pendingFocusNodeIdRef.current = rfId;\n // Keep current zoom/viewport; focus will center on the new node.\n pendingInitialFitRef.current = false;\n },\n }),\n [\n scaffolderActionIds,\n scaffolderActionInputsById,\n scaffolderActionOutputsById,\n scaffolderActionInputRequiredById,\n nodeDefaults,\n setNodes,\n setEdges,\n ]\n );\n\n const handleRemoveNode = useMemo(\n () =>\n createHandleRemoveNode(setNodes, setEdges, {\n fixedXPosition: FIXED_X_POSITION,\n verticalSpacing: VERTICAL_SPACING,\n }),\n [setNodes, setEdges]\n );\n\n const emitChanges = useCallback(() => {\n if (!onStepsChange && !onParametersChange && !onOutputChange) {\n return;\n }\n const stepsFromNodes = extractStepsFromNodes(nodes);\n const parametersFromNodes = extractParametersFromNodes(nodes);\n const outputFromNodes = extractOutputFromNodes(nodes);\n\n const nextHash = stableStringify({\n steps: stepsFromNodes,\n parameters: parametersFromNodes,\n output: outputFromNodes,\n });\n\n if (nextHash === lastEmittedModelHashRef.current) {\n return;\n }\n\n lastEmittedModelHashRef.current = nextHash;\n onStepsChange?.(stepsFromNodes);\n onParametersChange?.(parametersFromNodes);\n onOutputChange?.(outputFromNodes);\n }, [\n nodes,\n onOutputChange,\n onParametersChange,\n onStepsChange,\n lastEmittedModelHashRef,\n ]);\n\n const emitChangesDeferred = useCallback(() => {\n if (emitDebounceRef.current) {\n clearTimeout(emitDebounceRef.current);\n }\n emitDebounceRef.current = setTimeout(() => {\n emitChanges();\n emitDebounceRef.current = null;\n }, EMIT_DEBOUNCE_MS);\n }, [emitChanges]);\n\n const flushPendingEmit = useCallback(() => {\n if (emitDebounceRef.current) {\n clearTimeout(emitDebounceRef.current);\n emitDebounceRef.current = null;\n }\n emitChanges();\n }, [emitChanges]);\n\n // Hoist handler/data refs into state so ReactFlow sees unchanged node objects when nothing relevant changed.\n const ensureNodeDataStability = useCallback(\n (node: Node): Node => {\n if (node.type === \"actionNode\") {\n const data = node.data as ActionNodeData;\n const nextRefs =\n stepOutputReferencesByNode[node.id] ?? data.stepOutputReferences;\n const refsUnchanged = shallowArrayEqual(\n data.stepOutputReferences,\n nextRefs\n );\n\n const hasSameHandlers =\n data.onAddNode === handleAddNode &&\n data.onRemoveNode === handleRemoveNode &&\n data.onUpdateField === onUpdateField &&\n data.onUpdateInput === onUpdateInput &&\n data.onRemoveInputKey === onRemoveInputKey;\n const hasSameCaches =\n data.scaffolderActionIds === scaffolderActionIds &&\n data.scaffolderActionInputsById === scaffolderActionInputsById &&\n data.scaffolderActionOutputsById === scaffolderActionOutputsById &&\n data.scaffolderActionInputRequiredById ===\n scaffolderActionInputRequiredById;\n\n if (hasSameHandlers && hasSameCaches && refsUnchanged) {\n return node;\n }\n\n return {\n ...node,\n data: {\n ...data,\n onAddNode: handleAddNode,\n onRemoveNode: handleRemoveNode,\n onUpdateField,\n onUpdateInput,\n onRemoveInputKey,\n scaffolderActionIds,\n scaffolderActionInputsById,\n scaffolderActionOutputsById,\n scaffolderActionInputRequiredById,\n stepOutputReferences: refsUnchanged\n ? data.stepOutputReferences\n : nextRefs,\n },\n };\n }\n\n if (node.type === \"outputNode\") {\n const data = node.data as OutputNodeData;\n const nextRefs =\n stepOutputReferencesByNode[node.id] ?? data.stepOutputReferences;\n const refsUnchanged = shallowArrayEqual(\n data.stepOutputReferences,\n nextRefs\n );\n const hasSameHandlers =\n data.onUpdateOutput === onUpdateOutput &&\n data.onRemoveNode === handleRemoveNode &&\n data.onAddNode === handleAddNode;\n\n const hasSameCaches =\n data.scaffolderActionIds === scaffolderActionIds &&\n data.scaffolderActionInputsById === scaffolderActionInputsById &&\n data.scaffolderActionOutputsById === scaffolderActionOutputsById &&\n data.scaffolderActionInputRequiredById ===\n scaffolderActionInputRequiredById;\n\n if (hasSameHandlers && hasSameCaches && refsUnchanged) {\n return node;\n }\n\n return {\n ...node,\n data: {\n ...data,\n onUpdateOutput,\n onRemoveNode: handleRemoveNode,\n onAddNode: handleAddNode,\n scaffolderActionIds,\n scaffolderActionInputsById,\n scaffolderActionOutputsById,\n scaffolderActionInputRequiredById,\n stepOutputReferences: refsUnchanged\n ? data.stepOutputReferences\n : nextRefs,\n },\n };\n }\n\n if (node.type === \"parametersNode\") {\n const data = node.data as ParametersNodeData;\n const hasSameHandlers =\n data.onUpdateSections === onUpdateSections &&\n data.onRemoveNode === handleRemoveNode &&\n data.onAddNode === handleAddNode;\n const hasSameCaches =\n data.scaffolderActionIds === scaffolderActionIds &&\n data.scaffolderActionInputsById === scaffolderActionInputsById &&\n data.scaffolderActionOutputsById === scaffolderActionOutputsById &&\n data.scaffolderActionInputRequiredById ===\n scaffolderActionInputRequiredById;\n\n if (hasSameHandlers && hasSameCaches) {\n return node;\n }\n\n return {\n ...node,\n data: {\n ...data,\n onUpdateSections,\n onRemoveNode: handleRemoveNode,\n onAddNode: handleAddNode,\n scaffolderActionIds,\n scaffolderActionInputsById,\n scaffolderActionOutputsById,\n scaffolderActionInputRequiredById,\n },\n };\n }\n\n return node;\n },\n [\n handleAddNode,\n handleRemoveNode,\n onUpdateField,\n onUpdateInput,\n onRemoveInputKey,\n onUpdateOutput,\n onUpdateSections,\n scaffolderActionIds,\n scaffolderActionInputsById,\n scaffolderActionOutputsById,\n scaffolderActionInputRequiredById,\n stepOutputReferencesByNode,\n ]\n );\n\n useEffect(() => {\n setNodes((currentNodes) => {\n let changed = false;\n const nextNodes = currentNodes.map((node) => {\n const updated = ensureNodeDataStability(node);\n if (updated !== node) {\n changed = true;\n }\n return updated;\n });\n\n // Returning the same array keeps ReactFlow nodes prop stable unless something truly changed.\n return changed ? nextNodes : currentNodes;\n });\n }, [ensureNodeDataStability, setNodes]);\n\n useEffect(() => {\n emitChangesDeferred();\n }, [nodes, emitChangesDeferred]);\n\n useEffect(() => {\n // Force next emit to run even if hash matches, so input edits flush to YAML.\n lastEmittedModelHashRef.current = null;\n }, [nodes]);\n\n useEffect(() => {\n if (!nodes.length) {\n return;\n }\n emitChangesDeferred();\n }, [emitChangesDeferred, modelHash, nodes]);\n\n useEffect(() => {\n return () => {\n if (emitDebounceRef.current) {\n clearTimeout(emitDebounceRef.current);\n }\n if (fitViewRafRef.current !== null) {\n cancelAnimationFrame(fitViewRafRef.current);\n fitViewRafRef.current = null;\n }\n if (fitViewTimeoutRef.current) {\n clearTimeout(fitViewTimeoutRef.current);\n fitViewTimeoutRef.current = null;\n }\n if (alignDebounceRef.current) {\n clearTimeout(alignDebounceRef.current);\n }\n flushPendingEmit();\n };\n }, [flushPendingEmit]);\n\n const [reactFlowInstance, setReactFlowInstance] =\n useState<ReactFlowInstance | null>(null);\n const fitFlowToView = useCallback(() => {\n if (!reactFlowInstance || !nodes.length) {\n return;\n }\n if (fitViewRafRef.current !== null) {\n return;\n }\n if (userMovedViewportRef.current && !pendingInitialFitRef.current) {\n // Respect user navigation; don't snap back after they moved the camera.\n return;\n }\n const nodeWithWidth = nodes.find((node) => node.width);\n const nodeWidth = nodeWithWidth?.width ?? 760;\n const padding = Math.max((window.innerWidth - nodeWidth) / 2 - 24, 60);\n const viewOptions = {\n padding,\n minZoom: 0.2,\n };\n // Delay fitView to the next frame to avoid ResizeObserver loops while nodes mount/measure.\n fitViewRafRef.current = window.requestAnimationFrame(() => {\n fitViewRafRef.current = null;\n try {\n reactFlowInstance.fitView(viewOptions);\n setViewportIfChanged(reactFlowInstance.getViewport());\n } catch {\n // Swallow rare layout timing errors; the next change will try again.\n }\n });\n // Fallback in case RAF is skipped (tab in background).\n if (fitViewTimeoutRef.current) {\n clearTimeout(fitViewTimeoutRef.current);\n }\n fitViewTimeoutRef.current = setTimeout(() => {\n fitViewTimeoutRef.current = null;\n try {\n reactFlowInstance.fitView(viewOptions);\n setViewportIfChanged(reactFlowInstance.getViewport());\n } catch {\n // Ignore; typically triggered only during tab throttling.\n }\n }, VIEWPORT_TUNING.fitFallbackDelayMs);\n }, [nodes, reactFlowInstance, setViewportIfChanged]);\n\n useEffect(() => {\n if (!reactFlowInstance) {\n return;\n }\n if (viewport === null) {\n setViewportIfChanged(viewport);\n }\n if (!pendingInitialFitRef.current) {\n return;\n }\n pendingInitialFitRef.current = false;\n fitFlowToView();\n }, [\n fitFlowToView,\n nodes,\n edges,\n reactFlowInstance,\n viewport,\n setViewportIfChanged,\n ]);\n\n useEffect(() => {\n const swallowResizeObserverError = (event: ErrorEvent) => {\n const message =\n event?.message || (event as any)?.error?.message || String(event);\n if (\n typeof message === \"string\" &&\n message.includes(\"ResizeObserver loop\")\n ) {\n // Prevent dev overlay noise for benign ResizeObserver timing loops that appear after fitView/layout.\n event.preventDefault();\n event.stopImmediatePropagation();\n }\n };\n const swallowResizeObserverRejection = (event: PromiseRejectionEvent) => {\n const message = (event.reason as any)?.message ?? String(event.reason);\n if (\n typeof message === \"string\" &&\n message.includes(\"ResizeObserver loop\")\n ) {\n event.preventDefault();\n event.stopImmediatePropagation();\n }\n };\n window.addEventListener(\"error\", swallowResizeObserverError, true);\n window.addEventListener(\n \"unhandledrejection\",\n swallowResizeObserverRejection,\n true\n );\n // Chrome/FF dispatch a dedicated event for this condition; capture it to prevent overlay noise.\n const swallowLoopErrorEvent = (event: Event) => {\n event.preventDefault();\n event.stopImmediatePropagation();\n };\n window.addEventListener(\n \"resizeobserverlooperror\" as any,\n swallowLoopErrorEvent,\n true\n );\n return () => {\n window.removeEventListener(\"error\", swallowResizeObserverError, true);\n window.removeEventListener(\n \"unhandledrejection\",\n swallowResizeObserverRejection,\n true\n );\n window.removeEventListener(\n \"resizeobserverlooperror\" as any,\n swallowLoopErrorEvent,\n true\n );\n };\n }, []);\n\n useEffect(() => {\n if (!reactFlowInstance) {\n return undefined;\n }\n window.addEventListener(\"resize\", fitFlowToView);\n return () => {\n window.removeEventListener(\"resize\", fitFlowToView);\n };\n }, [fitFlowToView, reactFlowInstance]);\n\n useEffect(() => {\n if (!isDragging) {\n if (emitAfterDragRef.current) {\n emitAfterDragRef.current = false;\n lastEmittedModelHashRef.current = null;\n }\n // Trigger emit cycle after drag ends so external state is up to date.\n lastEmittedModelHashRef.current = null;\n }\n }, [isDragging]);\n\n const handleMoveEnd: OnMoveEnd = useCallback(\n (_event, nextViewport: Viewport) => {\n // Keep zoom stable to optionally cull edges when zoomed out.\n setViewportIfChanged(nextViewport);\n },\n [setViewportIfChanged]\n );\n\n const handleMove: OnMove = useCallback(\n (_, nextViewport) => {\n userMovedViewportRef.current = true;\n setViewportIfChanged(nextViewport);\n },\n [setViewportIfChanged]\n );\n\n const shouldCullEdges =\n edges.length > 300 && (viewport?.zoom ?? 1) < 0.3 && !isDragging;\n const renderedEdges = useMemo(\n () =>\n shouldCullEdges\n ? EMPTY_EDGES // Dropping edges when zoomed out keeps canvas responsive with huge graphs.\n : edges,\n [edges, shouldCullEdges]\n );\n\n useEffect(() => {\n if (!reactFlowInstance) {\n return;\n }\n const pendingId = pendingFocusNodeIdRef.current;\n if (!pendingId) {\n return;\n }\n const target = nodes.find((node) => node.id === pendingId);\n if (!target) {\n return;\n }\n pendingFocusNodeIdRef.current = null;\n const nodeCenterX = target.position.x + (target.width ?? 0) / 2;\n const nodeCenterY = target.position.y + (target.height ?? 0) / 2;\n const zoom = viewport?.zoom ?? lastViewportRef.current?.zoom ?? undefined;\n try {\n reactFlowInstance.setCenter(nodeCenterX, nodeCenterY, {\n zoom,\n duration: VIEWPORT_TUNING.centerDurationMs,\n });\n window.requestAnimationFrame(() => {\n setViewportIfChanged(reactFlowInstance.getViewport());\n });\n } catch {\n // ignore\n }\n }, [nodes, reactFlowInstance, viewport, setViewportIfChanged]);\n\n return (\n <div style={{ width: \"100%\", height: \"100%\", minHeight: \"100%\" }}>\n <ReactFlow\n nodes={nodes}\n edges={renderedEdges}\n nodeTypes={resolvedNodeTypes}\n defaultViewport={\n viewport ?? {\n x: 0,\n y: 0,\n zoom: 1,\n }\n }\n viewport={viewport ?? undefined}\n onNodesChange={onNodesChange}\n onEdgesChange={onEdgesChange}\n onNodeDragStop={onNodeDragStop}\n onConnect={onConnect}\n onMove={handleMove}\n onlyRenderVisibleElements\n onInit={setReactFlowInstance}\n onMoveEnd={handleMoveEnd}\n />\n </div>\n );\n}\n"],"names":["nodeDefaults","baseNodeDefaults","nodes","edges"],"mappings":"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"}
@@ -109,45 +109,59 @@ const collectParameterReferences = (parameters) => {
109
109
  }
110
110
  return parameters.flatMap(
111
111
  (param) => Object.keys(param?.properties ?? {}).map(
112
- (propKey) => `parameters.${propKey}`
112
+ (propKey) => `\${{ parameters.${propKey} }}`
113
113
  )
114
114
  );
115
115
  };
116
116
  const collectStepOutputReferences = (nodes, parameterReferences) => {
117
- const formatRef = (ref) => `\${{ ${ref} }}`;
118
- const actionNodes = nodes.filter(
119
- (node) => node.type === "actionNode"
120
- );
121
- const outputNode = nodes.find((node) => node.type === "outputNode");
122
- const references = {};
123
- actionNodes.forEach((node, index) => {
124
- const priorSteps = actionNodes.slice(0, index).map((n) => n.data?.step?.id).filter(Boolean);
125
- const priorStepRefs = priorSteps.map(
126
- (id) => formatRef(`steps.${id}.output`)
127
- );
128
- const priorIds = priorSteps.map((id) => formatRef(`steps.${id}.id`));
129
- const parameterRefs = parameterReferences.map((ref) => formatRef(ref));
130
- const thisStepId = node.data?.step?.id;
131
- if (!thisStepId) {
132
- references[node.id] = [...parameterRefs, ...priorStepRefs, ...priorIds];
117
+ const formatStepOutputProp = (stepId, prop) => `\${{ steps['${stepId}'].output.${prop} }}`;
118
+ const referencesByNode = {};
119
+ const sortedNodes = [...nodes].sort((a, b) => a.position.y - b.position.y);
120
+ const accumulatedReferences = [...parameterReferences];
121
+ const accumulatedSet = new Set(parameterReferences);
122
+ sortedNodes.forEach((node) => {
123
+ referencesByNode[node.id] = [...accumulatedReferences];
124
+ const data = node.data;
125
+ if (!data || !data.step) {
126
+ return;
127
+ }
128
+ const { step, scaffolderActionOutputsById } = data;
129
+ const stepId = step && typeof step.id === "string" && step.id.trim().length > 0 ? step.id : null;
130
+ const actionId = step && typeof step.action === "string" && step.action.trim().length > 0 ? step.action : null;
131
+ if (!stepId || !actionId) {
133
132
  return;
134
133
  }
135
- const outputRefs = [
136
- formatRef(`steps.${thisStepId}.output`),
137
- ...priorStepRefs,
138
- ...parameterRefs
139
- ];
140
- references[node.id] = Array.from(new Set(outputRefs));
134
+ const outputKeys = /* @__PURE__ */ new Set();
135
+ const schemaOutputs = scaffolderActionOutputsById?.[actionId];
136
+ if (schemaOutputs && typeof schemaOutputs === "object") {
137
+ const props = schemaOutputs.properties ?? schemaOutputs;
138
+ Object.keys(props ?? {}).forEach((key) => {
139
+ if (key) {
140
+ outputKeys.add(key);
141
+ }
142
+ });
143
+ }
144
+ const stepOutput = step.output;
145
+ if (stepOutput && typeof stepOutput === "object") {
146
+ Object.keys(stepOutput).forEach((key) => {
147
+ if (key) {
148
+ outputKeys.add(key);
149
+ }
150
+ });
151
+ }
152
+ if (outputKeys.size === 0) {
153
+ return;
154
+ }
155
+ Array.from(outputKeys);
156
+ outputKeys.forEach((outputKey) => {
157
+ const reference = formatStepOutputProp(stepId, outputKey);
158
+ if (!accumulatedSet.has(reference)) {
159
+ accumulatedSet.add(reference);
160
+ accumulatedReferences.push(reference);
161
+ }
162
+ });
141
163
  });
142
- if (outputNode) {
143
- const allSteps = actionNodes.map((n) => n.data?.step?.id).filter(Boolean);
144
- const refs = [
145
- ...allSteps.map((id) => formatRef(`steps.${id}.output`)),
146
- ...parameterReferences.map((ref) => formatRef(ref))
147
- ];
148
- references[outputNode.id] = Array.from(new Set(refs));
149
- }
150
- return references;
164
+ return referencesByNode;
151
165
  };
152
166
  const stableStringify = (value) => JSON.stringify(value, (_key, v) => {
153
167
  if (Array.isArray(v)) {
@@ -1 +1 @@
1
- {"version":3,"file":"model.esm.js","sources":["../../src/designerFlow/model.ts"],"sourcesContent":["import type { Node } from \"@xyflow/react\";\nimport type {\n TaskStep,\n ScaffolderTaskOutput,\n} from \"@backstage/plugin-scaffolder-common\";\nimport type {\n ActionNodeData,\n OutputNodeData,\n ParametersNodeData,\n TemplateParametersValue,\n} from \"../types/flowNodes\";\nimport { alignNodes } from \"./nodeLayout\";\nimport { normalizeParametersToSections } from \"./parameterTransforms\";\nimport { FLOW_LAYOUT, nodeDefaults } from \"../components/designerFlowConfig\";\n\nconst sanitizeForRfId = (value: string) =>\n value.replace(/[^a-zA-Z0-9-_.:]/g, \"_\");\n\nconst buildRfId = (step: TaskStep | undefined, index: number) => {\n if (step && typeof step.id === \"string\" && step.id.trim().length > 0) {\n return `rf-${sanitizeForRfId(step.id)}-${index}`;\n }\n return `rf-${index + 1}`;\n};\n\nexport const cloneStep = (step: TaskStep): TaskStep =>\n JSON.parse(JSON.stringify(step ?? {})) as TaskStep;\n\nexport const cloneOutput = (\n output: ScaffolderTaskOutput | undefined | null\n): ScaffolderTaskOutput =>\n JSON.parse(JSON.stringify(output ?? {})) as ScaffolderTaskOutput;\n\nexport const cloneParameters = (\n parameters: TemplateParametersValue\n): TemplateParametersValue =>\n parameters === undefined\n ? undefined\n : (JSON.parse(JSON.stringify(parameters)) as TemplateParametersValue);\n\nexport type BuildNodesFromModelOptions = {\n scaffolderActionIds: string[];\n scaffolderActionInputsById: Record<string, Record<string, unknown>>;\n scaffolderActionOutputsById: Record<string, Record<string, unknown>>;\n scaffolderActionInputRequiredById: Record<string, string[]>;\n};\n\nexport const buildNodesFromModel = (\n steps: TaskStep[],\n parameters: TemplateParametersValue,\n output: ScaffolderTaskOutput | undefined | null,\n options: BuildNodesFromModelOptions\n) => {\n const {\n scaffolderActionIds,\n scaffolderActionInputsById,\n scaffolderActionOutputsById,\n scaffolderActionInputRequiredById,\n } = options;\n\n const parameterSections = normalizeParametersToSections(parameters);\n const nodes: Node[] = [];\n\n const rfParametersId = \"rf-parameters\";\n nodes.push({\n id: rfParametersId,\n type: \"parametersNode\",\n position: { x: FLOW_LAYOUT.fixedXPosition, y: 0 },\n data: {\n rfId: rfParametersId,\n parameters: cloneParameters(parameters),\n sections: parameterSections,\n scaffolderActionIds,\n scaffolderActionInputsById,\n scaffolderActionInputRequiredById,\n scaffolderActionOutputsById,\n },\n ...nodeDefaults,\n });\n\n const rfOutputId = \"rf-output\";\n nodes.push({\n id: rfOutputId,\n type: \"outputNode\",\n position: {\n x: FLOW_LAYOUT.fixedXPosition,\n y: FLOW_LAYOUT.verticalSpacing * (steps.length + 1),\n },\n data: {\n rfId: rfOutputId,\n output: cloneOutput(output),\n scaffolderActionIds,\n scaffolderActionInputsById,\n scaffolderActionInputRequiredById,\n scaffolderActionOutputsById,\n } satisfies OutputNodeData,\n ...nodeDefaults,\n });\n\n steps.forEach((step, index) => {\n const rfId = buildRfId(step, index);\n nodes.splice(index + 1, 0, {\n id: rfId,\n type: \"actionNode\",\n position: {\n x: FLOW_LAYOUT.fixedXPosition,\n y: FLOW_LAYOUT.verticalSpacing * (index + 1),\n },\n data: {\n rfId,\n step: cloneStep(step),\n scaffolderActionIds,\n scaffolderActionInputsById,\n scaffolderActionInputRequiredById,\n scaffolderActionOutputsById,\n } satisfies ActionNodeData,\n ...nodeDefaults,\n });\n });\n\n return alignNodes(\n nodes,\n FLOW_LAYOUT.fixedXPosition,\n FLOW_LAYOUT.verticalSpacing\n );\n};\n\nexport const extractStepsFromNodes = (nodes: Node[]): TaskStep[] => {\n const actionNodes = nodes.filter(\n (node) => node.type === \"actionNode\"\n ) as Node<ActionNodeData>[];\n return actionNodes.map((node) => cloneStep(node.data.step));\n};\n\nexport const extractParametersFromNodes = (\n nodes: Node[]\n): TemplateParametersValue => {\n const parametersNode = nodes.find(\n (node) => node.type === \"parametersNode\"\n ) as Node<ParametersNodeData> | undefined;\n if (!parametersNode) {\n return [];\n }\n return cloneParameters(parametersNode.data.parameters);\n};\n\nexport const extractOutputFromNodes = (\n nodes: Node[]\n): ScaffolderTaskOutput | undefined => {\n const outputNode = nodes.find((node) => node.type === \"outputNode\") as\n | Node<OutputNodeData>\n | undefined;\n if (!outputNode) {\n return undefined;\n }\n return cloneOutput(outputNode.data.output);\n};\n\nexport const collectParameterReferences = (\n parameters: TemplateParametersValue | undefined\n): string[] => {\n if (!parameters || !Array.isArray(parameters)) {\n return [];\n }\n return parameters.flatMap((param) =>\n Object.keys((param as any)?.properties ?? {}).map(\n (propKey) => `parameters.${propKey}`\n )\n );\n};\n\nexport const collectStepOutputReferences = (\n nodes: Node[],\n parameterReferences: string[]\n): Record<string, string[]> => {\n const formatRef = (ref: string) => `\\${{ ${ref} }}`;\n\n const actionNodes = nodes.filter(\n (node) => node.type === \"actionNode\"\n ) as Node<ActionNodeData>[];\n const outputNode = nodes.find((node) => node.type === \"outputNode\") as\n | Node<OutputNodeData>\n | undefined;\n\n const references: Record<string, string[]> = {};\n\n actionNodes.forEach((node, index) => {\n const priorSteps = actionNodes\n .slice(0, index)\n .map((n) => n.data?.step?.id)\n .filter(Boolean) as string[];\n const priorStepRefs = priorSteps.map((id) =>\n formatRef(`steps.${id}.output`)\n );\n const priorIds = priorSteps.map((id) => formatRef(`steps.${id}.id`));\n const parameterRefs = parameterReferences.map((ref) => formatRef(ref));\n\n const thisStepId = node.data?.step?.id;\n if (!thisStepId) {\n references[node.id] = [...parameterRefs, ...priorStepRefs, ...priorIds];\n return;\n }\n\n const outputRefs = [\n formatRef(`steps.${thisStepId}.output`),\n ...priorStepRefs,\n ...parameterRefs,\n ];\n references[node.id] = Array.from(new Set(outputRefs));\n });\n\n if (outputNode) {\n const allSteps = actionNodes.map((n) => n.data?.step?.id).filter(Boolean);\n const refs = [\n ...allSteps.map((id) => formatRef(`steps.${id}.output`)),\n ...parameterReferences.map((ref) => formatRef(ref)),\n ];\n references[outputNode.id] = Array.from(new Set(refs));\n }\n\n return references;\n};\n\nexport const stableStringify = (value: unknown) =>\n JSON.stringify(value, (_key, v) => {\n if (Array.isArray(v)) {\n return v;\n }\n if (v && typeof v === \"object\") {\n return Object.keys(v as Record<string, unknown>)\n .sort()\n .reduce<Record<string, unknown>>((acc, k) => {\n acc[k] = (v as Record<string, unknown>)[k];\n return acc;\n }, {});\n }\n return v;\n });\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"model.esm.js","sources":["../../src/designerFlow/model.ts"],"sourcesContent":["import type { Node } from \"@xyflow/react\";\nimport type {\n TaskStep,\n ScaffolderTaskOutput,\n} from \"@backstage/plugin-scaffolder-common\";\nimport type {\n ActionNodeData,\n OutputNodeData,\n ParametersNodeData,\n TemplateParametersValue,\n} from \"../types/flowNodes\";\nimport { alignNodes } from \"./nodeLayout\";\nimport { normalizeParametersToSections } from \"./parameterTransforms\";\nimport { FLOW_LAYOUT, nodeDefaults } from \"../components/designerFlowConfig\";\n\nconst sanitizeForRfId = (value: string) =>\n value.replace(/[^a-zA-Z0-9-_.:]/g, \"_\");\n\nconst buildRfId = (step: TaskStep | undefined, index: number) => {\n if (step && typeof step.id === \"string\" && step.id.trim().length > 0) {\n return `rf-${sanitizeForRfId(step.id)}-${index}`;\n }\n return `rf-${index + 1}`;\n};\n\nexport const cloneStep = (step: TaskStep): TaskStep =>\n JSON.parse(JSON.stringify(step ?? {})) as TaskStep;\n\nexport const cloneOutput = (\n output: ScaffolderTaskOutput | undefined | null\n): ScaffolderTaskOutput =>\n JSON.parse(JSON.stringify(output ?? {})) as ScaffolderTaskOutput;\n\nexport const cloneParameters = (\n parameters: TemplateParametersValue\n): TemplateParametersValue =>\n parameters === undefined\n ? undefined\n : (JSON.parse(JSON.stringify(parameters)) as TemplateParametersValue);\n\nexport type BuildNodesFromModelOptions = {\n scaffolderActionIds: string[];\n scaffolderActionInputsById: Record<string, Record<string, unknown>>;\n scaffolderActionOutputsById: Record<string, Record<string, unknown>>;\n scaffolderActionInputRequiredById: Record<string, string[]>;\n};\n\nexport const buildNodesFromModel = (\n steps: TaskStep[],\n parameters: TemplateParametersValue,\n output: ScaffolderTaskOutput | undefined | null,\n options: BuildNodesFromModelOptions\n) => {\n const {\n scaffolderActionIds,\n scaffolderActionInputsById,\n scaffolderActionOutputsById,\n scaffolderActionInputRequiredById,\n } = options;\n\n const parameterSections = normalizeParametersToSections(parameters);\n const nodes: Node[] = [];\n\n const rfParametersId = \"rf-parameters\";\n nodes.push({\n id: rfParametersId,\n type: \"parametersNode\",\n position: { x: FLOW_LAYOUT.fixedXPosition, y: 0 },\n data: {\n rfId: rfParametersId,\n parameters: cloneParameters(parameters),\n sections: parameterSections,\n scaffolderActionIds,\n scaffolderActionInputsById,\n scaffolderActionInputRequiredById,\n scaffolderActionOutputsById,\n },\n ...nodeDefaults,\n });\n\n const rfOutputId = \"rf-output\";\n nodes.push({\n id: rfOutputId,\n type: \"outputNode\",\n position: {\n x: FLOW_LAYOUT.fixedXPosition,\n y: FLOW_LAYOUT.verticalSpacing * (steps.length + 1),\n },\n data: {\n rfId: rfOutputId,\n output: cloneOutput(output),\n scaffolderActionIds,\n scaffolderActionInputsById,\n scaffolderActionInputRequiredById,\n scaffolderActionOutputsById,\n } satisfies OutputNodeData,\n ...nodeDefaults,\n });\n\n steps.forEach((step, index) => {\n const rfId = buildRfId(step, index);\n nodes.splice(index + 1, 0, {\n id: rfId,\n type: \"actionNode\",\n position: {\n x: FLOW_LAYOUT.fixedXPosition,\n y: FLOW_LAYOUT.verticalSpacing * (index + 1),\n },\n data: {\n rfId,\n step: cloneStep(step),\n scaffolderActionIds,\n scaffolderActionInputsById,\n scaffolderActionInputRequiredById,\n scaffolderActionOutputsById,\n } satisfies ActionNodeData,\n ...nodeDefaults,\n });\n });\n\n return alignNodes(\n nodes,\n FLOW_LAYOUT.fixedXPosition,\n FLOW_LAYOUT.verticalSpacing\n );\n};\n\nexport const extractStepsFromNodes = (nodes: Node[]): TaskStep[] => {\n const actionNodes = nodes.filter(\n (node) => node.type === \"actionNode\"\n ) as Node<ActionNodeData>[];\n return actionNodes.map((node) => cloneStep(node.data.step));\n};\n\nexport const extractParametersFromNodes = (\n nodes: Node[]\n): TemplateParametersValue => {\n const parametersNode = nodes.find(\n (node) => node.type === \"parametersNode\"\n ) as Node<ParametersNodeData> | undefined;\n if (!parametersNode) {\n return [];\n }\n return cloneParameters(parametersNode.data.parameters);\n};\n\nexport const extractOutputFromNodes = (\n nodes: Node[]\n): ScaffolderTaskOutput | undefined => {\n const outputNode = nodes.find((node) => node.type === \"outputNode\") as\n | Node<OutputNodeData>\n | undefined;\n if (!outputNode) {\n return undefined;\n }\n return cloneOutput(outputNode.data.output);\n};\n\nexport const collectParameterReferences = (\n parameters: TemplateParametersValue | undefined\n): string[] => {\n if (!parameters || !Array.isArray(parameters)) {\n return [];\n }\n return parameters.flatMap((param) =>\n Object.keys((param as any)?.properties ?? {}).map(\n (propKey) => `\\${{ parameters.${propKey} }}`\n )\n );\n};\n\nexport const collectStepOutputReferences = (\n nodes: Node[],\n parameterReferences: string[]\n): Record<string, string[]> => {\n const formatStepOutputProp = (stepId: string, prop: string) =>\n `\\${{ steps['${stepId}'].output.${prop} }}`;\n\n const referencesByNode: Record<string, string[]> = {};\n const sortedNodes = [...nodes].sort((a, b) => a.position.y - b.position.y);\n const accumulatedReferences: string[] = [...parameterReferences];\n const accumulatedSet = new Set<string>(parameterReferences);\n const outputKeysByStepId: Record<string, string[]> = {};\n\n sortedNodes.forEach((node) => {\n referencesByNode[node.id] = [...accumulatedReferences];\n\n const data = node.data as Partial<ActionNodeData> | undefined;\n if (!data || !data.step) {\n return;\n }\n\n const { step, scaffolderActionOutputsById } = data;\n const stepId =\n step && typeof step.id === \"string\" && step.id.trim().length > 0\n ? step.id\n : null;\n const actionId =\n step && typeof step.action === \"string\" && step.action.trim().length > 0\n ? step.action\n : null;\n\n if (!stepId || !actionId) {\n return;\n }\n\n const outputKeys = new Set<string>();\n const schemaOutputs = scaffolderActionOutputsById?.[actionId];\n if (schemaOutputs && typeof schemaOutputs === \"object\") {\n // Prefer nested properties if present; otherwise use top-level keys.\n const props =\n (schemaOutputs as { properties?: Record<string, unknown> })\n .properties ?? schemaOutputs;\n Object.keys(props ?? {}).forEach((key) => {\n if (key) {\n outputKeys.add(key);\n }\n });\n }\n\n const stepOutput = (step as { output?: Record<string, unknown> }).output;\n if (stepOutput && typeof stepOutput === \"object\") {\n Object.keys(stepOutput).forEach((key) => {\n if (key) {\n outputKeys.add(key);\n }\n });\n }\n\n if (outputKeys.size === 0) {\n return;\n }\n\n outputKeysByStepId[stepId] = Array.from(outputKeys);\n\n // Add per-key references from schema/output values (omit whole output object to avoid unusable suggestion).\n outputKeys.forEach((outputKey) => {\n const reference = formatStepOutputProp(stepId, outputKey);\n if (!accumulatedSet.has(reference)) {\n accumulatedSet.add(reference);\n accumulatedReferences.push(reference);\n }\n });\n });\n\n return referencesByNode;\n};\n\nexport const stableStringify = (value: unknown) =>\n JSON.stringify(value, (_key, v) => {\n if (Array.isArray(v)) {\n return v;\n }\n if (v && typeof v === \"object\") {\n return Object.keys(v as Record<string, unknown>)\n .sort()\n .reduce<Record<string, unknown>>((acc, k) => {\n acc[k] = (v as Record<string, unknown>)[k];\n return acc;\n }, {});\n }\n return v;\n });\n"],"names":[],"mappings":"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"}
@@ -67,6 +67,10 @@ const estimateHeightByType = (node) => {
67
67
  return estimateParametersNodeHeight(node) ?? estimateActionNodeHeight(node) ?? estimateOutputNodeHeight(node);
68
68
  };
69
69
  const resolveNodeHeightForTracking = (node) => {
70
+ const dataHeight = parseNumericHeight(node.data?.measuredHeight);
71
+ if (dataHeight !== null) {
72
+ return dataHeight;
73
+ }
70
74
  const explicit = parseNumericHeight(node?.measured?.height);
71
75
  if (explicit !== null) {
72
76
  return explicit;
@@ -77,12 +81,12 @@ const alignNodes = (nodes, fixedXPosition, verticalSpacing) => {
77
81
  const parametersNode = nodes.find((node) => node.type === "parametersNode");
78
82
  const actionNodes = nodes.filter((node) => node.type === "actionNode");
79
83
  const outputNode = nodes.find((node) => node.type === "outputNode");
80
- let nextY = 0;
84
+ let nextY = parametersNode?.position?.y ?? 0;
81
85
  const aligned = [];
82
86
  if (parametersNode) {
83
87
  aligned.push({
84
88
  ...parametersNode,
85
- position: { x: fixedXPosition, y: 0 }
89
+ position: { x: fixedXPosition, y: nextY }
86
90
  });
87
91
  const height = resolveNodeHeightForTracking(parametersNode) ?? NODE_VERTICAL_SPACING.parametersNode ?? DEFAULT_NODE_HEIGHT;
88
92
  nextY += height + verticalSpacing + MIN_VERTICAL_GAP;
@@ -1 +1 @@
1
- {"version":3,"file":"nodeLayout.esm.js","sources":["../../src/designerFlow/nodeLayout.ts"],"sourcesContent":["import type { Node } from \"@xyflow/react\";\nimport type {\n ActionNodeData,\n OutputNodeData,\n ParametersNodeData,\n} from \"../types/flowNodes\";\nimport { NODE_VERTICAL_SPACING } from \"../types/flowNodes\";\n\n// Shared helpers for computing consistent node alignment/spacing in the flow.\n\nconst DEFAULT_NODE_HEIGHT = 320;\nconst MIN_VERTICAL_GAP = 16;\n\nconst parseNumericHeight = (value: unknown): number | null => {\n if (typeof value === \"number\" && Number.isFinite(value) && value > 0) {\n return value;\n }\n if (typeof value === \"string\") {\n const parsed = Number.parseFloat(value);\n if (!Number.isNaN(parsed) && parsed > 0) {\n return parsed;\n }\n }\n return null;\n};\n\nconst estimateParametersNodeHeight = (node: Node): number | null => {\n if (node.type !== \"parametersNode\") {\n return null;\n }\n const data = node.data as ParametersNodeData | undefined;\n if (!data) {\n return null;\n }\n\n const sections = data.sections ?? [];\n const PARAMETER_SHELL_HEIGHT = 300;\n const PARAMETER_CARD_BASE = 220;\n const SECTION_BASE = 180;\n const FIELD_HEIGHT = 86;\n\n if (!sections.length) {\n return PARAMETER_SHELL_HEIGHT + PARAMETER_CARD_BASE + SECTION_BASE;\n }\n\n const sectionsHeight = sections.reduce((total, section) => {\n const fieldCount = section.fields?.length ?? 0;\n return total + SECTION_BASE + Math.max(fieldCount, 1) * FIELD_HEIGHT;\n }, 0);\n\n return PARAMETER_SHELL_HEIGHT + PARAMETER_CARD_BASE + sectionsHeight;\n};\n\nconst estimateActionNodeHeight = (node: Node): number | null => {\n if (node.type !== \"actionNode\") {\n return null;\n }\n const data = node.data as ActionNodeData | undefined;\n if (!data) {\n return null;\n }\n const inputsLength = Object.keys(data.step?.input ?? {}).length || 0;\n const INPUT_ROW_HEIGHT = 56;\n const BASE_HEIGHT = 420;\n return BASE_HEIGHT + inputsLength * INPUT_ROW_HEIGHT;\n};\n\nconst estimateOutputNodeHeight = (node: Node): number | null => {\n if (node.type !== \"outputNode\") {\n return null;\n }\n const data = node.data as OutputNodeData | undefined;\n if (!data) {\n return null;\n }\n const linksLength = Array.isArray(data.output?.links)\n ? data.output.links.length\n : 0;\n const textLength = Array.isArray((data.output as any)?.text)\n ? (data.output as any).text.length\n : 0;\n const ITEM_HEIGHT = 56;\n const BASE_HEIGHT = 320;\n return BASE_HEIGHT + Math.max(linksLength + textLength, 1) * ITEM_HEIGHT;\n};\n\nconst estimateHeightByType = (node: Node): number | null => {\n return (\n estimateParametersNodeHeight(node) ??\n estimateActionNodeHeight(node) ??\n estimateOutputNodeHeight(node)\n );\n};\n\nexport const resolveNodeHeightForTracking = (node: Node): number | null => {\n const explicit = parseNumericHeight(node?.measured?.height);\n if (explicit !== null) {\n return explicit;\n }\n return estimateHeightByType(node);\n};\n\nexport const alignNodes = (\n nodes: Node[],\n fixedXPosition: number,\n verticalSpacing: number\n) => {\n const parametersNode = nodes.find((node) => node.type === \"parametersNode\");\n const actionNodes = nodes.filter((node) => node.type === \"actionNode\");\n const outputNode = nodes.find((node) => node.type === \"outputNode\");\n\n let nextY = 0;\n const aligned: Node[] = [];\n\n if (parametersNode) {\n aligned.push({\n ...parametersNode,\n position: { x: fixedXPosition, y: 0 },\n });\n const height =\n resolveNodeHeightForTracking(parametersNode) ??\n NODE_VERTICAL_SPACING.parametersNode ??\n DEFAULT_NODE_HEIGHT;\n nextY += height + verticalSpacing + MIN_VERTICAL_GAP;\n }\n\n actionNodes.forEach((node, _index) => {\n aligned.push({\n ...node,\n position: { x: fixedXPosition, y: nextY },\n });\n const height =\n resolveNodeHeightForTracking(node) ??\n NODE_VERTICAL_SPACING.actionNode ??\n DEFAULT_NODE_HEIGHT;\n nextY += height + verticalSpacing + MIN_VERTICAL_GAP;\n });\n\n if (outputNode) {\n aligned.push({\n ...outputNode,\n position: { x: fixedXPosition, y: nextY },\n });\n }\n\n return aligned;\n};\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"nodeLayout.esm.js","sources":["../../src/designerFlow/nodeLayout.ts"],"sourcesContent":["import type { Node } from \"@xyflow/react\";\nimport type {\n ActionNodeData,\n OutputNodeData,\n ParametersNodeData,\n} from \"../types/flowNodes\";\nimport { NODE_VERTICAL_SPACING } from \"../types/flowNodes\";\n\n// Shared helpers for computing consistent node alignment/spacing in the flow.\n\nconst DEFAULT_NODE_HEIGHT = 320;\nconst MIN_VERTICAL_GAP = 16;\n\nconst parseNumericHeight = (value: unknown): number | null => {\n if (typeof value === \"number\" && Number.isFinite(value) && value > 0) {\n return value;\n }\n if (typeof value === \"string\") {\n const parsed = Number.parseFloat(value);\n if (!Number.isNaN(parsed) && parsed > 0) {\n return parsed;\n }\n }\n return null;\n};\n\nconst estimateParametersNodeHeight = (node: Node): number | null => {\n if (node.type !== \"parametersNode\") {\n return null;\n }\n const data = node.data as ParametersNodeData | undefined;\n if (!data) {\n return null;\n }\n\n const sections = data.sections ?? [];\n const PARAMETER_SHELL_HEIGHT = 300;\n const PARAMETER_CARD_BASE = 220;\n const SECTION_BASE = 180;\n const FIELD_HEIGHT = 86;\n\n if (!sections.length) {\n return PARAMETER_SHELL_HEIGHT + PARAMETER_CARD_BASE + SECTION_BASE;\n }\n\n const sectionsHeight = sections.reduce((total, section) => {\n const fieldCount = section.fields?.length ?? 0;\n return total + SECTION_BASE + Math.max(fieldCount, 1) * FIELD_HEIGHT;\n }, 0);\n\n return PARAMETER_SHELL_HEIGHT + PARAMETER_CARD_BASE + sectionsHeight;\n};\n\nconst estimateActionNodeHeight = (node: Node): number | null => {\n if (node.type !== \"actionNode\") {\n return null;\n }\n const data = node.data as ActionNodeData | undefined;\n if (!data) {\n return null;\n }\n const inputsLength = Object.keys(data.step?.input ?? {}).length || 0;\n const INPUT_ROW_HEIGHT = 56;\n const BASE_HEIGHT = 420;\n return BASE_HEIGHT + inputsLength * INPUT_ROW_HEIGHT;\n};\n\nconst estimateOutputNodeHeight = (node: Node): number | null => {\n if (node.type !== \"outputNode\") {\n return null;\n }\n const data = node.data as OutputNodeData | undefined;\n if (!data) {\n return null;\n }\n const linksLength = Array.isArray(data.output?.links)\n ? data.output.links.length\n : 0;\n const textLength = Array.isArray((data.output as any)?.text)\n ? (data.output as any).text.length\n : 0;\n const ITEM_HEIGHT = 56;\n const BASE_HEIGHT = 320;\n return BASE_HEIGHT + Math.max(linksLength + textLength, 1) * ITEM_HEIGHT;\n};\n\nconst estimateHeightByType = (node: Node): number | null => {\n return (\n estimateParametersNodeHeight(node) ??\n estimateActionNodeHeight(node) ??\n estimateOutputNodeHeight(node)\n );\n};\n\nexport const resolveNodeHeightForTracking = (node: Node): number | null => {\n const dataHeight = parseNumericHeight((node.data as any)?.measuredHeight);\n if (dataHeight !== null) {\n return dataHeight;\n }\n const explicit = parseNumericHeight(node?.measured?.height);\n if (explicit !== null) {\n return explicit;\n }\n return estimateHeightByType(node);\n};\n\nexport const alignNodes = (\n nodes: Node[],\n fixedXPosition: number,\n verticalSpacing: number\n) => {\n const parametersNode = nodes.find((node) => node.type === \"parametersNode\");\n const actionNodes = nodes.filter((node) => node.type === \"actionNode\");\n const outputNode = nodes.find((node) => node.type === \"outputNode\");\n\n let nextY = parametersNode?.position?.y ?? 0;\n const aligned: Node[] = [];\n\n if (parametersNode) {\n aligned.push({\n ...parametersNode,\n position: { x: fixedXPosition, y: nextY },\n });\n const height =\n resolveNodeHeightForTracking(parametersNode) ??\n NODE_VERTICAL_SPACING.parametersNode ??\n DEFAULT_NODE_HEIGHT;\n nextY += height + verticalSpacing + MIN_VERTICAL_GAP;\n }\n\n actionNodes.forEach((node, _index) => {\n aligned.push({\n ...node,\n position: { x: fixedXPosition, y: nextY },\n });\n const height =\n resolveNodeHeightForTracking(node) ??\n NODE_VERTICAL_SPACING.actionNode ??\n DEFAULT_NODE_HEIGHT;\n nextY += height + verticalSpacing + MIN_VERTICAL_GAP;\n });\n\n if (outputNode) {\n aligned.push({\n ...outputNode,\n position: { x: fixedXPosition, y: nextY },\n });\n }\n\n return aligned;\n};\n"],"names":[],"mappings":";;AAUA,MAAM,mBAAA,GAAsB,GAAA;AAC5B,MAAM,gBAAA,GAAmB,EAAA;AAEzB,MAAM,kBAAA,GAAqB,CAAC,KAAA,KAAkC;AAC5D,EAAA,IAAI,OAAO,UAAU,QAAA,IAAY,MAAA,CAAO,SAAS,KAAK,CAAA,IAAK,QAAQ,CAAA,EAAG;AACpE,IAAA,OAAO,KAAA;AAAA,EACT;AACA,EAAA,IAAI,OAAO,UAAU,QAAA,EAAU;AAC7B,IAAA,MAAM,MAAA,GAAS,MAAA,CAAO,UAAA,CAAW,KAAK,CAAA;AACtC,IAAA,IAAI,CAAC,MAAA,CAAO,KAAA,CAAM,MAAM,CAAA,IAAK,SAAS,CAAA,EAAG;AACvC,MAAA,OAAO,MAAA;AAAA,IACT;AAAA,EACF;AACA,EAAA,OAAO,IAAA;AACT,CAAA;AAEA,MAAM,4BAAA,GAA+B,CAAC,IAAA,KAA8B;AAClE,EAAA,IAAI,IAAA,CAAK,SAAS,gBAAA,EAAkB;AAClC,IAAA,OAAO,IAAA;AAAA,EACT;AACA,EAAA,MAAM,OAAO,IAAA,CAAK,IAAA;AAClB,EAAA,IAAI,CAAC,IAAA,EAAM;AACT,IAAA,OAAO,IAAA;AAAA,EACT;AAEA,EAAA,MAAM,QAAA,GAAW,IAAA,CAAK,QAAA,IAAY,EAAC;AACnC,EAAA,MAAM,sBAAA,GAAyB,GAAA;AAC/B,EAAA,MAAM,mBAAA,GAAsB,GAAA;AAC5B,EAAA,MAAM,YAAA,GAAe,GAAA;AACrB,EAAA,MAAM,YAAA,GAAe,EAAA;AAErB,EAAA,IAAI,CAAC,SAAS,MAAA,EAAQ;AACpB,IAAA,OAAO,yBAAyB,mBAAA,GAAsB,YAAA;AAAA,EACxD;AAEA,EAAA,MAAM,cAAA,GAAiB,QAAA,CAAS,MAAA,CAAO,CAAC,OAAO,OAAA,KAAY;AACzD,IAAA,MAAM,UAAA,GAAa,OAAA,CAAQ,MAAA,EAAQ,MAAA,IAAU,CAAA;AAC7C,IAAA,OAAO,QAAQ,YAAA,GAAe,IAAA,CAAK,GAAA,CAAI,UAAA,EAAY,CAAC,CAAA,GAAI,YAAA;AAAA,EAC1D,GAAG,CAAC,CAAA;AAEJ,EAAA,OAAO,yBAAyB,mBAAA,GAAsB,cAAA;AACxD,CAAA;AAEA,MAAM,wBAAA,GAA2B,CAAC,IAAA,KAA8B;AAC9D,EAAA,IAAI,IAAA,CAAK,SAAS,YAAA,EAAc;AAC9B,IAAA,OAAO,IAAA;AAAA,EACT;AACA,EAAA,MAAM,OAAO,IAAA,CAAK,IAAA;AAClB,EAAA,IAAI,CAAC,IAAA,EAAM;AACT,IAAA,OAAO,IAAA;AAAA,EACT;AACA,EAAA,MAAM,YAAA,GAAe,OAAO,IAAA,CAAK,IAAA,CAAK,MAAM,KAAA,IAAS,EAAE,CAAA,CAAE,MAAA,IAAU,CAAA;AACnE,EAAA,MAAM,gBAAA,GAAmB,EAAA;AACzB,EAAA,MAAM,WAAA,GAAc,GAAA;AACpB,EAAA,OAAO,cAAc,YAAA,GAAe,gBAAA;AACtC,CAAA;AAEA,MAAM,wBAAA,GAA2B,CAAC,IAAA,KAA8B;AAC9D,EAAA,IAAI,IAAA,CAAK,SAAS,YAAA,EAAc;AAC9B,IAAA,OAAO,IAAA;AAAA,EACT;AACA,EAAA,MAAM,OAAO,IAAA,CAAK,IAAA;AAClB,EAAA,IAAI,CAAC,IAAA,EAAM;AACT,IAAA,OAAO,IAAA;AAAA,EACT;AACA,EAAA,MAAM,WAAA,GAAc,KAAA,CAAM,OAAA,CAAQ,IAAA,CAAK,MAAA,EAAQ,KAAK,CAAA,GAChD,IAAA,CAAK,MAAA,CAAO,KAAA,CAAM,MAAA,GAClB,CAAA;AACJ,EAAA,MAAM,UAAA,GAAa,KAAA,CAAM,OAAA,CAAS,IAAA,CAAK,MAAA,EAAgB,IAAI,CAAA,GACtD,IAAA,CAAK,MAAA,CAAe,IAAA,CAAK,MAAA,GAC1B,CAAA;AACJ,EAAA,MAAM,WAAA,GAAc,EAAA;AACpB,EAAA,MAAM,WAAA,GAAc,GAAA;AACpB,EAAA,OAAO,cAAc,IAAA,CAAK,GAAA,CAAI,WAAA,GAAc,UAAA,EAAY,CAAC,CAAA,GAAI,WAAA;AAC/D,CAAA;AAEA,MAAM,oBAAA,GAAuB,CAAC,IAAA,KAA8B;AAC1D,EAAA,OACE,6BAA6B,IAAI,CAAA,IACjC,yBAAyB,IAAI,CAAA,IAC7B,yBAAyB,IAAI,CAAA;AAEjC,CAAA;AAEO,MAAM,4BAAA,GAA+B,CAAC,IAAA,KAA8B;AACzE,EAAA,MAAM,UAAA,GAAa,kBAAA,CAAoB,IAAA,CAAK,IAAA,EAAc,cAAc,CAAA;AACxE,EAAA,IAAI,eAAe,IAAA,EAAM;AACvB,IAAA,OAAO,UAAA;AAAA,EACT;AACA,EAAA,MAAM,QAAA,GAAW,kBAAA,CAAmB,IAAA,EAAM,QAAA,EAAU,MAAM,CAAA;AAC1D,EAAA,IAAI,aAAa,IAAA,EAAM;AACrB,IAAA,OAAO,QAAA;AAAA,EACT;AACA,EAAA,OAAO,qBAAqB,IAAI,CAAA;AAClC;AAEO,MAAM,UAAA,GAAa,CACxB,KAAA,EACA,cAAA,EACA,eAAA,KACG;AACH,EAAA,MAAM,iBAAiB,KAAA,CAAM,IAAA,CAAK,CAAC,IAAA,KAAS,IAAA,CAAK,SAAS,gBAAgB,CAAA;AAC1E,EAAA,MAAM,cAAc,KAAA,CAAM,MAAA,CAAO,CAAC,IAAA,KAAS,IAAA,CAAK,SAAS,YAAY,CAAA;AACrE,EAAA,MAAM,aAAa,KAAA,CAAM,IAAA,CAAK,CAAC,IAAA,KAAS,IAAA,CAAK,SAAS,YAAY,CAAA;AAElE,EAAA,IAAI,KAAA,GAAQ,cAAA,EAAgB,QAAA,EAAU,CAAA,IAAK,CAAA;AAC3C,EAAA,MAAM,UAAkB,EAAC;AAEzB,EAAA,IAAI,cAAA,EAAgB;AAClB,IAAA,OAAA,CAAQ,IAAA,CAAK;AAAA,MACX,GAAG,cAAA;AAAA,MACH,QAAA,EAAU,EAAE,CAAA,EAAG,cAAA,EAAgB,GAAG,KAAA;AAAM,KACzC,CAAA;AACD,IAAA,MAAM,MAAA,GACJ,4BAAA,CAA6B,cAAc,CAAA,IAC3C,sBAAsB,cAAA,IACtB,mBAAA;AACF,IAAA,KAAA,IAAS,SAAS,eAAA,GAAkB,gBAAA;AAAA,EACtC;AAEA,EAAA,WAAA,CAAY,OAAA,CAAQ,CAAC,IAAA,EAAM,MAAA,KAAW;AACpC,IAAA,OAAA,CAAQ,IAAA,CAAK;AAAA,MACX,GAAG,IAAA;AAAA,MACH,QAAA,EAAU,EAAE,CAAA,EAAG,cAAA,EAAgB,GAAG,KAAA;AAAM,KACzC,CAAA;AACD,IAAA,MAAM,MAAA,GACJ,4BAAA,CAA6B,IAAI,CAAA,IACjC,sBAAsB,UAAA,IACtB,mBAAA;AACF,IAAA,KAAA,IAAS,SAAS,eAAA,GAAkB,gBAAA;AAAA,EACtC,CAAC,CAAA;AAED,EAAA,IAAI,UAAA,EAAY;AACd,IAAA,OAAA,CAAQ,IAAA,CAAK;AAAA,MACX,GAAG,UAAA;AAAA,MACH,QAAA,EAAU,EAAE,CAAA,EAAG,cAAA,EAAgB,GAAG,KAAA;AAAM,KACzC,CAAA;AAAA,EACH;AAEA,EAAA,OAAO,OAAA;AACT;;;;"}
package/dist/index.d.ts CHANGED
@@ -187,6 +187,8 @@ type BaseNodeData = {
187
187
  stepOutputReferences?: string[];
188
188
  onAddNode?: (config: AddNodeConfig) => void;
189
189
  onRemoveNode?: (rfId: string) => void;
190
+ /** DOM-measured height used to stabilize layout */
191
+ measuredHeight?: number;
190
192
  };
191
193
  type ActionNodeData = BaseNodeData & {
192
194
  /** User payload; id is editable string (reserved by your template) */
@@ -1 +1 @@
1
- {"version":3,"file":"flowNodes.esm.js","sources":["../../src/types/flowNodes.ts"],"sourcesContent":["import type {\n ScaffolderTaskOutput,\n TaskStep,\n} from \"@backstage/plugin-scaffolder-common\";\nimport type { TemplateParametersValue } from \"./templateParameters\";\n\nexport type DesignerNodeType = \"parametersNode\" | \"actionNode\" | \"outputNode\";\n\nexport type AddNodeConfig = {\n afterRfId: string;\n type?: DesignerNodeType;\n stepTemplate?: Partial<TaskStep>;\n outputTemplate?: ScaffolderTaskOutput;\n parametersTemplate?: TemplateParametersValue;\n};\n\ntype BaseNodeData = {\n /** Stable ReactFlow node id */\n rfId: string;\n /** Cached scaffolder action ids for dropdown options */\n scaffolderActionIds?: string[];\n /** Cached action input schemas keyed by action id */\n scaffolderActionInputsById?: Record<string, Record<string, unknown>>;\n /** Cached action required input keys keyed by action id */\n scaffolderActionInputRequiredById?: Record<string, string[]>;\n /** Cached action output schemas keyed by action id */\n scaffolderActionOutputsById?: Record<string, Record<string, unknown>>;\n /** Suggestions for referencing previous step outputs */\n stepOutputReferences?: string[];\n onAddNode?: (config: AddNodeConfig) => void;\n onRemoveNode?: (rfId: string) => void;\n};\n\nexport type ActionNodeData = BaseNodeData & {\n /** User payload; id is editable string (reserved by your template) */\n step: TaskStep & { input?: Record<string, unknown> };\n onUpdateField?: (rfId: string, field: keyof TaskStep, value: string) => void;\n onUpdateInput?: (rfId: string, key: string, value: unknown) => void;\n onRemoveInputKey?: (rfId: string, key: string) => void;\n};\n\nexport type OutputNodeData = BaseNodeData & {\n output: ScaffolderTaskOutput;\n onUpdateOutput?: (\n rfId: string,\n updater: (prev: ScaffolderTaskOutput) => ScaffolderTaskOutput\n ) => void;\n};\n\nexport type ParameterFieldDisplay = {\n id: string;\n fieldName: string;\n sectionId: string;\n sectionTitle?: string;\n required: boolean;\n schema?: Record<string, unknown>;\n};\n\nexport type ParameterSectionDisplay = {\n id: string;\n title?: string;\n description?: string;\n required?: string[];\n properties?: Record<string, Record<string, unknown>>;\n fields: ParameterFieldDisplay[];\n};\n\nexport type ParametersNodeData = BaseNodeData & {\n parameters: TemplateParametersValue;\n sections?: ParameterSectionDisplay[];\n onUpdateSections?: (\n rfId: string,\n updater: (prev: ParameterSectionDisplay[]) => ParameterSectionDisplay[]\n ) => void;\n};\n\nexport const NODE_VERTICAL_SPACING: Record<DesignerNodeType, number> = {\n parametersNode: 120,\n actionNode: 120,\n outputNode: 120,\n};\n\nexport type { TemplateParametersValue };\n"],"names":[],"mappings":"AA4EO,MAAM,qBAAA,GAA0D;AAAA,EACrE,cAAA,EAAgB,GAAA;AAAA,EAChB,UAAA,EAAY,GAAA;AAAA,EACZ,UAAA,EAAY;AACd;;;;"}
1
+ {"version":3,"file":"flowNodes.esm.js","sources":["../../src/types/flowNodes.ts"],"sourcesContent":["import type {\n ScaffolderTaskOutput,\n TaskStep,\n} from \"@backstage/plugin-scaffolder-common\";\nimport type { TemplateParametersValue } from \"./templateParameters\";\n\nexport type DesignerNodeType = \"parametersNode\" | \"actionNode\" | \"outputNode\";\n\nexport type AddNodeConfig = {\n afterRfId: string;\n type?: DesignerNodeType;\n stepTemplate?: Partial<TaskStep>;\n outputTemplate?: ScaffolderTaskOutput;\n parametersTemplate?: TemplateParametersValue;\n};\n\ntype BaseNodeData = {\n /** Stable ReactFlow node id */\n rfId: string;\n /** Cached scaffolder action ids for dropdown options */\n scaffolderActionIds?: string[];\n /** Cached action input schemas keyed by action id */\n scaffolderActionInputsById?: Record<string, Record<string, unknown>>;\n /** Cached action required input keys keyed by action id */\n scaffolderActionInputRequiredById?: Record<string, string[]>;\n /** Cached action output schemas keyed by action id */\n scaffolderActionOutputsById?: Record<string, Record<string, unknown>>;\n /** Suggestions for referencing previous step outputs */\n stepOutputReferences?: string[];\n onAddNode?: (config: AddNodeConfig) => void;\n onRemoveNode?: (rfId: string) => void;\n /** DOM-measured height used to stabilize layout */\n measuredHeight?: number;\n};\n\nexport type ActionNodeData = BaseNodeData & {\n /** User payload; id is editable string (reserved by your template) */\n step: TaskStep & { input?: Record<string, unknown> };\n onUpdateField?: (rfId: string, field: keyof TaskStep, value: string) => void;\n onUpdateInput?: (rfId: string, key: string, value: unknown) => void;\n onRemoveInputKey?: (rfId: string, key: string) => void;\n};\n\nexport type OutputNodeData = BaseNodeData & {\n output: ScaffolderTaskOutput;\n onUpdateOutput?: (\n rfId: string,\n updater: (prev: ScaffolderTaskOutput) => ScaffolderTaskOutput\n ) => void;\n};\n\nexport type ParameterFieldDisplay = {\n id: string;\n fieldName: string;\n sectionId: string;\n sectionTitle?: string;\n required: boolean;\n schema?: Record<string, unknown>;\n};\n\nexport type ParameterSectionDisplay = {\n id: string;\n title?: string;\n description?: string;\n required?: string[];\n properties?: Record<string, Record<string, unknown>>;\n fields: ParameterFieldDisplay[];\n};\n\nexport type ParametersNodeData = BaseNodeData & {\n parameters: TemplateParametersValue;\n sections?: ParameterSectionDisplay[];\n onUpdateSections?: (\n rfId: string,\n updater: (prev: ParameterSectionDisplay[]) => ParameterSectionDisplay[]\n ) => void;\n};\n\nexport const NODE_VERTICAL_SPACING: Record<DesignerNodeType, number> = {\n parametersNode: 120,\n actionNode: 120,\n outputNode: 120,\n};\n\nexport type { TemplateParametersValue };\n"],"names":[],"mappings":"AA8EO,MAAM,qBAAA,GAA0D;AAAA,EACrE,cAAA,EAAgB,GAAA;AAAA,EAChB,UAAA,EAAY,GAAA;AAAA,EACZ,UAAA,EAAY;AACd;;;;"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tduniec/plugin-template-designer-foundation",
3
- "version": "0.1.1",
3
+ "version": "0.1.2",
4
4
  "license": "Apache-2.0",
5
5
  "main": "./dist/index.esm.js",
6
6
  "types": "./dist/index.d.ts",