@viji-dev/core 0.8.16 → 0.9.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/README.md +30 -24
- package/dist/artist-dts-p5.js +1 -1
- package/dist/artist-dts.js +1 -1
- package/dist/artist-global-p5.d.ts +1 -1
- package/dist/artist-global.d.ts +1 -1
- package/dist/assets/{viji.worker-BEba5y4h.js → viji.worker-DYCbS06e.js} +205 -191
- package/dist/docs-api.js +2 -2
- package/dist/{essentia-wasm.web-Bt54HQaY.js → essentia-wasm.web-OmHe6rAT.js} +2 -2
- package/dist/{index-f5EKzN3f.js → index-CAx7Pxyl.js} +869 -513
- package/dist/index.d.ts +137 -47
- package/dist/index.js +1 -1
- package/package.json +2 -1
package/dist/index.d.ts
CHANGED
|
@@ -307,7 +307,9 @@ export declare class AudioSystem {
|
|
|
307
307
|
private debugLog;
|
|
308
308
|
private fftSize;
|
|
309
309
|
private audioStateBeat;
|
|
310
|
-
private
|
|
310
|
+
private analysisSinks;
|
|
311
|
+
private latestChannelResults;
|
|
312
|
+
private channelMeta;
|
|
311
313
|
constructor(sendAnalysisResultsCallback?: (data: any) => void);
|
|
312
314
|
/**
|
|
313
315
|
* Get the current audio analysis state (for host-side usage)
|
|
@@ -420,6 +422,23 @@ export declare class AudioSystem {
|
|
|
420
422
|
* Tags with streamIndex and conditionally includes beat data (main channel only).
|
|
421
423
|
*/
|
|
422
424
|
private sendChannelResults;
|
|
425
|
+
/**
|
|
426
|
+
* Register a result-delivery sink (one per attached core's worker) and
|
|
427
|
+
* replay current state to it in FIFO order: the latest main-channel
|
|
428
|
+
* analysis, then per non-main channel its `audio-stream-setup` identity
|
|
429
|
+
* followed by the latest cached analysis. A mid-stream attach is thereby
|
|
430
|
+
* indistinguishable from a fresh connect on the receiving worker.
|
|
431
|
+
*/
|
|
432
|
+
addSink(id: string, send: (message: {
|
|
433
|
+
type: string;
|
|
434
|
+
data: any;
|
|
435
|
+
}) => void): void;
|
|
436
|
+
/**
|
|
437
|
+
* Remove a previously registered result-delivery sink.
|
|
438
|
+
*/
|
|
439
|
+
removeSink(id: string): void;
|
|
440
|
+
private buildStreamSetupMessage;
|
|
441
|
+
private emitStreamSetup;
|
|
423
442
|
/**
|
|
424
443
|
* Reset audio values to defaults (main channel + beat state)
|
|
425
444
|
*/
|
|
@@ -436,17 +455,25 @@ export declare class AudioSystem {
|
|
|
436
455
|
resetAudioState(): Promise<void>;
|
|
437
456
|
/**
|
|
438
457
|
* Add an additional audio stream (lightweight analysis, no beat detection).
|
|
439
|
-
*
|
|
458
|
+
* When `meta` is provided, the stream identity is recorded and an
|
|
459
|
+
* `audio-stream-setup` message is emitted to every sink (and replayed to
|
|
460
|
+
* sinks attached later).
|
|
461
|
+
* @param streamIndex Global stream index (AUDIO_ADDITIONAL_BASE + n or AUDIO_DEVICE_BASE + n)
|
|
440
462
|
* @param stream The MediaStream to analyze
|
|
463
|
+
* @param meta Stream identity for the worker-side two-phase setup protocol
|
|
441
464
|
*/
|
|
442
|
-
addStream(streamIndex: number, stream: MediaStream
|
|
465
|
+
addStream(streamIndex: number, stream: MediaStream, meta?: {
|
|
466
|
+
streamType: 'additional' | 'device';
|
|
467
|
+
deviceId?: string;
|
|
468
|
+
}): Promise<void>;
|
|
443
469
|
/**
|
|
444
470
|
* Remove an additional audio stream.
|
|
445
471
|
*/
|
|
446
472
|
removeStream(streamIndex: number): void;
|
|
447
473
|
/**
|
|
448
|
-
* Tear down all additional channels and rebuild with
|
|
449
|
-
*
|
|
474
|
+
* Tear down all additional channels in the base range and rebuild with
|
|
475
|
+
* corrected indices, re-emitting `audio-stream-setup` for the re-indexed
|
|
476
|
+
* streams. Mirrors video's reinitializeAdditionalCoordinators pattern.
|
|
450
477
|
*/
|
|
451
478
|
reinitializeAdditionalChannels(streams: MediaStream[], baseIndex: number): Promise<void>;
|
|
452
479
|
/**
|
|
@@ -2665,7 +2692,7 @@ declare type TrackingState = 'TRACKING' | 'LOCKED' | 'BREAKDOWN' | 'LOST';
|
|
|
2665
2692
|
/** Returned by `on*` listener registration calls; invoke to unsubscribe. */
|
|
2666
2693
|
export declare type Unsubscribe = () => void;
|
|
2667
2694
|
|
|
2668
|
-
export declare const VERSION = "0.
|
|
2695
|
+
export declare const VERSION = "0.9.0";
|
|
2669
2696
|
|
|
2670
2697
|
/**
|
|
2671
2698
|
* Real-time video API: drawable frame, dimensions, and the source-side
|
|
@@ -3024,7 +3051,6 @@ export declare class VijiCore {
|
|
|
3024
3051
|
private workerManager;
|
|
3025
3052
|
private interactionManager;
|
|
3026
3053
|
private deviceSensorManager;
|
|
3027
|
-
private audioSystem;
|
|
3028
3054
|
private isInitialized;
|
|
3029
3055
|
private isDestroyed;
|
|
3030
3056
|
private isInitializing;
|
|
@@ -3038,23 +3064,10 @@ export declare class VijiCore {
|
|
|
3038
3064
|
private debugLog;
|
|
3039
3065
|
private config;
|
|
3040
3066
|
private isHeadless;
|
|
3041
|
-
private currentAudioStream;
|
|
3042
|
-
private static readonly ADDITIONAL_STREAM_BASE;
|
|
3043
|
-
private static readonly DEVICE_VIDEO_BASE;
|
|
3044
3067
|
private static readonly DIRECT_FRAME_BASE;
|
|
3045
|
-
private
|
|
3046
|
-
private
|
|
3047
|
-
private static readonly MAX_ADDITIONAL_AUDIO_STREAMS;
|
|
3048
|
-
private static readonly MAX_ADDITIONAL_VIDEO_STREAMS;
|
|
3049
|
-
private videoStream;
|
|
3050
|
-
private videoStreams;
|
|
3051
|
-
private audioStreams;
|
|
3052
|
-
private deviceAudioStreamIndices;
|
|
3053
|
-
private mainVideoCoordinator;
|
|
3054
|
-
private additionalCoordinators;
|
|
3068
|
+
private engineGroup;
|
|
3069
|
+
private groupMember;
|
|
3055
3070
|
private directFrameSlots;
|
|
3056
|
-
private deviceVideoCoordinators;
|
|
3057
|
-
private deviceVideoStreamIndices;
|
|
3058
3071
|
private latestFrameBuffer;
|
|
3059
3072
|
private autoCaptureEnabled;
|
|
3060
3073
|
private eventSourceCore;
|
|
@@ -3367,27 +3380,33 @@ export declare class VijiCore {
|
|
|
3367
3380
|
code: string;
|
|
3368
3381
|
}) => void): void;
|
|
3369
3382
|
/**
|
|
3370
|
-
* Snapshot the full audio analysis + onset state for cross-
|
|
3371
|
-
* transfer.
|
|
3372
|
-
* `
|
|
3383
|
+
* Snapshot the full audio analysis + onset state for **cross-device**
|
|
3384
|
+
* transfer (e.g. host → second host, multi-machine sync). Pair with
|
|
3385
|
+
* `importFullState` on the receiver, applying an NTP-derived `clockOffset`.
|
|
3386
|
+
*
|
|
3387
|
+
* NOT needed for same-process transitions: construct the successor core
|
|
3388
|
+
* with `{ mediaSource: oldCore }` instead — the shared audio engine (and
|
|
3389
|
+
* its live BPM lock / onset patterns) survives the swap with no
|
|
3390
|
+
* export/import step and no warm-up gap.
|
|
3373
3391
|
*
|
|
3374
|
-
* For
|
|
3392
|
+
* For controller → host onset sync, prefer `audio.onset.exportSessionState`
|
|
3375
3393
|
* — the controller's audio analysis state doesn't apply to the host's
|
|
3376
3394
|
* audio source and would corrupt detection.
|
|
3377
3395
|
*
|
|
3378
3396
|
* Wall-clock fields are in this instance's `performance.now()` clock space.
|
|
3379
|
-
* Receiver applies `clockOffset` on import (use `0` for same-process).
|
|
3380
3397
|
*
|
|
3381
|
-
* **Staleness caveat**: the audio block is robust to
|
|
3382
|
-
* ~1 second. Longer gaps (>5s, e.g.
|
|
3398
|
+
* **Staleness caveat**: the audio block is robust to transfer gaps under
|
|
3399
|
+
* ~1 second. Longer gaps (>5s, e.g. slow network) may cause
|
|
3383
3400
|
* stale-timestamp drift in `gridLockMemoryTime` / `warmupStartTimeMs`;
|
|
3384
3401
|
* callers should treat that as a degraded path and skip the audio block.
|
|
3385
3402
|
*/
|
|
3386
3403
|
exportFullState(): SerializedCoreState;
|
|
3387
3404
|
/**
|
|
3388
|
-
* Replace the audio analysis + onset state from a serialized payload
|
|
3389
|
-
*
|
|
3390
|
-
*
|
|
3405
|
+
* Replace the audio analysis + onset state from a serialized payload
|
|
3406
|
+
* (**cross-device** transfer — for same-process transitions use
|
|
3407
|
+
* `mediaSource` instead, see {@link exportFullState}).
|
|
3408
|
+
* `clockOffset` is added to all sender-clocked fields (NTP-derived;
|
|
3409
|
+
* `0` only when clocks are genuinely shared). Mutation is synchronous.
|
|
3391
3410
|
*
|
|
3392
3411
|
* Field-level events (`onModeChange`, `onMuteChange`) fire when imported
|
|
3393
3412
|
* values differ from current — consumer-visible state stays consistent
|
|
@@ -3495,57 +3514,76 @@ export declare class VijiCore {
|
|
|
3495
3514
|
*/
|
|
3496
3515
|
setAudioStream(audioStream: MediaStream | null): Promise<void>;
|
|
3497
3516
|
/**
|
|
3498
|
-
* Sets the main video stream (CV enabled)
|
|
3517
|
+
* Sets the main video stream (CV enabled).
|
|
3518
|
+
*
|
|
3519
|
+
* Engine-level write: visible to ALL cores sharing this core's media
|
|
3520
|
+
* engines — each attached core's worker gets its own fresh capture for the
|
|
3521
|
+
* new stream. Capability change notifications fan out to all of them.
|
|
3499
3522
|
*/
|
|
3500
3523
|
setVideoStream(stream: MediaStream | null): Promise<void>;
|
|
3501
3524
|
/**
|
|
3502
|
-
* Gets the main video stream
|
|
3525
|
+
* Gets the main video stream (engine-scoped — identical for all cores
|
|
3526
|
+
* sharing this core's media engines)
|
|
3503
3527
|
*/
|
|
3504
3528
|
getVideoStream(): MediaStream | null;
|
|
3505
3529
|
/**
|
|
3506
3530
|
* Adds an additional video stream (no CV). Returns its index in viji.videoStreams[].
|
|
3531
|
+
*
|
|
3532
|
+
* Engine-level write: the stream appears in `viji.videoStreams[]` of EVERY
|
|
3533
|
+
* core sharing this core's media engines.
|
|
3507
3534
|
*/
|
|
3508
3535
|
addVideoStream(stream: MediaStream): Promise<number>;
|
|
3509
3536
|
/**
|
|
3510
|
-
* Removes an additional video stream by index.
|
|
3537
|
+
* Removes an additional video stream by index. Stops the stream's tracks.
|
|
3538
|
+
*
|
|
3539
|
+
* Engine-level write: removal (and the resulting re-indexing) is visible to
|
|
3540
|
+
* ALL cores sharing this core's media engines.
|
|
3511
3541
|
*/
|
|
3512
3542
|
removeVideoStream(index: number): Promise<void>;
|
|
3513
3543
|
/**
|
|
3514
|
-
* Gets the number of additional video streams.
|
|
3544
|
+
* Gets the number of additional video streams (engine-scoped).
|
|
3515
3545
|
*/
|
|
3516
3546
|
getVideoStreamCount(): number;
|
|
3517
3547
|
/**
|
|
3518
3548
|
* Add an additional audio stream for lightweight analysis (no beat detection).
|
|
3549
|
+
*
|
|
3550
|
+
* Engine-level write: the stream appears in `viji.audioStreams[]` of EVERY
|
|
3551
|
+
* core sharing this core's media engines.
|
|
3519
3552
|
* @param stream MediaStream with audio tracks
|
|
3520
3553
|
* @returns Index of the new stream (0-based within additional streams)
|
|
3521
3554
|
* @throws VijiCoreError if limit reached (max 8)
|
|
3522
3555
|
*/
|
|
3523
3556
|
addAudioStream(stream: MediaStream): Promise<number>;
|
|
3524
3557
|
/**
|
|
3525
|
-
* Remove an additional audio stream by index.
|
|
3526
|
-
*
|
|
3558
|
+
* Remove an additional audio stream by index. Stops the stream's tracks
|
|
3559
|
+
* and triggers re-indexing of remaining streams.
|
|
3560
|
+
*
|
|
3561
|
+
* Engine-level write: removal is visible to ALL cores sharing this core's
|
|
3562
|
+
* media engines.
|
|
3527
3563
|
*/
|
|
3528
3564
|
removeAudioStream(index: number): Promise<void>;
|
|
3529
3565
|
/**
|
|
3530
|
-
* Gets the number of additional audio streams.
|
|
3566
|
+
* Gets the number of additional audio streams (engine-scoped).
|
|
3531
3567
|
*/
|
|
3532
3568
|
getAudioStreamCount(): number;
|
|
3533
3569
|
/**
|
|
3534
3570
|
* Set audio stream from an external device.
|
|
3571
|
+
*
|
|
3572
|
+
* Engine-level write: visible to ALL cores sharing this core's media
|
|
3573
|
+
* engines. Device registration (`addExternalDevice`) stays per-core.
|
|
3535
3574
|
* @param deviceId Device identifier (must be registered via addExternalDevice)
|
|
3536
3575
|
* @param stream MediaStream with audio tracks from the device
|
|
3537
3576
|
*/
|
|
3538
3577
|
setDeviceAudio(deviceId: string, stream: MediaStream): Promise<void>;
|
|
3539
3578
|
/**
|
|
3540
3579
|
* Clear audio stream from a device.
|
|
3580
|
+
*
|
|
3581
|
+
* Engine-level write: visible to ALL cores sharing this core's media engines.
|
|
3541
3582
|
*/
|
|
3542
3583
|
clearDeviceAudio(deviceId: string): Promise<void>;
|
|
3543
3584
|
/**
|
|
3544
|
-
*
|
|
3545
|
-
|
|
3546
|
-
private reinitializeAdditionalCoordinators;
|
|
3547
|
-
/**
|
|
3548
|
-
* Gets the current audio stream
|
|
3585
|
+
* Gets the current audio stream (engine-scoped — identical for all cores
|
|
3586
|
+
* sharing this core's media engines)
|
|
3549
3587
|
*/
|
|
3550
3588
|
getAudioStream(): MediaStream | null;
|
|
3551
3589
|
/**
|
|
@@ -3556,6 +3594,16 @@ export declare class VijiCore {
|
|
|
3556
3594
|
* Gets the current interaction enabled state
|
|
3557
3595
|
*/
|
|
3558
3596
|
getInteractionEnabled(): boolean;
|
|
3597
|
+
/**
|
|
3598
|
+
* Lazy audio-engine access. Read-only getters use `audioEngine` (never
|
|
3599
|
+
* materializes — headless previews construct nothing); every other
|
|
3600
|
+
* `core.audio.*` call uses `ensureAudioEngine()` (materialize-on-use:
|
|
3601
|
+
* mutators, subscriptions, imports AND exports — a listener registered or
|
|
3602
|
+
* a tap received before any stream exists must hit a live engine, see the
|
|
3603
|
+
* constructor-started idle ticker in AudioSystem).
|
|
3604
|
+
*/
|
|
3605
|
+
private get audioEngine();
|
|
3606
|
+
private ensureAudioEngine;
|
|
3559
3607
|
readonly audio: {
|
|
3560
3608
|
/**
|
|
3561
3609
|
* Beat control namespace
|
|
@@ -3637,6 +3685,11 @@ export declare class VijiCore {
|
|
|
3637
3685
|
*
|
|
3638
3686
|
* Idempotent transitions (already in target mode) do not fire.
|
|
3639
3687
|
*
|
|
3688
|
+
* Engine-level: the listener registry lives on the shared audio engine,
|
|
3689
|
+
* so subscribing through several cores that share media engines targets
|
|
3690
|
+
* ONE registry — subscribe once per app. The same function reference is
|
|
3691
|
+
* deduped by identity; distinct closures doing the same work are not.
|
|
3692
|
+
*
|
|
3640
3693
|
* @returns Unsubscribe function. Call to remove the listener.
|
|
3641
3694
|
*/
|
|
3642
3695
|
onModeChange: (listener: (ev: OnsetModeChangeEvent) => void) => Unsubscribe;
|
|
@@ -3656,6 +3709,9 @@ export declare class VijiCore {
|
|
|
3656
3709
|
* when fields differ; this event does not because session-end is a
|
|
3657
3710
|
* different category — about session lifecycle, not field state.
|
|
3658
3711
|
*
|
|
3712
|
+
* Engine-level: one registry per shared audio engine — subscribe once
|
|
3713
|
+
* per app (see {@link onModeChange}).
|
|
3714
|
+
*
|
|
3659
3715
|
* @returns Unsubscribe function. Call to remove the listener.
|
|
3660
3716
|
*/
|
|
3661
3717
|
onSessionEnd: (listener: (ev: OnsetSessionEndEvent) => void) => Unsubscribe;
|
|
@@ -3671,6 +3727,9 @@ export declare class VijiCore {
|
|
|
3671
3727
|
* Idempotent calls (e.g. `setMuted(true)` on an already-muted instrument)
|
|
3672
3728
|
* do not fire.
|
|
3673
3729
|
*
|
|
3730
|
+
* Engine-level: one registry per shared audio engine — subscribe once
|
|
3731
|
+
* per app (see {@link onModeChange}).
|
|
3732
|
+
*
|
|
3674
3733
|
* @returns Unsubscribe function. Call to remove the listener.
|
|
3675
3734
|
*/
|
|
3676
3735
|
onMuteChange: (listener: (ev: OnsetMuteChangeEvent) => void) => Unsubscribe;
|
|
@@ -3717,7 +3776,11 @@ export declare class VijiCore {
|
|
|
3717
3776
|
importSessionState: (state: SerializedOnsetState, clockOffset: number) => void;
|
|
3718
3777
|
};
|
|
3719
3778
|
/**
|
|
3720
|
-
* Advanced audio controls
|
|
3779
|
+
* Advanced audio controls.
|
|
3780
|
+
*
|
|
3781
|
+
* Engine-level: these settings live on the shared audio engine and are
|
|
3782
|
+
* visible to ALL cores sharing this core's media engines (same rule as
|
|
3783
|
+
* the stream mutators).
|
|
3721
3784
|
*/
|
|
3722
3785
|
advanced: {
|
|
3723
3786
|
/**
|
|
@@ -3939,12 +4002,20 @@ export declare class VijiCore {
|
|
|
3939
4002
|
/**
|
|
3940
4003
|
* Set video stream for an external device
|
|
3941
4004
|
* Device camera will appear in viji.devices[].video
|
|
4005
|
+
*
|
|
4006
|
+
* Engine-level write: every core sharing this core's media engines gets
|
|
4007
|
+
* its own capture of the device stream. Device registration
|
|
4008
|
+
* (`addExternalDevice`) and sensor state stay per-core, so each attached
|
|
4009
|
+
* core's host app registers the device on that core — the worker
|
|
4010
|
+
* self-heals whichever of stream/registration arrives last.
|
|
3942
4011
|
* @param deviceId - Device identifier
|
|
3943
4012
|
* @param stream - MediaStream from device camera
|
|
3944
4013
|
*/
|
|
3945
4014
|
setDeviceVideo(deviceId: string, stream: MediaStream): Promise<void>;
|
|
3946
4015
|
/**
|
|
3947
4016
|
* Clear video stream from device
|
|
4017
|
+
*
|
|
4018
|
+
* Engine-level write: visible to ALL cores sharing this core's media engines.
|
|
3948
4019
|
* @param deviceId - Device identifier
|
|
3949
4020
|
*/
|
|
3950
4021
|
clearDeviceVideo(deviceId: string): Promise<void>;
|
|
@@ -4004,8 +4075,27 @@ export declare interface VijiCoreConfig {
|
|
|
4004
4075
|
videoStreams?: MediaStream[];
|
|
4005
4076
|
/** Additional audio input streams (lightweight analysis, no beat detection) */
|
|
4006
4077
|
audioStreams?: MediaStream[];
|
|
4007
|
-
/**
|
|
4008
|
-
|
|
4078
|
+
/**
|
|
4079
|
+
* Share another core's media analysis engines instead of creating private
|
|
4080
|
+
* ones. The new core attaches to the referenced core's engine group at
|
|
4081
|
+
* construction time and detaches on `destroy()`; the engines (audio
|
|
4082
|
+
* analysis, video capture) survive as long as ANY attached core is alive,
|
|
4083
|
+
* so analysis state (BPM lock, onset patterns, stream connections) carries
|
|
4084
|
+
* across core transitions with no export/import step.
|
|
4085
|
+
*
|
|
4086
|
+
* Mutually exclusive with `audioStream`, `videoStream`, `audioStreams`,
|
|
4087
|
+
* and `videoStreams` — the engine group already owns the streams.
|
|
4088
|
+
*
|
|
4089
|
+
* Stream mutators (`setAudioStream`, `setVideoStream`, `addAudioStream`,
|
|
4090
|
+
* `setDeviceAudio`, …) called on ANY attached core write to the shared
|
|
4091
|
+
* engines and are visible to ALL attached cores.
|
|
4092
|
+
*
|
|
4093
|
+
* The referenced core must not be destroyed and must not have a fenced
|
|
4094
|
+
* benchmark in flight (`BENCHMARK_NOT_ALLOWED`). The reference is resolved
|
|
4095
|
+
* to the engine group at construction; it is not retained afterwards and
|
|
4096
|
+
* is omitted from the `configuration` getter.
|
|
4097
|
+
*/
|
|
4098
|
+
mediaSource?: VijiCore;
|
|
4009
4099
|
/** Enable user interaction events (DOM event capture, disabled in headless by default) */
|
|
4010
4100
|
allowUserInteraction?: boolean;
|
|
4011
4101
|
/** Enable device sensor APIs (motion, orientation) */
|
package/dist/index.js
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@viji-dev/core",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.9.0",
|
|
4
4
|
"description": "Universal execution engine for Viji Creative scenes",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.js",
|
|
@@ -49,6 +49,7 @@
|
|
|
49
49
|
],
|
|
50
50
|
"scripts": {
|
|
51
51
|
"prebuild": "node scripts/prebuild-clean.mjs && node scripts/sync-version.mjs",
|
|
52
|
+
"version": "npm run build && git add -A",
|
|
52
53
|
"build": "vite build && node scripts/copy-tasks-assets.mjs && node scripts/build-artist-types.mjs && node scripts/build-docs-api.mjs",
|
|
53
54
|
"build:docs": "node scripts/build-docs-api.mjs",
|
|
54
55
|
"lint:ai-prompts-drift": "node scripts/lint-ai-prompts-drift.mjs",
|