@msb235/blits 0.13.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 (178) hide show
  1. package/CHANGELOG.md +183 -0
  2. package/README.md +20 -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/closed.d.ts +1 -0
  21. package/dist/closed.js +45 -1
  22. package/dist/color.d.ts +12 -10
  23. package/dist/color.js +25 -25
  24. package/dist/columns.js +7 -3
  25. package/dist/contribution.d.ts +30 -0
  26. package/dist/contribution.js +374 -0
  27. package/dist/copyout.d.ts +10 -0
  28. package/dist/copyout.js +69 -24
  29. package/dist/crowd.d.ts +8 -2
  30. package/dist/crowd.js +4 -5
  31. package/dist/cue.d.ts +8 -1
  32. package/dist/cue.js +47 -14
  33. package/dist/cut.d.ts +8 -0
  34. package/dist/cut.js +4 -0
  35. package/dist/drop.d.ts +9 -0
  36. package/dist/drop.js +84 -0
  37. package/dist/due.d.ts +24 -5
  38. package/dist/due.js +113 -33
  39. package/dist/easing.d.ts +4 -4
  40. package/dist/easing.js +3 -3
  41. package/dist/everyone.d.ts +3 -2
  42. package/dist/everyone.js +3 -3
  43. package/dist/fade.d.ts +2 -1
  44. package/dist/fade.js +2 -1
  45. package/dist/fill.d.ts +3 -2
  46. package/dist/fill.js +51 -19
  47. package/dist/fit.d.ts +44 -26
  48. package/dist/fit.js +10 -9
  49. package/dist/fling.d.ts +66 -0
  50. package/dist/fling.js +162 -0
  51. package/dist/fold.d.ts +4 -37
  52. package/dist/fold.js +5 -512
  53. package/dist/gather.d.ts +12 -7
  54. package/dist/gather.js +179 -44
  55. package/dist/gone.js +2 -2
  56. package/dist/grid.d.ts +47 -0
  57. package/dist/grid.js +247 -0
  58. package/dist/handle.d.ts +3 -0
  59. package/dist/handle.js +19 -8
  60. package/dist/held.d.ts +2 -1
  61. package/dist/history.d.ts +6 -5
  62. package/dist/history.js +9 -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 +36 -6
  70. package/dist/lane.js +32 -1
  71. package/dist/lanes.d.ts +23 -8
  72. package/dist/lanes.js +29 -8
  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 +90 -4
  79. package/dist/mixer.d.ts +61 -35
  80. package/dist/mixer.js +64 -169
  81. package/dist/motion.d.ts +19 -106
  82. package/dist/motion.js +60 -13
  83. package/dist/motions.d.ts +62 -150
  84. package/dist/motions.js +57 -369
  85. package/dist/move.js +24 -1
  86. package/dist/moved.d.ts +1 -1
  87. package/dist/moved.js +16 -7
  88. package/dist/named.d.ts +0 -1
  89. package/dist/named.js +20 -2
  90. package/dist/numbers.d.ts +2 -0
  91. package/dist/numbers.js +4 -0
  92. package/dist/owed.d.ts +2 -0
  93. package/dist/owed.js +4 -0
  94. package/dist/pack.d.ts +3 -1
  95. package/dist/pack.js +4 -3
  96. package/dist/patch.d.ts +7 -3
  97. package/dist/patch.js +6 -2
  98. package/dist/places.d.ts +53 -0
  99. package/dist/places.js +171 -0
  100. package/dist/plot.d.ts +12 -0
  101. package/dist/plot.js +52 -0
  102. package/dist/project.d.ts +4 -4
  103. package/dist/project.js +9 -211
  104. package/dist/pull.js +11 -8
  105. package/dist/qualify.js +84 -21
  106. package/dist/reading.d.ts +6 -0
  107. package/dist/reading.js +5 -0
  108. package/dist/record.d.ts +5 -1
  109. package/dist/record.js +4 -2
  110. package/dist/relink.d.ts +1 -1
  111. package/dist/restored.d.ts +2 -2
  112. package/dist/restored.js +1 -1
  113. package/dist/rests.d.ts +9 -0
  114. package/dist/rests.js +76 -0
  115. package/dist/revive.d.ts +3 -2
  116. package/dist/revive.js +2 -2
  117. package/dist/{locus.d.ts → role.d.ts} +10 -9
  118. package/dist/{locus.js → role.js} +3 -3
  119. package/dist/roles.d.ts +10 -0
  120. package/dist/roles.js +158 -0
  121. package/dist/roster.js +3 -3
  122. package/dist/rotation.d.ts +1 -1
  123. package/dist/rotation.js +1 -1
  124. package/dist/rows.js +1 -1
  125. package/dist/sample.d.ts +2 -2
  126. package/dist/sample.js +33 -7
  127. package/dist/seek.js +13 -5
  128. package/dist/setting.d.ts +27 -0
  129. package/dist/setting.js +55 -0
  130. package/dist/shared.d.ts +1 -1
  131. package/dist/shared.js +1 -1
  132. package/dist/signals.d.ts +64 -32
  133. package/dist/signals.js +20 -18
  134. package/dist/stack.d.ts +5 -5
  135. package/dist/stack.js +5 -5
  136. package/dist/standing.d.ts +2 -1
  137. package/dist/standing.js +3 -2
  138. package/dist/store.d.ts +9 -0
  139. package/dist/store.js +24 -0
  140. package/dist/strays.d.ts +2 -1
  141. package/dist/strays.js +21 -14
  142. package/dist/stretch.d.ts +112 -0
  143. package/dist/stretch.js +9 -0
  144. package/dist/subject.d.ts +142 -0
  145. package/dist/subject.js +1 -0
  146. package/dist/tape.d.ts +9 -5
  147. package/dist/tape.js +5 -1
  148. package/dist/then.d.ts +9 -0
  149. package/dist/then.js +57 -0
  150. package/dist/ticker.d.ts +4 -4
  151. package/dist/transport.d.ts +0 -8
  152. package/dist/transport.js +0 -4
  153. package/dist/turns.d.ts +4 -3
  154. package/dist/turns.js +4 -3
  155. package/dist/types/arc.d.ts +12 -11
  156. package/dist/types/channel.d.ts +12 -8
  157. package/dist/types/history.d.ts +35 -19
  158. package/dist/types/mix.d.ts +222 -161
  159. package/dist/types/motion.d.ts +151 -0
  160. package/dist/types/motion.js +1 -0
  161. package/dist/types/patch.d.ts +69 -34
  162. package/dist/types/place.d.ts +51 -36
  163. package/dist/types/transport.d.ts +20 -18
  164. package/dist/types/voice.d.ts +145 -72
  165. package/dist/types/watch.d.ts +88 -40
  166. package/dist/types.d.ts +1 -0
  167. package/dist/voice.d.ts +9 -141
  168. package/dist/voice.js +30 -79
  169. package/dist/warn.d.ts +2 -0
  170. package/dist/warn.js +1 -1
  171. package/dist/watch.d.ts +2 -2
  172. package/dist/watch.js +5 -3
  173. package/dist/wave.d.ts +4 -3
  174. package/dist/wave.js +3 -2
  175. package/dist/weigh.d.ts +7 -1
  176. package/dist/weigh.js +27 -0
  177. package/docs/schema.html +223 -37
  178. package/package.json +6 -2
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';
package/dist/voice.d.ts CHANGED
@@ -1,5 +1,6 @@
1
1
  import type { Arc } from './arcs.js';
2
2
  import type { Blend } from './blend.js';
3
+ import type { Bound } from './bound.js';
3
4
  import { type Clock } from './clock.js';
4
5
  import { type Curve } from './easing.js';
5
6
  import type { Leavings } from './leavings.js';
@@ -8,149 +9,12 @@ import { Named } from './named.js';
8
9
  import type { Past } from './origin.js';
9
10
  import { Holding } from './owner.js';
10
11
  import { type Built, intosOf, type Scratch } from './patch.js';
11
- import type { Stamp } from './restored.js';
12
+ import { VoiceSetting } from './setting.js';
12
13
  import type { Fitting } from './spans.js';
13
14
  import { Store } from './store.js';
14
- import type { Anchor, Channel, FadeSpec, Handle, Patch, Setting, VoiceSpec } from './types.js';
15
- /**
16
- * A subject's record as it left a voice, faded out of it or dropped: the mix time and frame it
17
- * left at, and `sync` where it shows in its own frame: left in the frame's sync, or before anything
18
- * read the mix that frame.
19
- */
20
- export interface Left<I> {
21
- subject: I;
22
- at: number;
23
- seq: number;
24
- sync: boolean;
25
- held: Subject<unknown>;
26
- /**
27
- * The voice's fade of the subject as it stood on leaving, which a seek or read back to before
28
- * puts back: its ramp out, while running, or its having faded out.
29
- */
30
- ramp: Parting | null;
31
- parted: Parted | null;
32
- }
33
- /** A subject's ramp out of one voice: when it began, how long it runs, and the frame it was asked in. */
34
- export interface Parting {
35
- at: number;
36
- over: number;
37
- seq: number;
38
- }
39
- export interface Parted {
40
- at: number;
41
- seq: number;
42
- ramp: Parting | undefined;
43
- }
15
+ import type { Parted, Parting, Snap, Subject } from './subject.js';
16
+ import type { Anchor, Channel, FadeSpec, Handle, Patch, VoiceSpec } from './types.js';
44
17
  export declare const none: readonly string[];
45
- /**
46
- * What a copy of a record keeps for the seeks that put a record back from it: the copy's state
47
- * stepped on to `ticks`, as it stood near `at`, a moment one of them sought.
48
- */
49
- export interface Ahead<S> {
50
- /** The record the last seek put back, and the moment it sought, until that record steps. */
51
- put: Subject<S> | null;
52
- sought: number;
53
- /** The `since` of the record put back, which the steps in `state` were counted from. */
54
- since: number;
55
- at: number;
56
- ticks: number;
57
- /** Undefined until a record has stepped on from the copy. */
58
- state: S | undefined;
59
- /**
60
- * The state the record a seek replaced had stepped on to from the copy, at `leftTicks`; undefined
61
- * until one had.
62
- */
63
- leftTicks: number;
64
- left: S | undefined;
65
- }
66
- /** A copy of a record kept under `history`, by the mix time and frame it was taken at. */
67
- export interface Snap<S> {
68
- at: number;
69
- seq: number;
70
- held: Subject<S>;
71
- ahead?: Ahead<S>;
72
- /** Set where another record's list holds it too, so a seek cutting it from one lets go of it. */
73
- shared?: true;
74
- }
75
- /** Everything one voice holds for one subject, chained through the next voice that reaches it. */
76
- export interface Subject<S> {
77
- /** The voice's `target` answer, fixed on first sight. */
78
- reaches: boolean;
79
- /** The voice's `stagger` answer in voice ms, fixed on first sight. */
80
- delay: number;
81
- /** The mix timestamp this subject's delay ran out at, which its step grid counts from. */
82
- since: number;
83
- /** The mix timestamp its fade in counts from: `since`, or earlier for a voice freezing before. */
84
- shown: number;
85
- /** The weight this voice gave this subject the last frame it was probed, 0 where it gave none. */
86
- weight: number;
87
- /** Left at rest during a handover, so it stops contributing. */
88
- rested: boolean;
89
- /**
90
- * Per written channel, whether a rest-less contribution is on: 0 unknown, 1 on, 2 off; null until
91
- * a rest-less channel asks.
92
- */
93
- bands: Uint8Array | null;
94
- state: S;
95
- /** The `now` this subject last caught up to, for this voice. */
96
- stepped: number;
97
- /** Under `stepMs`, how many intervals have run since `since`; `stepped` is where that lands. */
98
- ticks: number;
99
- /** The `now` this subject was last probed at, so twelve probes in a frame step once. */
100
- probed: number;
101
- /** The last delta computed this frame, handed back to a repeat probe unchanged. */
102
- delta: Record<string, unknown> | null;
103
- /** The phase `delta` was read at, to read it again once its voice's scratch has moved on. */
104
- phase: number;
105
- /** The voice's `seeks` when `delta` was read, so a seek later in the frame reads it again. */
106
- seeks: number;
107
- /** The voice's `rebuilds` when its state was last made, so a seek's rebuild reaches it once. */
108
- rebuilt: number;
109
- /** Its kept signal state was stepped on in one go from a copy history kept, by a seek. */
110
- copied: boolean;
111
- /** Stop 0 for a `from: 'current'` voice, taken the first frame this subject is seen. */
112
- base?: Record<string, unknown>;
113
- /** The pose's velocity per channel at that moment, units per ms, so the first segment leaves at it. */
114
- slope?: Record<string, unknown>;
115
- /** What `setting.keep` holds for this voice and subject, by owner; null until it holds any. */
116
- kept: Map<object, unknown> | null;
117
- /** Kept state a history store gave back, which each owner takes in turn on its first keep. */
118
- unkept?: unknown[];
119
- /** Under `history`, copies of this record by the mix time they were taken, oldest first. */
120
- snaps?: Snap<S>[];
121
- /** In a projection: where this record started from, and whether nothing known could be. */
122
- from?: number;
123
- unknown?: boolean;
124
- /** Under `history` with `inputs`, what an input weight signal read for this subject, when it changed. */
125
- inputs?: {
126
- at: number;
127
- seq: number;
128
- value: number;
129
- }[];
130
- /** In a projection reading back: that record, to read in place of the signal. */
131
- replay?: {
132
- at: number;
133
- value: number;
134
- }[];
135
- /** The voice this is the record of; null on a subject's stub. */
136
- voice: object | null;
137
- /** The next voice's record for this subject, in voice order, among those that reach it. */
138
- next: Subject<unknown> | null;
139
- /**
140
- * On the first record, which the mix keeps per subject so a probe makes one lookup: the `version`
141
- * the chain was linked at, and per locus, by channel slot, whether a rest-less contribution is on:
142
- * 0 never decided, 1 on, 2 off.
143
- */
144
- version: number;
145
- loci: Map<string, Uint8Array> | null;
146
- /** On the first record: the number lanes index this subject by, -1 without one. */
147
- slot: number;
148
- /** A motion voice's number for this subject in its patch, good while `freed` is the patch's own. */
149
- run: number;
150
- freed: number;
151
- /** In a voice's store once a seek has gone back, the stamp of the seek it was last put back or written at. */
152
- restored: Stamp | null;
153
- }
154
18
  /** A voice's clock, weight and fade from one mix time on, kept under `history`. */
155
19
  export interface Controls extends Clock {
156
20
  at: number;
@@ -299,7 +163,7 @@ export declare class Voice<I, O> {
299
163
  /** The clocks it ran on before its current one, where a subject's origin may lie; null for none. */
300
164
  clocks: Past[] | null;
301
165
  /** Reused for every call this voice makes, so it is valid only during the call. */
302
- readonly setting: Setting<unknown>;
166
+ readonly setting: VoiceSetting<I, O>;
303
167
  /** Every subject this voice has been asked about, so a handover knows when it is finished. */
304
168
  seen: number;
305
169
  /** The longest stagger of any subject seen, so a finite loop waits for the last of them. */
@@ -333,6 +197,8 @@ export declare class Voice<I, O> {
333
197
  outSet: boolean;
334
198
  /** The host time a pinned start was given at, NaN for none: a seek back pins it again. */
335
199
  pinned: number;
200
+ /** Cued with no start while its mix slept, so the next sync sets its start. */
201
+ waking: boolean;
336
202
  /** Whether its start is still to be fixed by an anchor, so it waits pending. */
337
203
  placing: boolean;
338
204
  /** What each member of a join last answered, kept for once its target has left. */
@@ -359,6 +225,8 @@ export declare class Voice<I, O> {
359
225
  unreachedBits: Uint32Array | null;
360
226
  /** Whether one record stands for every subject: see `shares` in `everyone.ts`. */
361
227
  sharing: boolean;
228
+ /** Where its signal is declared 0, its cue's `within`, so it is not read there: see `bound.ts`. */
229
+ bound: Bound<I, O> | null;
362
230
  /** The frames it has played sharing it. */
363
231
  shared: number;
364
232
  /** That record, null until a chain first asks and once the voice shares no more. */
package/dist/voice.js CHANGED
@@ -4,87 +4,33 @@ import { motionOf } from './motion.js';
4
4
  import { Named } from './named.js';
5
5
  import { childPlayed, Holding, mixTime, ownedElapsed, ownerPatch, ownerReading, turnedBack, } from './owner.js';
6
6
  import { builtOf, intosOf } from './patch.js';
7
- import { reading } from './reading.js';
8
- import { Store } from './store.js';
7
+ import { keeping, VoiceSetting } from './setting.js';
8
+ import { Filled, Store } from './store.js';
9
9
  import { warnOnce } from './warn.js';
10
10
  export const none = Object.freeze([]);
11
- /**
12
- * A voice's `setting.keep`, one per voice: a setting is valid only during its call, so the state
13
- * goes on the record of the subject being called for, `keepOn`, or on the voice before any is.
14
- */
15
- function keeping(voice) {
16
- return function keep(owner, init) {
17
- const held = voice.keepOn;
18
- let kept = held === null ? voice.ownKept : held.kept;
19
- if (kept === null) {
20
- kept = new Map();
21
- if (held === null)
22
- voice.ownKept = kept;
23
- else
24
- held.kept = kept;
25
- }
26
- if (kept.has(owner))
27
- return kept.get(owner);
28
- const unkept = held?.unkept;
29
- const made = unkept === undefined ? init() : unkept.shift();
30
- if (unkept?.length === 0 && held !== null)
31
- held.unkept = undefined;
32
- kept.set(owner, made);
33
- reading.kept++;
34
- return made;
35
- };
36
- }
37
- /**
38
- * A voice's setting. `keep` is made on first read: most patches keep no state, and a closure and
39
- * its context per voice cost a one-subject tween voice about 100 bytes.
40
- */
41
- class VoiceSetting {
42
- host;
43
- send;
44
- voice;
45
- timestamp = 0;
46
- dt = 0;
47
- elapsed = 0;
48
- pass = 0;
49
- weight = 0;
50
- state = undefined;
51
- kept = null;
52
- constructor(host, send, voice) {
53
- this.host = host;
54
- this.send = send;
55
- this.voice = voice;
56
- }
57
- get keep() {
58
- if (this.kept === null)
59
- this.kept = keeping(this.voice);
60
- return this.kept;
61
- }
11
+ const noSend = () => { };
12
+ /** By a mix's `slotOf`, the slots and lerps of a patch writing one channel, shared by its voices. */
13
+ const writings = new WeakMap();
14
+ function writing(writes, slotOf, channels) {
15
+ if (writes.length !== 1)
16
+ return written(writes, slotOf, channels);
17
+ let known = writings.get(slotOf);
18
+ if (known === undefined) {
19
+ known = new Map();
20
+ writings.set(slotOf, known);
21
+ }
22
+ const key = writes[0];
23
+ let found = known.get(key);
24
+ if (found === undefined) {
25
+ found = written(writes, slotOf, channels);
26
+ known.set(key, found);
27
+ }
28
+ return found;
62
29
  }
63
- /** A store that fills a missing entry from `make` on first ask. */
64
- class Filled extends Store {
65
- make;
66
- /** Keys deleted here, which are made afresh by whoever asks and never again by `make`. */
67
- gone = null;
68
- constructor(make) {
69
- super();
70
- this.make = make;
71
- }
72
- get(key) {
73
- let v = super.get(key);
74
- if (v === undefined && this.gone?.get(key) !== true) {
75
- v = this.make(key);
76
- if (v !== undefined)
77
- super.set(key, v);
78
- }
79
- return v;
80
- }
81
- delete(key) {
82
- super.delete(key);
83
- this.gone ??= new Store();
84
- this.gone.set(key, true);
85
- }
30
+ function written(writes, slotOf, channels) {
31
+ const slots = writes.map((k) => slotOf.get(k));
32
+ return { slots, lerps: slots.map((slot) => channels[slot].lerp) };
86
33
  }
87
- const noSend = () => { };
88
34
  export class Voice {
89
35
  id;
90
36
  spec;
@@ -226,6 +172,8 @@ export class Voice {
226
172
  outSet = false;
227
173
  /** The host time a pinned start was given at, NaN for none: a seek back pins it again. */
228
174
  pinned = Number.NaN;
175
+ /** Cued with no start while its mix slept, so the next sync sets its start. */
176
+ waking = false;
229
177
  /** Whether its start is still to be fixed by an anchor, so it waits pending. */
230
178
  placing = false;
231
179
  /** What each member of a join last answered, kept for once its target has left. */
@@ -249,6 +197,8 @@ export class Voice {
249
197
  unreachedBits = null;
250
198
  /** Whether one record stands for every subject: see `shares` in `everyone.ts`. */
251
199
  sharing = false;
200
+ /** Where its signal is declared 0, its cue's `within`, so it is not read there: see `bound.ts`. */
201
+ bound = null;
252
202
  /** The frames it has played sharing it. */
253
203
  shared = 0;
254
204
  /** That record, null until a chain first asks and once the voice shares no more. */
@@ -441,10 +391,11 @@ export class Voice {
441
391
  this.start = start;
442
392
  this.owner = owner;
443
393
  this.holding = patch === ownerPatch ? new Holding() : null;
444
- this.slots = patch.writes.map((k) => slotOf.get(k));
394
+ const wrote = writing(patch.writes, slotOf, channels);
395
+ this.slots = wrote.slots;
445
396
  this.named = spec.subjects ? new Named(spec.subjects) : null;
446
397
  this.built = patch.form === 'keys' && patch.keys ? builtOf(patch) : null;
447
- this.lerps = this.slots.map((slot) => channels[slot].lerp);
398
+ this.lerps = wrote.lerps;
448
399
  this.intos = this.built
449
400
  ? intosOf(this.built, this.slots.map((slot) => channels[slot]))
450
401
  : undefined;
package/dist/warn.d.ts CHANGED
@@ -1,2 +1,4 @@
1
+ /** Whether this is a production build: a bundler's `NODE_ENV`, or Node's; false where neither is. */
2
+ export declare function production(): boolean;
1
3
  /** Warns outside production, once for each `about`. */
2
4
  export declare function warnOnce(about: object, message: string): void;
package/dist/warn.js CHANGED
@@ -1,5 +1,5 @@
1
1
  /** Whether this is a production build: a bundler's `NODE_ENV`, or Node's; false where neither is. */
2
- function production() {
2
+ export function production() {
3
3
  try {
4
4
  return process.env.NODE_ENV === 'production';
5
5
  }
package/dist/watch.d.ts CHANGED
@@ -2,8 +2,8 @@ import type { Mixer } from './mixer.js';
2
2
  import type { MixOptions, Registry } from './types.js';
3
3
  type Any = Mixer<unknown, unknown>;
4
4
  /**
5
- * Every mix made on the page, shared by every copy of blits loaded: what a debugger reads to find
6
- * them. See `Registry`.
5
+ * The registry a debugger reads to find every mix made on the page. It is shared by every copy of
6
+ * blits loaded. See `Registry`.
7
7
  *
8
8
  * @category mix
9
9
  */
package/dist/watch.js CHANGED
@@ -4,8 +4,8 @@ import { hostAhead } from './tape.js';
4
4
  const KEY = Symbol.for('@msb235/blits/watch/1');
5
5
  const slot = globalThis;
6
6
  /**
7
- * Every mix made on the page, shared by every copy of blits loaded: what a debugger reads to find
8
- * them. See `Registry`.
7
+ * The registry a debugger reads to find every mix made on the page. It is shared by every copy of
8
+ * blits loaded. See `Registry`.
9
9
  *
10
10
  * @category mix
11
11
  */
@@ -90,7 +90,9 @@ export function register(mix) {
90
90
  channels: mix.names,
91
91
  voice: (handle) => {
92
92
  const v = mix.cued.find((c) => c.handle === handle) ?? mix.gone.find((c) => c.handle === handle);
93
- return v === undefined ? undefined : { name: v.spec.name, tags: v.spec.tags ?? [] };
93
+ return v === undefined
94
+ ? undefined
95
+ : { name: v.spec.name, tags: v.spec.tags ?? [], within: v.bound?.area };
94
96
  },
95
97
  label: (subject) => labelOf(mix, subject),
96
98
  watch: (fn) => tap(mix, fn),
package/dist/wave.d.ts CHANGED
@@ -11,7 +11,7 @@ export type WaveShape = 'sine' | 'triangle' | 'saw' | 'square';
11
11
  * @category patch
12
12
  */
13
13
  export interface WaveOptions<O> {
14
- /** Default 'sine'. */
14
+ /** The wave's form: 'sine', 'triangle', 'saw' or 'square'. Default 'sine'. */
15
15
  shape?: WaveShape;
16
16
  /** Whole or fractional cycles per pass of the patch's duration. Default 1. */
17
17
  cycles?: number;
@@ -27,13 +27,14 @@ export interface WaveOptions<O> {
27
27
  kit?: Partial<Kit<O>>;
28
28
  }
29
29
  /**
30
- * The unit wave: -1..1 at `x` cycles, starting at 0 and rising (square: +1 for the first half).
30
+ * The unit wave's value at `x` cycles, from -1 to 1. It starts at 0 and rises (square: +1 for the
31
+ * first half).
31
32
  *
32
33
  * @category patch
33
34
  */
34
35
  export declare function waveAt(shape: WaveShape, x: number): number;
35
36
  /**
36
- * A periodic swing on each channel `depth` names, around its rest: an LFO for a bob, a sway or a
37
+ * A periodic swing on each channel `depth` names, around its rest. An LFO for a bob, a sway or a
37
38
  * pulse. An `fn` patch that keeps its options on `patch.wave`, for an engine reading the wave
38
39
  * rather than calling it.
39
40
  *
package/dist/wave.js CHANGED
@@ -1,6 +1,7 @@
1
1
  import { patch } from './patch.js';
2
2
  /**
3
- * The unit wave: -1..1 at `x` cycles, starting at 0 and rising (square: +1 for the first half).
3
+ * The unit wave's value at `x` cycles, from -1 to 1. It starts at 0 and rises (square: +1 for the
4
+ * first half).
4
5
  *
5
6
  * @category patch
6
7
  */
@@ -39,7 +40,7 @@ function planOf(opts) {
39
40
  return plan;
40
41
  }
41
42
  /**
42
- * A periodic swing on each channel `depth` names, around its rest: an LFO for a bob, a sway or a
43
+ * A periodic swing on each channel `depth` names, around its rest. An LFO for a bob, a sway or a
43
44
  * pulse. An `fn` patch that keeps its options on `patch.wave`, for an engine reading the wave
44
45
  * rather than calling it.
45
46
  *
package/dist/weigh.d.ts CHANGED
@@ -1,5 +1,6 @@
1
1
  import type { Mixer } from './mixer.js';
2
- import type { Subject, Voice } from './voice.js';
2
+ import type { Subject } from './subject.js';
3
+ import type { Voice } from './voice.js';
3
4
  /**
4
5
  * Where `prime` reads its numbers in `Mixer.primed`: as arguments, each would be boxed wherever V8
5
6
  * does not inline the call, which turns on the order its compiles ran (bench/frame.mjs `glow`,
@@ -13,6 +14,11 @@ export declare const enum Primed {
13
14
  }
14
15
  /** Fills a voice's setting for a call to its patch, the weight aside, from `primed`. */
15
16
  export declare function prime<I, O>(this: Mixer<I, O>, voice: Voice<I, O>, held: Subject<unknown>): void;
17
+ /**
18
+ * `prime` for a lane's call, from `arg`: the per-lane fields only where the setting was not
19
+ * already filled under `Arg.MARK`, since nothing but the engine writes a setting.
20
+ */
21
+ export declare function primeLaned<I, O>(this: Mixer<I, O>, voice: Voice<I, O>, held: Subject<unknown>, arg: Float64Array): void;
16
22
  /** A gap as a `dt`: Infinity under reduced motion, and no more than `maxDt`. */
17
23
  export declare function capped<I, O>(this: Mixer<I, O>, gap: number): number;
18
24
  /** The earliest voice time a read may still ask for, for a subject delayed `delay`. */
package/dist/weigh.js CHANGED
@@ -17,8 +17,35 @@ export function prime(voice, held) {
17
17
  setting.pass = pass;
18
18
  setting.weight = 0;
19
19
  setting.state = held.state;
20
+ setting.mark = 0;
20
21
  voice.keepOn = held;
21
22
  }
23
+ /**
24
+ * `prime` for a lane's call, from `arg`: the per-lane fields only where the setting was not
25
+ * already filled under `Arg.MARK`, since nothing but the engine writes a setting.
26
+ */
27
+ export function primeLaned(voice, held, arg) {
28
+ const now = this.now;
29
+ const setting = voice.setting;
30
+ if (setting.mark !== arg[6 /* Arg.MARK */])
31
+ markSetting(setting, now, arg);
32
+ if (voice.patch.step === undefined && held.probed < now)
33
+ held.stepped = held.probed;
34
+ setting.dt = this.capped(now - held.stepped);
35
+ setting.weight = 0;
36
+ setting.state = held.state;
37
+ voice.keepOn = held;
38
+ }
39
+ /**
40
+ * `primeLaned`'s once-a-lane fields, kept out of it so it fits `one`'s inlining budget beside
41
+ * `signalled`, which otherwise took its place (`glow^` 4.5% faster, 2026-10-28).
42
+ */
43
+ function markSetting(setting, now, arg) {
44
+ setting.timestamp = now;
45
+ setting.elapsed = arg[1 /* Arg.ELAPSED */];
46
+ setting.pass = arg[3 /* Arg.PASS */];
47
+ setting.mark = arg[6 /* Arg.MARK */];
48
+ }
22
49
  /** A gap as a `dt`: Infinity under reduced motion, and no more than `maxDt`. */
23
50
  export function capped(gap) {
24
51
  const cap = this.opts.maxDt;