@msb235/blits 0.14.0 → 0.15.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +198 -0
- package/README.md +3 -3
- package/dist/ahead.d.ts +26 -0
- package/dist/ahead.js +264 -0
- package/dist/around.d.ts +11 -0
- package/dist/around.js +32 -0
- package/dist/bare.js +37 -14
- package/dist/blank.d.ts +10 -0
- package/dist/blank.js +26 -0
- package/dist/blend.d.ts +2 -1
- package/dist/blend.js +1 -6
- package/dist/bound.d.ts +70 -0
- package/dist/bound.js +351 -0
- package/dist/chain.d.ts +2 -1
- package/dist/chain.js +7 -5
- package/dist/changes.d.ts +24 -0
- package/dist/changes.js +189 -0
- package/dist/channels.d.ts +39 -13
- package/dist/channels.js +14 -5
- package/dist/color.d.ts +12 -10
- package/dist/color.js +25 -25
- package/dist/columns.d.ts +2 -1
- package/dist/columns.js +62 -38
- package/dist/contribution.d.ts +30 -0
- package/dist/contribution.js +374 -0
- package/dist/copyout.d.ts +10 -0
- package/dist/copyout.js +69 -24
- package/dist/crowd.d.ts +16 -6
- package/dist/crowd.js +20 -11
- package/dist/cue.d.ts +8 -1
- package/dist/cue.js +39 -13
- package/dist/cut.d.ts +8 -0
- package/dist/cut.js +4 -0
- package/dist/delay.d.ts +3 -0
- package/dist/delay.js +7 -0
- package/dist/drop.d.ts +9 -0
- package/dist/drop.js +84 -0
- package/dist/due.d.ts +24 -5
- package/dist/due.js +114 -34
- package/dist/easing.d.ts +6 -4
- package/dist/easing.js +7 -3
- package/dist/everyone.d.ts +8 -2
- package/dist/everyone.js +33 -3
- package/dist/fade.d.ts +2 -1
- package/dist/fade.js +2 -1
- package/dist/fill.d.ts +3 -2
- package/dist/fill.js +52 -20
- package/dist/fit.d.ts +44 -26
- package/dist/fit.js +10 -9
- package/dist/fold.d.ts +4 -37
- package/dist/fold.js +5 -513
- package/dist/gather.d.ts +12 -7
- package/dist/gather.js +179 -44
- package/dist/gone.js +2 -2
- package/dist/grid.d.ts +47 -0
- package/dist/grid.js +247 -0
- package/dist/handle.d.ts +2 -0
- package/dist/handle.js +14 -8
- package/dist/held.d.ts +2 -1
- package/dist/held.js +2 -1
- package/dist/history.d.ts +6 -5
- package/dist/history.js +7 -9
- package/dist/hosts.js +9 -15
- package/dist/index.d.ts +5 -4
- package/dist/keyfill.d.ts +1 -1
- package/dist/keyfill.js +5 -3
- package/dist/keyrows.d.ts +12 -0
- package/dist/keyrows.js +99 -12
- package/dist/lane.d.ts +38 -11
- package/dist/lane.js +46 -11
- package/dist/lanes.d.ts +30 -12
- package/dist/lanes.js +56 -36
- package/dist/leavings.d.ts +2 -2
- package/dist/leavings.js +1 -1
- package/dist/lives.d.ts +47 -0
- package/dist/lives.js +180 -0
- package/dist/meet.d.ts +2 -2
- package/dist/meet.js +95 -7
- package/dist/mixer.d.ts +56 -37
- package/dist/mixer.js +57 -171
- package/dist/motion.d.ts +14 -118
- package/dist/motion.js +16 -8
- package/dist/motions.d.ts +62 -155
- package/dist/motions.js +56 -370
- package/dist/moved.d.ts +1 -1
- package/dist/moved.js +16 -7
- package/dist/named.d.ts +6 -2
- package/dist/named.js +49 -3
- package/dist/numbers.d.ts +7 -0
- package/dist/numbers.js +33 -0
- package/dist/owed.d.ts +2 -0
- package/dist/owed.js +4 -0
- package/dist/pack.d.ts +2 -1
- package/dist/pack.js +2 -3
- package/dist/patch.d.ts +7 -3
- package/dist/patch.js +6 -2
- package/dist/places.d.ts +53 -0
- package/dist/places.js +171 -0
- package/dist/plot.d.ts +12 -0
- package/dist/plot.js +52 -0
- package/dist/project.d.ts +4 -4
- package/dist/project.js +9 -212
- package/dist/pull.js +22 -9
- package/dist/qualify.js +93 -31
- package/dist/reading.d.ts +6 -0
- package/dist/reading.js +5 -0
- package/dist/record.d.ts +5 -1
- package/dist/record.js +3 -2
- package/dist/relink.d.ts +1 -1
- package/dist/renumber.d.ts +10 -0
- package/dist/renumber.js +75 -0
- package/dist/restored.d.ts +2 -2
- package/dist/restored.js +1 -1
- package/dist/rests.d.ts +9 -0
- package/dist/rests.js +76 -0
- package/dist/revive.d.ts +3 -2
- package/dist/revive.js +2 -2
- package/dist/{locus.d.ts → role.d.ts} +10 -9
- package/dist/{locus.js → role.js} +3 -3
- package/dist/roles.d.ts +10 -0
- package/dist/roles.js +158 -0
- package/dist/roster.js +3 -3
- package/dist/rotation.d.ts +1 -1
- package/dist/rotation.js +1 -1
- package/dist/rows.js +28 -20
- package/dist/sample.d.ts +2 -2
- package/dist/sample.js +33 -7
- package/dist/seat.d.ts +17 -0
- package/dist/seat.js +25 -0
- package/dist/seek.js +5 -5
- package/dist/setting.d.ts +27 -0
- package/dist/setting.js +55 -0
- package/dist/shared.d.ts +1 -1
- package/dist/shared.js +1 -1
- package/dist/signals.d.ts +64 -32
- package/dist/signals.js +20 -18
- package/dist/stack.d.ts +5 -5
- package/dist/stack.js +5 -5
- package/dist/standing.d.ts +2 -1
- package/dist/standing.js +3 -2
- package/dist/store.d.ts +9 -0
- package/dist/store.js +24 -0
- package/dist/strays.d.ts +2 -1
- package/dist/strays.js +23 -15
- package/dist/stretch.d.ts +112 -0
- package/dist/stretch.js +9 -0
- package/dist/subject.d.ts +142 -0
- package/dist/subject.js +1 -0
- package/dist/tape.d.ts +9 -5
- package/dist/tape.js +5 -1
- package/dist/then.d.ts +9 -0
- package/dist/then.js +57 -0
- package/dist/ticker.d.ts +4 -4
- package/dist/trace.d.ts +4 -0
- package/dist/trace.js +255 -0
- package/dist/transport.d.ts +0 -8
- package/dist/transport.js +0 -4
- package/dist/turns.d.ts +4 -3
- package/dist/turns.js +4 -3
- package/dist/types/arc.d.ts +12 -11
- package/dist/types/channel.d.ts +12 -8
- package/dist/types/history.d.ts +35 -19
- package/dist/types/mix.d.ts +237 -163
- package/dist/types/motion.d.ts +151 -0
- package/dist/types/motion.js +1 -0
- package/dist/types/patch.d.ts +67 -34
- package/dist/types/place.d.ts +51 -36
- package/dist/types/trace.d.ts +51 -0
- package/dist/types/trace.js +1 -0
- package/dist/types/transport.d.ts +20 -18
- package/dist/types/voice.d.ts +144 -73
- package/dist/types/watch.d.ts +88 -40
- package/dist/types.d.ts +2 -0
- package/dist/unreached.d.ts +2 -0
- package/dist/unreached.js +7 -0
- package/dist/voice.d.ts +10 -143
- package/dist/voice.js +37 -82
- package/dist/warn.d.ts +2 -0
- package/dist/warn.js +1 -1
- package/dist/watch.d.ts +2 -2
- package/dist/watch.js +5 -3
- package/dist/wave.d.ts +4 -3
- package/dist/wave.js +3 -2
- package/dist/weigh.d.ts +7 -1
- package/dist/weigh.js +27 -0
- package/docs/schema.html +223 -34
- package/package.json +2 -2
package/dist/types/watch.d.ts
CHANGED
|
@@ -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
|
|
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
|
|
24
|
-
* transport, so a debugger present before the page's
|
|
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
|
-
|
|
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
|
-
/**
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
/** What to call a subject
|
|
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
|
-
/**
|
|
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
|
|
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
|
|
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
|
|
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
|
|
122
|
-
* its clock calls made meanwhile are made, in order. A call made while the tape holds
|
|
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,8 +2,10 @@ 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';
|
|
8
|
+
export type * from './types/trace.js';
|
|
7
9
|
export type * from './types/transport.js';
|
|
8
10
|
export type * from './types/voice.js';
|
|
9
11
|
export type * from './types/watch.js';
|
package/dist/unreached.d.ts
CHANGED
|
@@ -3,3 +3,5 @@ import type { Voice } from './voice.js';
|
|
|
3
3
|
export declare function unreached<I, O>(voice: Voice<I, O>, slot: number): boolean;
|
|
4
4
|
/** Marks or clears the subject numbered `slot` as one the voice does not reach. */
|
|
5
5
|
export declare function unreach<I, O>(voice: Voice<I, O>, slot: number, on: boolean): void;
|
|
6
|
+
/** The subject numbered `from` is numbered `to` now, a number let go of: its mark moves along. */
|
|
7
|
+
export declare function reunreach<I, O>(voice: Voice<I, O>, from: number, to: number): void;
|
package/dist/unreached.js
CHANGED
|
@@ -22,3 +22,10 @@ export function unreach(voice, slot, on) {
|
|
|
22
22
|
const bit = 1 << (slot & 31);
|
|
23
23
|
bits[word] = on ? bits[word] | bit : bits[word] & ~bit;
|
|
24
24
|
}
|
|
25
|
+
/** The subject numbered `from` is numbered `to` now, a number let go of: its mark moves along. */
|
|
26
|
+
export function reunreach(voice, from, to) {
|
|
27
|
+
if (!unreached(voice, from))
|
|
28
|
+
return;
|
|
29
|
+
unreach(voice, to, true);
|
|
30
|
+
unreach(voice, from, false);
|
|
31
|
+
}
|
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,151 +9,13 @@ 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 {
|
|
12
|
+
import type { Seat } from './seat.js';
|
|
13
|
+
import { VoiceSetting } from './setting.js';
|
|
12
14
|
import type { Fitting } from './spans.js';
|
|
13
15
|
import { Store } from './store.js';
|
|
14
|
-
import type {
|
|
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
|
-
}
|
|
16
|
+
import type { Parted, Parting, Snap, Subject } from './subject.js';
|
|
17
|
+
import type { Anchor, Channel, FadeSpec, Handle, Patch, VoiceSpec } from './types.js';
|
|
44
18
|
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
|
-
/** The mix time it rested at, which a seek reads to know whether it had by then; NaN until it does. */
|
|
90
|
-
restedAt: number;
|
|
91
|
-
/**
|
|
92
|
-
* Per written channel, whether a rest-less contribution is on: 0 unknown, 1 on, 2 off; null until
|
|
93
|
-
* a rest-less channel asks.
|
|
94
|
-
*/
|
|
95
|
-
bands: Uint8Array | null;
|
|
96
|
-
state: S;
|
|
97
|
-
/** The `now` this subject last caught up to, for this voice. */
|
|
98
|
-
stepped: number;
|
|
99
|
-
/** Under `stepMs`, how many intervals have run since `since`; `stepped` is where that lands. */
|
|
100
|
-
ticks: number;
|
|
101
|
-
/** The `now` this subject was last probed at, so twelve probes in a frame step once. */
|
|
102
|
-
probed: number;
|
|
103
|
-
/** The last delta computed this frame, handed back to a repeat probe unchanged. */
|
|
104
|
-
delta: Record<string, unknown> | null;
|
|
105
|
-
/** The phase `delta` was read at, to read it again once its voice's scratch has moved on. */
|
|
106
|
-
phase: number;
|
|
107
|
-
/** The voice's `seeks` when `delta` was read, so a seek later in the frame reads it again. */
|
|
108
|
-
seeks: number;
|
|
109
|
-
/** The voice's `rebuilds` when its state was last made, so a seek's rebuild reaches it once. */
|
|
110
|
-
rebuilt: number;
|
|
111
|
-
/** Its kept signal state was stepped on in one go from a copy history kept, by a seek. */
|
|
112
|
-
copied: boolean;
|
|
113
|
-
/** Stop 0 for a `from: 'current'` voice, taken the first frame this subject is seen. */
|
|
114
|
-
base?: Record<string, unknown>;
|
|
115
|
-
/** The pose's velocity per channel at that moment, units per ms, so the first segment leaves at it. */
|
|
116
|
-
slope?: Record<string, unknown>;
|
|
117
|
-
/** What `setting.keep` holds for this voice and subject, by owner; null until it holds any. */
|
|
118
|
-
kept: Map<object, unknown> | null;
|
|
119
|
-
/** Kept state a history store gave back, which each owner takes in turn on its first keep. */
|
|
120
|
-
unkept?: unknown[];
|
|
121
|
-
/** Under `history`, copies of this record by the mix time they were taken, oldest first. */
|
|
122
|
-
snaps?: Snap<S>[];
|
|
123
|
-
/** In a projection: where this record started from, and whether nothing known could be. */
|
|
124
|
-
from?: number;
|
|
125
|
-
unknown?: boolean;
|
|
126
|
-
/** Under `history` with `inputs`, what an input weight signal read for this subject, when it changed. */
|
|
127
|
-
inputs?: {
|
|
128
|
-
at: number;
|
|
129
|
-
seq: number;
|
|
130
|
-
value: number;
|
|
131
|
-
}[];
|
|
132
|
-
/** In a projection reading back: that record, to read in place of the signal. */
|
|
133
|
-
replay?: {
|
|
134
|
-
at: number;
|
|
135
|
-
value: number;
|
|
136
|
-
}[];
|
|
137
|
-
/** The voice this is the record of; null on a subject's stub. */
|
|
138
|
-
voice: object | null;
|
|
139
|
-
/** The next voice's record for this subject, in voice order, among those that reach it. */
|
|
140
|
-
next: Subject<unknown> | null;
|
|
141
|
-
/**
|
|
142
|
-
* On the first record, which the mix keeps per subject so a probe makes one lookup: the `version`
|
|
143
|
-
* the chain was linked at, and per locus, by channel slot, whether a rest-less contribution is on:
|
|
144
|
-
* 0 never decided, 1 on, 2 off.
|
|
145
|
-
*/
|
|
146
|
-
version: number;
|
|
147
|
-
loci: Map<string, Uint8Array> | null;
|
|
148
|
-
/** On the first record: the number lanes index this subject by, -1 without one. */
|
|
149
|
-
slot: number;
|
|
150
|
-
/** A motion voice's number for this subject in its patch, good while `freed` is the patch's own. */
|
|
151
|
-
run: number;
|
|
152
|
-
freed: number;
|
|
153
|
-
/** In a voice's store once a seek has gone back, the stamp of the seek it was last put back or written at. */
|
|
154
|
-
restored: Stamp | null;
|
|
155
|
-
}
|
|
156
19
|
/** A voice's clock, weight and fade from one mix time on, kept under `history`. */
|
|
157
20
|
export interface Controls extends Clock {
|
|
158
21
|
at: number;
|
|
@@ -239,6 +102,8 @@ export declare class Voice<I, O> {
|
|
|
239
102
|
holder: Subject<unknown> | null;
|
|
240
103
|
/** Whether its channels run as lanes this frame, so the general fold passes it by. */
|
|
241
104
|
laned: boolean;
|
|
105
|
+
/** Its crowd row, while its channels run in a crowd. */
|
|
106
|
+
seat: Seat<I, O> | null;
|
|
242
107
|
/**
|
|
243
108
|
* How many times it has been sought or touched, so a delta read before either is not handed out
|
|
244
109
|
* after it.
|
|
@@ -301,7 +166,7 @@ export declare class Voice<I, O> {
|
|
|
301
166
|
/** The clocks it ran on before its current one, where a subject's origin may lie; null for none. */
|
|
302
167
|
clocks: Past[] | null;
|
|
303
168
|
/** Reused for every call this voice makes, so it is valid only during the call. */
|
|
304
|
-
readonly setting:
|
|
169
|
+
readonly setting: VoiceSetting<I, O>;
|
|
305
170
|
/** Every subject this voice has been asked about, so a handover knows when it is finished. */
|
|
306
171
|
seen: number;
|
|
307
172
|
/** The longest stagger of any subject seen, so a finite loop waits for the last of them. */
|
|
@@ -363,6 +228,8 @@ export declare class Voice<I, O> {
|
|
|
363
228
|
unreachedBits: Uint32Array | null;
|
|
364
229
|
/** Whether one record stands for every subject: see `shares` in `everyone.ts`. */
|
|
365
230
|
sharing: boolean;
|
|
231
|
+
/** Where its signal is declared 0, its cue's `within`, so it is not read there: see `bound.ts`. */
|
|
232
|
+
bound: Bound<I, O> | null;
|
|
366
233
|
/** The frames it has played sharing it. */
|
|
367
234
|
shared: number;
|
|
368
235
|
/** 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 {
|
|
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
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
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
|
-
|
|
64
|
-
|
|
65
|
-
|
|
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;
|
|
@@ -126,6 +72,8 @@ export class Voice {
|
|
|
126
72
|
holder = null;
|
|
127
73
|
/** Whether its channels run as lanes this frame, so the general fold passes it by. */
|
|
128
74
|
laned = false;
|
|
75
|
+
/** Its crowd row, while its channels run in a crowd. */
|
|
76
|
+
seat = null;
|
|
129
77
|
/**
|
|
130
78
|
* How many times it has been sought or touched, so a delta read before either is not handed out
|
|
131
79
|
* after it.
|
|
@@ -251,6 +199,8 @@ export class Voice {
|
|
|
251
199
|
unreachedBits = null;
|
|
252
200
|
/** Whether one record stands for every subject: see `shares` in `everyone.ts`. */
|
|
253
201
|
sharing = false;
|
|
202
|
+
/** Where its signal is declared 0, its cue's `within`, so it is not read there: see `bound.ts`. */
|
|
203
|
+
bound = null;
|
|
254
204
|
/** The frames it has played sharing it. */
|
|
255
205
|
shared = 0;
|
|
256
206
|
/** That record, null until a chain first asks and once the voice shares no more. */
|
|
@@ -410,8 +360,8 @@ export class Voice {
|
|
|
410
360
|
this.dueToken++;
|
|
411
361
|
this.early = null;
|
|
412
362
|
this.seen = 0;
|
|
413
|
-
this.latest = 0;
|
|
414
|
-
this.soonest = 0;
|
|
363
|
+
this.latest = this.named?.latest ?? 0;
|
|
364
|
+
this.soonest = this.named?.soonest ?? 0;
|
|
415
365
|
this.restedCount = 0;
|
|
416
366
|
this.cuedAt = Number.NEGATIVE_INFINITY;
|
|
417
367
|
this.cuedSeq = Number.NEGATIVE_INFINITY;
|
|
@@ -443,10 +393,14 @@ export class Voice {
|
|
|
443
393
|
this.start = start;
|
|
444
394
|
this.owner = owner;
|
|
445
395
|
this.holding = patch === ownerPatch ? new Holding() : null;
|
|
446
|
-
|
|
447
|
-
this.
|
|
396
|
+
const wrote = writing(patch.writes, slotOf, channels);
|
|
397
|
+
this.slots = wrote.slots;
|
|
398
|
+
this.named = spec.subjects ? new Named(spec.subjects, spec.stagger) : null;
|
|
399
|
+
// Every subject's stagger is known at cue, so a finite loop ends by them all, read or not.
|
|
400
|
+
this.latest = this.named?.latest ?? 0;
|
|
401
|
+
this.soonest = this.named?.soonest ?? 0;
|
|
448
402
|
this.built = patch.form === 'keys' && patch.keys ? builtOf(patch) : null;
|
|
449
|
-
this.lerps =
|
|
403
|
+
this.lerps = wrote.lerps;
|
|
450
404
|
this.intos = this.built
|
|
451
405
|
? intosOf(this.built, this.slots.map((slot) => channels[slot]))
|
|
452
406
|
: undefined;
|
|
@@ -618,6 +572,7 @@ export class Voice {
|
|
|
618
572
|
v.scratch = [];
|
|
619
573
|
v.holder = null;
|
|
620
574
|
v.laned = false;
|
|
575
|
+
v.seat = null;
|
|
621
576
|
v.log = null;
|
|
622
577
|
v.early = null;
|
|
623
578
|
if (controls)
|
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
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
|
-
*
|
|
6
|
-
*
|
|
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
|
-
*
|
|
8
|
-
*
|
|
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
|
|
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
|
|
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
|
|
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
|
*
|