@m4l-jweb/bridge 1.0.0 → 1.1.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/package.json +1 -1
- package/src/index.ts +73 -1
package/package.json
CHANGED
package/src/index.ts
CHANGED
|
@@ -127,6 +127,22 @@ export function uiReady(): void {
|
|
|
127
127
|
outlet("ui_ready");
|
|
128
128
|
}
|
|
129
129
|
|
|
130
|
+
/**
|
|
131
|
+
* Send a message to the page in another of this device's windows.
|
|
132
|
+
*
|
|
133
|
+
* Two pages of one device are two Chromium contexts: no shared globals, no
|
|
134
|
+
* shared memory, no events between them. They talk through Max, and this is the
|
|
135
|
+
* message that does not persist - the receiving page gets `<selector> <value>` on
|
|
136
|
+
* the inlet it bound with `bindInlet`, and nothing is written to the Live set.
|
|
137
|
+
*
|
|
138
|
+
* Use a STATE SLOT instead for anything that must survive a save (the pattern,
|
|
139
|
+
* a preset). Use this for what is happening NOW: a transport change, a knob
|
|
140
|
+
* position, a nudge to re-read something.
|
|
141
|
+
*/
|
|
142
|
+
export function sendToWindow(windowId: string, selector: string, value: unknown): void {
|
|
143
|
+
outlet("window_send", windowId, selector, value);
|
|
144
|
+
}
|
|
145
|
+
|
|
130
146
|
/* ------------------------------------------------------------------ *
|
|
131
147
|
* The chain contract
|
|
132
148
|
*
|
|
@@ -218,14 +234,69 @@ export const STATE_OUT = {
|
|
|
218
234
|
export const PARAM_OUT = {
|
|
219
235
|
/** UI -> wrapper: `get_param_id <id>` - what is this parameter's LOM id? Reply on `param_id`. */
|
|
220
236
|
get_param_id: "get_param_id",
|
|
237
|
+
/** UI -> wrapper: `param_label <id> <name>` - rename the dial on the device panel. */
|
|
238
|
+
param_label: "param_label",
|
|
239
|
+
/** UI -> wrapper: `param_unit <id> <unit>` - how Live PRINTS the value. */
|
|
240
|
+
param_unit: "param_unit",
|
|
241
|
+
/** UI -> wrapper: `param_range <id> <lo> <hi>` - the dial's travel. Answered. */
|
|
242
|
+
param_range: "param_range",
|
|
221
243
|
} as const;
|
|
222
244
|
|
|
223
245
|
/** ...and the reply. */
|
|
224
246
|
export const PARAM_IN = {
|
|
225
247
|
/** wrapper -> UI: `param_id <id> <lomId>` - 0 means no parameter of that name resolved. */
|
|
226
248
|
param_id: "param_id",
|
|
249
|
+
/** wrapper -> UI: `param_range_ok <id>` - Live took the range; the parameter now carries it. */
|
|
250
|
+
param_range_ok: "param_range_ok",
|
|
251
|
+
/** wrapper -> UI: `param_range_failed <id>` - it did not; the parameter is still as declared. */
|
|
252
|
+
param_range_failed: "param_range_failed",
|
|
253
|
+
/** wrapper -> device view: `param_desc <id> <name>` - what some page called this parameter. */
|
|
254
|
+
param_desc: "param_desc",
|
|
255
|
+
/** wrapper -> device view: `param_desc_range <id> <lo> <hi> <took>` - and its travel. */
|
|
256
|
+
param_desc_range: "param_desc_range",
|
|
227
257
|
} as const;
|
|
228
258
|
|
|
259
|
+
/**
|
|
260
|
+
* Say what a parameter IS, at runtime: its name, how Live should print it, and the
|
|
261
|
+
* travel it should have.
|
|
262
|
+
*
|
|
263
|
+
* A surface declares all three at BUILD time, which is right when the device knows
|
|
264
|
+
* what its controls do. It does not when the control is whatever the user's code
|
|
265
|
+
* just asked for - a pattern's `slider()`, a modulation slot pointed at something
|
|
266
|
+
* new - and then the dial reads `S1`, travels 0..1 and says nothing about the sound
|
|
267
|
+
* it is moving.
|
|
268
|
+
*
|
|
269
|
+
* ------------------------------------------------------------------------------
|
|
270
|
+
* WHAT TAKES, AND WHAT DOES NOT - measured in Live, not assumed.
|
|
271
|
+
*
|
|
272
|
+
* `name` reaches the DEVICE PANEL. It does NOT reach Live's parameter registry or
|
|
273
|
+
* the Rack macro picker, which keep the declared short name: a frozen
|
|
274
|
+
* device cannot rename a parameter there.
|
|
275
|
+
* `unit` takes. It is the unit STYLE, so the readout says "600 Hz" and not "600";
|
|
276
|
+
* anything outside Max's list becomes a custom unit and still prints.
|
|
277
|
+
* `range` takes, AND CHANGES THE DOMAIN THE PARAMETER REPORTS. That is the trap:
|
|
278
|
+
* a page that goes on normalizing 0..1 will scale a value that is already
|
|
279
|
+
* scaled, and the control sticks at its minimum. So the wrapper ANSWERS -
|
|
280
|
+
* `param_range_ok` or `param_range_failed` - and the caller must stop
|
|
281
|
+
* normalizing when it took. `onParamRange()` below is that answer.
|
|
282
|
+
*/
|
|
283
|
+
export function describeParam(id: string, desc: { name?: string; unit?: string; range?: [number, number] }): void {
|
|
284
|
+
if (desc.name) outlet(PARAM_OUT.param_label, id, desc.name);
|
|
285
|
+
if (desc.unit) outlet(PARAM_OUT.param_unit, id, desc.unit);
|
|
286
|
+
if (desc.range && desc.range[1] > desc.range[0]) outlet(PARAM_OUT.param_range, id, desc.range[0], desc.range[1]);
|
|
287
|
+
}
|
|
288
|
+
|
|
289
|
+
/**
|
|
290
|
+
* Hear whether a `describeParam` range took, per parameter.
|
|
291
|
+
*
|
|
292
|
+
* Until this says yes, the parameter is still in its declared domain and the page
|
|
293
|
+
* owns the scaling. Exactly one scaling, wherever it ends up living.
|
|
294
|
+
*/
|
|
295
|
+
export function onParamRange(fn: (id: string, took: boolean) => void): void {
|
|
296
|
+
bindInlet(PARAM_IN.param_range_ok, (id) => fn(String(id), true));
|
|
297
|
+
bindInlet(PARAM_IN.param_range_failed, (id) => fn(String(id), false));
|
|
298
|
+
}
|
|
299
|
+
|
|
229
300
|
/**
|
|
230
301
|
* Selectors the WRAPPER handles for reading and writing the CLIP on this device's
|
|
231
302
|
* track (`read_notes`/`write_clip` in liveapi.ts). Wrapper-owned, like DEVICE_IN -
|
|
@@ -470,7 +541,8 @@ export function saveToFile(destPath: string, bytes: ArrayBuffer): Promise<{ byte
|
|
|
470
541
|
* running set, not names: they are not stable across a set reload, so an id saved
|
|
471
542
|
* yesterday points at whatever occupies that slot today - or at nothing. Persist how
|
|
472
543
|
* you FOUND the parameter (the device's position, the parameter's name) and resolve it
|
|
473
|
-
* again
|
|
544
|
+
* again. (Translate mode's reconciler followed the same rule; that mode was settled as
|
|
545
|
+
* adopt-only, permanently - Live's Browser is unreachable from [js].)
|
|
474
546
|
*/
|
|
475
547
|
export function bindRemote(slot: number, lomId: number | string): void {
|
|
476
548
|
outlet(CHAIN_OUT.remote_bind, slot, lomId);
|