@dskripchenko/flow 0.0.0-stage → 1.0.1
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 +82 -0
- package/LICENSE +21 -0
- package/README.md +87 -2
- package/dist/core-DfJMfClV.js +4121 -0
- package/dist/core-dyjNI9N1.cjs +4522 -0
- package/dist/index.cjs +69 -0
- package/dist/index.d.ts +767 -0
- package/dist/index.mjs +1 -0
- package/dist/mermaid.cjs +222 -0
- package/dist/mermaid.d.ts +107 -0
- package/dist/mermaid.mjs +220 -0
- package/dist/standalone.css +2 -0
- package/dist/standalone.js +14 -0
- package/dist/style.css +1119 -0
- package/dist/vue.cjs +5836 -0
- package/dist/vue.d.ts +1041 -0
- package/dist/vue.mjs +5823 -0
- package/package.json +122 -4
- package/schema/graph.schema.json +95 -0
- package/schema/snapshot.schema.json +35 -0
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,767 @@
|
|
|
1
|
+
export declare type Alignment = 'left' | 'center' | 'right' | 'top' | 'middle' | 'bottom';
|
|
2
|
+
|
|
3
|
+
/** Aligns the boxes' edges or centres; returns a move command (or null for < 2 nodes). */
|
|
4
|
+
export declare function alignNodes(boxes: ReadonlyMap<string, NodeBox>, ids: readonly string[], how: Alignment): Command | null;
|
|
5
|
+
|
|
6
|
+
export declare interface Anchor {
|
|
7
|
+
point: Point;
|
|
8
|
+
side: PortSide;
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
/** Applies a command; returns a new graph and leaves the old one untouched. */
|
|
12
|
+
export declare function applyCommand(graph: Graph, command: Command): Graph;
|
|
13
|
+
|
|
14
|
+
export declare const approximateMeasurer: TextMeasurer;
|
|
15
|
+
|
|
16
|
+
/** The delay after `failures` errors in a row. */
|
|
17
|
+
export declare function backoffDelay(intervalMs: number, failures: number, backoff?: BackoffOptions | false): number;
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* A framework-agnostic poller: calls `fetch` every `intervalMs`, pauses while
|
|
21
|
+
* the page is hidden, backs off after errors, and aborts the request in
|
|
22
|
+
* flight on stop. One request at a time; the next one is scheduled after the
|
|
23
|
+
* previous settles, so a slow endpoint is never hit twice at once.
|
|
24
|
+
*/
|
|
25
|
+
export declare interface BackoffOptions {
|
|
26
|
+
/** Multiplier per consecutive failure; 2 by default. */
|
|
27
|
+
factor?: number;
|
|
28
|
+
/** Upper bound of the delay; 60 s by default. */
|
|
29
|
+
maxMs?: number;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
/** A cubic Bézier point, for the label of a direct spline. */
|
|
33
|
+
export declare function bezierPoint(p0: Point, p1: Point, p2: Point, p3: Point, t: number): Point;
|
|
34
|
+
|
|
35
|
+
/** Everything drawn: nodes, edge bends and labels, frames. */
|
|
36
|
+
export declare function boundsOf(nodes: Map<string, NodeBox>, edges: Map<string, EdgeGeometry>, groups: Map<string, NodeBox>, outsideLabels?: number): GraphLayout['bounds'];
|
|
37
|
+
|
|
38
|
+
export declare const BUILTIN_TYPES: Readonly<Record<string, NodeTypeDef>>;
|
|
39
|
+
|
|
40
|
+
/** Built-in node types; any other string is a custom type from a registry. */
|
|
41
|
+
export declare type BuiltinNodeType = 'start' | 'end' | 'state' | 'task' | 'decision' | 'subprocess' | 'note';
|
|
42
|
+
|
|
43
|
+
/** Pans so that a graph point sits in the screen centre, keeping the zoom. */
|
|
44
|
+
export declare function centreOn(v: Viewport, p: Point, width: number, height: number): Viewport;
|
|
45
|
+
|
|
46
|
+
export declare function clampZoom(k: number, limits?: ZoomLimits): number;
|
|
47
|
+
|
|
48
|
+
export declare type Command = {
|
|
49
|
+
type: 'addNodes';
|
|
50
|
+
nodes: FlowNode[];
|
|
51
|
+
edges?: FlowEdge[];
|
|
52
|
+
} | {
|
|
53
|
+
type: 'removeElements';
|
|
54
|
+
ids: string[];
|
|
55
|
+
} | {
|
|
56
|
+
type: 'updateNode';
|
|
57
|
+
id: string;
|
|
58
|
+
patch: Patch<Omit<FlowNode, 'id'>>;
|
|
59
|
+
} | {
|
|
60
|
+
type: 'moveNodes';
|
|
61
|
+
moves: {
|
|
62
|
+
id: string;
|
|
63
|
+
position: Point;
|
|
64
|
+
}[];
|
|
65
|
+
} | {
|
|
66
|
+
type: 'addEdge';
|
|
67
|
+
edge: FlowEdge;
|
|
68
|
+
} | {
|
|
69
|
+
type: 'updateEdge';
|
|
70
|
+
id: string;
|
|
71
|
+
patch: Patch<Omit<FlowEdge, 'id'>>;
|
|
72
|
+
} | {
|
|
73
|
+
type: 'setEnabled';
|
|
74
|
+
kind: Exclude<ElementKind, 'group'>;
|
|
75
|
+
id: string;
|
|
76
|
+
enabled: boolean;
|
|
77
|
+
} | {
|
|
78
|
+
type: 'addGroup';
|
|
79
|
+
group: FlowGroup;
|
|
80
|
+
} | {
|
|
81
|
+
type: 'updateGroup';
|
|
82
|
+
id: string;
|
|
83
|
+
patch: Patch<Omit<FlowGroup, 'id'>>;
|
|
84
|
+
} | {
|
|
85
|
+
type: 'updateMeta';
|
|
86
|
+
patch: Record<string, unknown>;
|
|
87
|
+
} | {
|
|
88
|
+
type: 'replace';
|
|
89
|
+
graph: Graph;
|
|
90
|
+
} | {
|
|
91
|
+
type: 'batch';
|
|
92
|
+
commands: Command[];
|
|
93
|
+
};
|
|
94
|
+
|
|
95
|
+
/** Thrown when a command does not fit the graph (unknown id, duplicate id…). */
|
|
96
|
+
export declare class CommandError extends Error {
|
|
97
|
+
readonly name = "CommandError";
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
/**
|
|
101
|
+
* Copies the selected nodes, with positions from the layout, and the edges
|
|
102
|
+
* whose both ends are selected (plus selected edges between them).
|
|
103
|
+
*/
|
|
104
|
+
export declare function copyFragment(graph: Graph, selected: Iterable<string>, layout?: GraphLayout): Fragment;
|
|
105
|
+
|
|
106
|
+
export declare function createPoller<T>(options: PollerOptions<T>): Poller;
|
|
107
|
+
|
|
108
|
+
/** A registry with the built-in types plus `custom` (which may override them). */
|
|
109
|
+
export declare function createRegistry(custom?: Record<string, NodeTypeDef>): NodeTypeRegistry;
|
|
110
|
+
|
|
111
|
+
/** Data values a node or an edge carries for the host: shown as key/value. */
|
|
112
|
+
export declare type DataValue = string | number | boolean | null | DataValue[] | {
|
|
113
|
+
[key: string]: DataValue;
|
|
114
|
+
};
|
|
115
|
+
|
|
116
|
+
export declare const DEFAULT_LIMITS: ZoomLimits;
|
|
117
|
+
|
|
118
|
+
export declare const defaultRegistry: NodeTypeRegistry;
|
|
119
|
+
|
|
120
|
+
/** A short human description of a command, for undo tooltips and logs. */
|
|
121
|
+
export declare function describeCommand(c: Command): string;
|
|
122
|
+
|
|
123
|
+
export declare const DESCRIPTION_FONT: FontSpec;
|
|
124
|
+
|
|
125
|
+
export declare type Direction = 'TB' | 'LR';
|
|
126
|
+
|
|
127
|
+
/** Distance from a point to a polyline: hit testing edges in the editor. */
|
|
128
|
+
export declare function distanceToPolyline(p: Point, points: readonly Point[]): number;
|
|
129
|
+
|
|
130
|
+
/** Spaces the boxes evenly between the outermost two (gaps, not centres). */
|
|
131
|
+
export declare function distributeNodes(boxes: ReadonlyMap<string, NodeBox>, ids: readonly string[], axis: 'horizontal' | 'vertical'): Command | null;
|
|
132
|
+
|
|
133
|
+
export declare const EDGE_FONT: FontSpec;
|
|
134
|
+
|
|
135
|
+
export declare interface EdgeGeometry {
|
|
136
|
+
id: string;
|
|
137
|
+
d: string;
|
|
138
|
+
/** The polyline the path follows. */
|
|
139
|
+
points: Point[];
|
|
140
|
+
from: Anchor;
|
|
141
|
+
to: Anchor;
|
|
142
|
+
label?: {
|
|
143
|
+
x: number;
|
|
144
|
+
y: number;
|
|
145
|
+
width: number;
|
|
146
|
+
height: number;
|
|
147
|
+
lines: string[];
|
|
148
|
+
};
|
|
149
|
+
selfLoop?: boolean;
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
export declare interface EdgeRunState {
|
|
153
|
+
count?: number;
|
|
154
|
+
traversed?: boolean;
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
export declare type ElementKind = 'node' | 'edge' | 'group';
|
|
158
|
+
|
|
159
|
+
/** A reference to one element of a graph. */
|
|
160
|
+
export declare interface ElementRef {
|
|
161
|
+
kind: ElementKind;
|
|
162
|
+
id: string;
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
/** An empty model. */
|
|
166
|
+
export declare function emptyGraph(meta?: Graph['meta']): Graph;
|
|
167
|
+
|
|
168
|
+
export declare function emptyMonitorState(): MonitorState;
|
|
169
|
+
|
|
170
|
+
/**
|
|
171
|
+
* The side of `box` that faces `toward`. `prefer` biases ties to the flow's
|
|
172
|
+
* axis: in a TB layout an edge leaves through top/bottom unless the other
|
|
173
|
+
* end is clearly beside the node.
|
|
174
|
+
*/
|
|
175
|
+
export declare function facingSide(box: NodeBox, toward: Point, prefer: 'vertical' | 'horizontal'): PortSide;
|
|
176
|
+
|
|
177
|
+
/**
|
|
178
|
+
* The centre nearest to `near` where a box of `size` overlaps no box in
|
|
179
|
+
* `boxes` (with `padding`), searching outward ring by ring on the grid.
|
|
180
|
+
* Used to place nodes added from the palette.
|
|
181
|
+
*/
|
|
182
|
+
export declare function findFreeSpot(boxes: Iterable<NodeBox>, size: {
|
|
183
|
+
width: number;
|
|
184
|
+
height: number;
|
|
185
|
+
}, near: Point, options?: FreeSpotOptions): Point;
|
|
186
|
+
|
|
187
|
+
/**
|
|
188
|
+
* The viewport that shows `bounds` whole and centred in a `width × height`
|
|
189
|
+
* screen with `padding`; never zooms in beyond `maxFit` (small graphs stay
|
|
190
|
+
* at a readable size instead of blowing up).
|
|
191
|
+
*/
|
|
192
|
+
export declare function fitView(bounds: {
|
|
193
|
+
x: number;
|
|
194
|
+
y: number;
|
|
195
|
+
width: number;
|
|
196
|
+
height: number;
|
|
197
|
+
}, width: number, height: number, padding?: number, limits?: ZoomLimits, maxFit?: number): Viewport;
|
|
198
|
+
|
|
199
|
+
export declare interface FlowEdge {
|
|
200
|
+
id: string;
|
|
201
|
+
from: string;
|
|
202
|
+
to: string;
|
|
203
|
+
fromPort?: string;
|
|
204
|
+
toPort?: string;
|
|
205
|
+
label?: string;
|
|
206
|
+
/** A guard or condition, shown in the details and, when there is no label, on the edge. */
|
|
207
|
+
condition?: string;
|
|
208
|
+
enabled?: boolean;
|
|
209
|
+
/** `association` is a dashed line without an arrow (a note to its node). */
|
|
210
|
+
kind?: 'transition' | 'association';
|
|
211
|
+
data?: Record<string, DataValue>;
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
export declare interface FlowGroup {
|
|
215
|
+
id: string;
|
|
216
|
+
label?: string;
|
|
217
|
+
/** The enclosing group. */
|
|
218
|
+
parent?: string;
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
export declare interface FlowNode {
|
|
222
|
+
id: string;
|
|
223
|
+
type: NodeType;
|
|
224
|
+
label?: string;
|
|
225
|
+
/** The node's centre. Nodes without one are placed by the auto layout. */
|
|
226
|
+
position?: Point;
|
|
227
|
+
/** The group (frame) the node sits in. */
|
|
228
|
+
group?: string;
|
|
229
|
+
data?: Record<string, DataValue>;
|
|
230
|
+
/** `false` disables the node: drawn dimmed and struck through. Enabled by default. */
|
|
231
|
+
enabled?: boolean;
|
|
232
|
+
/**
|
|
233
|
+
* The node's own process: an inline graph, or a reference the host resolves
|
|
234
|
+
* (`subgraphs` prop or `loadSubgraph`). Makes the node drillable.
|
|
235
|
+
*/
|
|
236
|
+
subgraph?: string | Graph;
|
|
237
|
+
/** Overrides the type's ports. */
|
|
238
|
+
ports?: Port[];
|
|
239
|
+
/** A short secondary line under the label. */
|
|
240
|
+
description?: string;
|
|
241
|
+
}
|
|
242
|
+
|
|
243
|
+
/**
|
|
244
|
+
* Text sizes without a DOM. Layout must be deterministic and run in Node, so
|
|
245
|
+
* the default measurer is a glyph-class table; a browser host may pass a
|
|
246
|
+
* canvas measurer for a tighter fit (the Vue component does).
|
|
247
|
+
*/
|
|
248
|
+
export declare interface FontSpec {
|
|
249
|
+
size: number;
|
|
250
|
+
weight?: number;
|
|
251
|
+
}
|
|
252
|
+
|
|
253
|
+
/** What the editor's clipboard holds: nodes and the edges among them. */
|
|
254
|
+
export declare interface Fragment {
|
|
255
|
+
kind: 'dskripchenko-flow/fragment';
|
|
256
|
+
version: 1;
|
|
257
|
+
nodes: FlowNode[];
|
|
258
|
+
edges: FlowEdge[];
|
|
259
|
+
}
|
|
260
|
+
|
|
261
|
+
/** A group frame around its member nodes and nested groups. */
|
|
262
|
+
export declare function frameAround(groupId: string, graph: Graph, nodes: Map<string, NodeBox>, pad?: number, title?: number): NodeBox | undefined;
|
|
263
|
+
|
|
264
|
+
export declare interface FreeSpotOptions {
|
|
265
|
+
/** Snap candidates to this grid (0: no snapping). */
|
|
266
|
+
grid?: number;
|
|
267
|
+
/** Clear space kept around other nodes. */
|
|
268
|
+
padding?: number;
|
|
269
|
+
/** Give up after this many rings of candidates. */
|
|
270
|
+
maxRings?: number;
|
|
271
|
+
}
|
|
272
|
+
|
|
273
|
+
export declare interface Graph {
|
|
274
|
+
version: typeof GRAPH_VERSION;
|
|
275
|
+
nodes: FlowNode[];
|
|
276
|
+
edges: FlowEdge[];
|
|
277
|
+
groups?: FlowGroup[];
|
|
278
|
+
meta?: GraphMeta;
|
|
279
|
+
}
|
|
280
|
+
|
|
281
|
+
/** The model format this package reads and writes. */
|
|
282
|
+
export declare const GRAPH_VERSION = 1;
|
|
283
|
+
|
|
284
|
+
export declare class GraphError extends Error {
|
|
285
|
+
/** Where in the input, as a JSON pointer. */
|
|
286
|
+
readonly pointer: string;
|
|
287
|
+
readonly name = "GraphError";
|
|
288
|
+
constructor(message: string,
|
|
289
|
+
/** Where in the input, as a JSON pointer. */
|
|
290
|
+
pointer?: string);
|
|
291
|
+
}
|
|
292
|
+
|
|
293
|
+
export declare interface GraphLayout {
|
|
294
|
+
direction: Direction;
|
|
295
|
+
routing: Routing;
|
|
296
|
+
nodes: Map<string, NodeGeometry>;
|
|
297
|
+
edges: Map<string, EdgeGeometry>;
|
|
298
|
+
groups: Map<string, GroupGeometry>;
|
|
299
|
+
/** Waypoints the layered layout chose, by edge; valid while both ends stay put. */
|
|
300
|
+
waypoints: Map<string, Point[]>;
|
|
301
|
+
bounds: {
|
|
302
|
+
x: number;
|
|
303
|
+
y: number;
|
|
304
|
+
width: number;
|
|
305
|
+
height: number;
|
|
306
|
+
};
|
|
307
|
+
}
|
|
308
|
+
|
|
309
|
+
export declare interface GraphMeta {
|
|
310
|
+
title?: string;
|
|
311
|
+
/** Auto-layout direction; `LR` by default. */
|
|
312
|
+
direction?: 'TB' | 'LR';
|
|
313
|
+
[key: string]: DataValue | undefined;
|
|
314
|
+
}
|
|
315
|
+
|
|
316
|
+
export declare interface GroupGeometry extends NodeBox {
|
|
317
|
+
id: string;
|
|
318
|
+
label?: string;
|
|
319
|
+
}
|
|
320
|
+
|
|
321
|
+
declare class History_2 {
|
|
322
|
+
private current;
|
|
323
|
+
private past;
|
|
324
|
+
private future;
|
|
325
|
+
private readonly limit;
|
|
326
|
+
private readonly mergeWindow;
|
|
327
|
+
private readonly now;
|
|
328
|
+
constructor(current: Graph, options?: HistoryOptions);
|
|
329
|
+
get graph(): Graph;
|
|
330
|
+
get canUndo(): boolean;
|
|
331
|
+
get canRedo(): boolean;
|
|
332
|
+
/** The entry `undo` would revert. */
|
|
333
|
+
get last(): HistoryEntry | undefined;
|
|
334
|
+
get next(): HistoryEntry | undefined;
|
|
335
|
+
/** Applies a command and records it. Throws CommandError and records nothing when it does not apply. */
|
|
336
|
+
execute(command: Command, mergeKey?: string): Graph;
|
|
337
|
+
undo(): HistoryEntry | undefined;
|
|
338
|
+
redo(): HistoryEntry | undefined;
|
|
339
|
+
/**
|
|
340
|
+
* Takes a graph from outside (the host changed the model). When it is the
|
|
341
|
+
* one history already holds, nothing happens; otherwise history restarts.
|
|
342
|
+
*/
|
|
343
|
+
reset(graph: Graph): void;
|
|
344
|
+
/** Ends merging: the next command starts a new entry even with the same key. */
|
|
345
|
+
seal(): void;
|
|
346
|
+
}
|
|
347
|
+
export { History_2 as History }
|
|
348
|
+
|
|
349
|
+
export declare interface HistoryEntry {
|
|
350
|
+
command: Command;
|
|
351
|
+
before: Graph;
|
|
352
|
+
after: Graph;
|
|
353
|
+
/** Entries with the same key in a row merge into one (a drag, arrow nudges). */
|
|
354
|
+
mergeKey?: string;
|
|
355
|
+
at: number;
|
|
356
|
+
}
|
|
357
|
+
|
|
358
|
+
export declare interface HistoryOptions {
|
|
359
|
+
/** Entries kept; 200 by default. */
|
|
360
|
+
limit?: number;
|
|
361
|
+
/** Merge window for entries with the same `mergeKey`, ms; 800 by default. */
|
|
362
|
+
mergeWindowMs?: number;
|
|
363
|
+
now?: () => number;
|
|
364
|
+
}
|
|
365
|
+
|
|
366
|
+
/** `enabled` treats a missing flag as enabled. */
|
|
367
|
+
export declare function isEnabled(el: {
|
|
368
|
+
enabled?: boolean;
|
|
369
|
+
}): boolean;
|
|
370
|
+
|
|
371
|
+
export declare function isFragment(v: unknown): v is Fragment;
|
|
372
|
+
|
|
373
|
+
/** Whether the editor must leave a node alone (its type is locked). */
|
|
374
|
+
export declare function isLocked(registry: NodeTypeRegistry, node: FlowNode): boolean;
|
|
375
|
+
|
|
376
|
+
/**
|
|
377
|
+
* Whether the state is too old to trust: nothing received for `staleAfterMs`.
|
|
378
|
+
* A state that never received anything is not stale (it is loading).
|
|
379
|
+
*/
|
|
380
|
+
export declare function isStale(state: MonitorState | undefined, now: number, staleAfterMs: number): boolean;
|
|
381
|
+
|
|
382
|
+
export declare interface Issue {
|
|
383
|
+
severity: IssueSeverity;
|
|
384
|
+
code: IssueCode;
|
|
385
|
+
message: string;
|
|
386
|
+
/** The element the issue is about, when there is one. */
|
|
387
|
+
target?: {
|
|
388
|
+
kind: ElementKind;
|
|
389
|
+
id: string;
|
|
390
|
+
};
|
|
391
|
+
}
|
|
392
|
+
|
|
393
|
+
export declare type IssueCode = 'duplicate-id' | 'unknown-node' | 'unknown-port' | 'unknown-group' | 'group-cycle' | 'unknown-type' | 'missing-start' | 'missing-end' | 'start-incoming' | 'end-outgoing' | 'unreachable' | 'dead-end' | 'empty-label';
|
|
394
|
+
|
|
395
|
+
/** Issues grouped by element id, for highlighting. */
|
|
396
|
+
export declare function issuesByElement(issues: readonly Issue[]): Map<string, Issue[]>;
|
|
397
|
+
|
|
398
|
+
export declare type IssueSeverity = 'error' | 'warning';
|
|
399
|
+
|
|
400
|
+
/** Whether a graph-space box is (mostly) inside the visible area. */
|
|
401
|
+
export declare function isVisible(v: Viewport, box: {
|
|
402
|
+
x: number;
|
|
403
|
+
y: number;
|
|
404
|
+
width: number;
|
|
405
|
+
height: number;
|
|
406
|
+
}, width: number, height: number, margin?: number): boolean;
|
|
407
|
+
|
|
408
|
+
export declare const LABEL_FONT: FontSpec;
|
|
409
|
+
|
|
410
|
+
/** Fixes every node where a layout put it: auto layout as one undoable command. */
|
|
411
|
+
export declare function layoutCommand(layout: GraphLayout): Command;
|
|
412
|
+
|
|
413
|
+
/**
|
|
414
|
+
* Errors of the layered layout. Copied from @dskripchenko/diagrams
|
|
415
|
+
* (src/core/errors.ts) together with the layout; the name stays so that a
|
|
416
|
+
* later switch to the diagrams export changes nothing for callers.
|
|
417
|
+
*/
|
|
418
|
+
export declare class LayoutError extends Error {
|
|
419
|
+
readonly line: number;
|
|
420
|
+
readonly column: number;
|
|
421
|
+
readonly hint?: string | undefined;
|
|
422
|
+
readonly name = "DiagramError";
|
|
423
|
+
constructor(message: string, line?: number, column?: number, hint?: string | undefined);
|
|
424
|
+
}
|
|
425
|
+
|
|
426
|
+
/** Lays out a graph. */
|
|
427
|
+
export declare function layoutGraph(graph: Graph, options?: LayoutOptions): GraphLayout;
|
|
428
|
+
|
|
429
|
+
export declare interface LayoutOptions {
|
|
430
|
+
/** `LR` by default (or the model's `meta.direction`). */
|
|
431
|
+
direction?: Direction;
|
|
432
|
+
routing?: Routing;
|
|
433
|
+
registry?: NodeTypeRegistry;
|
|
434
|
+
measure?: TextMeasurer;
|
|
435
|
+
/** Ignore the model's positions and lay out everything. */
|
|
436
|
+
ignorePositions?: boolean;
|
|
437
|
+
/** Space between neighbouring nodes in a rank, and between ranks. */
|
|
438
|
+
nodeSep?: number;
|
|
439
|
+
rankSep?: number;
|
|
440
|
+
/** Extra room beside edge labels (the monitoring counter pill). */
|
|
441
|
+
edgeLabelExtra?: number;
|
|
442
|
+
}
|
|
443
|
+
|
|
444
|
+
export declare const MAX_EDGES = 2000;
|
|
445
|
+
|
|
446
|
+
export declare const MAX_NODES = 500;
|
|
447
|
+
|
|
448
|
+
export declare function measureEdgeLabel(e: FlowEdge, measure: TextMeasurer, extra?: number): {
|
|
449
|
+
width: number;
|
|
450
|
+
height: number;
|
|
451
|
+
lines: string[];
|
|
452
|
+
} | undefined;
|
|
453
|
+
|
|
454
|
+
/** A node's size and wrapped label, before it is placed. */
|
|
455
|
+
export declare function measureNode(node: FlowNode, registry: NodeTypeRegistry, measure: TextMeasurer): Omit<NodeGeometry, 'x' | 'y'>;
|
|
456
|
+
|
|
457
|
+
/** Folds a snapshot into a state: the shorthand for the common case. */
|
|
458
|
+
export declare function mergeSnapshot(state: MonitorState | undefined, snapshot: MonitorSnapshot, at?: number, merge?: boolean): MonitorState;
|
|
459
|
+
|
|
460
|
+
/** The point halfway along a polyline: where a label goes without a layout hint. */
|
|
461
|
+
export declare function midpoint(points: readonly Point[]): Point;
|
|
462
|
+
|
|
463
|
+
export declare type MonitorAction =
|
|
464
|
+
/** Replaces everything with the snapshot (`merge: false`, the default) or merges into it. */
|
|
465
|
+
{
|
|
466
|
+
type: 'snapshot';
|
|
467
|
+
snapshot: MonitorSnapshot;
|
|
468
|
+
at: number;
|
|
469
|
+
merge?: boolean;
|
|
470
|
+
} | {
|
|
471
|
+
type: 'error';
|
|
472
|
+
error: string;
|
|
473
|
+
at: number;
|
|
474
|
+
} | {
|
|
475
|
+
type: 'reset';
|
|
476
|
+
};
|
|
477
|
+
|
|
478
|
+
/** One snapshot from the host: the JSON a monitoring endpoint returns. */
|
|
479
|
+
export declare interface MonitorSnapshot {
|
|
480
|
+
nodes?: Record<string, NodeRunState>;
|
|
481
|
+
edges?: Record<string, EdgeRunState>;
|
|
482
|
+
/** The current instance's path: node ids in the order visited. */
|
|
483
|
+
path?: string[];
|
|
484
|
+
/** Nodes the current instance is in now. */
|
|
485
|
+
current?: string[];
|
|
486
|
+
/** When the host produced the snapshot (ISO or epoch ms). */
|
|
487
|
+
updatedAt?: string | number;
|
|
488
|
+
}
|
|
489
|
+
|
|
490
|
+
export declare interface MonitorState extends Required<Pick<MonitorSnapshot, 'nodes' | 'edges'>> {
|
|
491
|
+
path?: string[];
|
|
492
|
+
current?: string[];
|
|
493
|
+
/** Epoch ms of the last snapshot received. */
|
|
494
|
+
receivedAt?: number;
|
|
495
|
+
/** Epoch ms the host stamped on the last snapshot, if it did. */
|
|
496
|
+
updatedAt?: number;
|
|
497
|
+
/** The last polling error, cleared by the next snapshot. */
|
|
498
|
+
error?: string;
|
|
499
|
+
/** Errors in a row. */
|
|
500
|
+
failures: number;
|
|
501
|
+
}
|
|
502
|
+
|
|
503
|
+
/** The node nearest to `from` in a direction: arrow-key navigation. */
|
|
504
|
+
export declare function nearestInDirection(from: Point, candidates: Iterable<{
|
|
505
|
+
id: string;
|
|
506
|
+
x: number;
|
|
507
|
+
y: number;
|
|
508
|
+
}>, dir: 'up' | 'down' | 'left' | 'right'): string | undefined;
|
|
509
|
+
|
|
510
|
+
/** A fresh id with a prefix: `state-3`. */
|
|
511
|
+
export declare function nextId(graph: Graph, prefix: string, taken?: Set<string>): string;
|
|
512
|
+
|
|
513
|
+
export declare interface NodeBox {
|
|
514
|
+
/** Centre. */
|
|
515
|
+
x: number;
|
|
516
|
+
y: number;
|
|
517
|
+
width: number;
|
|
518
|
+
height: number;
|
|
519
|
+
}
|
|
520
|
+
|
|
521
|
+
export declare interface NodeGeometry extends NodeBox {
|
|
522
|
+
id: string;
|
|
523
|
+
lines: string[];
|
|
524
|
+
descriptionLines: string[];
|
|
525
|
+
}
|
|
526
|
+
|
|
527
|
+
export declare interface NodeRunState {
|
|
528
|
+
status?: NodeStatus;
|
|
529
|
+
/** How many instances are in (or went through) the node. */
|
|
530
|
+
count?: number;
|
|
531
|
+
/** A short text or number on the node's corner (e.g. an error count). */
|
|
532
|
+
badge?: string | number;
|
|
533
|
+
/** A line for the details panel (e.g. the last error). */
|
|
534
|
+
message?: string;
|
|
535
|
+
/** ISO string or epoch milliseconds. */
|
|
536
|
+
updatedAt?: string | number;
|
|
537
|
+
}
|
|
538
|
+
|
|
539
|
+
/** Outlines the built-in renderer can draw. */
|
|
540
|
+
export declare type NodeShape = 'rect' | 'rounded' | 'circle' | 'ring' | 'diamond' | 'note' | 'pill';
|
|
541
|
+
|
|
542
|
+
/** Built-in statuses; any other string is shown as a neutral status. */
|
|
543
|
+
export declare type NodeStatus = 'active' | 'done' | 'error' | 'waiting' | 'skipped' | (string & {});
|
|
544
|
+
|
|
545
|
+
export declare type NodeType = BuiltinNodeType | (string & {});
|
|
546
|
+
|
|
547
|
+
export declare interface NodeTypeDef {
|
|
548
|
+
/** The type's name in the UI (palette, details). */
|
|
549
|
+
title: string;
|
|
550
|
+
shape: NodeShape;
|
|
551
|
+
/** A fixed size; otherwise the label decides the width between min and max. */
|
|
552
|
+
size?: {
|
|
553
|
+
width: number;
|
|
554
|
+
height: number;
|
|
555
|
+
};
|
|
556
|
+
minWidth?: number;
|
|
557
|
+
maxWidth?: number;
|
|
558
|
+
/** Minimum height; grows with wrapped label lines. */
|
|
559
|
+
height?: number;
|
|
560
|
+
/** Default ports; without them edges attach where they meet the outline. */
|
|
561
|
+
ports?: Port[];
|
|
562
|
+
/** An icon name the renderer maps to a glyph (`play`, `square`, `cog`, …). */
|
|
563
|
+
icon?: string;
|
|
564
|
+
/** The label is drawn outside the outline (start/end circles). */
|
|
565
|
+
labelOutside?: boolean;
|
|
566
|
+
/** Edges cannot end here (`start`) or start here (`end`). */
|
|
567
|
+
noIncoming?: boolean;
|
|
568
|
+
noOutgoing?: boolean;
|
|
569
|
+
/** Not part of the flow: no reachability or dead-end checks (`note`). */
|
|
570
|
+
annotation?: boolean;
|
|
571
|
+
/** The editor does not let a user change or delete nodes of this type. */
|
|
572
|
+
locked?: boolean;
|
|
573
|
+
/** The node can be drilled into (gets a "subgraph" field in the editor). */
|
|
574
|
+
drillable?: boolean;
|
|
575
|
+
}
|
|
576
|
+
|
|
577
|
+
export declare type NodeTypeRegistry = ReadonlyMap<string, NodeTypeDef>;
|
|
578
|
+
|
|
579
|
+
/**
|
|
580
|
+
* Reads a model from parsed JSON (or a JSON string). Fills defaults, drops
|
|
581
|
+
* unknown fields of nodes and edges, and throws `GraphError` with a JSON
|
|
582
|
+
* pointer when the shape is wrong.
|
|
583
|
+
*/
|
|
584
|
+
export declare function parseGraph(input: unknown, at?: string): Graph;
|
|
585
|
+
|
|
586
|
+
/**
|
|
587
|
+
* The command that pastes a fragment with fresh ids, shifted by `offset`
|
|
588
|
+
* (or centred on `at`). Returns the new node ids for the selection.
|
|
589
|
+
*/
|
|
590
|
+
export declare function pasteFragment(graph: Graph, fragment: Fragment, place?: {
|
|
591
|
+
offset?: Point;
|
|
592
|
+
at?: Point;
|
|
593
|
+
}): {
|
|
594
|
+
command: Command;
|
|
595
|
+
ids: string[];
|
|
596
|
+
};
|
|
597
|
+
|
|
598
|
+
/** A patch sets fields; a field set to `null` is removed. */
|
|
599
|
+
export declare type Patch<T> = {
|
|
600
|
+
[K in keyof T]?: T[K] | null;
|
|
601
|
+
};
|
|
602
|
+
|
|
603
|
+
/**
|
|
604
|
+
* The edges of a path: for each consecutive pair of nodes, the first enabled
|
|
605
|
+
* edge between them (then any edge). Pairs without an edge are skipped.
|
|
606
|
+
*/
|
|
607
|
+
export declare function pathEdges(graph: Graph, path: readonly string[] | undefined): string[];
|
|
608
|
+
|
|
609
|
+
export declare interface Point {
|
|
610
|
+
x: number;
|
|
611
|
+
y: number;
|
|
612
|
+
}
|
|
613
|
+
|
|
614
|
+
export declare interface Poller {
|
|
615
|
+
start(): void;
|
|
616
|
+
stop(): void;
|
|
617
|
+
/** Fetches now (aborting a request in flight) and reschedules. */
|
|
618
|
+
refresh(): void;
|
|
619
|
+
readonly status: PollerStatus;
|
|
620
|
+
/** Errors in a row. */
|
|
621
|
+
readonly failures: number;
|
|
622
|
+
/** The delay before the next fetch, as scheduled now. */
|
|
623
|
+
readonly nextDelay: number;
|
|
624
|
+
}
|
|
625
|
+
|
|
626
|
+
export declare interface PollerOptions<T> {
|
|
627
|
+
fetch: (signal: AbortSignal) => Promise<T>;
|
|
628
|
+
intervalMs: number;
|
|
629
|
+
/** `false` keeps the interval after errors. On by default. */
|
|
630
|
+
backoff?: BackoffOptions | false;
|
|
631
|
+
/** Pause while the page is hidden (on by default); or a custom source. */
|
|
632
|
+
visibilityPause?: boolean | VisibilitySource;
|
|
633
|
+
onData?: (data: T) => void;
|
|
634
|
+
onError?: (error: unknown, failures: number) => void;
|
|
635
|
+
/** Fetch at start instead of after the first interval (default true). */
|
|
636
|
+
immediate?: boolean;
|
|
637
|
+
}
|
|
638
|
+
|
|
639
|
+
export declare type PollerStatus = 'idle' | 'running' | 'paused';
|
|
640
|
+
|
|
641
|
+
/** A named connection point on a node's side. */
|
|
642
|
+
export declare interface Port {
|
|
643
|
+
id: string;
|
|
644
|
+
side: PortSide;
|
|
645
|
+
/** Position along the side, 0…1 from its start (left or top); 0.5 by default. */
|
|
646
|
+
offset?: number;
|
|
647
|
+
/** `in` takes incoming edges only, `out` outgoing only; both by default. */
|
|
648
|
+
kind?: 'in' | 'out' | 'both';
|
|
649
|
+
label?: string;
|
|
650
|
+
}
|
|
651
|
+
|
|
652
|
+
export declare type PortSide = 'top' | 'right' | 'bottom' | 'left';
|
|
653
|
+
|
|
654
|
+
/** The ports a node offers: its own, else its type's. */
|
|
655
|
+
export declare function portsOf(registry: NodeTypeRegistry, node: FlowNode): readonly Port[];
|
|
656
|
+
|
|
657
|
+
/** The pure reducer. Never mutates `state`. */
|
|
658
|
+
export declare function reduceMonitor(state: MonitorState, action: MonitorAction): MonitorState;
|
|
659
|
+
|
|
660
|
+
export declare function route(input: RouteInput): RoutedPath;
|
|
661
|
+
|
|
662
|
+
declare interface RouteContext {
|
|
663
|
+
direction: Direction;
|
|
664
|
+
routing: Routing;
|
|
665
|
+
registry: NodeTypeRegistry;
|
|
666
|
+
waypoints: Map<string, Point[]>;
|
|
667
|
+
labelAt: Map<string, Point>;
|
|
668
|
+
labels: Map<string, {
|
|
669
|
+
width: number;
|
|
670
|
+
height: number;
|
|
671
|
+
lines: string[];
|
|
672
|
+
} | undefined>;
|
|
673
|
+
/** Group frames: back-edge channels keep their drops out of foreign groups. */
|
|
674
|
+
groups?: ReadonlyMap<string, NodeBox>;
|
|
675
|
+
}
|
|
676
|
+
|
|
677
|
+
export declare interface RoutedPath {
|
|
678
|
+
/** SVG path data. */
|
|
679
|
+
d: string;
|
|
680
|
+
/** The polyline the path follows (anchors, stubs and bends): for hit tests and the label. */
|
|
681
|
+
points: Point[];
|
|
682
|
+
}
|
|
683
|
+
|
|
684
|
+
/**
|
|
685
|
+
* Routes edges between placed nodes. Anchors on one side of a rectangular
|
|
686
|
+
* node are spread along it so parallel edges do not merge.
|
|
687
|
+
*/
|
|
688
|
+
export declare function routeEdges(graph: Graph, nodes: Map<string, NodeGeometry | NodeBox>, ctx: RouteContext, only?: Set<string>): Map<string, EdgeGeometry>;
|
|
689
|
+
|
|
690
|
+
export declare interface RouteInput {
|
|
691
|
+
from: Anchor;
|
|
692
|
+
to: Anchor;
|
|
693
|
+
/** Bends between the anchors (from the layered layout), in order. */
|
|
694
|
+
waypoints?: readonly Point[];
|
|
695
|
+
routing: Routing;
|
|
696
|
+
/** Corner radius for orthogonal routes. */
|
|
697
|
+
radius?: number;
|
|
698
|
+
}
|
|
699
|
+
|
|
700
|
+
export declare type Routing = 'spline' | 'orthogonal';
|
|
701
|
+
|
|
702
|
+
export declare function sideNormal(side: PortSide): Point;
|
|
703
|
+
|
|
704
|
+
/** A point on a box side, `offset` 0…1 along it (left→right, top→bottom). */
|
|
705
|
+
export declare function sidePoint(box: NodeBox, side: PortSide, offset?: number): Point;
|
|
706
|
+
|
|
707
|
+
/** Snaps a point to a grid. */
|
|
708
|
+
export declare function snap(p: Point, grid: number): Point;
|
|
709
|
+
|
|
710
|
+
/** Built-in statuses and the kit tone each is drawn with. */
|
|
711
|
+
export declare const STATUS_TONES: Readonly<Record<string, 'accent' | 'success' | 'danger' | 'warning' | 'info' | 'neutral'>>;
|
|
712
|
+
|
|
713
|
+
/** Counts of nodes by status: the summary line of a monitor. */
|
|
714
|
+
export declare function statusSummary(state: MonitorState | undefined): Record<string, number>;
|
|
715
|
+
|
|
716
|
+
/** The model as stable JSON text (2-space indent). */
|
|
717
|
+
export declare function stringifyGraph(graph: Graph): string;
|
|
718
|
+
|
|
719
|
+
export declare type TextMeasurer = (text: string, font: FontSpec) => number;
|
|
720
|
+
|
|
721
|
+
export declare function toEpoch(v: string | number | undefined): number | undefined;
|
|
722
|
+
|
|
723
|
+
export declare function toGraph(v: Viewport, p: Point): Point;
|
|
724
|
+
|
|
725
|
+
export declare function toScreen(v: Viewport, p: Point): Point;
|
|
726
|
+
|
|
727
|
+
/** The definition for a node's type; an unknown type is drawn as a state. */
|
|
728
|
+
export declare function typeOf(registry: NodeTypeRegistry, type: string): NodeTypeDef;
|
|
729
|
+
|
|
730
|
+
/** All issues of a graph, errors first, then in model order. */
|
|
731
|
+
export declare function validateGraph(graph: Graph, options?: ValidateOptions): Issue[];
|
|
732
|
+
|
|
733
|
+
export declare interface ValidateOptions {
|
|
734
|
+
registry?: NodeTypeRegistry;
|
|
735
|
+
/** Report a missing start/end node (on by default; off for fragments). */
|
|
736
|
+
requireStartEnd?: boolean;
|
|
737
|
+
}
|
|
738
|
+
|
|
739
|
+
export declare interface Viewport {
|
|
740
|
+
x: number;
|
|
741
|
+
y: number;
|
|
742
|
+
/** Zoom factor. */
|
|
743
|
+
k: number;
|
|
744
|
+
}
|
|
745
|
+
|
|
746
|
+
/** Where the poller learns about page visibility; the document by default. */
|
|
747
|
+
export declare interface VisibilitySource {
|
|
748
|
+
hidden(): boolean;
|
|
749
|
+
subscribe(listener: () => void): () => void;
|
|
750
|
+
}
|
|
751
|
+
|
|
752
|
+
/**
|
|
753
|
+
* Splits text into lines no wider than `max`, at spaces; a word longer than
|
|
754
|
+
* a line is cut with an ellipsis. At most `maxLines` lines; the last one
|
|
755
|
+
* ends with "…" when text is left over.
|
|
756
|
+
*/
|
|
757
|
+
export declare function wrapText(text: string, max: number, font: FontSpec, measure: TextMeasurer, maxLines?: number): string[];
|
|
758
|
+
|
|
759
|
+
/** Zooms by `factor` keeping the graph point under `at` (screen) in place. */
|
|
760
|
+
export declare function zoomAt(v: Viewport, factor: number, at: Point, limits?: ZoomLimits): Viewport;
|
|
761
|
+
|
|
762
|
+
export declare interface ZoomLimits {
|
|
763
|
+
min: number;
|
|
764
|
+
max: number;
|
|
765
|
+
}
|
|
766
|
+
|
|
767
|
+
export { }
|