@theclearsky/react-blender-nodes 0.0.10 → 0.0.13

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.
@@ -0,0 +1,1119 @@
1
+ import { ComponentProps } from 'react';
2
+ import { ControlLinePosition } from '@xyflow/react';
3
+ import { ControlPosition } from '@xyflow/react';
4
+ import { Edge } from '@xyflow/react';
5
+ import { HTMLAttributes } from 'react';
6
+ import { Node as Node_2 } from '@xyflow/react';
7
+ import { NodeProps } from '@xyflow/react';
8
+ import { NodeResizeControl } from '@xyflow/react';
9
+ import { NodeResizerProps } from '@xyflow/react';
10
+ import { Patch } from 'immer';
11
+ import { ReactNode } from 'react';
12
+ import { Viewport } from '@xyflow/react';
13
+ import { XYPosition } from '@xyflow/react';
14
+ import { z } from 'zod';
15
+
16
+ /**
17
+ * Currently open drawer. UI-only state — stripped during export.
18
+ * Managed by OPEN_DRAWER / CLOSE_DRAWER actions.
19
+ */
20
+ declare type ActiveDrawer = {
21
+ type: 'editLoop';
22
+ nodeId: string;
23
+ } | {
24
+ type: 'editNodeType';
25
+ nodeTypeId: string;
26
+ } | {
27
+ type: 'editSwitch';
28
+ nodeId: string;
29
+ } | {
30
+ type: 'editGraphInput';
31
+ nodeId: string;
32
+ } | {
33
+ type: 'editGraphOutput';
34
+ nodeId: string;
35
+ } | null;
36
+
37
+ /**
38
+ * Mapping of allowed conversions between data types
39
+ *
40
+ * @template DataTypeUniqueId - Unique identifier type for data types
41
+ */
42
+ declare type AllowedConversionsBetweenDataTypes<DataTypeUniqueId extends string = string> = Partial<Record<DataTypeUniqueId, Partial<Record<DataTypeUniqueId, boolean>>>>;
43
+
44
+ /** Context for `artifact` targets: the read-only base data only. */
45
+ export declare type ArtifactRunContext<DataTypeUniqueId extends string = string, NodeTypeUniqueId extends string = string, UnderlyingType extends SupportedUnderlyingTypes = SupportedUnderlyingTypes, ComplexSchemaType extends UnderlyingType extends 'complex' ? z.ZodType : never = never> = RunTargetContextBase<DataTypeUniqueId, NodeTypeUniqueId, UnderlyingType, ComplexSchemaType>;
46
+
47
+ /** An `artifact` target: returns / downloads a file or string; no timeline. */
48
+ export declare type ArtifactRunTarget<DataTypeUniqueId extends string = string, NodeTypeUniqueId extends string = string, UnderlyingType extends SupportedUnderlyingTypes = SupportedUnderlyingTypes, ComplexSchemaType extends UnderlyingType extends 'complex' ? z.ZodType : never = never> = RunTargetIdentity & {
49
+ mode: 'artifact';
50
+ run: (context: ArtifactRunContext<DataTypeUniqueId, NodeTypeUniqueId, UnderlyingType, ComplexSchemaType>) => Promise<void>;
51
+ };
52
+
53
+ /**
54
+ * Per-edge data carried on a configurable edge.
55
+ *
56
+ * `order` is the connection's rank WITHIN its target input handle's fan-in group
57
+ * — a contiguous `0..n-1` written across the group's sibling edges when the user
58
+ * reorders the connections (`REORDER_INPUT_CONNECTIONS`). It is absent on edges
59
+ * that have never been reordered; the compiler then falls back to the
60
+ * edges-array order, so existing graphs and the common single-connection case are
61
+ * unchanged. It is the only field the library itself persists on an edge today.
62
+ *
63
+ * The `& Record<string, unknown>` keeps the data bag OPEN — a consumer may still
64
+ * stash their own arbitrary keys on `edge.data` (as the prior
65
+ * `Record<string, unknown>` typing allowed), so adding the typed `order` is a
66
+ * purely additive, non-breaking change to the (internal) `ConfigurableEdgeState`.
67
+ */
68
+ declare type ConfigurableEdgeData = {
69
+ order?: number;
70
+ } & Record<string, unknown>;
71
+
72
+ /** State type for configurable edges */
73
+ declare type ConfigurableEdgeState = Edge<ConfigurableEdgeData, 'configurableEdge'>;
74
+
75
+ /**
76
+ * Configuration for a node input
77
+ *
78
+ * Defines an input socket on a node with optional interactive input component.
79
+ * Supports both string and number types with type-specific onChange handlers.
80
+ */
81
+ declare type ConfigurableNodeInput<UnderlyingType extends SupportedUnderlyingTypes = SupportedUnderlyingTypes, ComplexSchemaType extends UnderlyingType extends 'complex' ? z.ZodType : never = never, DataTypeUniqueId extends string = string> = {
82
+ /** Unique identifier for the input */
83
+ id: string;
84
+ /** Display name for the input */
85
+ name: string;
86
+ /** Color of the input handle/socket */
87
+ handleColor?: string;
88
+ /** Shape of the input handle (circle, square, diamond, etc.) */
89
+ handleShape?: HandleShape;
90
+ /** Whether to show an interactive input component when not connected */
91
+ allowInput?: boolean;
92
+ /** Maximum number of connections for this input */
93
+ maxConnections?: number;
94
+ /** Data type of the input, used by full graph */
95
+ dataType?: {
96
+ dataTypeObject: DataType<UnderlyingType, ComplexSchemaType>;
97
+ dataTypeUniqueId: DataTypeUniqueId;
98
+ };
99
+ /** Inferred data type of the input (only when type inference is enabled and datatype is inferredFromConnection and connected), used by full graph */
100
+ inferredDataType?: {
101
+ dataTypeObject: DataType<UnderlyingType, ComplexSchemaType>;
102
+ dataTypeUniqueId: DataTypeUniqueId;
103
+ } | null;
104
+ } & ({
105
+ /** String input type */
106
+ type: 'string';
107
+ /** Current value of the input */
108
+ value?: string;
109
+ /** Callback when the input value changes */
110
+ onChange?: (value: string) => void;
111
+ /** When set, renders a select dropdown instead of a free-text input */
112
+ allowedStrings?: readonly string[];
113
+ } | {
114
+ /** Number input type */
115
+ type: 'number';
116
+ /** Current value of the input */
117
+ value?: number;
118
+ /** Callback when the input value changes */
119
+ onChange?: (value: number) => void;
120
+ } | {
121
+ /** */
122
+ type: 'boolean';
123
+ /** Current value of the input */
124
+ value?: boolean;
125
+ /** Callback when the input value changes */
126
+ onChange?: (value: boolean) => void;
127
+ } | {
128
+ /** Unsupported input type */
129
+ type: 'unsupportedDirectly';
130
+ /** Current value of the input */
131
+ value?: unknown;
132
+ /** Callback when the input value changes */
133
+ onChange?: (value: unknown) => void;
134
+ });
135
+
136
+ /**
137
+ * Configuration for a collapsible input panel
138
+ *
139
+ * Groups multiple inputs together in a collapsible panel for better organization.
140
+ */
141
+ declare type ConfigurableNodeInputPanel<UnderlyingType extends SupportedUnderlyingTypes = SupportedUnderlyingTypes, ComplexSchemaType extends UnderlyingType extends 'complex' ? z.ZodType : never = never, DataTypeUniqueId extends string = string> = {
142
+ /** Unique identifier for the panel */
143
+ id: string;
144
+ /** Display name for the panel */
145
+ name: string;
146
+ /** Array of inputs contained in this panel */
147
+ inputs: ConfigurableNodeInput<UnderlyingType, ComplexSchemaType, DataTypeUniqueId>[];
148
+ };
149
+
150
+ /**
151
+ * Configuration for a node output
152
+ *
153
+ * Defines an output socket on a node that can be connected to inputs.
154
+ */
155
+ declare type ConfigurableNodeOutput<UnderlyingType extends SupportedUnderlyingTypes = SupportedUnderlyingTypes, ComplexSchemaType extends UnderlyingType extends 'complex' ? z.ZodType : never = never, DataTypeUniqueId extends string = string> = {
156
+ /** Unique identifier for the output */
157
+ id: string;
158
+ /** Display name for the output */
159
+ name: string;
160
+ /** Color of the output handle/socket */
161
+ handleColor?: string;
162
+ /** Shape of the output handle (circle, square, diamond, etc.) */
163
+ handleShape?: HandleShape;
164
+ /** Maximum number of connections for this output */
165
+ maxConnections?: number;
166
+ /** Data type of the output, used by full graph */
167
+ dataType?: {
168
+ dataTypeObject: DataType<UnderlyingType, ComplexSchemaType>;
169
+ dataTypeUniqueId: DataTypeUniqueId;
170
+ };
171
+ /** Inferred data type of the output (only when type inference is enabled and datatype is inferredFromConnection and connected), used by full graph */
172
+ inferredDataType?: {
173
+ dataTypeObject: DataType<UnderlyingType, ComplexSchemaType>;
174
+ dataTypeUniqueId: DataTypeUniqueId;
175
+ } | null;
176
+ } & ({
177
+ /** String output type */
178
+ type: 'string';
179
+ } | {
180
+ /** Number output type */
181
+ type: 'number';
182
+ } | {
183
+ /** Boolean output type */
184
+ type: 'boolean';
185
+ } | {
186
+ /** Unsupported output type */
187
+ type: 'unsupportedDirectly';
188
+ });
189
+
190
+ /**
191
+ * Props for the ConfigurableNode component
192
+ *
193
+ * Defines the complete configuration for a customizable node with inputs, outputs,
194
+ * and optional panels. Supports both standalone usage and ReactFlow integration.
195
+ */
196
+ declare type ConfigurableNodeProps<UnderlyingType extends SupportedUnderlyingTypes = SupportedUnderlyingTypes, NodeTypeUniqueId extends string = string, ComplexSchemaType extends UnderlyingType extends 'complex' ? z.ZodType : never = never, DataTypeUniqueId extends string = string> = {
197
+ /** Unique identifier for the node, for debugging when enableDebugMode is true and inside react flow */
198
+ id?: string;
199
+ /** Display name of the node */
200
+ name?: string;
201
+ /** Optional user-chosen instance name shown over the type name (standard nodes
202
+ * only; absent = show the type name). */
203
+ customName?: string;
204
+ /** Whether this node instance's preview panel is collapsed (persisted on
205
+ * `node.data`; absent = expanded). Only rendered when a `nodePreviews`
206
+ * component is registered for this node type. */
207
+ previewCollapsed?: boolean;
208
+ /** Background color of the node header */
209
+ headerColor?: string;
210
+ /** Array of inputs and input panels */
211
+ inputs?: (ConfigurableNodeInput<UnderlyingType, ComplexSchemaType, DataTypeUniqueId> | ConfigurableNodeInputPanel<UnderlyingType, ComplexSchemaType, DataTypeUniqueId>)[];
212
+ /** Array of output sockets */
213
+ outputs?: ConfigurableNodeOutput<UnderlyingType, ComplexSchemaType, DataTypeUniqueId>[];
214
+ /** Whether the node is currently inside a ReactFlow context */
215
+ isCurrentlyInsideReactFlow?: boolean;
216
+ /** Props for the node resizer component */
217
+ nodeResizerProps?: NodeResizerWithMoreControlsProps;
218
+ /** Node type unique id */
219
+ nodeTypeUniqueId?: NodeTypeUniqueId;
220
+ /** Runner visual state for this node (undefined = no runner overlay) */
221
+ runnerVisualState?: NodeVisualState;
222
+ /** Errors from the runner for this node */
223
+ runnerErrors?: ReadonlyArray<GraphError>;
224
+ /** Warnings from the runner for this node (e.g., missing implementation) */
225
+ runnerWarnings?: ReadonlyArray<string>;
226
+ } & HTMLAttributes<HTMLDivElement>;
227
+
228
+ /** Props for the ConfigurableNodeReactFlowWrapper component */
229
+ declare type ConfigurableNodeReactFlowWrapperProps<UnderlyingType extends SupportedUnderlyingTypes = SupportedUnderlyingTypes, NodeTypeUniqueId extends string = string, ComplexSchemaType extends UnderlyingType extends 'complex' ? z.ZodType : never = never, DataTypeUniqueId extends string = string> = NodeProps<ConfigurableNodeState<UnderlyingType, NodeTypeUniqueId, ComplexSchemaType, DataTypeUniqueId>> & {
230
+ position: XYPosition;
231
+ };
232
+
233
+ /** State type for configurable nodes in ReactFlow */
234
+ declare type ConfigurableNodeState<UnderlyingType extends SupportedUnderlyingTypes = SupportedUnderlyingTypes, NodeTypeUniqueId extends string = string, ComplexSchemaType extends UnderlyingType extends 'complex' ? z.ZodType : never = never, DataTypeUniqueId extends string = string> = Node_2<Omit<ConfigurableNodeProps<UnderlyingType, NodeTypeUniqueId, ComplexSchemaType, DataTypeUniqueId>, 'isCurrentlyInsideReactFlow'>, 'configurableNode'>;
235
+
236
+ /**
237
+ * Definition of a data type in the graph system
238
+ *
239
+ * @template UnderlyingType - The underlying type of the data
240
+ * @template ComplexSchemaType - Zod schema type for complex data types
241
+ */
242
+ declare type DataType<UnderlyingType extends SupportedUnderlyingTypes = SupportedUnderlyingTypes, ComplexSchemaType extends UnderlyingType extends 'complex' ? z.ZodType : never = never> = UnderlyingType extends 'complex' ? {
243
+ /** Display name of the data type */
244
+ name: string;
245
+ /** The underlying type of the data */
246
+ underlyingType: UnderlyingType;
247
+ /** Zod schema for complex data validation */
248
+ complexSchema: ComplexSchemaType;
249
+ /** Color used for visual representation */
250
+ color: string;
251
+ /** Shape of the handle */
252
+ shape?: HandleShape;
253
+ /** Whether this input allows direct user input */
254
+ allowInput?: boolean;
255
+ /** Maximum number of connections for this data type */
256
+ maxConnections?: number;
257
+ } : {
258
+ /** Display name of the data type */
259
+ name: string;
260
+ /** The underlying type of the data */
261
+ underlyingType: UnderlyingType;
262
+ /** Complex schema is not used for non-complex types */
263
+ complexSchema?: undefined;
264
+ /** Color used for visual representation */
265
+ color: string;
266
+ /** Shape of the handle */
267
+ shape?: HandleShape;
268
+ /** Whether this input allows direct user input */
269
+ allowInput?: boolean;
270
+ /** Maximum number of connections for this data type */
271
+ maxConnections?: number;
272
+ /** When set on a string type, renders a select dropdown instead of a free-text input. */
273
+ allowedStrings?: readonly string[];
274
+ };
275
+
276
+ /**
277
+ * Trigger a browser download of `text` as a file named `filename`.
278
+ *
279
+ * A tiny, library-free DOM helper that the built-in artifact run targets
280
+ * (`json-ir`, `codegen-js`) use to deliver their output. It is part of the
281
+ * public run-targets surface so a custom artifact target can reuse it instead of
282
+ * re-implementing blob/anchor plumbing — though a target is equally free to
283
+ * deliver its artifact another way (a callback, a network upload, …) inside its
284
+ * own `run`.
285
+ *
286
+ * No-op when there is no DOM (SSR / unit tests, or a browser without
287
+ * `URL.createObjectURL`) so invoking an artifact target's `run` never throws
288
+ * outside the browser.
289
+ */
290
+ export declare function downloadTextArtifact(filename: string, text: string, mimeType?: string): void;
291
+
292
+ /**
293
+ * Array of configurable edges in the graph
294
+ */
295
+ declare type Edges = ConfigurableEdgeState[];
296
+
297
+ /**
298
+ * The compiled execution plan — an intermediate representation
299
+ * of the graph ready for execution. Produced by the compiler,
300
+ * consumed by the executor.
301
+ *
302
+ * Steps are grouped into concurrency levels: all steps within
303
+ * a level have no data dependencies on each other and can
304
+ * execute concurrently via Promise.allSettled.
305
+ */
306
+ export declare type ExecutionPlan = {
307
+ /**
308
+ * Steps grouped by concurrency level.
309
+ * levels[0] runs first, levels[1] after all of levels[0] complete, etc.
310
+ * Steps within the same level run concurrently.
311
+ */
312
+ levels: ReadonlyArray<ReadonlyArray<ExecutionStep>>;
313
+ /**
314
+ * Maps "nodeId:handleId" to the list of edges that feed into that input handle.
315
+ * Used by the executor to resolve input values from the ValueStore.
316
+ */
317
+ inputResolutionMap: ReadonlyMap<string, ReadonlyArray<InputResolutionEntry>>;
318
+ /**
319
+ * Maps "nodeId:handleId" to the list of edges that consume from that output handle.
320
+ * Used for building OutputHandleInfo for function implementations.
321
+ */
322
+ outputDistributionMap: ReadonlyMap<string, ReadonlyArray<OutputDistributionEntry>>;
323
+ /** Total number of executable nodes in the plan */
324
+ nodeCount: number;
325
+ /** Warnings generated during compilation (e.g., missing implementations) */
326
+ warnings: ReadonlyArray<string>;
327
+ /** Root-level Graph Input node id, when the graph declares its own inputs. Its
328
+ * output handles are the program's parameters (fed by the executor's
329
+ * `rootInputs` / codegen's `runGraph` params). Absent ⇒ no declared inputs. */
330
+ rootInputNodeId?: string;
331
+ /** Root-level Graph Output node id, when the graph declares its own outputs. Its
332
+ * input handles are the program's return (collected as `rootOutputs` / codegen's
333
+ * `runGraph` return). Absent ⇒ the whole value store is returned (compat). */
334
+ rootOutputNodeId?: string;
335
+ };
336
+
337
+ /**
338
+ * Discriminated union of all execution step types.
339
+ * Used in the ExecutionPlan's levels array.
340
+ */
341
+ export declare type ExecutionStep = StandardExecutionStep | LoopExecutionBlock | SwitchExecutionBlock | GroupExecutionScope;
342
+
343
+ /** Find the condition input handle on Loop Stop (the one with dataType 'condition'). */
344
+ export declare function findConditionInputId(handles: ReadonlyArray<{
345
+ id?: string;
346
+ dataType?: {
347
+ dataTypeUniqueId?: string;
348
+ };
349
+ inferredDataType?: {
350
+ dataTypeUniqueId?: string;
351
+ } | null;
352
+ }>): string | undefined;
353
+
354
+ /**
355
+ * Flattens inputs (which may contain panels) into a flat array of
356
+ * individual input handles, preserving index order.
357
+ */
358
+ export declare function flattenInputs(inputs: ReadonlyArray<MinimalInput | MinimalInputPanel> | undefined): MinimalInput[];
359
+
360
+ /** Extract handle IDs for user data handles (not bindLoopNodes, loopInfer, or condition). */
361
+ export declare function getDataHandleIds(handles: ReadonlyArray<{
362
+ id?: string;
363
+ dataType?: {
364
+ dataTypeUniqueId?: string;
365
+ };
366
+ inferredDataType?: {
367
+ dataTypeUniqueId?: string;
368
+ } | null;
369
+ }>): string[];
370
+
371
+ /**
372
+ * A rich error type capturing the full context of where and
373
+ * how an error occurred during graph execution.
374
+ *
375
+ * Includes the error message, the node that errored, the full
376
+ * execution path leading to it, and optional loop/group context.
377
+ */
378
+ declare type GraphError = {
379
+ /** Human-readable error message */
380
+ message: string;
381
+ /** ID of the node where the error occurred */
382
+ nodeId: string;
383
+ /** Node type ID */
384
+ nodeTypeId: string;
385
+ /** Display name of the node type */
386
+ nodeTypeName: string;
387
+ /** Optional user-given custom display name (standard nodes only) */
388
+ customName?: string;
389
+ /** Handle ID where the error manifested (if applicable) */
390
+ handleId?: string;
391
+ /** Ordered list of nodes in the execution path leading to this error */
392
+ path: ReadonlyArray<GraphErrorPathEntry>;
393
+ /** Loop context (if the error occurred inside a loop) */
394
+ loopContext?: {
395
+ loopStructureId: string;
396
+ iteration: number;
397
+ maxIterations: number;
398
+ };
399
+ /** Group context (if the error occurred inside a node group) */
400
+ groupContext?: {
401
+ groupNodeId: string;
402
+ groupNodeTypeId: string;
403
+ depth: number;
404
+ };
405
+ /** Timestamp when the error occurred (performance.now() relative to run start) */
406
+ timestamp: number;
407
+ /** Duration of the step before the error (ms) */
408
+ duration: number;
409
+ /** The original thrown error value */
410
+ originalError: unknown;
411
+ };
412
+
413
+ /**
414
+ * One entry in the error's execution path trace,
415
+ * showing the chain of nodes that led to the error.
416
+ */
417
+ declare type GraphErrorPathEntry = {
418
+ nodeId: string;
419
+ nodeTypeId: string;
420
+ nodeTypeName: string;
421
+ customName?: string;
422
+ handleId?: string;
423
+ concurrencyLevel: number;
424
+ };
425
+
426
+ /**
427
+ * A compiled node group scope containing the recursive inner execution plan
428
+ * and the handle mappings between outer and inner boundaries.
429
+ */
430
+ export declare type GroupExecutionScope = {
431
+ kind: 'group';
432
+ /** The group node instance ID in the outer graph */
433
+ groupNodeId: string;
434
+ /** The group's node type ID (key in typeOfNodes) */
435
+ groupNodeTypeId: string;
436
+ /** Display name of the group node type */
437
+ groupNodeTypeName: string;
438
+ /** Recursively compiled execution plan for the subtree */
439
+ innerPlan: ExecutionPlan;
440
+ /** Map of outer input handle IDs to inner GroupInput output handle IDs */
441
+ inputMapping: ReadonlyMap<string, string>;
442
+ /** Map of inner GroupOutput input handle IDs to outer output handle IDs */
443
+ outputMapping: ReadonlyMap<string, string>;
444
+ concurrencyLevel: number;
445
+ };
446
+
447
+ /** Type representing all available handle shapes */
448
+ declare type HandleShape = (typeof handleShapesMap)[keyof typeof handleShapesMap];
449
+
450
+ /** Map of handle shapes for type-safe access */
451
+ declare const handleShapesMap: {
452
+ readonly circle: "circle";
453
+ readonly square: "square";
454
+ readonly rectangle: "rectangle";
455
+ readonly list: "list";
456
+ readonly grid: "grid";
457
+ readonly diamond: "diamond";
458
+ readonly trapezium: "trapezium";
459
+ readonly hexagon: "hexagon";
460
+ readonly star: "star";
461
+ readonly cross: "cross";
462
+ readonly zigzag: "zigzag";
463
+ readonly sparkle: "sparkle";
464
+ readonly parallelogram: "parallelogram";
465
+ };
466
+
467
+ /**
468
+ * Configuration for the undo/redo history subsystem.
469
+ *
470
+ * @example
471
+ * ```ts
472
+ * const initialState = makeStateWithAutoInfer({
473
+ * ...myState,
474
+ * history: {
475
+ * undoStack: [],
476
+ * redoStack: [],
477
+ * config: { maxSize: 100 },
478
+ * activeBatch: null,
479
+ * },
480
+ * });
481
+ * ```
482
+ */
483
+ declare type HistoryConfig = {
484
+ /** Maximum number of undo entries. Undefined means unlimited. */
485
+ maxSize?: number;
486
+ };
487
+
488
+ /**
489
+ * A single entry in the undo/redo history.
490
+ *
491
+ * Stores the Immer patches that transition state forward (for redo)
492
+ * and backward (for undo). The actionType is stored for debugging
493
+ * and optional UI labeling (e.g., tooltip: "Undo Add Node").
494
+ *
495
+ * @example
496
+ * ```ts
497
+ * const entry: HistoryEntry = {
498
+ * patches: [{ op: 'add', path: ['nodes', 5], value: newNode }],
499
+ * inversePatches: [{ op: 'remove', path: ['nodes', 5] }],
500
+ * actionType: 'ADD_NODE',
501
+ * timestamp: 1716825600000,
502
+ * };
503
+ * ```
504
+ */
505
+ declare type HistoryEntry = {
506
+ /** Patches to move state forward (apply on redo). */
507
+ patches: Patch[];
508
+ /** Patches to move state backward (apply on undo). */
509
+ inversePatches: Patch[];
510
+ /** The action type(s) that produced this entry, for debugging/display. */
511
+ actionType: string;
512
+ /** Timestamp of when this entry was created. */
513
+ timestamp: number;
514
+ };
515
+
516
+ /**
517
+ * Describes one edge feeding into a specific input handle.
518
+ * Multiple entries for the same handle indicate fan-in.
519
+ */
520
+ declare type InputResolutionEntry = {
521
+ edgeId: string;
522
+ sourceNodeId: string;
523
+ sourceHandleId: string;
524
+ /**
525
+ * Position of this edge in `state.edges` at compile time — the deterministic
526
+ * tiebreak when two connections in the same fan-in group share (or both lack) a
527
+ * `data.order`. Mirrors the reorder popover's `reactFlow.getEdges()` index (both
528
+ * derive from the same edges array), so on-screen order ≡ compiled order without
529
+ * relying on `Array.prototype.sort` stability. Also surfaced (additive) in the
530
+ * `json-ir` run target. `compile()` ALWAYS sets it; optional in the type only so
531
+ * hand-built test fixtures (codegen tests that never read it) needn't supply it.
532
+ */
533
+ edgesArrayIndex?: number;
534
+ };
535
+
536
+ /**
537
+ * A compiled loop structure containing the loop triplet node IDs
538
+ * and the topologically sorted body steps.
539
+ */
540
+ export declare type LoopExecutionBlock = {
541
+ kind: 'loop';
542
+ loopStartNodeId: string;
543
+ loopStopNodeId: string;
544
+ loopEndNodeId: string;
545
+ /** Topologically sorted body steps (nodes between loopStart and loopStop) */
546
+ preStopSteps: ReadonlyArray<ExecutionStep>;
547
+ /** Topologically sorted body steps (nodes between loopStop and loopEnd) */
548
+ postStopSteps: ReadonlyArray<ExecutionStep>;
549
+ /** Maximum iterations before erroring (configurable, default 100) */
550
+ maxIterations: number;
551
+ concurrencyLevel: number;
552
+ };
553
+
554
+ /**
555
+ * Minimal structural types for reading node handle data without
556
+ * importing the full generic ConfigurableNode types (avoids variance issues).
557
+ */
558
+ export declare type MinimalInput = {
559
+ id?: string;
560
+ name?: string;
561
+ allowInput?: boolean;
562
+ value?: unknown;
563
+ dataType?: {
564
+ dataTypeUniqueId?: string;
565
+ };
566
+ inferredDataType?: {
567
+ dataTypeUniqueId?: string;
568
+ } | null;
569
+ };
570
+
571
+ export declare type MinimalInputPanel = {
572
+ id?: string;
573
+ name?: string;
574
+ inputs: ReadonlyArray<MinimalInput>;
575
+ };
576
+
577
+ export declare type MinimalNodeData = {
578
+ inputs?: ReadonlyArray<MinimalInput | MinimalInputPanel>;
579
+ outputs?: ReadonlyArray<MinimalOutput>;
580
+ nodeTypeUniqueId?: string;
581
+ /** Optional user custom name (standard nodes only) — for the inspector's
582
+ * "coming from" source label. */
583
+ customName?: string;
584
+ };
585
+
586
+ export declare type MinimalOutput = {
587
+ id?: string;
588
+ name?: string;
589
+ dataType?: {
590
+ dataTypeUniqueId?: string;
591
+ };
592
+ inferredDataType?: {
593
+ dataTypeUniqueId?: string;
594
+ } | null;
595
+ };
596
+
597
+ /**
598
+ * Constraints on how many nodes of each type may exist in different scopes.
599
+ *
600
+ * - If undefined on State: no constraints at all
601
+ * - If a node type has no entry: no constraints for that type
602
+ * - Each field is optional; only provided fields are enforced (AND-ed together)
603
+ * - Only checked during ADD_NODE (max) and node deletion (min)
604
+ *
605
+ * @template NodeTypeUniqueId - Unique identifier type for node types
606
+ */
607
+ declare type NodeCountConstraints<NodeTypeUniqueId extends string = string> = Partial<Record<NodeTypeUniqueId, {
608
+ /** Minimum count across root + all group subtrees combined */
609
+ minAcrossAllNodes?: number;
610
+ /** Maximum count across root + all group subtrees combined */
611
+ maxAcrossAllNodes?: number;
612
+ /** Minimum count within each individual group subtree (checked per-group) */
613
+ minWithinANodeGroup?: number;
614
+ /** Maximum count within each individual group subtree (checked per-group) */
615
+ maxWithinANodeGroup?: number;
616
+ /** Minimum count in the root scope only */
617
+ minInRoot?: number;
618
+ /** Maximum count in the root scope only */
619
+ maxInRoot?: number;
620
+ }>>;
621
+
622
+ declare type NodeOptionalKeys = 'draggable' | 'zIndex' | 'selectable' | 'deletable' | 'dragging' | 'selected' | 'isConnectable' | 'positionAbsoluteX' | 'positionAbsoluteY';
623
+
624
+ /**
625
+ * Props for the NodeResizerWithMoreControls component
626
+ */
627
+ declare type NodeResizerWithMoreControlsProps = NodeResizerProps & {
628
+ /** Array of line positions for resize controls */
629
+ linePosition?: ControlLinePosition[];
630
+ /** Array of handle positions for resize controls */
631
+ handlePosition?: ControlPosition[];
632
+ /** Direction of resize operation */
633
+ resizeDirection?: ResizeControlDirection;
634
+ };
635
+
636
+ /**
637
+ * Array of configurable nodes in the graph
638
+ */
639
+ declare type Nodes<UnderlyingType extends SupportedUnderlyingTypes = SupportedUnderlyingTypes, NodeTypeUniqueId extends string = string, ComplexSchemaType extends UnderlyingType extends 'complex' ? z.ZodType : never = never, DataTypeUniqueId extends string = string> = Optional<ConfigurableNodeReactFlowWrapperProps<UnderlyingType, NodeTypeUniqueId, ComplexSchemaType, DataTypeUniqueId>, NodeOptionalKeys>[];
640
+
641
+ declare type NodeVisualState = (typeof nodeVisualStates)[number];
642
+
643
+ declare const nodeVisualStates: readonly ["idle", "running", "completed", "errored", "skipped", "warning"];
644
+
645
+ declare type Optional<T, K extends keyof T> = Pick<Partial<T>, K> & Omit<T, K>;
646
+
647
+ /**
648
+ * Describes one edge consuming from a specific output handle.
649
+ * Multiple entries for the same handle indicate fan-out.
650
+ */
651
+ declare type OutputDistributionEntry = {
652
+ edgeId: string;
653
+ targetNodeId: string;
654
+ targetHandleId: string;
655
+ };
656
+
657
+ /**
658
+ * Builds the qualified handle ID used as a key in the ValueStore.
659
+ * Format: "nodeId:handleId"
660
+ *
661
+ * **Important:** `nodeId` and `handleId` must NOT contain `:` or `>`
662
+ * characters. `:` is the internal separator between node and handle IDs,
663
+ * and `>` is the scope separator used by {@link ValueStore.createScope}.
664
+ * Using these characters in IDs will cause data corruption in the runner.
665
+ */
666
+ export declare function qualifiedId(nodeId: string, handleId: string): string;
667
+
668
+ /** Minimal structural shape of one input handle's value (matches the runner). */
669
+ export declare type ReadableInputHandle = {
670
+ connections: ReadonlyArray<{
671
+ value: unknown;
672
+ }>;
673
+ defaultValue?: unknown;
674
+ };
675
+
676
+ /**
677
+ * Read a node input by handle name.
678
+ *
679
+ * @param inputs - The implementation's input map (handle name → value).
680
+ * @param name - The input handle name.
681
+ * @returns Every connected value (fan-in), or `[bakedDefault]` when unconnected.
682
+ */
683
+ export declare function readInput(inputs: ReadonlyMap<string, ReadableInputHandle>, name: string): unknown[];
684
+
685
+ /**
686
+ * Resize direction, derived from the ReactFlow control's own prop type so it
687
+ * stays in lockstep with the underlying control instead of reaching into
688
+ * `@xyflow/system` internals for a single prop type.
689
+ */
690
+ declare type ResizeControlDirection = NonNullable<ComponentProps<typeof NodeResizeControl>['resizeDirection']>;
691
+
692
+ /**
693
+ * Runner-panel view preferences — document-level, PERSISTED runner UI preferences
694
+ * that live on the graph `State` (distinct from the per-recording
695
+ * `RecordingViewState`).
696
+ *
697
+ * - `autoScroll` — auto-scroll the timeline and canvas to follow the selected step.
698
+ * - `followIntoGroups` — open/close group scopes so the canvas follows the scrub
699
+ * head into the executing group instance.
700
+ *
701
+ * Both are toggled through the `UPDATE_RUNNER_VIEW_PREFERENCE` reducer action,
702
+ * persisted on state export (like `userZones`), and defaulted per-field on read.
703
+ *
704
+ * This module imports NOTHING (a pure leaf) so it can be imported from anywhere
705
+ * without a cycle; the accessor takes a STRUCTURAL parameter (not `State<…>`), which
706
+ * also sidesteps the 4-parameter generic-widening trap at concretely-typed call
707
+ * sites.
708
+ */
709
+ declare type RunnerViewPreferences = {
710
+ autoScroll: boolean;
711
+ followIntoGroups: boolean;
712
+ };
713
+
714
+ /**
715
+ * Read-only data EVERY target receives. NOTE: `functionImplementations` is NOT
716
+ * here — no artifact target needs the impl closures (json-ir serializes the
717
+ * plan; codegen emits a function that TAKES impls as a parameter), so it lives
718
+ * on `ExecuteRunContext` only (Interface Segregation).
719
+ */
720
+ declare type RunTargetContextBase<DataTypeUniqueId extends string = string, NodeTypeUniqueId extends string = string, UnderlyingType extends SupportedUnderlyingTypes = SupportedUnderlyingTypes, ComplexSchemaType extends UnderlyingType extends 'complex' ? z.ZodType : never = never> = {
721
+ /** Raw graph state — escape hatch for targets that re-derive their own IR. */
722
+ state: Readonly<State<DataTypeUniqueId, NodeTypeUniqueId, UnderlyingType, ComplexSchemaType>>;
723
+ /** The compiled stable IR — the default input a target consumes. */
724
+ executionPlan: ExecutionPlan;
725
+ options: {
726
+ maxLoopIterations: number;
727
+ };
728
+ abortSignal: AbortSignal;
729
+ /**
730
+ * Values for the graph's declared root inputs, keyed by Graph Input handle
731
+ * NAME. The in-process executor seeds these into the root Graph Input node's
732
+ * output handles (mirroring codegen's `runGraph(a, b)` parameters); other
733
+ * targets may forward them however they model parameters. Absent / `undefined`
734
+ * when the graph declares no root inputs or the host supplies no values.
735
+ */
736
+ rootInputs?: Record<string, unknown>;
737
+ };
738
+
739
+ declare type RunTargetIdentity = {
740
+ /** Stable unique id (used for selection + dedupe). */
741
+ id: string;
742
+ /** Human-facing label for the run-target dropdown. */
743
+ label: string;
744
+ /** Optional icon shown in the dropdown / on the Run button. */
745
+ icon?: ReactNode;
746
+ };
747
+
748
+ /**
749
+ * A standard node execution step — call the function implementation,
750
+ * pass inputs, store outputs.
751
+ */
752
+ export declare type StandardExecutionStep = {
753
+ kind: 'standard';
754
+ nodeId: string;
755
+ nodeTypeId: string;
756
+ nodeTypeName: string;
757
+ /** Optional user custom name for this node instance (standard nodes only). */
758
+ customName?: string;
759
+ concurrencyLevel: number;
760
+ };
761
+
762
+ /**
763
+ * Complete state definition for the graph system
764
+ *
765
+ * @template DataTypeUniqueId - Unique identifier type for data types
766
+ * @template NodeTypeUniqueId - Unique identifier type for node types
767
+ * @template UnderlyingType - Supported underlying data types ('string' | 'number' | 'complex')
768
+ * @template ComplexSchemaType - Zod schema type for complex data types
769
+ */
770
+ export declare type State<DataTypeUniqueId extends string = string, NodeTypeUniqueId extends string = string, UnderlyingType extends SupportedUnderlyingTypes = SupportedUnderlyingTypes, ComplexSchemaType extends UnderlyingType extends 'complex' ? z.ZodType : never = never> = {
771
+ openedNodeGroupStack?: ({
772
+ nodeType: NodeTypeUniqueId;
773
+ previousViewport?: Viewport;
774
+ } | {
775
+ nodeType: NodeTypeUniqueId;
776
+ /**
777
+ * If not provided, it means that this node group isn't instantiated yet and we are editing the original node group
778
+ */
779
+ nodeId: string;
780
+ previousViewport?: Viewport;
781
+ })[];
782
+ /** Map of data type definitions */
783
+ dataTypes: Record<DataTypeUniqueId, DataType<UnderlyingType, ComplexSchemaType>>;
784
+ /** Current viewport of the graph */
785
+ viewport?: Viewport;
786
+ /** Map of node type definitions */
787
+ typeOfNodes: Record<NodeTypeUniqueId, TypeOfNode<DataTypeUniqueId, NodeTypeUniqueId, UnderlyingType, ComplexSchemaType>>;
788
+ /** Array of nodes in the graph */
789
+ nodes: Nodes<UnderlyingType, NodeTypeUniqueId, ComplexSchemaType, DataTypeUniqueId>;
790
+ /** Array of edges in the graph */
791
+ edges: Edges;
792
+ /**
793
+ * Optional mapping of allowed conversions between data types
794
+ * - When not provided, all conversions are allowed
795
+ * - If provided, only the conversions that are explicitly allowed will be allowed (happens even with empty object)
796
+ * - By default, it will not allow conversion between complex types unless explicitly allowed here (even if complex type checking is enabled)
797
+ * - If you want to allow conversion between complex types unless disallowed by complex type checking, you can set `allowConversionBetweenComplexTypesUnlessDisallowedByComplexTypeChecking` to true
798
+ *
799
+ * @default undefined
800
+ */
801
+ allowedConversionsBetweenDataTypes?: AllowedConversionsBetweenDataTypes<DataTypeUniqueId>;
802
+ /**
803
+ * Whether to allow conversion between complex types unless disallowed by complex type checking
804
+ * - If not provided, is considered disabled
805
+ * - Only takes effect if complex type checking is enabled (`allowedConversionsBetweenDataTypes` is provided)
806
+ * - If enabled, it will allow conversion between complex types unless disallowed by complex type checking
807
+ * - If disabled, it will not allow conversion between complex types unless explicitly allowed by `allowedConversionsBetweenDataTypes`, even if complex type checking is enabled
808
+ *
809
+ * @default undefined
810
+ */
811
+ allowConversionBetweenComplexTypesUnlessDisallowedByComplexTypeChecking?: boolean;
812
+ /**
813
+ * Whether to enable type inference
814
+ * - If not provided, is considered disabled
815
+ * - When disabled, the types of the nodes are not inferred from the connections
816
+ * - When enabled, the types of the nodes are inferred from the connections and reset when edges are removed
817
+ *
818
+ * @default undefined
819
+ */
820
+ enableTypeInference?: boolean;
821
+ /**
822
+ * Whether to enable complex type checking
823
+ * - If not provided, is considered disabled
824
+ * - When disabled, the complex types are not checked for compatibility, all connections are allowed
825
+ * - When enabled, the complex types are checked for compatibility, and connections are not allowed if the complex types are not compatible
826
+ * - Complex types are compatible if they are the same type or if they have exactly the same schema
827
+ *
828
+ * @default undefined
829
+ */
830
+ enableComplexTypeChecking?: boolean;
831
+ /**
832
+ * Whether to enable cycle checking
833
+ * - If not provided, is considered disabled
834
+ * - When disabled, the cycles are not checked, all connections are allowed
835
+ * - When enabled, the cycles are checked, and connections are not allowed if they create a cycle
836
+ *
837
+ * @default undefined
838
+ */
839
+ enableCycleChecking?: boolean;
840
+ /**
841
+ * Whether to enable recursion checking
842
+ * - If not provided, is considered disabled
843
+ * - When disabled, the recursion is not checked, all nesting of node groups is allowed
844
+ * - When enabled, the recursion is checked, and nesting of node groups is not allowed if it creates a recursion
845
+ *
846
+ * @default undefined
847
+ */
848
+ enableRecursionChecking?: boolean;
849
+ /**
850
+ * Optional constraints on how many nodes of each type may exist.
851
+ * If not provided, no constraints are enforced.
852
+ * Only checked during ADD_NODE (max) and node deletion (min).
853
+ *
854
+ * @default undefined
855
+ */
856
+ nodeCountConstraints?: NodeCountConstraints<NodeTypeUniqueId>;
857
+ /**
858
+ * Node types to hide from the "Add Node" context menu.
859
+ * If not provided, all node types are shown.
860
+ * Use `standardHiddenNodeTypesInContextMenu` from standardNodes for the default set.
861
+ *
862
+ * @default undefined
863
+ */
864
+ hiddenNodeTypesInContextMenu?: Partial<Record<NodeTypeUniqueId, true>>;
865
+ /**
866
+ * Whether to enable debugging mode
867
+ * - If not provided, is considered disabled
868
+ * - When disabled, no debug information is displayed in the graph
869
+ * - When enabled, debug information is displayed in the graph
870
+ *
871
+ * @default undefined
872
+ */
873
+ enableDebugMode?: boolean;
874
+ /**
875
+ * Currently open drawer. UI-only state — stripped during export.
876
+ * Managed by OPEN_DRAWER / CLOSE_DRAWER actions.
877
+ * @default undefined
878
+ */
879
+ activeDrawer?: ActiveDrawer;
880
+ /**
881
+ * Root-level zone definitions for structures at the top scope.
882
+ * Each zone defines a region with boundary handles, visual frame, and
883
+ * optional connection enforcement. UI-only — stripped on export,
884
+ * rehydrated on import via REPLACE_STATE.
885
+ * @default undefined
886
+ */
887
+ zones?: Record<string, Zone>;
888
+ /**
889
+ * Reverse index from boundary handle IDs to zone IDs for O(1)
890
+ * lookups during connection validation. Rebuilt whenever zones change.
891
+ * UI-only — stripped on export.
892
+ * @default undefined
893
+ */
894
+ zoneIndex?: ZoneIndex;
895
+ /**
896
+ * Root-level USER-AUTHORED zones (named/colored visual frames the user creates
897
+ * around selected nodes). Unlike `zones` (derived from loop/switch structures,
898
+ * recomputed/stripped/rehydrated), these are AUTHORED: membership is an explicit
899
+ * `nodeIds` set, never recomputed. Persisted in export (NOT stripped) and forwarded
900
+ * on import (NOT rehydrated). Visual-only — `enforced: false`, no
901
+ * boundaryHandles/structureLink. Scope-local like `zones` (root vs subtree).
902
+ * @default undefined
903
+ */
904
+ userZones?: Record<string, Zone>;
905
+ /**
906
+ * Document-level runner-panel view preferences: `autoScroll` (auto-scroll the
907
+ * timeline/canvas to the selected step) and `followIntoGroups` (follow the scrub
908
+ * head into executing group instances). Toggled by UPDATE_RUNNER_VIEW_PREFERENCE.
909
+ * Persisted on export and forwarded on import (NOT stripped, NOT rehydrated) like
910
+ * `userZones`; GLOBAL (root-only, not scope-local — no subtree copy). The
911
+ * per-recording snapshot lives in `RecordingViewState`; `autoScroll` is mirrored
912
+ * there with graph state authoritative and NOT restored on load. Inner fields
913
+ * REQUIRED — read via `getRunnerViewPreferences`, which defaults per-field.
914
+ * @default undefined → read as { autoScroll: true, followIntoGroups: true }
915
+ */
916
+ runnerViewPreferences?: RunnerViewPreferences;
917
+ /**
918
+ * Undo/redo history. Stores Immer patches for each undoable action.
919
+ * Managed by UNDO, REDO, BEGIN_BATCH, END_BATCH, CLEAR_HISTORY actions.
920
+ * Stripped on export by default; optionally preserved via "Export with History".
921
+ * @default undefined
922
+ */
923
+ history?: {
924
+ undoStack: HistoryEntry[];
925
+ redoStack: HistoryEntry[];
926
+ config: HistoryConfig;
927
+ activeBatch: {
928
+ patches: Patch[];
929
+ inversePatches: Patch[];
930
+ actionTypes: string[];
931
+ startTimestamp: number;
932
+ } | null;
933
+ };
934
+ };
935
+
936
+ /**
937
+ * Union type of all supported underlying data types
938
+ */
939
+ export declare type SupportedUnderlyingTypes = (typeof supportedUnderlyingTypes)[number];
940
+
941
+ /**
942
+ * Array of supported underlying data types
943
+ */
944
+ declare const supportedUnderlyingTypes: readonly ["string", "number", "boolean", "complex", "noEquivalent", "inferFromConnection"];
945
+
946
+ export declare type SwitchExecutionBlock = {
947
+ kind: 'switch';
948
+ switchStartNodeId: string;
949
+ switchEndNodeId: string;
950
+ trueBranchSteps: ReadonlyArray<ExecutionStep>;
951
+ falseBranchSteps: ReadonlyArray<ExecutionStep>;
952
+ concurrencyLevel: number;
953
+ };
954
+
955
+ /**
956
+ * Definition of an input type in a node
957
+ *
958
+ * @template DataTypeUniqueId - Unique identifier type for data types
959
+ */
960
+ declare type TypeOfInput<DataTypeUniqueId extends string = string> = {
961
+ /** Display name of the input */
962
+ name: string;
963
+ /** The data type identifier this input uses */
964
+ dataType: DataTypeUniqueId;
965
+ /** Whether this input allows direct user input */
966
+ allowInput?: boolean;
967
+ /** Maximum number of connections for this input */
968
+ maxConnections?: number;
969
+ /**
970
+ * Initial value seeded onto a freshly-constructed node's input handle
971
+ * (`node.data.inputs[].value`). Copied at construction only for
972
+ * `number`/`string`/`boolean` underlying types whose runtime value matches;
973
+ * ignored for `complex`/`inferFromConnection`/`noEquivalent`. Lets a node
974
+ * type declare its own defaults instead of the consumer seeding them via
975
+ * `UPDATE_INPUT_VALUE` after every add.
976
+ */
977
+ defaultValue?: string | number | boolean;
978
+ };
979
+
980
+ /**
981
+ * Definition of an input panel type in a node
982
+ *
983
+ * @template DataTypeUniqueId - Unique identifier type for data types
984
+ */
985
+ declare type TypeOfInputPanel<DataTypeUniqueId extends string = string> = {
986
+ /** Display name of the input panel */
987
+ name: string;
988
+ /** Array of inputs within this panel */
989
+ inputs: TypeOfInput<DataTypeUniqueId>[];
990
+ };
991
+
992
+ /**
993
+ * Definition of a node type in the graph system
994
+ *
995
+ * @template DataTypeUniqueId - Unique identifier type for data types
996
+ */
997
+ declare type TypeOfNode<DataTypeUniqueId extends string = string, NodeTypeUniqueId extends string = string, UnderlyingType extends SupportedUnderlyingTypes = SupportedUnderlyingTypes, ComplexSchemaType extends UnderlyingType extends 'complex' ? z.ZodType : never = never> = {
998
+ /** Display name of the node type */
999
+ name: string;
1000
+ /** Color used for the node header */
1001
+ headerColor?: string;
1002
+ /** Array of inputs (can be regular inputs or input panels) */
1003
+ inputs: (TypeOfInput<DataTypeUniqueId> | TypeOfInputPanel<DataTypeUniqueId>)[];
1004
+ /** Array of outputs */
1005
+ outputs: TypeOfInput<DataTypeUniqueId>[];
1006
+ /** Path in the "Add Node" context menu. e.g. ["Math", "Trig"] nests under Math > Trig.
1007
+ * Omit to place at root level of "Add Node". */
1008
+ locationInContextMenu?: string[];
1009
+ /** Ordering priority in the context menu. Higher values appear first. Default: 0. */
1010
+ priorityInContextMenu?: number;
1011
+ /** Subtree of the node type (if this exists, this is a node group) */
1012
+ subtree?: {
1013
+ nodes: State<DataTypeUniqueId, NodeTypeUniqueId, UnderlyingType, ComplexSchemaType>['nodes'];
1014
+ edges: State<DataTypeUniqueId, NodeTypeUniqueId, UnderlyingType, ComplexSchemaType>['edges'];
1015
+ /**
1016
+ * Number of references to this node group
1017
+ * This subtree can only be edited or deleted if there are no references to it
1018
+ */
1019
+ numberOfReferences: number;
1020
+ /**
1021
+ * Input node id of the node group
1022
+ * - It is used to connect the node group to the rest of the graph
1023
+ * - Not allowed to be deleted or duplicated, must always be one
1024
+ */
1025
+ inputNodeId: string;
1026
+ /**
1027
+ * Output node id of the node group
1028
+ * - It is used to connect the node group to the rest of the graph
1029
+ * - Not allowed to be deleted or duplicated, must always be one
1030
+ */
1031
+ outputNodeId: string;
1032
+ /** Scope-local zone definitions for structures inside this subtree. UI-only — stripped on export. */
1033
+ zones?: Record<string, Zone>;
1034
+ /** Reverse index from boundary handle IDs to zone IDs for this subtree. UI-only — stripped on export. */
1035
+ zoneIndex?: ZoneIndex;
1036
+ /**
1037
+ * Scope-local USER-AUTHORED zones for this subtree (named/colored visual frames
1038
+ * the user wraps around selected nodes). Unlike `zones` (derived from loop/switch
1039
+ * structures, recomputed/stripped/rehydrated), these are AUTHORED: membership is an
1040
+ * explicit `nodeIds` set, never recomputed. Persisted (NOT stripped on export, NOT
1041
+ * rehydrated on import). Visual-only — `enforced: false`, no boundaryHandles/structureLink.
1042
+ */
1043
+ userZones?: Record<string, Zone>;
1044
+ };
1045
+ };
1046
+
1047
+ /**
1048
+ * A first-class region of the graph, visually rendered as a frame polygon
1049
+ * and optionally enforcing connection boundary rules.
1050
+ *
1051
+ * System zones (switches, loops) are created/updated automatically when
1052
+ * structures are added or edges change. User zones are authored (named/colored
1053
+ * frames the user wraps around selected nodes) and visual-only — `enforced: false`,
1054
+ * no `structureLink`/`boundaryHandles`, no boundary enforcement.
1055
+ *
1056
+ * Zones are scope-local: root-level zones live on `state.zones`, subtree
1057
+ * zones live on `subtree.zones` inside their node group.
1058
+ */
1059
+ declare type Zone = {
1060
+ /** Opaque unique identifier (UUID, not derived from node IDs). */
1061
+ id: string;
1062
+ /** Display name shown on the zone frame label. */
1063
+ name: string;
1064
+ /** CSS color for the zone frame polygon and label. */
1065
+ color: string;
1066
+ /**
1067
+ * Member node IDs. For SYSTEM zones this is recomputed on every edge change;
1068
+ * for USER zones it is AUTHORED (never recomputed).
1069
+ */
1070
+ nodeIds: string[];
1071
+ /**
1072
+ * Per-boundary-node handle definitions. Keys are boundary node IDs.
1073
+ * The BFS zone discovery starts from edges connected to these handles
1074
+ * and stops at boundary nodes.
1075
+ *
1076
+ * Undefined for user-created zones (no boundaries, visual only).
1077
+ */
1078
+ boundaryHandles?: Record<string, ZoneBoundaryHandle>;
1079
+ /** Present for system-controlled zones; absent for user-created zones. */
1080
+ structureLink?: ZoneStructureLink;
1081
+ /** Whether connections crossing this zone's boundary are blocked. */
1082
+ enforced: boolean;
1083
+ };
1084
+
1085
+ /**
1086
+ * Describes the boundary handles on a single boundary node that define
1087
+ * one edge of a zone. The direction indicates which side of the boundary
1088
+ * node the zone's body nodes connect to.
1089
+ */
1090
+ declare type ZoneBoundaryHandle = {
1091
+ /** Handle IDs on this boundary node that belong to this zone. */
1092
+ handleIds: string[];
1093
+ /** Whether these handles are inputs or outputs on the boundary node. */
1094
+ direction: 'inputs' | 'outputs';
1095
+ };
1096
+
1097
+ /**
1098
+ * Reverse index from handle IDs to zone IDs for O(1) lookups
1099
+ * during connection validation. Rebuilt whenever zones change.
1100
+ */
1101
+ declare type ZoneIndex = {
1102
+ /** Maps each boundary handle ID to the zone it belongs to. */
1103
+ handleToZone: Record<string, string>;
1104
+ };
1105
+
1106
+ /**
1107
+ * Links a system-controlled zone to the structural node pair that owns it.
1108
+ * Used to find zones by their parent structure without relying on zone IDs.
1109
+ */
1110
+ declare type ZoneStructureLink = {
1111
+ /** The kind of structure that owns this zone. */
1112
+ structureType: 'switch' | 'loop';
1113
+ /** The anchor node ID of the structure (switchStartId or loopStartId). */
1114
+ structureId: string;
1115
+ /** Which region of the structure this zone represents (e.g. 'trueBranch', 'preStop'). */
1116
+ zoneRole: string;
1117
+ };
1118
+
1119
+ export { }