@weasel-js/diagram 1.13.0 → 1.14.0

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.
Files changed (35) hide show
  1. package/README.md +122 -17
  2. package/dist/{chunk-Y72FK3Y7.js → chunk-5VNPLOIX.js} +94 -6
  3. package/dist/chunk-5VNPLOIX.js.map +1 -0
  4. package/dist/{chunk-ESFIS7BB.js → chunk-62SMY45E.js} +918 -574
  5. package/dist/chunk-62SMY45E.js.map +1 -0
  6. package/dist/{chunk-FAQXYGMX.js → chunk-TBG6DFB2.js} +3 -3
  7. package/dist/{chunk-FAQXYGMX.js.map → chunk-TBG6DFB2.js.map} +1 -1
  8. package/dist/{chunk-L4H444QI.js → chunk-VB6HUKNG.js} +659 -185
  9. package/dist/chunk-VB6HUKNG.js.map +1 -0
  10. package/dist/{chunk-QU4QZUC6.js → chunk-ZWXM5F4I.js} +141 -39
  11. package/dist/chunk-ZWXM5F4I.js.map +1 -0
  12. package/dist/{dataTypes-DW-MljuN.d.ts → dataTypes-BIkhAOc4.d.ts} +13 -2
  13. package/dist/effect-audio.d.ts +2 -1
  14. package/dist/effect-audio.js +6 -5
  15. package/dist/effect-audio.js.map +1 -1
  16. package/dist/effect.d.ts +46 -16
  17. package/dist/effect.js +257 -102
  18. package/dist/effect.js.map +1 -1
  19. package/dist/icons.table.js +262 -0
  20. package/dist/icons.table.js.map +1 -1
  21. package/dist/icons.table.json +262 -0
  22. package/dist/index.d.ts +491 -167
  23. package/dist/index.js +586 -36
  24. package/dist/index.js.map +1 -1
  25. package/dist/labelTrait-BBjRgxbz.d.ts +44 -0
  26. package/dist/layout.d.ts +4 -3
  27. package/dist/{layout.entry-CQoPNfzA.d.ts → layout.entry-Ca6pVvqo.d.ts} +23 -2
  28. package/dist/layout.js +2 -2
  29. package/dist/{stageTypes-DvnR8cKQ.d.ts → stageTypes-UiO25hcn.d.ts} +7 -0
  30. package/dist/{types-vbW21fHm.d.ts → types-B0n2CNTW.d.ts} +108 -81
  31. package/package.json +11 -9
  32. package/dist/chunk-ESFIS7BB.js.map +0 -1
  33. package/dist/chunk-L4H444QI.js.map +0 -1
  34. package/dist/chunk-QU4QZUC6.js.map +0 -1
  35. package/dist/chunk-Y72FK3Y7.js.map +0 -1
@@ -1,6 +1,7 @@
1
- import { DerivedDep, PoseDescriptor, NodeShapeEntry, MarkerRef, Page, PageLayoutOptions, AddNodeSpec, Stroke, RectPose } from '@weasel-js/core';
1
+ import { DerivedDep, PoseDescriptor, NodeShapeEntry, MarkerRef, Page, PageLayoutOptions, PoseComposition, RectPose, AddNodeSpec, Stroke } from '@weasel-js/core';
2
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-vbW21fHm.js';
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, L as LayoutPorts, c as LayoutFn, d as LayoutOptions, M as MeasureRowText, e as DiagramNode } from './types-B0n2CNTW.js';
4
+ import { D as DiagramLabel } from './labelTrait-BBjRgxbz.js';
4
5
 
5
6
  /**
6
7
  * Off-page markers as data: what a connector cut at the page gap holds, and
@@ -202,6 +203,7 @@ type DiagramTextStyle = {
202
203
  fontFamily: string;
203
204
  fontSize: number;
204
205
  fontWeight?: number;
206
+ fontStyle?: 'italic';
205
207
  align?: 'center';
206
208
  };
207
209
  type Font = {
@@ -409,6 +411,11 @@ interface DataContainer {
409
411
  members?: readonly string[];
410
412
  /** A pool's lanes, in the order they stack. */
411
413
  lanes?: readonly DataLane[];
414
+ /** Lets a container's members be dragged along this axis among each other
415
+ * with `onReorder`, which hears the container and its members in their
416
+ * new order, as a group's do. Nothing moves until the members do: write
417
+ * the order to `members`, and place them by it. Not for a pool. */
418
+ reorder?: 'x' | 'y';
412
419
  /** The axis a pool stacks its lanes along: `'y'` for rows. Default `'y'`. */
413
420
  axis?: 'x' | 'y';
414
421
  /** Where it stands and how big it is, in world units. A pool's size along
@@ -553,6 +560,10 @@ interface DiagramSceneOptions<TLayer extends string = 'main'> {
553
560
  /** Styles nodes by their `style` role, and edges, groups and text by the theme, where the
554
561
  * functions above leave them; and its face is the default `font`. */
555
562
  theme?: DiagramTheme;
563
+ /** How the scene the specs go into folds a child's pose into its container's: each
564
+ * spec's pose is stored in its container's frame under it. Default
565
+ * `RIGID_POSE_COMPOSITION`, a scene's own default. */
566
+ composition?: PoseComposition<RectPose>;
556
567
  }
557
568
 
558
569
  export { ANCHOR_DERIVE_POSE as A, EDGE_STROKE_WIDTH as B, type GroupPoseOptions as C, type DiagramTheme as D, type EdgeStyle as E, NODE_STROKE_WIDTH as F, GROUP_DERIVE_POSE as G, type OffPageTag as H, anchorDerivePose as I, boxAround as J, diagramAnchorOf as K, LANE_STROKE_WIDTH as L, diagramEdgeOf as M, type NodeStyle as N, type OffPageSplit as O, diagramGroupOf as P, diagramMarkOf as Q, groupDerivePose as R, layoutOwnsPort as S, layoutOwnsRoute as T, layoutWritesRoute as U, markShape as V, offPageTagId as W, offPageTagOf as X, registerMarkShape as Y, rowTextStyle as Z, 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_NODE_STYLE as l, DEFAULT_POOL_ACROSS as m, DIAGRAM_ANCHOR as n, DIAGRAM_GROUP as o, DIAGRAM_ROLES as p, DIAGRAM_THEME_KEY as q, type DataGroup as r, type DataLane as s, type DataMark as t, type DiagramAnchor as u, type DiagramDerivePose as v, type DiagramFont as w, type DiagramMark as x, type DiagramRole as y, type DiagramTextStyle as z };
@@ -1,8 +1,9 @@
1
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';
2
+ import { E as EffectPipeline, a as EffectRun, b as EffectStageType } from './stageTypes-UiO25hcn.js';
3
3
  import { VisibleRafOptions } from '@weasel-js/react';
4
4
  import '@weasel-js/core';
5
5
  import '@weasel-js/core/math';
6
+ import './labelTrait-BBjRgxbz.js';
6
7
 
7
8
  /** What a run supplies to its source stages. */
8
9
  interface AudioSources {
@@ -1,6 +1,6 @@
1
- import { formatParam, uniqueStages, runOrder, paramValues, PREVIEW_DENSITY, closeBitmaps, previewsOf, PREVIEW_SIZE } from './chunk-FAQXYGMX.js';
2
- import './chunk-QU4QZUC6.js';
3
- import './chunk-L4H444QI.js';
1
+ import { formatParam, uniqueStages, runOrder, paramValues, PREVIEW_DENSITY, closeBitmaps, previewsOf, PREVIEW_SIZE } from './chunk-TBG6DFB2.js';
2
+ import './chunk-ZWXM5F4I.js';
3
+ import './chunk-VB6HUKNG.js';
4
4
  import { createMixNode, createFileSourceNode, compressorNode, reverbNode, delayNode, filterNode, createPanNode, createGainNode, createNoiseNode, createOscillatorNode } from '@weasel-js/audio';
5
5
  import { useEffect, useSyncExternalStore, useMemo, useState } from 'react';
6
6
  import { useVisibleRaf, useStableByContent, useLatest } from '@weasel-js/react';
@@ -397,7 +397,8 @@ var param = (id, control) => ({ id, label: id, value: formatParam(control), cont
397
397
  var amount = (value, min, max, step, unit) => ({ kind: "number", value, min, max, step, ...unit !== void 0 ? { unit } : {} });
398
398
  var choice = (value, ...options) => ({ kind: "enum", value, options: options.map((o) => ({ value: o, label: o[0].toUpperCase() + o.slice(1) })) });
399
399
  var port = (id) => ({ id, type: "audio" });
400
- var IN = [port("in")];
400
+ var input = (id) => ({ ...port(id), many: true });
401
+ var IN = [input("in")];
401
402
  var OUT = [port("out")];
402
403
  var AUDIO_STAGE_TYPES = [
403
404
  { type: "audio.file", title: "File", kind: "source", outputs: OUT },
@@ -459,7 +460,7 @@ var AUDIO_STAGE_TYPES = [
459
460
  {
460
461
  type: "audio.mix",
461
462
  title: "Mix",
462
- inputs: [port("a"), port("b")],
463
+ inputs: [input("a"), input("b")],
463
464
  outputs: OUT,
464
465
  params: [param("a", amount(1, 0, 2, 0.01)), param("b", amount(1, 0, 2, 0.01))]
465
466
  },
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/effect/audio/nodes.ts","../src/effect/audio/plan.ts","../src/effect/audio/patches.ts","../src/effect/audio/scope.ts","../src/effect/audio/livePreviews.ts","../src/effect/audio/liveRunner.ts","../src/effect/audio/stageTypes.ts","../src/effect/audio/useFollowAudioRunner.ts","../src/effect/audio/useLiveAudioRunner.ts"],"names":["levels","param","useEffect"],"mappings":"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","file":"effect-audio.js","sourcesContent":["import {\n compressorNode, createFileSourceNode, createGainNode, createMixNode, createNoiseNode, createOscillatorNode,\n createPanNode, delayNode, filterNode, reverbNode, type GraphNodeDef,\n} from '@weasel-js/audio';\n\n/** What a run supplies to its source stages. */\nexport interface AudioSources { audio?: AudioBuffer }\n\ntype Values = Readonly<Record<string, unknown>>;\n\n/** How one stage type becomes a graph node: its settings, its levels, and the node it builds. */\nexport interface AudioStageNode {\n /** The stage's discrete settings, from its param values and the run's sources. Throws to fail the stage. */\n settings(params: Values, sources: AudioSources): Values;\n /** The ids of its numeric params, each a `params` key of the def `build` returns. */\n levels: readonly string[];\n build(ctx: BaseAudioContext, settings: Values, levels: Readonly<Record<string, number>>): GraphNodeDef;\n}\n/** The graph node of each stage type, by `type`. */\nexport type AudioStageNodes = Readonly<Record<string, AudioStageNode>>;\n\n/** A node whose settings are the named param values; the factory takes them with the levels as one options bag. */\nconst node = (\n settingIds: readonly string[], levels: readonly string[],\n make: (ctx: BaseAudioContext, opts: never) => GraphNodeDef,\n): AudioStageNode => ({\n settings: (params) => Object.fromEntries(settingIds.filter((id) => params[id] !== undefined).map((id) => [id, params[id]])),\n levels,\n build: (ctx, settings, levels) => make(ctx, { ...settings, ...levels } as never),\n});\n\n/** The graph node each stage type builds; `audio.output` has none. */\nexport const audioStageNodes: AudioStageNodes = {\n 'audio.file': {\n settings: (_params, sources) => {\n if (!sources.audio) throw new Error('no source audio');\n return { buffer: sources.audio };\n },\n levels: [],\n build: (ctx, settings) => createFileSourceNode(ctx, { buffer: settings.buffer as AudioBuffer, loop: true }),\n },\n 'audio.oscillator': node(['wave'], ['frequency'], createOscillatorNode),\n 'audio.noise': node(['color'], [], createNoiseNode),\n 'audio.gain': node([], ['gain'], createGainNode),\n 'audio.pan': node([], ['pan'], createPanNode),\n 'audio.filter': node(['type'], ['frequency', 'Q'], filterNode),\n 'audio.delay': node([], ['time', 'feedback', 'mix'], delayNode),\n 'audio.reverb': node(['seconds'], ['mix'], reverbNode),\n 'audio.compressor': node([], ['threshold', 'ratio'], compressorNode),\n 'audio.mix': {\n settings: () => ({}),\n levels: ['a', 'b'],\n build: (ctx, _settings, levels) => {\n const def = createMixNode(ctx, { inputs: ['a', 'b'] });\n for (const id of ['a', 'b']) if (levels[id] !== undefined) def.params[id]!(levels[id], 0);\n return def;\n },\n },\n};\n","import type { GraphTarget } from '@weasel-js/audio';\nimport { uniqueStages } from '../draw';\nimport { runOrder } from '../runner/order';\nimport { paramValues } from '../runner/params';\nimport type { EffectPipeline, EffectStage } from '../types';\nimport type { AudioSources, AudioStageNodes } from './nodes';\n\n/** A node the plan builds: its stage type, its discrete settings and its numeric levels. */\nexport interface PlanNode {\n type: string;\n settings: Readonly<Record<string, unknown>>;\n levels: Readonly<Record<string, number>>;\n}\n/** A connection the plan makes, from a node to another node's port or to the graph's output. */\nexport interface PlanEdge { from: string; to: GraphTarget }\n\n/** The graph an audio pipeline should play: what to build, how it connects, and which stages it left out. */\nexport interface LivePlan {\n nodes: Readonly<Record<string, PlanNode>>;\n /** Sorted by `edgeKey`, so equal plans compare equal. */\n edges: readonly PlanEdge[];\n /** Why a stage is not in `nodes`, by stage id. A stage left out for want of input has none. */\n errors: Readonly<Record<string, string>>;\n}\n\n/** The plan of a graph holding nothing. */\nexport const EMPTY_PLAN: LivePlan = { nodes: {}, edges: [], errors: {} };\n\nconst OUTPUT_TYPE = 'audio.output';\n\n/** One string per edge, the same for equal edges. */\nexport const edgeKey = (e: PlanEdge): string =>\n JSON.stringify([e.from, 'output' in e.to ? null : [e.to.node, e.to.port]]);\n\nfunction levelsOf(levels: readonly string[], params: Readonly<Record<string, unknown>>): Record<string, number> {\n const out: Record<string, number> = {};\n for (const id of levels) {\n const v = params[id];\n if (typeof v === 'number') out[id] = v;\n }\n return out;\n}\n\n/** Compiles the audio stages of `pipeline`; stages of other types are ignored. */\nexport function livePlan(pipeline: EffectPipeline, nodes: AudioStageNodes, sources: AudioSources): LivePlan {\n const stages = new Map<string, EffectStage>();\n for (const s of uniqueStages(pipeline)) {\n if (s.type !== undefined && (Object.hasOwn(nodes, s.type) || s.type === OUTPUT_TYPE)) stages.set(s.id, s);\n }\n const { order, cyclic } = runOrder(pipeline);\n const planNodes: Record<string, PlanNode> = {};\n const errors: Record<string, string> = {};\n for (const id of cyclic) if (stages.has(id)) errors[id] = 'on a feedback loop';\n\n /** The planned nodes whose sound leaves each stage: itself, or what a bypassed stage carries on. */\n const origins = new Map<string, readonly string[]>();\n const edges = new Map<string, PlanEdge>();\n\n for (const id of order) {\n const stage = stages.get(id);\n if (stage === undefined) continue;\n const isOutput = stage.type === OUTPUT_TYPE;\n const bypassed = stage.bypassed === true && !isOutput;\n const firstAudio = (stage.inputs ?? []).find((i) => i.type === 'audio')?.id;\n const fed = pipeline.wires\n .filter((w) => w.to.stage === id && stages.has(w.from.stage) && (!bypassed || w.to.port === firstAudio))\n .flatMap((w) => (origins.get(w.from.stage) ?? []).map((from) => ({ from, port: w.to.port })));\n if ((stage.inputs?.length ?? 0) > 0 && fed.length === 0) continue;\n\n if (bypassed) {\n origins.set(id, [...new Set(fed.map((f) => f.from))]);\n continue;\n }\n if (!isOutput) {\n const entry = nodes[stage.type!]!;\n const params = paramValues(stage);\n try {\n planNodes[id] = { type: stage.type!, settings: entry.settings(params, sources), levels: levelsOf(entry.levels, params) };\n } catch (err) {\n errors[id] = err instanceof Error ? err.message : String(err);\n continue;\n }\n origins.set(id, [id]);\n }\n for (const f of fed) {\n const edge: PlanEdge = { from: f.from, to: isOutput ? { output: true } : { node: id, port: f.port } };\n edges.set(edgeKey(edge), edge);\n }\n }\n return {\n nodes: planNodes,\n edges: [...edges.values()].sort((a, b) => {\n const [ka, kb] = [edgeKey(a), edgeKey(b)];\n return ka < kb ? -1 : ka > kb ? 1 : 0;\n }),\n errors,\n };\n}\n","import type { GraphNodeDef, GraphPatch } from '@weasel-js/audio';\nimport { edgeKey, type LivePlan, type PlanEdge, type PlanNode } from './plan';\n\n/** Makes the def for a node that is added or replaced. */\nexport type BuildNode = (id: string, node: PlanNode) => GraphNodeDef;\n\nfunction sameSettings(a: PlanNode['settings'], b: PlanNode['settings']): boolean {\n const keys = Object.keys(a);\n return keys.length === Object.keys(b).length && keys.every((k) => k in b && Object.is(a[k], b[k]));\n}\n\nconst touches = (e: PlanEdge, ids: ReadonlySet<string>): boolean =>\n ids.has(e.from) || ('node' in e.to && ids.has(e.to.node));\n\n/** The patches that turn the graph `prev` describes into the one `next` describes. */\nexport function diffPlans(prev: LivePlan, next: LivePlan, build: BuildNode): GraphPatch[] {\n const prevIds = Object.keys(prev.nodes).sort();\n const nextIds = Object.keys(next.nodes).sort();\n const gone = new Set<string>(); // removed, or removed to change type: their old edges are dropped\n const fresh = new Set<string>(); // gone, or newly added: every edge touching them in `next` is connected\n const groups = {\n disconnect: [] as GraphPatch[],\n remove: [] as GraphPatch[],\n add: [] as GraphPatch[],\n replace: [] as GraphPatch[],\n set: [] as GraphPatch[],\n connect: [] as GraphPatch[],\n };\n\n for (const id of prevIds) {\n const now = next.nodes[id];\n if (now === undefined || now.type !== prev.nodes[id]!.type) {\n gone.add(id);\n fresh.add(id);\n groups.remove.push({ kind: 'remove', id });\n }\n }\n for (const id of nextIds) {\n const now = next.nodes[id]!;\n const was = prev.nodes[id];\n if (was === undefined || gone.has(id)) {\n fresh.add(id);\n groups.add.push({ kind: 'add', id, def: build(id, now) });\n } else if (!sameSettings(was.settings, now.settings)) {\n groups.replace.push({ kind: 'replace', id, def: build(id, now) });\n } else {\n for (const param of Object.keys(now.levels).sort()) {\n const value = now.levels[param]!;\n if (!Object.is(was.levels[param], value)) groups.set.push({ kind: 'set', id, param, value });\n }\n }\n }\n\n const nextKeys = new Set(next.edges.map(edgeKey));\n const prevKeys = new Set(prev.edges.map(edgeKey));\n for (const e of prev.edges) {\n if (!nextKeys.has(edgeKey(e)) && !touches(e, gone)) {\n groups.disconnect.push({ kind: 'disconnect', from: e.from, to: e.to });\n }\n }\n for (const e of next.edges) {\n if (!prevKeys.has(edgeKey(e)) || touches(e, fresh)) groups.connect.push({ kind: 'connect', from: e.from, to: e.to });\n }\n\n return [\n ...groups.disconnect,\n ...groups.remove,\n ...groups.add,\n ...groups.replace,\n ...groups.set,\n ...groups.connect,\n ];\n}\n","import type { AnalyserTap } from '@weasel-js/audio';\nimport { PREVIEW_DENSITY } from '../draw';\n\n/** What a stage's preview slot shows while its graph plays. */\nexport type AudioPreview = 'off' | 'scope' | 'spectrum';\n\n// Neutral enough to read on both the light and the dark theme; no image preview names a foreground to match.\nconst INK = '#8a8f98';\nconst BANDS = 32;\nconst LINE = 1.5;\n\ntype Size = { width: number; height: number };\n\nfunction canvasOf(size: Size) {\n const canvas = new OffscreenCanvas(\n Math.max(1, Math.round(size.width * PREVIEW_DENSITY)),\n Math.max(1, Math.round(size.height * PREVIEW_DENSITY)),\n );\n return { canvas, g: canvas.getContext('2d')!, w: canvas.width, h: canvas.height };\n}\n\n/** The waveform as a line across the bitmap, silence at mid-height. */\nexport function drawScope(tap: AnalyserTap, size: Size): ImageBitmap {\n const { canvas, g, w, h } = canvasOf(size);\n const wave = tap.waveform();\n g.strokeStyle = INK;\n g.lineWidth = LINE * PREVIEW_DENSITY;\n g.lineJoin = 'round';\n g.beginPath();\n for (let x = 0; x < w; x += 1) {\n const v = wave[Math.min(wave.length - 1, Math.floor((x / Math.max(1, w - 1)) * (wave.length - 1)))]! / 255;\n const y = h - v * h;\n if (x === 0) g.moveTo(x, y);\n else g.lineTo(x, y);\n }\n g.stroke();\n return canvas.transferToImageBitmap();\n}\n\n/** The spectrum as filled bars rising from the bottom, low frequencies on the left. */\nexport function drawSpectrum(tap: AnalyserTap, size: Size): ImageBitmap {\n const { canvas, g, w, h } = canvasOf(size);\n const bands = tap.bands(BANDS);\n const slot = w / BANDS;\n g.fillStyle = INK;\n for (let i = 0; i < BANDS; i += 1) {\n const bar = bands[i]! * h;\n g.fillRect(i * slot, h - bar, slot * 0.8, bar);\n }\n return canvas.transferToImageBitmap();\n}\n","import type { AnalyserTap, AudioGraph } from '@weasel-js/audio';\nimport { PREVIEW_SIZE } from '../draw';\nimport { closeBitmaps, previewsOf } from '../runner/previews';\nimport type { EffectRun, EffectStageRun } from '../types';\nimport { drawScope, drawSpectrum, type AudioPreview } from './scope';\n\n/** The analyser taps behind a live runner's previews, and the runs it has drawn them into. */\nexport interface LivePreviews {\n mode(): AudioPreview;\n setMode(mode: AudioPreview, graph: AudioGraph, ids: readonly string[]): void;\n /** After an edit: forgets taps of `removed` nodes (the graph disposed them) and taps any planned node without one. */\n follow(graph: AudioGraph, removed: readonly string[], planned: readonly string[]): void;\n /** Forgets every tap: they went with the graph they were on. */\n restart(): void;\n /** A run with the previews drawn from every tap, over `errors`; undefined when nothing is tapped. */\n draw(errors: Readonly<Record<string, string>>): EffectRun | undefined;\n /** Notes a run the runner published, so `drawn` can tell which came before it. */\n track(run: EffectRun): void;\n drawn(run: EffectRun | undefined): void;\n /** Closes every bitmap still held and disposes the taps. */\n dispose(): void;\n}\n\n/** A run holding only `errors`, by stage id. */\nexport const errorsRun = (errors: Readonly<Record<string, string>>): EffectRun =>\n ({ stages: Object.fromEntries(Object.entries(errors).map(([id, error]) => [id, { error }])) });\n\nexport function createLivePreviews(): LivePreviews {\n let mode: AudioPreview = 'off';\n let taps = new Map<string, AnalyserTap>();\n // Runs published and not yet known to be off screen, oldest first.\n let published: EffectRun[] = [];\n\n const tapAll = (graph: AudioGraph, ids: readonly string[]) => {\n for (const id of ids) if (!taps.has(id)) taps.set(id, graph.tap(id));\n };\n const disposeTaps = () => {\n for (const t of taps.values()) t.dispose();\n taps = new Map();\n };\n\n return {\n mode: () => mode,\n setMode(next, graph, ids) {\n mode = next;\n if (next === 'off') disposeTaps();\n else tapAll(graph, ids);\n },\n follow(graph, removed, planned) {\n if (mode === 'off') return;\n for (const id of removed) taps.delete(id);\n const live = new Set(planned);\n for (const id of [...taps.keys()]) if (!live.has(id)) taps.delete(id);\n tapAll(graph, planned);\n },\n restart() {\n taps = new Map();\n },\n draw(errors) {\n if (mode === 'off' || taps.size === 0) return undefined;\n const paint = mode === 'scope' ? drawScope : drawSpectrum;\n const stages: Record<string, EffectStageRun> = { ...errorsRun(errors).stages };\n for (const [id, tap] of taps) {\n stages[id] = { ...stages[id], previews: { out: paint(tap, { width: PREVIEW_SIZE, height: PREVIEW_SIZE }) } };\n }\n return { stages };\n },\n track(run) {\n published.push(run);\n },\n drawn(run) {\n const at = run === undefined ? published.length : published.indexOf(run);\n if (at <= 0) return;\n const keep = new Set(run === undefined ? [] : previewsOf(run));\n closeBitmaps(published.slice(0, at).flatMap(previewsOf).filter((b) => !keep.has(b)));\n published = published.slice(at);\n },\n dispose() {\n disposeTaps();\n closeBitmaps(published.flatMap(previewsOf));\n published = [];\n },\n };\n}\n","import type { AudioEngine, AudioGraph, GraphPatch } from '@weasel-js/audio';\nimport type { EffectPipeline, EffectRun } from '../types';\nimport { audioStageNodes, type AudioSources, type AudioStageNodes } from './nodes';\nimport { createLivePreviews, errorsRun } from './livePreviews';\nimport { diffPlans } from './patches';\nimport { EMPTY_PLAN, livePlan, type LivePlan } from './plan';\nimport type { AudioPreview } from './scope';\n\n/** What a live runner last published: its run, and whether it plays. */\nexport interface LiveAudioRunnerState { run: EffectRun | undefined; playing: boolean }\n\n/** What a live runner plays, and through which engine. */\nexport interface LiveAudioRunnerOptions {\n engine: AudioEngine;\n pipeline: EffectPipeline;\n nodes?: AudioStageNodes;\n sources?: AudioSources;\n /** The engine bus the graph plays through. */\n bus?: string;\n}\n\n/** Plays an audio pipeline through a patchable graph, editing the graph as the pipeline changes. */\nexport interface LiveAudioRunner {\n readonly state: LiveAudioRunnerState;\n /** The graph follows `pipeline` while it plays, or while it does not. */\n setPipeline(pipeline: EffectPipeline): void;\n /** A new buffer replaces each file node. */\n setSources(sources: AudioSources): void;\n /** Unlocks the engine, then starts the graph. */\n play(): Promise<void>;\n pause(): void;\n /** Which stages draw into their `out` preview: a scope, a spectrum, or none. Takes effect on the next `frame`. */\n setPreviews(mode: AudioPreview): void;\n /** Publishes a run with each tapped stage's preview drawn from its tap's current window. */\n frame(): void;\n /** Call after the render that shows `run`: the bitmaps of earlier runs are closed. */\n drawn(run: EffectRun | undefined): void;\n /** A fresh graph holding the current plan, not playing: files start again from 0. */\n reset(): void;\n subscribe(listener: () => void): () => void;\n /** Disposes the graph; the runner does nothing after. The engine is the caller's. */\n dispose(): void;\n}\n\nconst messageOf = (err: unknown): string => (err instanceof Error ? err.message : String(err));\n\nconst idsOf = (p: GraphPatch): string[] =>\n 'id' in p ? [p.id] : [p.from, ...('node' in p.to ? [p.to.node] : [])];\n\n/** The stage a failed structural patch names: the one whose id the error message quotes. */\nconst failingStage = (patches: readonly GraphPatch[], message: string): string | undefined =>\n patches.flatMap(idsOf).find((id) => message.includes(`\"${id}\"`));\n\nconst sameErrors = (a: Readonly<Record<string, string>>, b: Readonly<Record<string, string>>): boolean => {\n const keys = Object.keys(a);\n return keys.length === Object.keys(b).length && keys.every((k) => a[k] === b[k]);\n};\n\n/** Applies the param writes together; when that throws, one by one, to name the stage that failed. */\nfunction applySets(graph: AudioGraph, sets: readonly GraphPatch[], failures: Record<string, string>): void {\n if (sets.length === 0) return;\n try {\n graph.apply(sets);\n } catch (err) {\n console.warn(`@weasel-js/diagram: audio graph edit failed: ${messageOf(err)}`);\n for (const p of sets) {\n try {\n graph.apply([p]);\n } catch (one) {\n if (p.kind === 'set') failures[p.id] = messageOf(one);\n break;\n }\n }\n }\n}\n\n/** A runner over `opts.pipeline` holding a fresh graph on `opts.engine`, not playing. */\nexport function createLiveAudioRunner(opts: LiveAudioRunnerOptions): LiveAudioRunner {\n const { engine, bus } = opts;\n const nodes = opts.nodes ?? audioStageNodes;\n let pipeline = opts.pipeline;\n let sources: AudioSources = opts.sources ?? {};\n let graph: AudioGraph = engine.graph(bus);\n let plan: LivePlan = EMPTY_PLAN;\n let errors: Readonly<Record<string, string>> = {};\n let state: LiveAudioRunnerState = { run: { stages: {} }, playing: false };\n let disposed = false;\n const listeners = new Set<() => void>();\n const previews = createLivePreviews();\n\n const set = (next: Partial<LiveAudioRunnerState>) => {\n const merged = { ...state, ...next };\n if (merged.run === state.run && merged.playing === state.playing) return;\n if (merged.run !== state.run && merged.run !== undefined) previews.track(merged.run);\n state = merged;\n for (const l of [...listeners]) l();\n };\n const publishErrors = (next: Readonly<Record<string, string>>) => {\n if (sameErrors(errors, next)) return;\n errors = next;\n set({ run: errorsRun(next) });\n };\n\n /** Brings the graph from `from` to the plan `pipeline` and `sources` now give. Structure goes first\n * in its own apply: a throw there changed nothing, while a throw from the sets means structure landed. */\n const sync = (from: LivePlan) => {\n const next = livePlan(pipeline, nodes, sources);\n const merged: Record<string, string> = { ...next.errors };\n let adopted = next;\n let structural: GraphPatch[] = [];\n let removed: string[] = [];\n let sets: GraphPatch[] = [];\n try {\n const patches = diffPlans(from, next, (_id, n) => nodes[n.type]!.build(engine.context, n.settings, n.levels));\n structural = patches.filter((p) => p.kind !== 'set');\n sets = patches.filter((p) => p.kind === 'set');\n if (structural.length > 0) graph.apply(structural);\n removed = structural.flatMap((p) => (p.kind === 'remove' ? [p.id] : []));\n } catch (err) {\n const message = messageOf(err);\n const id = failingStage(structural, message);\n if (id !== undefined) merged[id] = message;\n console.warn(`@weasel-js/diagram: audio graph edit failed: ${message}`);\n adopted = from;\n sets = [];\n }\n applySets(graph, sets, merged);\n plan = adopted;\n previews.follow(graph, removed, Object.keys(adopted.nodes));\n publishErrors(merged);\n };\n\n sync(EMPTY_PLAN);\n\n return {\n get state() { return state; },\n setPipeline(next) {\n if (disposed) return;\n pipeline = next;\n sync(plan);\n },\n setSources(next) {\n if (disposed) return;\n sources = next;\n sync(plan);\n },\n async play() {\n if (disposed) return;\n await engine.unlock();\n if (disposed) return;\n graph.start();\n set({ playing: true });\n },\n pause() {\n if (disposed) return;\n graph.stop();\n set({ playing: false });\n },\n setPreviews(mode) {\n if (disposed) return;\n previews.setMode(mode, graph, Object.keys(plan.nodes));\n if (mode === 'off') set({ run: errorsRun(errors) });\n },\n frame() {\n if (disposed) return;\n const run = previews.draw(errors);\n if (run !== undefined) set({ run });\n },\n drawn: previews.drawn,\n reset() {\n if (disposed) return;\n graph.dispose();\n graph = engine.graph(bus);\n previews.restart();\n sync(EMPTY_PLAN);\n set({ playing: false });\n },\n subscribe(listener) {\n listeners.add(listener);\n return () => { listeners.delete(listener); };\n },\n dispose() {\n if (disposed) return;\n disposed = true;\n previews.dispose();\n graph.dispose();\n },\n };\n}\n","import { formatParam, type EffectStageType } from '../stageTypes';\nimport type { EffectParam, EffectParamControl, EffectPort } from '../types';\n\nconst param = (id: string, control: EffectParamControl): EffectParam => ({ id, label: id, value: formatParam(control), control });\n\nconst amount = (value: number, min: number, max: number, step: number, unit?: string): EffectParamControl =>\n ({ kind: 'number', value, min, max, step, ...(unit !== undefined ? { unit } : {}) });\n\nconst choice = (value: string, ...options: string[]): EffectParamControl =>\n ({ kind: 'enum', value, options: options.map((o) => ({ value: o, label: o[0]!.toUpperCase() + o.slice(1) })) });\n\nconst port = (id: string): EffectPort => ({ id, type: 'audio' });\nconst IN = [port('in')];\nconst OUT = [port('out')];\n\n/** Stage types over audio, each with a graph node in `audioStageNodes` except\n * `audio.output`, which is the graph's own output. Every `type` is prefixed\n * because `IMAGE_STAGE_TYPES` already has an `oscillator`. */\nexport const AUDIO_STAGE_TYPES: readonly EffectStageType[] = [\n { type: 'audio.file', title: 'File', kind: 'source', outputs: OUT },\n {\n type: 'audio.oscillator', title: 'Oscillator', kind: 'source', outputs: OUT,\n params: [\n param('wave', choice('sine', 'sine', 'square', 'sawtooth', 'triangle')),\n param('frequency', amount(440, 20, 20000, 1, 'Hz')),\n ],\n },\n {\n type: 'audio.noise', title: 'Noise', kind: 'source', outputs: OUT,\n params: [param('color', choice('white', 'white', 'pink', 'brown'))],\n },\n { type: 'audio.gain', title: 'Gain', inputs: IN, outputs: OUT, params: [param('gain', amount(1, 0, 2, 0.01))] },\n { type: 'audio.pan', title: 'Pan', inputs: IN, outputs: OUT, params: [param('pan', amount(0, -1, 1, 0.01))] },\n {\n type: 'audio.filter', title: 'Filter', inputs: IN, outputs: OUT,\n params: [\n param('type', choice('lowpass', 'lowpass', 'highpass', 'bandpass')),\n param('frequency', amount(1000, 20, 20000, 1, 'Hz')),\n param('Q', amount(1, 0.1, 20, 0.1)),\n ],\n },\n {\n type: 'audio.delay', title: 'Delay', inputs: IN, outputs: OUT,\n params: [\n param('time', amount(300, 0, 2000, 10, 'ms')),\n param('feedback', amount(0.4, 0, 0.95, 0.01)),\n param('mix', amount(0.5, 0, 1, 0.01)),\n ],\n },\n {\n type: 'audio.reverb', title: 'Reverb', inputs: IN, outputs: OUT,\n params: [param('seconds', amount(2, 0.1, 10, 0.1, 's')), param('mix', amount(0.3, 0, 1, 0.01))],\n },\n {\n type: 'audio.compressor', title: 'Compressor', inputs: IN, outputs: OUT,\n params: [param('threshold', amount(-24, -60, 0, 1, 'dB')), param('ratio', amount(4, 1, 20, 0.5))],\n },\n {\n type: 'audio.mix', title: 'Mix', inputs: [port('a'), port('b')], outputs: OUT,\n params: [param('a', amount(1, 0, 2, 0.01)), param('b', amount(1, 0, 2, 0.01))],\n },\n { type: 'audio.output', title: 'Output', kind: 'sink', inputs: IN },\n];\n","import { useEffect, useMemo, useSyncExternalStore } from 'react';\nimport { useVisibleRaf, type VisibleRafOptions } from '@weasel-js/react';\nimport type { EffectPipeline } from '../types';\nimport type { LiveAudioRunner, LiveAudioRunnerState } from './liveRunner';\nimport { errorsRun } from './livePreviews';\nimport { audioStageNodes, type AudioSources, type AudioStageNodes } from './nodes';\nimport { livePlan } from './plan';\nimport type { AudioPreview } from './scope';\n\n/** What `useFollowAudioRunner` keeps a runner following, and how its preview loop is gated. */\nexport interface FollowAudioRunnerOptions extends Pick<VisibleRafOptions, 'target' | 'requestFrame' | 'cancelFrame'> {\n pipeline: EffectPipeline;\n sources?: AudioSources;\n previews: AudioPreview;\n /** The nodes the plan is read with while there is no runner. */\n nodes?: AudioStageNodes;\n}\n\nconst noSubscribe = () => () => {};\n\n/**\n * Keeps a caller-owned `runner` following `pipeline`, `sources` and `previews`, draws its previews every\n * visible frame while it plays, and closes the bitmaps of runs no render shows. While `runner` is null,\n * the run holds the plan's errors, so a stage that cannot play says why before any engine exists.\n */\nexport function useFollowAudioRunner(runner: LiveAudioRunner | null, opts: FollowAudioRunnerOptions): LiveAudioRunnerState {\n const { pipeline, sources, previews, nodes, target, requestFrame, cancelFrame } = opts;\n useEffect(() => { runner?.setPipeline(pipeline); }, [runner, pipeline]);\n useEffect(() => { if (sources !== undefined) runner?.setSources(sources); }, [runner, sources]);\n useEffect(() => { runner?.setPreviews(previews); }, [runner, previews]);\n const live = useSyncExternalStore(runner?.subscribe ?? noSubscribe, () => runner?.state ?? null);\n const planned = useMemo(\n () => (runner !== null ? undefined : errorsRun(livePlan(pipeline, nodes ?? audioStageNodes, sources ?? {}).errors)),\n [runner, pipeline, nodes, sources],\n );\n const playing = live?.playing ?? false;\n\n const loop = useVisibleRaf((_now, self) => {\n if (runner === null || !runner.state.playing || previews === 'off') return;\n runner.frame();\n self.request();\n }, {\n ...(target !== undefined ? { target } : {}),\n ...(requestFrame !== undefined ? { requestFrame } : {}),\n ...(cancelFrame !== undefined ? { cancelFrame } : {}),\n });\n useEffect(() => {\n if (playing && previews !== 'off') loop.request();\n else loop.cancel();\n }, [playing, previews, loop]);\n\n useEffect(() => { runner?.drawn(live?.run); }, [runner, live?.run]);\n return live ?? { run: planned, playing: false };\n}\n","import { useEffect, useState } from 'react';\nimport { useLatest, useStableByContent } from '@weasel-js/react';\nimport { createLiveAudioRunner, type LiveAudioRunner, type LiveAudioRunnerOptions, type LiveAudioRunnerState } from './liveRunner';\nimport type { AudioStageNodes } from './nodes';\nimport { useFollowAudioRunner, type FollowAudioRunnerOptions } from './useFollowAudioRunner';\n\n/** Options for `useLiveAudioRunner`: the runner's, which it follows as they change, and how its preview loop is gated. */\nexport interface UseLiveAudioRunnerOptions\n extends LiveAudioRunnerOptions, Pick<FollowAudioRunnerOptions, 'previews' | 'target' | 'requestFrame' | 'cancelFrame'> {}\n\n/** What `useLiveAudioRunner` returns: the runner's state, and the runner to drive, null until it mounts. */\nexport interface LiveAudioRunnerHandle extends LiveAudioRunnerState {\n runner: LiveAudioRunner | null;\n}\n\n/**\n * A runner made on mount and remade when `engine`, `bus` or `nodes` change, following `pipeline`,\n * `sources` and `previews` through `useFollowAudioRunner`, and disposed on unmount. Before the first\n * mount the runner is null and the run holds the plan's errors. The engine is the caller's. `nodes`\n * counts as changed only when a type is added, dropped or given a different node, so it can be built in render.\n */\nexport function useLiveAudioRunner(opts: UseLiveAudioRunnerOptions): LiveAudioRunnerHandle {\n const { engine, bus } = opts;\n const nodes = useStableByContent(opts.nodes, sameNodes);\n const latest = useLatest(opts);\n const [runner, setRunner] = useState<LiveAudioRunner | null>(null);\n useEffect(() => {\n const { pipeline, sources } = latest.current;\n const made = createLiveAudioRunner({\n engine, pipeline,\n ...(nodes !== undefined ? { nodes } : {}),\n ...(sources !== undefined ? { sources } : {}),\n ...(bus !== undefined ? { bus } : {}),\n });\n // eslint-disable-next-line react-hooks/set-state-in-effect -- publishes the runner this effect creates\n setRunner(made);\n return () => made.dispose();\n }, [engine, bus, nodes, latest]);\n const state = useFollowAudioRunner(runner, { ...opts, ...(nodes !== undefined ? { nodes } : {}) });\n return { ...state, runner };\n}\n\nfunction sameNodes(a: AudioStageNodes | undefined, b: AudioStageNodes | undefined): boolean {\n if (a === undefined || b === undefined) return a === b;\n const keys = Object.keys(a);\n return keys.length === Object.keys(b).length && keys.every((k) => Object.hasOwn(b, k) && a[k] === b[k]);\n}\n"]}
1
+ {"version":3,"sources":["../src/effect/audio/nodes.ts","../src/effect/audio/plan.ts","../src/effect/audio/patches.ts","../src/effect/audio/scope.ts","../src/effect/audio/livePreviews.ts","../src/effect/audio/liveRunner.ts","../src/effect/audio/stageTypes.ts","../src/effect/audio/useFollowAudioRunner.ts","../src/effect/audio/useLiveAudioRunner.ts"],"names":["levels","param","useEffect"],"mappings":"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","file":"effect-audio.js","sourcesContent":["import {\n compressorNode, createFileSourceNode, createGainNode, createMixNode, createNoiseNode, createOscillatorNode,\n createPanNode, delayNode, filterNode, reverbNode, type GraphNodeDef,\n} from '@weasel-js/audio';\n\n/** What a run supplies to its source stages. */\nexport interface AudioSources { audio?: AudioBuffer }\n\ntype Values = Readonly<Record<string, unknown>>;\n\n/** How one stage type becomes a graph node: its settings, its levels, and the node it builds. */\nexport interface AudioStageNode {\n /** The stage's discrete settings, from its param values and the run's sources. Throws to fail the stage. */\n settings(params: Values, sources: AudioSources): Values;\n /** The ids of its numeric params, each a `params` key of the def `build` returns. */\n levels: readonly string[];\n build(ctx: BaseAudioContext, settings: Values, levels: Readonly<Record<string, number>>): GraphNodeDef;\n}\n/** The graph node of each stage type, by `type`. */\nexport type AudioStageNodes = Readonly<Record<string, AudioStageNode>>;\n\n/** A node whose settings are the named param values; the factory takes them with the levels as one options bag. */\nconst node = (\n settingIds: readonly string[], levels: readonly string[],\n make: (ctx: BaseAudioContext, opts: never) => GraphNodeDef,\n): AudioStageNode => ({\n settings: (params) => Object.fromEntries(settingIds.filter((id) => params[id] !== undefined).map((id) => [id, params[id]])),\n levels,\n build: (ctx, settings, levels) => make(ctx, { ...settings, ...levels } as never),\n});\n\n/** The graph node each stage type builds; `audio.output` has none. */\nexport const audioStageNodes: AudioStageNodes = {\n 'audio.file': {\n settings: (_params, sources) => {\n if (!sources.audio) throw new Error('no source audio');\n return { buffer: sources.audio };\n },\n levels: [],\n build: (ctx, settings) => createFileSourceNode(ctx, { buffer: settings.buffer as AudioBuffer, loop: true }),\n },\n 'audio.oscillator': node(['wave'], ['frequency'], createOscillatorNode),\n 'audio.noise': node(['color'], [], createNoiseNode),\n 'audio.gain': node([], ['gain'], createGainNode),\n 'audio.pan': node([], ['pan'], createPanNode),\n 'audio.filter': node(['type'], ['frequency', 'Q'], filterNode),\n 'audio.delay': node([], ['time', 'feedback', 'mix'], delayNode),\n 'audio.reverb': node(['seconds'], ['mix'], reverbNode),\n 'audio.compressor': node([], ['threshold', 'ratio'], compressorNode),\n 'audio.mix': {\n settings: () => ({}),\n levels: ['a', 'b'],\n build: (ctx, _settings, levels) => {\n const def = createMixNode(ctx, { inputs: ['a', 'b'] });\n for (const id of ['a', 'b']) if (levels[id] !== undefined) def.params[id]!(levels[id], 0);\n return def;\n },\n },\n};\n","import type { GraphTarget } from '@weasel-js/audio';\nimport { uniqueStages } from '../draw';\nimport { runOrder } from '../runner/order';\nimport { paramValues } from '../runner/params';\nimport type { EffectPipeline, EffectStage } from '../types';\nimport type { AudioSources, AudioStageNodes } from './nodes';\n\n/** A node the plan builds: its stage type, its discrete settings and its numeric levels. */\nexport interface PlanNode {\n type: string;\n settings: Readonly<Record<string, unknown>>;\n levels: Readonly<Record<string, number>>;\n}\n/** A connection the plan makes, from a node to another node's port or to the graph's output. */\nexport interface PlanEdge { from: string; to: GraphTarget }\n\n/** The graph an audio pipeline should play: what to build, how it connects, and which stages it left out. */\nexport interface LivePlan {\n nodes: Readonly<Record<string, PlanNode>>;\n /** Sorted by `edgeKey`, so equal plans compare equal. */\n edges: readonly PlanEdge[];\n /** Why a stage is not in `nodes`, by stage id. A stage left out for want of input has none. */\n errors: Readonly<Record<string, string>>;\n}\n\n/** The plan of a graph holding nothing. */\nexport const EMPTY_PLAN: LivePlan = { nodes: {}, edges: [], errors: {} };\n\nconst OUTPUT_TYPE = 'audio.output';\n\n/** One string per edge, the same for equal edges. */\nexport const edgeKey = (e: PlanEdge): string =>\n JSON.stringify([e.from, 'output' in e.to ? null : [e.to.node, e.to.port]]);\n\nfunction levelsOf(levels: readonly string[], params: Readonly<Record<string, unknown>>): Record<string, number> {\n const out: Record<string, number> = {};\n for (const id of levels) {\n const v = params[id];\n if (typeof v === 'number') out[id] = v;\n }\n return out;\n}\n\n/** Compiles the audio stages of `pipeline`; stages of other types are ignored. */\nexport function livePlan(pipeline: EffectPipeline, nodes: AudioStageNodes, sources: AudioSources): LivePlan {\n const stages = new Map<string, EffectStage>();\n for (const s of uniqueStages(pipeline)) {\n if (s.type !== undefined && (Object.hasOwn(nodes, s.type) || s.type === OUTPUT_TYPE)) stages.set(s.id, s);\n }\n const { order, cyclic } = runOrder(pipeline);\n const planNodes: Record<string, PlanNode> = {};\n const errors: Record<string, string> = {};\n for (const id of cyclic) if (stages.has(id)) errors[id] = 'on a feedback loop';\n\n /** The planned nodes whose sound leaves each stage: itself, or what a bypassed stage carries on. */\n const origins = new Map<string, readonly string[]>();\n const edges = new Map<string, PlanEdge>();\n\n for (const id of order) {\n const stage = stages.get(id);\n if (stage === undefined) continue;\n const isOutput = stage.type === OUTPUT_TYPE;\n const bypassed = stage.bypassed === true && !isOutput;\n const firstAudio = (stage.inputs ?? []).find((i) => i.type === 'audio')?.id;\n const fed = pipeline.wires\n .filter((w) => w.to.stage === id && stages.has(w.from.stage) && (!bypassed || w.to.port === firstAudio))\n .flatMap((w) => (origins.get(w.from.stage) ?? []).map((from) => ({ from, port: w.to.port })));\n if ((stage.inputs?.length ?? 0) > 0 && fed.length === 0) continue;\n\n if (bypassed) {\n origins.set(id, [...new Set(fed.map((f) => f.from))]);\n continue;\n }\n if (!isOutput) {\n const entry = nodes[stage.type!]!;\n const params = paramValues(stage);\n try {\n planNodes[id] = { type: stage.type!, settings: entry.settings(params, sources), levels: levelsOf(entry.levels, params) };\n } catch (err) {\n errors[id] = err instanceof Error ? err.message : String(err);\n continue;\n }\n origins.set(id, [id]);\n }\n for (const f of fed) {\n const edge: PlanEdge = { from: f.from, to: isOutput ? { output: true } : { node: id, port: f.port } };\n edges.set(edgeKey(edge), edge);\n }\n }\n return {\n nodes: planNodes,\n edges: [...edges.values()].sort((a, b) => {\n const [ka, kb] = [edgeKey(a), edgeKey(b)];\n return ka < kb ? -1 : ka > kb ? 1 : 0;\n }),\n errors,\n };\n}\n","import type { GraphNodeDef, GraphPatch } from '@weasel-js/audio';\nimport { edgeKey, type LivePlan, type PlanEdge, type PlanNode } from './plan';\n\n/** Makes the def for a node that is added or replaced. */\nexport type BuildNode = (id: string, node: PlanNode) => GraphNodeDef;\n\nfunction sameSettings(a: PlanNode['settings'], b: PlanNode['settings']): boolean {\n const keys = Object.keys(a);\n return keys.length === Object.keys(b).length && keys.every((k) => k in b && Object.is(a[k], b[k]));\n}\n\nconst touches = (e: PlanEdge, ids: ReadonlySet<string>): boolean =>\n ids.has(e.from) || ('node' in e.to && ids.has(e.to.node));\n\n/** The patches that turn the graph `prev` describes into the one `next` describes. */\nexport function diffPlans(prev: LivePlan, next: LivePlan, build: BuildNode): GraphPatch[] {\n const prevIds = Object.keys(prev.nodes).sort();\n const nextIds = Object.keys(next.nodes).sort();\n const gone = new Set<string>(); // removed, or removed to change type: their old edges are dropped\n const fresh = new Set<string>(); // gone, or newly added: every edge touching them in `next` is connected\n const groups = {\n disconnect: [] as GraphPatch[],\n remove: [] as GraphPatch[],\n add: [] as GraphPatch[],\n replace: [] as GraphPatch[],\n set: [] as GraphPatch[],\n connect: [] as GraphPatch[],\n };\n\n for (const id of prevIds) {\n const now = next.nodes[id];\n if (now === undefined || now.type !== prev.nodes[id]!.type) {\n gone.add(id);\n fresh.add(id);\n groups.remove.push({ kind: 'remove', id });\n }\n }\n for (const id of nextIds) {\n const now = next.nodes[id]!;\n const was = prev.nodes[id];\n if (was === undefined || gone.has(id)) {\n fresh.add(id);\n groups.add.push({ kind: 'add', id, def: build(id, now) });\n } else if (!sameSettings(was.settings, now.settings)) {\n groups.replace.push({ kind: 'replace', id, def: build(id, now) });\n } else {\n for (const param of Object.keys(now.levels).sort()) {\n const value = now.levels[param]!;\n if (!Object.is(was.levels[param], value)) groups.set.push({ kind: 'set', id, param, value });\n }\n }\n }\n\n const nextKeys = new Set(next.edges.map(edgeKey));\n const prevKeys = new Set(prev.edges.map(edgeKey));\n for (const e of prev.edges) {\n if (!nextKeys.has(edgeKey(e)) && !touches(e, gone)) {\n groups.disconnect.push({ kind: 'disconnect', from: e.from, to: e.to });\n }\n }\n for (const e of next.edges) {\n if (!prevKeys.has(edgeKey(e)) || touches(e, fresh)) groups.connect.push({ kind: 'connect', from: e.from, to: e.to });\n }\n\n return [\n ...groups.disconnect,\n ...groups.remove,\n ...groups.add,\n ...groups.replace,\n ...groups.set,\n ...groups.connect,\n ];\n}\n","import type { AnalyserTap } from '@weasel-js/audio';\nimport { PREVIEW_DENSITY } from '../draw';\n\n/** What a stage's preview slot shows while its graph plays. */\nexport type AudioPreview = 'off' | 'scope' | 'spectrum';\n\n// Neutral enough to read on both the light and the dark theme; no image preview names a foreground to match.\nconst INK = '#8a8f98';\nconst BANDS = 32;\nconst LINE = 1.5;\n\ntype Size = { width: number; height: number };\n\nfunction canvasOf(size: Size) {\n const canvas = new OffscreenCanvas(\n Math.max(1, Math.round(size.width * PREVIEW_DENSITY)),\n Math.max(1, Math.round(size.height * PREVIEW_DENSITY)),\n );\n return { canvas, g: canvas.getContext('2d')!, w: canvas.width, h: canvas.height };\n}\n\n/** The waveform as a line across the bitmap, silence at mid-height. */\nexport function drawScope(tap: AnalyserTap, size: Size): ImageBitmap {\n const { canvas, g, w, h } = canvasOf(size);\n const wave = tap.waveform();\n g.strokeStyle = INK;\n g.lineWidth = LINE * PREVIEW_DENSITY;\n g.lineJoin = 'round';\n g.beginPath();\n for (let x = 0; x < w; x += 1) {\n const v = wave[Math.min(wave.length - 1, Math.floor((x / Math.max(1, w - 1)) * (wave.length - 1)))]! / 255;\n const y = h - v * h;\n if (x === 0) g.moveTo(x, y);\n else g.lineTo(x, y);\n }\n g.stroke();\n return canvas.transferToImageBitmap();\n}\n\n/** The spectrum as filled bars rising from the bottom, low frequencies on the left. */\nexport function drawSpectrum(tap: AnalyserTap, size: Size): ImageBitmap {\n const { canvas, g, w, h } = canvasOf(size);\n const bands = tap.bands(BANDS);\n const slot = w / BANDS;\n g.fillStyle = INK;\n for (let i = 0; i < BANDS; i += 1) {\n const bar = bands[i]! * h;\n g.fillRect(i * slot, h - bar, slot * 0.8, bar);\n }\n return canvas.transferToImageBitmap();\n}\n","import type { AnalyserTap, AudioGraph } from '@weasel-js/audio';\nimport { PREVIEW_SIZE } from '../draw';\nimport { closeBitmaps, previewsOf } from '../runner/previews';\nimport type { EffectRun, EffectStageRun } from '../types';\nimport { drawScope, drawSpectrum, type AudioPreview } from './scope';\n\n/** The analyser taps behind a live runner's previews, and the runs it has drawn them into. */\nexport interface LivePreviews {\n mode(): AudioPreview;\n setMode(mode: AudioPreview, graph: AudioGraph, ids: readonly string[]): void;\n /** After an edit: forgets taps of `removed` nodes (the graph disposed them) and taps any planned node without one. */\n follow(graph: AudioGraph, removed: readonly string[], planned: readonly string[]): void;\n /** Forgets every tap: they went with the graph they were on. */\n restart(): void;\n /** A run with the previews drawn from every tap, over `errors`; undefined when nothing is tapped. */\n draw(errors: Readonly<Record<string, string>>): EffectRun | undefined;\n /** Notes a run the runner published, so `drawn` can tell which came before it. */\n track(run: EffectRun): void;\n drawn(run: EffectRun | undefined): void;\n /** Closes every bitmap still held and disposes the taps. */\n dispose(): void;\n}\n\n/** A run holding only `errors`, by stage id. */\nexport const errorsRun = (errors: Readonly<Record<string, string>>): EffectRun =>\n ({ stages: Object.fromEntries(Object.entries(errors).map(([id, error]) => [id, { error }])) });\n\nexport function createLivePreviews(): LivePreviews {\n let mode: AudioPreview = 'off';\n let taps = new Map<string, AnalyserTap>();\n // Runs published and not yet known to be off screen, oldest first.\n let published: EffectRun[] = [];\n\n const tapAll = (graph: AudioGraph, ids: readonly string[]) => {\n for (const id of ids) if (!taps.has(id)) taps.set(id, graph.tap(id));\n };\n const disposeTaps = () => {\n for (const t of taps.values()) t.dispose();\n taps = new Map();\n };\n\n return {\n mode: () => mode,\n setMode(next, graph, ids) {\n mode = next;\n if (next === 'off') disposeTaps();\n else tapAll(graph, ids);\n },\n follow(graph, removed, planned) {\n if (mode === 'off') return;\n for (const id of removed) taps.delete(id);\n const live = new Set(planned);\n for (const id of [...taps.keys()]) if (!live.has(id)) taps.delete(id);\n tapAll(graph, planned);\n },\n restart() {\n taps = new Map();\n },\n draw(errors) {\n if (mode === 'off' || taps.size === 0) return undefined;\n const paint = mode === 'scope' ? drawScope : drawSpectrum;\n const stages: Record<string, EffectStageRun> = { ...errorsRun(errors).stages };\n for (const [id, tap] of taps) {\n stages[id] = { ...stages[id], previews: { out: paint(tap, { width: PREVIEW_SIZE, height: PREVIEW_SIZE }) } };\n }\n return { stages };\n },\n track(run) {\n published.push(run);\n },\n drawn(run) {\n const at = run === undefined ? published.length : published.indexOf(run);\n if (at <= 0) return;\n const keep = new Set(run === undefined ? [] : previewsOf(run));\n closeBitmaps(published.slice(0, at).flatMap(previewsOf).filter((b) => !keep.has(b)));\n published = published.slice(at);\n },\n dispose() {\n disposeTaps();\n closeBitmaps(published.flatMap(previewsOf));\n published = [];\n },\n };\n}\n","import type { AudioEngine, AudioGraph, GraphPatch } from '@weasel-js/audio';\nimport type { EffectPipeline, EffectRun } from '../types';\nimport { audioStageNodes, type AudioSources, type AudioStageNodes } from './nodes';\nimport { createLivePreviews, errorsRun } from './livePreviews';\nimport { diffPlans } from './patches';\nimport { EMPTY_PLAN, livePlan, type LivePlan } from './plan';\nimport type { AudioPreview } from './scope';\n\n/** What a live runner last published: its run, and whether it plays. */\nexport interface LiveAudioRunnerState { run: EffectRun | undefined; playing: boolean }\n\n/** What a live runner plays, and through which engine. */\nexport interface LiveAudioRunnerOptions {\n engine: AudioEngine;\n pipeline: EffectPipeline;\n nodes?: AudioStageNodes;\n sources?: AudioSources;\n /** The engine bus the graph plays through. */\n bus?: string;\n}\n\n/** Plays an audio pipeline through a patchable graph, editing the graph as the pipeline changes. */\nexport interface LiveAudioRunner {\n readonly state: LiveAudioRunnerState;\n /** The graph follows `pipeline` while it plays, or while it does not. */\n setPipeline(pipeline: EffectPipeline): void;\n /** A new buffer replaces each file node. */\n setSources(sources: AudioSources): void;\n /** Unlocks the engine, then starts the graph. */\n play(): Promise<void>;\n pause(): void;\n /** Which stages draw into their `out` preview: a scope, a spectrum, or none. Takes effect on the next `frame`. */\n setPreviews(mode: AudioPreview): void;\n /** Publishes a run with each tapped stage's preview drawn from its tap's current window. */\n frame(): void;\n /** Call after the render that shows `run`: the bitmaps of earlier runs are closed. */\n drawn(run: EffectRun | undefined): void;\n /** A fresh graph holding the current plan, not playing: files start again from 0. */\n reset(): void;\n subscribe(listener: () => void): () => void;\n /** Disposes the graph; the runner does nothing after. The engine is the caller's. */\n dispose(): void;\n}\n\nconst messageOf = (err: unknown): string => (err instanceof Error ? err.message : String(err));\n\nconst idsOf = (p: GraphPatch): string[] =>\n 'id' in p ? [p.id] : [p.from, ...('node' in p.to ? [p.to.node] : [])];\n\n/** The stage a failed structural patch names: the one whose id the error message quotes. */\nconst failingStage = (patches: readonly GraphPatch[], message: string): string | undefined =>\n patches.flatMap(idsOf).find((id) => message.includes(`\"${id}\"`));\n\nconst sameErrors = (a: Readonly<Record<string, string>>, b: Readonly<Record<string, string>>): boolean => {\n const keys = Object.keys(a);\n return keys.length === Object.keys(b).length && keys.every((k) => a[k] === b[k]);\n};\n\n/** Applies the param writes together; when that throws, one by one, to name the stage that failed. */\nfunction applySets(graph: AudioGraph, sets: readonly GraphPatch[], failures: Record<string, string>): void {\n if (sets.length === 0) return;\n try {\n graph.apply(sets);\n } catch (err) {\n console.warn(`@weasel-js/diagram: audio graph edit failed: ${messageOf(err)}`);\n for (const p of sets) {\n try {\n graph.apply([p]);\n } catch (one) {\n if (p.kind === 'set') failures[p.id] = messageOf(one);\n break;\n }\n }\n }\n}\n\n/** A runner over `opts.pipeline` holding a fresh graph on `opts.engine`, not playing. */\nexport function createLiveAudioRunner(opts: LiveAudioRunnerOptions): LiveAudioRunner {\n const { engine, bus } = opts;\n const nodes = opts.nodes ?? audioStageNodes;\n let pipeline = opts.pipeline;\n let sources: AudioSources = opts.sources ?? {};\n let graph: AudioGraph = engine.graph(bus);\n let plan: LivePlan = EMPTY_PLAN;\n let errors: Readonly<Record<string, string>> = {};\n let state: LiveAudioRunnerState = { run: { stages: {} }, playing: false };\n let disposed = false;\n const listeners = new Set<() => void>();\n const previews = createLivePreviews();\n\n const set = (next: Partial<LiveAudioRunnerState>) => {\n const merged = { ...state, ...next };\n if (merged.run === state.run && merged.playing === state.playing) return;\n if (merged.run !== state.run && merged.run !== undefined) previews.track(merged.run);\n state = merged;\n for (const l of [...listeners]) l();\n };\n const publishErrors = (next: Readonly<Record<string, string>>) => {\n if (sameErrors(errors, next)) return;\n errors = next;\n set({ run: errorsRun(next) });\n };\n\n /** Brings the graph from `from` to the plan `pipeline` and `sources` now give. Structure goes first\n * in its own apply: a throw there changed nothing, while a throw from the sets means structure landed. */\n const sync = (from: LivePlan) => {\n const next = livePlan(pipeline, nodes, sources);\n const merged: Record<string, string> = { ...next.errors };\n let adopted = next;\n let structural: GraphPatch[] = [];\n let removed: string[] = [];\n let sets: GraphPatch[] = [];\n try {\n const patches = diffPlans(from, next, (_id, n) => nodes[n.type]!.build(engine.context, n.settings, n.levels));\n structural = patches.filter((p) => p.kind !== 'set');\n sets = patches.filter((p) => p.kind === 'set');\n if (structural.length > 0) graph.apply(structural);\n removed = structural.flatMap((p) => (p.kind === 'remove' ? [p.id] : []));\n } catch (err) {\n const message = messageOf(err);\n const id = failingStage(structural, message);\n if (id !== undefined) merged[id] = message;\n console.warn(`@weasel-js/diagram: audio graph edit failed: ${message}`);\n adopted = from;\n sets = [];\n }\n applySets(graph, sets, merged);\n plan = adopted;\n previews.follow(graph, removed, Object.keys(adopted.nodes));\n publishErrors(merged);\n };\n\n sync(EMPTY_PLAN);\n\n return {\n get state() { return state; },\n setPipeline(next) {\n if (disposed) return;\n pipeline = next;\n sync(plan);\n },\n setSources(next) {\n if (disposed) return;\n sources = next;\n sync(plan);\n },\n async play() {\n if (disposed) return;\n await engine.unlock();\n if (disposed) return;\n graph.start();\n set({ playing: true });\n },\n pause() {\n if (disposed) return;\n graph.stop();\n set({ playing: false });\n },\n setPreviews(mode) {\n if (disposed) return;\n previews.setMode(mode, graph, Object.keys(plan.nodes));\n if (mode === 'off') set({ run: errorsRun(errors) });\n },\n frame() {\n if (disposed) return;\n const run = previews.draw(errors);\n if (run !== undefined) set({ run });\n },\n drawn: previews.drawn,\n reset() {\n if (disposed) return;\n graph.dispose();\n graph = engine.graph(bus);\n previews.restart();\n sync(EMPTY_PLAN);\n set({ playing: false });\n },\n subscribe(listener) {\n listeners.add(listener);\n return () => { listeners.delete(listener); };\n },\n dispose() {\n if (disposed) return;\n disposed = true;\n previews.dispose();\n graph.dispose();\n },\n };\n}\n","import { formatParam, type EffectStageType } from '../stageTypes';\nimport type { EffectParam, EffectParamControl, EffectPort } from '../types';\n\nconst param = (id: string, control: EffectParamControl): EffectParam => ({ id, label: id, value: formatParam(control), control });\n\nconst amount = (value: number, min: number, max: number, step: number, unit?: string): EffectParamControl =>\n ({ kind: 'number', value, min, max, step, ...(unit !== undefined ? { unit } : {}) });\n\nconst choice = (value: string, ...options: string[]): EffectParamControl =>\n ({ kind: 'enum', value, options: options.map((o) => ({ value: o, label: o[0]!.toUpperCase() + o.slice(1) })) });\n\nconst port = (id: string): EffectPort => ({ id, type: 'audio' });\n/** Every audio input sums whatever is wired into it. */\nconst input = (id: string): EffectPort => ({ ...port(id), many: true });\nconst IN = [input('in')];\nconst OUT = [port('out')];\n\n/** Stage types over audio, each with a graph node in `audioStageNodes` except\n * `audio.output`, which is the graph's own output. Every `type` is prefixed\n * because `IMAGE_STAGE_TYPES` already has an `oscillator`. */\nexport const AUDIO_STAGE_TYPES: readonly EffectStageType[] = [\n { type: 'audio.file', title: 'File', kind: 'source', outputs: OUT },\n {\n type: 'audio.oscillator', title: 'Oscillator', kind: 'source', outputs: OUT,\n params: [\n param('wave', choice('sine', 'sine', 'square', 'sawtooth', 'triangle')),\n param('frequency', amount(440, 20, 20000, 1, 'Hz')),\n ],\n },\n {\n type: 'audio.noise', title: 'Noise', kind: 'source', outputs: OUT,\n params: [param('color', choice('white', 'white', 'pink', 'brown'))],\n },\n { type: 'audio.gain', title: 'Gain', inputs: IN, outputs: OUT, params: [param('gain', amount(1, 0, 2, 0.01))] },\n { type: 'audio.pan', title: 'Pan', inputs: IN, outputs: OUT, params: [param('pan', amount(0, -1, 1, 0.01))] },\n {\n type: 'audio.filter', title: 'Filter', inputs: IN, outputs: OUT,\n params: [\n param('type', choice('lowpass', 'lowpass', 'highpass', 'bandpass')),\n param('frequency', amount(1000, 20, 20000, 1, 'Hz')),\n param('Q', amount(1, 0.1, 20, 0.1)),\n ],\n },\n {\n type: 'audio.delay', title: 'Delay', inputs: IN, outputs: OUT,\n params: [\n param('time', amount(300, 0, 2000, 10, 'ms')),\n param('feedback', amount(0.4, 0, 0.95, 0.01)),\n param('mix', amount(0.5, 0, 1, 0.01)),\n ],\n },\n {\n type: 'audio.reverb', title: 'Reverb', inputs: IN, outputs: OUT,\n params: [param('seconds', amount(2, 0.1, 10, 0.1, 's')), param('mix', amount(0.3, 0, 1, 0.01))],\n },\n {\n type: 'audio.compressor', title: 'Compressor', inputs: IN, outputs: OUT,\n params: [param('threshold', amount(-24, -60, 0, 1, 'dB')), param('ratio', amount(4, 1, 20, 0.5))],\n },\n {\n type: 'audio.mix', title: 'Mix', inputs: [input('a'), input('b')], outputs: OUT,\n params: [param('a', amount(1, 0, 2, 0.01)), param('b', amount(1, 0, 2, 0.01))],\n },\n { type: 'audio.output', title: 'Output', kind: 'sink', inputs: IN },\n];\n","import { useEffect, useMemo, useSyncExternalStore } from 'react';\nimport { useVisibleRaf, type VisibleRafOptions } from '@weasel-js/react';\nimport type { EffectPipeline } from '../types';\nimport type { LiveAudioRunner, LiveAudioRunnerState } from './liveRunner';\nimport { errorsRun } from './livePreviews';\nimport { audioStageNodes, type AudioSources, type AudioStageNodes } from './nodes';\nimport { livePlan } from './plan';\nimport type { AudioPreview } from './scope';\n\n/** What `useFollowAudioRunner` keeps a runner following, and how its preview loop is gated. */\nexport interface FollowAudioRunnerOptions extends Pick<VisibleRafOptions, 'target' | 'requestFrame' | 'cancelFrame'> {\n pipeline: EffectPipeline;\n sources?: AudioSources;\n previews: AudioPreview;\n /** The nodes the plan is read with while there is no runner. */\n nodes?: AudioStageNodes;\n}\n\nconst noSubscribe = () => () => {};\n\n/**\n * Keeps a caller-owned `runner` following `pipeline`, `sources` and `previews`, draws its previews every\n * visible frame while it plays, and closes the bitmaps of runs no render shows. While `runner` is null,\n * the run holds the plan's errors, so a stage that cannot play says why before any engine exists.\n */\nexport function useFollowAudioRunner(runner: LiveAudioRunner | null, opts: FollowAudioRunnerOptions): LiveAudioRunnerState {\n const { pipeline, sources, previews, nodes, target, requestFrame, cancelFrame } = opts;\n useEffect(() => { runner?.setPipeline(pipeline); }, [runner, pipeline]);\n useEffect(() => { if (sources !== undefined) runner?.setSources(sources); }, [runner, sources]);\n useEffect(() => { runner?.setPreviews(previews); }, [runner, previews]);\n const live = useSyncExternalStore(runner?.subscribe ?? noSubscribe, () => runner?.state ?? null);\n const planned = useMemo(\n () => (runner !== null ? undefined : errorsRun(livePlan(pipeline, nodes ?? audioStageNodes, sources ?? {}).errors)),\n [runner, pipeline, nodes, sources],\n );\n const playing = live?.playing ?? false;\n\n const loop = useVisibleRaf((_now, self) => {\n if (runner === null || !runner.state.playing || previews === 'off') return;\n runner.frame();\n self.request();\n }, {\n ...(target !== undefined ? { target } : {}),\n ...(requestFrame !== undefined ? { requestFrame } : {}),\n ...(cancelFrame !== undefined ? { cancelFrame } : {}),\n });\n useEffect(() => {\n if (playing && previews !== 'off') loop.request();\n else loop.cancel();\n }, [playing, previews, loop]);\n\n useEffect(() => { runner?.drawn(live?.run); }, [runner, live?.run]);\n return live ?? { run: planned, playing: false };\n}\n","import { useEffect, useState } from 'react';\nimport { useLatest, useStableByContent } from '@weasel-js/react';\nimport { createLiveAudioRunner, type LiveAudioRunner, type LiveAudioRunnerOptions, type LiveAudioRunnerState } from './liveRunner';\nimport type { AudioStageNodes } from './nodes';\nimport { useFollowAudioRunner, type FollowAudioRunnerOptions } from './useFollowAudioRunner';\n\n/** Options for `useLiveAudioRunner`: the runner's, which it follows as they change, and how its preview loop is gated. */\nexport interface UseLiveAudioRunnerOptions\n extends LiveAudioRunnerOptions, Pick<FollowAudioRunnerOptions, 'previews' | 'target' | 'requestFrame' | 'cancelFrame'> {}\n\n/** What `useLiveAudioRunner` returns: the runner's state, and the runner to drive, null until it mounts. */\nexport interface LiveAudioRunnerHandle extends LiveAudioRunnerState {\n runner: LiveAudioRunner | null;\n}\n\n/**\n * A runner made on mount and remade when `engine`, `bus` or `nodes` change, following `pipeline`,\n * `sources` and `previews` through `useFollowAudioRunner`, and disposed on unmount. Before the first\n * mount the runner is null and the run holds the plan's errors. The engine is the caller's. `nodes`\n * counts as changed only when a type is added, dropped or given a different node, so it can be built in render.\n */\nexport function useLiveAudioRunner(opts: UseLiveAudioRunnerOptions): LiveAudioRunnerHandle {\n const { engine, bus } = opts;\n const nodes = useStableByContent(opts.nodes, sameNodes);\n const latest = useLatest(opts);\n const [runner, setRunner] = useState<LiveAudioRunner | null>(null);\n useEffect(() => {\n const { pipeline, sources } = latest.current;\n const made = createLiveAudioRunner({\n engine, pipeline,\n ...(nodes !== undefined ? { nodes } : {}),\n ...(sources !== undefined ? { sources } : {}),\n ...(bus !== undefined ? { bus } : {}),\n });\n // eslint-disable-next-line react-hooks/set-state-in-effect -- publishes the runner this effect creates\n setRunner(made);\n return () => made.dispose();\n }, [engine, bus, nodes, latest]);\n const state = useFollowAudioRunner(runner, { ...opts, ...(nodes !== undefined ? { nodes } : {}) });\n return { ...state, runner };\n}\n\nfunction sameNodes(a: AudioStageNodes | undefined, b: AudioStageNodes | undefined): boolean {\n if (a === undefined || b === undefined) return a === b;\n const keys = Object.keys(a);\n return keys.length === Object.keys(b).length && keys.every((k) => Object.hasOwn(b, k) && a[k] === b[k]);\n}\n"]}
package/dist/effect.d.ts CHANGED
@@ -1,10 +1,12 @@
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-DW-MljuN.js';
4
- import { a as Row, M as MeasureRowText } from './types-vbW21fHm.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-UiO25hcn.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-UiO25hcn.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-BIkhAOc4.js';
4
+ import { a as Row, M as MeasureRowText } from './types-B0n2CNTW.js';
5
5
  import * as react from 'react';
6
6
  import { Paint } from '@weasel-js/core';
7
7
  import { Vec2 } from '@weasel-js/core/math';
8
+ import { D as DiagramLabel } from './labelTrait-BBjRgxbz.js';
9
+ import { ClockHandle } from '@weasel-js/clock';
8
10
  import { VisibleRafOptions } from '@weasel-js/react';
9
11
  import '@weasel-js/geom';
10
12
 
@@ -190,9 +192,14 @@ declare function wireEdges(pipeline: EffectPipeline, color: TypeColor): {
190
192
  type BranchNode = Pick<DataNode, 'outline' | 'lines' | 'rows' | 'ports' | 'marks' | 'width' | 'height' | 'padding'>;
191
193
  /** How a look wants a branch symbol drawn. */
192
194
  interface BranchOptions {
195
+ /** Which way the signal runs through the symbol: in on the left and out on
196
+ * the right, or, for `'down'`, in at the top and out at the bottom. Default `'right'`. */
197
+ direction?: 'right' | 'down';
193
198
  /** The edge control inputs enter by: the side the stages driving them sit
194
- * on. Default `'top'`. */
195
- controlSide?: 'top' | 'bottom';
199
+ * on, `'top'` or `'bottom'` along a row and `'left'` or `'right'` down a
200
+ * column. A side the signal runs through counts as the default, `'top'`
201
+ * along a row and `'left'` down a column. */
202
+ controlSide?: 'top' | 'bottom' | 'left' | 'right';
196
203
  /** The style the look draws the stage's node in: lines, dots and ticks
197
204
  * take its `text` color. Default `stageStyle(stage)`. */
198
205
  style?: NodeStyle;
@@ -346,7 +353,13 @@ declare const nodeGraph: EffectLook<NodeGraphOptions>;
346
353
  interface RackOptions extends RunRowOptions, LookThemeOptions {
347
354
  /** The stage ids on the line, in order. Default the longest path over data wires. */
348
355
  chain?: readonly string[];
349
- /** Where what feeds the chain from the side sits. Default `'below'`. */
356
+ /** Which way the main signal runs: `'right'` (default) along a row, or
357
+ * `'down'` as a column, entering each stage at its top and leaving at its
358
+ * bottom. */
359
+ direction?: 'right' | 'down';
360
+ /** Where what feeds the chain from the side sits. Default `'below'`. Under
361
+ * `direction: 'down'`, `'below'` hangs it on the right of the column and
362
+ * `'above'` on the left. */
350
363
  side?: 'below' | 'above';
351
364
  nodeGap?: number;
352
365
  rankGap?: number;
@@ -423,8 +436,9 @@ interface EffectEditorBaseProps {
423
436
  run?: EffectRun;
424
437
  /** A stage id, or null for none. */
425
438
  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;
439
+ /** Hears each pick: a stage's id, or `null` for anything else, a wire included; and every stage and group
440
+ * picked, in the order they were, for `EffectEditorApi.group`. Shift-click adds one, or takes it out. */
441
+ onSelect?: (stage: string | null, picked: readonly string[]) => void;
428
442
  /** A group id, or null for none: drawn picked while no stage is. */
429
443
  selectedGroup?: string | null;
430
444
  /** Hears each pick: a group's id, or `null` for anything else. */
@@ -432,6 +446,13 @@ interface EffectEditorBaseProps {
432
446
  /** CSS pixels. Omit both to fill the parent. */
433
447
  width?: number;
434
448
  height?: number;
449
+ /** The largest scale the fit may use, as `DiagramView`'s. Default 1; raise it to zoom a small
450
+ * pipeline up to fill its box. */
451
+ maxScale?: number;
452
+ /** Keep the view on the pipeline, as `DiagramView`'s `bounded` does. */
453
+ bounded?: boolean;
454
+ /** When a changed doc refits the view, as `DiagramView`'s `refit`. */
455
+ refit?: 'overflow' | 'always';
435
456
  background?: Paint;
436
457
  className?: string;
437
458
  }
@@ -467,7 +488,8 @@ interface EffectEditorApi {
467
488
  * title renames it; under `lanes` a lane drags by its header. A selected
468
489
  * wire's route drags under every look: into `routes` under `nodeGraph`, and
469
490
  * 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,
491
+ * ends stay put. A selected wire's label drags under every look into
492
+ * `labels`, and stays where it was put whatever the look. Every edit is a doc handed to `onChange`. Text paints only in a registered font family,
471
493
  * as with `EffectChart`. */
472
494
  declare const EffectEditor: react.ForwardRefExoticComponent<EffectEditorProps & react.RefAttributes<EffectEditorApi>>;
473
495
 
@@ -478,10 +500,6 @@ declare const EffectEditor: react.ForwardRefExoticComponent<EffectEditorProps &
478
500
  /** The action that drags a lane to another place among the lanes. */
479
501
  declare const REORDER_LANES_ACTION_ID = "diagram.reorderLanes";
480
502
 
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
503
  /** The looks whose routes `lookRoutes` keeps. */
486
504
  type RoutedLook = keyof LookRoutes;
487
505
  /** Routes wire `wire` through `waypoints` under `look`, for as long as its
@@ -513,6 +531,8 @@ declare function addStage(doc: EffectDoc, stage: EffectStage, at?: Vec2): Effect
513
531
  /** Drops the stages with their wires, places, routes and group memberships,
514
532
  * and any group that leaves empty, with its box. */
515
533
  declare function removeStages(doc: EffectDoc, ids: readonly string[]): EffectDoc;
534
+ /** Puts wire `wire`'s label at `placement`; `null` gives it back to the look. */
535
+ declare function setWireLabel(doc: EffectDoc, wire: string, placement: DiagramLabel | null): EffectDoc;
516
536
  /** Routes wire `wire` through `points`; none clears its route. */
517
537
  declare function setWireRoute(doc: EffectDoc, wire: string, points: readonly Vec2[]): EffectDoc;
518
538
  /** Mints an id when the wire has none. */
@@ -747,6 +767,10 @@ interface EffectRunner {
747
767
  /** Moves the play clock on by `seconds` while playing, and starts a run
748
768
  * unless one is still going. A frame source calls it once a frame. */
749
769
  advance(seconds: number): void;
770
+ /** Moves the play clock to `seconds`, playing or not, and starts a run at
771
+ * it; while one is still going, one more follows it at the latest time. A
772
+ * clock that can be scrubbed calls it on every frame it moves. */
773
+ seek(seconds: number): void;
750
774
  /** The next run, step, or played frame follows `pipeline`. A step run under
751
775
  * way starts over. */
752
776
  setPipeline(pipeline: EffectPipeline): void;
@@ -765,6 +789,12 @@ declare function createEffectRunner(opts: EffectRunnerOptions): EffectRunner;
765
789
  /** Options for `useEffectRunner`: the runner's, which it follows as they
766
790
  * change, and how its play loop is gated and clocked. */
767
791
  interface UseEffectRunnerOptions extends EffectRunnerOptions, Pick<VisibleRafOptions, 'target' | 'requestFrame' | 'cancelFrame'> {
792
+ /** A clock to play on instead of a frame loop of its own: the play time is
793
+ * its `elapsed`, so its rate, seeks and visibility gate move the runner,
794
+ * and its host's `useClockLoop` syncs it. The runner plays while the clock
795
+ * does, and `play` and `pause` set the clock's rate. `target`,
796
+ * `requestFrame` and `cancelFrame` then go unused. */
797
+ clock?: ClockHandle;
768
798
  }
769
799
  /** What `useEffectRunner` returns: the runner's state, and the runner to drive. */
770
800
  interface EffectRunnerHandle extends EffectRunnerState {
@@ -775,8 +805,8 @@ interface EffectRunnerHandle extends EffectRunnerState {
775
805
  * advances its clock by the time since the last and starts a run once the last
776
806
  * has finished; time spent hidden does not count. Each run it hands back is
777
807
  * taken as drawn after the render that shows it, so the previews of the runs
778
- * before it are closed then.
808
+ * before it are closed then. Given a `clock`, it plays on that instead.
779
809
  */
780
810
  declare function useEffectRunner(opts: UseEffectRunnerOptions): EffectRunnerHandle;
781
811
 
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 };
812
+ 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, setWireLabel, setWireRoute, shownPorts, stageRows, stageStyle, symbolNameFor, testCard, typeColors, ungroup, uniqueGroups, uniqueStages, useEffectRunner, valueRowId, wireEdges, wireEnds, wireStyle };