@msb235/blits 0.3.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 +314 -0
  2. package/README.md +3 -2
  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 +143 -122
  47. package/dist/lanes.js +236 -742
  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 -169
  55. package/dist/mixer.js +321 -1793
  56. package/dist/motion.d.ts +104 -19
  57. package/dist/motion.js +448 -180
  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 +261 -42
  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 +151 -46
  102. package/package.json +5 -2
package/dist/motion.d.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  import { type Curve } from './easing.js';
2
- import type { Easing, Patch } from './types.js';
2
+ import type { Easing, MotionSpec, Patch } from './types.js';
3
3
  /**
4
4
  * A number, or one number per axis.
5
5
  *
@@ -31,8 +31,23 @@ interface Change {
31
31
  to?: number[];
32
32
  v?: number[];
33
33
  }
34
- /** A motion patch's `frame` while no mix plays it: no subject has a latest frame. */
35
- export declare const noFrame: () => number;
34
+ /**
35
+ * The mix playing a patch, asked with its voice's id: an owner and an id, where a pair of closures
36
+ * cost two functions, their contexts and a weak reference per voice.
37
+ */
38
+ export interface MotionOwner {
39
+ /** The subject's voice time at the mix's latest frame; NaN where no frame of the voice met it. */
40
+ frame(id: number, subject: unknown): number;
41
+ /** Brings a subject the voice faded out back to it, so a change is not made for nothing. */
42
+ revive(id: number, subject: unknown): void;
43
+ }
44
+ /**
45
+ * What a mix keeping copies of a patch's stretches is told, with its id and the subject's number,
46
+ * before one changes.
47
+ */
48
+ export interface Watcher {
49
+ stretchChanged(id: number, s: number): void;
50
+ }
36
51
  /**
37
52
  * A patch whose motion is a closed form per subject, so it lands in the same place at any frame
38
53
  * rate, and whose changes mid-flight start from where the subject is and how fast it moves.
@@ -55,54 +70,103 @@ export type Moving<I, O, V extends Value> = Patch<I, O, void> & {
55
70
  };
56
71
  interface Shape<I> {
57
72
  from: (subject: I) => number[];
58
- velocity: (subject: I) => number[];
73
+ /** How fast each axis starts moving, given where it starts: still unless the options say. */
74
+ velocity: (subject: I, x: number[]) => number[];
59
75
  /** Where it heads when released from `x` at `v`, given where it was heading. */
60
76
  aim: (x: number[], v: number[], was: number[] | null, subject: I) => number[];
61
77
  /** `[form, settle, k1, k2, k3]`. */
62
78
  law: readonly number[];
63
79
  /** Whether a subject's value is a number rather than an array. */
64
80
  scalar: (subject: I) => boolean;
81
+ /** Whether every subject's value is a number; undefined where that depends on the subject. */
82
+ scalarEvery(): boolean | undefined;
65
83
  /** A tween's easing, which its law cannot hold; undefined, but present, on every other shape. */
66
84
  ease: Curve | undefined;
85
+ /** A tween's seconds for a stretch the subject starts now; undefined, but present, on the rest. */
86
+ ms: ((subject: I) => number) | undefined;
87
+ /** The patch's kind and constants, as `Patch.motion` reports them. */
88
+ spec(): MotionSpec;
67
89
  }
68
90
  /**
69
91
  * A motion patch's subjects: the stretch each is playing, in one flat array by a number the patch
70
92
  * gives it, with earlier stretches a read back may reach and changes not yet applied beside them.
71
93
  * The one copy, read by `at` and by a mix's lane alike.
72
94
  *
73
- * After the law, each subject's run of `stride` numbers is its release time, its flags, then `x0`,
74
- * `v0` and `to` per axis. A live sample reads this one buffer and nothing else the patch owns: at
95
+ * After the law, each subject's run of `stride` numbers is its release time, its flags, a tween's
96
+ * seconds for the stretch, then `x0`, `v0` and `to` per axis. A live sample reads this one buffer and nothing else the patch owns: at
75
97
  * 10k springs of one subject each, a buffer per field, a map lookup per sample and the law in an
76
98
  * object of its own took a call from 130 ns to 490.
77
99
  */
78
100
  export declare class Motions<I> {
79
101
  private readonly shape;
80
102
  private readonly numbers;
103
+ /** Numbers by subject once a second is numbered: till then the one subject is found by `numbers`. */
81
104
  private readonly slots;
82
105
  /** Axes per subject; -1 until the first subject sets it. */
83
106
  n: number;
84
107
  private cap;
85
108
  private stride;
86
- private runs;
109
+ /**
110
+ * The law, then each subject's run; empty until the first subject, the law read from `shape`.
111
+ * Read outside, at `bareAt`, and written only here.
112
+ */
113
+ runs: Float64Array<ArrayBuffer>;
87
114
  /**
88
115
  * Where `sample` leaves a subject's position and velocity, per axis. Shared by every patch, so
89
116
  * read it before the next sample.
90
117
  */
91
118
  xs: Float64Array<ArrayBuffer>;
92
119
  vs: Float64Array<ArrayBuffer>;
93
- private readonly pending;
94
- private readonly older;
95
120
  /**
96
- * The subject's voice time at the mix's latest frame, which an untimed change and a `read` with
97
- * no time take; NaN where no frame of the patch's voice has met the subject. Set by the mix that
98
- * cues the patch, and put back when its voice retires.
121
+ * By subject number, changes not yet applied and earlier stretches a read back may reach: null
122
+ * until a subject first has one, since many patches are never changed. Each starts with room for
123
+ * one: an empty array written at 0 reserves 17, and most patches have one subject.
124
+ */
125
+ private pending;
126
+ private older;
127
+ /**
128
+ * The mix playing the patch and its voice's id, which an untimed change and a `read` with no time
129
+ * ask for the latest frame. Set by the mix that cues the patch, and cleared when its voice retires.
130
+ */
131
+ owner: MotionOwner | null;
132
+ ownerId: number;
133
+ /** Whether the channel it was cued on holds a number; undefined until it is cued. */
134
+ private holdsNumber;
135
+ private channel;
136
+ /**
137
+ * Records what the channel the patch is cued on holds, refusing a value of the other kind: at once
138
+ * where every subject's value is one kind, else on the first sample of a subject whose value is not.
99
139
  */
100
- frame: (subject: I) => number;
140
+ cuedOn(channel: string, holdsNumber: boolean): void;
141
+ private frame;
101
142
  constructor(shape: Shape<I>);
102
143
  /** The patch's number for `subject`, made with its first stretch on first ask. */
103
144
  slot(subject: I): number;
145
+ /** The patch's number for `subject`, undefined where it has none. */
146
+ private known;
104
147
  /** Forgets a subject, so a later ask starts it afresh from `from`. */
105
148
  release(subject: I): void;
149
+ /**
150
+ * Told, with `watchId`, whenever a subject's stretch or what is pending for it changes, so a mix
151
+ * keeping a copy of it knows to read it again. Set by the mix, cleared when its voice retires. An
152
+ * owner and an id, where a callback cost a closure and its context per patch.
153
+ */
154
+ watcher: Watcher | null;
155
+ watchId: number;
156
+ /** The easing a tween's stretches follow; undefined for every other shape. */
157
+ get ease(): Curve | undefined;
158
+ /** The patch's kind and constants. */
159
+ spec(): MotionSpec;
160
+ /** A copy of the patch's law, `[form, settle, k1, k2, k3]`. */
161
+ law(): Float64Array;
162
+ /** Whether `law` holds this patch's law, number for number, as `Object.is` compares them. */
163
+ hasLaw(law: Float64Array): boolean;
164
+ /**
165
+ * Copies subject `s`'s current stretch into `out` from `o` as its release time, its seconds, then
166
+ * `x0`, `v0` and `to` per axis; false, copying nothing, while it has a change pending or an
167
+ * earlier stretch kept, which only `sample` handles.
168
+ */
169
+ stretchInto(s: number, out: Float64Array, o: number): boolean;
106
170
  /** Whether subject `s`'s value is a number rather than an array. */
107
171
  scalar(s: number): boolean;
108
172
  /** The value `at` hands the mix: the first axis for a number, a fresh array otherwise. */
@@ -113,6 +177,21 @@ export declare class Motions<I> {
113
177
  * a projection's read applies the timed ones to a copy and commits nothing.
114
178
  */
115
179
  sample(s: number, t: number, xo: Float64Array, vo: Float64Array): void;
180
+ /**
181
+ * Where subject `s`'s run starts in `runs` (its release time, then flags, seconds, `x0`, `v0`
182
+ * and `to`) while it has nothing pending and no earlier stretch kept; -1 for any other.
183
+ */
184
+ bareAt(s: number): number;
185
+ /**
186
+ * A live `sample` at `t` for a subject with nothing pending and no earlier stretch kept, true
187
+ * then; false, writing nothing, for any other, which `quiet` and `sample` take instead.
188
+ */
189
+ sampleBare(s: number, t: number, xo: Float64Array, vo: Float64Array): boolean;
190
+ /**
191
+ * Whether every subject has landed on its target at its voice time at the latest frame, as a
192
+ * sample there would find; one with a change waiting has not. Commits nothing.
193
+ */
194
+ landed(): boolean;
116
195
  /**
117
196
  * Whether a live `sample` at `t` would leave the subject's state as it is: nothing to stamp or
118
197
  * commit by then, and nothing older than `reading.horizon` to let go of.
@@ -135,9 +214,9 @@ export declare class Motions<I> {
135
214
  private peek;
136
215
  private check;
137
216
  private flag;
138
- private forget;
217
+ forget(s: number): void;
139
218
  /** Where subject `s`'s run starts in `runs`. */
140
- private base;
219
+ base(s: number): number;
141
220
  private grow;
142
221
  private write;
143
222
  /** The stretch subject `s` is playing now, as an object. */
@@ -151,9 +230,15 @@ export declare class Motions<I> {
151
230
  private prune;
152
231
  private evaluateSegment;
153
232
  private evaluate;
154
- /** A tween's stretch, `dt` seconds after release, kept out of `evaluate` so a spring's stays small. */
155
- private eased;
156
233
  }
234
+ /**
235
+ * A stretch `t` voice ms into it, released at `at` from `x0` moving at `v0` toward `to` (each read
236
+ * from its offset), into `xo` and `vo`: the one copy of the closed forms, which `law` (a patch's
237
+ * `[form, settle, k1, k2, k3]`, the head of a patch's buffer or a copy of it) picks between. A tween reads `ease` and
238
+ * `ms`, the stretch's length, dividing in milliseconds so a boundary lands exactly; every other
239
+ * form ignores them.
240
+ */
241
+ export declare function closed(law: Float64Array, ease: Curve | undefined, n: number, at: number, ms: number, x0: ArrayLike<number>, x: number, v0: ArrayLike<number>, v: number, to: ArrayLike<number>, g: number, t: number, xo: Float64Array, vo: Float64Array): boolean;
157
242
  /** The state behind a `'motion'` patch, for an engine that reads it directly. */
158
243
  export declare function motionOf<I>(p: object): Motions<I> | undefined;
159
244
  interface Common<I, V extends Value> {
@@ -217,8 +302,8 @@ export declare function tween<I, O, V extends Value = number>(writes: keyof O, o
217
302
  from: PerSubject<I, V>;
218
303
  /** Where each subject ends. */
219
304
  to: PerSubject<I, V>;
220
- /** How long a stretch takes, ms. */
221
- ms: number;
305
+ /** How long a stretch takes, ms: asked per subject each time one of its stretches starts. */
306
+ ms: PerSubject<I, number>;
222
307
  /** The curve from `from` to `to`. Default `'ease'`, as CSS's. */
223
308
  ease?: Easing;
224
309
  }): Omit<Moving<I, O, V>, 'push'> & {