@weasel-js/diagram 1.11.0 → 1.11.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/dist/effect.d.ts CHANGED
@@ -1,100 +1,38 @@
1
- import { D as DiagramData, a as DiagramSceneOptions, N as NodeStyle, b as DataEdge, E as EdgeStyle, c as DataNode, d as DiagramRouter, e as DiagramSpec } from './fromData-GKqRgPFs.js';
2
- import { a as Row, M as MeasureRowText } from './body-2lC7IiIA.js';
1
+ import { c as EffectDoc, E as EffectPipeline, d as EffectWire, e as EffectStage, f as EffectPort, g as EffectGroup, a as EffectRun, b as EffectStageType, L as LookRoutes, h as EffectParamControl, i as EffectBox } from './stageTypes-DvnR8cKQ.js';
2
+ export { j as EffectParam, k as EffectPlaces, l as EffectStageRun, m as EffectType, n as LookRoute, o as formatParam, s as stageFromType } from './stageTypes-DvnR8cKQ.js';
3
+ import { D as DiagramTheme, a as DiagramData, b as DiagramSceneOptions, N as NodeStyle, c as DataEdge, E as EdgeStyle, d as DataNode, e as DiagramRouter, f as DiagramSpec } from './dataTypes-B-iEwKZp.js';
4
+ import { a as Row, M as MeasureRowText } from './types-BbHunLXm.js';
3
5
  import * as react from 'react';
4
6
  import { Paint } from '@weasel-js/core';
5
- import '@weasel-js/core/math';
7
+ import { Vec2 } from '@weasel-js/core/math';
8
+ import { VisibleRafOptions } from '@weasel-js/react';
6
9
  import '@weasel-js/geom';
7
10
 
8
- /** An effects pipeline as plain data. It says what is wired to what and
9
- * nothing about how any of it is drawn. */
10
- interface EffectPipeline {
11
- stages: readonly EffectStage[];
12
- wires: readonly EffectWire[];
13
- groups?: readonly EffectGroup[];
14
- /** What the value types mean. A type no entry names is plain data. */
15
- types?: Readonly<Record<string, EffectType>>;
16
- }
17
- /** One step of a pipeline: what it reads and writes, and what its box shows. */
18
- interface EffectStage {
19
- id: string;
20
- title: string;
21
- /** What sort of stage this is, for a look to read. The shipped looks know
22
- * 'stage' (default), 'decision', 'source' and 'sink', and draw any other
23
- * value as 'stage'. */
24
- kind?: string;
25
- inputs?: readonly EffectPort[];
26
- outputs?: readonly EffectPort[];
27
- /** Settings worth showing, in order. */
28
- params?: readonly {
29
- label: string;
30
- value: string;
31
- }[];
32
- /** For a decision that splits on a number: the input it compares, and the
33
- * cut points in ascending order. N cuts need N + 1 outputs, the lowest
34
- * band first. */
35
- split?: {
36
- input: string;
37
- at: readonly number[];
38
- };
39
- /** The stage is in the pipeline and switched off. */
40
- bypassed?: boolean;
41
- /** Anything else a look wants. No shipped look reads it. */
42
- data?: Readonly<Record<string, unknown>>;
43
- }
44
- /** One input or output of a stage, carrying a value of one type. */
45
- interface EffectPort {
46
- /** Unique among the stage's inputs and outputs together. */
47
- id: string;
48
- /** Default the id. */
49
- label?: string;
50
- type: string;
51
- }
52
- /** A connection from one stage's output to another stage's input. */
53
- interface EffectWire {
54
- from: {
55
- stage: string;
56
- port: string;
57
- };
58
- to: {
59
- stage: string;
60
- port: string;
61
- };
62
- /** Drawn on the wire. */
63
- label?: string;
64
- }
65
- /** A box drawn around some stages, and around other groups. */
66
- interface EffectGroup {
67
- id: string;
68
- label?: string;
69
- /** Stage ids and group ids. */
70
- members: readonly string[];
71
- }
72
- /** One run of a pipeline: what happened, beside the pipeline rather than in
73
- * it, so it can change every frame while the pipeline and its layout stay
74
- * put. A stage the run has no entry for is one it never reached. */
75
- interface EffectRun {
76
- stages: Readonly<Record<string, EffectStageRun>>;
77
- }
78
- /** What one stage did in a run. */
79
- interface EffectStageRun {
80
- /** How long it took, in milliseconds. */
81
- cost?: number;
82
- /** For a decision: the output it chose. */
83
- taken?: string;
84
- /** What each output carried, by port id, as text to show. */
85
- values?: Readonly<Record<string, string>>;
86
- /** What each output carried, by port id, as a picture, drawn in the slot a
87
- * look keeps for it (`showPreviews`). A bitmap rather than a canvas
88
- * because its pixels cannot change: hand back the same one and nothing is
89
- * uploaded again; draw new pixels into a new one. */
90
- previews?: Readonly<Record<string, ImageBitmap>>;
91
- }
92
- /** What a value type means, as `EffectPipeline.types` records it. */
93
- interface EffectType {
94
- /** A control value: a condition, a gate, a modulation source. Looks draw
95
- * its wires apart from data wires. */
96
- control?: boolean;
11
+ /** How the stages of a chain are joined. */
12
+ interface ChainLinks {
13
+ /** By stage id: the input the main signal arrives on. */
14
+ mainIn: ReadonlyMap<string, string>;
15
+ /** By stage id: the output the main signal leaves by. */
16
+ mainOut: ReadonlyMap<string, string>;
17
+ /** By `k`: the index into `pipeline.wires` of the wire from `chain[k]` to
18
+ * `chain[k + 1]`, or `undefined` where no data wire joins them. */
19
+ between: readonly (number | undefined)[];
97
20
  }
21
+ /** The first data wire from each chain stage to the next, and the ports it joins. */
22
+ declare function chainLinks(pipeline: EffectPipeline, chain: readonly string[]): ChainLinks;
23
+ /**
24
+ * The doc with `stage`, which must be on `mainChain`, moved to gap `to` of
25
+ * that chain: 0 before its first stage, `chain.length` after its last. Its
26
+ * main input and output wires come off and its old neighbors are wired to
27
+ * each other; the wire between its new neighbors comes off and it is wired
28
+ * between them. Side wires, control wires, and params stay with it. `null`
29
+ * where a new wire would join unlike types or a fed input, where `to` leaves
30
+ * it where it is, or where the rewired pipeline's main line would not read
31
+ * in the new order.
32
+ */
33
+ declare function moveInChain(doc: EffectDoc, stage: string, to: number): EffectDoc | null;
34
+ /** Whether `moveInChain` would make the move. */
35
+ declare function canMoveInChain(doc: EffectDoc, stage: string, to: number): boolean;
98
36
 
99
37
  /** One thing wrong with a pipeline, and where. */
100
38
  interface EffectProblem {
@@ -127,19 +65,49 @@ interface EffectLookResult {
127
65
  stage: string;
128
66
  port: string;
129
67
  }>;
68
+ /** The stages on the main line, in the order the look draws them, for a
69
+ * reorder to drag along. Looks that place stages freely leave it out. */
70
+ order?: LookOrder;
71
+ /** The lanes, top down, where the look draws lanes. */
72
+ laneOrder?: LookOrder;
73
+ }
74
+ /** A sequence a look draws: the scene node ids of its items in order along
75
+ * `axis`. `reorder`'s `sequenceSlots` turns it into slots once the items
76
+ * have drawn boxes. */
77
+ interface LookOrder {
78
+ axis: 'x' | 'y';
79
+ /** `grip` is where a press picks the item up, in world units; default its drawn box. */
80
+ items: readonly {
81
+ id: string;
82
+ grip?: {
83
+ x: number;
84
+ y: number;
85
+ width: number;
86
+ height: number;
87
+ };
88
+ }[];
130
89
  }
131
90
  /** One way of drawing a pipeline. Unparameterized, a look whose options are
132
91
  * not known: any look fits it, and it is called with none. */
133
92
  type EffectLook<TOptions = never> = (pipeline: EffectPipeline, options?: TOptions) => EffectLookResult;
93
+ /** The theme the shipped looks draw in when their options name none. */
94
+ declare const LOOK_THEME: DiagramTheme;
95
+ /** The option every shipped look takes for its colors. */
96
+ interface LookThemeOptions {
97
+ /** Stages take its default role, bypassed ones its muted role; value types its `series` in
98
+ * turn; groups its container; lanes its lane bodies. Default `night`. */
99
+ theme?: DiagramTheme;
100
+ }
134
101
  /** The color `wireStyle` draws a wire in when `checkPipeline` reported it. */
135
102
  declare const PROBLEM_COLOR = "#ff5d5d";
136
- /** A color per type: the one given, or the next in the palette in the order
103
+ /** A color per type: the one given, or the next in `series` in the order
137
104
  * types first appear on the pipeline's ports. */
138
- declare function typeColors(pipeline: EffectPipeline, given?: Readonly<Record<string, string>>): TypeColor;
105
+ declare function typeColors(pipeline: EffectPipeline, given?: Readonly<Record<string, string>>, series?: readonly string[]): TypeColor;
139
106
  /** Whether `type` is one the pipeline's `types` mark as `control`. */
140
107
  declare function isControl(pipeline: EffectPipeline, type: string | undefined): boolean;
141
- /** The node style the shipped looks give a stage: dashed and dim when it is bypassed. */
142
- declare function stageStyle(stage: EffectStage): NodeStyle;
108
+ /** The node style the shipped looks give a stage: the theme's default role, or dashed in its
109
+ * muted role when the stage is bypassed. */
110
+ declare function stageStyle(stage: EffectStage, theme?: DiagramTheme): NodeStyle;
143
111
  /** The edge style the shipped looks give a wire: `color`, dashed for a
144
112
  * control wire, and `PROBLEM_COLOR` in place of `color` for a flagged one. */
145
113
  declare function wireStyle(color: string, control: boolean, problem: boolean): EdgeStyle;
@@ -171,6 +139,10 @@ interface DrawableWire {
171
139
  declare function drawableWires(pipeline: EffectPipeline): DrawableWire[];
172
140
  /** What a value row shows before a run fills it in. */
173
141
  declare const NO_VALUE = "\u2013";
142
+ /** The ports a run shows values and previews on: a stage's outputs, or for a
143
+ * stage with none, such as a sink, its inputs, so the end of a pipeline
144
+ * shows what reached it. */
145
+ declare function shownPorts(stage: EffectStage): readonly EffectPort[];
174
146
  /** The row id of the value row for an output, under its stage's body. */
175
147
  declare const valueRowId: (port: string) => string;
176
148
  /** The row id of the preview slot for an output, under its stage's body. */
@@ -193,8 +165,9 @@ interface RunRowOptions {
193
165
  };
194
166
  }
195
167
  /** The body rows of an ordinary stage: its title, a row of its ports when
196
- * `withPorts` (inputs left, outputs right), then for each output its value
197
- * row when `showValues` and its preview slot when `showPreviews`, then its
168
+ * `withPorts` (inputs left, outputs right), then for each of its
169
+ * `shownPorts` its value row when `showValues` and its preview slot when
170
+ * `showPreviews`, then its
198
171
  * params when `showParams`. */
199
172
  declare function stageRows(stage: EffectStage, opts: {
200
173
  showParams: boolean;
@@ -245,7 +218,7 @@ declare function symbolNameFor(stage: EffectStage, choice?: BranchChoice): Exclu
245
218
  declare function branchNode(stage: EffectStage, pipeline: EffectPipeline, choice?: BranchChoice, options?: BranchOptions): BranchNode;
246
219
 
247
220
  /** Options for the `compact` look. */
248
- interface CompactOptions {
221
+ interface CompactOptions extends LookThemeOptions {
249
222
  /** Default `'bezier'`. */
250
223
  router?: DiagramRouter;
251
224
  /** Default 16. */
@@ -315,7 +288,7 @@ declare const EFFECT_MIN_SCALE = 0.5;
315
288
  declare function EffectChart<TOptions = never>({ pipeline: given, run, look, options, width, height, minScale, background, selected, onSelect, onProblems, className, }: EffectChartProps<TOptions>): react.JSX.Element;
316
289
 
317
290
  /** Options for the `lanes` look. */
318
- interface LanesOptions extends RunRowOptions {
291
+ interface LanesOptions extends RunRowOptions, LookThemeOptions {
319
292
  /** The value types whose lanes come first, top down. The rest follow in
320
293
  * the order their types first appear on the pipeline's ports. */
321
294
  lanes?: readonly string[];
@@ -341,16 +314,36 @@ interface LanesOptions extends RunRowOptions {
341
314
  declare const LANE_INSET = 6;
342
315
  /** The node id of the lane for a value type. */
343
316
  declare const laneId: (type: string) => string;
317
+ /** The value type of the lane `laneId` named, or `undefined` for any other id. */
318
+ declare const laneTypeOf: (id: string) => string | undefined;
344
319
  /** The lanes look: a horizontal lane per value type, and each stage standing
345
320
  * across the lanes of the types it reads and writes, as tall as they are,
346
321
  * its ports in their own lanes. A decision keeps its symbol's size, centered
347
- * across its lanes. Columns run left to right in the order the signal flows.
348
- * A wire runs around the stages between its ends along the lane edges, each
322
+ * across its lanes. Columns run left to right in the order the signal flows,
323
+ * and a group's members hold columns no other stage stands in. A wire runs around the stages between its ends along the lane edges, each
349
324
  * sharing one on a track of its own. */
350
325
  declare const lanes: EffectLook<LanesOptions>;
351
326
 
327
+ /** Options for the `nodeGraph` look. */
328
+ interface NodeGraphOptions extends RunRowOptions, LookThemeOptions {
329
+ /** Default `'bezier'`. */
330
+ router?: DiagramRouter;
331
+ nodeGap?: number;
332
+ rankGap?: number;
333
+ /** A color per value type, over the palette's own. */
334
+ colors?: Readonly<Record<string, string>>;
335
+ /** Whether a stage lists its `params`. Default true. A decision's symbol
336
+ * does not show params either way. */
337
+ showParams?: boolean;
338
+ /** Default `'auto'`. */
339
+ branch?: BranchChoice;
340
+ }
341
+ /** The node-graph look: every port a named row on its stage, a wire from port
342
+ * to port in the color of what it carries, flowing left to right. */
343
+ declare const nodeGraph: EffectLook<NodeGraphOptions>;
344
+
352
345
  /** Options for the `rack` look. */
353
- interface RackOptions extends RunRowOptions {
346
+ interface RackOptions extends RunRowOptions, LookThemeOptions {
354
347
  /** The stage ids on the line, in order. Default the longest path over data wires. */
355
348
  chain?: readonly string[];
356
349
  /** Where what feeds the chain from the side sits. Default `'below'`. */
@@ -371,23 +364,277 @@ interface RackOptions extends RunRowOptions {
371
364
  * order, and whatever feeds a stage from the side hung beside it. */
372
365
  declare const rack: EffectLook<RackOptions>;
373
366
 
374
- /** Options for the `nodeGraph` look. */
375
- interface NodeGraphOptions extends RunRowOptions {
376
- /** Default `'bezier'`. */
377
- router?: DiagramRouter;
378
- nodeGap?: number;
379
- rankGap?: number;
380
- /** A color per value type, over the palette's own. */
381
- colors?: Readonly<Record<string, string>>;
382
- /** Whether a stage lists its `params`. Default true. A decision's symbol
383
- * does not show params either way. */
384
- showParams?: boolean;
385
- /** Default `'auto'`. */
386
- branch?: BranchChoice;
367
+ /** The looks an editor draws a doc in. */
368
+ type EditorLook = 'nodeGraph' | 'rack' | 'lanes';
369
+ /** Each editor look's options. Rack's `chain` is left out: a reorder follows
370
+ * the wiring, and a chain given here would draw some other order. */
371
+ interface EditorLookOptions {
372
+ nodeGraph: NodeGraphOptions;
373
+ rack: Omit<RackOptions, 'chain'>;
374
+ lanes: LanesOptions;
387
375
  }
388
- /** The node-graph look: every port a named row on its stage, a wire from port
389
- * to port in the color of what it carries, flowing left to right. */
390
- declare const nodeGraph: EffectLook<NodeGraphOptions>;
376
+ /** A look's drawing of a doc, and the way back from what the drawing reports
377
+ * to the doc. A port id needs no mapping: box stages and decision symbols
378
+ * both give each port its `EffectPort` id. */
379
+ interface EditorScene extends EffectLookResult {
380
+ /** The stage a scene node is, or `undefined` for a group box, a lane, or anything else. */
381
+ stageOf(node: string): string | undefined;
382
+ /** The group a scene node is: a container under `nodeGraph`, a group box under the others. */
383
+ groupOf(node: string): string | undefined;
384
+ /** The wire a data edge id (`edgeIdOf`) draws, by its id in
385
+ * `ensureWireIds(doc)`, so an id-less wire is found by the id it will get.
386
+ * `undefined` for an edge standing in for more than one wire, such as
387
+ * rack's arc over a skip. */
388
+ wireOf(edge: string): string | undefined;
389
+ }
390
+ /** The look's drawing of the doc's pipeline. Under `nodeGraph` every placed
391
+ * stage is pinned at its place, so layered layout places only the stages
392
+ * that have none, and each group is a container, at its `groupBoxes` box or
393
+ * fitting its members; the other looks place every stage themselves and draw
394
+ * groups as boxes around their members. `lanes` takes the doc's `laneOrder`
395
+ * over its options' `lanes`. */
396
+ declare function editorScene<L extends EditorLook = 'nodeGraph'>(doc: EffectDoc, look?: L, options?: EditorLookOptions[L]): EditorScene;
397
+
398
+ /** Which look `EffectEditor` draws in, and that look's options. Keep the
399
+ * options object's identity steady between renders. */
400
+ type EffectEditorLookProps = {
401
+ look?: 'nodeGraph';
402
+ options?: NodeGraphOptions;
403
+ } | {
404
+ look: 'rack';
405
+ options?: EditorLookOptions['rack'];
406
+ } | {
407
+ look: 'lanes';
408
+ options?: LanesOptions;
409
+ };
410
+ /** Props for `EffectEditor`. */
411
+ type EffectEditorProps = EffectEditorBaseProps & EffectEditorLookProps;
412
+ /** `EffectEditor`'s props apart from its look. */
413
+ interface EffectEditorBaseProps {
414
+ /** The pipeline and where its stages sit. The editor keeps none of it:
415
+ * every edit comes back through `onChange` and shows once `doc` follows. */
416
+ doc: EffectDoc;
417
+ /** Hears each edit as the doc it makes, and a name for it fit for an undo
418
+ * entry: 'Move', 'Connect', 'Delete', 'Reconnect', 'Edit route', 'Add stage',
419
+ * 'Reorder', 'Reorder lanes', 'Resize group', 'Group', 'Ungroup' or 'Rename group'. */
420
+ onChange: (next: EffectDoc, label: string) => void;
421
+ /** One run of the pipeline, drawn over it as `EffectChart` draws its
422
+ * `run`, with the stage it is `at` outlined. */
423
+ run?: EffectRun;
424
+ /** A stage id, or null for none. */
425
+ selected?: string | null;
426
+ /** Hears each pick: a stage's id, or `null` for anything else, a wire included. */
427
+ onSelect?: (stage: string | null) => void;
428
+ /** A group id, or null for none: drawn picked while no stage is. */
429
+ selectedGroup?: string | null;
430
+ /** Hears each pick: a group's id, or `null` for anything else. */
431
+ onSelectGroup?: (group: string | null) => void;
432
+ /** CSS pixels. Omit both to fill the parent. */
433
+ width?: number;
434
+ height?: number;
435
+ background?: Paint;
436
+ className?: string;
437
+ }
438
+ /** What a `ref` on `EffectEditor` holds. */
439
+ interface EffectEditorApi {
440
+ /** Adds a stage of type `type`. Under `nodeGraph` its top-left goes at the
441
+ * world point under `client` when given, or in the first free spot in view
442
+ * (`freeSpot`), and like a drag it pins every stage layout placed where it
443
+ * shows, so nothing moves under it; the other looks place it themselves.
444
+ * Returns the new stage's id. */
445
+ addStage(type: EffectStageType, client?: {
446
+ x: number;
447
+ y: number;
448
+ }): string;
449
+ /** Groups stages and groups, as `groupStages` does, and reports it as 'Group'.
450
+ * Under `nodeGraph` it first pins every stage where it shows, as a drag
451
+ * does. Returns the new group's id, or `null` for no ids. */
452
+ group(ids: readonly string[]): string | null;
453
+ /** Dissolves a group, as `ungroup` does, and reports it as 'Ungroup'. */
454
+ ungroup(id: string): void;
455
+ /** Opens the field a group's title is renamed in, over its title, or above
456
+ * its box where it has none; a double-click on the title does
457
+ * the same. Renaming reports 'Rename group'. */
458
+ renameGroup(id: string): void;
459
+ }
460
+ /** The pipeline-mode editor: a look's drawing of an effect pipeline, whose
461
+ * ports wire output to input, and whose wires and stages reconnect and
462
+ * delete. Under `nodeGraph` stages drag freely, and each group is a titled
463
+ * box: drag a stage into or out of it, drag the box to carry what it holds,
464
+ * resize it, or double-click its title to rename it; under `rack` and `lanes` a
465
+ * stage on the main line drags along it to another place, rewiring the
466
+ * pipeline, a group drags along it by its title, and a double-click on that
467
+ * title renames it; under `lanes` a lane drags by its header. A selected
468
+ * wire's route drags under every look: into `routes` under `nodeGraph`, and
469
+ * into `lookRoutes` under the others, where it holds only while the wire's
470
+ * ends stay put. Every edit is a doc handed to `onChange`. Text paints only in a registered font family,
471
+ * as with `EffectChart`. */
472
+ declare const EffectEditor: react.ForwardRefExoticComponent<EffectEditorProps & react.RefAttributes<EffectEditorApi>>;
473
+
474
+ /** The reorders an editor installs under a look that places stages itself:
475
+ * a main-line stage dragged along the line, a lane dragged by its header,
476
+ * and a group dragged along the line by its title. */
477
+
478
+ /** The action that drags a lane to another place among the lanes. */
479
+ declare const REORDER_LANES_ACTION_ID = "diagram.reorderLanes";
480
+
481
+ /** Routes a person drew under `rack` and `lanes`, which place every stage
482
+ * themselves: each holds only while its wire's ends are where they were
483
+ * drawn from. */
484
+
485
+ /** The looks whose routes `lookRoutes` keeps. */
486
+ type RoutedLook = keyof LookRoutes;
487
+ /** Routes wire `wire` through `waypoints` under `look`, for as long as its
488
+ * ends stay at `ends`, its from end first. No waypoints gives the wire back
489
+ * to the look. */
490
+ declare function setLookRoute(doc: EffectDoc, look: RoutedLook, wire: string, waypoints: readonly Vec2[], ends: readonly [Vec2, Vec2]): EffectDoc;
491
+ /** `doc` without the look routes of wires it no longer has, or of the
492
+ * `rewired` ones, whose ends now join other ports. */
493
+ declare function pruneLookRoutes(doc: EffectDoc, rewired?: Iterable<string>): EffectDoc;
494
+ /** The points of the ports edge `edge` joins as `specs` draw it, from end
495
+ * first, or `undefined` when either end names no port. */
496
+ declare function wireEnds(specs: readonly DiagramSpec[], edge: string): [Vec2, Vec2] | undefined;
497
+ /** `specs`, drawn from `built`, with each wire `doc` routed under `look`
498
+ * drawn through its waypoints where its ends are still where they were. An
499
+ * edge's own waypoints win over the route a look worked out (`routed`), as
500
+ * for any `DataEdge`. `specs` itself when no route holds. */
501
+ declare function applyLookRoutes(specs: readonly DiagramSpec[], doc: EffectDoc, look: EditorLook, built: EditorScene): readonly DiagramSpec[];
502
+
503
+ type Ref = {
504
+ stage: string;
505
+ port: string;
506
+ };
507
+ /** `base` if no stage has it, else `base-2`, `base-3`, … */
508
+ declare function nextStageId(p: EffectPipeline, base: string): string;
509
+ /** The first of `w1`, `w2`, … no wire has. */
510
+ declare function nextWireId(p: EffectPipeline): string;
511
+ /** Appends the stage, pinning it at `at` when given. */
512
+ declare function addStage(doc: EffectDoc, stage: EffectStage, at?: Vec2): EffectDoc;
513
+ /** Drops the stages with their wires, places, routes and group memberships,
514
+ * and any group that leaves empty, with its box. */
515
+ declare function removeStages(doc: EffectDoc, ids: readonly string[]): EffectDoc;
516
+ /** Routes wire `wire` through `points`; none clears its route. */
517
+ declare function setWireRoute(doc: EffectDoc, wire: string, points: readonly Vec2[]): EffectDoc;
518
+ /** Mints an id when the wire has none. */
519
+ declare function addWire(doc: EffectDoc, wire: EffectWire): EffectDoc;
520
+ /** An id-less wire is never matched: run `ensureWireIds` first. */
521
+ declare function removeWires(doc: EffectDoc, ids: readonly string[]): EffectDoc;
522
+ /** An id-less wire is never matched: run `ensureWireIds` first. */
523
+ declare function reconnectWire(doc: EffectDoc, id: string, end: 'from' | 'to', to: Ref): EffectDoc;
524
+ /** Replaces a param's control and re-formats its display value. */
525
+ declare function setParam(doc: EffectDoc, stage: string, param: string, control: EffectParamControl): EffectDoc;
526
+ /** Pins each stage at its new position. */
527
+ declare function moveStages(doc: EffectDoc, moves: readonly {
528
+ id: string;
529
+ x: number;
530
+ y: number;
531
+ }[]): EffectDoc;
532
+ /** Sets the value types whose lanes `lanes` draws first, top down. */
533
+ declare function setLaneOrder(doc: EffectDoc, order: readonly string[]): EffectDoc;
534
+ /** Mints ids for id-less wires; returns `doc` itself when none lacks one. */
535
+ declare function ensureWireIds(doc: EffectDoc): EffectDoc;
536
+ /** An output into an input of the same type, both existing, on different stages. */
537
+ declare function canWire(p: EffectPipeline, from: Ref, to: Ref): boolean;
538
+
539
+ /** Edits to a pipeline's groups: what each holds, its label, and its box under `nodeGraph`. */
540
+
541
+ /** `group` if no stage or group has it, else `group-2`, `group-3`, … */
542
+ declare function nextGroupId(p: EffectPipeline): string;
543
+ /**
544
+ * Groups `ids`, stages or groups, in a new group whose id is
545
+ * {@link nextGroupId}'s. It nests inside the group all of them share, where
546
+ * the first of them was; otherwise it goes at the top level, taking them out
547
+ * of the groups they were in.
548
+ */
549
+ declare function groupStages(doc: EffectDoc, ids: readonly string[], label?: string): EffectDoc;
550
+ /** Dissolves group `id`: its members go to its parent group, in its place, or to the top level. */
551
+ declare function ungroup(doc: EffectDoc, id: string): EffectDoc;
552
+ /** Sets group `id`'s label; an empty one removes it. */
553
+ declare function renameGroup(doc: EffectDoc, id: string, label: string): EffectDoc;
554
+ /**
555
+ * Moves `ids`, stages or groups, into group `group`, or to the top level for
556
+ * `null`, out of the groups they were in. A group left empty goes too unless
557
+ * it has a box. `doc` itself when `group` is unknown or inside one of `ids`.
558
+ */
559
+ declare function moveToGroup(doc: EffectDoc, ids: readonly string[], group: string | null): EffectDoc;
560
+ /** Sets group `id`'s box under `nodeGraph`; `null` has it fit its members again. */
561
+ declare function setGroupBox(doc: EffectDoc, id: string, box: EffectBox | null): EffectDoc;
562
+ /** Group `id` and every stage and group inside it. */
563
+ declare function groupContents(doc: EffectDoc, id: string): {
564
+ stages: Set<string>;
565
+ groups: Set<string>;
566
+ };
567
+ /**
568
+ * Moves group `id` by `offset`: the places of the stages inside it, its box
569
+ * and the boxes inside it, and the routes of wires with both ends inside it.
570
+ * A stage with no place stays where layout puts it.
571
+ */
572
+ declare function moveGroup(doc: EffectDoc, id: string, offset: Vec2): EffectDoc;
573
+
574
+ /** What an evaluator is handed for one stage of one run. */
575
+ interface EffectEvalContext {
576
+ stage: EffectStage;
577
+ /** The value on each input a wire feeds, by port id. An input no reached
578
+ * wire feeds is absent. */
579
+ inputs: Readonly<Record<string, unknown>>;
580
+ /** Each param's control value (its display string when it has no
581
+ * control), by param id, or by label for a param without one. */
582
+ params: Readonly<Record<string, unknown>>;
583
+ /** The values the run was handed (`RunPipelineOptions.sources`), for a
584
+ * source stage to read. */
585
+ sources: Readonly<Record<string, unknown>>;
586
+ /** Seconds of play time. */
587
+ time: number;
588
+ /** Aborted when the run is abandoned. */
589
+ signal: AbortSignal;
590
+ }
591
+ /** What one stage produced: a value per output it fed, by port id, and for a
592
+ * decision the output it chose. An output left out feeds nothing. */
593
+ interface EffectEvalResult {
594
+ outputs: Readonly<Record<string, unknown>>;
595
+ taken?: string;
596
+ }
597
+ /** Evaluates one stage. Throw to fail it: the run records the message as the
598
+ * stage's `error` and leaves what it feeds unreached. */
599
+ type EffectEvaluator = (ctx: EffectEvalContext) => EffectEvalResult | Promise<EffectEvalResult>;
600
+ /** Evaluators by stage `type`. */
601
+ type EffectEvaluators = Readonly<Record<string, EffectEvaluator>>;
602
+ /** How a run shows, previews, and lets go of the values of one value type. */
603
+ interface EffectValueKind {
604
+ /** The value as text for a value row. Default `String(value)` for a
605
+ * number, string, or boolean, and nothing for anything else. */
606
+ show?(value: unknown): string;
607
+ /** The value as a picture of `size`, for a preview slot. */
608
+ preview?(value: unknown, size: {
609
+ width: number;
610
+ height: number;
611
+ }): ImageBitmap | Promise<ImageBitmap> | undefined;
612
+ /** Frees what the value holds, once nothing reads it again. */
613
+ dispose?(value: unknown): void;
614
+ }
615
+ /** Value kinds by value type. */
616
+ type EffectValueKinds = Readonly<Record<string, EffectValueKind>>;
617
+
618
+ /** Evaluators for `IMAGE_STAGE_TYPES`, drawing on `OffscreenCanvas` 2D. An
619
+ * image or mask is an `ImageBitmap`; a source puts out `sources.image`. */
620
+ declare const imageEvaluators: EffectEvaluators;
621
+
622
+ /** Stage types over images, each with an evaluator in `imageEvaluators`.
623
+ * Ports carry `image`, `number`, or `mask`, and a wire joins only like to
624
+ * like. Mark `number` as control in a pipeline's `types`. */
625
+ declare const IMAGE_STAGE_TYPES: readonly EffectStageType[];
626
+
627
+ /** A test card of `size` (a square's side, or a width and height): color bars
628
+ * over a gray ramp, with a white ring in the middle, so every stage has edges,
629
+ * hues, and levels to work on. */
630
+ declare function testCard(size: number | {
631
+ width: number;
632
+ height: number;
633
+ }): ImageBitmap;
634
+
635
+ /** Value kinds for `IMAGE_STAGE_TYPES`: an image or mask shows as its size and
636
+ * previews as a copy scaled to the slot; a number shows to three places. */
637
+ declare const imageValueKinds: EffectValueKinds;
391
638
 
392
639
  /** The looks that ship, by name. */
393
640
  declare const EFFECT_LOOKS: Readonly<{
@@ -403,15 +650,133 @@ declare const EFFECT_LOOKS: Readonly<{
403
650
  /** Stage ids of the longest path over data wires, sources first. */
404
651
  declare function mainChain(pipeline: EffectPipeline): string[];
405
652
 
653
+ /** The outline of the stage a run taken a step at a time is `at`. */
654
+ declare const AT_COLOR = "#ffc94d";
406
655
  /**
407
656
  * `specs` as `run` leaves them: a stage the run never reached faded, with its
408
657
  * wires; a decision's wires to the outputs it did not take faded; each value
409
658
  * row a look kept filled in; a `switch` thrown to the output its decision
410
- * took; and each stage's cost written above its corner.
659
+ * took; each stage's cost, or its error in `PROBLEM_COLOR`, written above
660
+ * its corner; and the stage the run is `at` outlined in `AT_COLOR`.
411
661
  * No run, no change.
412
662
  */
413
663
  declare function paintRun(pipeline: EffectPipeline, specs: readonly DiagramSpec[], run: EffectRun | undefined, exits?: EffectLookResult['exits']): DiagramSpec[];
414
664
  /** A cost in milliseconds, to three figures. */
415
665
  declare function costText(ms: number): string;
416
666
 
417
- export { BRANCH_SYMBOLS, type BranchChoice, type BranchNode, type BranchOptions, type BranchSymbol, COMPACT_PADDING, type CompactOptions, type DrawableWire, EFFECT_LOOKS, EFFECT_MIN_SCALE, EffectChart, type EffectChartProps, type EffectGroup, type EffectLook, type EffectLookResult, type EffectPipeline, type EffectPort, type EffectProblem, type EffectRun, type EffectStage, type EffectStageRun, type EffectType, type EffectWire, LANE_INSET, type LanesOptions, NO_VALUE, type NodeGraphOptions, PREVIEW_SIZE, PROBLEM_COLOR, type RackOptions, type RunRowOptions, type TypeColor, branchNode, checkPipeline, compact, costText, drawableWires, exitLabel, isControl, kindOf, laneId, lanes, mainChain, nodeGraph, paintRun, portOn, previewRowId, rack, stageRows, stageStyle, symbolNameFor, typeColors, uniqueGroups, uniqueStages, valueRowId, wireEdges, wireStyle };
667
+ /** The order a run evaluates stages in, and the stages it never can. */
668
+ interface RunOrder {
669
+ /** Every stage outside a cycle, each after every stage that feeds it. */
670
+ order: string[];
671
+ /** The stages on a cycle of wires, in stage order. */
672
+ cyclic: string[];
673
+ }
674
+ /** The stages topologically over data and control wires alike, stable by
675
+ * stage order: of the stages ready to go, the earliest goes first. A stage on
676
+ * a cycle is left out, and so are its wires. */
677
+ declare function runOrder(pipeline: EffectPipeline): RunOrder;
678
+
679
+ /** Options for `runPipeline` and `createEffectRunner`. */
680
+ interface RunPipelineOptions {
681
+ /** By stage `type`. A stage whose type has none fails. */
682
+ evaluators: EffectEvaluators;
683
+ /** By value type. A value whose type has none shows as text when it is a
684
+ * number, string, or boolean, and has no preview. */
685
+ kinds?: EffectValueKinds;
686
+ /** Handed to every evaluator, for source stages. The run never disposes them. */
687
+ sources?: Readonly<Record<string, unknown>>;
688
+ /** Seconds of play time. Default 0. */
689
+ time?: number;
690
+ signal?: AbortSignal;
691
+ /** Make a preview of each output whose kind can. Default true. */
692
+ previews?: boolean;
693
+ /** The size previews are made at: `RunRowOptions.previewSize`. Default `PREVIEW_SIZE`. */
694
+ previewSize?: number | {
695
+ width: number;
696
+ height: number;
697
+ };
698
+ }
699
+ /** A run taken a stage at a time. */
700
+ interface EffectPass {
701
+ /** Evaluates the next stage the run reaches, passing over those it does
702
+ * not, and returns its id; `undefined` once none is left. */
703
+ step(): Promise<string | undefined>;
704
+ /** The run so far: a new object after each step. */
705
+ readonly run: EffectRun;
706
+ /** Disposes every value the pass made. Its previews are the caller's. */
707
+ dispose(): void;
708
+ }
709
+ /** A pass over `pipeline` that has evaluated nothing yet. */
710
+ declare function createPass(pipeline: EffectPipeline, opts: RunPipelineOptions): EffectPass;
711
+
712
+ /**
713
+ * One whole run of `pipeline`, stage by stage in `runOrder`. A stage with
714
+ * inputs none of which a value reaches is skipped; a bypassed stage passes its
715
+ * first input of each output's type through; a throwing evaluator sets the
716
+ * stage's `error` and leaves what it feeds unreached; stages on a cycle never
717
+ * run. Every value the run made is disposed before it resolves; the previews
718
+ * in the run are the caller's to close. Rejects once `signal` aborts.
719
+ */
720
+ declare function runPipeline(pipeline: EffectPipeline, opts: RunPipelineOptions): Promise<EffectRun>;
721
+
722
+ /** What `createEffectRunner` is made with. */
723
+ interface EffectRunnerOptions extends Omit<RunPipelineOptions, 'time' | 'signal'> {
724
+ pipeline: EffectPipeline;
725
+ }
726
+ /** What a runner shows now. A new object whenever any of it changes. */
727
+ interface EffectRunnerState {
728
+ /** The run to draw: the last whole run, or the step run so far. */
729
+ run: EffectRun | undefined;
730
+ playing: boolean;
731
+ /** Seconds of play time. */
732
+ time: number;
733
+ }
734
+ /** Runs one pipeline over and over: whole, a stage at a time, or every frame
735
+ * while playing. It owns the values its runs make and the previews in them. */
736
+ interface EffectRunner {
737
+ readonly state: EffectRunnerState;
738
+ /** One whole run at the current play time. */
739
+ run(): Promise<void>;
740
+ /** Evaluates the next stage the run reaches and makes it the run's `at`;
741
+ * after the last stage, starts over. */
742
+ step(): Promise<void>;
743
+ play(): void;
744
+ pause(): void;
745
+ /** Pauses, drops the run, and sets the clock back to zero. */
746
+ reset(): void;
747
+ /** Moves the play clock on by `seconds` while playing, and starts a run
748
+ * unless one is still going. A frame source calls it once a frame. */
749
+ advance(seconds: number): void;
750
+ /** The next run, step, or played frame follows `pipeline`. A step run under
751
+ * way starts over. */
752
+ setPipeline(pipeline: EffectPipeline): void;
753
+ setSources(sources: Readonly<Record<string, unknown>>): void;
754
+ setOptions(opts: Partial<Omit<EffectRunnerOptions, 'pipeline' | 'sources'>>): void;
755
+ /** Says `run` is on screen: every preview of an older run that `run` does
756
+ * not show is closed. */
757
+ drawn(run: EffectRun | undefined): void;
758
+ subscribe(listener: () => void): () => void;
759
+ /** Resets and closes every preview it still holds. The runner stays usable. */
760
+ dispose(): void;
761
+ }
762
+ /** A runner over `opts.pipeline`, with nothing run yet. */
763
+ declare function createEffectRunner(opts: EffectRunnerOptions): EffectRunner;
764
+
765
+ /** Options for `useEffectRunner`: the runner's, which it follows as they
766
+ * change, and how its play loop is gated and clocked. */
767
+ interface UseEffectRunnerOptions extends EffectRunnerOptions, Pick<VisibleRafOptions, 'target' | 'requestFrame' | 'cancelFrame'> {
768
+ }
769
+ /** What `useEffectRunner` returns: the runner's state, and the runner to drive. */
770
+ interface EffectRunnerHandle extends EffectRunnerState {
771
+ runner: EffectRunner;
772
+ }
773
+ /**
774
+ * A runner for the life of the component. While it plays, every visible frame
775
+ * advances its clock by the time since the last and starts a run once the last
776
+ * has finished; time spent hidden does not count. Each run it hands back is
777
+ * taken as drawn after the render that shows it, so the previews of the runs
778
+ * before it are closed then.
779
+ */
780
+ declare function useEffectRunner(opts: UseEffectRunnerOptions): EffectRunnerHandle;
781
+
782
+ export { AT_COLOR, BRANCH_SYMBOLS, type BranchChoice, type BranchNode, type BranchOptions, type BranchSymbol, COMPACT_PADDING, type ChainLinks, type CompactOptions, type DrawableWire, EFFECT_LOOKS, EFFECT_MIN_SCALE, type EditorLook, type EditorLookOptions, type EditorScene, EffectBox, EffectChart, type EffectChartProps, EffectDoc, EffectEditor, type EffectEditorApi, type EffectEditorBaseProps, type EffectEditorLookProps, type EffectEditorProps, type EffectEvalContext, type EffectEvalResult, type EffectEvaluator, type EffectEvaluators, EffectGroup, type EffectLook, type EffectLookResult, EffectParamControl, type EffectPass, EffectPipeline, EffectPort, type EffectProblem, EffectRun, type EffectRunner, type EffectRunnerHandle, type EffectRunnerOptions, type EffectRunnerState, EffectStage, EffectStageType, type EffectValueKind, type EffectValueKinds, EffectWire, IMAGE_STAGE_TYPES, LANE_INSET, LOOK_THEME, type LanesOptions, type LookOrder, LookRoutes, type LookThemeOptions, NO_VALUE, type NodeGraphOptions, PREVIEW_SIZE, PROBLEM_COLOR, REORDER_LANES_ACTION_ID, type RackOptions, type RoutedLook, type RunOrder, type RunPipelineOptions, type RunRowOptions, type TypeColor, type UseEffectRunnerOptions, addStage, addWire, applyLookRoutes, branchNode, canMoveInChain, canWire, chainLinks, checkPipeline, compact, costText, createEffectRunner, createPass, drawableWires, editorScene, ensureWireIds, exitLabel, groupContents, groupStages, imageEvaluators, imageValueKinds, isControl, kindOf, laneId, laneTypeOf, lanes, mainChain, moveGroup, moveInChain, moveStages, moveToGroup, nextGroupId, nextStageId, nextWireId, nodeGraph, paintRun, portOn, previewRowId, pruneLookRoutes, rack, reconnectWire, removeStages, removeWires, renameGroup, runOrder, runPipeline, setGroupBox, setLaneOrder, setLookRoute, setParam, setWireRoute, shownPorts, stageRows, stageStyle, symbolNameFor, testCard, typeColors, ungroup, uniqueGroups, uniqueStages, useEffectRunner, valueRowId, wireEdges, wireEnds, wireStyle };