@msb235/blits 0.4.0 → 0.5.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 (102) hide show
  1. package/CHANGELOG.md +262 -0
  2. package/README.md +2 -1
  3. package/dist/bare.d.ts +29 -0
  4. package/dist/bare.js +105 -0
  5. package/dist/blend.d.ts +34 -0
  6. package/dist/blend.js +102 -0
  7. package/dist/book.d.ts +53 -0
  8. package/dist/book.js +218 -0
  9. package/dist/chain.d.ts +22 -0
  10. package/dist/chain.js +150 -0
  11. package/dist/channels.d.ts +2 -0
  12. package/dist/channels.js +3 -1
  13. package/dist/clock.d.ts +50 -3
  14. package/dist/clock.js +102 -9
  15. package/dist/clone.d.ts +7 -0
  16. package/dist/clone.js +57 -0
  17. package/dist/columns.d.ts +29 -0
  18. package/dist/columns.js +183 -0
  19. package/dist/crowd.d.ts +128 -0
  20. package/dist/crowd.js +354 -0
  21. package/dist/cue.d.ts +3 -0
  22. package/dist/cue.js +115 -0
  23. package/dist/due.d.ts +12 -0
  24. package/dist/due.js +93 -0
  25. package/dist/fade.d.ts +19 -0
  26. package/dist/fade.js +133 -0
  27. package/dist/fill.d.ts +42 -0
  28. package/dist/fill.js +381 -0
  29. package/dist/fold.d.ts +51 -0
  30. package/dist/fold.js +475 -0
  31. package/dist/gather.d.ts +24 -0
  32. package/dist/gather.js +186 -0
  33. package/dist/handle.d.ts +31 -0
  34. package/dist/handle.js +56 -0
  35. package/dist/held.d.ts +14 -0
  36. package/dist/held.js +117 -0
  37. package/dist/history.d.ts +22 -0
  38. package/dist/history.js +149 -0
  39. package/dist/hosts.d.ts +16 -0
  40. package/dist/hosts.js +178 -0
  41. package/dist/index.d.ts +1 -1
  42. package/dist/keyrows.d.ts +36 -0
  43. package/dist/keyrows.js +138 -0
  44. package/dist/lane.d.ts +210 -0
  45. package/dist/lane.js +187 -0
  46. package/dist/lanes.d.ts +121 -246
  47. package/dist/lanes.js +150 -1578
  48. package/dist/locus.d.ts +40 -0
  49. package/dist/locus.js +89 -0
  50. package/dist/marks.d.ts +12 -0
  51. package/dist/marks.js +80 -0
  52. package/dist/meet.d.ts +16 -0
  53. package/dist/meet.js +113 -0
  54. package/dist/mixer.d.ts +244 -196
  55. package/dist/mixer.js +242 -2220
  56. package/dist/motion.d.ts +66 -21
  57. package/dist/motion.js +325 -165
  58. package/dist/move.d.ts +9 -0
  59. package/dist/move.js +190 -0
  60. package/dist/named.d.ts +12 -0
  61. package/dist/named.js +39 -0
  62. package/dist/numbers.d.ts +18 -6
  63. package/dist/numbers.js +59 -31
  64. package/dist/owed.d.ts +24 -0
  65. package/dist/owed.js +51 -0
  66. package/dist/owner.d.ts +43 -0
  67. package/dist/owner.js +117 -0
  68. package/dist/pace.d.ts +40 -0
  69. package/dist/pace.js +113 -0
  70. package/dist/patch.d.ts +51 -10
  71. package/dist/patch.js +140 -45
  72. package/dist/place.d.ts +20 -0
  73. package/dist/place.js +196 -0
  74. package/dist/project.d.ts +4 -0
  75. package/dist/project.js +233 -0
  76. package/dist/pull.d.ts +5 -0
  77. package/dist/pull.js +175 -0
  78. package/dist/qualify.d.ts +31 -0
  79. package/dist/qualify.js +345 -0
  80. package/dist/relink.d.ts +25 -0
  81. package/dist/relink.js +59 -0
  82. package/dist/rows.d.ts +33 -0
  83. package/dist/rows.js +282 -0
  84. package/dist/sample.d.ts +21 -0
  85. package/dist/sample.js +232 -0
  86. package/dist/signals.d.ts +12 -9
  87. package/dist/signals.js +8 -5
  88. package/dist/store.d.ts +10 -3
  89. package/dist/store.js +44 -9
  90. package/dist/strays.d.ts +21 -0
  91. package/dist/strays.js +84 -0
  92. package/dist/tweened.d.ts +11 -0
  93. package/dist/tweened.js +48 -0
  94. package/dist/types.d.ts +217 -34
  95. package/dist/unreached.d.ts +5 -0
  96. package/dist/unreached.js +24 -0
  97. package/dist/voice.d.ts +240 -0
  98. package/dist/voice.js +322 -0
  99. package/dist/weigh.d.ts +26 -0
  100. package/dist/weigh.js +89 -0
  101. package/docs/schema.html +118 -40
  102. package/package.json +5 -2
package/dist/mixer.d.ts CHANGED
@@ -1,212 +1,260 @@
1
- import { type Curve } from './easing.js';
2
- import { type Motions } from './motion.js';
3
- import { type Built, intosOf, type Scratch } from './patch.js';
1
+ import { blended, laneRead, shareKept } from './blend.js';
2
+ import type { Book } from './book.js';
3
+ import { aims, chain, linkable } from './chain.js';
4
+ import { type LerpInto } from './channels.js';
5
+ import type { Due } from './due.js';
6
+ import { parting } from './fade.js';
7
+ import { apply, baseFor, clamp, fold, folded, foldLoci, foldWith, influence, isRest, type Key, keyed, linked, owedBy, passes, read, slopeFor, tick } from './fold.js';
8
+ import type { HandleHost } from './handle.js';
9
+ import { held, shownOf, sinceOf, unreachedOf } from './held.js';
10
+ import { Lanes } from './lanes.js';
11
+ import { foldLocus, type LocusScratch } from './locus.js';
12
+ import type { MotionOwner, Motions } from './motion.js';
13
+ import { Pace } from './pace.js';
14
+ import { keep } from './pull.js';
15
+ import { Steps } from './relink.js';
4
16
  import { Store } from './store.js';
5
- import type { Channel, Engine, FadeSpec, Kit, Mix, MixOptions, Patch, Setting, VoiceSpec } from './types.js';
6
- /** Everything one voice holds for one subject, chained through the next voice that reaches it. */
7
- export interface Subject<S> {
8
- /** The voice's `target` answer, fixed on first sight. */
9
- reaches: boolean;
10
- /** The voice's `stagger` answer in voice ms, fixed on first sight. */
11
- delay: number;
12
- /** The mix timestamp this subject's delay ran out at, which its step grid counts from. */
13
- since: number;
14
- /** The mix timestamp its fade in counts from: `since`, or earlier for a voice holding before. */
15
- shown: number;
16
- /** The weight this voice gave this subject the last frame it was probed, 0 where it gave none. */
17
- weight: number;
18
- /** Left at rest during a handover, so it stops contributing. */
19
- rested: boolean;
20
- /** Per written channel, whether a rest-less influence is on: 0 unknown, 1 on, 2 off. */
21
- bands: Uint8Array;
22
- state: S;
23
- /** The `now` this subject last caught up to, for this voice. */
24
- stepped: number;
25
- /** Under `stepMs`, how many intervals have run since `since`; `stepped` is where that lands. */
26
- ticks: number;
27
- /** The `now` this subject was last probed at, so twelve probes in a frame step once. */
28
- probed: number;
29
- /** The last delta computed this frame, handed back to a repeat probe unchanged. */
30
- delta: Record<string, unknown> | null;
31
- /** The phase `delta` was read at, to read it again once its voice's scratch has moved on. */
32
- phase: number;
33
- /** The voice's `seeks` when `delta` was read, so a seek later in the frame reads it again. */
34
- seeks: number;
35
- /** Stop 0 for a `from: 'current'` voice, taken the first frame this subject is seen. */
36
- base?: Record<string, unknown>;
37
- /** The pose's velocity per channel at that moment, units per ms, so the first segment leaves at it. */
38
- slope?: Record<string, unknown>;
39
- /** What each stateful signal on this voice keeps for this subject, by the signal. */
40
- kept: Map<object, unknown>;
41
- keep: Setting['keep'];
42
- /** Under `history`, copies of this record by the mix time they were taken, oldest first. */
43
- snaps?: {
17
+ import type { Booker, BookOptions, Channel, Columns, Engine, Handle, Kit, Marked, Mix, MixOptions, OwnerSpec, Patch, Projection, Sent, Signal, VoiceSpec } from './types.js';
18
+ import { type Subject, type Voice } from './voice.js';
19
+ import { base, capped, fadeOf, horizonFor, ownedBy, ownerBase, prime, weigh, weighOwned } from './weigh.js';
20
+ export declare class Mixer<I, O> implements Mix<I, O> {
21
+ readonly kit: Kit<O>;
22
+ readonly opts: MixOptions;
23
+ cued: Voice<I, O>[];
24
+ /** Under `history`, voices that have left but that a read back may still reach. */
25
+ gone: Voice<I, O>[];
26
+ /** Set on a projection's own mixer: it sends nothing, keeps no history, and reads without committing. */
27
+ projecting: boolean;
28
+ /** Set on a projection reading back: a subject it has nothing on starts from its voice's start. */
29
+ backward: boolean;
30
+ /** True during a sync, so a control change it makes is recorded as showing in that frame. */
31
+ moving: boolean;
32
+ /**
33
+ * Under `history` with `inputs`, the host fields patches read, copied each frame they changed. In
34
+ * a projection reading back, the copy in force then.
35
+ */
36
+ hostLog: {
44
37
  at: number;
45
- held: Subject<S>;
38
+ fields: Record<string, unknown>;
46
39
  }[];
47
- /** In a projection: where this record started from, and whether nothing known could be. */
48
- from?: number;
49
- unknown?: boolean;
50
- /** Under `history` with `inputs`, what an input weight signal read for this subject, when it changed. */
51
- inputs?: {
40
+ /**
41
+ * Marks the host announced on a score: `at` in host time, so the mix's rate never moves one, and
42
+ * NaN until the next sync for one announced as now before any sync; `made` is the mix time it was
43
+ * announced, for a read back to know what was known.
44
+ */
45
+ announced: {
46
+ name: string;
47
+ score: string | undefined;
48
+ tags: readonly string[];
52
49
  at: number;
53
- value: number;
50
+ made: number;
51
+ order: number;
54
52
  }[];
55
- /** In a projection reading back: that record, to read in place of the signal. */
56
- replay?: {
53
+ hostThen: {
54
+ fields: Record<string, unknown>;
55
+ } | undefined;
56
+ /** Each subject's last two poses and when they were probed, for `from: 'current'`. */
57
+ pose: Store<I, {
58
+ pose: O;
57
59
  at: number;
58
- value: number;
59
- }[];
60
- /** The voice this is the record of; null on a subject's stub. */
61
- voice: object | null;
62
- /** The next voice's record for this subject, in voice order, among those that reach it. */
63
- next: Subject<unknown> | null;
60
+ prev: O | undefined;
61
+ prevAt: number;
62
+ }>;
63
+ nextId: number;
64
64
  /**
65
- * On the first record, which the mix keeps per subject so a probe makes one lookup: the `version`
66
- * the chain was linked at, and per locus and channel whether a rest-less influence is on.
65
+ * The mix clock: host time at the mix's rate. Host time is the host's timestamp less every gap
66
+ * `rebase` has taken out, `u` at the last sync.
67
67
  */
68
- version: number;
69
- loci: Map<string, boolean> | null;
70
- /** On the first record: the number lanes index this subject by, -1 without one. */
71
- slot: number;
72
- }
73
- /** What sets a voice's clock: its rate, and where it was last anchored. */
74
- interface Clock {
75
- anchorNow: number;
76
- anchorElapsed: number;
77
- rate: number;
78
- ramp: {
79
- from: number;
80
- to: number;
81
- over: number;
82
- } | null;
83
- }
84
- /** A voice's clock, weight and fade from one mix time on, kept under `history`. */
85
- interface Controls extends Clock {
86
- at: number;
87
- weight: number;
88
- out: Ramp | null;
89
- /** Where its anchors had placed it then: start, and the start of an anchored fade out. */
90
- start: number;
91
- outAt: number;
92
- /** Made by a sync, so it shows in that frame; a host's change between frames shows from the next. */
93
- sync: boolean;
94
- }
95
- interface Ramp {
96
- from: number;
97
- at: number;
98
- over: number;
99
- rest: boolean;
100
- deadline?: number;
101
- }
102
- export declare class Voice<I, O> {
103
- readonly id: number;
104
- readonly spec: VoiceSpec<I, O>;
105
- readonly patch: Patch<I, O, unknown>;
106
- readonly fade: FadeSpec;
107
- start: number;
108
- state: 'pending' | 'live' | 'held' | 'fading' | 'done';
109
- rate: number;
110
- weight: number;
68
+ now: number;
69
+ u: number;
70
+ /** This mix's frame among every mix's: moved by a sync, and by a control change or drop within one. */
71
+ frame: number;
72
+ offset: number;
73
+ /** The mix's own rate; null while it has never been set, when mix time is host time. */
74
+ pace: Pace | null;
75
+ /** Pending voices whose start the host gave, by its host time, kept where the rate puts it. */
76
+ pins: Map<Voice<I, O>, number> | null;
77
+ last: number;
78
+ rebasing: boolean;
79
+ wantsPose: boolean;
80
+ /** The pose `pull` folds a subject into where it cannot read straight from the lanes. */
81
+ scratch: O | undefined;
82
+ /** The last array `pull` read, by position, with each subject's chain head, to skip the lookup. */
83
+ /** Live voices by the earliest mix time `moveTo` would change each, a binary heap. */
84
+ due: Due<I, O>[];
85
+ /** Voices retired since `moveTo` last pruned them, in the order they retired. */
86
+ retired: Voice<I, O>[];
87
+ /** Visit every voice each sync, as before the due queue; for tests that compare the two. */
88
+ walkAll: boolean;
89
+ pulled: I[];
90
+ pulledHeads: (Subject<unknown> | undefined)[];
91
+ /** Each remembered head's lane slot, and the `version` and `relinks` they were all current at. */
92
+ pulledSlots: Int32Array<ArrayBuffer>;
93
+ pulledVersion: number;
94
+ pulledRelinks: number;
95
+ /** Counts chains made stale one subject at a time, which `version` does not. */
96
+ relinks: number;
97
+ /** Read once a sync, so a `reduce` function is not called per voice per subject. */
98
+ reducedNow: boolean;
99
+ /** Something was changed since the last sync, so the next frame may differ from this one. */
100
+ stirred: boolean;
101
+ /** Counts the changes `stir` records, which a frame's record of a probe is current only before. */
102
+ stirs: number;
103
+ /** Records a change to the mix's voices or controls. */
104
+ stir(): void;
111
105
  /**
112
- * elapsed = anchorElapsed + the rate integrated from anchorNow, rebased on a rate change or a seek.
113
- * Without a ramp the rate is constant; with one it moves linearly from `from` to `to` over `over`
114
- * mix ms starting at the anchor, and holds `to` after.
106
+ * Per subject, the first record of the chain through every live voice that reaches it, or a stub
107
+ * where none does. Relinked when `version` moves, which is whenever the list or a voice's pending
108
+ * state changes.
115
109
  */
116
- anchorNow: number;
117
- anchorElapsed: number;
118
- ramp: {
119
- from: number;
120
- to: number;
121
- over: number;
122
- } | null;
123
- out: Ramp | null;
124
- readonly subjects: Store<I, Subject<unknown>>;
125
- /** The subjects its spec names, or null where it names none. */
126
- readonly named: ReadonlySet<I> | null;
127
- /** Kit slot of each channel the patch writes, in `writes` order. */
128
- readonly slots: number[];
129
- /** The stops built ahead of time, for a `keys` patch. */
130
- readonly built: Built | null;
131
- /** The kit's `lerp` for each channel the patch writes, which keyed stops interpolate through. */
132
- readonly lerps: Channel<unknown>['lerp'][];
133
- /** Per keyed channel, the in-place form of the lerp its stops take, where it has one. */
134
- readonly intos: ReturnType<typeof intosOf> | undefined;
110
+ readonly chains: Store<I, Subject<unknown>>;
111
+ version: number;
112
+ readonly steps: Steps<Voice<I, O>>;
113
+ /** Per subject, the voices whose `subjects` name it, in voice order. */
114
+ named: Store<I, Voice<I, O>[]>;
115
+ /** Voices a subject has been faded out of, which `drop` looks in besides those that reach it. */
116
+ readonly parters: Set<Voice<I, O>>;
135
117
  /**
136
- * The arrays keyed reads interpolate into: one set for the voice, not one per subject, since 10k
137
- * subjects' worth of long-lived arrays costs more in cache misses than allocating them did.
118
+ * Motion patches that may hold state for a subject no voice still reaching it plays, which `drop`
119
+ * frees besides those voices' own: per subject, a patch a voice naming it left while another
120
+ * voice plays on, or that the host retargeted it on; and any patch a voice over every subject
121
+ * left while another plays on. How many live voices play each motion patch says which.
138
122
  */
139
- scratch: Scratch;
140
- /** The record whose delta holds `scratch`'s arrays; any other's must be read again to be handed out. */
141
- holder: Subject<unknown> | null;
142
- /** Whether its channels run as lanes this frame, so the general fold passes it by. */
143
- laned: boolean;
144
- /** How many times it has been sought, so a delta read before a seek is not handed out after it. */
145
- seeks: number;
146
- /** Whether its patch has kept state on a record through `setting.keep`, which makes it stateful. */
147
- keeping: boolean;
148
- /** For a motion patch, the hook it was given to ask the mix for its subjects' voice time. */
149
- frame: ((subject: I) => number) | null;
150
- /** For a motion patch, the hook it was given to bring a subject faded out of this voice back. */
151
- revive: ((subject: I) => void) | null;
152
- /** Subjects fading out of this voice alone, by the ramp each started; null while none are. */
153
- parts: Map<I, {
154
- at: number;
155
- over: number;
156
- }> | null;
157
- /** Subjects faded out of this voice, by the mix time each left at; null while none have. */
158
- parted: Map<I, number> | null;
159
- readonly ease: Curve | undefined;
160
- /** How many passes its `loop` plays, worked out once. */
161
- readonly passes: number;
162
- /** Voice ms its passes last, Infinity for an aperiodic patch or a loop for good. */
163
- readonly span: number;
164
- /** The state behind a motion patch, undefined for any other. */
165
- readonly motion: Motions<I> | undefined;
166
- /** Its `hold`, for a patch it applies to: motion holds its target already. */
167
- readonly holdsBefore: boolean;
168
- readonly holdsAfter: boolean;
169
- /** The mix time it first showed: when it was cued, or the first sync after. */
170
- opened: number;
171
- /** Which of its entries in the mix's due queue is current; older ones are skipped when popped. */
172
- dueToken: number;
173
- /** Records made while it was pending, whose `since` its start may since have moved. */
174
- early: Subject<unknown>[] | null;
175
- /** Reused for every call this voice makes, so it is valid only during the call. */
176
- readonly setting: Setting<unknown>;
177
- /** Every subject this voice has been asked about, so a handover knows when it is finished. */
178
- seen: number;
179
- /** The longest stagger of any subject seen, so a finite loop waits for the last of them. */
180
- latest: number;
181
- restedCount: number;
182
- /** The mix time it was cued at; -Infinity before the first sync. */
183
- cuedAt: number;
184
- /** The mix time it left at. */
185
- doneAt: number;
186
- /** Under `history`, its controls after each change, oldest first. */
187
- log: Controls[] | null;
188
- /** Where an anchored `out` or `end` puts its fade's start, mix time; Infinity until known. */
189
- outAt: number;
190
- /** Whether its start is still to be fixed by an anchor, so it waits pending. */
191
- placing: boolean;
192
- resolve: () => void;
193
- readonly done: Promise<void>;
194
- play: (played: boolean) => void;
195
- readonly played: Promise<boolean>;
196
- constructor(id: number, spec: VoiceSpec<I, O>, patch: Patch<I, O, unknown>, fade: FadeSpec, now: number, start: number, slotOf: Map<string, number>, channels: readonly Channel<unknown>[], host: unknown, send: (event: unknown) => void);
197
- elapsedAt(now: number): number;
198
- /** The mix time its clock reads `elapsed`, inverting `elapsedAt`; Infinity where it never will. */
199
- timeAt(elapsed: number): number;
200
- /** Records this voice's controls as they stand, from mix time `at`. */
201
- note(at: number, sync?: boolean): void;
123
+ readonly strays: Store<I, Motions<I>[]>;
124
+ readonly strayAll: Set<Motions<I>>;
125
+ readonly playing: Map<Motions<I>, number>;
126
+ /** How many voices in the list carry `subjects`. */
127
+ naming: number;
128
+ /** The voices in the list that name no subjects, in voice order. */
129
+ general: Voice<I, O>[];
130
+ /** How many voices in the list carry a locus; with none, a fold allocates nothing. */
131
+ loci: number;
132
+ /** What every motion patch it plays asks for its voice's time, holding this mix weakly. */
133
+ owner: MotionOwner | null;
134
+ /** How many voices in the list are anchored, so a sync with none skips placing them. */
135
+ anchored: number;
136
+ /** Events sent since the last drain, and who is being probed, so `send` knows whose they are. */
137
+ sent: Sent<I, unknown>[];
138
+ sending: {
139
+ voice: Voice<I, O> | null;
140
+ subject: I;
141
+ };
142
+ readonly send: (event: unknown) => void;
143
+ /** The weight `influence` found besides the delta, read by the caller at once. */
144
+ w: number;
145
+ readonly names: Key<O>[];
146
+ readonly channels: Channel<unknown>[];
147
+ /** Slots of the channels that declare bounds, clamped after every fold. */
148
+ readonly bounded: number[];
149
+ /** By slot, a stock array channel's in-place `lerp`. */
150
+ readonly lerpsInto: (LerpInto | undefined)[];
151
+ /** What a fold with a locus in play gathers into, one per depth of folds under way. */
152
+ readonly locusScratch: LocusScratch<I, O>[];
153
+ locusDepth: number;
154
+ readonly slotOf: Map<string, number>;
155
+ readonly lanes: Lanes<I, O> | null;
156
+ handles: HandleHost<I, O> | null;
157
+ /** What `book` made, still booking; null while there is none. */
158
+ bookers: Book<I, O>[] | null;
159
+ /** Every owner still in the mix, null until one is cued. */
160
+ owners: Voice<I, O>[] | null;
161
+ constructor(kit: Kit<O>, opts: MixOptions);
162
+ get reduced(): boolean;
163
+ get band(): {
164
+ on: number;
165
+ off: number;
166
+ };
167
+ cue(spec: VoiceSpec<I, O>): Handle<I>;
168
+ blend(patches: readonly Patch<I, O, unknown>[], by: Signal<I>, spec?: Omit<VoiceSpec<I, O>, 'patch' | 'weight' | 'locus'>): Handle<I>[];
169
+ owns(spec: OwnerSpec<I>): Handle<I>;
170
+ sync(timestamp: number): void;
171
+ book(opts: BookOptions): Booker;
172
+ probe(subject: I, out?: O): O;
173
+ pull(subjects: Iterable<I>, into: Columns<O>): void;
174
+ project(timestamp: number): Projection<I, O>;
175
+ announce(name: string, opts?: {
176
+ at?: number;
177
+ score?: string;
178
+ tags?: readonly string[];
179
+ }): void;
180
+ marks(from: number, to: number): Marked[];
181
+ atRest(subject: I): boolean;
182
+ rests(pose: O): boolean;
183
+ rebase(): void;
184
+ voices(tag?: string): Handle<I>[];
185
+ get live(): boolean;
186
+ get inert(): boolean;
187
+ get rate(): number;
188
+ set rate(r: number);
189
+ ramp(rate: number, over: number): void;
190
+ /** Whether a voice will change no pose from `now` on, short of a change made to it. */
191
+ still(voice: Voice<I, O>, now: number): boolean;
192
+ mute(opts?: {
193
+ over?: number;
194
+ }): void;
195
+ drop(subject: I): void;
196
+ drain<E = unknown>(tag?: string): Sent<I, E>[];
197
+ /** Voices whose stop 0 is mid-computation, so a fold for one cannot re-enter itself. */
198
+ readonly folding: Set<number>;
199
+ linkedLaned: boolean;
202
200
  /**
203
- * A copy for a projection: its own setting, which sends nothing, and its own per-subject records,
204
- * filled from `fill`. With `controls` it takes those, as the voice stood at an earlier time.
201
+ * Per subject, twice `restsKey` at its last probe plus 1 if the pose rested; null until `atRest`
202
+ * is first asked, when probes start writing it.
205
203
  */
206
- copy(fill: (subject: I) => Subject<unknown> | undefined, controls?: Controls): Voice<I, O>;
207
- rateAt(now: number): number;
208
- /** Moves the anchor to `now`, carrying what is left of a ramp. */
209
- rebase(now: number): void;
204
+ restStamps: Store<I, number> | null;
205
+ /** What a probe's record of rest is good for: moved by a new frame, version or relink. */
206
+ private restsEpoch;
207
+ private restsFrame;
208
+ private restsVersion;
209
+ private restsRelinks;
210
+ private restsStirs;
211
+ /** The pose `atRest` folds into where no probe this frame answers. */
212
+ private restScratch;
213
+ private restsLaned;
214
+ private restsKey;
215
+ }
216
+ declare const methods: {
217
+ fold: typeof fold;
218
+ folded: typeof folded;
219
+ linked: typeof linked;
220
+ foldWith: typeof foldWith;
221
+ owedBy: typeof owedBy;
222
+ foldLoci: typeof foldLoci;
223
+ read: typeof read;
224
+ influence: typeof influence;
225
+ keyed: typeof keyed;
226
+ tick: typeof tick;
227
+ apply: typeof apply;
228
+ clamp: typeof clamp;
229
+ passes: typeof passes;
230
+ isRest: typeof isRest;
231
+ baseFor: typeof baseFor;
232
+ slopeFor: typeof slopeFor;
233
+ prime: typeof prime;
234
+ capped: typeof capped;
235
+ horizonFor: typeof horizonFor;
236
+ weigh: typeof weigh;
237
+ weighOwned: typeof weighOwned;
238
+ base: typeof base;
239
+ envelope: typeof fadeOf;
240
+ ownedBy: typeof ownedBy;
241
+ ownerBase: typeof ownerBase;
242
+ blended: typeof blended;
243
+ laneRead: typeof laneRead;
244
+ shareKept: typeof shareKept;
245
+ parting: typeof parting;
246
+ chain: typeof chain;
247
+ linkable: typeof linkable;
248
+ aims: typeof aims;
249
+ held: typeof held;
250
+ unreachedOf: typeof unreachedOf;
251
+ sinceOf: typeof sinceOf;
252
+ shownOf: typeof shownOf;
253
+ keep: typeof keep;
254
+ foldLocus: typeof foldLocus;
255
+ };
256
+ type Methods = typeof methods;
257
+ export interface Mixer<I, O> extends Methods {
210
258
  }
211
259
  /**
212
260
  * The one that ships: every form on the CPU, probed per subject on demand.
@@ -219,5 +267,5 @@ export declare const mixer: Engine;
219
267
  *
220
268
  * @category mix
221
269
  */
222
- export declare function mix<I, O>(kit: Kit<O>, opts?: MixOptions): Mix<I, O>;
270
+ export declare function mix<I, O, H = unknown>(kit: Kit<O>, opts?: MixOptions<H>): Mix<I, O, H>;
223
271
  export {};