@msb235/blits 0.14.0 → 0.15.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +154 -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 +15 -7
- 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.js +7 -3
- 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 +8 -2
- package/dist/crowd.js +4 -5
- 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/drop.d.ts +9 -0
- package/dist/drop.js +84 -0
- package/dist/due.d.ts +24 -5
- package/dist/due.js +113 -33
- package/dist/easing.d.ts +4 -4
- package/dist/easing.js +3 -3
- package/dist/everyone.d.ts +3 -2
- package/dist/everyone.js +3 -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 +51 -19
- 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/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 +36 -6
- package/dist/lane.js +32 -1
- package/dist/lanes.d.ts +23 -8
- package/dist/lanes.js +29 -8
- 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 +90 -4
- package/dist/mixer.d.ts +54 -36
- package/dist/mixer.js +53 -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 +0 -1
- package/dist/named.js +20 -2
- package/dist/numbers.d.ts +2 -0
- package/dist/numbers.js +4 -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 +11 -8
- package/dist/qualify.js +84 -21
- 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/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 +1 -1
- package/dist/sample.d.ts +2 -2
- package/dist/sample.js +33 -7
- 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 +20 -13
- 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/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 +222 -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/transport.d.ts +20 -18
- package/dist/types/voice.d.ts +136 -70
- package/dist/types/watch.d.ts +88 -40
- package/dist/types.d.ts +1 -0
- package/dist/voice.d.ts +7 -143
- package/dist/voice.js +28 -79
- 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 +212 -34
- package/package.json +2 -2
package/dist/handle.js
CHANGED
|
@@ -76,9 +76,10 @@ export class VoiceHandle {
|
|
|
76
76
|
voice.written = true;
|
|
77
77
|
voice.weight = w;
|
|
78
78
|
this.#host.changed(voice);
|
|
79
|
-
this.#host.
|
|
80
|
-
|
|
81
|
-
|
|
79
|
+
if (this.#host.taping())
|
|
80
|
+
this.#host.record(this, 'weight', (h) => {
|
|
81
|
+
h.weight = w;
|
|
82
|
+
});
|
|
82
83
|
}
|
|
83
84
|
get rate() {
|
|
84
85
|
const voice = this.#voice;
|
|
@@ -105,7 +106,8 @@ export class VoiceHandle {
|
|
|
105
106
|
retime(voice, now, r, over);
|
|
106
107
|
}
|
|
107
108
|
this.#host.changed(voice);
|
|
108
|
-
this.#host.
|
|
109
|
+
if (this.#host.taping())
|
|
110
|
+
this.#host.record(this, 'rate', (h) => h.ramp(r, over));
|
|
109
111
|
}
|
|
110
112
|
seek(elapsed, opts) {
|
|
111
113
|
const voice = this.#cued;
|
|
@@ -122,7 +124,8 @@ export class VoiceHandle {
|
|
|
122
124
|
voice.seeks++;
|
|
123
125
|
const doubt = this.#host.sought(voice, opts?.state !== 'keep');
|
|
124
126
|
this.#host.changed(voice);
|
|
125
|
-
this.#host.
|
|
127
|
+
if (this.#host.taping())
|
|
128
|
+
this.#host.record(this, 'seek', (h) => h.seek(elapsed, opts));
|
|
126
129
|
return doubt;
|
|
127
130
|
}
|
|
128
131
|
fade(opts) {
|
|
@@ -131,7 +134,8 @@ export class VoiceHandle {
|
|
|
131
134
|
return;
|
|
132
135
|
voice.written = true;
|
|
133
136
|
this.#host.fade(voice, opts);
|
|
134
|
-
this.#host.
|
|
137
|
+
if (this.#host.taping())
|
|
138
|
+
this.#host.record(this, 'fade', (h) => h.fade(opts));
|
|
135
139
|
}
|
|
136
140
|
rise(opts) {
|
|
137
141
|
const voice = this.#cued;
|
|
@@ -139,7 +143,8 @@ export class VoiceHandle {
|
|
|
139
143
|
return;
|
|
140
144
|
voice.written = true;
|
|
141
145
|
this.#host.rise(voice, opts);
|
|
142
|
-
this.#host.
|
|
146
|
+
if (this.#host.taping())
|
|
147
|
+
this.#host.record(this, 'rise', (h) => h.rise(opts));
|
|
143
148
|
}
|
|
144
149
|
release() {
|
|
145
150
|
const voice = this.#cued;
|
|
@@ -147,7 +152,8 @@ export class VoiceHandle {
|
|
|
147
152
|
return;
|
|
148
153
|
voice.written = true;
|
|
149
154
|
this.#host.release(voice);
|
|
150
|
-
this.#host.
|
|
155
|
+
if (this.#host.taping())
|
|
156
|
+
this.#host.record(this, 'release', (h) => h.release());
|
|
151
157
|
}
|
|
152
158
|
weightOf(subject) {
|
|
153
159
|
const voice = this.#voice;
|
package/dist/held.d.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import type { Mixer } from './mixer.js';
|
|
2
|
-
import type { Subject
|
|
2
|
+
import type { Subject } from './subject.js';
|
|
3
|
+
import type { Voice } from './voice.js';
|
|
3
4
|
/** The record a voice gives every subject it does not reach. */
|
|
4
5
|
export declare function unreachedOf<I, O>(this: Mixer<I, O>, voice: Voice<I, O>, now: number): Subject<unknown>;
|
|
5
6
|
/**
|
package/dist/history.d.ts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
|
+
import { type Cut } from './cut.js';
|
|
1
2
|
import type { Mixer } from './mixer.js';
|
|
2
|
-
import {
|
|
3
|
-
import { type
|
|
3
|
+
import type { Subject } from './subject.js';
|
|
4
|
+
import { type Voice } from './voice.js';
|
|
4
5
|
/** The last entry taken before `t`, or at it where `inclusive` says so. */
|
|
5
6
|
export declare function last<T extends {
|
|
6
7
|
at: number;
|
|
@@ -56,7 +57,7 @@ export declare function remember<I, O>(mix: Mixer<I, O>, voice: Voice<I, O>, sub
|
|
|
56
57
|
*/
|
|
57
58
|
export declare function leave<I, O>(mix: Mixer<I, O>, voice: Voice<I, O>, subject: I, held: Subject<unknown> | undefined): void;
|
|
58
59
|
/**
|
|
59
|
-
* The mix time a motion patch keeps a released subject from, how far back,
|
|
60
|
-
* history.
|
|
60
|
+
* The mix time a motion patch keeps a released subject from, how far back, the frame, and whether
|
|
61
|
+
* the release came before anything read it, under history.
|
|
61
62
|
*/
|
|
62
|
-
export declare function releasing<I, O>(mix: Mixer<I, O>): [at?: number, reach?: number, seq?: number];
|
|
63
|
+
export declare function releasing<I, O>(mix: Mixer<I, O>): [at?: number, reach?: number, seq?: number, early?: boolean];
|
package/dist/history.js
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
import { elapsedWith } from './clock.js';
|
|
2
2
|
import { clone } from './clone.js';
|
|
3
|
+
import { within } from './cut.js';
|
|
3
4
|
import { schedule } from './due.js';
|
|
4
5
|
import { Leavings } from './leavings.js';
|
|
5
6
|
import { packHeld } from './pack.js';
|
|
6
7
|
import { pageOut } from './paging.js';
|
|
7
8
|
import { scoreTouched } from './scored.js';
|
|
8
|
-
import { within } from './transport.js';
|
|
9
9
|
import { none } from './voice.js';
|
|
10
10
|
/** The last entry taken before `t`, or at it where `inclusive` says so. */
|
|
11
11
|
export function last(list, t, inclusive) {
|
|
@@ -121,7 +121,6 @@ export function copyHeld(voice, h, shared = false) {
|
|
|
121
121
|
since: h.since,
|
|
122
122
|
shown: h.shown,
|
|
123
123
|
weight: h.weight,
|
|
124
|
-
rested: h.rested,
|
|
125
124
|
restedAt: h.restedAt,
|
|
126
125
|
bands: h.bands === null ? null : h.bands.slice(),
|
|
127
126
|
state: h.state === undefined || shared ? h.state : copyState(voice, h.state),
|
|
@@ -145,7 +144,7 @@ export function copyHeld(voice, h, shared = false) {
|
|
|
145
144
|
voice: h.voice,
|
|
146
145
|
next: h.next,
|
|
147
146
|
version: h.version,
|
|
148
|
-
|
|
147
|
+
roles: h.roles,
|
|
149
148
|
slot: h.slot,
|
|
150
149
|
run: h.run,
|
|
151
150
|
freed: h.freed,
|
|
@@ -172,7 +171,6 @@ export function copyHeldInto(voice, h, into, shared = false) {
|
|
|
172
171
|
into.since = h.since;
|
|
173
172
|
into.shown = h.shown;
|
|
174
173
|
into.weight = h.weight;
|
|
175
|
-
into.rested = h.rested;
|
|
176
174
|
into.restedAt = h.restedAt;
|
|
177
175
|
into.bands = h.bands === null ? null : h.bands.slice();
|
|
178
176
|
into.state = h.state === undefined || shared ? h.state : copyState(voice, h.state);
|
|
@@ -192,7 +190,7 @@ export function copyHeldInto(voice, h, into, shared = false) {
|
|
|
192
190
|
into.run = h.run;
|
|
193
191
|
into.freed = h.freed;
|
|
194
192
|
into.restored = null;
|
|
195
|
-
// `probed`, `delta`, `phase`, `seeks`, `snaps`, `inputs`, `next`, `version` and `
|
|
193
|
+
// `probed`, `delta`, `phase`, `seeks`, `snaps`, `inputs`, `next`, `version` and `roles` as
|
|
196
194
|
// `unread` leaves them.
|
|
197
195
|
return unread(into);
|
|
198
196
|
}
|
|
@@ -209,7 +207,7 @@ export function unread(h) {
|
|
|
209
207
|
h.inputs = undefined;
|
|
210
208
|
h.next = null;
|
|
211
209
|
h.version = Number.NaN;
|
|
212
|
-
h.
|
|
210
|
+
h.roles = null;
|
|
213
211
|
return h;
|
|
214
212
|
}
|
|
215
213
|
/** Under `history` with `inputs`, copies the host fields any voice reads, once a frame, when they changed. */
|
|
@@ -334,12 +332,12 @@ export function leave(mix, voice, subject, held) {
|
|
|
334
332
|
});
|
|
335
333
|
}
|
|
336
334
|
/**
|
|
337
|
-
* The mix time a motion patch keeps a released subject from, how far back,
|
|
338
|
-
* history.
|
|
335
|
+
* The mix time a motion patch keeps a released subject from, how far back, the frame, and whether
|
|
336
|
+
* the release came before anything read it, under history.
|
|
339
337
|
*/
|
|
340
338
|
export function releasing(mix) {
|
|
341
339
|
const history = mix.opts.history;
|
|
342
340
|
if (history === undefined || Number.isNaN(mix.now))
|
|
343
341
|
return [];
|
|
344
|
-
return [mix.now, mix.now - history.ms, mix.transport.seq];
|
|
342
|
+
return [mix.now, mix.now - history.ms, mix.transport.seq, mix.syncing || !mix.looked];
|
|
345
343
|
}
|
package/dist/hosts.js
CHANGED
|
@@ -18,7 +18,7 @@ import { localNow } from './place.js';
|
|
|
18
18
|
import { reading } from './reading.js';
|
|
19
19
|
import { heard } from './signals.js';
|
|
20
20
|
import { cuedById } from './strays.js';
|
|
21
|
-
import { record } from './tape.js';
|
|
21
|
+
import { record, taping } from './tape.js';
|
|
22
22
|
import { unreach } from './unreached.js';
|
|
23
23
|
export function book(mix, opts) {
|
|
24
24
|
if (mix.projecting)
|
|
@@ -62,6 +62,7 @@ export function laneHost(mix) {
|
|
|
62
62
|
return mix.held(voice, subject, slot);
|
|
63
63
|
},
|
|
64
64
|
forgot: (slot) => {
|
|
65
|
+
mix.places?.forgot(slot);
|
|
65
66
|
// Only a voice over every subject keeps bits, and one gone may still be read back.
|
|
66
67
|
for (const voice of mix.general) {
|
|
67
68
|
unreach(voice, slot, false);
|
|
@@ -80,11 +81,7 @@ export function laneHost(mix) {
|
|
|
80
81
|
parting: (voice, subject) => mix.parting(voice, subject, mix.now),
|
|
81
82
|
ready: (voice, subject, held) => {
|
|
82
83
|
const arg = mix.lanes.arg;
|
|
83
|
-
|
|
84
|
-
primed[0 /* Primed.NOW */] = mix.now;
|
|
85
|
-
primed[1 /* Primed.ELAPSED */] = arg[1 /* Arg.ELAPSED */];
|
|
86
|
-
primed[2 /* Primed.PASS */] = arg[3 /* Arg.PASS */];
|
|
87
|
-
mix.prime(voice, held);
|
|
84
|
+
mix.primeLaned(voice, held, arg);
|
|
88
85
|
voice.setting.weight = arg[0 /* Arg.WEIGHT */];
|
|
89
86
|
mix.sending.voice = voice;
|
|
90
87
|
mix.sending.subject = subject;
|
|
@@ -97,11 +94,7 @@ export function laneHost(mix) {
|
|
|
97
94
|
arg[0 /* Arg.WEIGHT */] = read;
|
|
98
95
|
return;
|
|
99
96
|
}
|
|
100
|
-
|
|
101
|
-
primed[0 /* Primed.NOW */] = mix.now;
|
|
102
|
-
primed[1 /* Primed.ELAPSED */] = arg[1 /* Arg.ELAPSED */];
|
|
103
|
-
primed[2 /* Primed.PASS */] = arg[3 /* Arg.PASS */];
|
|
104
|
-
mix.prime(voice, held);
|
|
97
|
+
mix.primeLaned(voice, held, arg);
|
|
105
98
|
const kept = reading.kept;
|
|
106
99
|
const base = mix.base(voice, subject, mix.now, held, slot);
|
|
107
100
|
if (reading.kept !== kept && !voice.keeping)
|
|
@@ -145,13 +138,13 @@ export function fits(mix, voice) {
|
|
|
145
138
|
return false;
|
|
146
139
|
if (patch.reads !== undefined && patch.reads.length > 0)
|
|
147
140
|
return false;
|
|
148
|
-
// A
|
|
149
|
-
if (spec.
|
|
141
|
+
// A role on lanes gathers keys and fn members; a motion member keeps it on the general path.
|
|
142
|
+
if (spec.role !== undefined && voice.motion !== undefined)
|
|
150
143
|
return false;
|
|
151
144
|
if (spec.from === 'current')
|
|
152
145
|
return false;
|
|
153
|
-
// A rest-less channel's band is read on the record `one` folds; crowds, motions and
|
|
154
|
-
if ((voice.motion !== undefined || spec.
|
|
146
|
+
// A rest-less channel's band is read on the record `one` folds; crowds, motions and roles fold elsewhere.
|
|
147
|
+
if ((voice.motion !== undefined || spec.role !== undefined || crowdable(voice)) &&
|
|
155
148
|
voice.slots.some((s) => numericOf(mix.channels[s])?.op === 'last'))
|
|
156
149
|
return false;
|
|
157
150
|
if (voice.out?.rest)
|
|
@@ -257,6 +250,7 @@ function handleHost(mix) {
|
|
|
257
250
|
// A voice that stopped sharing makes a subject's record at its next read, from what it kept.
|
|
258
251
|
return held !== undefined ? held.weight : weightAt(voice, slot);
|
|
259
252
|
},
|
|
253
|
+
taping: () => taping(mix),
|
|
260
254
|
record: (h, label, again) => record(mix, label, (stage) => {
|
|
261
255
|
const to = stage.mix(mix);
|
|
262
256
|
if (to === mix)
|
package/dist/index.d.ts
CHANGED
|
@@ -1,25 +1,26 @@
|
|
|
1
|
-
export type { NumberOptions, Vec } from './channels.js';
|
|
1
|
+
export type { LastOptions, NumberOptions, NumberTuple, Vec } from './channels.js';
|
|
2
2
|
export { kit, last, max, mul, sum, vec } from './channels.js';
|
|
3
3
|
export type { ColorOptions } from './color.js';
|
|
4
4
|
export { color, css, mixHex, oklab, toHex } from './color.js';
|
|
5
5
|
export type { Curve } from './easing.js';
|
|
6
6
|
export { curve } from './easing.js';
|
|
7
|
-
export type { Claim, Fit, FitPlan, Order, SpanClaim, Strength } from './fit.js';
|
|
7
|
+
export type { Claim, Fit, FitPlan, Layout, Order, OverrunOptions, SpanClaim, Strength, } from './fit.js';
|
|
8
8
|
export { conclude, condense, lax, layout, overrun, pipe, plain, shed, } from './fit.js';
|
|
9
9
|
export { mix, mixer } from './mixer.js';
|
|
10
|
-
export type { Motion, Moving, PerSubject, Value } from './motion.js';
|
|
10
|
+
export type { Glide, GlideOptions, Motion, MotionOptions, Moving, PerSubject, Spring, SpringOptions, Tween, TweenOptions, Value, } from './motion.js';
|
|
11
11
|
export { glide, spring, tween } from './motion.js';
|
|
12
12
|
export { HistoryMiss } from './paging.js';
|
|
13
13
|
export type { KeysOptions, PatchOptions } from './patch.js';
|
|
14
14
|
export { keys, patch } from './patch.js';
|
|
15
15
|
export type { AngleOptions } from './rotation.js';
|
|
16
16
|
export { angle, quat } from './rotation.js';
|
|
17
|
+
export type { Input, LagOptions, Level, SlewOptions } from './signals.js';
|
|
17
18
|
export { gate, input, lag, level, peak, share, slew } from './signals.js';
|
|
18
19
|
export { fold } from './stack.js';
|
|
19
20
|
export type { Ticked, Ticker, TickerOptions } from './ticker.js';
|
|
20
21
|
export { ticker } from './ticker.js';
|
|
21
22
|
export { transport } from './transport.js';
|
|
22
|
-
export type { Anchor, ArcHandle, ArcPart, ArcSpec, ArcVoice, BlendMember, BookedHit, Booker, BookOptions, Channel, Columns, Described, Doubt, Easing, Engine, FadeOptions, FadeSpec, FitResult, Handle, HistoryOptions, HistoryStore, Hit, Hold, Keyframe, Kit, Mark, Marked, MarkName, Mix, MixOptions, MotionSpec, OwnerSpec, Paged, PagedStream, Patch, Placement, Projection, Query, Registry, SeekOptions, Sent, Setting, Signal, SpanHandle, SpanHints, SpanSpec, Tape, TapeBranch, TapeMaker, TapeOp, Transport, TransportOptions, TransportProjection, VoiceSpec, Watched, WatchedFrame, } from './types.js';
|
|
23
|
+
export type { Anchor, AnnounceOptions, ArcHandle, ArcPart, ArcSpec, ArcVoice, Band, BlendMember, BookedHit, Booker, BookOptions, Channel, Circle, Columns, Described, Doubt, Easing, Engine, FadeOptions, FadeSpec, Finder, FitResult, GlideSpec, Handle, HistoryOptions, HistoryStore, Hit, Hold, Keyframe, Kit, Mark, Marked, MarkName, Mix, MixOptions, MotionSpec, OwnerSpec, Paged, PagedStream, Patch, Placement, Probed, Projection, Pulled, Query, Registry, RegistryChange, SeekOptions, Sent, Setting, Signal, SpanHandle, SpanHints, SpanSpec, SpringSpec, SubjectFade, Taken, Tape, TapeBranch, TapeMaker, TapeOp, TapeOptions, Transport, TransportOptions, TransportProjection, TweenSpec, VoiceFade, VoiceSpec, Watched, WatchedFrame, WatchedHistory, WatchedVoice, } from './types.js';
|
|
23
24
|
export { watched } from './watch.js';
|
|
24
25
|
export type { WaveOptions, WaveShape } from './wave.js';
|
|
25
26
|
export { wave, waveAt } from './wave.js';
|
package/dist/keyfill.d.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { type Lane } from './lane.js';
|
|
2
2
|
import type { Lanes } from './lanes.js';
|
|
3
3
|
/**
|
|
4
|
-
* A keys voice's fill outside a
|
|
4
|
+
* A keys voice's fill outside a role, its weight a number: what `one` does for each subject, in
|
|
5
5
|
* one loop, so no weight or time crosses a call as a boxed double per subject.
|
|
6
6
|
*/
|
|
7
7
|
export declare function runKeys<I, O>(lanes: Lanes<I, O>, lane: Lane<I, O>): void;
|
package/dist/keyfill.js
CHANGED
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
import { foldNumber } from './channels.js';
|
|
2
2
|
import { clampWeight, frozenTime, phaseAt, same, weighed } from './clock.js';
|
|
3
3
|
import { unband } from './fold.js';
|
|
4
|
+
import { keepProbed } from './lane.js';
|
|
4
5
|
import { shortWay } from './turns.js';
|
|
5
6
|
/**
|
|
6
|
-
* A keys voice's fill outside a
|
|
7
|
+
* A keys voice's fill outside a role, its weight a number: what `one` does for each subject, in
|
|
7
8
|
* one loop, so no weight or time crosses a call as a boxed double per subject.
|
|
8
9
|
*/
|
|
9
10
|
export function runKeys(lanes, lane) {
|
|
@@ -18,6 +19,8 @@ export function runKeys(lanes, lane) {
|
|
|
18
19
|
const fills = lanes.fills;
|
|
19
20
|
const lately = lanes.lately;
|
|
20
21
|
const elapsedNow = voice.elapsedAt(lanes.now);
|
|
22
|
+
// For `one`, where a probe meeting the voice later this fill reads it (`foldNow` in `meet.ts`).
|
|
23
|
+
lane.elapsedNow = elapsedNow;
|
|
21
24
|
const duration = voice.duration;
|
|
22
25
|
const passes = voice.passes;
|
|
23
26
|
const before = voice.freezesBefore;
|
|
@@ -39,8 +42,7 @@ export function runKeys(lanes, lane) {
|
|
|
39
42
|
for (let p = 0; p < list.length; p++) {
|
|
40
43
|
const slot = list[p];
|
|
41
44
|
const o = p * 8 /* Row.STRIDE */;
|
|
42
|
-
|
|
43
|
-
data[o + 3 /* Row.PROBED */] = data[o + 2 /* Row.WEIGHT */];
|
|
45
|
+
keepProbed(data, o, per, slot * 6 /* Per.SLOT */, fills);
|
|
44
46
|
if (lately >= 0 && lanes.unread(slot))
|
|
45
47
|
continue;
|
|
46
48
|
const raw = elapsedNow - data[o + 0 /* Row.DELAY */];
|
package/dist/keyrows.d.ts
CHANGED
|
@@ -6,6 +6,7 @@ export interface KeyChannel {
|
|
|
6
6
|
scalar: boolean;
|
|
7
7
|
op: Numeric['op'];
|
|
8
8
|
plain: boolean;
|
|
9
|
+
straight: boolean;
|
|
9
10
|
rest: number;
|
|
10
11
|
axes: number;
|
|
11
12
|
values: Float64Array;
|
|
@@ -21,6 +22,11 @@ export declare class KeyRows {
|
|
|
21
22
|
data: Float64Array<ArrayBuffer>;
|
|
22
23
|
used: number;
|
|
23
24
|
eases: (Curve | undefined)[];
|
|
25
|
+
/** The timing and phase `search` last ran for, and what it found per track. */
|
|
26
|
+
private lastTiming;
|
|
27
|
+
private lastPhase;
|
|
28
|
+
private found;
|
|
29
|
+
private easedAt;
|
|
24
30
|
/**
|
|
25
31
|
* Copies a voice's stops for channels `chans` and returns the row's offset; -1 where a stop's
|
|
26
32
|
* value is not one a lane folds as a number per axis, so the row reads its voice's stops instead.
|
|
@@ -33,5 +39,11 @@ export declare class KeyRows {
|
|
|
33
39
|
* and the stock lerp and fold give for each track, read from this pool.
|
|
34
40
|
*/
|
|
35
41
|
fold(off: number, phase: number, chans: readonly KeyChannel[], slot: number, w: number): void;
|
|
42
|
+
/**
|
|
43
|
+
* What `segment` finds for each track of the row at `off` at `phase`, kept for every row after it
|
|
44
|
+
* with the same timing at the same phase: the stop, and the eased fraction of its segment.
|
|
45
|
+
*/
|
|
46
|
+
private search;
|
|
47
|
+
private grow;
|
|
36
48
|
private reserve;
|
|
37
49
|
}
|
package/dist/keyrows.js
CHANGED
|
@@ -1,7 +1,49 @@
|
|
|
1
1
|
import { foldNumber, lerpNumber } from './channels.js';
|
|
2
2
|
import { fraction, locate, shift } from './patch.js';
|
|
3
|
-
/**
|
|
4
|
-
|
|
3
|
+
/**
|
|
4
|
+
* A row's header: its length in `data`, its offset in `eases`, its duration, its stop count, and
|
|
5
|
+
* its timing's number.
|
|
6
|
+
*/
|
|
7
|
+
const HEAD = 5;
|
|
8
|
+
/**
|
|
9
|
+
* Timings by what makes two rows find the same stop and easing at the same phase: the duration,
|
|
10
|
+
* and each track's delay, stop phases and easings. Numbers are never reused, so clearing the map
|
|
11
|
+
* once it is large only stops rows added later sharing with rows added earlier.
|
|
12
|
+
*/
|
|
13
|
+
const timings = new Map();
|
|
14
|
+
const easeIds = new WeakMap();
|
|
15
|
+
let timed = 0;
|
|
16
|
+
let eased = 0;
|
|
17
|
+
function easeId(ease) {
|
|
18
|
+
if (ease === undefined)
|
|
19
|
+
return 0;
|
|
20
|
+
let id = easeIds.get(ease);
|
|
21
|
+
if (id === undefined) {
|
|
22
|
+
id = ++eased;
|
|
23
|
+
easeIds.set(ease, id);
|
|
24
|
+
}
|
|
25
|
+
return id;
|
|
26
|
+
}
|
|
27
|
+
/** A phase written so -0 and 0 differ, as a stop search can tell them apart. */
|
|
28
|
+
const exact = (x) => (Object.is(x, -0) ? '-0' : String(x));
|
|
29
|
+
function timingOf(built) {
|
|
30
|
+
let key = exact(built.duration);
|
|
31
|
+
for (const track of built.tracks) {
|
|
32
|
+
if (track === undefined)
|
|
33
|
+
return ++timed;
|
|
34
|
+
key += `|${exact(track.delay)}`;
|
|
35
|
+
for (const pt of track.all)
|
|
36
|
+
key += `,${exact(pt.at)}:${easeId(pt.ease)}`;
|
|
37
|
+
}
|
|
38
|
+
let id = timings.get(key);
|
|
39
|
+
if (id === undefined) {
|
|
40
|
+
if (timings.size >= 4096)
|
|
41
|
+
timings.clear();
|
|
42
|
+
id = ++timed;
|
|
43
|
+
timings.set(key, id);
|
|
44
|
+
}
|
|
45
|
+
return id;
|
|
46
|
+
}
|
|
5
47
|
/**
|
|
6
48
|
* The stops of a crowd's `keys` rows, copied into one array as a row joins, so a fill reads each
|
|
7
49
|
* row's stops in place rather than through its voice, its built tracks and every stop's own array.
|
|
@@ -13,6 +55,11 @@ export class KeyRows {
|
|
|
13
55
|
data = new Float64Array(64);
|
|
14
56
|
used = 0;
|
|
15
57
|
eases = [];
|
|
58
|
+
/** The timing and phase `search` last ran for, and what it found per track. */
|
|
59
|
+
lastTiming = -1;
|
|
60
|
+
lastPhase = Number.NaN;
|
|
61
|
+
found = new Int32Array(4);
|
|
62
|
+
easedAt = new Float64Array(4);
|
|
16
63
|
/**
|
|
17
64
|
* Copies a voice's stops for channels `chans` and returns the row's offset; -1 where a stop's
|
|
18
65
|
* value is not one a lane folds as a number per axis, so the row reads its voice's stops instead.
|
|
@@ -23,7 +70,7 @@ export class KeyRows {
|
|
|
23
70
|
for (let i = 0; i < built.tracks.length; i++) {
|
|
24
71
|
const track = built.tracks[i];
|
|
25
72
|
const ch = chans[i];
|
|
26
|
-
if (track === undefined || ch === undefined || !ch.plain)
|
|
73
|
+
if (track === undefined || ch === undefined || !ch.plain || !ch.straight)
|
|
27
74
|
return -1;
|
|
28
75
|
for (const pt of track.all)
|
|
29
76
|
if (!flat(pt.value, ch))
|
|
@@ -37,6 +84,7 @@ export class KeyRows {
|
|
|
37
84
|
d[off + 1] = this.eases.length;
|
|
38
85
|
d[off + 2] = built.duration;
|
|
39
86
|
d[off + 3] = stops;
|
|
87
|
+
d[off + 4] = timingOf(built);
|
|
40
88
|
let o = off + HEAD;
|
|
41
89
|
for (let i = 0; i < built.tracks.length; i++) {
|
|
42
90
|
const track = built.tracks[i];
|
|
@@ -75,8 +123,12 @@ export class KeyRows {
|
|
|
75
123
|
*/
|
|
76
124
|
fold(off, phase, chans, slot, w) {
|
|
77
125
|
const d = this.data;
|
|
78
|
-
const
|
|
79
|
-
|
|
126
|
+
const timing = d[off + 4];
|
|
127
|
+
// A phase of 0 is searched afresh: -0 and 0 compare equal and need not find the same.
|
|
128
|
+
if (timing !== this.lastTiming || phase !== this.lastPhase || phase === 0)
|
|
129
|
+
this.search(off, phase, chans);
|
|
130
|
+
const found = this.found;
|
|
131
|
+
const easedAt = this.easedAt;
|
|
80
132
|
let o = off + HEAD;
|
|
81
133
|
const end = off + d[off];
|
|
82
134
|
for (let i = 0; o < end; i++) {
|
|
@@ -84,12 +136,9 @@ export class KeyRows {
|
|
|
84
136
|
const axes = ch.axes;
|
|
85
137
|
const stride = 1 + axes;
|
|
86
138
|
const n = d[o];
|
|
87
|
-
const ph = shift(d[o + 1], phase, duration);
|
|
88
139
|
const first = o + 2;
|
|
89
140
|
o = first + n * stride;
|
|
90
|
-
const k =
|
|
91
|
-
const stops = e;
|
|
92
|
-
e += n;
|
|
141
|
+
const k = found[i];
|
|
93
142
|
if (k === -2)
|
|
94
143
|
continue;
|
|
95
144
|
const values = ch.values;
|
|
@@ -102,15 +151,53 @@ export class KeyRows {
|
|
|
102
151
|
}
|
|
103
152
|
const b = first + k * stride;
|
|
104
153
|
const before = b - stride;
|
|
105
|
-
const
|
|
106
|
-
const ease = this.eases[stops + k];
|
|
107
|
-
const eased = ease ? ease(u) : u;
|
|
154
|
+
const eased = easedAt[i];
|
|
108
155
|
for (let a = 0; a < axes; a++) {
|
|
109
156
|
const v = lerpNumber(d[before + 1 + a], d[b + 1 + a], eased);
|
|
110
157
|
values[base + a] = foldNumber(ch.op, values[base + a], v, w);
|
|
111
158
|
}
|
|
112
159
|
}
|
|
113
160
|
}
|
|
161
|
+
/**
|
|
162
|
+
* What `segment` finds for each track of the row at `off` at `phase`, kept for every row after it
|
|
163
|
+
* with the same timing at the same phase: the stop, and the eased fraction of its segment.
|
|
164
|
+
*/
|
|
165
|
+
search(off, phase, chans) {
|
|
166
|
+
const d = this.data;
|
|
167
|
+
this.lastTiming = -1;
|
|
168
|
+
const duration = d[off + 2];
|
|
169
|
+
let e = d[off + 1];
|
|
170
|
+
let o = off + HEAD;
|
|
171
|
+
const end = off + d[off];
|
|
172
|
+
for (let i = 0; o < end; i++) {
|
|
173
|
+
if (i >= this.found.length)
|
|
174
|
+
this.grow(i + 1);
|
|
175
|
+
const stride = 1 + chans[i].axes;
|
|
176
|
+
const n = d[o];
|
|
177
|
+
const ph = shift(d[o + 1], phase, duration);
|
|
178
|
+
const first = o + 2;
|
|
179
|
+
o = first + n * stride;
|
|
180
|
+
const k = locate(d, first, stride, n, ph);
|
|
181
|
+
this.found[i] = k;
|
|
182
|
+
if (k >= 0 && k < n) {
|
|
183
|
+
const b = first + k * stride;
|
|
184
|
+
const u = fraction(ph, d[b - stride], d[b]);
|
|
185
|
+
const ease = this.eases[e + k];
|
|
186
|
+
this.easedAt[i] = ease ? ease(u) : u;
|
|
187
|
+
}
|
|
188
|
+
e += n;
|
|
189
|
+
}
|
|
190
|
+
this.lastTiming = d[off + 4];
|
|
191
|
+
this.lastPhase = phase;
|
|
192
|
+
}
|
|
193
|
+
grow(tracks) {
|
|
194
|
+
const found = new Int32Array(tracks * 2);
|
|
195
|
+
found.set(this.found);
|
|
196
|
+
this.found = found;
|
|
197
|
+
const easedAt = new Float64Array(tracks * 2);
|
|
198
|
+
easedAt.set(this.easedAt);
|
|
199
|
+
this.easedAt = easedAt;
|
|
200
|
+
}
|
|
114
201
|
reserve(len) {
|
|
115
202
|
const at = this.used;
|
|
116
203
|
if (at + len > this.data.length) {
|
package/dist/lane.d.ts
CHANGED
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
import type { Numeric } from './channels.js';
|
|
2
2
|
import type { Motions } from './motions.js';
|
|
3
3
|
import type { Scratch } from './patch.js';
|
|
4
|
+
import type { Subject } from './subject.js';
|
|
4
5
|
import type { Channel } from './types.js';
|
|
5
|
-
import type {
|
|
6
|
+
import type { Voice } from './voice.js';
|
|
6
7
|
/** One laned channel: its arithmetic, and every numbered subject's folded value, `axes` per subject. */
|
|
7
8
|
export interface Laned {
|
|
8
9
|
name: string;
|
|
@@ -11,6 +12,8 @@ export interface Laned {
|
|
|
11
12
|
op: Numeric['op'];
|
|
12
13
|
/** Its values fold as its `op` alone: not through a band as `'last'` does, and not a rotation. */
|
|
13
14
|
plain: boolean;
|
|
15
|
+
/** A plain channel's values lerp straight across each axis, not through the channel's `lerp`. */
|
|
16
|
+
straight: boolean;
|
|
14
17
|
/** An angle's full turn, and 0 for any other channel. */
|
|
15
18
|
turn: number;
|
|
16
19
|
/** The channel, whose own `fold` and `lerp` an `'own'` lane calls. */
|
|
@@ -24,11 +27,11 @@ export interface Laned {
|
|
|
24
27
|
index: number;
|
|
25
28
|
}
|
|
26
29
|
/**
|
|
27
|
-
* The laned voices sharing one
|
|
30
|
+
* The laned voices sharing one role, in voice order, and what a fill gathers from them for each
|
|
28
31
|
* subject before folding it in at the subject's first member: their summed weight, and per laned
|
|
29
32
|
* channel the members' values lerped by share of weight and the weight taken into each.
|
|
30
33
|
*/
|
|
31
|
-
export interface
|
|
34
|
+
export interface Role<I, O> {
|
|
32
35
|
readonly members: Lane<I, O>[];
|
|
33
36
|
/** By subject number: the fill that last met it, the member it met first then, the summed weight. */
|
|
34
37
|
met: Float64Array;
|
|
@@ -37,6 +40,10 @@ export interface Locus<I, O> {
|
|
|
37
40
|
/** By laned channel, then subject number (times axes for `values`). */
|
|
38
41
|
values: (Float64Array | undefined)[];
|
|
39
42
|
taken: (Float64Array | undefined)[];
|
|
43
|
+
/** No other laned or crowded voice falls between its members in voice order, as qualify found. */
|
|
44
|
+
contiguous: boolean;
|
|
45
|
+
/** This fill runs it a subject at a time at its first member's turn, folding each as it goes. */
|
|
46
|
+
inline: boolean;
|
|
40
47
|
}
|
|
41
48
|
/**
|
|
42
49
|
* Where each of a lane position's or crowd row's `STRIDE` numbers sits. The layouts are const
|
|
@@ -58,6 +65,11 @@ export declare const enum Row {
|
|
|
58
65
|
/** 1 once the general path has made the voice's first call for the subject, which never undoes. */
|
|
59
66
|
MET = 7
|
|
60
67
|
}
|
|
68
|
+
/**
|
|
69
|
+
* Keeps the weight a probe read from the last fill as `Row.PROBED`, for `weightOf`, before a fill
|
|
70
|
+
* writes the position's new weight; reads `per` only where the copy could change a bit.
|
|
71
|
+
*/
|
|
72
|
+
export declare function keepProbed(data: Float64Array, o: number, per: Float64Array, q: number, fills: number): void;
|
|
61
73
|
/** What `begin` found: the general path, or lanes filled. */
|
|
62
74
|
export declare const enum Begin {
|
|
63
75
|
GENERAL = 0,
|
|
@@ -79,7 +91,14 @@ export declare const enum Arg {
|
|
|
79
91
|
DELAY = 4,
|
|
80
92
|
/** The voice's own fade, for `signalled`. */
|
|
81
93
|
FADE = 5,
|
|
82
|
-
|
|
94
|
+
/**
|
|
95
|
+
* The fill and voice time a lane's subjects share since it last placed one, numbered once per
|
|
96
|
+
* placing; NaN where the caller shares none. A setting already filled under it skips its per-lane fields.
|
|
97
|
+
*/
|
|
98
|
+
MARK = 6,
|
|
99
|
+
/** A number a delta gave, for `gatherScalar`. */
|
|
100
|
+
VALUE = 7,
|
|
101
|
+
SIZE = 8
|
|
83
102
|
}
|
|
84
103
|
/** Where each of a subject's `SLOT` numbers in `Lanes.per` sits. */
|
|
85
104
|
export declare const enum Per {
|
|
@@ -207,6 +226,8 @@ export declare class Lane<I, O> implements Positions<I, O> {
|
|
|
207
226
|
fade: number;
|
|
208
227
|
/** Whether the voice has no fade in or out this fill, so its envelope is 1 for every subject. */
|
|
209
228
|
flat: boolean;
|
|
229
|
+
/** The fill that last ran it, so what it remembers within one fill is that fill's. */
|
|
230
|
+
ran: number;
|
|
210
231
|
/** The voice's clock at this fill, set before `one` runs its subjects. */
|
|
211
232
|
elapsedNow: number;
|
|
212
233
|
/** A motion patch's state, which the lane samples in place of calling the patch. */
|
|
@@ -217,8 +238,12 @@ export declare class Lane<I, O> implements Positions<I, O> {
|
|
|
217
238
|
bareFill: number;
|
|
218
239
|
bareElapsed: number;
|
|
219
240
|
bareSeeks: number;
|
|
220
|
-
/** The
|
|
221
|
-
group:
|
|
241
|
+
/** The role its voice shares, gathered before the voices are folded in order. */
|
|
242
|
+
group: Role<I, O> | null;
|
|
243
|
+
/** The `Arg.MARK` it was last placed under, for a role run a subject at a time to put back. */
|
|
244
|
+
mark: number;
|
|
245
|
+
/** Whether it took every subject when it opened, so a fill makes each one's first call. */
|
|
246
|
+
every: boolean;
|
|
222
247
|
voiceAt(): Voice<I, O>;
|
|
223
248
|
fix(p: number): void;
|
|
224
249
|
numbered(p: number, ms: number): void;
|
|
@@ -228,6 +253,11 @@ export declare class Lane<I, O> implements Positions<I, O> {
|
|
|
228
253
|
motionAt(): Motions<I> | undefined;
|
|
229
254
|
constructor(voice: Voice<I, O>);
|
|
230
255
|
positionOf(slot: number): number;
|
|
256
|
+
/**
|
|
257
|
+
* Room for `n` positions and subject numbers below `cap`, for a voice that reaches every subject:
|
|
258
|
+
* grown as it met them, a voice replaced every frame regrew both from nothing each frame.
|
|
259
|
+
*/
|
|
260
|
+
reserve(n: number, cap: number): void;
|
|
231
261
|
/** Gives a subject the voice reaches a position, from what its record fixed on first sight. */
|
|
232
262
|
add(slot: number, held: Subject<unknown>): void;
|
|
233
263
|
/** A subject lost its number: the last position moves into its place. */
|