@msb235/blits 0.7.1 → 0.8.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 +193 -0
- package/README.md +22 -4
- package/dist/book.js +4 -4
- package/dist/chain.d.ts +1 -1
- package/dist/chain.js +57 -54
- package/dist/channels.d.ts +26 -5
- package/dist/channels.js +12 -8
- package/dist/clock.d.ts +8 -1
- package/dist/clock.js +14 -3
- package/dist/clone.d.ts +8 -0
- package/dist/clone.js +22 -0
- package/dist/closed.d.ts +1 -1
- package/dist/closed.js +3 -2
- package/dist/color.d.ts +0 -11
- package/dist/color.js +4 -24
- package/dist/columns.js +0 -1
- package/dist/copyout.d.ts +6 -0
- package/dist/copyout.js +38 -0
- package/dist/crowd.d.ts +7 -5
- package/dist/crowd.js +32 -18
- package/dist/cue.d.ts +3 -1
- package/dist/cue.js +31 -20
- package/dist/departed.d.ts +34 -0
- package/dist/departed.js +73 -0
- package/dist/easing.d.ts +5 -0
- package/dist/easing.js +31 -2
- package/dist/everyone.d.ts +56 -0
- package/dist/everyone.js +221 -0
- package/dist/fade.d.ts +8 -1
- package/dist/fade.js +34 -6
- package/dist/fill.d.ts +22 -13
- package/dist/fill.js +104 -41
- package/dist/fit.js +2 -1
- package/dist/fold.d.ts +37 -0
- package/dist/fold.js +216 -31
- package/dist/frames.d.ts +21 -0
- package/dist/frames.js +59 -0
- package/dist/gather.d.ts +15 -9
- package/dist/gather.js +60 -25
- package/dist/gone.js +10 -0
- package/dist/handle.d.ts +16 -5
- package/dist/handle.js +56 -6
- package/dist/held.d.ts +8 -5
- package/dist/held.js +56 -58
- package/dist/history.d.ts +17 -13
- package/dist/history.js +47 -28
- package/dist/hosts.js +55 -8
- package/dist/index.d.ts +9 -4
- package/dist/index.js +5 -2
- package/dist/keyfill.d.ts +7 -0
- package/dist/keyfill.js +124 -0
- package/dist/keyrows.d.ts +1 -0
- package/dist/keyrows.js +1 -1
- package/dist/lane.d.ts +32 -2
- package/dist/lane.js +5 -0
- package/dist/lanes.d.ts +32 -8
- package/dist/lanes.js +69 -37
- package/dist/leavings.d.ts +26 -0
- package/dist/leavings.js +70 -0
- package/dist/locus.js +2 -2
- package/dist/meet.js +14 -8
- package/dist/mixer.d.ts +39 -7
- package/dist/mixer.js +50 -10
- package/dist/motion.d.ts +2 -0
- package/dist/motion.js +4 -1
- package/dist/motions.d.ts +22 -15
- package/dist/motions.js +40 -34
- package/dist/move.js +23 -16
- package/dist/moved.d.ts +11 -0
- package/dist/moved.js +29 -0
- package/dist/origin.d.ts +19 -0
- package/dist/origin.js +68 -0
- package/dist/owed.d.ts +4 -4
- package/dist/owed.js +8 -8
- package/dist/owner.d.ts +1 -1
- package/dist/owner.js +2 -2
- package/dist/pace.d.ts +13 -5
- package/dist/pace.js +21 -8
- package/dist/pack.d.ts +3 -1
- package/dist/pack.js +15 -24
- package/dist/paging.d.ts +8 -2
- package/dist/paging.js +39 -4
- package/dist/patch.d.ts +14 -9
- package/dist/patch.js +83 -21
- package/dist/place.js +18 -3
- package/dist/project.d.ts +12 -1
- package/dist/project.js +101 -83
- package/dist/pull.d.ts +2 -0
- package/dist/pull.js +8 -0
- package/dist/qualify.js +10 -2
- package/dist/reading.d.ts +5 -0
- package/dist/reading.js +5 -0
- package/dist/record.d.ts +9 -0
- package/dist/record.js +42 -0
- package/dist/relink.d.ts +11 -5
- package/dist/relink.js +7 -5
- package/dist/restored.d.ts +41 -0
- package/dist/restored.js +91 -0
- package/dist/revive.d.ts +10 -3
- package/dist/revive.js +31 -23
- package/dist/roster.d.ts +11 -0
- package/dist/roster.js +46 -0
- package/dist/rotation.d.ts +29 -0
- package/dist/rotation.js +91 -0
- package/dist/rows.d.ts +5 -5
- package/dist/rows.js +5 -5
- package/dist/sample.d.ts +3 -2
- package/dist/sample.js +32 -15
- package/dist/seek.js +97 -114
- package/dist/shared.d.ts +6 -0
- package/dist/shared.js +15 -0
- package/dist/signals.d.ts +24 -3
- package/dist/signals.js +50 -11
- package/dist/spans.js +7 -0
- package/dist/stack.d.ts +11 -0
- package/dist/stack.js +47 -0
- package/dist/standing.d.ts +10 -0
- package/dist/standing.js +79 -0
- package/dist/store.d.ts +3 -3
- package/dist/store.js +3 -3
- package/dist/strays.js +3 -0
- package/dist/tape.d.ts +8 -5
- package/dist/tape.js +21 -13
- package/dist/testing.d.ts +35 -0
- package/dist/testing.js +116 -0
- package/dist/touch.d.ts +6 -0
- package/dist/touch.js +28 -0
- package/dist/transport.d.ts +45 -6
- package/dist/transport.js +64 -19
- package/dist/turns.d.ts +18 -0
- package/dist/turns.js +72 -0
- package/dist/tweened.js +1 -1
- package/dist/types/channel.d.ts +46 -0
- package/dist/types/channel.js +1 -0
- package/dist/types/history.d.ts +139 -0
- package/dist/types/history.js +1 -0
- package/dist/types/mix.d.ts +336 -0
- package/dist/types/mix.js +1 -0
- package/dist/types/patch.d.ts +187 -0
- package/dist/types/patch.js +1 -0
- package/dist/types/place.d.ts +157 -0
- package/dist/types/place.js +1 -0
- package/dist/types/transport.d.ts +71 -0
- package/dist/types/transport.js +1 -0
- package/dist/types/voice.d.ts +323 -0
- package/dist/types/voice.js +1 -0
- package/dist/types.d.ts +7 -1162
- package/dist/unpage.d.ts +2 -2
- package/dist/unpage.js +53 -25
- package/dist/voice.d.ts +90 -22
- package/dist/voice.js +105 -43
- package/dist/wave.d.ts +42 -0
- package/dist/wave.js +62 -0
- package/dist/weigh.js +1 -1
- package/docs/schema.html +42 -36
- package/package.json +8 -3
package/dist/origin.d.ts
ADDED
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { type Clock } from './clock.js';
|
|
2
|
+
import type { Voice } from './voice.js';
|
|
3
|
+
/** A clock a voice ran on before its current one, until its local time `until`. */
|
|
4
|
+
export interface Past extends Clock {
|
|
5
|
+
until: number;
|
|
6
|
+
/** The voice's `rebuilds` while it ran on this clock. */
|
|
7
|
+
rebuilds: number;
|
|
8
|
+
}
|
|
9
|
+
/**
|
|
10
|
+
* Keeps the clock a voice is leaving at its local time `u`, ahead of a rate change, ramp or seek,
|
|
11
|
+
* where a subject's origin could still be found on it.
|
|
12
|
+
*/
|
|
13
|
+
export declare function leave<I, O>(voice: Voice<I, O>, u: number): void;
|
|
14
|
+
/**
|
|
15
|
+
* The mix time a voice's clock first read `elapsed`, or will by its controls now, through its owners'
|
|
16
|
+
* clocks. A clock entered already past it, by a seek, answers where that clock would have read it.
|
|
17
|
+
* `rebuilt` starts from the last seek that rebuilt state, as a stateful record does.
|
|
18
|
+
*/
|
|
19
|
+
export declare function originOf<I, O>(voice: Voice<I, O>, elapsed: number, rebuilt: boolean): number;
|
package/dist/origin.js
ADDED
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
import { elapsedWith, timeWith } from './clock.js';
|
|
2
|
+
/** The most past clocks a voice keeps. */
|
|
3
|
+
const MOST = 256;
|
|
4
|
+
/**
|
|
5
|
+
* Keeps the clock a voice is leaving at its local time `u`, ahead of a rate change, ramp or seek,
|
|
6
|
+
* where a subject's origin could still be found on it.
|
|
7
|
+
*/
|
|
8
|
+
export function leave(voice, u) {
|
|
9
|
+
const past = voice.clocks;
|
|
10
|
+
if (past !== null && past.length >= MOST)
|
|
11
|
+
return;
|
|
12
|
+
// A voice with neither stagger nor children is only ever asked when its clock read 0.
|
|
13
|
+
const reach = voice.holding !== null || voice.spec.stagger !== undefined ? Number.POSITIVE_INFINITY : 0;
|
|
14
|
+
if (past !== null && reached(past, 0) >= reach && reached(past, fresh(voice)) >= reach)
|
|
15
|
+
return;
|
|
16
|
+
const { anchorNow, anchorElapsed, rate, ramp, rebuilds } = voice;
|
|
17
|
+
const left = { anchorNow, anchorElapsed, rate, ramp, until: u, rebuilds };
|
|
18
|
+
if (past === null)
|
|
19
|
+
voice.clocks = [left];
|
|
20
|
+
else
|
|
21
|
+
past.push(left);
|
|
22
|
+
}
|
|
23
|
+
/** The most a voice's past clocks from index `from` read before they were left. */
|
|
24
|
+
function reached(past, from) {
|
|
25
|
+
let most = Number.NEGATIVE_INFINITY;
|
|
26
|
+
for (let i = from; i < past.length; i++) {
|
|
27
|
+
const p = past[i];
|
|
28
|
+
const e = elapsedWith(p, p.until);
|
|
29
|
+
if (e > most)
|
|
30
|
+
most = e;
|
|
31
|
+
}
|
|
32
|
+
return most;
|
|
33
|
+
}
|
|
34
|
+
/** Where a walk for a record rebuilt by the voice's last seek starts: its first clock since. */
|
|
35
|
+
function fresh(voice) {
|
|
36
|
+
const past = voice.clocks;
|
|
37
|
+
if (past === null)
|
|
38
|
+
return 0;
|
|
39
|
+
let i = 0;
|
|
40
|
+
while (i < past.length && past[i].rebuilds !== voice.rebuilds)
|
|
41
|
+
i++;
|
|
42
|
+
return i;
|
|
43
|
+
}
|
|
44
|
+
/**
|
|
45
|
+
* The mix time a voice's clock first read `elapsed`, or will by its controls now, through its owners'
|
|
46
|
+
* clocks. A clock entered already past it, by a seek, answers where that clock would have read it.
|
|
47
|
+
* `rebuilt` starts from the last seek that rebuilt state, as a stateful record does.
|
|
48
|
+
*/
|
|
49
|
+
export function originOf(voice, elapsed, rebuilt) {
|
|
50
|
+
const past = voice.clocks;
|
|
51
|
+
let t = Number.NaN;
|
|
52
|
+
if (past !== null) {
|
|
53
|
+
for (let i = rebuilt ? fresh(voice) : 0; i < past.length; i++) {
|
|
54
|
+
const p = past[i];
|
|
55
|
+
const at = timeWith(p, elapsed);
|
|
56
|
+
if (at <= p.until) {
|
|
57
|
+
t = at;
|
|
58
|
+
break;
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
if (Number.isNaN(t)) {
|
|
63
|
+
t = timeWith(voice, elapsed);
|
|
64
|
+
if (t === Number.POSITIVE_INFINITY)
|
|
65
|
+
t = voice.start + elapsed;
|
|
66
|
+
}
|
|
67
|
+
return voice.owner === null ? t : originOf(voice.owner, t, rebuilt);
|
|
68
|
+
}
|
package/dist/owed.d.ts
CHANGED
|
@@ -17,8 +17,8 @@ export declare class Owed {
|
|
|
17
17
|
owes(slot: number): boolean;
|
|
18
18
|
/** Whether the subject at `slot` owes voice `id` this fill. */
|
|
19
19
|
owesVoice(slot: number, id: number): boolean;
|
|
20
|
-
/** The subject at `slot` owes the voices `met`, which the caller may reuse after. */
|
|
21
|
-
owe(slot: number, met: readonly number[]): void;
|
|
22
|
-
/** Whether `met`
|
|
23
|
-
last(met: readonly number[]): boolean;
|
|
20
|
+
/** The subject at `slot` owes the first `n` voices of `met`, which the caller may reuse after. */
|
|
21
|
+
owe(slot: number, met: readonly number[], n: number): void;
|
|
22
|
+
/** Whether the first `n` of `met` are the last list a subject came to owe this fill. */
|
|
23
|
+
last(met: readonly number[], n: number): boolean;
|
|
24
24
|
}
|
package/dist/owed.js
CHANGED
|
@@ -31,19 +31,19 @@ export class Owed {
|
|
|
31
31
|
owesVoice(slot, id) {
|
|
32
32
|
return this.lists[this.at[slot]].includes(id);
|
|
33
33
|
}
|
|
34
|
-
/** The subject at `slot` owes the voices `met`, which the caller may reuse after. */
|
|
35
|
-
owe(slot, met) {
|
|
36
|
-
if (!this.last(met))
|
|
37
|
-
this.lists.push(met.slice());
|
|
34
|
+
/** The subject at `slot` owes the first `n` voices of `met`, which the caller may reuse after. */
|
|
35
|
+
owe(slot, met, n) {
|
|
36
|
+
if (!this.last(met, n))
|
|
37
|
+
this.lists.push(met.slice(0, n));
|
|
38
38
|
this.fill[slot] = this.now;
|
|
39
39
|
this.at[slot] = this.lists.length - 1;
|
|
40
40
|
}
|
|
41
|
-
/** Whether `met`
|
|
42
|
-
last(met) {
|
|
41
|
+
/** Whether the first `n` of `met` are the last list a subject came to owe this fill. */
|
|
42
|
+
last(met, n) {
|
|
43
43
|
const last = this.lists[this.lists.length - 1];
|
|
44
|
-
if (last === undefined || last.length !==
|
|
44
|
+
if (last === undefined || last.length !== n)
|
|
45
45
|
return false;
|
|
46
|
-
for (let i = 0; i <
|
|
46
|
+
for (let i = 0; i < n; i++)
|
|
47
47
|
if (last[i] !== met[i])
|
|
48
48
|
return false;
|
|
49
49
|
return true;
|
package/dist/owner.d.ts
CHANGED
|
@@ -24,7 +24,7 @@ export declare function adopt<I, O>(owner: Voice<I, O>, child: Voice<I, O>): voi
|
|
|
24
24
|
/** A child left: its owner, where that was its last child and it should leave too. */
|
|
25
25
|
export declare function orphan<I, O>(child: Voice<I, O>): Voice<I, O> | null;
|
|
26
26
|
/** A child finished its passes: its owner has played once every child it held has. */
|
|
27
|
-
export declare function childPlayed<I, O>(owner: Voice<I, O>, at: number): void;
|
|
27
|
+
export declare function childPlayed<I, O>(owner: Voice<I, O>, at: number, seq: number): void;
|
|
28
28
|
/** Every voice an owner holds, its children's children included. */
|
|
29
29
|
export declare function descendants<I, O>(owner: Voice<I, O>, visit: (v: Voice<I, O>) => void): void;
|
|
30
30
|
/** Whether any owner above a voice reads a signal for its weight, which lanes cannot fill. */
|
package/dist/owner.js
CHANGED
|
@@ -48,10 +48,10 @@ export function orphan(child) {
|
|
|
48
48
|
return h.children.length === 0 && owner.state !== 'done' ? owner : null;
|
|
49
49
|
}
|
|
50
50
|
/** A child finished its passes: its owner has played once every child it held has. */
|
|
51
|
-
export function childPlayed(owner, at) {
|
|
51
|
+
export function childPlayed(owner, at, seq) {
|
|
52
52
|
const h = owner.holding;
|
|
53
53
|
if (++h.played === h.kids)
|
|
54
|
-
owner.play(true, at);
|
|
54
|
+
owner.play(true, at, seq);
|
|
55
55
|
}
|
|
56
56
|
/** Every voice an owner holds, its children's children included. */
|
|
57
57
|
export function descendants(owner, visit) {
|
package/dist/pace.d.ts
CHANGED
|
@@ -1,4 +1,8 @@
|
|
|
1
1
|
import { type Clock } from './clock.js';
|
|
2
|
+
/** A clock in a pace's log, with the frame that set it, which a history store's cut goes by. */
|
|
3
|
+
export interface Paced extends Clock {
|
|
4
|
+
seq: number;
|
|
5
|
+
}
|
|
2
6
|
/**
|
|
3
7
|
* A mix's own rate, as a clock: mix time as a function of host time, which here means the host's
|
|
4
8
|
* timestamp less what `rebase` took out. Each entry is the clock from the host time it took effect,
|
|
@@ -9,7 +13,7 @@ import { type Clock } from './clock.js';
|
|
|
9
13
|
export declare class Pace {
|
|
10
14
|
private readonly keeps;
|
|
11
15
|
private log;
|
|
12
|
-
constructor(keeps: boolean, log?:
|
|
16
|
+
constructor(keeps: boolean, log?: Paced[]);
|
|
13
17
|
private get clock();
|
|
14
18
|
/** Set before the first sync, the clock waits to be anchored there, reading host time until then. */
|
|
15
19
|
private get waiting();
|
|
@@ -30,11 +34,15 @@ export declare class Pace {
|
|
|
30
34
|
/** Whether the mix clock stands still from host time `u` on, short of another change. */
|
|
31
35
|
stopped(u: number): boolean;
|
|
32
36
|
/**
|
|
33
|
-
* Sets the rate from host time `u`, at once or over `over` host ms, the way a
|
|
34
|
-
* voice's. Under history, lets go of the entries a read no longer reaches: those
|
|
35
|
-
* time `reach`.
|
|
37
|
+
* Sets the rate from host time `u`, in frame `seq`, at once or over `over` host ms, the way a
|
|
38
|
+
* handle sets a voice's. Under history, lets go of the entries a read no longer reaches: those
|
|
39
|
+
* over before mix time `reach`.
|
|
36
40
|
*/
|
|
37
|
-
change(u: number, rate: number, over: number, reach: number): void;
|
|
41
|
+
change(u: number, rate: number, over: number, reach: number, seq: number): void;
|
|
42
|
+
/** Lets go of the clocks over before mix time `reach`, and answers them. */
|
|
43
|
+
shed(reach: number): Paced[];
|
|
44
|
+
/** Puts back clocks a history store kept, ahead of the oldest still held. */
|
|
45
|
+
unshed(back: readonly Paced[]): void;
|
|
38
46
|
/** Lets go of the clocks set after host time `u`, for a seek back to then. */
|
|
39
47
|
cut(u: number): void;
|
|
40
48
|
/** A copy holding the clocks that took effect before host time `u`, for a read back to then. */
|
package/dist/pace.js
CHANGED
|
@@ -9,7 +9,9 @@ import { elapsedWith, rateWith, retime, timeWith } from './clock.js';
|
|
|
9
9
|
export class Pace {
|
|
10
10
|
keeps;
|
|
11
11
|
log;
|
|
12
|
-
constructor(keeps, log = [
|
|
12
|
+
constructor(keeps, log = [
|
|
13
|
+
{ anchorNow: 0, anchorElapsed: 0, rate: 1, ramp: null, seq: Number.NEGATIVE_INFINITY },
|
|
14
|
+
]) {
|
|
13
15
|
this.keeps = keeps;
|
|
14
16
|
this.log = log;
|
|
15
17
|
}
|
|
@@ -75,13 +77,13 @@ export class Pace {
|
|
|
75
77
|
return r.to === 0 && !this.waiting && u >= c.anchorNow + r.over;
|
|
76
78
|
}
|
|
77
79
|
/**
|
|
78
|
-
* Sets the rate from host time `u`, at once or over `over` host ms, the way a
|
|
79
|
-
* voice's. Under history, lets go of the entries a read no longer reaches: those
|
|
80
|
-
* time `reach`.
|
|
80
|
+
* Sets the rate from host time `u`, in frame `seq`, at once or over `over` host ms, the way a
|
|
81
|
+
* handle sets a voice's. Under history, lets go of the entries a read no longer reaches: those
|
|
82
|
+
* over before mix time `reach`.
|
|
81
83
|
*/
|
|
82
|
-
change(u, rate, over, reach) {
|
|
84
|
+
change(u, rate, over, reach, seq) {
|
|
83
85
|
const was = this.clock;
|
|
84
|
-
const next = { ...was };
|
|
86
|
+
const next = { ...was, seq };
|
|
85
87
|
if (Number.isNaN(u) || this.waiting) {
|
|
86
88
|
const from = this.rateAt(Number.NaN);
|
|
87
89
|
next.ramp = over > 0 && rate !== from ? { from, to: rate, over } : null;
|
|
@@ -96,11 +98,22 @@ export class Pace {
|
|
|
96
98
|
log.push(next);
|
|
97
99
|
else
|
|
98
100
|
log[log.length - 1] = next;
|
|
101
|
+
this.shed(reach);
|
|
102
|
+
}
|
|
103
|
+
/** Lets go of the clocks over before mix time `reach`, and answers them. */
|
|
104
|
+
shed(reach) {
|
|
105
|
+
const log = this.log;
|
|
99
106
|
let drop = 0;
|
|
100
107
|
while (drop + 1 < log.length && log[drop + 1].anchorElapsed <= reach)
|
|
101
108
|
drop++;
|
|
102
|
-
|
|
103
|
-
|
|
109
|
+
return drop > 0 ? log.splice(0, drop) : [];
|
|
110
|
+
}
|
|
111
|
+
/** Puts back clocks a history store kept, ahead of the oldest still held. */
|
|
112
|
+
unshed(back) {
|
|
113
|
+
const first = this.log[0].anchorNow;
|
|
114
|
+
const older = back.filter((c) => c.anchorNow < first).sort((a, b) => a.anchorNow - b.anchorNow);
|
|
115
|
+
if (older.length > 0)
|
|
116
|
+
this.log = [...older, ...this.log];
|
|
104
117
|
}
|
|
105
118
|
/** Lets go of the clocks set after host time `u`, for a seek back to then. */
|
|
106
119
|
cut(u) {
|
package/dist/pack.d.ts
CHANGED
|
@@ -11,6 +11,7 @@ export interface PackedRecord {
|
|
|
11
11
|
state: unknown;
|
|
12
12
|
stepped: number;
|
|
13
13
|
ticks: number;
|
|
14
|
+
rebuilt: number;
|
|
14
15
|
/**
|
|
15
16
|
* What `setting.keep` held, in the order its owners first kept it. An owner is code, which no
|
|
16
17
|
* store keeps, and a voice revived from a descriptor has new ones; the same code keeps in the same
|
|
@@ -19,9 +20,10 @@ export interface PackedRecord {
|
|
|
19
20
|
kept: unknown[] | null;
|
|
20
21
|
base?: Record<string, unknown>;
|
|
21
22
|
slope?: Record<string, unknown>;
|
|
22
|
-
snaps?: [at: number, held: PackedRecord][];
|
|
23
|
+
snaps?: [at: number, seq: number, held: PackedRecord][];
|
|
23
24
|
inputs?: {
|
|
24
25
|
at: number;
|
|
26
|
+
seq: number;
|
|
25
27
|
value: number;
|
|
26
28
|
}[];
|
|
27
29
|
}
|
package/dist/pack.js
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { clone } from './clone.js';
|
|
2
|
+
import { record } from './record.js';
|
|
2
3
|
/** A voice's record of one subject as plain data, its patch's `pack` taking its state. */
|
|
3
4
|
export function packHeld(voice, h) {
|
|
4
5
|
const patch = voice.patch;
|
|
@@ -14,6 +15,7 @@ export function packHeld(voice, h) {
|
|
|
14
15
|
state: h.state === undefined ? undefined : patch.pack ? patch.pack(h.state) : clone(h.state),
|
|
15
16
|
stepped: h.stepped,
|
|
16
17
|
ticks: h.ticks,
|
|
18
|
+
rebuilt: h.rebuilt,
|
|
17
19
|
kept: kept.length === 0 ? null : kept.map(clone),
|
|
18
20
|
};
|
|
19
21
|
if (h.base !== undefined)
|
|
@@ -21,7 +23,7 @@ export function packHeld(voice, h) {
|
|
|
21
23
|
if (h.slope !== undefined)
|
|
22
24
|
p.slope = clone(h.slope);
|
|
23
25
|
if (h.snaps !== undefined)
|
|
24
|
-
p.snaps = h.snaps.map((s) => [s.at, packHeld(voice, s.held)]);
|
|
26
|
+
p.snaps = h.snaps.map((s) => [s.at, s.seq, packHeld(voice, s.held)]);
|
|
25
27
|
if (h.inputs !== undefined)
|
|
26
28
|
p.inputs = h.inputs.map((e) => ({ ...e }));
|
|
27
29
|
return p;
|
|
@@ -29,28 +31,17 @@ export function packHeld(voice, h) {
|
|
|
29
31
|
/** A record made again from `packHeld`'s data, for `voice`. */
|
|
30
32
|
export function unpackHeld(voice, p) {
|
|
31
33
|
const patch = voice.patch;
|
|
32
|
-
const
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
probed: Number.NaN,
|
|
44
|
-
delta: null,
|
|
45
|
-
phase: 0,
|
|
46
|
-
seeks: 0,
|
|
47
|
-
kept: null,
|
|
48
|
-
voice,
|
|
49
|
-
next: null,
|
|
50
|
-
version: Number.NaN,
|
|
51
|
-
loci: null,
|
|
52
|
-
slot: -1,
|
|
53
|
-
};
|
|
34
|
+
const bands = p.bands === null ? null : Uint8Array.from(p.bands);
|
|
35
|
+
const h = record(voice, p.reaches, p.state === undefined ? undefined : patch.unpack ? patch.unpack(p.state) : p.state);
|
|
36
|
+
h.delay = p.delay;
|
|
37
|
+
h.since = p.since;
|
|
38
|
+
h.shown = p.shown;
|
|
39
|
+
h.weight = p.weight;
|
|
40
|
+
h.rested = p.rested;
|
|
41
|
+
h.bands = bands;
|
|
42
|
+
h.stepped = p.stepped;
|
|
43
|
+
h.ticks = p.ticks;
|
|
44
|
+
h.rebuilt = p.rebuilt;
|
|
54
45
|
if (p.kept !== null)
|
|
55
46
|
h.unkept = p.kept;
|
|
56
47
|
if (p.base !== undefined)
|
|
@@ -58,7 +49,7 @@ export function unpackHeld(voice, p) {
|
|
|
58
49
|
if (p.slope !== undefined)
|
|
59
50
|
h.slope = p.slope;
|
|
60
51
|
if (p.snaps !== undefined)
|
|
61
|
-
h.snaps = p.snaps.map(([at, held]) => ({ at, held: unpackHeld(voice, held) }));
|
|
52
|
+
h.snaps = p.snaps.map(([at, seq, held]) => ({ at, seq, held: unpackHeld(voice, held) }));
|
|
62
53
|
if (p.inputs !== undefined)
|
|
63
54
|
h.inputs = p.inputs;
|
|
64
55
|
return h;
|
package/dist/paging.d.ts
CHANGED
|
@@ -51,13 +51,19 @@ export declare class Keys {
|
|
|
51
51
|
subject(key: Key): unknown;
|
|
52
52
|
}
|
|
53
53
|
/**
|
|
54
|
-
* Hands records leaving memory to the store, the last of any
|
|
55
|
-
*
|
|
54
|
+
* Hands records leaving memory to the store, the last of any made in one frame, which is the one a
|
|
55
|
+
* read finds. `reach` is how far back memory still reaches.
|
|
56
56
|
*/
|
|
57
57
|
export declare function pageOut<I, O, E extends {
|
|
58
58
|
at: number;
|
|
59
|
+
seq: number;
|
|
59
60
|
}>(mix: Mixer<I, O>, stream: PagedStream, voice: number | undefined, subject: Key, out: readonly E[], data: (e: E) => unknown, reach: number): void;
|
|
60
61
|
/** Gives records to the store; memory now reaches back no further than `reach`. */
|
|
61
62
|
export declare function page(transport: Transport, records: Paged[], reach: number): void;
|
|
63
|
+
/**
|
|
64
|
+
* With a store, hands it what the transport itself keeps from before memory's reach: announced
|
|
65
|
+
* marks, changes of its rate, and frames, the last at or before the reach staying.
|
|
66
|
+
*/
|
|
67
|
+
export declare function pageTransport(transport: Transport): void;
|
|
62
68
|
/** Loads what a seek or read to `t` needs where it reaches past memory. */
|
|
63
69
|
export declare function prepare(transport: Transport, t: number): Promise<void>;
|
package/dist/paging.js
CHANGED
|
@@ -68,8 +68,8 @@ export class Keys {
|
|
|
68
68
|
}
|
|
69
69
|
}
|
|
70
70
|
/**
|
|
71
|
-
* Hands records leaving memory to the store, the last of any
|
|
72
|
-
*
|
|
71
|
+
* Hands records leaving memory to the store, the last of any made in one frame, which is the one a
|
|
72
|
+
* read finds. `reach` is how far back memory still reaches.
|
|
73
73
|
*/
|
|
74
74
|
export function pageOut(mix, stream, voice, subject, out, data, reach) {
|
|
75
75
|
const pager = mix.transport.pager;
|
|
@@ -79,9 +79,9 @@ export function pageOut(mix, stream, voice, subject, out, data, reach) {
|
|
|
79
79
|
const records = [];
|
|
80
80
|
for (let i = 0; i < out.length; i++) {
|
|
81
81
|
const e = out[i];
|
|
82
|
-
if (i + 1 < out.length && out[i + 1].
|
|
82
|
+
if (i + 1 < out.length && out[i + 1].seq === e.seq)
|
|
83
83
|
continue;
|
|
84
|
-
const r = { mix: name, stream, at: e.at, data: data(e) };
|
|
84
|
+
const r = { mix: name, stream, at: e.at, seq: e.seq, data: data(e) };
|
|
85
85
|
if (voice !== undefined)
|
|
86
86
|
r.voice = voice;
|
|
87
87
|
if (subject !== undefined)
|
|
@@ -100,6 +100,41 @@ export function page(transport, records, reach) {
|
|
|
100
100
|
if (reach > transport.floor)
|
|
101
101
|
transport.floor = reach;
|
|
102
102
|
}
|
|
103
|
+
/**
|
|
104
|
+
* With a store, hands it what the transport itself keeps from before memory's reach: announced
|
|
105
|
+
* marks, changes of its rate, and frames, the last at or before the reach staying.
|
|
106
|
+
*/
|
|
107
|
+
export function pageTransport(transport) {
|
|
108
|
+
const history = transport.history;
|
|
109
|
+
if (history === undefined || transport.pager === null)
|
|
110
|
+
return;
|
|
111
|
+
const reach = transport.now - history.ms;
|
|
112
|
+
const records = [];
|
|
113
|
+
transport.frames.shed(reach, (f) => records.push({ mix: '', stream: 'frame', at: f.at, seq: f.seq, data: f.u }));
|
|
114
|
+
const pace = transport.pace;
|
|
115
|
+
const timeOf = (u) => (pace === null ? u : pace.reading(u));
|
|
116
|
+
if (transport.announced.some((a) => timeOf(a.at) < reach)) {
|
|
117
|
+
const kept = [];
|
|
118
|
+
for (const a of transport.announced)
|
|
119
|
+
if (timeOf(a.at) < reach)
|
|
120
|
+
records.push({
|
|
121
|
+
mix: '',
|
|
122
|
+
stream: 'mark',
|
|
123
|
+
subject: a.order,
|
|
124
|
+
at: timeOf(a.at),
|
|
125
|
+
seq: a.seq,
|
|
126
|
+
data: a,
|
|
127
|
+
});
|
|
128
|
+
else
|
|
129
|
+
kept.push(a);
|
|
130
|
+
transport.announced = kept;
|
|
131
|
+
}
|
|
132
|
+
if (pace !== null)
|
|
133
|
+
for (const c of pace.shed(reach))
|
|
134
|
+
records.push({ mix: '', stream: 'pace', at: c.anchorElapsed, seq: c.seq, data: c });
|
|
135
|
+
if (records.length > 0)
|
|
136
|
+
page(transport, records, reach);
|
|
137
|
+
}
|
|
103
138
|
/** Loads what a seek or read to `t` needs where it reaches past memory. */
|
|
104
139
|
export async function prepare(transport, t) {
|
|
105
140
|
const pager = transport.pager;
|
package/dist/patch.d.ts
CHANGED
|
@@ -35,7 +35,7 @@ export interface KeysOptions<O> {
|
|
|
35
35
|
ease?: Easing;
|
|
36
36
|
/** A curve for one channel, where it differs from the rest. */
|
|
37
37
|
easeBy?: (channel: keyof O) => Easing | undefined;
|
|
38
|
-
/** Milliseconds one channel waits before it starts moving
|
|
38
|
+
/** Milliseconds one channel waits before it starts moving; it then travels in the time left. */
|
|
39
39
|
delayBy?: (channel: keyof O) => number;
|
|
40
40
|
/**
|
|
41
41
|
* How one channel interpolates, where it should differ from the channel's own `lerp`. A mix hands
|
|
@@ -45,8 +45,6 @@ export interface KeysOptions<O> {
|
|
|
45
45
|
/** The channels these stops were written against, which `cue` checks a mix's kit against. */
|
|
46
46
|
kit?: Partial<Kit<O>>;
|
|
47
47
|
}
|
|
48
|
-
/** The options a `keys` patch was built with, for an engine reading its stops rather than calling it. */
|
|
49
|
-
export declare function keysOptionsOf<I, O, S>(p: Patch<I, O, S>): KeysOptions<O> | undefined;
|
|
50
48
|
interface Point {
|
|
51
49
|
at: number;
|
|
52
50
|
value: unknown;
|
|
@@ -66,6 +64,12 @@ export interface Track {
|
|
|
66
64
|
tailAts: number[] | null;
|
|
67
65
|
delay: number;
|
|
68
66
|
lerp: ((a: never, b: never, u: number) => unknown) | undefined;
|
|
67
|
+
/** Where every stop is a plain number lerped straight across: the stops flat, for `readNumber`. */
|
|
68
|
+
numbers: {
|
|
69
|
+
ats: Float64Array;
|
|
70
|
+
values: Float64Array;
|
|
71
|
+
eases: (Curve | undefined)[];
|
|
72
|
+
} | null;
|
|
69
73
|
}
|
|
70
74
|
export interface Built {
|
|
71
75
|
tracks: Track[];
|
|
@@ -96,14 +100,14 @@ export declare function shift(delay: number, phase: number, duration: number): n
|
|
|
96
100
|
/**
|
|
97
101
|
* Where `phase` falls among `n` stop phases `ats[off + k * stride]`, in order: -2 for no stops, -1
|
|
98
102
|
* at or before the first, `n` at or past the last, and otherwise the first stop past it, where the
|
|
99
|
-
* segment from the one before ends.
|
|
103
|
+
* segment from the one before ends. `segment` and `readNumber` make the same search.
|
|
100
104
|
*/
|
|
101
105
|
export declare function locate(ats: ArrayLike<number>, off: number, stride: number, n: number, phase: number): number;
|
|
102
106
|
/** How far along a segment from phase `a` to `b` a phase is, before easing. */
|
|
103
107
|
export declare function fraction(phase: number, a: number, b: number): number;
|
|
104
108
|
/**
|
|
105
|
-
* Finds where one track is at a phase, into `seg`: the
|
|
106
|
-
*
|
|
109
|
+
* Finds where one track is at a phase, into `seg`: the search `read` and a lane folding stops
|
|
110
|
+
* straight into a subject's values both make. `base` stands in for the value at
|
|
107
111
|
* phase 0, which is how `from: 'current'` starts a voice wherever the subject already is.
|
|
108
112
|
*/
|
|
109
113
|
export declare function segment(track: Track, phase: number, base: unknown): number;
|
|
@@ -125,9 +129,10 @@ export declare function intosOf(built: Built, channels: readonly Channel<unknown
|
|
|
125
129
|
export declare function readKeys(built: Built, phase: number, out: Record<string, unknown>, base?: Record<string, unknown>, lerps?: readonly (Lerp | undefined)[],
|
|
126
130
|
/** Per channel, how fast a retargeted subject was moving, units per ms. */
|
|
127
131
|
slopes?: Record<string, unknown>, intos?: readonly (LerpInto | undefined)[], scratch?: Scratch): Record<string, unknown>;
|
|
128
|
-
/**
|
|
129
|
-
|
|
130
|
-
|
|
132
|
+
/**
|
|
133
|
+
* The built form of a patch's stops, made on first ask for a patch `keys()` did not build: a copy
|
|
134
|
+
* of one, or one another copy of blits made, each read by the fields it carries.
|
|
135
|
+
*/
|
|
131
136
|
export declare function builtOf<I, O, S>(p: Patch<I, O, S>): Built;
|
|
132
137
|
/** Evaluates a stop list into a fresh delta. */
|
|
133
138
|
export declare function evalKeys<O>(stops: readonly Keyframe<O>[], writes: readonly (keyof O)[], phase: number, duration: number, opts: KeysOptions<O>, base?: Partial<O>): Partial<O>;
|