@cyberart-io/engine 0.0.5 → 0.0.7
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 +117 -14
- package/dist/headless.d.ts +483 -6
- package/dist/headless.js +1 -1
- package/dist/index.d.ts +883 -6
- package/dist/index.js +1 -1
- package/docs/audio.md +152 -0
- package/docs/calculation-carts.md +134 -0
- package/docs/capability-manifest.md +5 -2
- package/docs/compositor.md +8 -3
- package/docs/executable-modules.md +112 -0
- package/docs/midi.md +128 -0
- package/docs/runtime-group.md +3 -3
- package/docs/snapshots.md +102 -0
- package/docs/visual-layers.md +151 -0
- package/package.json +1 -1
package/dist/headless.d.ts
CHANGED
|
@@ -254,11 +254,16 @@ type AnimationTiming = {
|
|
|
254
254
|
deltaSinceLastUpdate: number;
|
|
255
255
|
deltaSinceLastRender: number;
|
|
256
256
|
};
|
|
257
|
+
type CartKind = 'render' | 'calculation';
|
|
257
258
|
type AnimationCart<T = unknown, TFeatureState = undefined> = {
|
|
258
259
|
getDefaultFeatureState?: (R: Random, dimensionContext: DimensionContext, rawParams: number[], keyboardManager: KeyboardManager, customState?: Partial<T>, pointerManager?: PointerManager, gameManager?: unknown, hostChannel?: HostChannel) => TFeatureState;
|
|
259
260
|
getDefaultState: (R: Random, dimensionContext: DimensionContext, rawParams: number[], keyboardManager: KeyboardManager, customState?: Partial<T>, pointerManager?: PointerManager, gameManager?: unknown, featureState?: Readonly<TFeatureState>, hostChannel?: HostChannel) => T;
|
|
260
261
|
update: (R: Random, framesElapsed: number, rawParams: number[], dimensionContext: DimensionContext, state: T, keyboardManager: KeyboardManager, pointerManager?: PointerManager, gameManager?: unknown, timing?: AnimationTiming, featureState?: Readonly<TFeatureState>, hostChannel?: HostChannel) => T;
|
|
261
|
-
|
|
262
|
+
/**
|
|
263
|
+
* Draw into the 2D context. Optional on calculation carts (`kind:
|
|
264
|
+
* 'calculation'`); the runtime does not call it and does not create a canvas.
|
|
265
|
+
*/
|
|
266
|
+
render?: (R: Random, framesElapsed: number, rawParams: number[], dimensionContext: DimensionContext, state: T, drawingContext: CanvasRenderingContext2D, imageData: ImageData, pointerManager?: PointerManager, gameManager?: unknown, timing?: AnimationTiming, featureState?: Readonly<TFeatureState>, hostChannel?: HostChannel) => void;
|
|
262
267
|
adjust?: Record<string, {
|
|
263
268
|
type: 'switch';
|
|
264
269
|
immediate?: boolean;
|
|
@@ -328,6 +333,76 @@ type CartStateBundle = {
|
|
|
328
333
|
state: unknown;
|
|
329
334
|
};
|
|
330
335
|
|
|
336
|
+
/**
|
|
337
|
+
* Copyright (c) 2026 Aaron Boyarsky
|
|
338
|
+
* SPDX-License-Identifier: LicenseRef-CyberArt-Engine
|
|
339
|
+
* See packages/engine/LICENSE
|
|
340
|
+
*
|
|
341
|
+
* Versioned snapshot envelope. Schema 1 is the previous engine-owned
|
|
342
|
+
* `CartStateBundle` (`CART_STATE_BUNDLE_VERSION = 1`). Schema 2 wraps that
|
|
343
|
+
* blob in `engineState` and separates host-owned payload. Hosts persist
|
|
344
|
+
* the JSON; this module is not a database.
|
|
345
|
+
*/
|
|
346
|
+
|
|
347
|
+
/**
|
|
348
|
+
* Current envelope schema. Independent of `CART_STATE_BUNDLE_VERSION` (still
|
|
349
|
+
* 1 inside `engineState`) and of the npm package version.
|
|
350
|
+
*/
|
|
351
|
+
declare const SNAPSHOT_SCHEMA_VERSION: 2;
|
|
352
|
+
type SnapshotCartRef = {
|
|
353
|
+
id: string;
|
|
354
|
+
version: string;
|
|
355
|
+
generative?: boolean;
|
|
356
|
+
};
|
|
357
|
+
type SnapshotModuleRef = {
|
|
358
|
+
id: string;
|
|
359
|
+
version: string;
|
|
360
|
+
};
|
|
361
|
+
type SnapshotClock = {
|
|
362
|
+
framesElapsed: number;
|
|
363
|
+
elapsedSinceStart?: number;
|
|
364
|
+
now?: number;
|
|
365
|
+
frameRate?: number;
|
|
366
|
+
};
|
|
367
|
+
type SnapshotAssetRef = {
|
|
368
|
+
id: string;
|
|
369
|
+
version?: string;
|
|
370
|
+
ref?: string;
|
|
371
|
+
};
|
|
372
|
+
type SnapshotIntegrity = {
|
|
373
|
+
alg: string;
|
|
374
|
+
hash: string;
|
|
375
|
+
};
|
|
376
|
+
type SnapshotProvenance = {
|
|
377
|
+
source?: string;
|
|
378
|
+
integrity?: SnapshotIntegrity;
|
|
379
|
+
};
|
|
380
|
+
type SnapshotEnvelope = {
|
|
381
|
+
schemaVersion: typeof SNAPSHOT_SCHEMA_VERSION;
|
|
382
|
+
runtimeVersion: string;
|
|
383
|
+
cart: SnapshotCartRef;
|
|
384
|
+
seed: string;
|
|
385
|
+
clock: SnapshotClock;
|
|
386
|
+
engineState: CartStateBundle;
|
|
387
|
+
createdAt: string;
|
|
388
|
+
modules?: SnapshotModuleRef[];
|
|
389
|
+
rng?: RandomState;
|
|
390
|
+
hostState?: unknown;
|
|
391
|
+
hostStateRef?: string;
|
|
392
|
+
assets?: SnapshotAssetRef[];
|
|
393
|
+
provenance?: SnapshotProvenance;
|
|
394
|
+
};
|
|
395
|
+
type ExportSnapshotOptions = {
|
|
396
|
+
cartVersion?: string;
|
|
397
|
+
modules?: SnapshotModuleRef[];
|
|
398
|
+
hostState?: unknown;
|
|
399
|
+
hostStateRef?: string;
|
|
400
|
+
assets?: SnapshotAssetRef[];
|
|
401
|
+
createdAt?: string;
|
|
402
|
+
provenance?: SnapshotProvenance;
|
|
403
|
+
runtimeVersion?: string;
|
|
404
|
+
};
|
|
405
|
+
|
|
331
406
|
/**
|
|
332
407
|
* Copyright (c) 2026 Aaron Boyarsky
|
|
333
408
|
* SPDX-License-Identifier: LicenseRef-CyberArt-Engine
|
|
@@ -475,6 +550,75 @@ type AssetPreloader = {
|
|
|
475
550
|
dispose(): void;
|
|
476
551
|
};
|
|
477
552
|
|
|
553
|
+
type AudioUnlockState = 'locked' | 'unlocking' | 'unlocked' | 'failed';
|
|
554
|
+
type AudioUnlockStatus = {
|
|
555
|
+
state: AudioUnlockState;
|
|
556
|
+
error?: string;
|
|
557
|
+
};
|
|
558
|
+
type AudioAssetStatus = 'ready' | 'failed';
|
|
559
|
+
type AudioChannelInspect = {
|
|
560
|
+
id: string;
|
|
561
|
+
participantId?: string;
|
|
562
|
+
gain: number;
|
|
563
|
+
muted: boolean;
|
|
564
|
+
duckGain: number;
|
|
565
|
+
priority: number;
|
|
566
|
+
effectiveGain: number;
|
|
567
|
+
};
|
|
568
|
+
type AudioBrokerInspect = {
|
|
569
|
+
status: AudioUnlockStatus;
|
|
570
|
+
reducedSensory: boolean;
|
|
571
|
+
muted: boolean;
|
|
572
|
+
authorized: string[];
|
|
573
|
+
channels: AudioChannelInspect[];
|
|
574
|
+
assets: Record<string, AudioAssetStatus>;
|
|
575
|
+
};
|
|
576
|
+
type AudioBrokerNotice = {
|
|
577
|
+
type: 'asset';
|
|
578
|
+
id: string;
|
|
579
|
+
status: AudioAssetStatus;
|
|
580
|
+
} | {
|
|
581
|
+
type: 'teardown';
|
|
582
|
+
participantId: string;
|
|
583
|
+
} | {
|
|
584
|
+
type: 'mute';
|
|
585
|
+
} | {
|
|
586
|
+
type: 'destroy';
|
|
587
|
+
};
|
|
588
|
+
type AudioBrokerListener = (notice: AudioBrokerNotice) => void;
|
|
589
|
+
type ActiveAudioCue = {
|
|
590
|
+
idempotencyKey: string;
|
|
591
|
+
channelId: string;
|
|
592
|
+
participantId?: string;
|
|
593
|
+
priority: number;
|
|
594
|
+
};
|
|
595
|
+
type AudioBroker = {
|
|
596
|
+
unlock(): Promise<AudioUnlockStatus>;
|
|
597
|
+
status(): AudioUnlockStatus;
|
|
598
|
+
authorize(participantId: string): void;
|
|
599
|
+
revoke(participantId: string): void;
|
|
600
|
+
isAuthorized(participantId: string | undefined): boolean;
|
|
601
|
+
setChannelGain(channelId: string, gain: number, participantId?: string): void;
|
|
602
|
+
setPriority(channelId: string, priority: number, participantId?: string): void;
|
|
603
|
+
mute(): void;
|
|
604
|
+
unmute(): void;
|
|
605
|
+
muteChannel(channelId: string, participantId?: string): void;
|
|
606
|
+
unmuteChannel(channelId: string): void;
|
|
607
|
+
duck(channelId: string, gain?: number): void;
|
|
608
|
+
unduck(channelId: string): void;
|
|
609
|
+
effectiveGain(channelId: string): number;
|
|
610
|
+
handleHostEvent(event: HostEvent): void;
|
|
611
|
+
assetStatus(id: string): AudioAssetStatus | undefined;
|
|
612
|
+
noteCueStarted(cue: ActiveAudioCue): void;
|
|
613
|
+
noteCueEnded(idempotencyKey: string): void;
|
|
614
|
+
teardown(participantId: string): void;
|
|
615
|
+
onNotice(listener: AudioBrokerListener): () => void;
|
|
616
|
+
inspect(): AudioBrokerInspect;
|
|
617
|
+
destroy(): void;
|
|
618
|
+
readonly reducedSensory: boolean;
|
|
619
|
+
readonly muted: boolean;
|
|
620
|
+
};
|
|
621
|
+
|
|
478
622
|
/**
|
|
479
623
|
* Copyright (c) 2026 Aaron Boyarsky
|
|
480
624
|
* SPDX-License-Identifier: LicenseRef-CyberArt-Engine
|
|
@@ -519,6 +663,22 @@ type CreateRuntimeOptions = {
|
|
|
519
663
|
* scripted `{ type: 'asset' }` actions own delivery timing.
|
|
520
664
|
*/
|
|
521
665
|
assets?: AssetRuntimeOptions;
|
|
666
|
+
/**
|
|
667
|
+
* Shared page-level unlock broker. Optional. Carts that only set
|
|
668
|
+
* `metadata.audio: 'tone'` keep the existing `start()` / `unlockAudio()`
|
|
669
|
+
* path when this is omitted.
|
|
670
|
+
*/
|
|
671
|
+
audioBroker?: AudioBroker;
|
|
672
|
+
/**
|
|
673
|
+
* Runtime-group participant id to authorize on this runtime. Teardown of
|
|
674
|
+
* this id does not close Tone for remaining carts.
|
|
675
|
+
*/
|
|
676
|
+
audioParticipantId?: string;
|
|
677
|
+
/**
|
|
678
|
+
* `'calculation'` skips canvas construction and paint. `getDefaultState`,
|
|
679
|
+
* `update`, and host-channel events still run. Default `'render'`.
|
|
680
|
+
*/
|
|
681
|
+
kind?: CartKind;
|
|
522
682
|
};
|
|
523
683
|
type MountOptions<T = unknown> = {
|
|
524
684
|
/** Boot overrides passed as `customState` into `getDefaultState`. Not a live-state replay. */
|
|
@@ -549,7 +709,12 @@ type CartHandle = {
|
|
|
549
709
|
getCartState(): unknown;
|
|
550
710
|
exportState(): Promise<CartStateBundle>;
|
|
551
711
|
exportStateJSON(): Promise<string>;
|
|
552
|
-
importState(bundle: CartStateBundle | string, extras?: {
|
|
712
|
+
importState(bundle: CartStateBundle | SnapshotEnvelope | string, extras?: {
|
|
713
|
+
framebuffer?: ImageData | null;
|
|
714
|
+
}): Promise<void>;
|
|
715
|
+
exportSnapshot(options?: ExportSnapshotOptions): Promise<SnapshotEnvelope>;
|
|
716
|
+
exportSnapshotJSON(options?: ExportSnapshotOptions): Promise<string>;
|
|
717
|
+
importSnapshot(input: SnapshotEnvelope | CartStateBundle | string, extras?: {
|
|
553
718
|
framebuffer?: ImageData | null;
|
|
554
719
|
}): Promise<void>;
|
|
555
720
|
peekExportedFramebuffer(): ImageData | null;
|
|
@@ -590,6 +755,10 @@ type CyberArtRuntime = {
|
|
|
590
755
|
* Survives cart remount; `destroy()` disposes it.
|
|
591
756
|
*/
|
|
592
757
|
readonly assets: AssetPreloader | undefined;
|
|
758
|
+
/** Shared broker when `createRuntime({ audioBroker })` was set. */
|
|
759
|
+
readonly audioBroker: AudioBroker | undefined;
|
|
760
|
+
/** `'render'` (default) or `'calculation'` (no canvas / paint). */
|
|
761
|
+
readonly kind: CartKind;
|
|
593
762
|
onError?: (error: unknown, info: FrameErrorInfo) => void;
|
|
594
763
|
};
|
|
595
764
|
|
|
@@ -681,7 +850,7 @@ type EventRouter = {
|
|
|
681
850
|
* locksteps a deterministic clock. Carts never receive the router object.
|
|
682
851
|
*/
|
|
683
852
|
|
|
684
|
-
type RuntimeGroupKind =
|
|
853
|
+
type RuntimeGroupKind = CartKind;
|
|
685
854
|
/**
|
|
686
855
|
* Optional capability-shaped attach hints. Explicit participant `emit` /
|
|
687
856
|
* `subscribe` / `authoritative` win. Do not import the capability manifest
|
|
@@ -699,7 +868,7 @@ type RuntimeGroupFrameError = {
|
|
|
699
868
|
type RuntimeGroupParticipantConfig<T = unknown> = {
|
|
700
869
|
id: string;
|
|
701
870
|
cart: AnimationCart<T>;
|
|
702
|
-
/** Rendered surface vs calculation cart (
|
|
871
|
+
/** Rendered surface vs calculation cart (update + events, no canvas / paint). */
|
|
703
872
|
kind?: RuntimeGroupKind;
|
|
704
873
|
seed?: CreateRuntimeOptions['seed'];
|
|
705
874
|
container?: HTMLElement;
|
|
@@ -726,6 +895,8 @@ type CreateRuntimeGroupOptions = {
|
|
|
726
895
|
router?: EventRouterOptions;
|
|
727
896
|
/** Bound on the accepted-event trace (oldest dropped). Default 1024. */
|
|
728
897
|
maxTrace?: number;
|
|
898
|
+
/** Shared page-level audio unlock broker. Optional. */
|
|
899
|
+
audioBroker?: AudioBroker;
|
|
729
900
|
};
|
|
730
901
|
type RuntimeGroupParticipantInspect = {
|
|
731
902
|
state: unknown;
|
|
@@ -761,6 +932,7 @@ type RuntimeGroup = {
|
|
|
761
932
|
readonly router: EventRouter;
|
|
762
933
|
readonly origin: number;
|
|
763
934
|
readonly paused: boolean;
|
|
935
|
+
readonly audioBroker: AudioBroker | undefined;
|
|
764
936
|
participant(id: string): RuntimeGroupParticipantHandle;
|
|
765
937
|
step(frames?: number): Promise<void>;
|
|
766
938
|
pause(): void;
|
|
@@ -784,6 +956,20 @@ type CompositorBlendMode = (typeof COMPOSITOR_BLEND_MODES)[number];
|
|
|
784
956
|
declare const COMPOSITOR_CLEAR_POLICIES: readonly ["transparent", "opaque"];
|
|
785
957
|
type CompositorClearPolicy = (typeof COMPOSITOR_CLEAR_POLICIES)[number];
|
|
786
958
|
type CompositorPointerEvents = 'auto' | 'none';
|
|
959
|
+
declare const COMPOSITOR_SOURCE_KINDS: readonly ["participant", "image", "canvas"];
|
|
960
|
+
type CompositorSourceKind = (typeof COMPOSITOR_SOURCE_KINDS)[number];
|
|
961
|
+
type CompositorParticipantSource = {
|
|
962
|
+
kind: 'participant';
|
|
963
|
+
};
|
|
964
|
+
type CompositorImageSource = {
|
|
965
|
+
kind: 'image';
|
|
966
|
+
image: ImageData;
|
|
967
|
+
};
|
|
968
|
+
type CompositorCanvasSource = {
|
|
969
|
+
kind: 'canvas';
|
|
970
|
+
canvas: HTMLCanvasElement;
|
|
971
|
+
};
|
|
972
|
+
type CompositorLayerSource = CompositorParticipantSource | CompositorImageSource | CompositorCanvasSource;
|
|
787
973
|
type CompositorClip = {
|
|
788
974
|
x: number;
|
|
789
975
|
y: number;
|
|
@@ -799,6 +985,11 @@ type CompositorLayerConfig = {
|
|
|
799
985
|
clip?: CompositorClip;
|
|
800
986
|
pointerEvents?: CompositorPointerEvents;
|
|
801
987
|
clearPolicy?: CompositorClearPolicy;
|
|
988
|
+
/**
|
|
989
|
+
* Pixel source. Default `participant` reads the runtime-group canvas.
|
|
990
|
+
* `image` / `canvas` swap atomically via `setLayer` / `addLayer`.
|
|
991
|
+
*/
|
|
992
|
+
source?: CompositorLayerSource;
|
|
802
993
|
};
|
|
803
994
|
type CompositorLayerInspect = {
|
|
804
995
|
id: string;
|
|
@@ -809,6 +1000,7 @@ type CompositorLayerInspect = {
|
|
|
809
1000
|
clip: CompositorClip | null;
|
|
810
1001
|
pointerEvents: CompositorPointerEvents;
|
|
811
1002
|
clearPolicy: CompositorClearPolicy;
|
|
1003
|
+
sourceKind: CompositorSourceKind;
|
|
812
1004
|
};
|
|
813
1005
|
type ComposedFrame = {
|
|
814
1006
|
imageData: ImageData;
|
|
@@ -841,6 +1033,7 @@ type Compositor = {
|
|
|
841
1033
|
*/
|
|
842
1034
|
resize(width: number, height: number, dpr?: number): void;
|
|
843
1035
|
setLayer(id: string, patch: Partial<Omit<CompositorLayerConfig, 'id'>>): void;
|
|
1036
|
+
addLayer(config: CompositorLayerConfig): void;
|
|
844
1037
|
layer(id: string): CompositorLayerInspect;
|
|
845
1038
|
layers(): CompositorLayerInspect[];
|
|
846
1039
|
pointerTarget(x: number, y: number): string | undefined;
|
|
@@ -1213,6 +1406,289 @@ declare function replayExportedTrace(exported: ReplayInspectorExport, group: Run
|
|
|
1213
1406
|
report: ReplayInspectorReport;
|
|
1214
1407
|
}>;
|
|
1215
1408
|
|
|
1409
|
+
type CueEasing = 'linear' | 'ease-out';
|
|
1410
|
+
type CueDuplicatePolicy = 'ignore' | 'replace' | 'reject';
|
|
1411
|
+
type CueRepeatPolicy = {
|
|
1412
|
+
count: number;
|
|
1413
|
+
} | {
|
|
1414
|
+
forever: true;
|
|
1415
|
+
};
|
|
1416
|
+
type CueReducedMotionPolicy = 'skip' | 'complete' | {
|
|
1417
|
+
durationFrames: number;
|
|
1418
|
+
};
|
|
1419
|
+
type CueSpec = {
|
|
1420
|
+
name: string;
|
|
1421
|
+
idempotencyKey: string;
|
|
1422
|
+
/** Frame when the cue is eligible to start (before delay). Default: play frame. */
|
|
1423
|
+
startFrame?: number;
|
|
1424
|
+
durationFrames: number;
|
|
1425
|
+
delayFrames?: number;
|
|
1426
|
+
easing?: CueEasing;
|
|
1427
|
+
repeat?: CueRepeatPolicy;
|
|
1428
|
+
/**
|
|
1429
|
+
* When the timeline is in reduced-motion mode: skip (complete immediately),
|
|
1430
|
+
* complete (same), or a shorter duration. Default `complete`.
|
|
1431
|
+
*/
|
|
1432
|
+
reducedMotion?: CueReducedMotionPolicy;
|
|
1433
|
+
onDuplicate?: CueDuplicatePolicy;
|
|
1434
|
+
};
|
|
1435
|
+
type CuePhase = 'scheduled' | 'active' | 'completed' | 'cancelled';
|
|
1436
|
+
type CueView = {
|
|
1437
|
+
name: string;
|
|
1438
|
+
idempotencyKey: string;
|
|
1439
|
+
phase: CuePhase;
|
|
1440
|
+
startFrame: number;
|
|
1441
|
+
durationFrames: number;
|
|
1442
|
+
delayFrames: number;
|
|
1443
|
+
easing: CueEasing;
|
|
1444
|
+
progress: number;
|
|
1445
|
+
repeatIndex: number;
|
|
1446
|
+
};
|
|
1447
|
+
type PlayCueResult = {
|
|
1448
|
+
ok: true;
|
|
1449
|
+
cue: CueView;
|
|
1450
|
+
} | {
|
|
1451
|
+
ok: false;
|
|
1452
|
+
reason: 'duplicate' | 'invalid';
|
|
1453
|
+
detail: string;
|
|
1454
|
+
};
|
|
1455
|
+
|
|
1456
|
+
/**
|
|
1457
|
+
* Copyright (c) 2026 Aaron Boyarsky
|
|
1458
|
+
* SPDX-License-Identifier: LicenseRef-CyberArt-Engine
|
|
1459
|
+
* See packages/engine/LICENSE
|
|
1460
|
+
*
|
|
1461
|
+
* Deterministic audio-cue timeline. Scheduling is frame-stepped via
|
|
1462
|
+
* `createPresentationTimeline`; PCM output is not part of the event trace.
|
|
1463
|
+
*/
|
|
1464
|
+
|
|
1465
|
+
declare const AUDIO_CUE_EVENTS: readonly ["audio.cue.scheduled", "audio.cue.started", "audio.cue.skipped", "audio.cue.failed"];
|
|
1466
|
+
type AudioCueEventType = (typeof AUDIO_CUE_EVENTS)[number];
|
|
1467
|
+
type AudioCueSkipReason = 'reduced-sensory' | 'muted' | 'unauthorized';
|
|
1468
|
+
type AudioCueFailReason = 'asset-failed' | 'torn-down' | 'invalid';
|
|
1469
|
+
type AudioCueReason = AudioCueSkipReason | AudioCueFailReason;
|
|
1470
|
+
type AudioCueSpec = CueSpec & {
|
|
1471
|
+
assetId: string;
|
|
1472
|
+
channelId?: string;
|
|
1473
|
+
participantId?: string;
|
|
1474
|
+
priority?: number;
|
|
1475
|
+
gain?: number;
|
|
1476
|
+
};
|
|
1477
|
+
type AudioCueView = CueView & {
|
|
1478
|
+
assetId: string;
|
|
1479
|
+
channelId: string;
|
|
1480
|
+
participantId?: string;
|
|
1481
|
+
priority: number;
|
|
1482
|
+
audioPhase: 'scheduled' | 'started' | 'skipped' | 'failed' | 'completed';
|
|
1483
|
+
};
|
|
1484
|
+
type AudioCueEvent = {
|
|
1485
|
+
type: AudioCueEventType;
|
|
1486
|
+
atFrame: number;
|
|
1487
|
+
name: string;
|
|
1488
|
+
idempotencyKey: string;
|
|
1489
|
+
assetId: string;
|
|
1490
|
+
channelId: string;
|
|
1491
|
+
participantId?: string;
|
|
1492
|
+
reason?: AudioCueReason;
|
|
1493
|
+
progress: number;
|
|
1494
|
+
};
|
|
1495
|
+
type AudioCueTimelineSnapshot = {
|
|
1496
|
+
frame: number;
|
|
1497
|
+
reducedSensory: boolean;
|
|
1498
|
+
cues: AudioCueView[];
|
|
1499
|
+
events: AudioCueEvent[];
|
|
1500
|
+
};
|
|
1501
|
+
type PlayAudioCueResult = {
|
|
1502
|
+
ok: true;
|
|
1503
|
+
cue: AudioCueView;
|
|
1504
|
+
} | {
|
|
1505
|
+
ok: false;
|
|
1506
|
+
reason: 'duplicate' | 'invalid';
|
|
1507
|
+
detail: string;
|
|
1508
|
+
};
|
|
1509
|
+
type AudioCueTimeline = {
|
|
1510
|
+
play(spec: AudioCueSpec): PlayAudioCueResult;
|
|
1511
|
+
step(frames?: number): AudioCueEvent[];
|
|
1512
|
+
cancel(idempotencyKey: string): boolean;
|
|
1513
|
+
reset(): void;
|
|
1514
|
+
snapshot(): AudioCueTimelineSnapshot;
|
|
1515
|
+
get(idempotencyKey: string): AudioCueView | undefined;
|
|
1516
|
+
dispose(): void;
|
|
1517
|
+
readonly frame: number;
|
|
1518
|
+
readonly reducedSensory: boolean;
|
|
1519
|
+
};
|
|
1520
|
+
type HeadlessAudioAdapter = {
|
|
1521
|
+
readonly broker: AudioBroker;
|
|
1522
|
+
readonly timeline: AudioCueTimeline;
|
|
1523
|
+
unlock(): Promise<AudioUnlockStatus>;
|
|
1524
|
+
play(spec: AudioCueSpec): PlayAudioCueResult;
|
|
1525
|
+
step(frames?: number): AudioCueEvent[];
|
|
1526
|
+
handleHostEvent(event: HostEvent): void;
|
|
1527
|
+
snapshot(): AudioCueTimelineSnapshot & {
|
|
1528
|
+
unlock: AudioUnlockStatus;
|
|
1529
|
+
muted: boolean;
|
|
1530
|
+
};
|
|
1531
|
+
destroy(): void;
|
|
1532
|
+
};
|
|
1533
|
+
declare function createHeadlessAudioAdapter(options?: {
|
|
1534
|
+
reducedSensory?: boolean;
|
|
1535
|
+
originFrame?: number;
|
|
1536
|
+
}): HeadlessAudioAdapter;
|
|
1537
|
+
|
|
1538
|
+
declare const VISUAL_LAYER_SNAPSHOT_SCHEMA_VERSION: 1;
|
|
1539
|
+
declare const VISUAL_LAYER_KINDS: readonly ["layer", "mask", "sprite"];
|
|
1540
|
+
type VisualLayerKind = (typeof VISUAL_LAYER_KINDS)[number];
|
|
1541
|
+
declare const VISUAL_LAYER_TRANSITIONS: readonly ["show", "hide", "replace", "crossfade"];
|
|
1542
|
+
type VisualLayerTransitionKind = (typeof VISUAL_LAYER_TRANSITIONS)[number];
|
|
1543
|
+
declare const VISUAL_LAYER_EVENTS: readonly ["visual.layer.revealed", "visual.layer.hidden", "visual.layer.transition-started", "visual.layer.transition-completed", "visual.layer.failed"];
|
|
1544
|
+
type VisualLayerEventType = (typeof VISUAL_LAYER_EVENTS)[number];
|
|
1545
|
+
declare const VISUAL_LAYER_FAILURE_CODES: readonly ["asset-failed", "missing-source", "unknown-layer", "unknown-version", "invalid-snapshot"];
|
|
1546
|
+
type VisualLayerFailureCode = (typeof VISUAL_LAYER_FAILURE_CODES)[number];
|
|
1547
|
+
type VisualLayerAssetStatus = 'pending' | 'ready' | 'failed';
|
|
1548
|
+
type VisualLayerFallbackPolicy = 'keep-prior' | 'hide' | {
|
|
1549
|
+
version: string;
|
|
1550
|
+
};
|
|
1551
|
+
type VisualLayerVersionDeclaration = {
|
|
1552
|
+
id: string;
|
|
1553
|
+
assetId: string;
|
|
1554
|
+
provenance?: AssetProvenance;
|
|
1555
|
+
};
|
|
1556
|
+
type VisualLayerDeclaration = {
|
|
1557
|
+
id: string;
|
|
1558
|
+
kind: VisualLayerKind;
|
|
1559
|
+
versions: readonly VisualLayerVersionDeclaration[];
|
|
1560
|
+
initialVersion?: string;
|
|
1561
|
+
compositorLayerId?: string;
|
|
1562
|
+
incomingLayerId?: string;
|
|
1563
|
+
order?: number;
|
|
1564
|
+
blend?: CompositorBlendMode;
|
|
1565
|
+
clip?: CompositorClip;
|
|
1566
|
+
pointerEvents?: CompositorPointerEvents;
|
|
1567
|
+
clearPolicy?: CompositorClearPolicy;
|
|
1568
|
+
fallback?: VisualLayerFallbackPolicy;
|
|
1569
|
+
};
|
|
1570
|
+
type VisualLayerAcceptedBinding = {
|
|
1571
|
+
layerId: string;
|
|
1572
|
+
toVersion: string;
|
|
1573
|
+
kind?: VisualLayerTransitionKind;
|
|
1574
|
+
durationFrames?: number;
|
|
1575
|
+
delayFrames?: number;
|
|
1576
|
+
easing?: CueEasing;
|
|
1577
|
+
idempotencyKey?: string;
|
|
1578
|
+
};
|
|
1579
|
+
type VisualLayerCueSpec = CueSpec & {
|
|
1580
|
+
layerId: string;
|
|
1581
|
+
kind: VisualLayerTransitionKind;
|
|
1582
|
+
toVersion?: string;
|
|
1583
|
+
fromVersion?: string;
|
|
1584
|
+
};
|
|
1585
|
+
type VisualLayerTransitionInspect = {
|
|
1586
|
+
kind: VisualLayerTransitionKind;
|
|
1587
|
+
progress: number;
|
|
1588
|
+
fromVersion: string | null;
|
|
1589
|
+
toVersion: string | null;
|
|
1590
|
+
cueKey: string;
|
|
1591
|
+
startFrame: number;
|
|
1592
|
+
durationFrames: number;
|
|
1593
|
+
delayFrames: number;
|
|
1594
|
+
easing: CueEasing;
|
|
1595
|
+
};
|
|
1596
|
+
type VisualLayerInspect = {
|
|
1597
|
+
id: string;
|
|
1598
|
+
kind: VisualLayerKind;
|
|
1599
|
+
visible: boolean;
|
|
1600
|
+
activeVersion: string | null;
|
|
1601
|
+
pendingVersion: string | null;
|
|
1602
|
+
committedVersion: string | null;
|
|
1603
|
+
opacity: number;
|
|
1604
|
+
order: number;
|
|
1605
|
+
provenance: AssetProvenance | null;
|
|
1606
|
+
overrideVersion: string | null;
|
|
1607
|
+
transition: VisualLayerTransitionInspect | null;
|
|
1608
|
+
};
|
|
1609
|
+
type VisualLayerEvent = {
|
|
1610
|
+
type: VisualLayerEventType;
|
|
1611
|
+
atFrame: number;
|
|
1612
|
+
layerId: string;
|
|
1613
|
+
version?: string;
|
|
1614
|
+
kind?: VisualLayerTransitionKind;
|
|
1615
|
+
progress: number;
|
|
1616
|
+
code?: VisualLayerFailureCode;
|
|
1617
|
+
};
|
|
1618
|
+
type VisualLayerDiagnostic = {
|
|
1619
|
+
code: VisualLayerFailureCode;
|
|
1620
|
+
layerId: string;
|
|
1621
|
+
version?: string;
|
|
1622
|
+
assetId?: string;
|
|
1623
|
+
message: string;
|
|
1624
|
+
atFrame: number;
|
|
1625
|
+
failure?: AssetFailure;
|
|
1626
|
+
};
|
|
1627
|
+
type VisualLayerSnapshotRow = {
|
|
1628
|
+
id: string;
|
|
1629
|
+
kind: VisualLayerKind;
|
|
1630
|
+
visible: boolean;
|
|
1631
|
+
committedVersion: string | null;
|
|
1632
|
+
pendingVersion: string | null;
|
|
1633
|
+
activeVersion: string | null;
|
|
1634
|
+
opacity: number;
|
|
1635
|
+
order: number;
|
|
1636
|
+
overrideVersion: string | null;
|
|
1637
|
+
provenance: AssetProvenance | null;
|
|
1638
|
+
fallback: VisualLayerFallbackPolicy;
|
|
1639
|
+
transition: VisualLayerTransitionInspect | null;
|
|
1640
|
+
};
|
|
1641
|
+
type VisualLayerControllerSnapshot = {
|
|
1642
|
+
schemaVersion: typeof VISUAL_LAYER_SNAPSHOT_SCHEMA_VERSION;
|
|
1643
|
+
frame: number;
|
|
1644
|
+
sceneId: string | null;
|
|
1645
|
+
reducedMotion: boolean;
|
|
1646
|
+
layers: VisualLayerSnapshotRow[];
|
|
1647
|
+
assets: Record<string, VisualLayerAssetStatus>;
|
|
1648
|
+
events: VisualLayerEvent[];
|
|
1649
|
+
diagnostics: VisualLayerDiagnostic[];
|
|
1650
|
+
};
|
|
1651
|
+
type PlayVisualLayerResult = PlayCueResult;
|
|
1652
|
+
type RestoreVisualLayerResult = {
|
|
1653
|
+
ok: true;
|
|
1654
|
+
snapshot: VisualLayerControllerSnapshot;
|
|
1655
|
+
} | {
|
|
1656
|
+
ok: false;
|
|
1657
|
+
errors: VisualLayerDiagnostic[];
|
|
1658
|
+
};
|
|
1659
|
+
type CreateVisualLayerControllerOptions = {
|
|
1660
|
+
compositor: Compositor;
|
|
1661
|
+
layers: readonly VisualLayerDeclaration[];
|
|
1662
|
+
preloader?: AssetPreloader;
|
|
1663
|
+
originFrame?: number;
|
|
1664
|
+
reducedMotion?: boolean;
|
|
1665
|
+
sceneId?: string;
|
|
1666
|
+
fallback?: VisualLayerFallbackPolicy;
|
|
1667
|
+
onAccepted?: readonly VisualLayerAcceptedBinding[];
|
|
1668
|
+
dispatch?: (event: HostEvent) => void;
|
|
1669
|
+
};
|
|
1670
|
+
type VisualLayerController = {
|
|
1671
|
+
registerSource(assetId: string, source: ImageData | HTMLCanvasElement): void;
|
|
1672
|
+
handleHostEvent(event: HostEvent): void;
|
|
1673
|
+
override(layerId: string, version: string | null): void;
|
|
1674
|
+
play(spec: VisualLayerCueSpec): PlayVisualLayerResult;
|
|
1675
|
+
step(frames?: number): VisualLayerEvent[];
|
|
1676
|
+
snapshot(): VisualLayerControllerSnapshot;
|
|
1677
|
+
restore(input: unknown): RestoreVisualLayerResult;
|
|
1678
|
+
inspect(): VisualLayerInspect[];
|
|
1679
|
+
captureComposedFrame(): ComposedFrame;
|
|
1680
|
+
destroy(): void;
|
|
1681
|
+
readonly frame: number;
|
|
1682
|
+
readonly sceneId: string | null;
|
|
1683
|
+
readonly compositor: Compositor;
|
|
1684
|
+
};
|
|
1685
|
+
type VisualLayerCapture = {
|
|
1686
|
+
frame: ComposedFrame;
|
|
1687
|
+
layers: VisualLayerInspect[];
|
|
1688
|
+
};
|
|
1689
|
+
declare function captureVisualLayers(controller: VisualLayerController): VisualLayerCapture;
|
|
1690
|
+
declare function createVisualLayerController(options: CreateVisualLayerControllerOptions): VisualLayerController;
|
|
1691
|
+
|
|
1216
1692
|
/**
|
|
1217
1693
|
* Copyright (c) 2026 Aaron Boyarsky
|
|
1218
1694
|
* SPDX-License-Identifier: LicenseRef-CyberArt-Engine
|
|
@@ -1220,7 +1696,8 @@ declare function replayExportedTrace(exported: ReplayInspectorExport, group: Run
|
|
|
1220
1696
|
*
|
|
1221
1697
|
* Node/jsdom test helpers. Import from `@cyberart-io/engine/headless`.
|
|
1222
1698
|
* Production carts and browser hosts must import `@cyberart-io/engine` instead
|
|
1223
|
-
* so Vite never walks `node:fs/promises`.
|
|
1699
|
+
* so Vite never walks `node:fs/promises`. `createHeadlessMultiCartHarness`
|
|
1700
|
+
* is the same group API as `createRuntimeGroup`, including calculation carts.
|
|
1224
1701
|
*/
|
|
1225
1702
|
|
|
1226
1703
|
type WriteComposedFrameResult = ComposedFrame & {
|
|
@@ -1232,4 +1709,4 @@ type WriteComposedFrameResult = ComposedFrame & {
|
|
|
1232
1709
|
*/
|
|
1233
1710
|
declare function writeComposedFrame(compositor: Compositor, path?: string): Promise<WriteComposedFrameResult>;
|
|
1234
1711
|
|
|
1235
|
-
export { type BoundReplaySession, type CausationTreeNode, type CreateHeadlessHarnessOptions, type CreateHeadlessMultiCartHarnessOptions, type CreateReplayInspectorOptions, DEFAULT_HEADLESS_HEIGHT, DEFAULT_HEADLESS_WIDTH, type GlyphAtlas, HEADLESS_PNG_DATA_URL, type HeadlessCanvas2DSettings, type HeadlessFrameError, type HeadlessHarness, type HeadlessImageFixture, type HeadlessInspect, type HeadlessMultiCartHarness, HeadlessUnsupportedOperationError, type InspectorRecord, type InstallHeadlessCanvasOptions, type ReplayCompareResult, type ReplayInspector, type ReplayInspectorExport, type ReplayInspectorReport, type ReplayParticipantSummary, type ReplayTapeAction, type ReplayTraceFilter, UPDATE_GOLDEN_ENV, type VisualArtifactPaths, type VisualArtifacts, type VisualCompareOptions, type VisualCompareResult, type WriteComposedFrameResult, assertPixelsEqual, assertPngDataUrlsEqual, attachHeadlessCanvas2D, compareImageData, compareReplayTraces, createDefaultGlyphAtlas, createHeadlessHarness, createHeadlessMultiCartHarness, createImageFixture, createReplayInspector, decodePng, encodePng, encodePngDataUrl, getHeadlessSurface, imageDataFromPngDataUrl, installHeadlessCanvas, makeImageData, replayExportedTrace, setDefaultGlyphAtlas, shouldUpdateGolden, writeComposedFrame, writeVisualArtifacts };
|
|
1712
|
+
export { type BoundReplaySession, type CausationTreeNode, type CreateHeadlessHarnessOptions, type CreateHeadlessMultiCartHarnessOptions, type CreateReplayInspectorOptions, DEFAULT_HEADLESS_HEIGHT, DEFAULT_HEADLESS_WIDTH, type GlyphAtlas, HEADLESS_PNG_DATA_URL, type HeadlessAudioAdapter, type HeadlessCanvas2DSettings, type HeadlessFrameError, type HeadlessHarness, type HeadlessImageFixture, type HeadlessInspect, type HeadlessMultiCartHarness, HeadlessUnsupportedOperationError, type InspectorRecord, type InstallHeadlessCanvasOptions, type ReplayCompareResult, type ReplayInspector, type ReplayInspectorExport, type ReplayInspectorReport, type ReplayParticipantSummary, type ReplayTapeAction, type ReplayTraceFilter, UPDATE_GOLDEN_ENV, type VisualArtifactPaths, type VisualArtifacts, type VisualCompareOptions, type VisualCompareResult, type VisualLayerCapture, type VisualLayerController, type VisualLayerInspect, type WriteComposedFrameResult, assertPixelsEqual, assertPngDataUrlsEqual, attachHeadlessCanvas2D, captureVisualLayers, compareImageData, compareReplayTraces, createDefaultGlyphAtlas, createHeadlessAudioAdapter, createHeadlessHarness, createHeadlessMultiCartHarness, createImageFixture, createReplayInspector, createVisualLayerController, decodePng, encodePng, encodePngDataUrl, getHeadlessSurface, imageDataFromPngDataUrl, installHeadlessCanvas, makeImageData, replayExportedTrace, setDefaultGlyphAtlas, shouldUpdateGolden, writeComposedFrame, writeVisualArtifacts };
|