@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.
@@ -1,32 +1,29 @@
1
- import { DerivedDep, PoseDescriptor, NodeShapeEntry, MarkerRef, AddNodeSpec, Stroke, RectPose } from '@weasel-js/core';
2
- import { P as PortAnchor, D as DiagramGroup, R as RowTextStyle, a as Row, O as Outline, b as PortSpec, B as BodySpec, L as LayoutPorts, c as LayoutFn, d as LayoutOptions, M as MeasureRowText, e as DiagramNode } from './body-2lC7IiIA.js';
1
+ import { DerivedDep, PoseDescriptor, NodeShapeEntry, MarkerRef, Page, PageLayoutOptions, AddNodeSpec, Stroke, RectPose } from '@weasel-js/core';
3
2
  import { Vec2 } from '@weasel-js/core/math';
3
+ import { E as EdgeHop, S as StyleField, P as PortAnchor, D as DiagramGroup, R as RowTextStyle, a as Row, O as Outline, b as PortSpec, B as BodySpec, c as DiagramLabel, L as LayoutPorts, d as LayoutFn, e as LayoutOptions, M as MeasureRowText, f as DiagramNode } from './types-BbHunLXm.js';
4
4
 
5
5
  /**
6
- * The label trait: where along its edge a label sits. Data only — placing the
7
- * label on the route is `label`'s job, so layout can read one without
8
- * reaching the scene.
6
+ * Off-page markers as data: what a connector cut at the page gap holds, and
7
+ * what each of its two tags holds. The pass that writes both is `install`.
9
8
  */
10
-
11
- /** Where along an edge a label sits. */
12
- interface DiagramLabel {
13
- /** `'start'`, `'mid'` and `'end'` are 0, 0.5 and 1; a number is that
14
- * fraction of the route's length. `{ near }` is the point on the route
15
- * nearest `near`, in world coordinates — where `layered` leaves a label
16
- * room — so a bend added or removed elsewhere leaves the label on the
17
- * stretch it was on. */
18
- at: 'start' | 'mid' | 'end' | number | {
19
- near: Vec2;
20
- };
21
- /** World units between the route and the label's near side, to the **left
22
- * of the direction of travel** — above a left-to-right edge. Default 0,
23
- * which centers the label on the line. */
24
- offset?: number;
9
+ /** A connector whose ends sit on different pages: its reference letter, and
10
+ * the pages its `from` and `to` ends are on. */
11
+ interface OffPageSplit {
12
+ ref: string;
13
+ from: string;
14
+ to: string;
15
+ }
16
+ /** Which end of which connector a tag names the far page for. */
17
+ interface OffPageTag {
18
+ edge: string;
19
+ end: 'from' | 'to';
25
20
  }
26
- /** The label trait on a node's data, or `null`. */
27
- declare function diagramLabelOf(node: {
21
+ /** The id of the tag at end `end` of connector `edgeId`. */
22
+ declare const offPageTagId: (edgeId: string, end: "from" | "to") => string;
23
+ /** The off-page tag trait on a node's data (`data.diagram.offPageTag`), or `null`. */
24
+ declare function offPageTagOf(node: {
28
25
  data: unknown;
29
- }): DiagramLabel | null;
26
+ }): OffPageTag | null;
30
27
 
31
28
  /**
32
29
  * The edge trait: what an edge's `data` says about its ends and its route, and
@@ -61,10 +58,27 @@ interface DiagramEdge {
61
58
  * them, layout owns the route and rewrites it on its next run; once anyone
62
59
  * edits them, they are the author's and layout leaves them alone. */
63
60
  laidOut?: readonly Vec2[];
61
+ /** The bends between the ends that the obstacle-avoiding router last
62
+ * computed, kept so the edge draws without rerouting. The router owns it,
63
+ * and while it is here each end aims at its nearest bend. */
64
+ route?: readonly Vec2[];
65
+ /** Where it bows over the connectors drawn before it, as the line-jump
66
+ * pass last computed. Literal, so any reader draws them. */
67
+ hops?: readonly EdgeHop[];
68
+ /** Set while its ends sit on different pages, when it draws as two stubs
69
+ * ending at off-page tags. The off-page pass owns it (`installOffPageMarkers`). */
70
+ offPage?: OffPageSplit;
71
+ /** The theme role it is drawn in. Unset, the theme's own connector style. */
72
+ style?: string;
73
+ /** The colors the author set by hand, which a theme leaves as they are. */
74
+ ownStyle?: readonly StyleField[];
64
75
  }
65
76
  /** Whether layout may rewrite this edge's route: it has no waypoints, or only
66
77
  * the ones layout last wrote. */
67
78
  declare function layoutOwnsRoute(edge: DiagramEdge): boolean;
79
+ /** Whether layout writes this edge's waypoints: it owns the route, and the
80
+ * edge is not routed around obstacles, whose bends are never stops. */
81
+ declare function layoutWritesRoute(edge: DiagramEdge): boolean;
68
82
  /** The edge trait on a node's data, or `null`. */
69
83
  declare function diagramEdgeOf(node: {
70
84
  data: unknown;
@@ -183,13 +197,86 @@ declare function registerMarkShape<TPose>(opts?: {
183
197
  geometry?: PoseDescriptor<TPose>;
184
198
  }): () => void;
185
199
 
200
+ /** The face a diagram node's text is set in. */
201
+ type DiagramTextStyle = {
202
+ fontFamily: string;
203
+ fontSize: number;
204
+ fontWeight?: number;
205
+ align?: 'center';
206
+ };
207
+ type Font = {
208
+ fontFamily: string;
209
+ fontSize: number;
210
+ };
211
+ /** The face a body row's text is set in. A label row's is centered in the row. */
212
+ declare function rowTextStyle(row: Row | undefined, font: Font): DiagramTextStyle;
213
+
214
+ /** The roles every shipped theme styles, with the name a picker shows. */
215
+ declare const DIAGRAM_ROLES: readonly [{
216
+ readonly id: "default";
217
+ readonly label: "Default";
218
+ }, {
219
+ readonly id: "accent";
220
+ readonly label: "Accent";
221
+ }, {
222
+ readonly id: "muted";
223
+ readonly label: "Muted";
224
+ }, {
225
+ readonly id: "positive";
226
+ readonly label: "Positive";
227
+ }, {
228
+ readonly id: "warning";
229
+ readonly label: "Warning";
230
+ }, {
231
+ readonly id: "negative";
232
+ readonly label: "Negative";
233
+ }];
234
+ /** The id of one of {@link DIAGRAM_ROLES}. A theme may style roles of its own besides. */
235
+ type DiagramRole = (typeof DIAGRAM_ROLES)[number]['id'];
236
+
237
+ /** The face a theme sets diagram text in. A text row keeps its own size. */
238
+ interface DiagramFont {
239
+ family: string;
240
+ size: number;
241
+ }
186
242
  /**
187
- * `diagramScene` — a laid-out diagram from plain `{ nodes, edges }`.
188
- *
189
- * Every box is a `buildBody` body, so a data node can say anything a body
190
- * can: outline, rows, padding, ports. Sizes are estimated from character
191
- * counts unless `measure` is given, so layout runs without a canvas and gives
192
- * the same answer in node and in a browser.
243
+ * A document's colors and face. Applying one writes literal colors into the
244
+ * scene, so nothing that reads the scene needs the theme to draw it.
245
+ */
246
+ interface DiagramTheme {
247
+ id: string;
248
+ name: string;
249
+ /** A shape's fill, stroke and text by role id. A connector given a role takes that role's stroke. */
250
+ roles: Readonly<Record<string, NodeStyle>>;
251
+ /** The names a picker shows for roles beyond {@link DIAGRAM_ROLES}, or for a shipped role renamed. */
252
+ roleLabels?: Readonly<Record<string, string>>;
253
+ /** The role a shape or connector naming none, or naming one this theme lacks, is drawn in. */
254
+ defaultRole: string;
255
+ /** A connector naming no role. */
256
+ edge: EdgeStyle;
257
+ /** A connector's label, where the connector names no role. */
258
+ label: {
259
+ fill: string;
260
+ font?: DiagramFont;
261
+ };
262
+ /** A group's or a container's box, its `text` the title's color. */
263
+ container: NodeStyle;
264
+ /** A pool's header, and its lanes' bodies in turn. */
265
+ lane: {
266
+ header: NodeStyle;
267
+ bodies: readonly NodeStyle[];
268
+ };
269
+ /** The page a document is drawn on. */
270
+ page: string;
271
+ font: DiagramFont;
272
+ /** Colors for a series of things the theme cannot name in advance: an effect look's value types. */
273
+ series: readonly string[];
274
+ }
275
+ /** The document value a theme is saved under: a shipped theme's id, or a whole custom theme. */
276
+ declare const DIAGRAM_THEME_KEY = "diagram:theme";
277
+
278
+ /**
279
+ * The plain data `diagramScene` reads, and the options and styles it takes.
193
280
  */
194
281
 
195
282
  /** One node of a {@link DiagramData}: its rows of text, and optionally its outline, ports, size, and starting place. */
@@ -222,9 +309,18 @@ interface DataNode {
222
309
  /** Drawn over the box besides its rows: shapes in a unit square stretched
223
310
  * over it, and text pinned to a point on it. */
224
311
  marks?: readonly DataMark[];
312
+ /** The theme role it is drawn in, under `DiagramSceneOptions.theme`. Kept on its trait. */
313
+ style?: string;
314
+ /** Colors of its own, over its role's. Each one set is listed in the trait's `ownStyle`, so a
315
+ * theme change leaves it. */
316
+ colors?: Partial<NodeStyle>;
225
317
  }
226
318
  /** One edge of a {@link DiagramData}, between two nodes or groups by id. */
227
319
  interface DataEdge {
320
+ /** The scene node id this edge gets, for an editor that must find it again
321
+ * after its ends, ports or label change. Unset, {@link edgeIdOf} derives
322
+ * one from those. */
323
+ id?: string;
228
324
  /** A node's id, or a group's: an edge naming a group meets its box. */
229
325
  from: string;
230
326
  to: string;
@@ -248,6 +344,11 @@ interface DataEdge {
248
344
  /** Ports a layout run named, as `onMove` reports them: used like `routed`,
249
345
  * and not part of the edge's id. `fromPort` and `toPort` win. */
250
346
  routedPorts?: LayoutPorts;
347
+ /** The theme role it is drawn in, under `DiagramSceneOptions.theme`: that role's stroke. Kept on its trait. */
348
+ style?: string;
349
+ /** Its stroke, markers, and label color of its own, over the theme's. `stroke` and `label` are
350
+ * listed in the trait's `ownStyle` (as `stroke` and `text`), so a theme change leaves them. */
351
+ colors?: Partial<EdgeStyle>;
251
352
  }
252
353
  /** A box drawn around some nodes, which layout keeps together. */
253
354
  interface DataGroup {
@@ -262,16 +363,85 @@ interface DataGroup {
262
363
  /** Between the box and its members, and around the label. Default
263
364
  * `DiagramSceneOptions.groupPadding`. */
264
365
  padding?: number;
366
+ /** The axis its members can be dragged along to change their order, in a
367
+ * `DiagramView` given `onReorder`. A member that is a group carries
368
+ * everything inside it. */
369
+ reorder?: 'x' | 'y';
265
370
  }
266
371
  /** A diagram as plain data, the input to `diagramScene`. */
267
372
  interface DiagramData {
268
373
  nodes: readonly DataNode[];
269
374
  edges: readonly DataEdge[];
270
- /** A group may be a member of another. `layered`, `tree`, and `force` keep
271
- * each group's members together; `chain` and `'none'` ignore groups but
272
- * still draw them. */
375
+ /** A group may be a member of another. `layered`, `tree`, `force`, and `chain`
376
+ * keep each group's members together; `'none'` ignores groups but still
377
+ * draws them. */
273
378
  groups?: readonly DataGroup[];
379
+ /** Containers and pools: regions drawn as scene containers that hold their
380
+ * members, which a `DiagramView` drags shapes into and out of. */
381
+ containers?: readonly DataContainer[];
382
+ /** The sheets the diagram is drawn on, in world space as `layoutPages` places them; a node
383
+ * belongs to the page its box overlaps most (`pageOfBounds`). A connector whose ends belong
384
+ * to different pages is split into two stubs, each with an off-page tag. A node in the gap
385
+ * between pages belongs to none, and its connectors stay whole. */
386
+ pages?: readonly Page[];
387
+ /** How `pages` are laid out in world space. */
388
+ pageLayout?: PageLayoutOptions;
389
+ }
390
+ /**
391
+ * A container or a pool, drawn as a region that holds its members. Its id
392
+ * shares one namespace with node, group, and lane ids.
393
+ *
394
+ * With a `box` it is laid out as one node of that size, and its members ride
395
+ * along with it: a member with no `at` is seeded inside its body, in rows.
396
+ * With none, a container is laid out as a group and its box fits its members.
397
+ * A pool always has a box, {@link DEFAULT_POOL_ACROSS} across and
398
+ * {@link DEFAULT_LANE_SIZE} along per lane when none is given. An edge with
399
+ * an end inside a boxed region ranks against the outermost one holding it.
400
+ */
401
+ interface DataContainer {
402
+ id: string;
403
+ role: 'container' | 'pool';
404
+ /** Its title, drawn in its header. */
405
+ label?: string;
406
+ /** A container's direct members: node ids and container ids. A member
407
+ * already claimed by an earlier container, a pool, an unknown id, and one
408
+ * that would put a container inside itself are ignored. */
409
+ members?: readonly string[];
410
+ /** A pool's lanes, in the order they stack. */
411
+ lanes?: readonly DataLane[];
412
+ /** The axis a pool stacks its lanes along: `'y'` for rows. Default `'y'`. */
413
+ axis?: 'x' | 'y';
414
+ /** Where it stands and how big it is, in world units. A pool's size along
415
+ * its stack is shared by the lanes that give no `size`. */
416
+ box?: {
417
+ x: number;
418
+ y: number;
419
+ width: number;
420
+ height: number;
421
+ };
422
+ /** Layout leaves its box where it is. */
423
+ pinned?: boolean;
424
+ /** The theme role it is drawn in. Unset, a container takes the theme's
425
+ * `container` style, a pool its `lane.header`. */
426
+ style?: string;
427
+ /** Colors of its own, over its style's, listed in its trait's `ownStyle` as a node's are. */
428
+ colors?: Partial<NodeStyle>;
429
+ }
430
+ /** One lane of a pool. Its id shares the node id namespace. */
431
+ interface DataLane {
432
+ id: string;
433
+ label?: string;
434
+ /** Its depth along the pool's stack, in world units. */
435
+ size?: number;
436
+ /** Node ids and container ids, claimed as a container's are. */
437
+ members?: readonly string[];
438
+ /** Colors of its own, as a container's. A lane draws no fill. */
439
+ colors?: Partial<NodeStyle>;
274
440
  }
441
+ /** A pool's size across its stack when it gives no box. */
442
+ declare const DEFAULT_POOL_ACROSS = 600;
443
+ /** A lane's size along its pool's stack when neither it nor the pool's box gives one. */
444
+ declare const DEFAULT_LANE_SIZE = 120;
275
445
  /** The colors and outline a node is drawn with. */
276
446
  interface NodeStyle {
277
447
  fill: string;
@@ -280,6 +450,12 @@ interface NodeStyle {
280
450
  strokeWidth?: number;
281
451
  dash?: number[];
282
452
  }
453
+ /** A node's or region's outline width when its style gives none. */
454
+ declare const NODE_STROKE_WIDTH = 2;
455
+ /** A lane's outline width, which its style does not change. */
456
+ declare const LANE_STROKE_WIDTH = 1;
457
+ /** An edge's stroke width when its style gives none. */
458
+ declare const EDGE_STROKE_WIDTH = 1.5;
283
459
  /** The stroke, markers, and label color an edge is drawn with. */
284
460
  interface EdgeStyle {
285
461
  stroke: string;
@@ -293,13 +469,7 @@ interface EdgeStyle {
293
469
  label?: string;
294
470
  }
295
471
  /** How an edge is drawn between its ends. */
296
- type DiagramRouter = 'straight' | 'bezier' | 'orthogonal';
297
- /** The face a diagram node's text is set in. */
298
- type DiagramTextStyle = {
299
- fontFamily: string;
300
- fontSize: number;
301
- fontWeight?: number;
302
- };
472
+ type DiagramRouter = 'straight' | 'bezier' | 'orthogonal' | 'avoid';
303
473
  /** The `data` of a scene node `diagramScene` makes: its diagram role, and what it paints. */
304
474
  interface DiagramSceneData {
305
475
  diagram?: DiagramNode | DiagramEdge | {
@@ -308,6 +478,8 @@ interface DiagramSceneData {
308
478
  anchor: DiagramAnchor;
309
479
  } | {
310
480
  mark: DiagramMark;
481
+ } | {
482
+ offPageTag: OffPageTag;
311
483
  };
312
484
  fill?: {
313
485
  paint: {
@@ -318,16 +490,28 @@ interface DiagramSceneData {
318
490
  stroke?: Stroke;
319
491
  text?: string;
320
492
  style?: DiagramTextStyle;
493
+ verticalAlign?: 'top' | 'center' | 'bottom';
321
494
  /** What a slot is filled with: an image the kit's image painter draws. */
322
495
  image?: {
323
496
  src: string;
324
497
  opacity?: number;
325
498
  };
499
+ /** A body's text row: its place among the body's rows (see `DiagramNode.body`). */
500
+ bodyRow?: number;
501
+ /** An off-page tag's box, behind its text, and the room between them. */
502
+ background?: {
503
+ paint: {
504
+ color: string;
505
+ };
506
+ };
507
+ padding?: number;
326
508
  }
327
509
  /** A scene node spec, as `diagramScene` returns them. */
328
- type DiagramSpec = AddNodeSpec<DiagramSceneData, 'main', RectPose>;
510
+ type DiagramSpec<TLayer extends string = 'main'> = AddNodeSpec<DiagramSceneData, TLayer, RectPose>;
329
511
  /** How `diagramScene` lays out, routes, and styles a {@link DiagramData}. */
330
- interface DiagramSceneOptions {
512
+ interface DiagramSceneOptions<TLayer extends string = 'main'> {
513
+ /** The layer every spec goes on. Default `'main'`. */
514
+ layer?: TLayer;
331
515
  /** A layout by name, or any `LayoutFn`. Default `'layered'`. `'none'`
332
516
  * leaves every node at its `at`. */
333
517
  layout?: 'layered' | 'tree' | 'force' | 'chain' | 'none' | LayoutFn;
@@ -361,19 +545,9 @@ interface DiagramSceneOptions {
361
545
  /** A group's box and label. `text` colors the label. */
362
546
  groupStyle?: (group: DataGroup) => NodeStyle;
363
547
  edgeStyle?: (edge: DataEdge) => EdgeStyle;
548
+ /** Styles nodes by their `style` role, and edges, groups and text by the theme, where the
549
+ * functions above leave them; and its face is the default `font`. */
550
+ theme?: DiagramTheme;
364
551
  }
365
- /** The scene node id `diagramScene` gives an edge, built from its ends, ports,
366
- * and label. Two edges differing in any of those get different ids, an empty
367
- * port or label included: a `.`, `>`, `:`, `/` or `\` in one of them is
368
- * escaped with a backslash. */
369
- declare const edgeIdOf: (e: DataEdge) => string;
370
- /** Every spec carries an id — a node's own, `<id>/<k>` for its text,
371
- * `<id>/mark:<i>` for its marks, `<edge id>/label`, a group's own and
372
- * `<group id>/label` — so a later call's
373
- * specs can be reconciled against this one's. Throws on a repeated id among
374
- * nodes and groups, which names two things as one. An edge whose
375
- * end is not a node is dropped, and so is a repeat of an earlier edge with
376
- * the same ends, ports and label: it would draw exactly on top of the first. */
377
- declare function diagramScene(data: DiagramData, opts?: DiagramSceneOptions): DiagramSpec[];
378
552
 
379
- export { ANCHOR_DERIVE_POSE as A, edgeIdOf as B, groupDerivePose as C, type DiagramData as D, type EdgeStyle as E, layoutOwnsPort as F, GROUP_DERIVE_POSE as G, layoutOwnsRoute as H, markShape as I, registerMarkShape as J, type NodeStyle as N, type DiagramSceneOptions as a, type DataEdge as b, type DataNode as c, type DiagramRouter as d, type DiagramSpec as e, type EdgeEnd as f, DIAGRAM_ANCHOR as g, DIAGRAM_GROUP as h, type DataGroup as i, type DataMark as j, type DiagramAnchor as k, type DiagramDerivePose as l, type DiagramEdge as m, type DiagramLabel as n, type DiagramMark as o, type DiagramSceneData as p, type DiagramTextStyle as q, type GroupPoseOptions as r, anchorDerivePose as s, boxAround as t, diagramAnchorOf as u, diagramEdgeOf as v, diagramGroupOf as w, diagramLabelOf as x, diagramMarkOf as y, diagramScene as z };
553
+ export { ANCHOR_DERIVE_POSE as A, type GroupPoseOptions as B, NODE_STROKE_WIDTH as C, type DiagramTheme as D, type EdgeStyle as E, type OffPageTag as F, GROUP_DERIVE_POSE as G, anchorDerivePose as H, boxAround as I, diagramAnchorOf as J, diagramEdgeOf as K, LANE_STROKE_WIDTH as L, diagramGroupOf as M, type NodeStyle as N, type OffPageSplit as O, diagramMarkOf as P, groupDerivePose as Q, layoutOwnsPort as R, layoutOwnsRoute as S, layoutWritesRoute as T, markShape as U, offPageTagId as V, offPageTagOf as W, registerMarkShape as X, rowTextStyle as Y, type DiagramData as a, type DiagramSceneOptions as b, type DataEdge as c, type DataNode as d, type DiagramRouter as e, type DiagramSpec as f, type EdgeEnd as g, type DiagramSceneData as h, type DiagramEdge as i, type DataContainer as j, DEFAULT_LANE_SIZE as k, DEFAULT_POOL_ACROSS as l, DIAGRAM_ANCHOR as m, DIAGRAM_GROUP as n, DIAGRAM_ROLES as o, DIAGRAM_THEME_KEY as p, type DataGroup as q, type DataLane as r, type DataMark as s, type DiagramAnchor as t, type DiagramDerivePose as u, type DiagramFont as v, type DiagramMark as w, type DiagramRole as x, type DiagramTextStyle as y, EDGE_STROKE_WIDTH as z };
@@ -0,0 +1,138 @@
1
+ import { GraphNodeDef, GraphTarget, GraphPatch, AnalyserTap, AudioEngine } from '@weasel-js/audio';
2
+ import { E as EffectPipeline, a as EffectRun, b as EffectStageType } from './stageTypes-DvnR8cKQ.js';
3
+ import { VisibleRafOptions } from '@weasel-js/react';
4
+ import '@weasel-js/core';
5
+ import '@weasel-js/core/math';
6
+
7
+ /** What a run supplies to its source stages. */
8
+ interface AudioSources {
9
+ audio?: AudioBuffer;
10
+ }
11
+ type Values = Readonly<Record<string, unknown>>;
12
+ /** How one stage type becomes a graph node: its settings, its levels, and the node it builds. */
13
+ interface AudioStageNode {
14
+ /** The stage's discrete settings, from its param values and the run's sources. Throws to fail the stage. */
15
+ settings(params: Values, sources: AudioSources): Values;
16
+ /** The ids of its numeric params, each a `params` key of the def `build` returns. */
17
+ levels: readonly string[];
18
+ build(ctx: BaseAudioContext, settings: Values, levels: Readonly<Record<string, number>>): GraphNodeDef;
19
+ }
20
+ /** The graph node of each stage type, by `type`. */
21
+ type AudioStageNodes = Readonly<Record<string, AudioStageNode>>;
22
+ /** The graph node each stage type builds; `audio.output` has none. */
23
+ declare const audioStageNodes: AudioStageNodes;
24
+
25
+ /** A node the plan builds: its stage type, its discrete settings and its numeric levels. */
26
+ interface PlanNode {
27
+ type: string;
28
+ settings: Readonly<Record<string, unknown>>;
29
+ levels: Readonly<Record<string, number>>;
30
+ }
31
+ /** A connection the plan makes, from a node to another node's port or to the graph's output. */
32
+ interface PlanEdge {
33
+ from: string;
34
+ to: GraphTarget;
35
+ }
36
+ /** The graph an audio pipeline should play: what to build, how it connects, and which stages it left out. */
37
+ interface LivePlan {
38
+ nodes: Readonly<Record<string, PlanNode>>;
39
+ /** Sorted by `edgeKey`, so equal plans compare equal. */
40
+ edges: readonly PlanEdge[];
41
+ /** Why a stage is not in `nodes`, by stage id. A stage left out for want of input has none. */
42
+ errors: Readonly<Record<string, string>>;
43
+ }
44
+ /** The plan of a graph holding nothing. */
45
+ declare const EMPTY_PLAN: LivePlan;
46
+ /** Compiles the audio stages of `pipeline`; stages of other types are ignored. */
47
+ declare function livePlan(pipeline: EffectPipeline, nodes: AudioStageNodes, sources: AudioSources): LivePlan;
48
+
49
+ /** Makes the def for a node that is added or replaced. */
50
+ type BuildNode = (id: string, node: PlanNode) => GraphNodeDef;
51
+ /** The patches that turn the graph `prev` describes into the one `next` describes. */
52
+ declare function diffPlans(prev: LivePlan, next: LivePlan, build: BuildNode): GraphPatch[];
53
+
54
+ /** What a stage's preview slot shows while its graph plays. */
55
+ type AudioPreview = 'off' | 'scope' | 'spectrum';
56
+ type Size = {
57
+ width: number;
58
+ height: number;
59
+ };
60
+ /** The waveform as a line across the bitmap, silence at mid-height. */
61
+ declare function drawScope(tap: AnalyserTap, size: Size): ImageBitmap;
62
+ /** The spectrum as filled bars rising from the bottom, low frequencies on the left. */
63
+ declare function drawSpectrum(tap: AnalyserTap, size: Size): ImageBitmap;
64
+
65
+ /** What a live runner last published: its run, and whether it plays. */
66
+ interface LiveAudioRunnerState {
67
+ run: EffectRun | undefined;
68
+ playing: boolean;
69
+ }
70
+ /** What a live runner plays, and through which engine. */
71
+ interface LiveAudioRunnerOptions {
72
+ engine: AudioEngine;
73
+ pipeline: EffectPipeline;
74
+ nodes?: AudioStageNodes;
75
+ sources?: AudioSources;
76
+ /** The engine bus the graph plays through. */
77
+ bus?: string;
78
+ }
79
+ /** Plays an audio pipeline through a patchable graph, editing the graph as the pipeline changes. */
80
+ interface LiveAudioRunner {
81
+ readonly state: LiveAudioRunnerState;
82
+ /** The graph follows `pipeline` while it plays, or while it does not. */
83
+ setPipeline(pipeline: EffectPipeline): void;
84
+ /** A new buffer replaces each file node. */
85
+ setSources(sources: AudioSources): void;
86
+ /** Unlocks the engine, then starts the graph. */
87
+ play(): Promise<void>;
88
+ pause(): void;
89
+ /** Which stages draw into their `out` preview: a scope, a spectrum, or none. Takes effect on the next `frame`. */
90
+ setPreviews(mode: AudioPreview): void;
91
+ /** Publishes a run with each tapped stage's preview drawn from its tap's current window. */
92
+ frame(): void;
93
+ /** Call after the render that shows `run`: the bitmaps of earlier runs are closed. */
94
+ drawn(run: EffectRun | undefined): void;
95
+ /** A fresh graph holding the current plan, not playing: files start again from 0. */
96
+ reset(): void;
97
+ subscribe(listener: () => void): () => void;
98
+ /** Disposes the graph; the runner does nothing after. The engine is the caller's. */
99
+ dispose(): void;
100
+ }
101
+ /** A runner over `opts.pipeline` holding a fresh graph on `opts.engine`, not playing. */
102
+ declare function createLiveAudioRunner(opts: LiveAudioRunnerOptions): LiveAudioRunner;
103
+
104
+ /** Stage types over audio, each with a graph node in `audioStageNodes` except
105
+ * `audio.output`, which is the graph's own output. Every `type` is prefixed
106
+ * because `IMAGE_STAGE_TYPES` already has an `oscillator`. */
107
+ declare const AUDIO_STAGE_TYPES: readonly EffectStageType[];
108
+
109
+ /** What `useFollowAudioRunner` keeps a runner following, and how its preview loop is gated. */
110
+ interface FollowAudioRunnerOptions extends Pick<VisibleRafOptions, 'target' | 'requestFrame' | 'cancelFrame'> {
111
+ pipeline: EffectPipeline;
112
+ sources?: AudioSources;
113
+ previews: AudioPreview;
114
+ /** The nodes the plan is read with while there is no runner. */
115
+ nodes?: AudioStageNodes;
116
+ }
117
+ /**
118
+ * Keeps a caller-owned `runner` following `pipeline`, `sources` and `previews`, draws its previews every
119
+ * visible frame while it plays, and closes the bitmaps of runs no render shows. While `runner` is null,
120
+ * the run holds the plan's errors, so a stage that cannot play says why before any engine exists.
121
+ */
122
+ declare function useFollowAudioRunner(runner: LiveAudioRunner | null, opts: FollowAudioRunnerOptions): LiveAudioRunnerState;
123
+
124
+ /** Options for `useLiveAudioRunner`: the runner's, which it follows as they change, and how its preview loop is gated. */
125
+ interface UseLiveAudioRunnerOptions extends LiveAudioRunnerOptions, Pick<FollowAudioRunnerOptions, 'previews' | 'target' | 'requestFrame' | 'cancelFrame'> {
126
+ }
127
+ /** What `useLiveAudioRunner` returns: the runner's state, and the runner to drive, null until it mounts. */
128
+ interface LiveAudioRunnerHandle extends LiveAudioRunnerState {
129
+ runner: LiveAudioRunner | null;
130
+ }
131
+ /**
132
+ * A runner made on mount and remade when `engine`, `bus` or `nodes` change, following `pipeline`,
133
+ * `sources` and `previews` through `useFollowAudioRunner`, and disposed on unmount. Before the first
134
+ * mount the runner is null and the run holds the plan's errors. The engine is the caller's.
135
+ */
136
+ declare function useLiveAudioRunner(opts: UseLiveAudioRunnerOptions): LiveAudioRunnerHandle;
137
+
138
+ export { AUDIO_STAGE_TYPES, type AudioPreview, type AudioSources, type AudioStageNode, type AudioStageNodes, type BuildNode, EMPTY_PLAN, type FollowAudioRunnerOptions, type LiveAudioRunner, type LiveAudioRunnerHandle, type LiveAudioRunnerOptions, type LiveAudioRunnerState, type LivePlan, type PlanEdge, type PlanNode, type UseLiveAudioRunnerOptions, audioStageNodes, createLiveAudioRunner, diffPlans, drawScope, drawSpectrum, livePlan, useFollowAudioRunner, useLiveAudioRunner };