@msb235/blits 0.7.0 → 0.8.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (156) hide show
  1. package/CHANGELOG.md +196 -0
  2. package/README.md +22 -4
  3. package/dist/book.js +4 -4
  4. package/dist/chain.d.ts +1 -1
  5. package/dist/chain.js +57 -54
  6. package/dist/channels.d.ts +26 -5
  7. package/dist/channels.js +12 -8
  8. package/dist/clock.d.ts +8 -1
  9. package/dist/clock.js +14 -3
  10. package/dist/clone.d.ts +3 -0
  11. package/dist/clone.js +16 -1
  12. package/dist/closed.d.ts +1 -1
  13. package/dist/closed.js +3 -2
  14. package/dist/color.d.ts +0 -11
  15. package/dist/color.js +4 -24
  16. package/dist/columns.js +0 -1
  17. package/dist/copyout.d.ts +6 -0
  18. package/dist/copyout.js +38 -0
  19. package/dist/crowd.d.ts +7 -5
  20. package/dist/crowd.js +32 -18
  21. package/dist/cue.d.ts +3 -1
  22. package/dist/cue.js +33 -20
  23. package/dist/departed.d.ts +34 -0
  24. package/dist/departed.js +73 -0
  25. package/dist/easing.d.ts +5 -0
  26. package/dist/easing.js +31 -2
  27. package/dist/everyone.d.ts +56 -0
  28. package/dist/everyone.js +221 -0
  29. package/dist/fade.d.ts +8 -1
  30. package/dist/fade.js +36 -6
  31. package/dist/fill.d.ts +22 -13
  32. package/dist/fill.js +104 -41
  33. package/dist/fit.js +2 -1
  34. package/dist/fold.d.ts +37 -0
  35. package/dist/fold.js +213 -28
  36. package/dist/gather.d.ts +15 -9
  37. package/dist/gather.js +60 -25
  38. package/dist/gone.d.ts +32 -0
  39. package/dist/gone.js +144 -0
  40. package/dist/handle.d.ts +16 -5
  41. package/dist/handle.js +56 -6
  42. package/dist/held.d.ts +8 -5
  43. package/dist/held.js +56 -58
  44. package/dist/history.d.ts +17 -13
  45. package/dist/history.js +49 -28
  46. package/dist/hosts.js +57 -9
  47. package/dist/index.d.ts +9 -4
  48. package/dist/index.js +5 -2
  49. package/dist/keyfill.d.ts +7 -0
  50. package/dist/keyfill.js +124 -0
  51. package/dist/keyrows.d.ts +1 -0
  52. package/dist/keyrows.js +1 -1
  53. package/dist/lane.d.ts +32 -2
  54. package/dist/lane.js +5 -0
  55. package/dist/lanes.d.ts +32 -8
  56. package/dist/lanes.js +69 -37
  57. package/dist/leavings.d.ts +26 -0
  58. package/dist/leavings.js +70 -0
  59. package/dist/meet.js +14 -8
  60. package/dist/mixer.d.ts +43 -7
  61. package/dist/mixer.js +60 -11
  62. package/dist/motion.d.ts +2 -0
  63. package/dist/motion.js +4 -1
  64. package/dist/motions.d.ts +22 -15
  65. package/dist/motions.js +40 -34
  66. package/dist/move.js +31 -20
  67. package/dist/moved.d.ts +11 -0
  68. package/dist/moved.js +29 -0
  69. package/dist/origin.d.ts +19 -0
  70. package/dist/origin.js +68 -0
  71. package/dist/owed.d.ts +4 -4
  72. package/dist/owed.js +8 -8
  73. package/dist/owner.d.ts +1 -1
  74. package/dist/owner.js +2 -2
  75. package/dist/pace.d.ts +13 -5
  76. package/dist/pace.js +21 -8
  77. package/dist/pack.d.ts +3 -1
  78. package/dist/pack.js +15 -24
  79. package/dist/paging.d.ts +8 -2
  80. package/dist/paging.js +44 -4
  81. package/dist/patch.d.ts +14 -9
  82. package/dist/patch.js +83 -21
  83. package/dist/place.js +188 -30
  84. package/dist/project.d.ts +12 -1
  85. package/dist/project.js +101 -83
  86. package/dist/pull.d.ts +2 -0
  87. package/dist/pull.js +8 -0
  88. package/dist/qualify.js +10 -2
  89. package/dist/reading.d.ts +5 -0
  90. package/dist/reading.js +5 -0
  91. package/dist/record.d.ts +9 -0
  92. package/dist/record.js +42 -0
  93. package/dist/relink.d.ts +11 -5
  94. package/dist/relink.js +7 -5
  95. package/dist/restored.d.ts +41 -0
  96. package/dist/restored.js +91 -0
  97. package/dist/revive.d.ts +10 -3
  98. package/dist/revive.js +31 -23
  99. package/dist/roster.d.ts +11 -0
  100. package/dist/roster.js +46 -0
  101. package/dist/rotation.d.ts +29 -0
  102. package/dist/rotation.js +91 -0
  103. package/dist/rows.d.ts +5 -5
  104. package/dist/rows.js +5 -5
  105. package/dist/sample.d.ts +3 -2
  106. package/dist/sample.js +32 -15
  107. package/dist/scored.d.ts +57 -0
  108. package/dist/scored.js +196 -0
  109. package/dist/seek.js +97 -114
  110. package/dist/shared.d.ts +6 -0
  111. package/dist/shared.js +15 -0
  112. package/dist/signals.d.ts +24 -3
  113. package/dist/signals.js +50 -11
  114. package/dist/spans.js +7 -0
  115. package/dist/stack.d.ts +11 -0
  116. package/dist/stack.js +47 -0
  117. package/dist/standing.d.ts +10 -0
  118. package/dist/standing.js +79 -0
  119. package/dist/store.d.ts +3 -3
  120. package/dist/store.js +3 -3
  121. package/dist/strays.js +3 -0
  122. package/dist/tape.d.ts +8 -5
  123. package/dist/tape.js +21 -13
  124. package/dist/testing.d.ts +35 -0
  125. package/dist/testing.js +116 -0
  126. package/dist/touch.d.ts +6 -0
  127. package/dist/touch.js +28 -0
  128. package/dist/transport.d.ts +53 -6
  129. package/dist/transport.js +102 -20
  130. package/dist/turns.d.ts +18 -0
  131. package/dist/turns.js +72 -0
  132. package/dist/tweened.js +1 -1
  133. package/dist/types/channel.d.ts +46 -0
  134. package/dist/types/channel.js +1 -0
  135. package/dist/types/history.d.ts +139 -0
  136. package/dist/types/history.js +1 -0
  137. package/dist/types/mix.d.ts +336 -0
  138. package/dist/types/mix.js +1 -0
  139. package/dist/types/patch.d.ts +187 -0
  140. package/dist/types/patch.js +1 -0
  141. package/dist/types/place.d.ts +157 -0
  142. package/dist/types/place.js +1 -0
  143. package/dist/types/transport.d.ts +71 -0
  144. package/dist/types/transport.js +1 -0
  145. package/dist/types/voice.d.ts +323 -0
  146. package/dist/types/voice.js +1 -0
  147. package/dist/types.d.ts +7 -1162
  148. package/dist/unpage.d.ts +2 -2
  149. package/dist/unpage.js +55 -25
  150. package/dist/voice.d.ts +92 -22
  151. package/dist/voice.js +108 -43
  152. package/dist/wave.d.ts +42 -0
  153. package/dist/wave.js +62 -0
  154. package/dist/weigh.js +1 -1
  155. package/docs/schema.html +42 -36
  156. package/package.json +8 -3
package/dist/unpage.d.ts CHANGED
@@ -4,5 +4,5 @@ import type { Transport } from './transport.js';
4
4
  * it took records from the store. Throws before anything moves where it cannot.
5
5
  */
6
6
  export declare function cover(transport: Transport, t: number): boolean;
7
- /** A seek back to `t`: what the store and `prepare` hold after it is from a future the tape makes again. */
8
- export declare function cut(transport: Transport, t: number, unpaged: boolean): void;
7
+ /** A seek back to frame `seq`: what the store and `prepare` hold after it is from a future the tape makes again. */
8
+ export declare function cut(transport: Transport, seq: number, unpaged: boolean): void;
package/dist/unpage.js CHANGED
@@ -1,6 +1,8 @@
1
+ import { Leavings } from './leavings.js';
1
2
  import { unpackHeld } from './pack.js';
2
3
  import { HistoryMiss } from './paging.js';
3
4
  import { reviveVoice } from './revive.js';
5
+ import { scoredLeft } from './scored.js';
4
6
  /**
5
7
  * Makes memory reach mix time `t` for a seek or read there, from what `prepare` loaded; true where
6
8
  * it took records from the store. Throws before anything moves where it cannot.
@@ -27,24 +29,25 @@ export function cover(transport, t) {
27
29
  transport.floor = loaded.t;
28
30
  return true;
29
31
  }
30
- /** A seek back to `t`: what the store and `prepare` hold after it is from a future the tape makes again. */
31
- export function cut(transport, t, unpaged) {
32
+ /** A seek back to frame `seq`: what the store and `prepare` hold after it is from a future the tape makes again. */
33
+ export function cut(transport, seq, unpaged) {
32
34
  const pager = transport.pager;
33
35
  if (pager === null)
34
36
  return;
35
37
  if (unpaged)
36
- pager.store.cut(t);
38
+ pager.store.cut(seq);
37
39
  const loaded = pager.loaded;
38
40
  if (loaded !== null)
39
- loaded.records = loaded.records.filter((r) => r.at <= t);
41
+ loaded.records = loaded.records.filter((r) => r.seq <= seq);
40
42
  }
41
43
  /** Puts records a store gave back into memory ahead of what it still holds, as if never paged. */
42
44
  function unpage(transport, records) {
45
+ unpageTransport(transport, records);
43
46
  const mixes = new Map();
44
47
  for (const m of [...transport.members, ...transport.dropped.map((d) => d.mix)])
45
48
  mixes.set(m.name ?? '', m);
46
49
  const by = new Map();
47
- for (const r of [...records].sort((a, b) => a.at - b.at)) {
50
+ for (const r of [...records].sort((a, b) => a.seq - b.seq)) {
48
51
  const m = mixes.get(r.mix);
49
52
  if (m === undefined)
50
53
  continue;
@@ -57,6 +60,23 @@ function unpage(transport, records) {
57
60
  for (const [m, list] of by)
58
61
  unpageMix(m, list);
59
62
  }
63
+ /** The transport's own records: its rate changes, the frames it played and the marks announced on it. */
64
+ function unpageTransport(transport, records) {
65
+ const own = records.filter((r) => r.mix === '' && r.voice === undefined);
66
+ const paces = own.filter((r) => r.stream === 'pace').map((r) => r.data);
67
+ if (paces.length > 0)
68
+ transport.pace?.unshed(paces);
69
+ const frames = own
70
+ .filter((r) => r.stream === 'frame')
71
+ .map((r) => ({ seq: r.seq, at: r.at, u: r.data }));
72
+ transport.frames = before(frames, transport.frames);
73
+ const held = new Set(transport.announced.map((a) => a.order));
74
+ const marks = own
75
+ .filter((r) => r.stream === 'mark' && !held.has(r.data.order))
76
+ .map((r) => r.data);
77
+ if (marks.length > 0)
78
+ transport.announced = [...marks, ...transport.announced].sort((a, b) => a.order - b.order);
79
+ }
60
80
  function unpageMix(mix, records) {
61
81
  const voices = new Map();
62
82
  for (const v of [...mix.cued, ...mix.gone])
@@ -66,9 +86,10 @@ function unpageMix(mix, records) {
66
86
  const v = reviveVoice(mix, r.voice, r.data);
67
87
  voices.set(v.id, v);
68
88
  mix.gone.push(v);
89
+ scoredLeft(mix, v);
69
90
  }
70
91
  const host = records.filter((r) => r.stream === 'host');
71
- mix.hostLog = before(host.map((r) => ({ at: r.at, fields: r.data })), mix.hostLog);
92
+ mix.hostLog = before(host.map((r) => ({ at: r.at, seq: r.seq, fields: r.data })), mix.hostLog);
72
93
  const byVoice = new Map();
73
94
  for (const r of records) {
74
95
  if (r.voice === undefined)
@@ -90,29 +111,38 @@ function unpageVoice(voice, records, keys) {
90
111
  const of = (stream) => records.filter((r) => r.stream === stream);
91
112
  if (voice.log !== null)
92
113
  voice.log = before(of('controls').map((r) => r.data), voice.log);
93
- const left = voice.left ?? [];
94
- for (const r of of('left')) {
95
- const subject = keys.subject(r.subject);
96
- if (!left.some((e) => e.at === r.at && Object.is(e.subject, subject)))
97
- left.push({ subject, at: r.at, held: unpackHeld(voice, r.data) });
114
+ const paged = of('left');
115
+ if (paged.length > 0) {
116
+ const left = [...(voice.left?.all() ?? [])];
117
+ for (const r of paged) {
118
+ const subject = keys.subject(r.subject);
119
+ if (left.some((e) => e.seq === r.seq && Object.is(e.subject, subject)))
120
+ continue;
121
+ const [p, sync] = r.data;
122
+ left.push({ subject, at: r.at, seq: r.seq, sync, held: unpackHeld(voice, p) });
123
+ }
124
+ left.sort((a, b) => a.seq - b.seq);
125
+ voice.left = Leavings.from(left);
98
126
  }
99
- left.sort((a, b) => a.at - b.at);
100
- voice.left = left.length === 0 ? null : left;
101
127
  for (const [key, list] of bySubject(of('snap'))) {
102
128
  const subject = keys.subject(key);
103
129
  for (const [held, snaps] of lives(voice, subject, list))
104
- held.snaps = before(snaps.map((r) => ({ at: r.at, held: unpackHeld(voice, r.data) })), held.snaps ?? []);
130
+ held.snaps = before(snaps.map((r) => ({
131
+ at: r.at,
132
+ seq: r.seq,
133
+ held: unpackHeld(voice, r.data),
134
+ })), held.snaps ?? []);
105
135
  }
106
136
  for (const [key, list] of bySubject(of('input'))) {
107
137
  const subject = keys.subject(key);
108
138
  for (const [held, inputs] of lives(voice, subject, list))
109
- held.inputs = before(inputs.map((r) => ({ at: r.at, value: r.data })), held.inputs ?? []);
139
+ held.inputs = before(inputs.map((r) => ({ at: r.at, seq: r.seq, value: r.data })), held.inputs ?? []);
110
140
  }
111
141
  const motion = voice.motion;
112
142
  if (motion === undefined)
113
143
  return;
114
144
  for (const r of of('released'))
115
- motion.reclaim(keys.subject(r.subject), r.at, r.data);
145
+ motion.reclaim(keys.subject(r.subject), r.at, r.seq, r.data);
116
146
  for (const [key, list] of bySubject(of('stretch')))
117
147
  motion.restretch(keys.subject(key), list);
118
148
  }
@@ -132,29 +162,29 @@ function bySubject(records) {
132
162
  * subject leaves the voice, and the record it has now began after its last leaving.
133
163
  */
134
164
  function lives(voice, subject, records) {
135
- const left = (voice.left ?? []).filter((e) => Object.is(e.subject, subject));
165
+ const left = voice.left?.of(subject) ?? [];
136
166
  const out = [];
137
167
  let from = Number.NEGATIVE_INFINITY;
138
168
  for (const e of left) {
139
- out.push([e.held, records.filter((r) => r.at > from && r.at <= e.at)]);
140
- from = e.at;
169
+ out.push([e.held, records.filter((r) => r.seq > from && r.seq <= e.seq)]);
170
+ from = e.seq;
141
171
  }
142
172
  const live = voice.subjects.get(subject);
143
173
  if (live?.reaches)
144
- out.push([live, records.filter((r) => r.at > from)]);
174
+ out.push([live, records.filter((r) => r.seq > from)]);
145
175
  return out;
146
176
  }
147
177
  /**
148
- * `loaded`, in time order, ahead of `list`: those older than its first entry, the last of any that
149
- * share a time, which is the one a read finds.
178
+ * `loaded`, in the order it was made, ahead of `list`: those older than its first entry, the last
179
+ * of any that share a frame, which is the one a read finds.
150
180
  */
151
181
  function before(loaded, list) {
152
- const first = list[0]?.at ?? Number.POSITIVE_INFINITY;
182
+ const first = list[0]?.seq ?? Number.POSITIVE_INFINITY;
153
183
  const out = [];
154
184
  for (const e of loaded) {
155
- if (!(e.at < first))
185
+ if (!(e.seq < first))
156
186
  continue;
157
- if (out.length > 0 && out[out.length - 1].at === e.at)
187
+ if (out.length > 0 && out[out.length - 1].seq === e.seq)
158
188
  out[out.length - 1] = e;
159
189
  else
160
190
  out.push(e);
package/dist/voice.d.ts CHANGED
@@ -1,13 +1,26 @@
1
1
  import type { Blend } from './blend.js';
2
2
  import { type Clock } from './clock.js';
3
3
  import { type Curve } from './easing.js';
4
+ import type { Leavings } from './leavings.js';
4
5
  import type { Motions } from './motions.js';
5
6
  import { Named } from './named.js';
7
+ import type { Past } from './origin.js';
6
8
  import { Holding } from './owner.js';
7
9
  import { type Built, intosOf, type Scratch } from './patch.js';
8
10
  import type { Fitting } from './spans.js';
9
11
  import { Store } from './store.js';
10
12
  import type { Anchor, Channel, FadeSpec, Handle, Patch, Setting, VoiceSpec } from './types.js';
13
+ /**
14
+ * A subject's record as it left a voice, faded out of it or dropped: the mix time and frame it
15
+ * left at, and `sync` where the frame's sync made it, before the frame was read.
16
+ */
17
+ export interface Left<I> {
18
+ subject: I;
19
+ at: number;
20
+ seq: number;
21
+ sync: boolean;
22
+ held: Subject<unknown>;
23
+ }
11
24
  export declare const none: readonly string[];
12
25
  /** Everything one voice holds for one subject, chained through the next voice that reaches it. */
13
26
  export interface Subject<S> {
@@ -41,6 +54,8 @@ export interface Subject<S> {
41
54
  phase: number;
42
55
  /** The voice's `seeks` when `delta` was read, so a seek later in the frame reads it again. */
43
56
  seeks: number;
57
+ /** The voice's `rebuilds` when its state was last made, so a seek's rebuild reaches it once. */
58
+ rebuilt: number;
44
59
  /** Stop 0 for a `from: 'current'` voice, taken the first frame this subject is seen. */
45
60
  base?: Record<string, unknown>;
46
61
  /** The pose's velocity per channel at that moment, units per ms, so the first segment leaves at it. */
@@ -52,6 +67,7 @@ export interface Subject<S> {
52
67
  /** Under `history`, copies of this record by the mix time they were taken, oldest first. */
53
68
  snaps?: {
54
69
  at: number;
70
+ seq: number;
55
71
  held: Subject<S>;
56
72
  }[];
57
73
  /** In a projection: where this record started from, and whether nothing known could be. */
@@ -60,6 +76,7 @@ export interface Subject<S> {
60
76
  /** Under `history` with `inputs`, what an input weight signal read for this subject, when it changed. */
61
77
  inputs?: {
62
78
  at: number;
79
+ seq: number;
63
80
  value: number;
64
81
  }[];
65
82
  /** In a projection reading back: that record, to read in place of the signal. */
@@ -80,10 +97,15 @@ export interface Subject<S> {
80
97
  loci: Map<string, Uint8Array> | null;
81
98
  /** On the first record: the number lanes index this subject by, -1 without one. */
82
99
  slot: number;
100
+ /** A motion voice's number for this subject in its patch, good while `freed` is the patch's own. */
101
+ run: number;
102
+ freed: number;
83
103
  }
84
104
  /** A voice's clock, weight and fade from one mix time on, kept under `history`. */
85
105
  export interface Controls extends Clock {
86
106
  at: number;
107
+ /** The frame it was made in. */
108
+ seq: number;
87
109
  weight: number;
88
110
  out: Ramp | null;
89
111
  back: Rise | null;
@@ -93,7 +115,10 @@ export interface Controls extends Clock {
93
115
  /** A fade the host set for `outAt`: its ramp, NaN for the voice's own `fade.out`. */
94
116
  outOver: number;
95
117
  outSet: boolean;
96
- /** Made by a sync, so it shows in that frame; a host's change between frames shows from the next. */
118
+ rebuilds: number;
119
+ /** How many of the voice's past clocks it had then. */
120
+ past: number;
121
+ /** Shows in its own frame: made by a sync, or before anything read the mix that frame. */
97
122
  sync: boolean;
98
123
  }
99
124
  export interface Ramp {
@@ -158,26 +183,39 @@ export declare class Voice<I, O> {
158
183
  holder: Subject<unknown> | null;
159
184
  /** Whether its channels run as lanes this frame, so the general fold passes it by. */
160
185
  laned: boolean;
161
- /** How many times it has been sought, so a delta read before a seek is not handed out after it. */
186
+ /**
187
+ * How many times it has been sought or touched, so a delta read before either is not handed out
188
+ * after it.
189
+ */
162
190
  seeks: number;
191
+ /** Whether the host has written to its handle, so it no longer plays as it was cued. */
192
+ written: boolean;
193
+ /** How many of `seeks` were the mix's `touch`, which moves no clock. */
194
+ touches: number;
195
+ /** How many times its clock has jumped, which a booker counts hits again from. */
196
+ get jumps(): number;
197
+ /** Seeks that rebuild state; a record stamped with fewer makes its state again before stepping. */
198
+ rebuilds: number;
199
+ /** Whether its span's last fit jumped it to its end, which leaves it no time in that fit. */
200
+ skipped: boolean;
163
201
  /** Whether its patch has kept state on a record through `setting.keep`, which makes it stateful. */
164
202
  keeping: boolean;
165
203
  /** Subjects fading out of this voice alone, by the ramp each started; null while none are. */
166
204
  parts: Map<I, {
167
205
  at: number;
168
206
  over: number;
207
+ seq: number;
208
+ }> | null;
209
+ /** Subjects faded out of this voice, by the mix time and frame each left at; null while none have. */
210
+ parted: Map<I, {
211
+ at: number;
212
+ seq: number;
169
213
  }> | null;
170
- /** Subjects faded out of this voice, by the mix time each left at; null while none have. */
171
- parted: Map<I, number> | null;
172
214
  /**
173
- * Under history, the records of subjects that left this voice, by the mix time each left at,
174
- * while a seek or a read back may reach them; null while none have.
215
+ * Under history, the records of subjects that left this voice, by the mix time and frame each
216
+ * left at, while a seek or a read back may reach them; null while none have.
175
217
  */
176
- left: {
177
- subject: I;
178
- at: number;
179
- held: Subject<unknown>;
180
- }[] | null;
218
+ left: Leavings<I> | null;
181
219
  readonly ease: Curve | undefined;
182
220
  /** How many passes its `loop` plays, worked out once. */
183
221
  readonly passes: number;
@@ -193,8 +231,13 @@ export declare class Voice<I, O> {
193
231
  opened: number;
194
232
  /** Which of its entries in the mix's due queue is current; older ones are skipped when popped. */
195
233
  dueToken: number;
196
- /** Records made while it was pending, whose `since` its start may since have moved. */
234
+ /**
235
+ * Records whose `since` was still ahead when last worked out, which a later start, rate change
236
+ * or seek moves; null while none are.
237
+ */
197
238
  early: Subject<unknown>[] | null;
239
+ /** The clocks it ran on before its current one, where a subject's origin may lie; null for none. */
240
+ clocks: Past[] | null;
198
241
  /** Reused for every call this voice makes, so it is valid only during the call. */
199
242
  readonly setting: Setting<unknown>;
200
243
  /** Every subject this voice has been asked about, so a handover knows when it is finished. */
@@ -204,8 +247,12 @@ export declare class Voice<I, O> {
204
247
  restedCount: number;
205
248
  /** The mix time it was cued at; -Infinity before the first sync. */
206
249
  cuedAt: number;
207
- /** The mix time it left at. */
250
+ /** The frame it was cued in. */
251
+ cuedSeq: number;
252
+ /** The mix time it left at, which a fade or seek given a time already passed puts behind now. */
208
253
  doneAt: number;
254
+ /** The frame its leaving was decided in, which a seek or read back partitions by. */
255
+ doneSeq: number;
209
256
  /** Under `history`, its controls after each change, oldest first. */
210
257
  log: Controls[] | null;
211
258
  /** Under `history`, its controls as `cue` left them, which a voice parked by a seek takes back. */
@@ -222,6 +269,8 @@ export declare class Voice<I, O> {
222
269
  placing: boolean;
223
270
  /** What each member of a join last answered, kept for once its target has left. */
224
271
  answers: Map<Anchor, number> | null;
272
+ /** What each of its anchors' queries has read of each mix's gone voices (`place.ts`'s `Fold`). */
273
+ folds: Map<unknown, Map<unknown, unknown>> | null;
225
274
  /** The record `setting.keep` writes to: the one its patch or signal is being called for. */
226
275
  keepOn: Subject<unknown> | null;
227
276
  /** What `setting.keep` holds when called before any record is. */
@@ -235,6 +284,20 @@ export declare class Voice<I, O> {
235
284
  unreached: Subject<unknown> | null;
236
285
  /** By subject number, a bit set where `unreached` stands for the subject; null until one is. */
237
286
  unreachedBits: Uint32Array | null;
287
+ /** Whether one record stands for every subject: see `shares` in `everyone.ts`. */
288
+ sharing: boolean;
289
+ /** That record, null until a chain first asks and once the voice shares no more. */
290
+ everyone: Subject<unknown> | null;
291
+ /** While sharing, by subject number: a bit where a chain has asked about the subject. */
292
+ sighted: Uint32Array | null;
293
+ /** While sharing, by subject number: the weight last given the subject on the general path. */
294
+ weights: Float64Array | null;
295
+ /**
296
+ * While sharing a patch that is called, by subject number: when it was last called for the
297
+ * subject and at what `seeks`, side by side, and the delta that call gave.
298
+ */
299
+ stamps: Float64Array | null;
300
+ deltas: (Record<string, unknown> | null)[] | null;
238
301
  /** The handle `cue` returned, which `voices` hands back too. */
239
302
  handle: Handle<I> | null;
240
303
  /** With a history store, the key of every subject it has a record of; null without one. */
@@ -249,8 +312,10 @@ export declare class Voice<I, O> {
249
312
  */
250
313
  private finished;
251
314
  private playedAs;
252
- /** The mix time `played` was settled at, so a seek back to before it can open it again. */
315
+ /** The mix time `played` was settled at. */
253
316
  private playedAt;
317
+ /** The frame `played` was settled in, so a seek back to before it can open it again. */
318
+ private playedSeq;
254
319
  private donePromise;
255
320
  private doneSettle;
256
321
  private playedPromise;
@@ -265,21 +330,24 @@ export declare class Voice<I, O> {
265
330
  * Its finite loop ended (true) or it left first (false), whichever comes first, noticed at mix
266
331
  * time `at`: `played` resolves.
267
332
  */
268
- play(played: boolean, at: number): void;
269
- /** How `played` settled, and the mix time it did; undefined while it has not. */
333
+ play(played: boolean, at: number, seq: number): void;
334
+ /** How `played` settled, and the mix time and frame it did; undefined while it has not. */
270
335
  get settled(): {
271
336
  played: boolean | undefined;
272
337
  at: number;
338
+ seq: number;
273
339
  };
274
340
  /** Whether `played` settled true, which its owner counted. */
275
341
  get passed(): boolean;
276
342
  /** Whether `played` settled false: it left before its last pass ended. */
277
343
  get unplayed(): boolean;
278
344
  /**
279
- * A seek back to mix time `t`: `done` and `played`, where they settled after it, start over with
345
+ * A seek back to frame `seq`: `done` and `played`, where they settled after it, start over with
280
346
  * fresh promises. True where `played` had settled true, which its owner counted.
281
347
  */
282
- reopen(t: number): boolean;
348
+ reopen(seq: number): boolean;
349
+ /** Takes on a set of controls: its clock, weight, fades and where its anchors put it. */
350
+ take(c: Omit<Controls, 'at' | 'seq' | 'sync'>): void;
283
351
  /**
284
352
  * A seek back to before its cue: out of the mix, as `cue` left it, until the mix plays the cue
285
353
  * again. What it played since is forgotten, and `done` and `played` start over where they had
@@ -293,13 +361,15 @@ export declare class Voice<I, O> {
293
361
  elapsedAt(now: number): number;
294
362
  /** The mix time its clock reads `elapsed`, inverting `elapsedAt`; Infinity where it never will. */
295
363
  timeAt(elapsed: number): number;
296
- /** Records this voice's controls as they stand, from mix time `at`. */
297
- note(at: number, sync?: boolean): void;
364
+ /** Records this voice's controls as they stand, from mix time `at` in frame `seq`. */
365
+ note(at: number, seq: number, sync?: boolean): void;
298
366
  /**
299
367
  * A copy for a projection: its own setting, which sends nothing, and its own per-subject records,
300
- * filled from `fill`. With `controls` it takes those, as the voice stood at an earlier time.
368
+ * filled from `fill`. With `controls` it takes those, as the voice stood at an earlier time. With
369
+ * `share`, a voice keeping one record for every subject gives its copy a copy of that one, which
370
+ * a read ahead starts every subject from; `fill` then serves only a copy that shares no more.
301
371
  */
302
- copy(fill: (subject: I) => Subject<unknown> | undefined, controls?: Controls): Voice<I, O>;
372
+ copy(fill: (subject: I) => Subject<unknown> | undefined, controls?: Controls, share?: boolean): Voice<I, O>;
303
373
  rateAt(now: number): number;
304
374
  /** Moves the anchor to `now`, carrying what is left of a ramp. */
305
375
  rebase(now: number): void;