@msb235/blits 0.14.0 → 0.15.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 (173) hide show
  1. package/CHANGELOG.md +154 -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 +15 -7
  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.js +7 -3
  23. package/dist/contribution.d.ts +30 -0
  24. package/dist/contribution.js +374 -0
  25. package/dist/copyout.d.ts +10 -0
  26. package/dist/copyout.js +69 -24
  27. package/dist/crowd.d.ts +8 -2
  28. package/dist/crowd.js +4 -5
  29. package/dist/cue.d.ts +8 -1
  30. package/dist/cue.js +39 -13
  31. package/dist/cut.d.ts +8 -0
  32. package/dist/cut.js +4 -0
  33. package/dist/drop.d.ts +9 -0
  34. package/dist/drop.js +84 -0
  35. package/dist/due.d.ts +24 -5
  36. package/dist/due.js +113 -33
  37. package/dist/easing.d.ts +4 -4
  38. package/dist/easing.js +3 -3
  39. package/dist/everyone.d.ts +3 -2
  40. package/dist/everyone.js +3 -3
  41. package/dist/fade.d.ts +2 -1
  42. package/dist/fade.js +2 -1
  43. package/dist/fill.d.ts +3 -2
  44. package/dist/fill.js +51 -19
  45. package/dist/fit.d.ts +44 -26
  46. package/dist/fit.js +10 -9
  47. package/dist/fold.d.ts +4 -37
  48. package/dist/fold.js +5 -513
  49. package/dist/gather.d.ts +12 -7
  50. package/dist/gather.js +179 -44
  51. package/dist/gone.js +2 -2
  52. package/dist/grid.d.ts +47 -0
  53. package/dist/grid.js +247 -0
  54. package/dist/handle.d.ts +2 -0
  55. package/dist/handle.js +14 -8
  56. package/dist/held.d.ts +2 -1
  57. package/dist/history.d.ts +6 -5
  58. package/dist/history.js +7 -9
  59. package/dist/hosts.js +9 -15
  60. package/dist/index.d.ts +5 -4
  61. package/dist/keyfill.d.ts +1 -1
  62. package/dist/keyfill.js +5 -3
  63. package/dist/keyrows.d.ts +12 -0
  64. package/dist/keyrows.js +99 -12
  65. package/dist/lane.d.ts +36 -6
  66. package/dist/lane.js +32 -1
  67. package/dist/lanes.d.ts +23 -8
  68. package/dist/lanes.js +29 -8
  69. package/dist/leavings.d.ts +2 -2
  70. package/dist/leavings.js +1 -1
  71. package/dist/lives.d.ts +47 -0
  72. package/dist/lives.js +180 -0
  73. package/dist/meet.d.ts +2 -2
  74. package/dist/meet.js +90 -4
  75. package/dist/mixer.d.ts +54 -36
  76. package/dist/mixer.js +53 -171
  77. package/dist/motion.d.ts +14 -118
  78. package/dist/motion.js +16 -8
  79. package/dist/motions.d.ts +62 -155
  80. package/dist/motions.js +56 -370
  81. package/dist/moved.d.ts +1 -1
  82. package/dist/moved.js +16 -7
  83. package/dist/named.d.ts +0 -1
  84. package/dist/named.js +20 -2
  85. package/dist/numbers.d.ts +2 -0
  86. package/dist/numbers.js +4 -0
  87. package/dist/owed.d.ts +2 -0
  88. package/dist/owed.js +4 -0
  89. package/dist/pack.d.ts +2 -1
  90. package/dist/pack.js +2 -3
  91. package/dist/patch.d.ts +7 -3
  92. package/dist/patch.js +6 -2
  93. package/dist/places.d.ts +53 -0
  94. package/dist/places.js +171 -0
  95. package/dist/plot.d.ts +12 -0
  96. package/dist/plot.js +52 -0
  97. package/dist/project.d.ts +4 -4
  98. package/dist/project.js +9 -212
  99. package/dist/pull.js +11 -8
  100. package/dist/qualify.js +84 -21
  101. package/dist/reading.d.ts +6 -0
  102. package/dist/reading.js +5 -0
  103. package/dist/record.d.ts +5 -1
  104. package/dist/record.js +3 -2
  105. package/dist/relink.d.ts +1 -1
  106. package/dist/restored.d.ts +2 -2
  107. package/dist/restored.js +1 -1
  108. package/dist/rests.d.ts +9 -0
  109. package/dist/rests.js +76 -0
  110. package/dist/revive.d.ts +3 -2
  111. package/dist/revive.js +2 -2
  112. package/dist/{locus.d.ts → role.d.ts} +10 -9
  113. package/dist/{locus.js → role.js} +3 -3
  114. package/dist/roles.d.ts +10 -0
  115. package/dist/roles.js +158 -0
  116. package/dist/roster.js +3 -3
  117. package/dist/rotation.d.ts +1 -1
  118. package/dist/rotation.js +1 -1
  119. package/dist/rows.js +1 -1
  120. package/dist/sample.d.ts +2 -2
  121. package/dist/sample.js +33 -7
  122. package/dist/seek.js +5 -5
  123. package/dist/setting.d.ts +27 -0
  124. package/dist/setting.js +55 -0
  125. package/dist/shared.d.ts +1 -1
  126. package/dist/shared.js +1 -1
  127. package/dist/signals.d.ts +64 -32
  128. package/dist/signals.js +20 -18
  129. package/dist/stack.d.ts +5 -5
  130. package/dist/stack.js +5 -5
  131. package/dist/standing.d.ts +2 -1
  132. package/dist/standing.js +3 -2
  133. package/dist/store.d.ts +9 -0
  134. package/dist/store.js +24 -0
  135. package/dist/strays.d.ts +2 -1
  136. package/dist/strays.js +20 -13
  137. package/dist/stretch.d.ts +112 -0
  138. package/dist/stretch.js +9 -0
  139. package/dist/subject.d.ts +142 -0
  140. package/dist/subject.js +1 -0
  141. package/dist/tape.d.ts +9 -5
  142. package/dist/tape.js +5 -1
  143. package/dist/then.d.ts +9 -0
  144. package/dist/then.js +57 -0
  145. package/dist/ticker.d.ts +4 -4
  146. package/dist/transport.d.ts +0 -8
  147. package/dist/transport.js +0 -4
  148. package/dist/turns.d.ts +4 -3
  149. package/dist/turns.js +4 -3
  150. package/dist/types/arc.d.ts +12 -11
  151. package/dist/types/channel.d.ts +12 -8
  152. package/dist/types/history.d.ts +35 -19
  153. package/dist/types/mix.d.ts +222 -163
  154. package/dist/types/motion.d.ts +151 -0
  155. package/dist/types/motion.js +1 -0
  156. package/dist/types/patch.d.ts +67 -34
  157. package/dist/types/place.d.ts +51 -36
  158. package/dist/types/transport.d.ts +20 -18
  159. package/dist/types/voice.d.ts +136 -70
  160. package/dist/types/watch.d.ts +88 -40
  161. package/dist/types.d.ts +1 -0
  162. package/dist/voice.d.ts +7 -143
  163. package/dist/voice.js +28 -79
  164. package/dist/warn.d.ts +2 -0
  165. package/dist/warn.js +1 -1
  166. package/dist/watch.d.ts +2 -2
  167. package/dist/watch.js +5 -3
  168. package/dist/wave.d.ts +4 -3
  169. package/dist/wave.js +3 -2
  170. package/dist/weigh.d.ts +7 -1
  171. package/dist/weigh.js +27 -0
  172. package/docs/schema.html +212 -34
  173. package/package.json +2 -2
@@ -1,7 +1,7 @@
1
1
  import type { Fit, Order, Strength } from '../fit.js';
2
- import type { Motion, Value } from '../motion.js';
3
2
  import type { Described } from './history.js';
4
3
  import type { Doubt } from './mix.js';
4
+ import type { Motion, Value } from './motion.js';
5
5
  import type { Easing, Patch, Signal } from './patch.js';
6
6
  import type { Anchor, Hit, Placement } from './place.js';
7
7
  /**
@@ -15,42 +15,68 @@ export interface FadeSpec {
15
15
  ease?: Easing;
16
16
  }
17
17
  /**
18
- * How a voice or owner held by a span may give way so the span keeps its budget, which the span's
19
- * fit reads. Anything it does not allow, it will not do. Read only under a span.
18
+ * How a span's child may give way so the span keeps its budget. A child is a voice or owner
19
+ * held by a span, and the span's fit reads this. Anything it does not allow, it will not do. Read only under a span.
20
20
  *
21
21
  * @category score
22
22
  */
23
23
  export interface SpanHints {
24
- /** How many times faster than its own rate it may play. Default 1: no faster. */
24
+ /** How many times faster than its own rate it may play. Default 1, no faster. */
25
25
  faster?: number;
26
- /** How many times slower than its own rate it may play. Default 1: no slower. */
26
+ /** How many times slower than its own rate it may play. Default 1, no slower. */
27
27
  slower?: number;
28
- /** Whether it may start before the one before it ends, where the span's order would not. */
28
+ /** Whether it may start before the one before it ends, even where the span's order would not. */
29
29
  overlap?: boolean;
30
30
  /** Whether it may jump to its end instead of playing. A span held by a span is never skipped. */
31
31
  ballast?: boolean;
32
32
  /** How hard its own length holds against the span's budget. Default `weak`. */
33
33
  priority?: Strength;
34
34
  /**
35
- * The soonest it may start: a time on the span's clock, or an anchor. The fit never places it
35
+ * The soonest it may start, as a time on the span's clock or an anchor. The fit never places it
36
36
  * sooner, and the children after it are laid out from where it starts. One already past when it is
37
37
  * cued places it there, partway through. One whose anchor has no answer yet waits, and under `queue` or
38
38
  * `stagger` so does every child after it.
39
39
  */
40
40
  earliest?: number | Anchor;
41
- /** Where it plays among the span's children still to start: lower first, ties as cued. Default 0. */
41
+ /**
42
+ * Where it plays among the span's children still to start. Lower goes first, and ties go as cued.
43
+ * Default 0.
44
+ */
42
45
  rank?: number;
43
46
  }
44
47
  /**
45
- * What `cue` takes: a patch, and the clock, weight and reach it plays with.
48
+ * A circle by its center, `x` and `y`, and radius `r`. It is in the units of the positions `plot`
49
+ * gave.
50
+ *
51
+ * @category voice
52
+ */
53
+ export interface Circle {
54
+ x: number;
55
+ y: number;
56
+ r: number;
57
+ }
58
+ /**
59
+ * The host's own answer to where a `within` signal can be above 0. It works over any axes or
60
+ * none. Once a
61
+ * frame, `find` writes into `out`, from 0, the indices `place` or `plot` gave the subjects the
62
+ * signal can be above 0 for, and returns how many it wrote. `out` has room for every index handed
63
+ * out; a repeat is read once, and an index no subject holds is skipped.
64
+ *
65
+ * @category voice
66
+ */
67
+ export interface Finder {
68
+ find(out: Int32Array): number;
69
+ }
70
+ /**
71
+ * What `cue` takes. That is a patch, and the clock, weight and reach it plays with.
46
72
  *
47
73
  * @category voice
48
74
  */
49
75
  export interface VoiceSpec<I, O, H = unknown> extends SpanHints {
50
76
  patch: Patch<I, O, any, H>;
51
77
  /**
52
- * What `history.revive` rebuilds this spec from, so a history `store` can page the voice out once
53
- * it has left. A voice cued without it stays in memory for as long as history reaches it.
78
+ * What `history.revive` rebuilds this spec from. It lets a history `store` page the voice out
79
+ * once it has left. A voice cued without it stays in memory for as long as history reaches it.
54
80
  */
55
81
  as?: Described;
56
82
  /**
@@ -63,14 +89,14 @@ export interface VoiceSpec<I, O, H = unknown> extends SpanHints {
63
89
  */
64
90
  target?: (subject: I) => boolean;
65
91
  /**
66
- * The subjects this voice reaches, fixed at `cue` and matched by identity; a probe of any other
67
- * never asks this voice. Takes the place of `target`, and a cue giving both is refused: a
92
+ * The subjects this voice reaches, fixed at `cue` and matched by identity. A probe of any other
93
+ * never asks this voice. Takes the place of `target`, and a cue giving both is refused, since a
68
94
  * predicate over a fixed list is that list filtered, which the host can do before cueing.
69
95
  */
70
96
  subjects?: readonly I[];
71
97
  /**
72
- * When the voice starts, in ms on the host's clock, the one it passes `sync`: a rAF timestamp and
73
- * `performance.now()` share an origin, `Date.now()` does not. Default: the time the mix last
98
+ * When the voice starts, in ms on the host's clock. That is the clock it passes `sync`: a rAF
99
+ * timestamp and `performance.now()` share an origin, `Date.now()` does not. Default: the time the mix last
74
100
  * synced to, and 0 for a voice cued before the first sync, which that sync finds already as far
75
101
  * in as its timestamp. Where the host read `inert` as true since the last sync, its frame loop
76
102
  * may be asleep, and the default is the next sync instead, so a voice cued after a long pause
@@ -93,8 +119,8 @@ export interface VoiceSpec<I, O, H = unknown> extends SpanHints {
93
119
  */
94
120
  seek?: number;
95
121
  /**
96
- * The interval this voice's `step` runs at, in ms of mix time, in place of the mix's `stepMs`.
97
- * 0 steps it once a frame by the frame's gap, whatever the mix sets. Default: the mix's.
122
+ * The interval this voice's `step` runs at, in ms of mix time. It takes the place of the mix's
123
+ * `stepMs`. 0 steps it once a frame by the frame's gap, whatever the mix sets. Default: the mix's.
98
124
  */
99
125
  stepMs?: number;
100
126
  /**
@@ -107,20 +133,22 @@ export interface VoiceSpec<I, O, H = unknown> extends SpanHints {
107
133
  */
108
134
  catchUp?: 'exact' | 'fresh';
109
135
  /**
110
- * true loops for good, false plays one pass, n plays n passes. A finite loop leaves when its
136
+ * How many passes the voice plays. true loops for good, false plays one pass, n plays n passes.
137
+ * A finite loop leaves when its
111
138
  * passes are done for the latest-staggered subject it has seen — over `fade.out` where one is
112
139
  * set, at once where none is — unless it freezes after. Default: false.
113
140
  */
114
141
  loop?: boolean | number;
115
142
  /**
116
- * Per-subject delay in voice ms, klieg's stagger grammar reduced to the one thing the mix needs.
117
- * Like `target`, it runs once per subject on first sight, and the answer is kept.
143
+ * Per-subject delay in voice ms. It is klieg's stagger grammar reduced to the one thing the mix
144
+ * needs. Like `target`, it runs once per subject on first sight, and the answer is kept.
118
145
  */
119
146
  stagger?: (subject: I) => number;
120
147
  /**
121
- * Show a subject the first frame before it starts — while the voice is pending and while the
122
- * subject waits out its `stagger` — the last frame of the last pass after a finite loop plays
123
- * out, or both. A frozen subject's clock stands still: `at` is asked for the edge frame and `step`
148
+ * Which edge frames a subject is shown while the voice is not playing. `before` shows the first
149
+ * frame before it starts, while the voice is pending and while the subject waits out its
150
+ * `stagger`; `after` shows the last frame of the last pass after a finite loop plays out; `both`
151
+ * shows both. A frozen subject's clock stands still: `at` is asked for the edge frame and `step`
124
152
  * does not run, past one last step to the end of the last pass. `fade.in` counts from the first
125
153
  * frame the voice shows. A voice freezing after stays, `frozen`, until `fade()` or an anchored
126
154
  * `out` takes it out, so every one cued must be faded or it stays in the mix for good. Does
@@ -129,13 +157,32 @@ export interface VoiceSpec<I, O, H = unknown> extends SpanHints {
129
157
  freeze?: 'before' | 'after' | 'both';
130
158
  /** Steady weight, or a signal read per subject per frame. Default 1. */
131
159
  weight?: number | Signal<I, H>;
160
+ /**
161
+ * Where the `weight` signal can be above 0. It is a circle the host moves by writing to it, read
162
+ * once a frame, over the positions `plot` or `put` gave, or a `Finder` the host answers by index.
163
+ * Outside
164
+ * it the voice gives a subject nothing and the signal is not read, so a frame visits only the
165
+ * subjects within rather than all of them. The signal has to be 0 outside already, or the bound
166
+ * cuts it off: outside production, every few frames, the mix reads it for a few subjects just
167
+ * outside and warns once if one is above 0.
168
+ * A patch that steps still steps outside, and a `from: 'current'` voice still takes its base,
169
+ * as each does at weight 0. Needs `place` or `plot` first, and a signal `weight`.
170
+ */
171
+ within?: Circle | Finder;
132
172
  /** Ramp in and out, ms. Out applies on `fade()` and when a finite loop ends. */
133
173
  fade?: FadeSpec;
134
- /** Voices sharing a locus are alternatives: the mix folds them through each channel's `lerp`. */
174
+ /**
175
+ * The role this voice plays; voices in one role are alternatives. Whichever plays it, the subject
176
+ * shows one performance, not two stacked. The mix folds them through each channel's `lerp`.
177
+ */
178
+ role?: string;
179
+ /** @deprecated Renamed `role`. Taken as `role`, with a warning outside production. */
135
180
  locus?: string;
136
181
  /** A `keys` voice whose first stop reads wherever this subject is now. */
137
182
  from?: 'current';
138
- /** Words a source attaches to this voice, so its events and its handle can be taken as a set. */
183
+ /**
184
+ * Words a source attaches to this voice. They let its events and its handle be taken as a set.
185
+ */
139
186
  tags?: readonly string[];
140
187
  /** What other voices call this one by. A label blits never reads. */
141
188
  name?: string;
@@ -153,15 +200,15 @@ export interface VoiceSpec<I, O, H = unknown> extends SpanHints {
153
200
  */
154
201
  hits?: readonly Hit[];
155
202
  /**
156
- * Named marks inside the voice, beside its five, each at voice ms into a pass as a hit's `at` is:
157
- * `{ drop: 340 }`. An anchor names one as it names the five, `{ of: 'lead', mark: 'drop' }`, and
203
+ * Named marks inside the voice, beside its five. Each is at voice ms into a pass, as a hit's `at`
204
+ * is: `{ drop: 340 }`. An anchor names one as it names the five, `{ of: 'lead', mark: 'drop' }`, and
158
205
  * `marks` lists it and `book` books it under its name. Each is reached once: on the first pass
159
206
  * that reaches it from where the voice starts, while its clock runs forward and before it ends.
160
207
  * A name cannot be one of the five.
161
208
  */
162
209
  marks?: Readonly<Record<string, number>>;
163
210
  /**
164
- * The owner this voice plays under, a handle `owns` returned. Its `start` and `anchor` are then on
211
+ * The owner this voice plays under, as a handle `owns` returned. Its `start` and `anchor` are then on
165
212
  * the owner's clock, in ms from when the owner starts, and default to where that clock is now; a
166
213
  * bare name in an anchor means a sibling, another voice the owner holds. Its clock runs on the
167
214
  * owner's, so the owner's rate, ramp and seeks move it, and its weight is multiplied by the
@@ -170,7 +217,7 @@ export interface VoiceSpec<I, O, H = unknown> extends SpanHints {
170
217
  owner?: Handle<I>;
171
218
  }
172
219
  /**
173
- * One of `mix.blend`'s members, with the labels it carries in place of the spec's: each set here
220
+ * One of `mix.blend`'s members, with the labels it carries in place of the spec's. Each set here
174
221
  * replaces the spec's for this member alone. The rest of the spec times and places every member
175
222
  * alike, so they stay one blend.
176
223
  *
@@ -180,20 +227,20 @@ export interface BlendMember<I, O, H = unknown> {
180
227
  patch: Patch<I, O, any, H>;
181
228
  /** What other voices call this member by. Default: the spec's `name`. */
182
229
  name?: string;
183
- /** Default: the spec's `tags`. */
230
+ /** The member's tags. Default: the spec's `tags`. */
184
231
  tags?: readonly string[];
185
232
  /** Events at times on this member's clock, as a voice's `hits`. Default: the spec's. */
186
233
  hits?: readonly Hit[];
187
234
  }
188
235
  /**
189
- * What `owns` takes: an owner has no patch, and plays only through the voices it holds.
236
+ * What `owns` takes. An owner has no patch, and plays only through the voices it holds.
190
237
  *
191
238
  * @category voice
192
239
  */
193
240
  export interface OwnerSpec<I, H = unknown> extends SpanHints {
194
241
  /**
195
- * When the owner starts, on its own owner's clock: the host's for an owner on the mix, as a
196
- * voice's `start` is. Default: now.
242
+ * When the owner starts, on its own owner's clock. That is the host's clock for an owner on the
243
+ * mix, as a voice's `start` is. Default: now.
197
244
  */
198
245
  start?: number;
199
246
  /**
@@ -204,14 +251,14 @@ export interface OwnerSpec<I, H = unknown> extends SpanHints {
204
251
  */
205
252
  rate?: number;
206
253
  /**
207
- * Where its clock starts, ms, as `seek` on its handle sets: its children play as far in as that
254
+ * Where its clock starts, ms, as `seek` on its handle sets. Its children play as far in as that
208
255
  * puts them. Default 0, cued backward too, since an owner has no end of its own to start from; one
209
256
  * cued at a rate below 0 with no seek runs back from 0, before any child placed on its clock.
210
257
  */
211
258
  seek?: number;
212
259
  /**
213
- * Multiplied into every child's weight per subject, as the child's own fade is, before the child's
214
- * locus folds it: a number, or a signal read per subject per frame. Default 1.
260
+ * Multiplied into every child's weight per subject. It applies as the child's own fade does,
261
+ * before the child's role folds it: a number, or a signal read per subject per frame. Default 1.
215
262
  */
216
263
  weight?: number | Signal<I, H>;
217
264
  /** One ramp in and out over every child, multiplied into their weights as `weight` is. */
@@ -224,11 +271,14 @@ export interface OwnerSpec<I, H = unknown> extends SpanHints {
224
271
  name?: string;
225
272
  /** The plan it belongs to, as a voice's. */
226
273
  score?: string;
227
- /** Where it sits relative to its own owner's clock or to other voices, in place of `start`. */
274
+ /**
275
+ * Where it sits relative to its own owner's clock or to other voices. It takes the place of
276
+ * `start`.
277
+ */
228
278
  anchor?: Placement;
229
279
  /**
230
- * Events at times on its own clock, the one its children's `start` counts on, which `book`
231
- * hands a host ahead of time with its `score` and `tags`. An owner does not loop, so each is
280
+ * Events at times on its own clock, which `book` hands a host ahead of time. That is the clock its
281
+ * children's `start` counts on, and they go with its `score` and `tags`. An owner does not loop, so each is
232
282
  * booked once, while it plays: none past where it leaves, and none while its clock runs back.
233
283
  */
234
284
  hits?: readonly Hit[];
@@ -238,8 +288,8 @@ export interface OwnerSpec<I, H = unknown> extends SpanHints {
238
288
  owner?: Handle<I>;
239
289
  }
240
290
  /**
241
- * What `span` takes: an owner with a budget, which lays out the voices it holds in an order and
242
- * fits them into the budget.
291
+ * What `span` takes, an owner with a budget. It lays out the voices it holds in an order and fits
292
+ * them into the budget.
243
293
  *
244
294
  * @category score
245
295
  */
@@ -253,13 +303,13 @@ export interface SpanSpec<I, H = unknown> extends OwnerSpec<I, H> {
253
303
  /** How far through the one before a child starts under `stagger`, 0..1. Default 0.5. */
254
304
  share?: number;
255
305
  /**
256
- * How the children are fitted once they are retimed toward the budget, faster or slower as
257
- * their hints allow. Default `pipe(condense(), shed())`.
306
+ * How the children are fitted once they are retimed toward the budget. They are retimed faster
307
+ * or slower as their hints allow. Default `pipe(condense(), shed())`.
258
308
  */
259
309
  fit?: Fit;
260
310
  /**
261
- * What happens where the fit leaves them too long for a span at least `strong`: `instant` jumps
262
- * every child weaker than the span to its end at once, and `overrun` lets them run long.
311
+ * What happens where the fit leaves the children too long for a span at least `strong`.
312
+ * `instant` jumps every child weaker than the span to its end at once, and `overrun` lets them run long.
263
313
  * Default `instant`.
264
314
  */
265
315
  spill?: 'instant' | 'overrun';
@@ -282,7 +332,7 @@ export interface FitResult {
282
332
  fell: boolean;
283
333
  }
284
334
  /**
285
- * A span's handle: an owner's, and how its children were last fitted.
335
+ * A span's handle. It is an owner's, and reports how its children were last fitted.
286
336
  *
287
337
  * @category score
288
338
  */
@@ -290,15 +340,21 @@ export interface SpanHandle<I = unknown> extends Handle<I> {
290
340
  readonly result: FitResult;
291
341
  }
292
342
  /**
293
- * How a voice leaves when it is faded: the whole voice, or one subject.
343
+ * How a voice leaves when it is faded. It fades the whole voice, or one subject.
344
+ *
345
+ * @category blending
346
+ */
347
+ export type FadeOptions<I = unknown> = VoiceFade | SubjectFade<I>;
348
+ /**
349
+ * A fade of the whole voice, as `FadeOptions` takes it.
294
350
  *
295
351
  * @category blending
296
352
  */
297
- export type FadeOptions<I = unknown> = {
353
+ export interface VoiceFade {
298
354
  /** The ramp, ms. Defaults to the voice's own `fade.out`. */
299
355
  over?: number;
300
356
  /**
301
- * When the fade begins. A mix time: ahead, the voice plays untouched until then and begins
357
+ * When the fade begins, as a mix time or `'rest'`. A mix time: ahead, the voice plays untouched until then and begins
302
358
  * its fade exactly there, its `out` mark fixed from now, and `rise` before then takes it
303
359
  * back with nothing changed; at or behind now, the fade began then and is partway. `'rest'`:
304
360
  * leave per subject at the first frame that subject's contribution is at rest. Default now.
@@ -307,7 +363,13 @@ export type FadeOptions<I = unknown> = {
307
363
  /** Ms after which the voice leaves whether or not it rested. */
308
364
  deadline?: number;
309
365
  subject?: never;
310
- } | {
366
+ }
367
+ /**
368
+ * A fade of one subject out of a voice, as `FadeOptions` takes it.
369
+ *
370
+ * @category blending
371
+ */
372
+ export interface SubjectFade<I = unknown> {
311
373
  /**
312
374
  * The one subject to fade out of this voice, which plays on for the rest. Once the ramp ends
313
375
  * the voice forgets the subject and reaches it no more, until a motion patch's `to` or `push`
@@ -316,7 +378,7 @@ export type FadeOptions<I = unknown> = {
316
378
  subject: I;
317
379
  /** The ramp, ms. Defaults to the voice's own `fade.out`; 0 takes the subject out at once. */
318
380
  over?: number;
319
- };
381
+ }
320
382
  /**
321
383
  * The live controls on one voice, returned by `cue`.
322
384
  *
@@ -324,11 +386,16 @@ export type FadeOptions<I = unknown> = {
324
386
  */
325
387
  export interface Handle<I = unknown> {
326
388
  readonly id: number;
327
- /** `frozen`: a voice freezing after has played every pass and shows its last frame until faded. */
389
+ /**
390
+ * Where the voice is in its life. `frozen`: a voice freezing after has played every pass and shows
391
+ * its last frame until faded.
392
+ */
328
393
  readonly state: 'pending' | 'live' | 'frozen' | 'fading' | 'done';
329
- /** The handle of the owner this voice plays under; undefined for one on the mix clock. */
394
+ /** The handle of the owner this voice plays under. Undefined for one on the mix clock. */
330
395
  readonly owner: Handle<I> | undefined;
331
- /** Live. A write shows at the next probe. */
396
+ /**
397
+ * The voice's weight now, which can be written while it plays. A write shows at the next probe.
398
+ */
332
399
  weight: number;
333
400
  /**
334
401
  * Playback rate now. Setting it changes speed at once; `ramp` eases into a new one. On a voice
@@ -337,7 +404,7 @@ export interface Handle<I = unknown> {
337
404
  */
338
405
  rate: number;
339
406
  /**
340
- * Moves the rate to `rate` linearly over `over` mix ms, so a pause or a slow-motion eases in
407
+ * Moves the rate to `rate` linearly over `over` mix ms. A pause or a slow-motion then eases in
341
408
  * rather than snapping. The voice clock integrates the ramp, so its position stays continuous and
342
409
  * its speed does too. A later `rate` write or `ramp` replaces it; `seek` keeps it.
343
410
  */
@@ -359,9 +426,8 @@ export interface Handle<I = unknown> {
359
426
  */
360
427
  fade(opts?: FadeOptions<I>): void;
361
428
  /**
362
- * Turns a fade out around: the voice climbs back from where its fade had got to, up the same
363
- * curve, over `over` ms for the whole curve (default its `fade.in`, else its `fade.out`), and
364
- * plays on as if never faded. A fade waiting for rest is taken back at once; a voice not fading
429
+ * Turns a fade out around, so the voice plays on as if never faded. It climbs back from where its
430
+ * fade had got to, up the same curve, over `over` ms for the whole curve (default its `fade.in`, else its `fade.out`). A fade waiting for rest is taken back at once; a voice not fading
365
431
  * is left as it is. A voice whose own end began the fade starts it again at its next frame. A
366
432
  * voice faded before its start goes back to `pending` and starts on time.
367
433
  */
@@ -369,43 +435,43 @@ export interface Handle<I = unknown> {
369
435
  over?: number;
370
436
  }): void;
371
437
  /**
372
- * The weight this voice gave `subject` the last frame that subject was probed: after its fades
373
- * and its weight signal, before a locus folds it with its alternatives. 0 for a subject it does
438
+ * The weight this voice gave `subject` the last frame that subject was probed. That is after its
439
+ * fades and its weight signal, before a role folds it with its alternatives. 0 for a subject it does
374
440
  * not reach, has not started on and does not freeze before, has left at rest, or has never been
375
441
  * probed for; 0 once done, and 0 after `mix.seek` goes back until the subject is probed again.
376
442
  * Costs nothing until it is asked.
377
443
  */
378
444
  weightOf(subject: I): number;
379
445
  /**
380
- * Heads `subject` for `target`, for a voice playing a `spring` or a `tween`: the patch's own `to`,
381
- * reached without holding the patch. Throws for any other voice.
446
+ * Heads `subject` for `target`, for a voice playing a `spring` or a `tween`. It is the patch's own
447
+ * `to`, reached without holding the patch. Throws for any other voice.
382
448
  */
383
449
  to(subject: I, target: Value, at?: number): void;
384
450
  /**
385
- * Sets `subject` moving at `velocity`, units per second, for a voice playing a `spring` or a
386
- * `glide`: the patch's own `push`. Throws for any other voice.
451
+ * Sets `subject` moving at `velocity`, for a voice playing a `spring` or a `glide`. The velocity
452
+ * is in units per second, and this is the patch's own `push`. Throws for any other voice.
387
453
  */
388
454
  push(subject: I, velocity: Value, at?: number): void;
389
455
  /**
390
- * Puts `subject` at `value`, keeping its velocity, for a voice playing any motion patch: the
456
+ * Puts `subject` at `value`, keeping its velocity, for a voice playing any motion patch. It is the
391
457
  * patch's own `set`. Throws for any other voice.
392
458
  */
393
459
  set(subject: I, value: Value, at?: number): void;
394
460
  /**
395
- * Where `subject` is and how fast it moves, for a voice playing a motion patch: the patch's own
396
- * `read`. Undefined for any other voice, and wherever the patch's `read` is.
461
+ * Where `subject` is and how fast it moves, for a voice playing a motion patch. It is the patch's
462
+ * own `read`. Undefined for any other voice, and wherever the patch's `read` is.
397
463
  */
398
464
  read(subject: I, at?: number): Motion<Value> | undefined;
399
465
  /** Resolves when the voice has been removed from the mix, however that happened. */
400
466
  readonly done: Promise<void>;
401
467
  /**
402
- * Resolves true when a finite loop's last pass ends, for the latest-staggered subject it has
403
- * seen, and false if the voice leaves before that. Never rejects.
468
+ * Resolves true when a finite loop's last pass ends, false if the voice leaves before that. The
469
+ * last pass is the one for the latest-staggered subject it has seen. Never rejects.
404
470
  */
405
471
  readonly played: Promise<boolean>;
406
472
  }
407
473
  /**
408
- * What `Handle.seek` does with each subject's state: `rebuild` (the default) makes it fresh and
474
+ * What `Handle.seek` does with each subject's state. `rebuild` (the default) makes it fresh and
409
475
  * steps it to the new position; `keep` leaves it as it was, except for a subject the seek sends back
410
476
  * before its start, which starts afresh there.
411
477
  *
@@ -1,10 +1,10 @@
1
1
  import type { HistoryOptions } from './history.js';
2
2
  import type { Mix } from './mix.js';
3
3
  import type { Sent } from './patch.js';
4
- import type { Handle } from './voice.js';
4
+ import type { Circle, Finder, Handle } from './voice.js';
5
5
  /**
6
- * Every mix made on the page, for a debugger: shared by every copy of blits loaded, so a mix one
7
- * copy made is listed by another. `watched()` returns it.
6
+ * Every mix made on the page, for a debugger. It is shared by every copy of blits loaded, so a
7
+ * mix one copy made is listed by another. `watched()` returns it.
8
8
  *
9
9
  * @category mix
10
10
  */
@@ -12,19 +12,27 @@ export interface Registry {
12
12
  /** The mixes still alive, in the order they were made. */
13
13
  entries(): Watched[];
14
14
  /** Hears each mix made, and each one collected, by its entry's `id`. Returns an unsubscribe. */
15
- on(fn: (change: {
16
- kind: 'add';
17
- entry: Watched;
18
- } | {
19
- kind: 'gone';
20
- id: number;
21
- }) => void): () => void;
15
+ on(fn: (change: RegistryChange) => void): () => void;
22
16
  /**
23
- * The history a mix made from now on keeps when its options name none and it is on no
24
- * transport, so a debugger present before the page's mixes can scrub them. Undefined by default.
17
+ * The history new mixes keep when they name none. It applies to a mix made from now on whose
18
+ * options name no history and that is on no transport, so a debugger present before the page's
19
+ * mixes can scrub them. Undefined by default.
25
20
  */
26
21
  history: HistoryOptions | undefined;
27
22
  }
23
+ /**
24
+ * What `Registry.on` hears. It is a mix made, with its entry, or a mix collected, by its entry's
25
+ * `id`.
26
+ *
27
+ * @category mix
28
+ */
29
+ export type RegistryChange = {
30
+ kind: 'add';
31
+ entry: Watched;
32
+ } | {
33
+ kind: 'gone';
34
+ id: number;
35
+ };
28
36
  /**
29
37
  * One mix as a debugger sees it. Built by the copy of blits that made the mix, so a debugger
30
38
  * reads mixes from other releases through it alike.
@@ -39,21 +47,17 @@ export interface Watched<I = unknown, O = unknown> {
39
47
  readonly name: string | undefined;
40
48
  readonly mix: Mix<I, O>;
41
49
  /** What history it keeps, and whether the registry's `history` gave it; undefined for none. */
42
- readonly history: {
43
- readonly ms: number;
44
- readonly tape: boolean;
45
- readonly added: boolean;
46
- } | undefined;
47
- /** The earliest mix time `read` reaches back to: `mix.now` without history. */
50
+ readonly history: WatchedHistory | undefined;
51
+ /** The earliest mix time `read` reaches back to. It is `mix.now` without history. */
48
52
  readonly reach: number;
49
53
  /** The kit's channel names, in kit order. */
50
54
  readonly channels: readonly string[];
51
- /** What a voice was cued with that its handle does not carry; undefined for a handle not on this mix. */
52
- voice(handle: Handle<I>): {
53
- readonly name: string | undefined;
54
- readonly tags: readonly string[];
55
- } | undefined;
56
- /** What to call a subject: the mix's `labelOf`, else a guess from the subject itself. */
55
+ /**
56
+ * What a voice was cued with that its handle does not carry. Undefined for a handle not on this
57
+ * mix.
58
+ */
59
+ voice(handle: Handle<I>): WatchedVoice | undefined;
60
+ /** What to call a subject. It is the mix's `labelOf`, else a guess from the subject itself. */
57
61
  label(subject: I): string;
58
62
  /**
59
63
  * Calls `fn` with each frame the host read, once the next one begins. While anyone watches, the
@@ -61,16 +65,46 @@ export interface Watched<I = unknown, O = unknown> {
61
65
  * a function that stops watching.
62
66
  */
63
67
  watch(fn: (frame: WatchedFrame<I, O>) => void): () => void;
64
- /** The subjects its voices still playing name, and those the host read in the last two frames while watched. */
68
+ /**
69
+ * The subjects its voices still playing name. It also lists those the host read in the last two
70
+ * frames while watched.
71
+ */
65
72
  subjects(): I[];
66
73
  /**
67
- * One subject's pose at mix time `at`, default now, read through `project`, which moves nothing:
68
- * never a probe. A time behind now needs history that reaches it.
74
+ * One subject's pose at mix time `at`, default now. It is read through `project`, which moves
75
+ * nothing, never a probe. A time behind now needs history that reaches it.
69
76
  */
70
77
  read(subject: I, at?: number): O;
71
- /** Takes the clock from the host: see `Hold`. Throws while another hold has it. */
78
+ /** Takes the clock from the host. See `Hold`. Throws while another hold has it. */
72
79
  hold(): Hold;
73
80
  }
81
+ /**
82
+ * What history a watched mix keeps, as `Watched.history` reports it.
83
+ *
84
+ * @category mix
85
+ */
86
+ export interface WatchedHistory {
87
+ /** How much stays in memory, ms of mix time. */
88
+ readonly ms: number;
89
+ /** Whether it records a tape. */
90
+ readonly tape: boolean;
91
+ /** Whether the registry's `history` gave it. */
92
+ readonly added: boolean;
93
+ }
94
+ /**
95
+ * What a voice was cued with that its handle does not carry. `Watched.voice` reports it.
96
+ *
97
+ * @category mix
98
+ */
99
+ export interface WatchedVoice {
100
+ readonly name: string | undefined;
101
+ readonly tags: readonly string[];
102
+ /**
103
+ * What it is bounded to, by `within` or an `around` weight. It is a circle, read live, or the
104
+ * host's finder; undefined for none.
105
+ */
106
+ readonly within: Readonly<Circle> | Finder | undefined;
107
+ }
74
108
  /**
75
109
  * What the host read in one frame.
76
110
  *
@@ -83,19 +117,33 @@ export interface WatchedFrame<I, O> {
83
117
  /** The host's timestamp at the frame's sync. */
84
118
  timestamp: number;
85
119
  /** Each probe, in order, with a copy of the pose it returned. */
86
- probed: {
87
- subject: I;
88
- pose: O;
89
- }[];
120
+ probed: Probed<I, O>[];
90
121
  /** Each pull, with copies of the columns it wrote. */
91
- pulled: {
92
- subjects: I[];
93
- columns: Record<string, Float64Array>;
94
- }[];
122
+ pulled: Pulled<I>[];
95
123
  /** What `drain` handed the host. */
96
124
  sent: Sent<I, unknown>[];
97
125
  voices: Handle<I>[];
98
126
  }
127
+ /**
128
+ * One probe a watched frame recorded.
129
+ *
130
+ * @category mix
131
+ */
132
+ export interface Probed<I, O> {
133
+ subject: I;
134
+ /** A copy of the pose the probe returned. */
135
+ pose: O;
136
+ }
137
+ /**
138
+ * One pull a watched frame recorded.
139
+ *
140
+ * @category mix
141
+ */
142
+ export interface Pulled<I> {
143
+ subjects: I[];
144
+ /** Copies of the columns it wrote, by channel. */
145
+ columns: Record<string, Float64Array>;
146
+ }
99
147
  /**
100
148
  * A mix's clock in a debugger's hands, and every mix's on the same transport. The host's `sync`
101
149
  * still begins each frame, but the frame's gap counts at `rate`, so the mix moves at `rate` times
@@ -109,7 +157,7 @@ export interface Hold {
109
157
  readonly mixes: Mix<unknown, unknown>[];
110
158
  /** The mix clock. */
111
159
  readonly now: number;
112
- /** The earliest mix time `seek` reaches: `now` without history and a tape. */
160
+ /** The earliest mix time `seek` reaches. It is `now` without history and a tape. */
113
161
  readonly reach: number;
114
162
  /** How much of each of the host's frames the held mix plays; 0 pauses it. Starts at 0. */
115
163
  rate: number;
@@ -118,9 +166,9 @@ export interface Hold {
118
166
  /** Plays the mixes `ms` of mix time further on, in one frame. */
119
167
  step(ms: number): void;
120
168
  /**
121
- * Gives the clock back: the host's next sync carries on from where the hold left the mix, and
122
- * its clock calls made meanwhile are made, in order. A call made while the tape holds later
123
- * calls acts on the mix but is not recorded, so those calls still play.
169
+ * Gives the clock back to the host. The host's next sync carries on from where the hold left the
170
+ * mix, and its clock calls made meanwhile are made, in order. A call made while the tape holds
171
+ * later calls acts on the mix but is not recorded, so those calls still play.
124
172
  */
125
173
  free(): void;
126
174
  }
package/dist/types.d.ts CHANGED
@@ -2,6 +2,7 @@ export type * from './types/arc.js';
2
2
  export type * from './types/channel.js';
3
3
  export type * from './types/history.js';
4
4
  export type * from './types/mix.js';
5
+ export type * from './types/motion.js';
5
6
  export type * from './types/patch.js';
6
7
  export type * from './types/place.js';
7
8
  export type * from './types/transport.js';