@msb235/blits 0.14.0 → 0.15.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.
Files changed (187) hide show
  1. package/CHANGELOG.md +198 -0
  2. package/README.md +3 -3
  3. package/dist/ahead.d.ts +26 -0
  4. package/dist/ahead.js +264 -0
  5. package/dist/around.d.ts +11 -0
  6. package/dist/around.js +32 -0
  7. package/dist/bare.js +37 -14
  8. package/dist/blank.d.ts +10 -0
  9. package/dist/blank.js +26 -0
  10. package/dist/blend.d.ts +2 -1
  11. package/dist/blend.js +1 -6
  12. package/dist/bound.d.ts +70 -0
  13. package/dist/bound.js +351 -0
  14. package/dist/chain.d.ts +2 -1
  15. package/dist/chain.js +7 -5
  16. package/dist/changes.d.ts +24 -0
  17. package/dist/changes.js +189 -0
  18. package/dist/channels.d.ts +39 -13
  19. package/dist/channels.js +14 -5
  20. package/dist/color.d.ts +12 -10
  21. package/dist/color.js +25 -25
  22. package/dist/columns.d.ts +2 -1
  23. package/dist/columns.js +62 -38
  24. package/dist/contribution.d.ts +30 -0
  25. package/dist/contribution.js +374 -0
  26. package/dist/copyout.d.ts +10 -0
  27. package/dist/copyout.js +69 -24
  28. package/dist/crowd.d.ts +16 -6
  29. package/dist/crowd.js +20 -11
  30. package/dist/cue.d.ts +8 -1
  31. package/dist/cue.js +39 -13
  32. package/dist/cut.d.ts +8 -0
  33. package/dist/cut.js +4 -0
  34. package/dist/delay.d.ts +3 -0
  35. package/dist/delay.js +7 -0
  36. package/dist/drop.d.ts +9 -0
  37. package/dist/drop.js +84 -0
  38. package/dist/due.d.ts +24 -5
  39. package/dist/due.js +114 -34
  40. package/dist/easing.d.ts +6 -4
  41. package/dist/easing.js +7 -3
  42. package/dist/everyone.d.ts +8 -2
  43. package/dist/everyone.js +33 -3
  44. package/dist/fade.d.ts +2 -1
  45. package/dist/fade.js +2 -1
  46. package/dist/fill.d.ts +3 -2
  47. package/dist/fill.js +52 -20
  48. package/dist/fit.d.ts +44 -26
  49. package/dist/fit.js +10 -9
  50. package/dist/fold.d.ts +4 -37
  51. package/dist/fold.js +5 -513
  52. package/dist/gather.d.ts +12 -7
  53. package/dist/gather.js +179 -44
  54. package/dist/gone.js +2 -2
  55. package/dist/grid.d.ts +47 -0
  56. package/dist/grid.js +247 -0
  57. package/dist/handle.d.ts +2 -0
  58. package/dist/handle.js +14 -8
  59. package/dist/held.d.ts +2 -1
  60. package/dist/held.js +2 -1
  61. package/dist/history.d.ts +6 -5
  62. package/dist/history.js +7 -9
  63. package/dist/hosts.js +9 -15
  64. package/dist/index.d.ts +5 -4
  65. package/dist/keyfill.d.ts +1 -1
  66. package/dist/keyfill.js +5 -3
  67. package/dist/keyrows.d.ts +12 -0
  68. package/dist/keyrows.js +99 -12
  69. package/dist/lane.d.ts +38 -11
  70. package/dist/lane.js +46 -11
  71. package/dist/lanes.d.ts +30 -12
  72. package/dist/lanes.js +56 -36
  73. package/dist/leavings.d.ts +2 -2
  74. package/dist/leavings.js +1 -1
  75. package/dist/lives.d.ts +47 -0
  76. package/dist/lives.js +180 -0
  77. package/dist/meet.d.ts +2 -2
  78. package/dist/meet.js +95 -7
  79. package/dist/mixer.d.ts +56 -37
  80. package/dist/mixer.js +57 -171
  81. package/dist/motion.d.ts +14 -118
  82. package/dist/motion.js +16 -8
  83. package/dist/motions.d.ts +62 -155
  84. package/dist/motions.js +56 -370
  85. package/dist/moved.d.ts +1 -1
  86. package/dist/moved.js +16 -7
  87. package/dist/named.d.ts +6 -2
  88. package/dist/named.js +49 -3
  89. package/dist/numbers.d.ts +7 -0
  90. package/dist/numbers.js +33 -0
  91. package/dist/owed.d.ts +2 -0
  92. package/dist/owed.js +4 -0
  93. package/dist/pack.d.ts +2 -1
  94. package/dist/pack.js +2 -3
  95. package/dist/patch.d.ts +7 -3
  96. package/dist/patch.js +6 -2
  97. package/dist/places.d.ts +53 -0
  98. package/dist/places.js +171 -0
  99. package/dist/plot.d.ts +12 -0
  100. package/dist/plot.js +52 -0
  101. package/dist/project.d.ts +4 -4
  102. package/dist/project.js +9 -212
  103. package/dist/pull.js +22 -9
  104. package/dist/qualify.js +93 -31
  105. package/dist/reading.d.ts +6 -0
  106. package/dist/reading.js +5 -0
  107. package/dist/record.d.ts +5 -1
  108. package/dist/record.js +3 -2
  109. package/dist/relink.d.ts +1 -1
  110. package/dist/renumber.d.ts +10 -0
  111. package/dist/renumber.js +75 -0
  112. package/dist/restored.d.ts +2 -2
  113. package/dist/restored.js +1 -1
  114. package/dist/rests.d.ts +9 -0
  115. package/dist/rests.js +76 -0
  116. package/dist/revive.d.ts +3 -2
  117. package/dist/revive.js +2 -2
  118. package/dist/{locus.d.ts → role.d.ts} +10 -9
  119. package/dist/{locus.js → role.js} +3 -3
  120. package/dist/roles.d.ts +10 -0
  121. package/dist/roles.js +158 -0
  122. package/dist/roster.js +3 -3
  123. package/dist/rotation.d.ts +1 -1
  124. package/dist/rotation.js +1 -1
  125. package/dist/rows.js +28 -20
  126. package/dist/sample.d.ts +2 -2
  127. package/dist/sample.js +33 -7
  128. package/dist/seat.d.ts +17 -0
  129. package/dist/seat.js +25 -0
  130. package/dist/seek.js +5 -5
  131. package/dist/setting.d.ts +27 -0
  132. package/dist/setting.js +55 -0
  133. package/dist/shared.d.ts +1 -1
  134. package/dist/shared.js +1 -1
  135. package/dist/signals.d.ts +64 -32
  136. package/dist/signals.js +20 -18
  137. package/dist/stack.d.ts +5 -5
  138. package/dist/stack.js +5 -5
  139. package/dist/standing.d.ts +2 -1
  140. package/dist/standing.js +3 -2
  141. package/dist/store.d.ts +9 -0
  142. package/dist/store.js +24 -0
  143. package/dist/strays.d.ts +2 -1
  144. package/dist/strays.js +23 -15
  145. package/dist/stretch.d.ts +112 -0
  146. package/dist/stretch.js +9 -0
  147. package/dist/subject.d.ts +142 -0
  148. package/dist/subject.js +1 -0
  149. package/dist/tape.d.ts +9 -5
  150. package/dist/tape.js +5 -1
  151. package/dist/then.d.ts +9 -0
  152. package/dist/then.js +57 -0
  153. package/dist/ticker.d.ts +4 -4
  154. package/dist/trace.d.ts +4 -0
  155. package/dist/trace.js +255 -0
  156. package/dist/transport.d.ts +0 -8
  157. package/dist/transport.js +0 -4
  158. package/dist/turns.d.ts +4 -3
  159. package/dist/turns.js +4 -3
  160. package/dist/types/arc.d.ts +12 -11
  161. package/dist/types/channel.d.ts +12 -8
  162. package/dist/types/history.d.ts +35 -19
  163. package/dist/types/mix.d.ts +237 -163
  164. package/dist/types/motion.d.ts +151 -0
  165. package/dist/types/motion.js +1 -0
  166. package/dist/types/patch.d.ts +67 -34
  167. package/dist/types/place.d.ts +51 -36
  168. package/dist/types/trace.d.ts +51 -0
  169. package/dist/types/trace.js +1 -0
  170. package/dist/types/transport.d.ts +20 -18
  171. package/dist/types/voice.d.ts +144 -73
  172. package/dist/types/watch.d.ts +88 -40
  173. package/dist/types.d.ts +2 -0
  174. package/dist/unreached.d.ts +2 -0
  175. package/dist/unreached.js +7 -0
  176. package/dist/voice.d.ts +10 -143
  177. package/dist/voice.js +37 -82
  178. package/dist/warn.d.ts +2 -0
  179. package/dist/warn.js +1 -1
  180. package/dist/watch.d.ts +2 -2
  181. package/dist/watch.js +5 -3
  182. package/dist/wave.d.ts +4 -3
  183. package/dist/wave.js +3 -2
  184. package/dist/weigh.d.ts +7 -1
  185. package/dist/weigh.js +27 -0
  186. package/docs/schema.html +223 -34
  187. package/package.json +2 -2
@@ -1,18 +1,19 @@
1
1
  import type { ArcHandle, ArcSpec } from './arc.js';
2
2
  import type { Kit } from './channel.js';
3
3
  import type { HistoryOptions, Tape } from './history.js';
4
- import type { Patch, Sent, Signal } from './patch.js';
4
+ import type { Band, Easing, Patch, Sent, Signal } from './patch.js';
5
5
  import type { Booker, BookOptions, Marked } from './place.js';
6
+ import type { Trace, TraceOptions } from './trace.js';
6
7
  import type { Transport } from './transport.js';
7
- import type { BlendMember, Handle, OwnerSpec, SpanHandle, SpanSpec, VoiceSpec } from './voice.js';
8
+ import type { BlendMember, Circle, Handle, OwnerSpec, SpanHandle, SpanSpec, VoiceSpec } from './voice.js';
8
9
  /**
9
- * How a mix is built: its engine, reduced motion, the host, and its limits.
10
+ * How a mix is built. It names the engine, reduced motion, the host, and the mix's limits.
10
11
  *
11
12
  * @category mix
12
13
  */
13
14
  export interface MixOptions<H = unknown> {
14
15
  engine?: Engine;
15
- /** Reduced motion: fades and warm-ups snap, `dt` reads Infinity. */
16
+ /** Whether motion is reduced. Fades and warm-ups then snap, and `dt` reads Infinity. */
16
17
  reduce?: boolean | (() => boolean);
17
18
  /** Merged into every `setting.host`. Its type is the mix's `H`, which every patch and signal it cues reads. */
18
19
  host?: H;
@@ -20,14 +21,13 @@ export interface MixOptions<H = unknown> {
20
21
  * The band a rest-less channel's contribution switches on and off across. Default: on at any weight
21
22
  * above 0, off at 0, so the contribution passes whole while its voice has any weight.
22
23
  */
23
- band?: {
24
- on: number;
25
- off: number;
26
- };
24
+ band?: Band;
27
25
  /**
28
- * Tags that act as loci: a voice carrying one folds with the others carrying it, as if its `locus`
29
- * named that tag.
26
+ * Tags that act as roles. A voice carrying one folds with the others carrying it, as if its
27
+ * `role` named that tag.
30
28
  */
29
+ roles?: readonly string[];
30
+ /** @deprecated Renamed `roles`. Taken as `roles`, with a warning outside production. */
31
31
  loci?: readonly string[];
32
32
  /**
33
33
  * The most `dt` a `step` or signal is handed, however long the gap. Off by default, since a
@@ -35,48 +35,49 @@ export interface MixOptions<H = unknown> {
35
35
  */
36
36
  maxDt?: number;
37
37
  /**
38
- * Run every `step` at this fixed interval, ms, instead of once by the frame's gap, so stateful
39
- * patches play the same at any frame rate. Intervals count from when a subject's delay ran out,
40
- * the remainder carrying to the next sample; `maxDt` then caps how many one sample may run.
41
- * Signals and `at` still see the frame. Off by default.
38
+ * A fixed interval, ms, to run every `step` at. Without it each `step` runs once by the frame's
39
+ * gap; with it stateful patches play the same at any frame rate. Intervals count from when a
40
+ * subject's delay ran out, the remainder carrying to the next sample; `maxDt` then caps how many
41
+ * one sample may run. Signals and `at` still see the frame. Off by default.
42
42
  */
43
43
  stepMs?: number;
44
44
  /**
45
- * How far back `project` may read, in ms of mix time, and how often a stateful voice's state is
46
- * kept per subject on the way, `every` ms (default 200). Within it the mix remembers what it cued,
47
- * every change a handle made and when, the voices that have left, and those copies of state, so a
48
- * read back restores the nearest copy and steps forward from it. Off by default, and a mix without
49
- * it keeps nothing. With `inputs`, it also keeps what each input signal on a voice's weight read
50
- * per subject, and the host fields patches `reads`, each time they changed, so a read back over a
45
+ * What the mix remembers so `project` and `seek` can read back. `ms` is how far back `project`
46
+ * may read, in ms of mix time, and `every` how often a stateful voice's state is kept per subject
47
+ * on the way, in ms (default 200). Within it the mix remembers what it cued, every change a
48
+ * handle made and when, the voices that have left, and those copies of state, so a read back
49
+ * restores the nearest copy and steps forward from it. Off by default, and a mix without it keeps
50
+ * nothing. With `inputs`, it also keeps what each input signal on a voice's weight read per
51
+ * subject, and the host fields patches `reads`, each time they changed, so a read back over a
51
52
  * `level` or a pointer is known rather than held. With `tape`, the mix also records every call
52
53
  * the host makes on it, its handles and its motion patches, so `seek` can move it and play those
53
54
  * calls again.
54
55
  */
55
56
  history?: HistoryOptions;
56
57
  /**
57
- * A subject's key, for a history `store`: unique among this mix's subjects for the session. A
58
- * string or number subject is its own key; with a store, an object subject needs this.
58
+ * A subject's key, for a history `store`. It is unique among this mix's subjects for the session.
59
+ * A string or number subject is its own key; with a store, an object subject needs this.
59
60
  */
60
61
  keyOf?(subject: never): string | number;
61
62
  /**
62
- * What a debugger calls a subject (see `watched`); where it gives nothing, the subject's own
63
- * `name` or `id`, a DOM element's tag, id and classes, or its class and a number.
63
+ * What a debugger calls a subject (see `watched`). Where it gives nothing, the debugger uses the
64
+ * subject's own `name` or `id`, a DOM element's tag, id and classes, or its class and a number.
64
65
  */
65
66
  labelOf?(subject: never): string | undefined;
66
67
  /**
67
- * Whether a channel may run as a lane: computed for every subject at once in flat arrays, when
68
- * every voice writing it can run that way. On by default; what a host reads is the same either
69
- * way (`probe`, `pull`, `atRest`, `weightOf`, `inert` and `project`), so turning it off is for
70
- * ruling a lane out, or for comparing against. A voice weighted by an input signal `input` did not
71
- * make, or whose patch reads host fields, never runs on a lane, since a change to either
72
- * between two probes would not reach it. Two things differ: a
73
- * stateless patch's `setting.send` from `at` sends for every subject a lane fills, those probed
74
- * this frame or the last, and a patch that first calls `setting.keep` partway through playing can
75
- * advance that state once more for one subject probed the frame before (see `Setting.keep`).
68
+ * Whether a channel may run as a lane. A lane computes every subject at once in flat arrays, when
69
+ * every voice writing the channel can run that way. On by default; what a host reads is the same
70
+ * either way (`probe`, `pull`, `atRest`, `weightOf`, `inert` and `project`), so turning it off is
71
+ * for ruling a lane out, or for comparing against. A voice weighted by an input signal `input`
72
+ * did not make, or whose patch reads host fields, never runs on a lane, since a change to either
73
+ * between two probes would not reach it. Two things differ: a stateless patch's `setting.send`
74
+ * from `at` sends for every subject a lane fills, those probed this frame or the last, and a
75
+ * patch that first calls `setting.keep` partway through playing can advance that state once more
76
+ * for one subject probed the frame before (see `Setting.keep`).
76
77
  */
77
78
  lanes?: boolean;
78
79
  /**
79
- * The transport this mix plays on, shared with other mixes, so they keep one clock and a query
80
+ * The transport this mix plays on, shared with other mixes. They then keep one clock, and a query
80
81
  * naming a score looks in all of them. The transport's `sync`, `rebase`, `rate`, `ramp` and
81
82
  * `seek` move it, and the mix's own throw. Its history is the transport's, so the mix takes no
82
83
  * `history` of its own.
@@ -86,17 +87,17 @@ export interface MixOptions<H = unknown> {
86
87
  name?: string;
87
88
  }
88
89
  /**
89
- * How sure a projection is of one channel: `exact` where only the clock and known changes drove
90
- * it; `stepped` where state was advanced across a gap in one go, which is as good as the patch's
91
- * step makes it, or a signal's state was read back from a copy; `held` where it depends on input from outside the clock, whose value at that time
92
- * is not known, so the value it had is held.
90
+ * How sure a projection is of one channel. It is `exact` where only the clock and known changes
91
+ * drove it; `stepped` where state was advanced across a gap in one go, which is as good as the
92
+ * patch's step makes it, or a signal's state was read back from a copy; `held` where it depends on
93
+ * input from outside the clock, whose value at that time is not known, so the value it had is held.
93
94
  *
94
95
  * @category mix
95
96
  */
96
97
  export type Doubt = 'exact' | 'stepped' | 'held';
97
98
  /**
98
- * The mix read at another time: what `probe` would give at that timestamp, with nothing in the
99
- * live mix moved. Valid until the mix is next synced or cued.
99
+ * The mix read at another time, with nothing in the live mix moved. It gives what `probe` would
100
+ * give at that timestamp. Valid until the mix is next synced or cued.
100
101
  *
101
102
  * @category mix
102
103
  */
@@ -105,14 +106,14 @@ export interface Projection<I, O> {
105
106
  readonly timestamp: number;
106
107
  /** The merged pose for one subject at this projection's timestamp. */
107
108
  probe(subject: I, out?: O): O;
108
- /** Per channel, how sure that pose is; the least sure voice that fed a channel decides. */
109
+ /** How sure that pose is, per channel. The least sure voice that fed a channel decides. */
109
110
  assess(subject: I): {
110
111
  [K in keyof O]-?: Doubt;
111
112
  };
112
113
  }
113
114
  /**
114
- * Arrays for `pull` to write, one per channel it reads: any channel whose value is a number or an
115
- * array of numbers.
115
+ * Arrays for `pull` to write, one per channel it reads. It reads any channel whose value is a
116
+ * number or an array of numbers.
116
117
  *
117
118
  * @category mix
118
119
  */
@@ -128,45 +129,45 @@ export interface Mix<I, O, H = unknown> {
128
129
  /** Cues a voice. Throws when the engine cannot run the patch's form, or the kit lacks a channel. */
129
130
  cue(spec: VoiceSpec<I, O, H>): Handle<I>;
130
131
  /**
131
- * N voices whose weights split one signal, cued into one locus so they fold as alternatives. The
132
- * signal is read once per subject per frame, with the first member's setting, and every member
133
- * takes its share of that one reading, which `share` reads outside the blend; a signal keeping
134
- * state keeps it once, not per member. One `spec` cues them all, and a member given as a
132
+ * Cues N voices into one role, their weights split from one signal. They fold as alternatives.
133
+ * The signal is read once per subject per frame, with the first member's setting, and every
134
+ * member takes its share of that one reading, which `share` reads outside the blend; a signal
135
+ * keeping state keeps it once, not per member. One `spec` cues them all, and a member given as a
135
136
  * `BlendMember` carries its own `name`, `tags` and `hits` in place of the spec's.
136
137
  */
137
- blend(members: readonly (Patch<I, O, any, H> | BlendMember<I, O, H>)[], by: Signal<I, H>, spec?: Omit<VoiceSpec<I, O, H>, 'patch' | 'weight' | 'locus'>): Handle<I>[];
138
+ blend(members: readonly (Patch<I, O, any, H> | BlendMember<I, O, H>)[], by: Signal<I, H>, spec?: Omit<VoiceSpec<I, O, H>, 'patch' | 'weight' | 'role' | 'locus' | 'within'>): Handle<I>[];
138
139
  /**
139
- * Cues an owner: a voice with no patch that holds the voices cued with `owner` set to its handle,
140
- * and plays them on its own clock, so they can be placed, timed and faded as one. Its handle acts
141
- * on all of them: `rate` and `ramp` multiply into theirs, `seek` moves their clocks with its own
142
- * and rebuilds their state as it does a voice's, and `weight` and `fade()` multiply into their weights, by
143
- * what its `weightOf` reports; it fades as a whole, not by subject or at rest. It is
144
- * `played` once every voice it held has finished its passes, and leaves, `done`, with its last; a
145
- * fade that ends takes the rest with it. One that never holds a voice stays until faded. Owners
146
- * nest. Throws for a `loop`: a pass would have to restart its children.
140
+ * Cues an owner, a voice with no patch that plays other voices on its own clock. It holds the
141
+ * voices cued with `owner` set to its handle, so they can be placed, timed and faded as one. Its
142
+ * handle acts on all of them: `rate` and `ramp` multiply into theirs, `seek` moves their clocks
143
+ * with its own and rebuilds their state as it does a voice's, and `weight` and `fade()` multiply
144
+ * into their weights, by what its `weightOf` reports; it fades as a whole, not by subject or at
145
+ * rest. It is `played` once every voice it held has finished its passes, and leaves, `done`, with
146
+ * its last; a fade that ends takes the rest with it. One that never holds a voice stays until
147
+ * faded. Owners nest. Throws for a `loop`: a pass would have to restart its children.
147
148
  */
148
149
  owns(spec: OwnerSpec<I, H>): Handle<I>;
149
150
  /**
150
- * Cues a span: an owner that lays out the voices it holds in `order` and fits them into its
151
- * `duration`, again each time one joins or leaves early. A child's start and rate are the
152
- * span's to set, so it takes neither `start` nor an anchored start; its `SpanHints` say how it
153
- * may give way. A span with a budget stays until the budget has passed, though its children
154
- * finish sooner, so late ones can still join, and its `end` mark is where its children end or
155
- * its budget does, whichever is later. A voice that loops for good cannot join one. Throws for
156
- * a `rate` below 0: a span lays its children out forward from its start, and its handle's `rate`
157
- * turns it once it plays.
151
+ * Cues a span, an owner that fits the voices it holds into its `duration`. It lays them out in
152
+ * `order`, again each time one joins or leaves early. A child's start and rate are the span's to
153
+ * set, so it takes neither `start` nor an anchored start; its `SpanHints` say how it may give
154
+ * way. A span with a budget stays until the budget has passed, though its children finish sooner,
155
+ * so late ones can still join, and its `end` mark is where its children end or its budget does,
156
+ * whichever is later. A voice that loops for good cannot join one. Throws for a `rate` below 0: a
157
+ * span lays its children out forward from its start, and its handle's `rate` turns it once it
158
+ * plays.
158
159
  */
159
160
  span(spec: SpanSpec<I, H>): SpanHandle<I>;
160
161
  /**
161
- * Cues an arc: an owner holding three parts that hand over in order on its clock, `enter`, then
162
- * `active` for the `hold`, then `exit`, each a voice or several layered. Its marks are its own:
163
- * `start` as the enter begins, `in` as it ends, `coast` as the hold ends and `out` as the exit
164
- * begins, which are one time, and `end` as the exit ends, where it leaves and `done` resolves.
165
- * While the hold is open, `coast`, `out` and `end` are unknown until `release` fixes them. Each
166
- * part shows its first and last frames through the blends either side of it, and a part left
167
- * out leaves its time to the one before it. Its `fade` takes it out with no exit. An arc with a
168
- * finite hold may sit in a span. Throws for a `rate` below 0, a hold below 0, and an `enter` or
169
- * `exit` that never ends.
162
+ * Cues an arc, an owner holding three parts that hand over in order. On its clock `enter` plays,
163
+ * then `active` for the `hold`, then `exit`, each a voice or several layered. Its marks are its
164
+ * own: `start` as the enter begins, `in` as it ends, `coast` as the hold ends and `out` as the
165
+ * exit begins, which are one time, and `end` as the exit ends, where it leaves and `done`
166
+ * resolves. While the hold is open, `coast`, `out` and `end` are unknown until `release` fixes
167
+ * them. Each part shows its first and last frames through the blends either side of it, and a
168
+ * part left out leaves its time to the one before it. Its `fade` takes it out with no exit. An
169
+ * arc with a finite hold may sit in a span. Throws for a `rate` below 0, a hold below 0, and an
170
+ * `enter` or `exit` that never ends.
170
171
  */
171
172
  arc(spec: ArcSpec<I, O, H>): ArcHandle<I>;
172
173
  /**
@@ -176,27 +177,27 @@ export interface Mix<I, O, H = unknown> {
176
177
  */
177
178
  sync(timestamp: number): void;
178
179
  /**
179
- * The time between the last sync and the next one is not to count: a host calls it when a
180
- * hidden tab comes back. Every voice, fade and subject resumes where it was left.
180
+ * Leaves the time between the last sync and the next one uncounted. A host calls it when a hidden
181
+ * tab comes back. Every voice, fade and subject resumes where it was left.
181
182
  */
182
183
  rebase(): void;
183
184
  /**
184
- * The mix's own playback rate, multiplied into every voice's: 1 is real time and 0 pauses the
185
- * whole mix. A negative rate throws: the mix plays only forward, and `seek` moves it back. Setting it changes speed at
186
- * once; `ramp` eases into a new one. It scales mix time, which everything a voice owns runs on:
187
- * its clock, its fades and a handle's ramp, `stagger`, an anchor's `by`, `stepMs`, `maxDt`,
188
- * `history.ms`, every `dt`, and `setting.timestamp`. Timestamps on the host's clock name the same
189
- * moment whatever the rate does: a `start`, an anchor given as a number, an announced mark, what
190
- * `marks` reports and the time `project` reads, so a start ahead of a paused mix waits for the
191
- * host's clock to reach it. A weight signal is still asked at every probe, so one reading host
192
- * input follows it while the mix is paused.
185
+ * The mix's own playback rate, multiplied into every voice's. 1 is real time and 0 pauses the
186
+ * whole mix. A negative rate throws: the mix plays only forward, and `seek` moves it back.
187
+ * Setting it changes speed at once; `ramp` eases into a new one. It scales mix time, which
188
+ * everything a voice owns runs on: its clock, its fades and a handle's ramp, `stagger`, an
189
+ * anchor's `by`, `stepMs`, `maxDt`, `history.ms`, every `dt`, and `setting.timestamp`. Timestamps
190
+ * on the host's clock name the same moment whatever the rate does: a `start`, an anchor given as
191
+ * a number, an announced mark, what `marks` reports and the time `project` reads, so a start
192
+ * ahead of a paused mix waits for the host's clock to reach it. A weight signal is still asked at
193
+ * every probe, so one reading host input follows it while the mix is paused.
193
194
  */
194
195
  rate: number;
195
196
  /**
196
- * Moves the mix's rate to `rate` linearly over `over` ms of the host's clock, as `Handle.ramp`
197
- * moves a voice's. Mix time integrates the ramp and a voice's clock integrates mix time, so a ramp
198
- * on both multiplies and every position stays continuous. A later `rate` write or `ramp` replaces
199
- * it.
197
+ * Moves the mix's rate to `rate` linearly over `over` ms of the host's clock. It works as
198
+ * `Handle.ramp` does on a voice's. Mix time integrates the ramp and a voice's clock integrates
199
+ * mix time, so a ramp on both multiplies and every position stays continuous. A later `rate`
200
+ * write or `ramp` replaces it.
200
201
  */
201
202
  ramp(rate: number, over: number): void;
202
203
  /**
@@ -209,8 +210,17 @@ export interface Mix<I, O, H = unknown> {
209
210
  */
210
211
  probe(subject: I, out?: O): O;
211
212
  /**
212
- * Writes each subject's pose into arrays, one per channel, subject by subject in the order given:
213
- * what `probe(subject, out)` gives, without a pose object per subject. A channel of `n` numbers
213
+ * A new empty pose, to pass as `probe`'s `out`. Each call makes its own object, holding every
214
+ * channel with a rest in kit order: a number rest at its value, any other `undefined` until a
215
+ * probe writes it. Make one and pass it as `probe`'s `out` every frame. An `out` made as `{}` or
216
+ * a literal shares V8's shapes with the host's other small objects, which can leave each number
217
+ * written into it boxed; this one has a shape of its own, so the mix writes numbers into it
218
+ * without allocating.
219
+ */
220
+ pose(): O;
221
+ /**
222
+ * Writes each subject's pose into arrays, one per channel. Subjects go in the order given, each
223
+ * as `probe(subject, out)` gives it, without a pose object per subject. A channel of `n` numbers
214
224
  * takes `n` places per subject, side by side; one with no value for a subject writes NaN there.
215
225
  * Fastest while every voice runs on a lane, and when `subjects` is an array read again in the
216
226
  * same order: the mix remembers the last array's subjects by position, holding them until the
@@ -242,34 +252,49 @@ export interface Mix<I, O, H = unknown> {
242
252
  readonly frame: number;
243
253
  }): Projection<I, O>;
244
254
  /**
245
- * Moves the mix to mix time `time`, as it stood at the end of that frame, and plays on from
246
- * there; where rate 0 held the clock at `time` for several frames, the last of them. Needs
247
- * `history` with a `tape`, which records the host's calls by the host time they were made at.
255
+ * Reads the mix over a window of mix time, `from` to `to`, without moving it, as `project` reads
256
+ * one moment: `trace.of(subject, channel)` gives that channel as points joined by straight lines.
257
+ * Where every voice feeding the channel is a `keys` voice whose shape is known through the
258
+ * window, the points are its own breakpoints and the lines are exact; elsewhere the run is read
259
+ * every `grid` ms, as many `project` calls would read it.
260
+ *
261
+ * Exact needs, of each voice reaching the subject and writing the channel: a `keys` patch whose
262
+ * stops are plain numbers, eased `linear`; a number weight; no owner, anchor, role, blend,
263
+ * `within`, `stepMs`, `from: 'current'`, or rate ramp; a fade in finished by `from` and no fade
264
+ * out under way or due. The channel folds by `sum`, or by `mul` from one such voice, and has no
265
+ * `bounds`. The window lies at or after the mix's own time, and the tape holds no calls ahead.
266
+ */
267
+ trace(from: number, to: number, opts?: TraceOptions): Trace<I, O>;
268
+ /**
269
+ * Moves the mix to mix time `time` and plays on from there. It lands as the mix stood at the end
270
+ * of that frame; where rate 0 held the clock at `time` for several frames, the last of them.
271
+ * Needs `history` with a `tape`, which records the host's calls by the host time they were made
272
+ * at.
248
273
  *
249
274
  * Back, the mix restores itself: controls, records, voices and marks as they stood then. Voices
250
275
  * that left after it are back on the handles the host holds, their `done` and `played` starting
251
276
  * over where they had settled since. Voices cued after it wait as `pending` until the mix plays
252
277
  * their cue again, and a write to the handle of one waiting changes nothing. Stateful voices
253
278
  * restart from the copy `history` kept nearest before it and step once to it, exact under
254
- * `stepMs`. A subject faded out of a voice or dropped after it comes back with the record it
255
- * had, a motion patch's state included. Recorded input and host fields after it are let go:
256
- * after a seek back, signals and host fields read live again, and `assess` reports what they
257
- * fed as `held`.
279
+ * `stepMs`. A subject faded out of a voice or dropped after it comes back with the record it had,
280
+ * a motion patch's state included. Recorded input and host fields after it are let go: after a
281
+ * seek back, signals and host fields read live again, and `assess` reports what they fed as
282
+ * `held`.
258
283
  *
259
284
  * Forward, through a sync or a later seek, the mix plays the recorded calls again in the frames
260
- * they were made in: cues, handle writes, fades, retargets and pushes, its rate, marks,
261
- * `mute` and `drop`. A call the host makes while there are recorded calls ahead starts a new
262
- * branch, and the tape keeps the old future beside it; `tape.switchBranch` picks one back.
263
- * Playing past a time again sends its events and books its marks and hits again.
285
+ * they were made in: cues, handle writes, fades, retargets and pushes, its rate, marks, `mute`
286
+ * and `drop`. A call the host makes while there are recorded calls ahead starts a new branch, and
287
+ * the tape keeps the old future beside it; `tape.switchBranch` picks one back. Playing past a
288
+ * time again sends its events and books its marks and hits again.
264
289
  *
265
- * The host goes on passing its own clock: the next `sync` reads the moment sought plus the
266
- * host's time since its last sync. Throws for a time older than history reaches, and before
267
- * the first sync. With a history `store`, a time older than memory needs `prepare` first, or
268
- * throws `HistoryMiss` before anything moves.
290
+ * The host goes on passing its own clock: the next `sync` reads the moment sought plus the host's
291
+ * time since its last sync. Throws for a time older than history reaches, and before the first
292
+ * sync. With a history `store`, a time older than memory needs `prepare` first, or throws
293
+ * `HistoryMiss` before anything moves.
269
294
  *
270
- * Given `{ frame }`, a number `seq` read, it moves to the end of that frame instead, which is
271
- * how a host reaches an earlier one of several frames rate 0 held at one mix time. The frame has
272
- * to be one history still holds: not let go with age, and not after a moment an earlier seek went
295
+ * Given `{ frame }`, a number `seq` read, it moves to the end of that frame instead, which is how
296
+ * a host reaches an earlier one of several frames rate 0 held at one mix time. The frame has to
297
+ * be one history still holds: not let go with age, and not after a moment an earlier seek went
273
298
  * back to. With a store, one older than memory needs `prepare` of its mix time first.
274
299
  */
275
300
  seek(to: number | {
@@ -278,112 +303,161 @@ export interface Mix<I, O, H = unknown> {
278
303
  /** As `Transport.prepare`, for a mix made alone. */
279
304
  prepare(time: number): Promise<void>;
280
305
  /**
281
- * The mix clock at the last sync or seek, which `seek` and `project` take; NaN before the first
282
- * sync. Host time at the mix's rate, less what `rebase` took out and `seek` moved.
306
+ * The mix clock at the last sync or seek. It is the time `seek` and `project` take; NaN before
307
+ * the first sync. Host time at the mix's rate, less what `rebase` took out and `seek` moved.
283
308
  */
284
309
  readonly now: number;
285
310
  /** The host's timestamp at the last sync; NaN before the first. */
286
311
  readonly timestamp: number;
287
312
  /**
288
- * The number of the frame being played, which `seek({ frame })` and `project({ frame })` take:
289
- * each sync and seek begins a frame with a higher one, so two frames at one mix time differ.
313
+ * The number of the frame being played. `seek({ frame })` and `project({ frame })` take it. Each
314
+ * sync and seek begins a frame with a higher one, so two frames at one mix time differ.
290
315
  */
291
316
  readonly seq: number;
292
317
  /** The tape `history.tape` made, undefined without one. */
293
318
  readonly tape: Tape | undefined;
294
319
  /**
295
- * Every channel at rest for this subject this frame, so a host can skip the write. After a probe
296
- * of the subject this frame, it answers for the pose that probe gave, without folding again.
320
+ * Whether every channel is at rest for this subject this frame. A host can then skip the write.
321
+ * After a probe of the subject this frame, it answers for the pose that probe gave, without
322
+ * folding again.
297
323
  */
298
324
  atRest(subject: I): boolean;
299
325
  /**
300
- * A handle on every voice still in the mix, pending, live, frozen or fading, in the order they were
301
- * cued; given a tag, only the voices whose `tags` carry it. Each is the handle `cue` returned for
302
- * that voice, so a listed handle is `===` the cued one.
326
+ * A handle on every voice still in the mix, in the order they were cued. That includes pending,
327
+ * live, frozen and fading voices; given a tag, only the voices whose `tags` carry it. Each is the
328
+ * handle `cue` returned for that voice, so a listed handle is `===` the cued one.
303
329
  */
304
330
  voices(tag?: string): Handle<I>[];
305
331
  /** Anything still contributing, fading, or pending. */
306
332
  readonly live: boolean;
307
333
  /**
308
- * Another frame would change no pose, so a host's frame loop may sleep: every voice is done, frozen
309
- * at a plain weight, or a motion whose every subject has landed on its target. At rate 0 it is
310
- * enough that every voice not done has started, at a plain weight, with no anchor. A change made
311
- * since the last sync, a retarget or a rate included, makes it false until the next. Read as true,
312
- * it tells the mix the host may sleep: a voice cued with no `start` before the next sync starts
313
- * at that sync.
334
+ * Whether another frame would change no pose, so a host's frame loop may sleep. It holds when
335
+ * every voice is done, frozen at a plain weight, or a motion whose every subject has landed on
336
+ * its target. At rate 0 it is enough that every voice not done has started, at a plain weight,
337
+ * with no anchor. A change made since the last sync, a retarget or a rate included, makes it
338
+ * false until the next. Read as true, it tells the mix the host may sleep: a voice cued with no
339
+ * `start` before the next sync starts at that sync.
314
340
  */
315
341
  readonly inert: boolean;
316
342
  /**
317
- * Calls `fn` when a host call makes the mix need frames again after a sync: a cue, a fade, a
318
- * handle's or the mix's rate, a seek, a `drop`, a motion retargeted. It fires once until the next
319
- * sync clears the change, and never during `sync`. Returns a function that unsubscribes `fn`.
320
- * A frame loop sleeping on `inert` subscribes here to wake.
343
+ * Calls `fn` when a host call makes the mix need frames again after a sync. Such a call is a cue,
344
+ * a fade, a handle's or the mix's rate, a seek, a `drop`, or a motion retargeted. It fires once
345
+ * until the next sync clears the change, and never during `sync`. Returns a function that
346
+ * unsubscribes `fn`. A frame loop sleeping on `inert` subscribes here to wake.
321
347
  */
322
348
  onWake(fn: () => void): () => void;
323
349
  /**
324
- * Takes the mix off the list debuggers read (see `watched`), for a host done with it, where it
325
- * would otherwise stay until collected. Stops every watcher, and frees a hold no other listed mix
326
- * on its transport shares. It still plays if synced.
350
+ * Takes the mix off the list debuggers read (see `watched`). It is for a host done with it, where
351
+ * it would otherwise stay until collected. Stops every watcher, and frees a hold no other listed
352
+ * mix on its transport shares. It still plays if synced.
327
353
  */
328
354
  close(): void;
329
- /** Fades every voice out: over `over` when given, over each voice's own `fade.out` otherwise. */
355
+ /** Fades every voice out. The ramp is `over` when given, else each voice's own `fade.out`. */
330
356
  mute(opts?: {
331
357
  over?: number;
332
358
  }): void;
333
359
  /**
334
- * Forgets per-subject state, a motion patch's for the subject included, and any fade of the
335
- * subject out of a voice, so nothing keeps the subject alive.
360
+ * Forgets a subject's state, so nothing keeps the subject alive. That includes a motion patch's
361
+ * state for the subject, and any fade of the subject out of a voice.
336
362
  */
337
363
  drop(subject: I): void;
338
364
  /**
339
- * Says that something a patch reads from outside the mix has changed since the last sync, such as
340
- * a table its `at` looks a subject up in, so the next probe calls the patch again where it would
341
- * have answered with what it read this frame. Given a subject, for that subject only; with none,
342
- * for every subject. The clock stays where it is and no `step` runs again, and it wakes a frame
343
- * loop sleeping on `inert`, as any change does.
365
+ * Says that something a patch reads from outside the mix has changed since the last sync. One
366
+ * such thing is a table its `at` looks a subject up in. The next probe calls the patch again
367
+ * where it would have answered with what it read this frame. Given a subject, for that subject
368
+ * only; with none, for every subject. The clock stays where it is and no `step` runs again, and
369
+ * it wakes a frame loop sleeping on `inert`, as any change does.
344
370
  */
345
371
  touch(subject?: I): void;
346
372
  /**
347
- * Puts a named mark on a score, for anchors to target as they target a voice's marks: a voice
373
+ * The subject's index, which a `within` finder names it by. It is the one it has, or a new one.
374
+ * It keeps it until `drop`, or, for an object, until the host lets it go; then the index is
375
+ * handed to the next subject placed. A subject placed with no `plot` has no position until `put`
376
+ * gives it one.
377
+ */
378
+ place(subject: I): number;
379
+ /**
380
+ * Gives the mix each subject's index and position at once, for voices cued `within` a circle. The
381
+ * index is the subject's place in `subjects`, and `xy` holds two numbers a subject, `x` then `y`,
382
+ * in that order. It is read in place, so a host moving its subjects writes into it and calls
383
+ * `moved`. `cell` sizes the grid the mix finds subjects in, best near the radius the circles use;
384
+ * by default, about two subjects a cell. Another call replaces the list and every index. A
385
+ * subject `place`d after it takes an index freed by `drop`, which reads whatever `xy` holds
386
+ * there, or one past the list, which has no position. Throws for an `xy` shorter than two numbers
387
+ * a subject.
388
+ */
389
+ plot(subjects: readonly I[], xy: Float64Array, cell?: number): void;
390
+ /** Says the host wrote new positions into the array it gave `plot`. The next frame reads them. */
391
+ moved(): void;
392
+ /**
393
+ * Moves one subject to (`x`, `y`), for a host where few move at once. It writes into the array
394
+ * `plot` was given, so the host's array holds the move too, or with no `plot`, into the mix's
395
+ * own, and the grid is built again only once many subjects have left their cells. The same as
396
+ * writing the array and calling `moved`; the two mix freely. Throws for a subject with no index,
397
+ * and for one whose index is past the array `plot` was given.
398
+ */
399
+ put(subject: I, x: number, y: number): void;
400
+ /**
401
+ * A weight signal over the positions `plot` or `put` gave, highest at a circle's center. It is 1
402
+ * at the center, falling with distance to 0 at `r` and beyond, along `ease` read from the edge
403
+ * (0) to the center (1), linear by default. The host moves or resizes the circle by writing to
404
+ * it. A voice it weighs is bounded to the circle as if cued `within` it, with no check, since the
405
+ * circle is the signal's own edge, from the first `place` or `plot` for one cued before it. A
406
+ * subject with no position reads 0.
407
+ */
408
+ around(circle: Circle, opts?: {
409
+ ease?: Easing;
410
+ }): Signal<I, H>;
411
+ /**
412
+ * Puts a named mark on a score, for anchors to target as they target a voice's marks. A voice
348
413
  * placed `{ with: 'reply' }` waits until the host announces `reply`. `at` is a timestamp on the
349
414
  * host's clock, default now, and may lie ahead, so a read ahead sees it. A mark stays while it is
350
415
  * ahead or while the mix's history reaches it.
351
416
  */
352
- announce(name: string, opts?: {
353
- at?: number;
354
- score?: string;
355
- tags?: readonly string[];
356
- }): void;
417
+ announce(name: string, opts?: AnnounceOptions): void;
357
418
  /**
358
- * Every mark the plan knows between two timestamps on the host's clock, earliest first: when
359
- * voices start, are fully in, end their last pass, begin to fade and are gone, and what the host
360
- * announced. A mark
361
- * nothing has fixed yet, such as the out of a voice that loops for good, is not listed.
419
+ * Every mark the plan knows between two timestamps on the host's clock, earliest first. They are
420
+ * when voices start, are fully in, end their last pass, begin to fade and are gone, and what the
421
+ * host announced. A mark nothing has fixed yet, such as the out of a voice that loops for good,
422
+ * is not listed.
362
423
  */
363
424
  marks(from: number, to: number): Marked[];
364
425
  /**
365
- * Every event patches have sent since the last drain, earliest first, in the order they were sent
366
- * where two share a timestamp. A subject's events are made while it catches up, which is when it is
367
- * probed, so one nobody probes has sent nothing yet: promptness is the host's, by probing. A
368
- * stateless patch's `at` on a lane is the exception: it runs at the frame's first probe for every
369
- * subject probed that frame or the last. Under `stepMs` each carries the end of the interval it happened in, so
370
- * what is sent and when does not depend on how the host spaces its probes. Time `rebase` took out
371
- * sends nothing. Given a tag, it takes only the events of voices carrying it and leaves the rest for
372
- * whoever drains them.
426
+ * Every event patches have sent since the last drain, earliest first. Where two share a
427
+ * timestamp, they come in the order they were sent. A subject's events are made while it catches
428
+ * up, which is when it is probed, so one nobody probes has sent nothing yet: promptness is the
429
+ * host's, by probing. A stateless patch's `at` on a lane is the exception: it runs at the frame's
430
+ * first probe for every subject probed that frame or the last. Under `stepMs` each carries the
431
+ * end of the interval it happened in, so what is sent and when does not depend on how the host
432
+ * spaces its probes. Time `rebase` took out sends nothing. Given a tag, it takes only the events
433
+ * of voices carrying it and leaves the rest for whoever drains them.
373
434
  */
374
435
  drain<E = unknown>(tag?: string): Sent<I, E>[];
375
436
  /**
376
- * Hands the host each mark and hit before it comes, against a clock of its own, so it can schedule
377
- * the thing itself: a sound on an `AudioContext`, a MIDI message with a timestamp, a video loaded
378
- * before the voice that shows it starts. Booking runs at each `sync`, `ahead` ms out, and a
379
- * booking whose time moves is stopped and taken again. Nothing is booked twice: a mark is known by
380
- * its voice and which mark, a hit by its voice, index and pass. `project` books nothing, and
381
- * nothing about booking is replayed under `history`. A mix with no booker pays nothing for it.
437
+ * Hands the host each mark and hit ahead of time, against a clock of its own. The host can then
438
+ * schedule the thing itself: a sound on an `AudioContext`, a MIDI message with a timestamp, a
439
+ * video loaded before the voice that shows it starts. Booking runs at each `sync`, `ahead` ms
440
+ * out, and a booking whose time moves is stopped and taken again. Nothing is booked twice: a mark
441
+ * is known by its voice and which mark, a hit by its voice, index and pass. `project` books
442
+ * nothing, and nothing about booking is replayed under `history`. A mix with no booker pays
443
+ * nothing for it.
382
444
  */
383
445
  book<E = unknown>(opts: BookOptions<E, I>): Booker;
384
446
  }
385
447
  /**
386
- * The implementation behind a mix: which patch forms it runs, and how it makes one.
448
+ * What `announce` takes besides the mark's name.
449
+ *
450
+ * @category mix
451
+ */
452
+ export interface AnnounceOptions {
453
+ /** A timestamp on the host's clock, which may lie ahead. Default now. */
454
+ at?: number;
455
+ /** The score the mark goes on. Default: the mix's one unnamed score. */
456
+ score?: string;
457
+ tags?: readonly string[];
458
+ }
459
+ /**
460
+ * The implementation behind a mix. It says which patch forms it runs, and how it makes one.
387
461
  *
388
462
  * @category engine
389
463
  */