@msb235/blits 0.10.0 → 0.12.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.
- package/CHANGELOG.md +248 -0
- package/README.md +15 -4
- package/dist/arcs.d.ts +40 -0
- package/dist/arcs.js +239 -0
- package/dist/blend.js +1 -5
- package/dist/book.d.ts +2 -0
- package/dist/book.js +27 -3
- package/dist/chain.d.ts +17 -1
- package/dist/chain.js +57 -15
- package/dist/channels.d.ts +2 -0
- package/dist/channels.js +12 -1
- package/dist/clock.d.ts +14 -0
- package/dist/clock.js +9 -1
- package/dist/clone.js +16 -4
- package/dist/columns.d.ts +4 -5
- package/dist/columns.js +11 -5
- package/dist/crowd.d.ts +1 -1
- package/dist/crowd.js +4 -1
- package/dist/cue.js +63 -7
- package/dist/departed.d.ts +8 -3
- package/dist/departed.js +76 -29
- package/dist/due.d.ts +4 -0
- package/dist/due.js +16 -3
- package/dist/easing.d.ts +12 -1
- package/dist/easing.js +7 -1
- package/dist/everyone.d.ts +14 -1
- package/dist/everyone.js +27 -2
- package/dist/fade.d.ts +12 -5
- package/dist/fade.js +57 -19
- package/dist/fill.js +16 -9
- package/dist/fit.d.ts +8 -1
- package/dist/fit.js +7 -3
- package/dist/fold.d.ts +1 -1
- package/dist/fold.js +112 -9
- package/dist/frames.d.ts +2 -0
- package/dist/frames.js +17 -0
- package/dist/gather.js +38 -7
- package/dist/handle.d.ts +7 -2
- package/dist/handle.js +28 -12
- package/dist/held.d.ts +13 -2
- package/dist/held.js +43 -9
- package/dist/history.d.ts +25 -2
- package/dist/history.js +163 -35
- package/dist/hosts.js +45 -17
- package/dist/index.d.ts +5 -2
- package/dist/index.js +3 -1
- package/dist/keyfill.js +3 -1
- package/dist/lane.d.ts +1 -1
- package/dist/lane.js +3 -1
- package/dist/lanes.d.ts +31 -7
- package/dist/lanes.js +57 -6
- package/dist/lean.d.ts +15 -0
- package/dist/lean.js +23 -0
- package/dist/leavings.d.ts +6 -1
- package/dist/leavings.js +16 -2
- package/dist/marks.d.ts +7 -3
- package/dist/marks.js +105 -27
- package/dist/meet.js +1 -0
- package/dist/mixer.d.ts +35 -6
- package/dist/mixer.js +113 -45
- package/dist/motion.d.ts +4 -1
- package/dist/motion.js +16 -2
- package/dist/motions.d.ts +4 -0
- package/dist/motions.js +45 -11
- package/dist/move.js +35 -12
- package/dist/numbers.d.ts +5 -1
- package/dist/numbers.js +4 -0
- package/dist/owner.d.ts +18 -2
- package/dist/owner.js +44 -3
- package/dist/pack.d.ts +1 -0
- package/dist/pack.js +3 -0
- package/dist/place.d.ts +8 -0
- package/dist/place.js +16 -8
- package/dist/placed.d.ts +19 -0
- package/dist/placed.js +54 -0
- package/dist/project.d.ts +5 -2
- package/dist/project.js +238 -34
- package/dist/pull.js +37 -8
- package/dist/qualify.d.ts +10 -0
- package/dist/qualify.js +60 -3
- package/dist/reading.d.ts +8 -1
- package/dist/reading.js +8 -1
- package/dist/record.d.ts +6 -0
- package/dist/record.js +2 -0
- package/dist/restored.d.ts +69 -17
- package/dist/restored.js +163 -50
- package/dist/revive.d.ts +6 -3
- package/dist/revive.js +11 -3
- package/dist/roster.js +2 -1
- package/dist/rows.js +15 -5
- package/dist/seek.d.ts +7 -2
- package/dist/seek.js +152 -43
- package/dist/shared.d.ts +5 -0
- package/dist/shared.js +5 -0
- package/dist/signals.d.ts +10 -0
- package/dist/signals.js +17 -0
- package/dist/spans.d.ts +5 -0
- package/dist/spans.js +75 -5
- package/dist/store.d.ts +13 -0
- package/dist/store.js +23 -0
- package/dist/strays.js +50 -2
- package/dist/tape.d.ts +29 -4
- package/dist/tape.js +49 -11
- package/dist/touch.js +3 -2
- package/dist/transport.d.ts +11 -2
- package/dist/transport.js +26 -10
- package/dist/types/arc.d.ts +55 -0
- package/dist/types/arc.js +1 -0
- package/dist/types/mix.d.ts +57 -14
- package/dist/types/patch.d.ts +5 -1
- package/dist/types/place.d.ts +11 -4
- package/dist/types/transport.d.ts +12 -3
- package/dist/types/voice.d.ts +72 -5
- package/dist/types/watch.d.ts +126 -0
- package/dist/types/watch.js +1 -0
- package/dist/types.d.ts +2 -0
- package/dist/unpage.d.ts +6 -1
- package/dist/unpage.js +34 -2
- package/dist/voice.d.ts +93 -16
- package/dist/voice.js +60 -3
- package/dist/watch.d.ts +26 -0
- package/dist/watch.js +441 -0
- package/dist/weigh.d.ts +13 -2
- package/dist/weigh.js +10 -3
- package/docs/schema.html +106 -38
- package/package.json +10 -4
package/dist/types/voice.d.ts
CHANGED
|
@@ -3,7 +3,7 @@ import type { Motion, Value } from '../motion.js';
|
|
|
3
3
|
import type { Described } from './history.js';
|
|
4
4
|
import type { Doubt } from './mix.js';
|
|
5
5
|
import type { Easing, Patch, Signal } from './patch.js';
|
|
6
|
-
import type { Hit, Placement } from './place.js';
|
|
6
|
+
import type { Anchor, Hit, Placement } from './place.js';
|
|
7
7
|
/**
|
|
8
8
|
* A voice's own ramps in and out, in ms, and the curve both take.
|
|
9
9
|
*
|
|
@@ -31,6 +31,15 @@ export interface SpanHints {
|
|
|
31
31
|
ballast?: boolean;
|
|
32
32
|
/** How hard its own length holds against the span's budget. Default `weak`. */
|
|
33
33
|
priority?: Strength;
|
|
34
|
+
/**
|
|
35
|
+
* The soonest it may start: a time on the span's clock, or an anchor. The fit never places it
|
|
36
|
+
* sooner, and the children after it are laid out from where it starts. One already past when it is
|
|
37
|
+
* cued places it there, partway through. One whose anchor has no answer yet waits, and under `queue` or
|
|
38
|
+
* `stagger` so does every child after it.
|
|
39
|
+
*/
|
|
40
|
+
earliest?: number | Anchor;
|
|
41
|
+
/** Where it plays among the span's children still to start: lower first, ties as cued. Default 0. */
|
|
42
|
+
rank?: number;
|
|
34
43
|
}
|
|
35
44
|
/**
|
|
36
45
|
* What `cue` takes: a patch, and the clock, weight and reach it plays with.
|
|
@@ -81,10 +90,24 @@ export interface VoiceSpec<I, O, H = unknown> extends SpanHints {
|
|
|
81
90
|
* so one cued backward with no `seek` has ended as it starts.
|
|
82
91
|
*/
|
|
83
92
|
seek?: number;
|
|
93
|
+
/**
|
|
94
|
+
* The interval this voice's `step` runs at, in ms of mix time, in place of the mix's `stepMs`.
|
|
95
|
+
* 0 steps it once a frame by the frame's gap, whatever the mix sets. Default: the mix's.
|
|
96
|
+
*/
|
|
97
|
+
stepMs?: number;
|
|
98
|
+
/**
|
|
99
|
+
* How a stateful subject first probed after its delay ran out starts stepping. `exact` steps it
|
|
100
|
+
* from that origin, in one step capped by `maxDt` or every `stepMs` interval since, so its state
|
|
101
|
+
* is the same however late the host looked. `fresh` starts it from the probe that first meets it,
|
|
102
|
+
* with fresh state and no catch-up, on the `stepMs` grid counted from the origin: cheaper for a
|
|
103
|
+
* subject met long after its voice started, and probe-dependent by design. A subject met on time,
|
|
104
|
+
* and a handle `seek`'s rebuild, step the same either way. Default: `exact`.
|
|
105
|
+
*/
|
|
106
|
+
catchUp?: 'exact' | 'fresh';
|
|
84
107
|
/**
|
|
85
108
|
* true loops for good, false plays one pass, n plays n passes. A finite loop leaves when its
|
|
86
109
|
* passes are done for the latest-staggered subject it has seen — over `fade.out` where one is
|
|
87
|
-
* set, at once where none is — unless it freezes after. Default:
|
|
110
|
+
* set, at once where none is — unless it freezes after. Default: false.
|
|
88
111
|
*/
|
|
89
112
|
loop?: boolean | number;
|
|
90
113
|
/**
|
|
@@ -127,6 +150,14 @@ export interface VoiceSpec<I, O, H = unknown> extends SpanHints {
|
|
|
127
150
|
* events are not known ahead, so they stay drain-only; these are the plan.
|
|
128
151
|
*/
|
|
129
152
|
hits?: readonly Hit[];
|
|
153
|
+
/**
|
|
154
|
+
* Named marks inside the voice, beside its five, each at voice ms into a pass as a hit's `at` is:
|
|
155
|
+
* `{ drop: 340 }`. An anchor names one as it names the five, `{ of: 'lead', mark: 'drop' }`, and
|
|
156
|
+
* `marks` lists it and `book` books it under its name. Each is reached once: on the first pass
|
|
157
|
+
* that reaches it from where the voice starts, while its clock runs forward and before it ends.
|
|
158
|
+
* A name cannot be one of the five.
|
|
159
|
+
*/
|
|
160
|
+
marks?: Readonly<Record<string, number>>;
|
|
130
161
|
/**
|
|
131
162
|
* The owner this voice plays under, a handle `owns` returned. Its `start` and `anchor` are then on
|
|
132
163
|
* the owner's clock, in ms from when the owner starts, and default to where that clock is now; a
|
|
@@ -136,6 +167,22 @@ export interface VoiceSpec<I, O, H = unknown> extends SpanHints {
|
|
|
136
167
|
*/
|
|
137
168
|
owner?: Handle<I>;
|
|
138
169
|
}
|
|
170
|
+
/**
|
|
171
|
+
* One of `mix.blend`'s members, with the labels it carries in place of the spec's: each set here
|
|
172
|
+
* replaces the spec's for this member alone. The rest of the spec times and places every member
|
|
173
|
+
* alike, so they stay one blend.
|
|
174
|
+
*
|
|
175
|
+
* @category blending
|
|
176
|
+
*/
|
|
177
|
+
export interface BlendMember<I, O, H = unknown> {
|
|
178
|
+
patch: Patch<I, O, unknown, H>;
|
|
179
|
+
/** What other voices call this member by. Default: the spec's `name`. */
|
|
180
|
+
name?: string;
|
|
181
|
+
/** Default: the spec's `tags`. */
|
|
182
|
+
tags?: readonly string[];
|
|
183
|
+
/** Events at times on this member's clock, as a voice's `hits`. Default: the spec's. */
|
|
184
|
+
hits?: readonly Hit[];
|
|
185
|
+
}
|
|
139
186
|
/**
|
|
140
187
|
* What `owns` takes: an owner has no patch, and plays only through the voices it holds.
|
|
141
188
|
*
|
|
@@ -147,8 +194,19 @@ export interface OwnerSpec<I, H = unknown> extends SpanHints {
|
|
|
147
194
|
* voice's `start` is. Default: now.
|
|
148
195
|
*/
|
|
149
196
|
start?: number;
|
|
150
|
-
/**
|
|
197
|
+
/**
|
|
198
|
+
* Its clock's rate, multiplied into every child's own. Default 1. Below 0 its clock runs back,
|
|
199
|
+
* and so does every child's: a child plays backward to its start and leaves there, as a voice cued
|
|
200
|
+
* backward does, and the owner leaves with its last child. A span is not cued backward, since it
|
|
201
|
+
* lays out its children forward from its start; its handle's `rate` turns it once it plays.
|
|
202
|
+
*/
|
|
151
203
|
rate?: number;
|
|
204
|
+
/**
|
|
205
|
+
* Where its clock starts, ms, as `seek` on its handle sets: its children play as far in as that
|
|
206
|
+
* puts them. Default 0, cued backward too, since an owner has no end of its own to start from; one
|
|
207
|
+
* cued at a rate below 0 with no seek runs back from 0, before any child placed on its clock.
|
|
208
|
+
*/
|
|
209
|
+
seek?: number;
|
|
152
210
|
/**
|
|
153
211
|
* Multiplied into every child's weight per subject, as the child's own fade is, before the child's
|
|
154
212
|
* locus folds it: a number, or a signal read per subject per frame. Default 1.
|
|
@@ -166,6 +224,14 @@ export interface OwnerSpec<I, H = unknown> extends SpanHints {
|
|
|
166
224
|
score?: string;
|
|
167
225
|
/** Where it sits relative to its own owner's clock or to other voices, in place of `start`. */
|
|
168
226
|
anchor?: Placement;
|
|
227
|
+
/**
|
|
228
|
+
* Events at times on its own clock, the one its children's `start` counts on, which `book`
|
|
229
|
+
* hands a host ahead of time with its `score` and `tags`. An owner does not loop, so each is
|
|
230
|
+
* booked once, while it plays: none past where it leaves, and none while its clock runs back.
|
|
231
|
+
*/
|
|
232
|
+
hits?: readonly Hit[];
|
|
233
|
+
/** Named marks at times on its own clock, as a voice's `marks`. */
|
|
234
|
+
marks?: Readonly<Record<string, number>>;
|
|
169
235
|
/** The owner it plays under, so owners nest. */
|
|
170
236
|
owner?: Handle<I>;
|
|
171
237
|
}
|
|
@@ -294,7 +360,8 @@ export interface Handle<I = unknown> {
|
|
|
294
360
|
* Turns a fade out around: the voice climbs back from where its fade had got to, up the same
|
|
295
361
|
* curve, over `over` ms for the whole curve (default its `fade.in`, else its `fade.out`), and
|
|
296
362
|
* plays on as if never faded. A fade waiting for rest is taken back at once; a voice not fading
|
|
297
|
-
* is left as it is. A voice whose own end began the fade starts it again at its next frame.
|
|
363
|
+
* is left as it is. A voice whose own end began the fade starts it again at its next frame. A
|
|
364
|
+
* voice faded before its start goes back to `pending` and starts on time.
|
|
298
365
|
*/
|
|
299
366
|
rise(opts?: {
|
|
300
367
|
over?: number;
|
|
@@ -303,7 +370,7 @@ export interface Handle<I = unknown> {
|
|
|
303
370
|
* The weight this voice gave `subject` the last frame that subject was probed: after its fades
|
|
304
371
|
* and its weight signal, before a locus folds it with its alternatives. 0 for a subject it does
|
|
305
372
|
* not reach, has not started on and does not freeze before, has left at rest, or has never been
|
|
306
|
-
* probed for; 0 once done.
|
|
373
|
+
* probed for; 0 once done, and 0 after `mix.seek` goes back until the subject is probed again.
|
|
307
374
|
* Costs nothing until it is asked.
|
|
308
375
|
*/
|
|
309
376
|
weightOf(subject: I): number;
|
|
@@ -0,0 +1,126 @@
|
|
|
1
|
+
import type { HistoryOptions } from './history.js';
|
|
2
|
+
import type { Mix } from './mix.js';
|
|
3
|
+
import type { Sent } from './patch.js';
|
|
4
|
+
import type { Handle } from './voice.js';
|
|
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.
|
|
8
|
+
*
|
|
9
|
+
* @category mix
|
|
10
|
+
*/
|
|
11
|
+
export interface Registry {
|
|
12
|
+
/** The mixes still alive, in the order they were made. */
|
|
13
|
+
entries(): Watched[];
|
|
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;
|
|
22
|
+
/**
|
|
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.
|
|
25
|
+
*/
|
|
26
|
+
history: HistoryOptions | undefined;
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* One mix as a debugger sees it. Built by the copy of blits that made the mix, so a debugger
|
|
30
|
+
* reads mixes from other releases through it alike.
|
|
31
|
+
*
|
|
32
|
+
* @category mix
|
|
33
|
+
*/
|
|
34
|
+
export interface Watched<I = unknown, O = unknown> {
|
|
35
|
+
/** Numbers mixes in the order they were made, across copies; what a `gone` change names. */
|
|
36
|
+
readonly id: number;
|
|
37
|
+
/** The release of the copy that made it. */
|
|
38
|
+
readonly release: string;
|
|
39
|
+
readonly name: string | undefined;
|
|
40
|
+
readonly mix: Mix<I, O>;
|
|
41
|
+
/** 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. */
|
|
48
|
+
readonly reach: number;
|
|
49
|
+
/** The kit's channel names, in kit order. */
|
|
50
|
+
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. */
|
|
57
|
+
label(subject: I): string;
|
|
58
|
+
/**
|
|
59
|
+
* Calls `fn` with each frame the host read, once the next one begins. While anyone watches, the
|
|
60
|
+
* mix records what `probe`, `pull` and `drain` give the host, and nothing else changes. Returns
|
|
61
|
+
* a function that stops watching.
|
|
62
|
+
*/
|
|
63
|
+
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. */
|
|
65
|
+
subjects(): I[];
|
|
66
|
+
/**
|
|
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.
|
|
69
|
+
*/
|
|
70
|
+
read(subject: I, at?: number): O;
|
|
71
|
+
/** Takes the clock from the host: see `Hold`. Throws while another hold has it. */
|
|
72
|
+
hold(): Hold;
|
|
73
|
+
}
|
|
74
|
+
/**
|
|
75
|
+
* What the host read in one frame.
|
|
76
|
+
*
|
|
77
|
+
* @category mix
|
|
78
|
+
*/
|
|
79
|
+
export interface WatchedFrame<I, O> {
|
|
80
|
+
seq: number;
|
|
81
|
+
/** The mix clock the frame stood at. */
|
|
82
|
+
now: number;
|
|
83
|
+
/** The host's timestamp at the frame's sync. */
|
|
84
|
+
timestamp: number;
|
|
85
|
+
/** Each probe, in order, with a copy of the pose it returned. */
|
|
86
|
+
probed: {
|
|
87
|
+
subject: I;
|
|
88
|
+
pose: O;
|
|
89
|
+
}[];
|
|
90
|
+
/** Each pull, with copies of the columns it wrote. */
|
|
91
|
+
pulled: {
|
|
92
|
+
subjects: I[];
|
|
93
|
+
columns: Record<string, Float64Array>;
|
|
94
|
+
}[];
|
|
95
|
+
/** What `drain` handed the host. */
|
|
96
|
+
sent: Sent<I, unknown>[];
|
|
97
|
+
voices: Handle<I>[];
|
|
98
|
+
}
|
|
99
|
+
/**
|
|
100
|
+
* A mix's clock in a debugger's hands, and every mix's on the same transport. The host's `sync`
|
|
101
|
+
* still begins each frame, but the frame's gap counts at `rate`, so the mix moves at `rate` times
|
|
102
|
+
* its own rate; the host's own clock calls (`seek`, `rate`, `ramp`, `rebase`) wait for `free`.
|
|
103
|
+
* Nothing done through a hold is recorded on the tape or in the mix's rate, and each change wakes
|
|
104
|
+
* a host sleeping on `inert`.
|
|
105
|
+
*
|
|
106
|
+
* @category mix
|
|
107
|
+
*/
|
|
108
|
+
export interface Hold {
|
|
109
|
+
readonly mixes: Mix<unknown, unknown>[];
|
|
110
|
+
/** The mix clock. */
|
|
111
|
+
readonly now: number;
|
|
112
|
+
/** The earliest mix time `seek` reaches: `now` without history and a tape. */
|
|
113
|
+
readonly reach: number;
|
|
114
|
+
/** How much of each of the host's frames the held mix plays; 0 pauses it. Starts at 0. */
|
|
115
|
+
rate: number;
|
|
116
|
+
/** Moves the mixes to mix time `to`, back within `reach` or ahead. */
|
|
117
|
+
seek(to: number): void;
|
|
118
|
+
/** Plays the mixes `ms` of mix time further on, in one frame. */
|
|
119
|
+
step(ms: number): void;
|
|
120
|
+
/**
|
|
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.
|
|
124
|
+
*/
|
|
125
|
+
free(): void;
|
|
126
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
package/dist/types.d.ts
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
export type * from './types/arc.js';
|
|
1
2
|
export type * from './types/channel.js';
|
|
2
3
|
export type * from './types/history.js';
|
|
3
4
|
export type * from './types/mix.js';
|
|
@@ -5,3 +6,4 @@ export type * from './types/patch.js';
|
|
|
5
6
|
export type * from './types/place.js';
|
|
6
7
|
export type * from './types/transport.js';
|
|
7
8
|
export type * from './types/voice.js';
|
|
9
|
+
export type * from './types/watch.js';
|
package/dist/unpage.d.ts
CHANGED
|
@@ -1,8 +1,13 @@
|
|
|
1
|
-
import type { Transport } from './transport.js';
|
|
1
|
+
import type { Frame, Transport } from './transport.js';
|
|
2
2
|
/**
|
|
3
3
|
* Makes memory reach mix time `t` for a seek or read there, from what `prepare` loaded; true where
|
|
4
4
|
* it took records from the store. Throws before anything moves where it cannot.
|
|
5
5
|
*/
|
|
6
6
|
export declare function cover(transport: Transport, t: number): boolean;
|
|
7
|
+
/**
|
|
8
|
+
* The frame numbered `seq` for a seek or read to it, memory made to reach it from what `prepare`
|
|
9
|
+
* loaded. Throws before anything moves for a frame history does not hold.
|
|
10
|
+
*/
|
|
11
|
+
export declare function coverFrame(transport: Transport, seq: number): Frame;
|
|
7
12
|
/** A seek back to frame `seq`: what the store and `prepare` hold after it is from a future the tape makes again. */
|
|
8
13
|
export declare function cut(transport: Transport, seq: number): void;
|
package/dist/unpage.js
CHANGED
|
@@ -29,6 +29,29 @@ export function cover(transport, t) {
|
|
|
29
29
|
transport.floor = loaded.t;
|
|
30
30
|
return true;
|
|
31
31
|
}
|
|
32
|
+
/**
|
|
33
|
+
* The frame numbered `seq` for a seek or read to it, memory made to reach it from what `prepare`
|
|
34
|
+
* loaded. Throws before anything moves for a frame history does not hold.
|
|
35
|
+
*/
|
|
36
|
+
export function coverFrame(transport, seq) {
|
|
37
|
+
if (!Number.isInteger(seq))
|
|
38
|
+
throw new RangeError(`blits: a frame is a number \`seq\` read, not ${seq}`);
|
|
39
|
+
let frame = transport.frames.numbered(seq);
|
|
40
|
+
const pager = transport.pager;
|
|
41
|
+
if (frame === undefined && pager !== null && seq <= transport.seq) {
|
|
42
|
+
const paged = pager.loaded?.records.find((r) => r.stream === 'frame' && r.mix === '' && r.seq === seq);
|
|
43
|
+
if (paged !== undefined) {
|
|
44
|
+
cover(transport, paged.at);
|
|
45
|
+
frame = transport.frames.numbered(seq);
|
|
46
|
+
}
|
|
47
|
+
else if (seq < (transport.frames.all()[0]?.seq ?? Number.POSITIVE_INFINITY))
|
|
48
|
+
throw new Error(`blits: frame ${seq} reaches past memory; await prepare with its mix time first`);
|
|
49
|
+
}
|
|
50
|
+
if (frame === undefined)
|
|
51
|
+
throw new Error(`blits: frame ${seq} is not one this mix's history holds: not played yet, let go, or after a moment a seek went back to`);
|
|
52
|
+
cover(transport, frame.at);
|
|
53
|
+
return frame;
|
|
54
|
+
}
|
|
32
55
|
/** A seek back to frame `seq`: what the store and `prepare` hold after it is from a future the tape makes again. */
|
|
33
56
|
export function cut(transport, seq) {
|
|
34
57
|
const pager = transport.pager;
|
|
@@ -117,8 +140,17 @@ function unpageVoice(voice, records, keys) {
|
|
|
117
140
|
const subject = keys.subject(r.subject);
|
|
118
141
|
if (left.some((e) => e.seq === r.seq && Object.is(e.subject, subject)))
|
|
119
142
|
continue;
|
|
120
|
-
|
|
121
|
-
|
|
143
|
+
// A store written before a leaving kept its fades holds two.
|
|
144
|
+
const [p, sync, ramp = null, parted = null] = r.data;
|
|
145
|
+
left.push({
|
|
146
|
+
subject,
|
|
147
|
+
at: r.at,
|
|
148
|
+
seq: r.seq,
|
|
149
|
+
sync,
|
|
150
|
+
held: unpackHeld(voice, p),
|
|
151
|
+
ramp,
|
|
152
|
+
parted,
|
|
153
|
+
});
|
|
122
154
|
}
|
|
123
155
|
left.sort((a, b) => a.seq - b.seq);
|
|
124
156
|
voice.left = Leavings.from(left);
|
package/dist/voice.d.ts
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import type { Arc } from './arcs.js';
|
|
1
2
|
import type { Blend } from './blend.js';
|
|
2
3
|
import { type Clock } from './clock.js';
|
|
3
4
|
import { type Curve } from './easing.js';
|
|
@@ -7,12 +8,14 @@ import { Named } from './named.js';
|
|
|
7
8
|
import type { Past } from './origin.js';
|
|
8
9
|
import { Holding } from './owner.js';
|
|
9
10
|
import { type Built, intosOf, type Scratch } from './patch.js';
|
|
11
|
+
import type { Stamp } from './restored.js';
|
|
10
12
|
import type { Fitting } from './spans.js';
|
|
11
13
|
import { Store } from './store.js';
|
|
12
14
|
import type { Anchor, Channel, FadeSpec, Handle, Patch, Setting, VoiceSpec } from './types.js';
|
|
13
15
|
/**
|
|
14
16
|
* A subject's record as it left a voice, faded out of it or dropped: the mix time and frame it
|
|
15
|
-
* left at, and `sync` where the frame's sync
|
|
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.
|
|
16
19
|
*/
|
|
17
20
|
export interface Left<I> {
|
|
18
21
|
subject: I;
|
|
@@ -20,8 +23,55 @@ export interface Left<I> {
|
|
|
20
23
|
seq: number;
|
|
21
24
|
sync: boolean;
|
|
22
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;
|
|
23
43
|
}
|
|
24
44
|
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
|
+
}
|
|
25
75
|
/** Everything one voice holds for one subject, chained through the next voice that reaches it. */
|
|
26
76
|
export interface Subject<S> {
|
|
27
77
|
/** The voice's `target` answer, fixed on first sight. */
|
|
@@ -56,6 +106,8 @@ export interface Subject<S> {
|
|
|
56
106
|
seeks: number;
|
|
57
107
|
/** The voice's `rebuilds` when its state was last made, so a seek's rebuild reaches it once. */
|
|
58
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;
|
|
59
111
|
/** Stop 0 for a `from: 'current'` voice, taken the first frame this subject is seen. */
|
|
60
112
|
base?: Record<string, unknown>;
|
|
61
113
|
/** The pose's velocity per channel at that moment, units per ms, so the first segment leaves at it. */
|
|
@@ -65,11 +117,7 @@ export interface Subject<S> {
|
|
|
65
117
|
/** Kept state a history store gave back, which each owner takes in turn on its first keep. */
|
|
66
118
|
unkept?: unknown[];
|
|
67
119
|
/** Under `history`, copies of this record by the mix time they were taken, oldest first. */
|
|
68
|
-
snaps?:
|
|
69
|
-
at: number;
|
|
70
|
-
seq: number;
|
|
71
|
-
held: Subject<S>;
|
|
72
|
-
}[];
|
|
120
|
+
snaps?: Snap<S>[];
|
|
73
121
|
/** In a projection: where this record started from, and whether nothing known could be. */
|
|
74
122
|
from?: number;
|
|
75
123
|
unknown?: boolean;
|
|
@@ -100,6 +148,8 @@ export interface Subject<S> {
|
|
|
100
148
|
/** A motion voice's number for this subject in its patch, good while `freed` is the patch's own. */
|
|
101
149
|
run: number;
|
|
102
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;
|
|
103
153
|
}
|
|
104
154
|
/** A voice's clock, weight and fade from one mix time on, kept under `history`. */
|
|
105
155
|
export interface Controls extends Clock {
|
|
@@ -116,6 +166,8 @@ export interface Controls extends Clock {
|
|
|
116
166
|
outOver: number;
|
|
117
167
|
outSet: boolean;
|
|
118
168
|
rebuilds: number;
|
|
169
|
+
/** An arc's hold. */
|
|
170
|
+
hold: number;
|
|
119
171
|
/** How many of the voice's past clocks it had then. */
|
|
120
172
|
past: number;
|
|
121
173
|
/** Shows in its own frame: made by a sync, or before anything read the mix that frame. */
|
|
@@ -200,19 +252,17 @@ export declare class Voice<I, O> {
|
|
|
200
252
|
rebuilds: number;
|
|
201
253
|
/** Whether its span's last fit jumped it to its end, which leaves it no time in that fit. */
|
|
202
254
|
skipped: boolean;
|
|
255
|
+
/** What its `earliest` answered at its span's last fit, span ms; NaN while unknown or absent. */
|
|
256
|
+
floorSeen: number;
|
|
203
257
|
/** Whether its patch has kept state on a record through `setting.keep`, which makes it stateful. */
|
|
204
258
|
keeping: boolean;
|
|
205
259
|
/** Subjects fading out of this voice alone, by the ramp each started; null while none are. */
|
|
206
|
-
parts: Map<I,
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
parted: Map<I, {
|
|
213
|
-
at: number;
|
|
214
|
-
seq: number;
|
|
215
|
-
}> | null;
|
|
260
|
+
parts: Map<I, Parting> | null;
|
|
261
|
+
/**
|
|
262
|
+
* Subjects faded out of this voice, by the mix time and frame each left at, and the ramp that
|
|
263
|
+
* took it out, which a seek or a read back into it puts back; null while none have.
|
|
264
|
+
*/
|
|
265
|
+
parted: Map<I, Parted> | null;
|
|
216
266
|
/**
|
|
217
267
|
* Under history, the records of subjects that left this voice, by the mix time and frame each
|
|
218
268
|
* left at, while a seek or a read back may reach them; null while none have.
|
|
@@ -237,6 +287,8 @@ export declare class Voice<I, O> {
|
|
|
237
287
|
readonly freezesAfter: boolean;
|
|
238
288
|
/** The mix time it first showed: when it was cued, or the first sync after. */
|
|
239
289
|
opened: number;
|
|
290
|
+
/** Whether no delta its patch's `at` returned has been checked against `writes` yet. */
|
|
291
|
+
unchecked: boolean;
|
|
240
292
|
/** Which of its entries in the mix's due queue is current; older ones are skipped when popped. */
|
|
241
293
|
dueToken: number;
|
|
242
294
|
/**
|
|
@@ -255,6 +307,8 @@ export declare class Voice<I, O> {
|
|
|
255
307
|
/** The least stagger of any subject seen, 0 or below, which a voice running back ends at. */
|
|
256
308
|
soonest: number;
|
|
257
309
|
restedCount: number;
|
|
310
|
+
/** Whether a seek back to before its cue has it out of the mix, until the mix plays the cue again. */
|
|
311
|
+
parked: boolean;
|
|
258
312
|
/** The mix time it was cued at; -Infinity before the first sync. */
|
|
259
313
|
cuedAt: number;
|
|
260
314
|
/** The frame it was cued in. */
|
|
@@ -294,12 +348,19 @@ export declare class Voice<I, O> {
|
|
|
294
348
|
of: Blend<I, O>;
|
|
295
349
|
i: number;
|
|
296
350
|
} | null;
|
|
351
|
+
/**
|
|
352
|
+
* Copies the latest seek back cut from its records' lists that no other list holds, for the
|
|
353
|
+
* copies its probes keep next to be written over; null until a seek cuts one.
|
|
354
|
+
*/
|
|
355
|
+
spares: Snap<unknown>[] | null;
|
|
297
356
|
/** The one record of every subject it does not reach. */
|
|
298
357
|
unreached: Subject<unknown> | null;
|
|
299
358
|
/** By subject number, a bit set where `unreached` stands for the subject; null until one is. */
|
|
300
359
|
unreachedBits: Uint32Array | null;
|
|
301
360
|
/** Whether one record stands for every subject: see `shares` in `everyone.ts`. */
|
|
302
361
|
sharing: boolean;
|
|
362
|
+
/** The frames it has played sharing it. */
|
|
363
|
+
shared: number;
|
|
303
364
|
/** That record, null until a chain first asks and once the voice shares no more. */
|
|
304
365
|
everyone: Subject<unknown> | null;
|
|
305
366
|
/** While sharing, by subject number: a bit where a chain has asked about the subject. */
|
|
@@ -320,6 +381,12 @@ export declare class Voice<I, O> {
|
|
|
320
381
|
holding: Holding<Voice<I, O>> | null;
|
|
321
382
|
/** For a span, its budget and how its children were last fitted; null for any other voice. */
|
|
322
383
|
fitting: Fitting | null;
|
|
384
|
+
/** For an arc, how its parts are laid out; null for any other voice. */
|
|
385
|
+
arc: Arc | null;
|
|
386
|
+
/** For an arc, how long its hold lasts, ms on its clock: Infinity while open. */
|
|
387
|
+
hold: number;
|
|
388
|
+
/** For a voice an arc holds, which part it plays: 0 enter, 1 active, 2 exit; -1 for any other. */
|
|
389
|
+
part: number;
|
|
323
390
|
/**
|
|
324
391
|
* `done` and `played`, made when first asked for, already settled if the voice is: most hosts
|
|
325
392
|
* never await either, and a mix may hold tens of thousands of voices.
|
|
@@ -411,6 +478,11 @@ export declare class Voice<I, O> {
|
|
|
411
478
|
* fading out from where it ran back to its start, as one fading from its end shows its last.
|
|
412
479
|
*/
|
|
413
480
|
get holdsFirst(): boolean;
|
|
481
|
+
/**
|
|
482
|
+
* Whether a subject past the end of its passes shows nothing: its clock runs back, so it has yet
|
|
483
|
+
* to reach them, and it does not freeze after.
|
|
484
|
+
*/
|
|
485
|
+
get hidesPast(): boolean;
|
|
414
486
|
/** A subject's voice time at `raw` once the voice's freezes apply; NaN where it shows nothing. */
|
|
415
487
|
shownAt(raw: number): number;
|
|
416
488
|
/** Records this voice's controls as they stand, from mix time `at` in frame `seq`. */
|
|
@@ -426,3 +498,8 @@ export declare class Voice<I, O> {
|
|
|
426
498
|
/** Moves the anchor to `now`, carrying what is left of a ramp. */
|
|
427
499
|
rebase(now: number): void;
|
|
428
500
|
}
|
|
501
|
+
/**
|
|
502
|
+
* Warns, once a patch outside production, of a key the first delta `voice` read returns outside its
|
|
503
|
+
* patch's `writes`, which the mix drops.
|
|
504
|
+
*/
|
|
505
|
+
export declare function checkWrites<I, O>(voice: Voice<I, O>, delta: object | null): void;
|