@msb235/blits 0.7.1 → 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.
- package/CHANGELOG.md +180 -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 +3 -0
- package/dist/clone.js +16 -1
- 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 +213 -28
- 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/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 +44 -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 +49 -6
- package/dist/transport.js +89 -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/fill.js
CHANGED
|
@@ -1,14 +1,20 @@
|
|
|
1
1
|
import { foldNumber, lerpNumber } from './channels.js';
|
|
2
|
-
import { passAt, phaseAt, silent, weighed } from './clock.js';
|
|
2
|
+
import { passAt, phaseAt, same, silent, weighed } from './clock.js';
|
|
3
3
|
import { flush } from './columns.js';
|
|
4
4
|
import { crowdsUpTo, freshen } from './crowd.js';
|
|
5
|
+
import { open as openRecord, shut as shutRecord } from './everyone.js';
|
|
5
6
|
import { foldLocus, gatherLocus } from './gather.js';
|
|
7
|
+
import { runKeys } from './keyfill.js';
|
|
6
8
|
import { frozenAt } from './lane.js';
|
|
7
9
|
import { reach } from './meet.js';
|
|
8
10
|
import { absent } from './numbers.js';
|
|
9
11
|
import { AT, NOTHING, readKeys, seg, segment, shifted } from './patch.js';
|
|
10
12
|
import { reading } from './reading.js';
|
|
11
13
|
import { move, runMotion } from './sample.js';
|
|
14
|
+
import { rested } from './turns.js';
|
|
15
|
+
// V8 reads a local const as a constant, where it reads an import from its module on every call.
|
|
16
|
+
const open = openRecord;
|
|
17
|
+
const shut = shutRecord;
|
|
12
18
|
/** The least prime at least `n`, and 1 below 2. */
|
|
13
19
|
function primeFrom(n) {
|
|
14
20
|
if (n < 2)
|
|
@@ -47,7 +53,7 @@ export function fillAll(lanes, now, version) {
|
|
|
47
53
|
for (const lane of lanes.lanes) {
|
|
48
54
|
if (decide) {
|
|
49
55
|
// A lane with few subjects, such as one naming its own, goes by the share of all probed;
|
|
50
|
-
// one with a single subject shares nothing a fill could save
|
|
56
|
+
// one with a single subject shares nothing a fill could save.
|
|
51
57
|
const line = lane.line;
|
|
52
58
|
const n = lane.list.length;
|
|
53
59
|
if (n >= 64)
|
|
@@ -77,7 +83,7 @@ export function fillAll(lanes, now, version) {
|
|
|
77
83
|
}
|
|
78
84
|
if (busy) {
|
|
79
85
|
for (const ch of lanes.laned)
|
|
80
|
-
|
|
86
|
+
rested(ch, size);
|
|
81
87
|
for (const g of lanes.loci)
|
|
82
88
|
gatherLocus(lanes, g);
|
|
83
89
|
for (const lane of lanes.lanes) {
|
|
@@ -104,6 +110,7 @@ export function fillAll(lanes, now, version) {
|
|
|
104
110
|
lanes.holding = false;
|
|
105
111
|
}
|
|
106
112
|
lanes.moved = reading.moved;
|
|
113
|
+
lanes.inputs = reading.inputs;
|
|
107
114
|
}
|
|
108
115
|
finally {
|
|
109
116
|
lanes.filling = false;
|
|
@@ -168,21 +175,29 @@ export function wake(lanes, lane) {
|
|
|
168
175
|
reach(lanes, slot, -1);
|
|
169
176
|
}
|
|
170
177
|
/**
|
|
171
|
-
* A voice with a signal weight: its weight for the subject at `slot
|
|
172
|
-
*
|
|
173
|
-
*
|
|
174
|
-
* called where the general path
|
|
178
|
+
* A voice with a signal weight: its weight for the subject at `slot`, left in `Arg.WEIGHT`, at the
|
|
179
|
+
* voice time, pass and fade in `Arg.ELAPSED`, `Arg.PASS` and `Arg.FADE`, through the general path's
|
|
180
|
+
* own arithmetic. False where that path has not made the voice's first call for the subject, which
|
|
181
|
+
* it then makes this frame, so a signal that keeps state is first called where the general path
|
|
182
|
+
* would call it.
|
|
175
183
|
*/
|
|
176
|
-
export function signalled(voice, slot, rec
|
|
184
|
+
export function signalled(voice, slot, rec) {
|
|
185
|
+
const arg = this.arg;
|
|
186
|
+
const elapsed = arg[1 /* Arg.ELAPSED */];
|
|
187
|
+
const pass = arg[3 /* Arg.PASS */];
|
|
188
|
+
const fade = arg[5 /* Arg.FADE */];
|
|
177
189
|
if (Number.isNaN(rec.probed)) {
|
|
178
190
|
this.late.push(slot);
|
|
179
|
-
return
|
|
191
|
+
return false;
|
|
180
192
|
}
|
|
181
193
|
const subject = this.subjectAt(slot);
|
|
182
|
-
if (subject === absent)
|
|
183
|
-
|
|
194
|
+
if (subject === absent) {
|
|
195
|
+
arg[0 /* Arg.WEIGHT */] = 0;
|
|
196
|
+
return true;
|
|
197
|
+
}
|
|
184
198
|
const base = this.host.signal(voice, subject, rec, elapsed, pass, slot);
|
|
185
|
-
|
|
199
|
+
arg[0 /* Arg.WEIGHT */] = weighed(base, fade, voice.parts === null ? 1 : this.host.parting(voice, subject));
|
|
200
|
+
return true;
|
|
186
201
|
}
|
|
187
202
|
/** What a subject's own ramp out of a voice leaves of its weight: 1 with none. */
|
|
188
203
|
export function parting(voice, slot) {
|
|
@@ -228,25 +243,53 @@ export function run(lane) {
|
|
|
228
243
|
runMotion(this, lane, lane.motion);
|
|
229
244
|
return;
|
|
230
245
|
}
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
246
|
+
if (voice.built !== null && typeof voice.spec.weight !== 'function') {
|
|
247
|
+
runKeys(this, lane);
|
|
248
|
+
return;
|
|
249
|
+
}
|
|
250
|
+
lane.elapsedNow = voice.elapsedAt(this.now);
|
|
234
251
|
const list = lane.list;
|
|
252
|
+
if (voice.sharing) {
|
|
253
|
+
this.runEveryone(lane);
|
|
254
|
+
return;
|
|
255
|
+
}
|
|
235
256
|
for (let p = 0; p < list.length; p++) {
|
|
236
|
-
this.one(lane, p, list[p]
|
|
257
|
+
this.one(lane, p, list[p]);
|
|
237
258
|
// Its patch just made kept state: no further call this fill, the general path makes them.
|
|
238
259
|
if (voice.keeping)
|
|
239
260
|
return;
|
|
240
261
|
}
|
|
241
262
|
}
|
|
263
|
+
/**
|
|
264
|
+
* `run`'s loop for a voice keeping one record for every subject: the record is pointed at each
|
|
265
|
+
* subject before its call and taken back after, so `one` and `call` read it as a record of the
|
|
266
|
+
* subject's own. A loop of its own, which leaves theirs as they were for every other voice.
|
|
267
|
+
*/
|
|
268
|
+
export function runEveryone(lane) {
|
|
269
|
+
const voice = lane.voice;
|
|
270
|
+
const rec = voice.everyone;
|
|
271
|
+
const list = lane.list;
|
|
272
|
+
const cap = this.cap;
|
|
273
|
+
for (let p = 0; p < list.length; p++) {
|
|
274
|
+
const slot = list[p];
|
|
275
|
+
open(voice, rec, slot);
|
|
276
|
+
this.one(lane, p, slot);
|
|
277
|
+
// Its patch just made kept state, and the record is now that subject's own.
|
|
278
|
+
if (voice.keeping)
|
|
279
|
+
return;
|
|
280
|
+
shut(voice, rec, slot, cap);
|
|
281
|
+
}
|
|
282
|
+
}
|
|
242
283
|
/**
|
|
243
284
|
* One subject's contribution from a lane's voice. True where the voice gave the subject a delta,
|
|
244
285
|
* as the general path's `contribution` does where it returns one, which is what makes a voice in a
|
|
245
286
|
* locus one of its members for the subject.
|
|
246
287
|
*/
|
|
247
|
-
export function one(lane, p, slot
|
|
288
|
+
export function one(lane, p, slot) {
|
|
248
289
|
const host = this.host;
|
|
249
290
|
const voice = lane.voice;
|
|
291
|
+
const elapsedNow = lane.elapsedNow;
|
|
292
|
+
const arg = this.arg;
|
|
250
293
|
const data = lane.data;
|
|
251
294
|
const o = p * 8 /* Row.STRIDE */;
|
|
252
295
|
// A probe read this subject from the last fill: keep the weight it read for `weightOf`.
|
|
@@ -260,25 +303,28 @@ export function one(lane, p, slot, elapsedNow, duration, passes) {
|
|
|
260
303
|
data[o + 2 /* Row.WEIGHT */] = 0;
|
|
261
304
|
return false;
|
|
262
305
|
}
|
|
263
|
-
if (!lane.placed || !
|
|
306
|
+
if (!lane.placed || !same(elapsed, lane.placedAt)) {
|
|
264
307
|
lane.placed = true;
|
|
265
308
|
lane.placedAt = elapsed;
|
|
266
|
-
lane.phase = phaseAt(elapsed, duration, passes);
|
|
267
|
-
lane.pass = passAt(elapsed, duration, passes);
|
|
309
|
+
lane.phase = phaseAt(elapsed, voice.duration, voice.passes);
|
|
310
|
+
lane.pass = passAt(elapsed, voice.duration, voice.passes);
|
|
268
311
|
}
|
|
269
312
|
const since = data[o + 1 /* Row.SINCE */];
|
|
270
|
-
if (!lane.flat && (!lane.weighed || !
|
|
313
|
+
if (!lane.flat && (!lane.weighed || !same(since, lane.weighedSince))) {
|
|
271
314
|
lane.fade = host.envelope(voice, since);
|
|
272
315
|
lane.weighed = true;
|
|
273
316
|
lane.weighedSince = since;
|
|
274
317
|
}
|
|
275
318
|
let w;
|
|
276
319
|
if (typeof voice.spec.weight === 'function') {
|
|
277
|
-
|
|
278
|
-
|
|
320
|
+
arg[1 /* Arg.ELAPSED */] = elapsed;
|
|
321
|
+
arg[3 /* Arg.PASS */] = lane.pass;
|
|
322
|
+
arg[5 /* Arg.FADE */] = lane.fade;
|
|
323
|
+
if (!this.signalled(voice, slot, lane.records[p])) {
|
|
279
324
|
data[o + 2 /* Row.WEIGHT */] = 0;
|
|
280
325
|
return false;
|
|
281
326
|
}
|
|
327
|
+
w = arg[0 /* Arg.WEIGHT */];
|
|
282
328
|
}
|
|
283
329
|
else
|
|
284
330
|
w = weighed(voice.weight, lane.fade, this.parting(voice, slot));
|
|
@@ -286,14 +332,16 @@ export function one(lane, p, slot, elapsedNow, duration, passes) {
|
|
|
286
332
|
this.folding = lane;
|
|
287
333
|
this.rec = lane.records[p] ?? null;
|
|
288
334
|
if (voice.built !== null) {
|
|
289
|
-
if (!lane.read || !
|
|
335
|
+
if (!lane.read || !same(elapsed, lane.readAt)) {
|
|
290
336
|
this.readKeyed(voice, lane.phase, lane.delta, lane.scratch);
|
|
291
337
|
lane.read = true;
|
|
292
338
|
lane.readAt = elapsed;
|
|
293
339
|
this.gather(lane, lane.delta);
|
|
294
340
|
}
|
|
295
|
-
if (w > 0)
|
|
296
|
-
|
|
341
|
+
if (w > 0) {
|
|
342
|
+
arg[0 /* Arg.WEIGHT */] = w;
|
|
343
|
+
this.fold(lane, slot);
|
|
344
|
+
}
|
|
297
345
|
return true;
|
|
298
346
|
}
|
|
299
347
|
const rec = lane.records[p];
|
|
@@ -303,18 +351,25 @@ export function one(lane, p, slot, elapsedNow, duration, passes) {
|
|
|
303
351
|
return false;
|
|
304
352
|
}
|
|
305
353
|
// A motion patch needs the subject only to number it, so the lookup waits until then.
|
|
354
|
+
arg[1 /* Arg.ELAPSED */] = elapsed;
|
|
355
|
+
arg[4 /* Arg.DELAY */] = delay;
|
|
356
|
+
arg[0 /* Arg.WEIGHT */] = w;
|
|
306
357
|
if (lane.motion !== undefined) {
|
|
307
|
-
move(this, lane, lane.motion, p, slot, rec
|
|
358
|
+
move(this, lane, lane.motion, p, slot, rec);
|
|
308
359
|
return true;
|
|
309
360
|
}
|
|
310
|
-
|
|
361
|
+
arg[2 /* Arg.PHASE */] = lane.phase;
|
|
362
|
+
arg[3 /* Arg.PASS */] = lane.pass;
|
|
363
|
+
return this.call(voice, lane.chans, rec, slot);
|
|
311
364
|
}
|
|
312
365
|
/**
|
|
313
|
-
* A keys voice's stops at `
|
|
314
|
-
* `readKeyed` then `foldDelta` give, through the same segment search and the
|
|
315
|
-
* lerp, which is all a laned keys voice can use.
|
|
366
|
+
* A keys voice's stops at `Arg.PHASE` folded straight into a subject's values at `Arg.WEIGHT`,
|
|
367
|
+
* without a delta: what `readKeyed` then `foldDelta` give, through the same segment search and the
|
|
368
|
+
* stock channels' own lerp, which is all a laned keys voice can use.
|
|
316
369
|
*/
|
|
317
|
-
export function foldKeys(voice, chans,
|
|
370
|
+
export function foldKeys(voice, chans, slot) {
|
|
371
|
+
const phase = this.arg[2 /* Arg.PHASE */];
|
|
372
|
+
const w = this.arg[0 /* Arg.WEIGHT */];
|
|
318
373
|
const built = voice.built;
|
|
319
374
|
const tracks = built.tracks;
|
|
320
375
|
for (let i = 0; i < tracks.length; i++) {
|
|
@@ -324,14 +379,14 @@ export function foldKeys(voice, chans, phase, slot, w) {
|
|
|
324
379
|
if (found === NOTHING)
|
|
325
380
|
continue;
|
|
326
381
|
if (found === AT) {
|
|
327
|
-
this.foldInto(ch, slot, seg.a
|
|
382
|
+
this.foldInto(ch, slot, seg.a);
|
|
328
383
|
continue;
|
|
329
384
|
}
|
|
330
385
|
const a = seg.a;
|
|
331
386
|
const b = seg.b;
|
|
332
387
|
const u = seg.eased;
|
|
333
|
-
if (ch.scalar) {
|
|
334
|
-
this.foldInto(ch, slot, voice.lerps[i](a, b, u)
|
|
388
|
+
if (ch.scalar || !ch.plain) {
|
|
389
|
+
this.foldInto(ch, slot, voice.lerps[i](a, b, u));
|
|
335
390
|
continue;
|
|
336
391
|
}
|
|
337
392
|
// `vec`'s lerp, reading each end past its length as the rest, then its fold.
|
|
@@ -351,10 +406,18 @@ export function readKeyed(voice, phase, delta, scratch) {
|
|
|
351
406
|
readKeys(voice.built, phase, delta, undefined, voice.lerps, undefined, voice.intos, scratch);
|
|
352
407
|
}
|
|
353
408
|
/**
|
|
354
|
-
* Calls a stateless fn voice's patch for a subject its general path has met, and folds the delta
|
|
355
|
-
*
|
|
409
|
+
* Calls a stateless fn voice's patch for a subject its general path has met, and folds the delta,
|
|
410
|
+
* at the voice time, phase, pass, delay and weight in `Arg`; false where it gave no delta, for a
|
|
411
|
+
* subject the host has let go of or a weight the voice is silent at. As arguments those cost nothing where V8 inlines the call and 31 bytes a call where it
|
|
412
|
+
* does not, which differs by V8 version: Node 26.1 does not (2026-10-09).
|
|
356
413
|
*/
|
|
357
|
-
export function call(voice, chans, rec, slot
|
|
414
|
+
export function call(voice, chans, rec, slot) {
|
|
415
|
+
const arg = this.arg;
|
|
416
|
+
const elapsed = arg[1 /* Arg.ELAPSED */];
|
|
417
|
+
const phase = arg[2 /* Arg.PHASE */];
|
|
418
|
+
const pass = arg[3 /* Arg.PASS */];
|
|
419
|
+
const delay = arg[4 /* Arg.DELAY */];
|
|
420
|
+
const w = arg[0 /* Arg.WEIGHT */];
|
|
358
421
|
const host = this.host;
|
|
359
422
|
const subject = this.subjectAt(slot);
|
|
360
423
|
if (subject === absent)
|
|
@@ -362,11 +425,11 @@ export function call(voice, chans, rec, slot, elapsed, phase, pass, delay, w) {
|
|
|
362
425
|
// Called already this frame, by the general path or a fill before a refill: reuse, as a probe does.
|
|
363
426
|
if (rec.probed === this.now && rec.delta !== null && rec.seeks === voice.seeks) {
|
|
364
427
|
if (w > 0)
|
|
365
|
-
this.foldDelta(chans, slot, rec.delta
|
|
428
|
+
this.foldDelta(chans, slot, rec.delta);
|
|
366
429
|
return true;
|
|
367
430
|
}
|
|
368
431
|
if (silent(voice, w))
|
|
369
|
-
return
|
|
432
|
+
return false;
|
|
370
433
|
const kept = reading.kept;
|
|
371
434
|
host.ready(voice, subject, rec, elapsed, pass, w);
|
|
372
435
|
if (this.keeps)
|
|
@@ -383,6 +446,6 @@ export function call(voice, chans, rec, slot, elapsed, phase, pass, delay, w) {
|
|
|
383
446
|
if (reading.kept !== kept && !voice.keeping)
|
|
384
447
|
host.kept(voice);
|
|
385
448
|
if (w > 0)
|
|
386
|
-
this.foldDelta(chans, slot, delta
|
|
449
|
+
this.foldDelta(chans, slot, delta);
|
|
387
450
|
return true;
|
|
388
451
|
}
|
package/dist/fit.js
CHANGED
|
@@ -93,7 +93,8 @@ export function condense() {
|
|
|
93
93
|
if (fits(span, kids, plan) || !kids.some((k) => k.overlap))
|
|
94
94
|
return plan;
|
|
95
95
|
const at = (s) => ({ ...plan, share: s });
|
|
96
|
-
// `least` finds the smallest x that fits; the share wanted is the largest, so search
|
|
96
|
+
// `least` finds the smallest x that fits; the share wanted is the largest, so search how far
|
|
97
|
+
// under the plan's it is.
|
|
97
98
|
const x = least(0, plan.share, (d) => fits(span, kids, at(plan.share - d)));
|
|
98
99
|
return at(plan.share - x);
|
|
99
100
|
};
|
package/dist/fold.d.ts
CHANGED
|
@@ -1,7 +1,14 @@
|
|
|
1
1
|
import type { Mixer } from './mixer.js';
|
|
2
|
+
import type { Channel } from './types.js';
|
|
2
3
|
import type { Subject, Voice } from './voice.js';
|
|
3
4
|
export type Key<O> = keyof O & string;
|
|
4
5
|
export declare function near(a: unknown, b: unknown): boolean;
|
|
6
|
+
/**
|
|
7
|
+
* `merge(acc, b)`, where a result that is `b` itself, as `last()` gives, is copied into `acc` or a
|
|
8
|
+
* new array: `b` belongs to a patch or the mix's scratch, and a host may edit the pose. `acc` is a
|
|
9
|
+
* value this fold made.
|
|
10
|
+
*/
|
|
11
|
+
export declare function merged(channel: Channel<unknown>, acc: unknown, b: unknown): unknown;
|
|
5
12
|
export type Values = Record<string, unknown>;
|
|
6
13
|
/**
|
|
7
14
|
* One live voice's delta for one subject this frame, through its record for the subject, or null
|
|
@@ -28,12 +35,30 @@ export declare function baseFor<I, O>(this: Mixer<I, O>, voice: Voice<I, O>, sub
|
|
|
28
35
|
*/
|
|
29
36
|
export declare function slopeFor<I, O>(this: Mixer<I, O>, voice: Voice<I, O>, subject: I): Record<string, unknown> | undefined;
|
|
30
37
|
export declare function isRest<I, O>(this: Mixer<I, O>, delta: Record<string, unknown>): boolean;
|
|
38
|
+
/**
|
|
39
|
+
* A record's band state once its voice is skipped at weight 0: off, as `passes` would have said, so
|
|
40
|
+
* a weight that comes back inside the band does not find it still on.
|
|
41
|
+
*/
|
|
42
|
+
export declare function unband(held: Subject<unknown> | null | undefined): void;
|
|
31
43
|
/** Whether a rest-less channel's contribution is switched on, across a band rather than an edge. */
|
|
32
44
|
export declare function passes<I, O>(this: Mixer<I, O>, was: boolean | undefined, w: number): boolean;
|
|
33
45
|
/** Folds one voice's delta into the pose, its band state kept on the subject's record. */
|
|
34
46
|
export declare function apply<I, O>(this: Mixer<I, O>, pose: Record<string, unknown>, voice: Voice<I, O>, held: Subject<unknown>, delta: Record<string, unknown>, weight: number): void;
|
|
35
47
|
/** Clamps every bounded channel of a folded pose into its range, in place. */
|
|
36
48
|
export declare function clamp<I, O>(this: Mixer<I, O>, pose: Record<string, unknown>): Record<string, unknown>;
|
|
49
|
+
/** A folded value held to its channel's bounds: a number clamped, an array clamped in place. */
|
|
50
|
+
export declare function bound(channel: Channel<unknown>, v: unknown): unknown;
|
|
51
|
+
/**
|
|
52
|
+
* Whether a fold's next voice is its chain's next record, `held`, and not the next voice sharing
|
|
53
|
+
* one record, `sharers[q]`: the two lists are each in voice order, and a fold takes them as one.
|
|
54
|
+
*/
|
|
55
|
+
export declare function chainFirst<I, O>(held: Subject<unknown> | null, sharers: readonly Voice<I, O>[], q: number): boolean;
|
|
56
|
+
/**
|
|
57
|
+
* After a fold read a sharing voice for the subject numbered `slot`: keeps the weight it gave and
|
|
58
|
+
* what the read left on its record, and gives the fold's place in `sharers`, which moves back where
|
|
59
|
+
* the read made the voice share no more.
|
|
60
|
+
*/
|
|
61
|
+
export declare function shared<I, O>(this: Mixer<I, O>, voice: Voice<I, O>, slot: number, rec: Subject<unknown>, q: number): number;
|
|
37
62
|
export declare function fold<I, O>(this: Mixer<I, O>, subject: I, out?: O, dry?: boolean, except?: number): O;
|
|
38
63
|
export declare function folded<I, O>(this: Mixer<I, O>, subject: I, out?: O, dry?: boolean, except?: number): O;
|
|
39
64
|
/**
|
|
@@ -43,6 +68,18 @@ export declare function folded<I, O>(this: Mixer<I, O>, subject: I, out?: O, dry
|
|
|
43
68
|
export declare function linked<I, O>(this: Mixer<I, O>, subject: I): Subject<unknown> | null;
|
|
44
69
|
/** The fold after a subject's chain is linked and its lanes asked whether it reads from them. */
|
|
45
70
|
export declare function foldWith<I, O>(this: Mixer<I, O>, subject: I, out: O, head: Subject<unknown> | null, laned: boolean, dry: boolean, except?: number): O;
|
|
71
|
+
/**
|
|
72
|
+
* `foldWith`'s voices in a mix with a locus or a voice sharing one record in it. The chain is taken
|
|
73
|
+
* again where a voice stopped sharing since it was linked, as a patch call in this probe's fill can
|
|
74
|
+
* make one do. With no locus, the chain's records fold in voice order, and each voice sharing one
|
|
75
|
+
* record, which is in no chain, before the first chain record that comes after it.
|
|
76
|
+
*/
|
|
77
|
+
export declare function foldDetour<I, O>(this: Mixer<I, O>, subject: I, pose: Record<string, unknown>, linkedHead: Subject<unknown>, laned: boolean, dry: boolean, except: number | undefined, owed: number): O;
|
|
78
|
+
/**
|
|
79
|
+
* Folds the voices sharing one record from `sharers[q]` up to the first whose id is `before` or
|
|
80
|
+
* more, as `foldWith` folds a chain's records, and gives the place it stopped at.
|
|
81
|
+
*/
|
|
82
|
+
export declare function foldSharers<I, O>(this: Mixer<I, O>, pose: Record<string, unknown>, subject: I, head: Subject<unknown>, q: number, before: number, laned: boolean, dry: boolean, except: number | undefined, owed: number): number;
|
|
46
83
|
/** Whether the subject numbered `owed` reads laned `voice` from the general path this fill. */
|
|
47
84
|
export declare function owedBy<I, O>(this: Mixer<I, O>, owed: number, voice: Voice<I, O>): boolean;
|
|
48
85
|
/** `foldWith`'s voices with a locus in play: each locus folds at its first member's place. */
|