Public API declarations
Public API map
Only the package import paths in the export tables are supported entry points. The declaration appendix includes supporting types for understanding those signatures; filenames in that appendix do not grant additional public subpath imports. Private members and internal helper declarations are not extension points. Read embedding and ownership/lifecycle before calling playback methods.
@quay/projector
| Import path | Declaration |
|---|---|
| @quay/projector | ./dist/index.d.ts |
Projector.d.ts
TypeScript
import * as THREE from "three";
import { type SceneDocument, type Transform } from "@quay/contracts";
import type { WrightResolved } from "@quay/scene-contracts/wright";
import type { LoadDocumentOptions, LoadOptions, LoadResult, ProjectorOptions } from "./types.js";
export declare class SceneProjector {
private readonly options;
readonly root: THREE.Group<THREE.Object3DEventMap>;
readonly camera: THREE.Camera | undefined;
readonly renderer: THREE.WebGLRenderer | undefined;
document: SceneDocument | undefined;
private readonly instances;
private readonly clips;
private readonly ownedResources;
private readonly sources;
private readonly residents;
private readonly texturedFloors;
private readonly retainers;
private loadContext;
private wright;
private active;
private readonly signalCleanup;
private disposed;
private transformOwner;
private readonly controls;
private readonly ownsRenderer;
private previousBackground;
private previousFog;
constructor(options: ProjectorOptions);
load(url: string, options?: LoadOptions): Promise<LoadResult>;
loadDocument(value: SceneDocument, options?: LoadDocumentOptions): Promise<LoadResult>;
/** Loads a compiler result while keeping WRIGHT semantics out of ordinary instances. */
loadResolvedDocument(value: {
projection: SceneDocument;
wright: WrightResolved;
}, options?: LoadDocumentOptions): Promise<LoadResult>;
private projectDocument;
getInstance(id: string): THREE.Object3D | undefined;
isInstanceResident(id: string): boolean;
/** Actual resident geometry or a conservative pinned envelope at the current
* root pose. Deferred resources must never masquerade as empty occupancy. */
getInstanceBounds(id: string): THREE.Box3 | undefined;
/** Animation clocks retain their visual descendants independently of root ownership. */
retainInstances(ids: readonly string[]): () => void;
private validateResidency;
private loadImageRoot;
private loadSource;
/** Transactional visual residency. Stable roots, document and transient poses are
* never replaced. Failure keeps the previous residency; no placeholder success. */
setResidency(ids: readonly string[], options?: {
signal?: AbortSignal;
floorTextureInstanceIds?: readonly string[];
}): Promise<void>;
/** Copies only. Host animation clocks never mutate another instance's clips. */
getAnimationClips(id: string): THREE.AnimationClip[];
/** Exclusive transient transform lease. Never edits the loaded document. */
claimTransforms(owner: symbol): () => void;
applyTransientTransforms(owner: symbol, poses: Readonly<Record<string, Transform>>): void;
/** Fast path for authored pose/visibility/name edits; resource changes reload transactionally. */
updateDocument(value: SceneDocument, options?: LoadDocumentOptions): Promise<LoadResult>;
setVisible(id: string, visible: boolean): void;
update(deltaSeconds: number): void;
resize(width: number, height: number, pixelRatio?: number): void;
unload(abort?: boolean): void;
dispose(): void;
private beginLoad;
private finishLoad;
private resolve;
private resolveImage;
private applyRoomBackdrops;
private placeholder;
private collectResources;
private applyEnvironment;
private applyCamera;
private assertActive;
}
errors.d.ts
Reference
export declare class SceneValidationError extends Error {
name: string;
}
export declare class UnsupportedSceneVersionError extends Error {
name: string;
}
export declare class SceneFetchError extends Error {
name: string;
}
export declare class AssetLoadError extends Error {
name: string;
}
export declare class DisposedProjectorError extends Error {
name: string;
}
export declare class LoadAbortedError extends Error {
name: string;
}
index.d.ts
Reference
export * from "./Projector.js";
export * from "./errors.js";
export * from "./types.js";
export { applyMaterial } from "./materials.js";
legacy-floor-material.d.ts
TypeScript
import * as THREE from "three";
import type { OwnedResource } from "@quay/spatial";
/** Compatibility geometry/UV adapter for historical bundled floor finishes. */
export declare function applyFloorFinish(root: THREE.Object3D, tags: readonly string[], textureUri?: string, resources?: Set<OwnedResource>, deferred?: boolean): Promise<void>;
materials.d.ts
TypeScript
import * as THREE from "three";
import type { ImageAssetSnapshot, MaterialDefinition } from "@quay/contracts";
import type { OwnedResource } from "@quay/spatial";
/** One material implementation for GLB meshes and mounted image surfaces. */
export declare function applyMaterial(root: THREE.Object3D, definition: MaterialDefinition, resources: Set<OwnedResource>, resolveImage: (image: ImageAssetSnapshot) => string, manager?: THREE.LoadingManager): Promise<void>;
meshopt.d.ts
TypeScript
import { MeshoptDecoder } from "three/addons/libs/meshopt_decoder.module.js";
/** One decoder budget per GLB, before WASM allocates decompressed views. */
export declare function boundedMeshoptDecoder(): typeof MeshoptDecoder;
types.d.ts
TypeScript
import type * as THREE from "three";
import type { AssetSnapshot, ImageAssetSnapshot, SceneDocument } from "@quay/contracts";
import type { RoomBackdropSource, WrightResolved } from "@quay/scene-contracts/wright";
export type ProjectorWarning = {
code: string;
message: string;
assetId?: string;
instanceId?: string;
};
export type LoadResult = {
loadedInstanceIds: string[];
/** Intentionally metadata-only, not failed asset loads. */
deferredInstanceIds?: string[];
skippedInstanceIds: string[];
warnings: ProjectorWarning[];
durationMs: number;
};
export type ResolveContext = {
document: SceneDocument;
documentUrl?: string;
baseUrl?: string;
};
export type ProjectorOptions = {
scene: THREE.Scene;
camera?: THREE.Camera;
renderer?: THREE.WebGLRenderer;
createRenderer?: THREE.WebGLRendererParameters;
loadingManager?: THREE.LoadingManager;
createCamera?: boolean;
createControls?: {
domElement: HTMLElement;
};
applyEnvironment?: boolean;
resolveAssetUri?: (asset: AssetSnapshot, context: ResolveContext) => string;
resolveImageUri?: (asset: ImageAssetSnapshot, context: ResolveContext) => string;
resolveBackdropUri?: (source: RoomBackdropSource, context: ResolveContext) => string;
/** Resolve compiled floor-finish IDs to bundled texture URLs. */
resolveFloorTextureUri?: (finish: string, context: ResolveContext) => string | undefined;
/** Return cleanup only for decoders/resources whose ownership is transferred. */
configureGltfLoader?: (loader: unknown) => void | (() => void);
missingAssetPolicy?: "reject" | "skip" | "placeholder";
maxConcurrentLoads?: number;
onProgress?: (event: {
loaded: number;
total: number;
assetId: string;
}) => void;
onWarning?: (warning: ProjectorWarning) => void;
onError?: (error: Error) => void;
signal?: AbortSignal;
};
export type ResolvedSceneDocument = {
projection: SceneDocument;
wright: WrightResolved;
};
export type LoadOptions = {
signal?: AbortSignal;
};
export type LoadDocumentOptions = {
baseUrl?: string;
documentUrl?: string;
signal?: AbortSignal;
/** Omit for ordinary full projection. Deferred instances retain stable roots. */
residentInstanceIds?: readonly string[];
/** Limit finish texture loading independently of geometry residency. Omit for all. */
floorTextureInstanceIds?: readonly string[];
};
@quay/runtime
| Import path | Declaration |
|---|---|
| @quay/runtime/worldpack | ./dist/worldpack.d.ts |
| @quay/runtime | ./dist/index.d.ts |
actor-selection.d.ts
TypeScript
type Candidate = {
identity: string;
visible: boolean;
role: string;
label: string;
sizing?: {
profile: {
semanticClass: string;
} | null;
} | null;
};
/** Shared deterministic default; explicit authored control policies still win. */
export declare function defaultExperienceActors<T extends Candidate>(objects: readonly T[]): {
human: T | undefined;
dog: T | undefined;
};
export {};
animation.d.ts
TypeScript
import type { SceneProjector } from "@quay/projector";
import type { SemanticObject } from "@quay/scene-contracts";
export declare function hasAnimationOwner(projector: SceneProjector): boolean;
export declare function reserveAnimationInstances(projector: SceneProjector, ids: string[]): () => void;
/** Explicit managed descendant animation. Never owns the instance/normalization
* transform and never changes the source clip or authored document. */
export declare function bindAnimations(projector: SceneProjector, objects: readonly SemanticObject[]): {
readonly mode: "playing" | "paused";
readonly time: number;
play(): void;
pause(): void;
update(seconds: number): void;
step(): void;
reset(): void;
dispose(): void;
};
audio-bytes.d.ts
Reference
export { verifyAudioBytes } from "@quay/scene-contracts/audio-bytes";
audio.d.ts
TypeScript
import { type PerspectiveCamera, type Object3D } from "three";
import { type AudioResource, type MusicCommand } from "@quay/scene-contracts/audio";
/** Optional experience-scoped WebAudio owner. No compiler, authoring edits or global singleton. */
export declare class ExperienceAudio {
readonly resources: AudioResource[];
private readonly object;
private readonly resolve;
private context;
private analyser;
private buffers;
private voices;
private music;
private pending;
private epoch;
private disposed;
private abort;
private enabling;
readonly diagnostics: string[];
constructor(resources: AudioResource[], object: (id: string) => Object3D | undefined, resolve?: (uri: string) => string);
private fail;
get state(): {
status: string;
tracks: string[];
nodes: {
assetId: string;
startedAt: number;
gain: number;
spatial: string | null;
position: number[] | null;
}[];
voices: number;
rms: number;
diagnostics: string[];
};
enable(): Promise<void>;
private activate;
private voice;
private clean;
private ramp;
applyMusic(command: MusicCommand): void;
sfx(id: string, volume: number, spatial: string | null): void;
private position;
update(camera: PerspectiveCamera): void;
pause(): Promise<void>;
reset(): void;
dispose(): void;
}
chat-intents.d.ts
TypeScript
import type { SemanticSnapshot } from "./semantic-observer.js";
export type ChatContext = {
lastObjectId: string | null;
previousRoomId: string | null;
};
export type ChatIntent = {
kind: "help";
} | {
kind: "where";
} | {
kind: "describe-room";
} | {
kind: "list-objects";
} | {
kind: "list-exits";
} | {
kind: "list-actions";
objectId: string | null;
} | {
kind: "navigate";
roomId: string;
} | {
kind: "approach";
objectId: string;
} | {
kind: "inspect";
objectId: string;
} | {
kind: "activate-label";
labelId: string;
objectId: string;
} | {
kind: "clarify";
candidates: string[];
} | {
kind: "unknown";
};
/** Bounded no-AI interpreter. It can select only identifiers present in the
* supplied observer snapshot and returns clarification instead of guessing. */
export declare function resolveChatIntent(input: string, snapshot: SemanticSnapshot, context?: ChatContext): ChatIntent;
cinematic-camera.d.ts
TypeScript
import { Box3, Vector3 } from "three";
import type { SceneProjector } from "@quay/projector";
import type { SceneDocumentV2 } from "@quay/scene-contracts";
import type { CinematicCue } from "@quay/scene-contracts/cinematic";
export type ShotCue = Extract<CinematicCue, {
kind: "shot";
}>;
export type CameraPose = {
position: Vector3;
target: Vector3;
fov: number;
};
export type CameraPlan = {
start: CameraPose;
end: CameraPose;
region: Box3;
excluded: Set<string>;
diagnostics: string[];
movement: ShotCue["movement"];
hidden: Set<string>;
};
export declare function interpolateCamera(plan: CameraPlan, t: number): CameraPose;
/** Actual projected geometry only. Bounding proxies are conservative, not mesh
* visibility certificates or invented anatomical anchors. No authoring writes. */
export declare class CinematicCamera {
readonly projector: SceneProjector;
readonly world: SceneDocumentV2;
readonly aspect: () => number;
readonly actorForward?: ((identity: string) => Vector3 | null) | undefined;
private cache;
private staticBounds;
/** One actual-geometry snapshot per simulation tick, shared only within it. */
refresh(): void;
constructor(projector: SceneProjector, world: SceneDocumentV2, aspect: () => number, actorForward?: ((identity: string) => Vector3 | null) | undefined);
private forward;
bounds(id: string): Box3;
private objects;
currentRegion(cue: ShotCue): Box3;
evaluateSubjects(value: CameraPose, cue: ShotCue): string[];
private obstacles;
/** Independent continuous segment clearance, not success of camera proposal. */
clearSegment(a: Vector3, b: Vector3, hidden?: Set<string>): boolean;
transition(a: Vector3, b: Vector3, hidden: Set<string>): Vector3[];
evaluate(value: CameraPose, region: Box3, excluded: Set<string>, hidden?: Set<string>): string[];
resolve(cue: ShotCue): CameraPlan;
}
cinematic.d.ts
TypeScript
import { PerspectiveCamera } from "three";
import { type CinematicDocument, type CinematicRuntimeState, type PlayerMessage, type CinematicCue } from "@quay/scene-contracts/cinematic";
import type { PreviewPlayer } from "./preview.js";
export type PlayerEvent = {
type: string;
subject: string | null;
target: string | null;
cinematic: string | null;
time: number;
};
/** One directing clock over an existing player's roots, navigation and mixers.
* This class neither loads assets nor owns a second scene or authoring document. */
export declare class CinematicDirector {
readonly player: PreviewPlayer;
readonly camera: PerspectiveCamera;
readonly audioCue?: ((cue: Extract<CinematicCue, {
kind: "music" | "sfx";
}>) => void) | undefined;
private stateValue;
private sequence;
private framing;
private cameraPlan;
private cameraCue;
private previousCamera;
private lastCamera;
private transitionPath;
private restoreCamera;
private visibility;
private emitted;
private persistent;
private firedTriggers;
private near;
private queue;
private listeners;
private history;
private accumulator;
private disposed;
readonly document: CinematicDocument;
constructor(player: PreviewPlayer, camera: PerspectiveCamera, input: unknown, audioCue?: ((cue: Extract<CinematicCue, {
kind: "music" | "sfx";
}>) => void) | undefined);
get state(): CinematicRuntimeState;
get events(): PlayerEvent[];
get frame(): {
cue: string | null;
camera: import("three").Vector3Tuple;
quaternion: import("three").QuaternionTuple;
target: import("three").Vector3Tuple | undefined;
region: {
min: import("three").Vector3Tuple;
max: import("three").Vector3Tuple;
} | null;
objects: {
id: string;
min: import("three").Vector3Tuple;
max: import("three").Vector3Tuple;
}[];
};
subscribe(listener: (event: PlayerEvent) => void): () => void;
private diagnostic;
private emit;
dispatch(message: PlayerMessage): void;
private play;
private stop;
update(seconds: number): void;
private trigger;
private tick;
dispose(): void;
reset(): void;
}
conversation.d.ts
TypeScript
import { type PersonaResource, type ConversationMessage, type ConversationRequest, type ConversationResponse } from "@quay/scene-contracts/persona";
export type ConversationTransport = (request: ConversationRequest, signal: AbortSignal) => Promise<ConversationResponse>;
/** Session memory and stale-result fencing only; generated text has no world API. */
export declare class ConversationSession {
private readonly transport?;
private epoch;
private controller;
private profile;
private actor;
private sessionId;
private turn;
private messages;
private status;
private error;
constructor(transport?: ConversationTransport | undefined);
get state(): {
actor: string | null;
persona: string | null;
profileId: string | null;
status: string;
error: string;
messages: ConversationMessage[];
sessionId: string;
turn: number;
};
begin(actor: string, persona: PersonaResource): Promise<void>;
send(text: string): Promise<void>;
cancel(): void;
end(): void;
}
direction.d.ts
TypeScript
import { type Object3D, type PerspectiveCamera, type Scene, type WebGLRenderer } from "three";
import type { RoomDirectionDocument } from "@quay/scene-contracts/cinematic";
/** Executes only compiler-resolved presets. It has no parser, model, or AI dependency. */
export declare class DirectionExecutor {
private readonly scene;
private readonly renderer;
readonly document: RoomDirectionDocument | undefined;
readonly tier: "cinematicHigh" | "balanced" | "performance";
private readonly camera?;
private readonly resolveObject?;
private fired;
private active;
private elapsed;
private readonly rig;
private readonly fill;
private readonly key;
private readonly original;
private motion;
constructor(scene: Scene, renderer: WebGLRenderer, document: RoomDirectionDocument | undefined, tier?: "cinematicHigh" | "balanced" | "performance", camera?: PerspectiveCamera | undefined, resolveObject?: ((identity: string) => Object3D | undefined) | undefined);
activate(room: string, event: string, target?: string | null): void;
private apply;
update(seconds: number): void;
get state(): {
room: string | null;
tier: "cinematicHigh" | "balanced" | "performance";
fired: string[];
effects: {
lighting: "neutral" | "warm" | "cool" | "intimate" | "monumental" | "clinical" | "dramatic-hero";
atmosphere: "none" | "subtle-depth" | "haze";
postProcessing: "balanced" | "minimal" | "cinematic" | "hero";
entryCamera: "none" | "settle" | "slow-reveal" | "hero-reveal";
exploration: "free-stable";
ambientMotion: string[];
} | null;
};
dispose(): void;
}
embedded-preview.d.ts
TypeScript
import { PerspectiveCamera, Scene, WebGLRenderer } from "three";
import type { SceneDocumentV2 } from "@quay/scene-contracts";
import type { SceneProjector, ProjectorOptions } from "@quay/projector";
import { type PhysicsFactory } from "./scene-runtime.js";
import { PreviewPlayer } from "./preview.js";
import type { CinematicDirector } from "./cinematic.js";
import { ExperienceDirector } from "./experience.js";
import type { ConversationTransport } from "./conversation.js";
import type { ExperienceDocument } from "@quay/scene-contracts/experience";
import type { RoomDirectionDocument } from "@quay/scene-contracts/cinematic";
import type { CinematicDocument, PlayerMessage } from "@quay/scene-contracts/cinematic";
/** Human-readable WRIGHT room fact for the transient preview entry caption. */
export declare function roomEntryLabel(document: SceneDocumentV2, roomIdentity: string, locale?: "en" | "it", resolveRoomLabel?: (roomIdentity: string, fallback: string) => string): string | null;
/** Runtime defense in depth for authored links. Compilation and contract
* validation apply the same protocol/credential boundary. */
export declare function externalLinkUrl(value: string): string;
/** Same input/player binding for owned standalone and borrowed editor projection. */
export declare function createEmbeddedPreview(host: HTMLElement, document: SceneDocumentV2, options?: {
resolveAssetUri?: ProjectorOptions["resolveAssetUri"];
resolveImageUri?: ProjectorOptions["resolveImageUri"];
resolveAudioUri?: (uri: string) => string;
resolveContentUri?: (uri: string) => string;
quality?: "balanced" | "performance";
speechAudioContext?: () => AudioContext;
speechAudioAllowed?: () => boolean;
loadPdf?: (uri: string, signal: AbortSignal) => Promise<Uint8Array>;
interactionMode?: "authoring" | "player";
onInteractionLabelSelect?: (labelId: string, parentObjectId: string) => void;
conversationTransport?: ConversationTransport;
onStatus?: (message: string) => void;
onCamera?: (mode: number) => void;
/** Limit user camera selection without altering authored cinematic shots. */
allowedCameraModes?: readonly number[];
cinematic?: CinematicDocument;
experience?: ExperienceDocument;
direction?: RoomDirectionDocument;
locale?: "en" | "it";
resolveRoomLabel?: (roomIdentity: string, fallback: string) => string;
createPhysics?: PhysicsFactory;
borrowed?: {
projector: SceneProjector;
camera: PerspectiveCamera;
renderer: WebGLRenderer;
scene: Scene;
};
}): {
ready: Promise<void>;
update(now: number): void;
/** Host loading gate: preserve clocks and poses, discard stale input/time. */
setSuspended(value: boolean): void;
setCamera: (mode: number) => void;
focus(): void;
walkToRoom(room: string): void;
walkToObject(objectId: string): void;
enterRoom(room: string): void;
/** Programmatic activation shares the exact visual-label viewer/dispatch
* path. Callers may provide the control that should regain focus. */
activateInteraction(labelId: string, returnFocus?: HTMLElement): void;
dispatch(message: PlayerMessage | {
type: "ridley.state.goto";
state: string;
}): void;
readonly cinematic: CinematicDirector | null;
readonly experience: ExperienceDirector | null;
readonly directionState: {
room: string | null;
tier: "cinematicHigh" | "balanced" | "performance";
fired: string[];
effects: {
lighting: "neutral" | "warm" | "cool" | "intimate" | "monumental" | "clinical" | "dramatic-hero";
atmosphere: "none" | "subtle-depth" | "haze";
postProcessing: "balanced" | "minimal" | "cinematic" | "hero";
entryCamera: "none" | "settle" | "slow-reveal" | "hero-reveal";
exploration: "free-stable";
ambientMotion: string[];
} | null;
} | null;
/** Forward only declared topology or interaction events to resolved rules. */
direction(room: string, event: string, target?: string | null): void;
reset(): void;
readonly player: PreviewPlayer | null;
dispose(): void;
};
experience.d.ts
TypeScript
import type { PerspectiveCamera } from "three";
import { type ExperienceDocument } from "@quay/scene-contracts/experience";
import type { CinematicDocument, PlayerMessage } from "@quay/scene-contracts/cinematic";
import type { PreviewPlayer } from "./preview.js";
import { CinematicDirector } from "./cinematic.js";
import { StudioEventBus, type StudioEvent } from "./studio-events.js";
import { ExperienceAudio } from "./audio.js";
import { ConversationSession, type ConversationTransport } from "./conversation.js";
/** One experience owner above world capabilities and the existing film director.
* Old resolved scenes receive the versioned companion policy, not another player. */
export declare class ExperienceDirector {
readonly player: PreviewPlayer;
readonly camera: PerspectiveCamera;
readonly bus: StudioEventBus;
readonly cinematic: CinematicDirector | null;
readonly document: ExperienceDocument | null;
readonly audio: ExperienceAudio;
readonly conversation: ConversationSession;
private restoreConversationCamera;
private current;
private readonly fallback;
private readonly topology;
private pending;
private fired;
private time;
private disposed;
private continuous;
private returnState;
readonly diagnostics: string[];
constructor(player: PreviewPlayer, camera: PerspectiveCamera, film?: CinematicDocument, input?: ExperienceDocument, resolveAudio?: (uri: string) => string, conversationTransport?: ConversationTransport);
get state(): {
id: string;
mode: "interactive" | "cinematic" | "conversation";
policy: string;
time: number;
audio: {
status: string;
tracks: string[];
nodes: {
assetId: string;
startedAt: number;
gain: number;
spatial: string | null;
position: number[] | null;
}[];
voices: number;
rms: number;
diagnostics: string[];
};
conversation: {
actor: string | null;
persona: string | null;
profileId: string | null;
status: string;
error: string;
messages: import("@quay/scene-contracts/persona").ConversationMessage[];
sessionId: string;
turn: number;
};
diagnostics: string[];
};
get userCamera(): boolean;
get userControl(): boolean;
private enter;
private flush;
private observe;
update(dt: number, input: {
x: number;
z: number;
}): void;
emit(event: StudioEvent): void;
dispatch(message: PlayerMessage | {
type: "ridley.state.goto";
state: string;
}): void;
reset(): void;
dispose(): void;
finishConversation(): void;
}
frame-clock.d.ts
Reference
/** Bootstrap renders do not anchor the RAF clock. RAF timestamps describe frame
* start and can precede performance.now() sampled later in the same frame. */
export declare class FrameClock {
private previous;
reset(): void;
sample(timestamp: number, bootstrap?: boolean): number;
}
index.d.ts
Reference
export * from "./scene-runtime.js";
export { bindAnimations } from "./animation.js";
export { PreviewPlayer, locomotionClips } from "./preview.js";
export { createEmbeddedPreview } from "./embedded-preview.js";
export { CinematicDirector, type PlayerEvent } from "./cinematic.js";
export { ExperienceDirector } from "./experience.js";
export { DirectionExecutor } from "./direction.js";
export { ConversationSession, type ConversationTransport, } from "./conversation.js";
export { StudioEventBus, type StudioEvent } from "./studio-events.js";
export { defaultExperienceActors } from "./actor-selection.js";
export { SemanticObserver, type SemanticActionFact, type SemanticActorFact, type SemanticExitFact, type SemanticLabelFact, type SemanticObjectFact, type SemanticRoomFact, type SemanticRuntimeState, type SemanticSnapshot, } from "./semantic-observer.js";
export { resolveChatIntent, type ChatContext, type ChatIntent, } from "./chat-intents.js";
navigation.d.ts
Reference
export { NavigationField, type NavigationDomain, type Route, } from "@quay/spatial/navigation";
pdf-viewer.d.ts
Reference
/** Embedded PDF reader: external annotations open separately, internal links
* stay within the document. The engine loads only when a PDF is opened. */
export declare function createPdfViewer(host: HTMLElement, source: string | ((signal: AbortSignal) => Promise<Uint8Array>), title: string): () => void;
preview.d.ts
TypeScript
import { AnimationMixer, Object3D, Vector3, type AnimationAction, type PerspectiveCamera } from "three";
import type { SceneDocumentV2 } from "@quay/scene-contracts";
import type { PhysicsSession } from "./scene-runtime.js";
import type { Transform } from "@quay/contracts";
import type { SceneProjector } from "@quay/projector";
import { NavigationField } from "./navigation.js";
import type { CinematicCue } from "@quay/scene-contracts/cinematic";
import type { ExperienceState } from "@quay/scene-contracts/experience";
/** Evidence-based names only: an arbitrary first clip is not a walk animation. */
export declare function locomotionClips(names: readonly string[]): {
walk: number;
idle: number;
};
type Actor = {
id: string;
pose: Transform;
initial: Transform;
height: number;
radius: number;
mixer: AnimationMixer;
walk: AnimationAction | null;
idle: AnimationAction | null;
moving: boolean;
root: Object3D;
actions: Map<number, AnimationAction>;
/** Asset-specific visual forward correction, independent of path direction. */
headingOffset: number;
};
export declare const TELEPORT_SPEECH = "Beam me up, Scotty!";
export type PreviewPresentationEvent = {
kind: "teleport";
actor: string;
text: string;
from: [number, number, number];
to: [number, number, number];
};
/** Keep a physics-owned character inside the deterministic WRIGHT navigation
* domain. If a solver step crosses a wall outside a portal, return the furthest
* valid point on that segment instead of allowing the body to become embedded. */
export declare function constrainedNavigationPosition(field: NavigationField, from: Vector3, requested: Vector3): Vector3;
/** Embedded same-level preview. Without physics it owns root motion; with a
* physics session the character controller and rigid bodies own root motion. */
export declare class PreviewPlayer {
readonly projector: SceneProjector;
readonly document: SceneDocumentV2;
/** Visual facing used by locomotion, including legacy asset front correction. */
actorForward(identity: string): Vector3 | null;
readonly warnings: string[];
human: Actor | undefined;
readonly dog: Actor | undefined;
/** Mode 2 is the default over-the-shoulder player camera. */
cameraMode: number;
private lookPitch;
private lookYaw;
private readonly owner;
private readonly release;
private readonly physics;
private readonly releaseAnimations;
private readonly actors;
private readonly obstacles;
private target;
private doorwayAdvance;
private followers;
private disposed;
private bounds;
private readonly navigation;
/** Static scenery and topology share one deterministic navigation boundary;
* Rapier remains authoritative for dynamic-body contacts. */
private readonly movementNavigation;
private readonly cameraDomains;
private readonly doors;
private readonly hiddenDuplicateDoors;
private readonly doorSides;
private readonly paths;
private readonly routeStatus;
private readonly lastPhysicsPositions;
private readonly collisionRecovery;
private readonly presentationEvents;
private pendingTeleport;
private topologyDiscontinuity;
private cameraRoomId;
private directing;
private directedCue;
private directedGoal;
private directedTarget;
private restoreDirection;
constructor(projector: SceneProjector, document: SceneDocumentV2, directedActors?: readonly string[], physics?: PhysicsSession);
private instanceBounds;
private activeCameraRoom;
/** Sweep the shoulder boom inside connected rooms and their real apertures. */
private constrainShoulderCamera;
get observations(): {
camera: number;
initialWorldBounds: {
min: import("three").Vector3Tuple;
max: import("three").Vector3Tuple;
};
human: {
id: string;
position: number[];
quaternion: number[];
navigation: string;
moving: boolean;
} | null;
dog: {
id: string;
position: number[];
navigation: string;
moving: boolean;
} | null;
warnings: string[];
};
/** Capabilities are selected by RIDLEY; no authored scene mutation. */
configureExperience(control: string | null, followers: ExperienceState["followers"]): void;
get actorPositions(): {
identity: string;
position: Vector3;
}[];
setTarget(point: Vector3): void;
/** Selects a deterministic point inside a WRIGHT room. Nearby rooms are
* reached on foot; sufficiently remote rooms use an explicit transport. */
walkToRoom(roomId: string): void;
/** Places the controlled actor at a deterministic, collision-free semantic
* room entry. Hosts use this for direct URLs and browser history, where a
* portal-relative walking animation would leave URL and world state out of
* sync. The position is derived from WRIGHT room geometry, never host camera
* coordinates. */
enterRoom(roomId: string): void;
/** One-shot presentation events keep the shared editor and WorldPlayer UI
* in sync without making DOM concerns part of navigation. */
drainPresentationEvents(): PreviewPresentationEvent[];
/** Experience observers use this to suppress manufactured portal crossings
* while still emitting the real room leave/enter facts after transport. */
consumeTopologyDiscontinuity(): boolean;
/** Physical actor position, independent of camera and selected destination. */
get currentRoomId(): string | null;
private roomAt;
private portalDistance;
private relocateActor;
private relocateFollowers;
private updateTeleport;
/** A new destination supersedes the complete old movement, including any
* delayed transport and collision recovery, before planning from the live pose. */
cancelNavigation(): void;
setCamera(mode: number): void;
setLookPitch(pitch: number): void;
setLook(yaw: number, pitch: number): void;
/** Relative touch look supports looking below the horizon as well. */
adjustLook(yaw: number, pitch: number): void;
private plan;
private pathDirection;
private cancelDoorwayAdvance;
/** Continue a manual crossing far enough to clear the doorway and OTS boom.
* Only accept a straight, swept-clear segment on the destination side. */
private continueDoorwayCrossing;
/** Assist manual approach to a traversable aperture. Planned paths already
* account for furniture and must retain their collision-checked waypoints. */
private guideThroughDoorway;
private move;
private doorTransforms;
private applyDoorVisuals;
update(seconds: number, input?: {
x: number;
z: number;
}): void;
private updateActorAnimations;
/** Synchronize presentation from the same interpolated transforms already
* applied by SceneRuntime. Call after runtime.update and before the camera. */
postPhysicsUpdate(seconds: number): void;
/** Apply preview-only door presentation after the physics transform lease
* has synchronized the simulated roots. */
applyPresentation(): void;
updateCamera(camera: PerspectiveCamera): void;
reset(): void;
dispose(): void;
/** Temporary direction delegates to this same transform/mixer owner. Snapshot
* includes descendant poses and animation clocks, never authored scene data. */
beginDirection(): void;
direct(cue: Extract<CinematicCue, {
kind: "action";
}>, seconds: number): string | null;
directionResidual(id: string): number | null;
endDirection(persistent?: ReadonlySet<string>): void;
}
export {};
recorded-speech.d.ts
TypeScript
import type { AudioResource } from "@quay/scene-contracts/audio";
/** One decoded utterance at a time; async completions cannot revive stopped cues. */
export declare class RecordedSpeech {
private resolve;
private sharedContext?;
private audioAllowed;
private context;
private source;
private analyser;
private buffer;
private abort;
private epoch;
private offset;
private began;
private disposed;
private samples;
private audioSession;
private previousSessionType;
ended: boolean;
error: string;
loading: boolean;
constructor(resolve: (uri: string) => string, sharedContext?: (() => AudioContext) | undefined, audioAllowed?: () => boolean);
enable(): void;
get running(): boolean;
get state(): {
context: string;
loading: boolean;
running: boolean;
time: number;
duration: number;
error: string;
};
get time(): number;
get duration(): number;
get level(): number;
/** Resume a deferred utterance at the current subtitle time after a gesture. */
seek(seconds: number): void;
load(pin: AudioResource, offset: number): Promise<void>;
update(paused: boolean): void;
pause(): void;
stop(): void;
dispose(): void;
}
scene-runtime.d.ts
TypeScript
import { SceneProjector, type ProjectorOptions, type LoadDocumentOptions } from "@quay/projector";
import { type SceneDocumentV2 } from "@quay/scene-contracts";
import type { Transform } from "@quay/contracts";
import { AnimationMixer } from "three";
export interface TransformSimulation {
update(seconds: number): void;
transforms(interpolate?: boolean): Record<string, Transform>;
}
export interface PhysicsSession extends TransformSimulation {
readonly mode: "paused" | "playing" | "faulted";
play(): void;
pause(): void;
step(): void;
reset(): void;
dispose(): void;
grab(id: string): void;
moveGrab(id: string, position: [number, number, number]): void;
release(id: string): void;
moveCharacter?(id: string, delta: [number, number, number]): void;
setCharacterVelocity?(id: string, velocity: [number, number, number]): void;
setCharacterFacing?(id: string, rotation: [number, number, number, number]): void;
/** Explicit discontinuous relocation used by presentation-level transport.
* Walking continues to use the swept character controller. */
teleportCharacter?(id: string, position: [number, number, number]): void;
capture(): {
sourceHash: string;
revision: number;
poses: Record<string, Transform>;
};
}
export type PhysicsFactory = (scene: SceneDocumentV2, revision: number) => Promise<PhysicsSession>;
/** Shared editor/standalone transform bridge. Owns the lease, not the adapter. */
export declare function bindPhysics(projector: SceneProjector, simulation: TransformSimulation): {
update(seconds: number): void;
sync(): void;
dispose(): void;
};
/** Framework/provider/compiler/engine-independent host for resolved V2 scenes.
* The host injects physics explicitly. Loading never starts it implicitly. */
export declare class SceneRuntime {
private options;
readonly projector: SceneProjector;
private readonly ownsProjector;
private resolved;
private session;
private binding;
private disposed;
private generation;
private pending;
private assetsReady;
private loading;
private projectionLoad;
private animations;
private animatedInstances;
private managedAnimation;
constructor(options: {
projector: SceneProjector;
createPhysics?: PhysicsFactory;
} | {
projection: ProjectorOptions;
createPhysics?: PhysicsFactory;
});
get document(): SceneDocumentV2 | null;
get physics(): PhysicsSession | null;
get initializing(): boolean;
get animationState(): {
mode: string;
time: number;
} | null;
private active;
load(url: string, options?: {
signal?: AbortSignal;
}): Promise<import("@quay/projector").LoadResult>;
loadResolved(value: unknown, options?: LoadDocumentOptions): Promise<import("@quay/projector").LoadResult>;
/**
* Registers a document whose projection is already resident in a borrowed
* projector. This is used by the embedded editor preview: loading the
* projection a second time would discard resolved WRIGHT-only renderables
* such as room backdrops.
*/
adoptResolved(value: unknown): void;
play(revision?: number): Promise<void>;
update(seconds: number): void;
pause(): void;
step(): void;
reset(): void;
stop(): void;
resize(width: number, height: number, pixelRatio?: number): void;
/** Resource context only; no autoplay or authored animation policy. The host
* owns this clock. Phase11 integrates animation semantics/transform ownership. */
createAnimationContext(id: string): {
mixer: AnimationMixer;
clips: import("three").AnimationClip[];
dispose: () => void;
};
/** Opt-in playback of compiled clips, without a physics or compiler dependency.
* Concurrent simulation is rejected until articulated collider ownership exists. */
playAnimations(): void;
dispose(): void;
}
semantic-observer.d.ts
TypeScript
import type { InteractiveLabel, SceneDocumentV2 } from "@quay/scene-contracts";
import type { StudioEvent } from "./studio-events.js";
export type SemanticRuntimeState = {
controlledActorId: string | null;
actorPositions: Readonly<Record<string, readonly [number, number, number]>>;
objectPositions?: Readonly<Record<string, readonly [number, number, number]>>;
recentEvents: readonly StudioEvent[];
ridley: {
id: string;
mode: string;
userControl: boolean;
} | null;
};
export type SemanticRoomFact = {
id: string;
alias: string;
label: string;
};
export type SemanticExitFact = {
id: string;
alias: string;
room: SemanticRoomFact;
direction: "north" | "south" | "east" | "west";
available: boolean;
};
export type SemanticObjectFact = {
id: string;
alias: string;
label: string;
role: string;
notes: string | null;
visible: boolean;
relevant: boolean;
reachable: boolean;
};
export type SemanticLabelFact = {
id: string;
alias: string;
parentObjectId: string;
text: string;
icon: string | null;
kind: InteractiveLabel["action"]["kind"];
title: string | null;
};
export type SemanticActorFact = {
id: string;
label: string;
role: string;
roomId: string | null;
controlled: boolean;
};
export type SemanticActionFact = {
id: string;
kind: "navigate";
targetId: string;
label: string;
available: boolean;
} | {
id: string;
kind: "inspect";
targetId: string;
label: string;
available: true;
} | {
id: string;
kind: "approach";
targetId: string;
label: string;
available: true;
} | {
id: string;
kind: "activate-label";
targetId: string;
objectId: string;
label: string;
actionKind: InteractiveLabel["action"]["kind"];
available: true;
};
export type SemanticSnapshot = {
version: "qway.semantic-observer/1";
room: SemanticRoomFact | null;
rooms: SemanticRoomFact[];
exits: SemanticExitFact[];
objects: SemanticObjectFact[];
actors: SemanticActorFact[];
labels: SemanticLabelFact[];
availableActions: SemanticActionFact[];
recentEvents: StudioEvent[];
ridley: SemanticRuntimeState["ridley"];
};
/** A DOM-free, read-only projection of authored semantics and live runtime
* state. It derives every identifier from the resolved scene and never keeps
* an independent room or transform model. */
export declare class SemanticObserver {
private readonly document;
private readonly state;
private readonly topology;
constructor(document: SceneDocumentV2, state: () => SemanticRuntimeState);
snapshot(): SemanticSnapshot;
}
speech-audio-gate.d.ts
Reference
/** Capture useful gestures even while the world is still downloading. */
export declare function createSpeechAudioGate(): {
getContext: () => AudioContext;
allowed: () => boolean;
readonly state: AudioContextState;
activate(): Promise<void>;
mute(): void;
dispose(): void;
};
speech-voice.d.ts
Reference
export declare function maleItalianVoice(voices: SpeechSynthesisVoice[]): SpeechSynthesisVoice | null;
studio-events.d.ts
Reference
/** Neutral semantic facts. Targets may be object, room, portal or state identities. */
export type StudioEvent = {
type: string;
subject: string | null;
target: string | null;
time: number;
};
/** Iterative delivery bounds reentrant trigger cycles without recursive callbacks. */
export declare class StudioEventBus {
private listeners;
private queue;
private history;
private delivering;
readonly diagnostics: string[];
subscribe(listener: (event: StudioEvent) => void): () => void;
get events(): StudioEvent[];
emit(input: StudioEvent): void;
private issue;
reset(): void;
dispose(): void;
}
talking-human.d.ts
TypeScript
import { type Object3D } from "three";
import type { CinematicDirector } from "./cinematic.js";
/** Morph-only adapter: never owns character transforms, cameras or body clips. */
export declare class TalkingHumanSpeech {
private host;
private root;
private static owner;
private meshes;
private key;
private utterance;
private started;
private anchor;
private anchorTime;
private text;
private rate;
private pausedAt;
private needsGestureRetry;
private requestedAt;
private status;
private latestDirector;
private disposed;
private waitingForVoice;
private recorded;
private recordedCue;
private voicesChanged;
constructor(host: HTMLElement, root: (id: string) => Object3D | undefined, resolveAudio?: (uri: string) => string, context?: () => AudioContext, audioAllowed?: () => boolean);
private clearStatus;
private report;
/** Called synchronously from the host Play click, not a later animation frame.
* Reset even for the same sequence/cue so Replay cannot retain a stale key. */
play(director: CinematicDirector | null): void;
/** Unlock auto-triggered dialogue when the user first interacts with the view. */
activate(director: CinematicDirector | null): void;
private stop;
update(director: CinematicDirector | null, dt: number, suspended: boolean): void;
suspend(): void;
get state(): {
context: string;
loading: boolean;
running: boolean;
time: number;
duration: number;
error: string;
cue: string;
recorded: boolean;
};
dispose(): void;
/** Use audio time once started; silent fallback follows presentation time. */
clockDelta(director: CinematicDirector | null, dt: number): number;
}
touch-controls.d.ts
Reference
/** Analog touch input shares the player's ordinary navigation/collision path. */
export declare function createTouchControls(host: HTMLElement, locale: "en" | "it"): {
clear: () => void;
input: () => {
x: number;
z: number;
};
setEnabled(value: boolean): void;
dispose(): void;
};
touch-look.d.ts
Reference
/** Two fingers on the canvas steer the camera; overlays/joystick are excluded. */
export declare function createTouchLook(canvas: HTMLCanvasElement, enabled: () => boolean, move: (yaw: number, pitch: number) => void): {
clear: () => void;
suppressClick: () => boolean;
dispose(): void;
};
world-events.d.ts
TypeScript
import { Vector3 } from "three";
import type { WrightResolved } from "@quay/scene-contracts/wright";
import type { StudioEvent } from "./studio-events.js";
/** Observes resolved actor feet, not authored membership. Reset establishes a new
* baseline; discontinuous teleports must explicitly reset and never invent crossings. */
export declare class WorldTransitionObserver {
readonly world: WrightResolved;
private previous;
constructor(world: WrightResolved);
roomsAt(position: Vector3): Set<string>;
observe(subject: string, position: Vector3, time: number, continuous?: boolean): StudioEvent[];
reset(): void;
}
world-navigation.d.ts
Reference
export { worldNavigationDomain } from "@quay/spatial/navigation";
world-resources.d.ts
TypeScript
import { type WorldManifest, type WorldSource } from "@quay/worldpack";
/** Verified content-addressed object URLs. No catalog lookup or URI authority from
* snapshots. The host owns the WorldSource; this cache only owns its blob URLs. */
export declare class WorldResources {
private readonly source;
private readonly manifest;
readonly budget: number;
private readonly prepareConcurrency;
private readonly entries;
private disposed;
private bytes;
private pending;
constructor(source: WorldSource, manifest: Pick<WorldManifest, "resources">, budget?: number, prepareConcurrency?: number);
get usage(): {
bytes: number;
resources: number;
};
resolve(path: string): string;
has(path: string): boolean;
prepare(paths: readonly string[], pinned: ReadonlySet<string>, signal?: AbortSignal): Promise<void>;
private prepareNow;
trim(keep: ReadonlySet<string>): void;
private remove;
dispose(): void;
}
worldpack.d.ts
Reference
/** Optional compiled-world entry point. No authoring, provider or physics import. */
import { PerspectiveCamera, Scene, WebGLRenderer } from "three";
import { SceneProjector, type ProjectorOptions } from "@quay/projector";
import { type WorldProfile, type ResolvedWorld, type WorldSource } from "@quay/worldpack";
import { SceneRuntime, type PhysicsFactory } from "./scene-runtime.js";
import { createEmbeddedPreview } from "./embedded-preview.js";
import type { ConversationTransport } from "./conversation.js";
import { SemanticObserver } from "./semantic-observer.js";
export type WorldPlayerMode = "static" | "experience" | "physics";
export type RoomNavigationSource = "direct_url" | "browser_history";
export type WorldPlayerOptions = {
/** Select before fetching scene/media; auto uses input and memory capabilities. */
profile?: WorldProfile | "auto";
/** Lower peak decoding/GPU memory on touch devices. */
quality?: "balanced" | "mobile";
/** Host startup gate, e.g. wait for landscape before decoding any assets. */
startWhen?: Promise<void>;
mode?: WorldPlayerMode;
cacheBytes?: number;
createPhysics?: PhysicsFactory;
signal?: AbortSignal;
disposeSource?: boolean;
onStatus?: (message: string) => void;
conversationTransport?: ConversationTransport;
resolveFloorTextureUri?: ProjectorOptions["resolveFloorTextureUri"];
locale?: "en" | "it";
allowedCameraModes?: readonly number[];
resolveRoomLabel?: (roomIdentity: string, fallback: string) => string;
};
/** The editor previews one unambiguous room finish across all of that room's
* floor tiles. Apply the same transient presentation rule to decoded worlds;
* the packed authoring document remains unchanged. */
export declare function inheritRoomFloorFinishes(world: ResolvedWorld): void;
/** One compiled player for packed, HTTP, memory and filesystem WorldSources.
* Entry geometry renders first. Global compiled metadata then enables the existing
* navigation/director/physics machinery; distant static geometry remains deferred. */
export declare class WorldPlayer {
private readonly host;
private readonly options;
readonly profile: WorldProfile;
private readonly source;
private readonly originalSource;
readonly scene: Scene;
readonly camera: PerspectiveCamera;
readonly renderer: WebGLRenderer;
readonly projector: SceneProjector;
readonly runtime: SceneRuntime;
readonly ready: Promise<void>;
readonly firstFrame: Promise<void>;
private resolveFirst;
private rejectFirst;
private manifest;
private world;
private resources;
private preview;
private observer;
private semanticObserver;
private readonly controller;
private readonly protectedIds;
private residentPaths;
private currentRooms;
private residentRooms;
private busy;
private hostSuspended;
private initialImageLoad;
private pendingNavigation;
private disposed;
private fault;
private mode;
private frame;
private previousTime;
private readonly resize;
private readonly abort;
private readonly speechAudio;
constructor(host: HTMLElement, source: WorldSource, options?: WorldPlayerOptions);
get state(): {
mode: WorldPlayerMode;
profile: WorldProfile;
loading: boolean;
error: string | null;
buildId: string | null;
currentRooms: string[];
residentRooms: string[];
visualPolicy: string;
cache: {
bytes: number;
resources: number;
} | null;
residentInstances: string[];
experience: {
id: string;
mode: "interactive" | "cinematic" | "conversation";
policy: string;
time: number;
audio: {
status: string;
tracks: string[];
nodes: {
assetId: string;
startedAt: number;
gain: number;
spatial: string | null;
position: number[] | null;
}[];
voices: number;
rms: number;
diagnostics: string[];
};
conversation: {
actor: string | null;
persona: string | null;
profileId: string | null;
status: string;
error: string;
messages: import("@quay/scene-contracts/persona").ConversationMessage[];
sessionId: string;
turn: number;
};
diagnostics: string[];
} | null;
};
get document(): ResolvedWorld | null;
get player(): import("./preview.js").PreviewPlayer | null;
get semantics(): SemanticObserver | null;
/** Walk the active human to a compiled WRIGHT room using its route field. */
walkToRoom(roomId: string): void;
/** Walks through the same navigation field used by canvas clicks toward an
* authored semantic object's live projected position. */
walkToObject(objectId: string): void;
/** Resolves resources and places the controlled actor at WRIGHT's
* deterministic room entry. Web hosts may identify why the discontinuous
* navigation occurred without embedding routing policy in RIDLEY. */
enterRoom(roomId: string, source?: RoomNavigationSource): Promise<void>;
activateInteraction(labelId: string, returnFocus?: HTMLElement): void;
get experience(): import("./experience.js").ExperienceDirector | null;
get speechAudioState(): AudioContextState;
activateSpeechAudio(): Promise<void>;
muteSpeechAudio(): void;
/** Pause host playback without resetting the scene or its cinematic clock. */
setSuspended(value: boolean): void;
dispatch(message: Parameters<ReturnType<typeof createEmbeddedPreview>["dispatch"]>[0]): void;
private active;
private fail;
private initialize;
/** One low-priority image at a time, after Home is playable. Foreground
* residency checks share the verified cache and never race its byte budget. */
private prefetchImages;
private initialRooms;
private visualPolicy;
/** Close character shots need their room and neighbours, not every GLB in
* the world. Wide shots or cross-room framing retain global residency. */
private cinematicRooms;
private residency;
private commitResidency;
/** Explicit residency inspection/preload hook; does not teleport any actor. */
setRooms(ids: readonly string[]): Promise<void>;
preload(room: string): Promise<void>;
unloadUnused(): void;
setMode(mode: WorldPlayerMode): Promise<void>;
reset(): Promise<void>;
private update;
dispose(): void;
}
@quay/worldpack
| Import path | Declaration |
|---|---|
| @quay/worldpack/node | ./dist/node.d.ts |
| @quay/worldpack | ./dist/index.d.ts |
codec.d.ts
Reference
/** RFC8949 JSON data-model profile. No tags, indefinite lengths or executable
* extensions. Numbers preserve binary64; ordering and encoding are reproducible. */
export type Json = null | boolean | number | string | Json[] | {
[key: string]: Json;
};
export declare const LIMITS: Readonly<{
files: 4096;
packageBytes: number;
resourceBytes: number;
documentBytes: number;
manifestBytes: number;
depth: 48;
nodes: 2000000;
}>;
export declare function fail(code: string): never;
export declare function checkedJson(value: unknown): Json;
export declare function jsonBytes(value: unknown): Uint8Array<ArrayBuffer>;
export declare function parseJson(bytes: Uint8Array, max?: number): Json;
export declare function sha256(bytes: Uint8Array): Promise<string>;
export declare function encodeCbor(value: unknown): Uint8Array<ArrayBuffer>;
export declare function decodeCbor(bytes: Uint8Array): Json;
documents.d.ts
TypeScript
import { type SceneDocumentV2 } from "@quay/scene-contracts";
import { type CinematicDocument, type RidleyProject } from "@quay/scene-contracts/cinematic";
import { type ExperienceDocument } from "@quay/scene-contracts/experience";
import { type WorldManifest, type ResourceKind } from "./manifest.js";
import { type WorldSource } from "./source.js";
import { type RamsConfig } from "@quay/scene-contracts/rams";
export type ResolvedWorld = {
rams?: RamsConfig;
scene: SceneDocumentV2;
cinematic?: CinematicDocument;
experience?: ExperienceDocument;
};
/** Empty RIDLEY is a valid static project, not a failed experience compilation. */
export declare function acceptedDirection(r: RidleyProject | undefined): Omit<ResolvedWorld, "scene">;
/** Runtime fragments are exact subsets of SceneDocumentV2, never another authored model. */
export type SceneChunk = {
version: "quay.scene-chunk/1";
room: string;
scene: SceneDocumentV2;
};
export type ResourceReader = (input: {
id: string;
uri: string;
hash: string;
bytes: number;
kind: "glb" | "audio" | "image" | "content";
mediaType?: "audio/wav" | "audio/mpeg" | "image/png" | "image/jpeg" | "image/webp" | "application/pdf" | "text/html" | "video/mp4" | "video/webm" | "text/vtt";
}) => Promise<Uint8Array>;
export declare function buildWorldPack(input: ResolvedWorld, read: ResourceReader, options?: {
debug?: boolean;
entryRoom?: string;
resourcePrefix?: (kind: ResourceKind, hash: string) => "desktop" | "mobile" | "shared";
}): Promise<{
manifest: WorldManifest;
files: Map<string, Uint8Array<ArrayBufferLike>>;
bytes: Uint8Array<ArrayBuffer>;
}>;
export declare function loadWorldDocuments(source: WorldSource): Promise<ResolvedWorld>;
export declare function loadRoomDocument(source: WorldSource, id: string): Promise<SceneChunk>;
export declare function verifyWorld(source: WorldSource): Promise<ResolvedWorld>;
glb-codec.d.ts
Reference
export type GlbJson = Record<string, any>;
export declare const GLB_LIMIT: number;
export declare function splitGlb(bytes: Uint8Array): {
json: GlbJson;
bin: Uint8Array;
opaqueChunks: boolean;
};
export declare function packGlb(json: GlbJson, bin: Uint8Array): Uint8Array;
export declare class GlbBuffer {
private chunks;
length: number;
add(bytes: Uint8Array): number;
finish(): Uint8Array<ArrayBuffer>;
}
export declare function inspectWorldGlb(bytes: Uint8Array): Promise<void>;
glb-export.d.ts
TypeScript
import type { ResolvedWorld, ResourceReader } from "./documents.js";
export type GlbTextureEncoder = (bytes: Uint8Array, mediaType: "image/png" | "image/jpeg" | "image/webp") => Promise<Uint8Array | null>;
/** Keep unusual profiles, animation and >8-bit PNGs in their original encoding. */
export declare function pngTextureCandidate(bytes: Uint8Array): boolean;
/** No scene/mesh/material/node reindexing, no quantization, no resampling. */
export declare function optimizeGlb(bytes: Uint8Array, encodeTexture: GlbTextureEncoder): Promise<Uint8Array>;
export declare function glbWorld(world: ResolvedWorld, read: ResourceReader, encodeTexture: GlbTextureEncoder): Promise<{
world: ResolvedWorld;
read: ResourceReader;
}>;
glb-profile.d.ts
TypeScript
import type { ResolvedWorld, ResourceReader } from "./documents.js";
import { type WorldProfile } from "./profiles.js";
export type ProfileTextureEncoder = (bytes: Uint8Array, mediaType: "image/png" | "image/jpeg" | "image/webp", maxEdge: number) => Promise<Uint8Array | null>;
/** Texture-only derivative, including already Meshopt-compressed imported GLBs. */
export declare function profileGlb(original: Uint8Array, encode: ProfileTextureEncoder, edge: number, colorEdge?: number): Promise<Uint8Array<ArrayBufferLike>>;
export declare function profileGlbWorld(world: ResolvedWorld, read: ResourceReader, profile: WorldProfile, encode: ProfileTextureEncoder): Promise<{
world: ResolvedWorld;
read: ResourceReader;
}>;
image-export.d.ts
TypeScript
import type { ResolvedWorld, ResourceReader } from "./documents.js";
export type WebpEncoder = (bytes: Uint8Array, id: string, mediaType: "image/png" | "image/jpeg" | "image/webp") => Promise<Uint8Array>;
/** Export-only derivatives: verify originals, then replace every pinned copy.
* Source project metadata and source uploads are never modified. */
export declare function webpWorld(world: ResolvedWorld, read: ResourceReader, encode: WebpEncoder): Promise<{
world: ResolvedWorld;
read: ResourceReader;
}>;
index.d.ts
Reference
export * from "./codec.js";
export * from "./zip.js";
export * from "./manifest.js";
export * from "./source.js";
export * from "./documents.js";
export * from "./image-export.js";
export { inspectWorldGlb } from "./glb-codec.js";
export * from "./glb-export.js";
export * from "./speech.js";
export * from "./profiles.js";
export * from "./glb-profile.js";
export * from "./site.js";
manifest.d.ts
Reference
export type ResourceKind = "scene" | "world" | "topology" | "experience" | "cinematic" | "glb" | "audio" | "image" | "content" | "metadata" | "debug" | "rams" | "site";
export type Resource = {
path: string;
hash: string;
bytes: number;
kind: ResourceKind;
encoding: "json" | "cbor" | "binary";
dependencies: string[];
};
export type WorldManifest = {
schema: "quay.worldpack";
version: "1.0.0";
container: "zip-store/1";
worldId: string;
sceneId: string;
buildId: string;
runtime: {
scene: "2.0.0-draft.1";
wright: "wright.resolved/1" | null;
experience: "1.0.0" | null;
cinematic: "1.0.0" | null;
capabilities: string[];
};
world: string;
topology: string | null;
experience: string | null;
cinematic: string | null;
entry: {
room: string;
state: string | null;
};
rooms: {
id: string;
chunk: string;
adjacent: string[];
objects: string[];
}[];
assets: {
id: string;
resource: string;
scope: "standard" | "user" | "project";
projectId: string | null;
manifestId: string;
}[];
audio: {
id: string;
resource: string;
}[];
content?: {
id: string;
resource: string;
mediaType: string;
}[];
metadata: {
licenses: string;
provenance: string;
build: string;
};
/** Root inventory includes both profiles; each points to a verified subset manifest. */
profiles?: {
desktop: string;
mobile: string;
};
rams?: {
config: string;
site?: {
entry: string;
files: string[];
};
};
resources: Resource[];
};
export declare function validateManifest(input: unknown): WorldManifest;
export declare function manifestBuildId(m: Omit<WorldManifest, "buildId"> | WorldManifest): Promise<string>;
export declare function verifyManifest(value: unknown): Promise<WorldManifest>;
node.d.ts
TypeScript
import { VerifiedSource, type WorldSource, WorldPackSource } from "./source.js";
/** Explicit host-selected file; reject devices/symlinks and bound before allocation. */
export declare function readLocalFile(path: string, max: number): Promise<Uint8Array<ArrayBuffer>>;
/** Read below an explicit root. Package paths cannot choose another filesystem root. */
export declare function readRootFile(root: string, path: string, max: number): Promise<Uint8Array<ArrayBuffer>>;
export declare class FilesystemWorldSource extends VerifiedSource {
private readonly root;
constructor(root: string);
protected read(path: string, max: number, signal?: AbortSignal): Promise<Uint8Array<ArrayBuffer>>;
}
/** Exclusive atomic publication: hard-linking cannot overwrite an existing target. */
export declare function writeNewFile(path: string, bytes: Uint8Array): Promise<void>;
export declare function openWorldPack(path: string): Promise<WorldPackSource>;
/** No compiler. A failed publication has no manifest and is never a valid world. */
export declare function explodeWorld(source: WorldSource, output: string): Promise<{
directory: string;
files: number;
site: boolean;
capabilities: string[];
bytes: number;
}>;
export declare function serveWorld(source: WorldSource, options?: {
port?: number;
origin?: string;
}): Promise<{
url: string;
close: () => Promise<void>;
}>;
profiles.d.ts
TypeScript
import { type ResolvedWorld, type ResourceReader } from "./documents.js";
import { type Resource } from "./manifest.js";
export type WorldProfile = "desktop" | "mobile";
export declare function selectWorldProfile(preference?: WorldProfile | "auto", hints?: {
coarsePointer: boolean;
memoryGiB: number | undefined;
}): WorldProfile;
export declare const WORLD_PROFILE_LIMITS: {
readonly desktop: {
readonly imageEdge: 2560;
readonly materialEdge: 4096;
readonly actorColorEdge: 4096;
};
readonly mobile: {
readonly imageEdge: 1280;
readonly materialEdge: 512;
readonly actorColorEdge: 1024;
};
};
export declare function profileImageEdge(world: ResolvedWorld, id: string, profile: WorldProfile): 4096 | 512 | 2560 | 1280;
/** Same identities and authored scene; only image/GLB texture bytes may differ. */
export declare function buildProductionWorldPack(variants: Record<WorldProfile, {
world: ResolvedWorld;
read: ResourceReader;
}>, options?: {
debug?: boolean;
entryRoom?: string;
}): Promise<{
manifest: {
profiles: Record<WorldProfile, string>;
resources: Resource[];
schema: "quay.worldpack";
version: "1.0.0";
container: "zip-store/1";
worldId: string;
sceneId: string;
buildId: string;
runtime: {
scene: "2.0.0-draft.1";
wright: "wright.resolved/1" | null;
experience: "1.0.0" | null;
cinematic: "1.0.0" | null;
capabilities: string[];
};
world: string;
topology: string | null;
experience: string | null;
cinematic: string | null;
entry: {
room: string;
state: string | null;
};
rooms: {
id: string;
chunk: string;
adjacent: string[];
objects: string[];
}[];
assets: {
id: string;
resource: string;
scope: "standard" | "user" | "project";
projectId: string | null;
manifestId: string;
}[];
audio: {
id: string;
resource: string;
}[];
content?: {
id: string;
resource: string;
mediaType: string;
}[];
metadata: {
licenses: string;
provenance: string;
build: string;
};
rams?: {
config: string;
site?: {
entry: string;
files: string[];
};
};
};
files: Map<string, Uint8Array<ArrayBufferLike>>;
bytes: Uint8Array<ArrayBuffer>;
profileBytes: Record<WorldProfile, number>;
}>;
site.d.ts
TypeScript
import { type WorldManifest } from "./manifest.js";
export type RamsSiteBundle = {
entry: string;
files: Map<string, Uint8Array>;
};
/** Attach prebuilt trusted application files; this function never executes packaged code. */
export declare function attachRamsSite<T extends {
manifest: WorldManifest;
files: Map<string, Uint8Array>;
bytes: Uint8Array;
}>(pack: T, bundle: RamsSiteBundle): Promise<T>;
export declare function readRamsSiteBundle(index: unknown, read: (path: string) => Promise<Uint8Array>): Promise<RamsSiteBundle>;
source.d.ts
TypeScript
import { type WorldManifest } from "./manifest.js";
export interface WorldSource {
getManifest(signal?: AbortSignal): Promise<WorldManifest>;
getResource(path: string, signal?: AbortSignal): Promise<Uint8Array<ArrayBuffer>>;
dispose(): void;
}
export declare abstract class VerifiedSource implements WorldSource {
private manifest;
protected disposed: boolean;
protected abstract read(path: string, max: number, signal?: AbortSignal): Promise<Uint8Array<ArrayBuffer>>;
protected check(signal?: AbortSignal): void;
getManifest(signal?: AbortSignal): Promise<WorldManifest>;
getResource(path: string, signal?: AbortSignal): Promise<Uint8Array<ArrayBuffer>>;
dispose(): void;
}
export declare class MemoryWorldSource extends VerifiedSource {
protected files: Map<string, Uint8Array<ArrayBuffer>>;
constructor(files: ReadonlyMap<string, Uint8Array>);
protected read(path: string, max: number, signal?: AbortSignal): Promise<Uint8Array<ArrayBuffer>>;
getManifest(signal?: AbortSignal): Promise<WorldManifest>;
dispose(): void;
}
export declare class WorldPackSource extends MemoryWorldSource {
constructor(bytes: Uint8Array);
}
export declare class HttpWorldSource extends VerifiedSource {
private base;
private lifetime;
constructor(url: string);
protected read(path: string, max: number, signal?: AbortSignal): Promise<Uint8Array<ArrayBuffer>>;
dispose(): void;
}
export declare function verifyResources(source: WorldSource): Promise<WorldManifest>;
/** Non-owning view: reads only the chosen profile and shared resources. */
export declare class ProfileWorldSource implements WorldSource {
private readonly source;
readonly profile: "desktop" | "mobile";
private manifest;
private disposed;
constructor(source: WorldSource, profile: "desktop" | "mobile");
getManifest(signal?: AbortSignal): Promise<WorldManifest>;
getResource(path: string, signal?: AbortSignal): Promise<Uint8Array<ArrayBuffer>>;
dispose(): void;
}
speech.d.ts
TypeScript
import { type SpeechVoice } from "@quay/scene-contracts/cinematic";
import { type AudioResource } from "@quay/scene-contracts/audio";
import type { ResolvedWorld } from "./documents.js";
export type SpeechCompiler = (text: string, speech: SpeechVoice) => Promise<AudioResource | null>;
/** Runs only in authoring/export. Runtime receives immutable audio pins. */
export declare function compileWorldSpeech(input: ResolvedWorld, compile: SpeechCompiler, cachedOnly?: boolean): Promise<ResolvedWorld>;
/** Calls QUAY's authoring API; the OpenAI key never leaves that process. */
export declare function speechApiCompiler(apiBase: string, signal?: AbortSignal, cachedOnly?: boolean): SpeechCompiler;
zip.d.ts
Reference
/** Conservative ZIP32 STORE profile: no decompressor, data descriptors, ZIP64,
* encryption, extras or symlinks. Fixed DOS epoch/order for reproducible builds. */
export declare function safePath(path: string): string;
export declare function packZip(files: ReadonlyMap<string, Uint8Array>): Uint8Array<ArrayBuffer>;
export declare function openZip(input: Uint8Array): ReadonlyMap<string, Uint8Array>;
@quay/scene-contracts
| Import path | Declaration |
|---|---|
| @quay/scene-contracts/room-program | ./dist/room-program.d.ts |
| @quay/scene-contracts/audio-bytes | ./dist/audio-bytes.d.ts |
| @quay/scene-contracts/persona | ./dist/persona.d.ts |
| @quay/scene-contracts/audio | ./dist/audio.d.ts |
| @quay/scene-contracts/experience | ./dist/experience.d.ts |
| @quay/scene-contracts/wright | ./dist/wright.d.ts |
| @quay/scene-contracts/ridley-edits | ./dist/ridley-edits.d.ts |
| @quay/scene-contracts/cinematic | ./dist/cinematic.d.ts |
| @quay/scene-contracts/archetypes | ./dist/archetypes.d.ts |
| @quay/scene-contracts | ./dist/index.d.ts |
| @quay/scene-contracts/rams | ./dist/rams.d.ts |
actors.d.ts
Reference
/** Stable identities for the bundled pair of authored navigation actors. */
export declare const DEFAULT_ACTOR_IDENTITIES: {
readonly human: "ef164690-62a9-4817-a6c7-f7cfb6922524";
readonly dog: "f4a01813-f774-4dbc-9b57-3c204f7b31c5";
};
export declare const DEFAULT_ACTOR_ASSETS: {
readonly human: "2eff0198-e3bd-4541-97fb-172a8863d9a8";
readonly dog: "280af97c-c34d-44c0-94f0-2fa1d6572114";
};
archetypes.d.ts
Reference
/** Semantic expectations, never measured mesh geometry or regulatory standards. */
export type DimensionExpectation = {
minM: number;
typicalM: number;
maxM: number;
reference: "whole-bounds" | "withers" | "seat" | "worktop" | "opening";
};
export type ArchetypeProfile = {
schema: "quay.archetype";
schemaVersion: "1.0.0";
profileId: string;
revision: number;
parentId: string | null;
semanticClass: string;
status: "suggested" | "accepted" | "rejected" | "user-corrected";
dimensions: {
width: DimensionExpectation | null;
height: DimensionExpectation | null;
depth: DimensionExpectation | null;
};
preferredDimension: "width" | "height" | "depth" | null;
grounding: "floor" | "support" | "architectural" | "unknown";
orientation: {
up: "+Y" | "+Z" | "+X" | "-Y" | "-Z" | "-X" | null;
forward: "+X" | "-X" | "+Z" | "-Z" | null;
};
affordances: string[];
clearances: {
usableSideM: number | null;
circulationM: number | null;
};
relationHints: string[];
provenance: {
source: "curated" | "standard" | "ai_inferred" | "user_confirmed" | "project_specific";
producer: string;
model: string | null;
inferenceVersion: string;
requestedClass: string | null;
confidence: number;
createdAt: string;
evidence: string[];
};
};
export type SizingDecision = {
measurement?: {
reference: "whole-bounds" | "withers";
targetM: number;
sourceReferenceM: number;
method: "measured-bounds" | "rig-shoulder-envelope-approximation/1";
confidence: number;
evidence: string[];
};
policy: "quay.sizing/1";
measuredDimensions: [number, number, number];
orientedDimensions: [number, number, number];
chosenDimensions: [number, number, number];
finalSceneDimensions?: [number, number, number];
uniformScale: number;
profile: ArchetypeProfile | null;
source: "instance" | "archetype" | "conservative-fallback";
plausibility: "plausible" | "implausible" | "unknown";
diagnostics: string[];
};
export declare function validateArchetype(value: unknown): ArchetypeProfile;
audio-bytes.d.ts
TypeScript
import type { AudioResource } from "./audio-types.js";
export { inspectMp3 } from "./mp3.js";
/** Inspect the container before a browser decoder allocates untrusted PCM. */
export declare function verifyAudioBytes(bytes: ArrayBuffer, pin: AudioResource): Promise<void>;
audio-types.d.ts
Reference
/** Immutable measured audio resource; revision is the original byte hash. */
export type AudioResource = {
version: "ridley.audio/1";
assetId: string;
displayName: string;
sha256: string;
uri: string;
byteLength: number;
mediaType: "audio/wav" | "audio/mpeg";
durationSeconds: number;
sampleRate: number;
channels: 1 | 2;
};
export type MusicCommand = {
action: "play" | "stop" | "crossfade";
assetId: string;
from: string | null;
volume: number;
fade: number;
loop: boolean;
};
audio.d.ts
TypeScript
import type { AudioResource, MusicCommand } from "./audio-types.js";
export type * from "./audio-types.js";
export declare function validateAudioResource(value: unknown): AudioResource;
export declare function validateAudioResources(resources: readonly AudioResource[]): void;
export declare function validateMusic(command: MusicCommand, resources: readonly AudioResource[]): void;
cinematic-types.d.ts
TypeScript
import type { CompilerDiagnostic } from "./types.js";
import type { ExperienceDocument } from "./experience-types.js";
import type { AudioResource, MusicCommand } from "./audio-types.js";
import type { PersonaResource } from "./persona-types.js";
import type { DirectionProfile, RoomDirectionDocument } from "./direction-types.js";
export type { DirectionMood, DirectionProfile, RoomDirectionDocument, RoomDirectionPlan, } from "./direction-types.js";
export type { AudioResource, MusicCommand } from "./audio-types.js";
export type ShotType = "extreme-closeup" | "closeup" | "medium-closeup" | "medium" | "american" | "full" | "long" | "extreme-long" | "two-shot" | "over-the-shoulder" | "pov" | "establishing" | "insert";
export type CameraMovement = "static" | "pan" | "tilt" | "dolly" | "truck" | "pedestal" | "orbit" | "zoom" | "follow" | "crane";
export type CinematicSpan = {
start: number;
end: number;
line: number;
column: number;
};
export type CueTiming = {
id: string;
start: number;
duration: number;
span: CinematicSpan;
};
/** Build-time voice direction; no credentials or provider calls in the player. */
export type SpeechVoice = {
model: "gpt-4o-mini-tts-2025-12-15";
/** @schemaEnum */
voice: "alloy" | "ash" | "ballad" | "coral" | "echo" | "fable" | "nova" | "onyx" | "sage" | "shimmer" | "verse" | "marin" | "cedar";
/** @pattern ^[a-z]{2,3}(-[A-Za-z]{2,8})?$ */
language: string;
/** @maxLength 2000 */
instructions: string;
/**
* @minimum 0.25
* @maximum 4
*/
speed: number;
};
export type CinematicCue = CueTiming & ({
kind: "shot";
type: ShotType;
subjects: string[];
shoulder: string | null;
movement: CameraMovement;
amount: number;
transition: "cut" | "smooth";
} | {
kind: "dialogue" | "subtitle" | "narration";
actor: string | null;
text: string;
speech?: SpeechVoice;
/** @pattern ^[a-f0-9]{8}-[a-f0-9]{4}-[1-8][a-f0-9]{3}-[89ab][a-f0-9]{3}-[a-f0-9]{12}$ */
speechAudio?: string;
} | {
kind: "action";
actor: string;
action: "look-at" | "move-to" | "animate";
target: string | null;
clip: number | null;
persistence: "temporary" | "runtime";
} | {
kind: "emit";
event: string;
target: string | null;
} | {
kind: "music";
command: MusicCommand;
} | {
kind: "sfx";
assetId: string;
spatial: string | null;
volume: number;
} | {
kind: "return";
});
export type CinematicSequence = {
id: string;
duration: number;
cues: CinematicCue[];
};
export type CinematicTrigger = {
id: string;
subject: string;
target: string | null;
event: "near" | "qway.object.enter" | "qway.object.leave" | "qway.relation.changed" | "qway.interaction" | "qway.trigger" | "ridley.complete";
distance: number;
cinematic: string;
once: boolean;
};
/** Runtime-independent direction. No duplicated world geometry or engine handles. */
export type CinematicDocument = {
audio?: AudioResource[];
schema: "quay.cinematic";
version: "1.0.0";
compiler: "ridley.compiler/1";
worldSceneId: string;
worldSourceHash: string;
sourceHash: string;
bindings: Record<string, string>;
/** Fully resolved at compile time; projector never interprets authorial style. */
direction?: RoomDirectionDocument;
sequences: CinematicSequence[];
triggers: CinematicTrigger[];
};
export type Screenplay = {
id: string;
/** @maxLength 200 */
title: string;
/** @maxLength 65536 */
text: string;
};
export type RidleyInput = {
personas?: PersonaResource[];
audio?: AudioResource[];
/** @maxLength 131072 */
source: string;
screenplays: Screenplay[];
bindings: Record<string, string>;
styleProfile?: DirectionProfile;
};
export type RidleyProject = {
personas?: PersonaResource[];
audio?: AudioResource[];
version: "ridley.project/1";
screenplays: Screenplay[];
styleProfile?: DirectionProfile;
draft: {
source: string;
sourceHash: string;
diagnostics: CompilerDiagnostic[];
};
accepted: {
source: string;
document: CinematicDocument | null;
/** Direction is valid independently of an optional authored cinematic. */
direction: RoomDirectionDocument;
experience?: ExperienceDocument;
} | null;
};
export type PlayerMessage = {
type: "ridley.play" | "ridley.goto";
cinematic: string;
} | {
type: "ridley.pause" | "ridley.resume" | "ridley.stop" | "qway.interactive";
} | {
type: "qway.object.enter" | "qway.object.leave" | "qway.relation.changed" | "qway.interaction" | "qway.trigger";
subject: string;
target: string | null;
};
export type CinematicRuntimeState = {
mode: "interactive" | "playing" | "paused" | "faulted";
cinematic: string | null;
time: number;
subtitles: {
actor: string | null;
text: string;
}[];
diagnostics: string[];
};
cinematic.d.ts
TypeScript
import type { CinematicDocument } from "./cinematic-types.js";
export type * from "./cinematic-types.js";
export declare function validateCinematic(value: unknown): CinematicDocument;
deployment.d.ts
Reference
/** Portable profiles only. Secret values belong exclusively to the API SecretStore. */
export type DeploymentProfile = {
id: string;
name: string;
transport: "local" | "ssh" | "sftp" | "rsync" | "scp" | "ftp" | "ftps" | "custom";
host: string;
port: number;
username: string;
destination: string;
credentialRef: string;
strategy: "atomic" | "directory";
buildProfile: "production";
preDeploy: "verify";
postDeploy: "healthcheck";
healthCheck: {
url: string;
expectedStatus: number;
expectedText: string;
};
timeout: number;
keepReleases: number;
compression: boolean;
clean: boolean;
passive: boolean;
tls: boolean;
};
export declare function validateDeploymentProfiles(profiles: DeploymentProfile[]): void;
direction-types.d.ts
Reference
/** Compile-time-only RIDLEY direction policy. Values are renderer-neutral presets. */
export type DirectionStyle = "cinematic" | "restrained" | "surreal" | "documentary" | "elegant" | "playful" | "monumental" | "warm" | "cold" | "technological" | "natural" | "intimate" | "theatrical" | "high-contrast" | "soft-contrast";
export type DirectionMood = "neutral" | "warm" | "cool" | "intimate" | "dramatic" | "monumental" | "clinical" | "mysterious" | "energetic" | "contemplative";
export type RoomDirectionIntent = {
room: string;
intensity?: 0 | 1 | 2 | 3 | 4;
mood?: DirectionMood;
hero?: string | null;
motion?: "none" | "restrained" | "active";
contrast?: "soft" | "natural" | "dramatic";
};
/** Authorial preferences are semantic and are never renderer parameters. */
export type DirectionProfile = {
styles: DirectionStyle[];
rooms?: RoomDirectionIntent[];
};
export type RoomDirectionPlan = {
room: string;
intent: {
intensity: 0 | 1 | 2 | 3 | 4;
mood: DirectionMood;
hero: string | null;
motion: "none" | "restrained" | "active";
contrast: "soft" | "natural" | "dramatic";
};
resolved: {
lightingPreset: "neutral" | "warm" | "cool" | "intimate" | "dramatic-hero" | "monumental" | "clinical";
atmospherePreset: "none" | "subtle-depth" | "haze";
postProcessingPreset: "minimal" | "balanced" | "cinematic" | "hero";
cameraEntryPreset: "none" | "settle" | "slow-reveal" | "hero-reveal";
explorationPreset: "free-stable";
ambientMotion: string[];
performance: {
cinematicHigh: "high" | "balanced" | "minimal";
balanced: "high" | "balanced" | "minimal";
performance: "high" | "balanced" | "minimal";
};
};
rules: {
id: string;
event: "wright.room.enter" | "wright.room.leave" | "qway.object.near" | "ridley.dialogue.start" | "ridley.dialogue.end";
target: string | null;
preset: "entry" | "exploration" | "hero" | "dialogue" | "exit";
once: boolean;
}[];
};
/** Preserves intent separately from renderer instructions and has no executable code. */
export type RoomDirectionDocument = {
schema: "quay.room-direction";
version: "1.0.0";
compiler: "ridley.direction/1";
manual: "ridley.direction-manual/1";
styleProfile: DirectionProfile;
rooms: RoomDirectionPlan[];
};
experience-types.d.ts
Reference
/** RIDLEY policy, not world geometry or engine handles. */
import type { AudioResource, MusicCommand } from "./audio-types.js";
import type { PersonaResource, NpcBinding, ConversationPolicy } from "./persona-types.js";
export type ExperienceState = {
audio?: MusicCommand[];
id: string;
mode: "interactive" | "cinematic" | "conversation";
conversation?: ConversationPolicy;
cinematic: string | null;
control: string | null;
camera: "third-person" | "first-person" | "overhead" | "overview";
userCamera: boolean;
followers: {
actor: string;
target: string;
distance: number;
delay: number;
speed: number;
}[];
};
export type ExperienceTransition = {
id: string;
from: string;
to: string;
event: string;
subject: string | null;
target: string | null;
once: boolean;
};
export type ExperienceDocument = {
personas?: PersonaResource[];
npcs?: NpcBinding[];
audio?: AudioResource[];
schema: "quay.experience";
version: "1.0.0";
compiler: "ridley.experience/1";
worldSceneId: string;
worldSourceHash: string;
sourceHash: string;
bindings: Record<string, string>;
initial: string;
states: ExperienceState[];
transitions: ExperienceTransition[];
};
experience.d.ts
TypeScript
import type { ExperienceDocument } from "./experience-types.js";
export type * from "./experience-types.js";
export declare function validateExperience(input: unknown): ExperienceDocument;
index.d.ts
TypeScript
import type { SceneDocumentV2 } from "./types.js";
export type * from "./types.js";
export { DEFAULT_ACTOR_ASSETS, DEFAULT_ACTOR_IDENTITIES } from "./actors.js";
export declare function validateResolvedScene(value: unknown): SceneDocumentV2;
mp3.d.ts
Reference
/** Bounded MPEG Layer III structure inspection, not a decoder or metadata oracle.
* Duration includes encoded padding/Xing frames: a conservative decoded budget.
*/
export declare function inspectMp3(bytes: Uint8Array): {
sampleRate: number;
channels: number;
durationSeconds: number;
};
persona-types.d.ts
Reference
/** Immutable persona revision. Narrative expectations, never geometry or code. */
export type PersonaDescription = {
name: string;
role: string;
instructions: string;
knowledge: string;
speakingStyle: string;
language: string;
allowedTopics: string[];
forbiddenTopics: string[];
emotionalBaseline: string;
memory: "none" | "session";
maxTurns: number;
maxHistoryChars: number;
};
export type PersonaResource = {
version: "ridley.persona/1";
personaId: string;
profileId: string;
parentId: string | null;
revision: number;
createdAt: string;
sha256: string;
description: PersonaDescription;
};
export type NpcBinding = {
actor: string;
profileId: string;
};
export type ConversationPolicy = {
actor: string;
profileId: string;
};
export type ConversationMessage = {
role: "user" | "assistant";
text: string;
};
export type ConversationRequest = {
profileId: string;
profileHash: string;
actor: string;
sessionId: string;
requestId: string;
turn: number;
messages: ConversationMessage[];
};
export type ConversationResponse = {
sessionId: string;
requestId: string;
turn: number;
profileId: string;
profileHash: string;
status: "ok" | "unavailable";
reply: string | null;
model: string | null;
};
persona.d.ts
TypeScript
import type { PersonaResource } from "./persona-types.js";
export type * from "./persona-types.js";
export declare function validatePersonaResource(input: unknown): PersonaResource;
export declare function validatePersonas(resources: readonly PersonaResource[]): void;
export declare function personaHash(record: PersonaResource): Promise<string>;
export declare function verifyPersonaResource(record: unknown): Promise<PersonaResource>;
physics-types.d.ts
Reference
/** Engine-neutral, resolved collision geometry. Vertices already include instance
* scale and asset normalization, but not the instance root position/quaternion. */
export type ColliderShape = {
kind: "box";
center: [number, number, number];
halfExtents: [number, number, number];
} | {
kind: "convex";
vertices: number[];
} | {
kind: "triangle-mesh";
vertices: number[];
indices: number[];
};
export type PreparedBody = {
instanceId: string;
motion: "static" | "dynamic" | "kinematic";
collision: "solid" | "sensor" | "none";
controller: "none" | "character";
role: string;
canGrab: boolean;
massKg: number;
friction: number;
restitution: number;
colliders: {
shape: ColliderShape;
volumeM3: number;
evidence: string;
approximate: boolean;
}[];
};
export type PreparedPhysics = {
version: "quay.physics-preparation/1";
ready: boolean;
gravity: [number, number, number];
stepSeconds: number;
maxCatchUpSteps: number;
bodies: PreparedBody[];
diagnostics: {
code: string;
severity: "error" | "warning";
instanceId: string | null;
message: string;
}[];
};
program-verification.d.ts
TypeScript
import type { WrightResolved } from "./wright-types.js";
/** Referential integrity for persisted evidence, not geometric re-evaluation.
* A standalone consumer can validate links without importing the compiler. */
export declare function validateProgramVerification(world: WrightResolved, objects: ReadonlySet<string>): void;
rams.d.ts
TypeScript
import { type DeploymentProfile } from "./deployment.js";
export type { DeploymentProfile } from "./deployment.js";
import type { SceneDocumentV2 } from "./types.js";
export type RamsAction = {
kind: "navigate" | "focus" | "overlay" | "page" | "info" | "world-action" | "cinematic";
target: string;
} | {
kind: "external";
url: string;
} | {
kind: "back";
};
export type RamsLink = {
label: string;
action: RamsAction;
};
export type RamsFragment = {
html: string;
css: string;
script: string;
security: "safe" | "controlled-script";
};
export type RamsRoom = {
id: string;
title: string;
summary: string;
description: string;
descriptionSource: "generated" | "authored";
image: string | null;
actions: RamsLink[];
};
export type RamsPanel = {
id: string;
title: string;
kind: "text" | "project" | "about" | "gallery" | "embed" | "html" | "contact" | "component";
text: string;
images: string[];
url: string | null;
fragment: RamsFragment | null;
component: "rooms" | "chat" | null;
actions: RamsLink[];
};
export type RamsRoomPage = {
stableRoomId: string;
slug: string;
canonicalPath: string;
navigationTitle: string;
title: string;
subtitle: string;
seoTitle: string;
seoDescription: string;
html: string;
};
export type RamsPortfolio = {
template: "portfolio";
monogram: string;
rooms: RamsRoomPage[];
welcomeAudio: boolean;
landscapeOnMobile: boolean;
introState: string | null;
};
export type RamsConfig = {
presentation?: RamsPortfolio;
version: "rams.site/1";
title: string;
locale: "it" | "en";
navigation: RamsLink[];
footer: {
text: string;
links: RamsLink[];
branding: boolean;
};
rooms: RamsRoom[];
roomInfo: "card" | "panel" | "chat" | "none";
overlays: RamsPanel[];
pages: RamsPanel[];
assets: {
id: string;
alt: string;
data: string;
}[];
theme: {
mode: "dark" | "light" | "system";
font: "system" | "serif" | "mono";
fontSize: number;
spacing: number;
radius: number;
background: string;
foreground: string;
accent: string;
navigation: "solid" | "glass";
footer: "compact" | "expanded";
overlay: "center" | "side";
transitions: boolean;
logo: string | null;
};
contact: {
endpoint: string | null;
alternative: string;
privacy: string;
fields: {
id: string;
label: string;
required: boolean;
}[];
honeypot: boolean;
};
chat: {
enabled: boolean;
welcome: string;
};
security: {
embedOrigins: string[];
};
deploy: {
target: "static";
basePath: string;
profiles?: DeploymentProfile[];
};
};
export type RamsProject = {
source: string;
config: RamsConfig | null;
error: string | null;
};
export declare function validateRams(value: unknown): RamsConfig;
export declare function validateRamsWorld(config: RamsConfig, scene: SceneDocumentV2): void;
export declare function defaultRams(scene: SceneDocumentV2): RamsConfig;
/** Reject secret-bearing drafts before any project/history/browser persistence. */
export declare function assertRamsNoSecrets(source: string): void;
export declare function compileRams(source: string | undefined, scene: SceneDocumentV2 | undefined, previous?: RamsProject): RamsProject | undefined;
ridley-edits.d.ts
TypeScript
import type { ExperienceState, ExperienceTransition } from "./experience-types.js";
import type { MusicCommand } from "./audio-types.js";
import type { ConversationPolicy } from "./persona-types.js";
import type { ShotType, CameraMovement, CinematicTrigger } from "./cinematic-types.js";
type Timing = {
film: string;
id: string;
at: number;
duration: number;
};
export type RidleyEdit = (Omit<ExperienceState, "conversation"> & {
kind: "experience-state";
audio: MusicCommand[];
conversation?: ConversationPolicy | null;
}) | (ExperienceTransition & {
kind: "experience-transition";
}) | {
kind: "music";
film: string;
id: string;
at: number;
command: MusicCommand;
} | {
kind: "sfx";
film: string;
id: string;
at: number;
assetId: string;
spatial: string | null;
volume: number;
} | (Timing & {
kind: "shot";
shotType: ShotType;
subjects: string[];
shoulder: string | null;
movement: CameraMovement;
amount: number;
transition: "cut" | "smooth";
}) | (Timing & {
kind: "dialogue" | "subtitle" | "narration";
actor: string | null;
text: string;
}) | (Timing & {
kind: "action";
actor: string;
action: "look-at" | "move-to" | "animate";
target: string | null;
clip: number | null;
persistence: "temporary" | "runtime";
}) | {
kind: "emit" | "return";
film: string;
id: string;
at: number;
event: string | null;
target: string | null;
} | {
kind: "trigger";
id: string;
subject: string;
target: string | null;
event: CinematicTrigger["event"];
distance: number;
cinematic: string;
once: boolean;
} | {
kind: "remove-cue";
film: string;
id: string;
};
export type RidleySuggestion = {
operations: RidleyEdit[];
warnings: string[];
};
export declare function validateRidleyEdits(value: unknown): RidleySuggestion;
export {};
room-program-types.d.ts
Reference
/** Functional intent, not geometry or a second object registry. */
export type ProgramPriority = "required" | "recommended" | "optional";
export type ProgramProducer = {
provider: string;
model: string;
version: string;
};
export type ProgramRepair = {
stage: "semantic";
attempts: number;
strategy: "none" | "bounded-semantic-revision";
initialFailures: string[];
finalState: "accepted";
relaxedConstraints: string[];
};
export type ProgramEvidence = {
origin: "explicit" | "archetype" | "inferred";
confidence: number;
explanation: string;
};
export type FunctionalZone = {
reference: string;
purpose: string;
priority: ProgramPriority;
};
export type ProgramNeed = {
reference: string;
category: string;
zone: string;
quantity: number;
capacity: number | null;
priority: ProgramPriority;
assetAlias: string | null;
placement: "auto" | "center" | "perimeter";
evidence: ProgramEvidence;
};
export type ProgramRule = {
reference: string;
kind: "on" | "seating" | "beside" | "facing" | "near-window" | "wall-alignment" | "interior" | "access" | "visibility" | "clearance" | "circulation" | "minimum-dimensions" | "unsupported";
subjects: string[];
target: string | null;
priority: ProgramPriority;
strength: "hard" | "soft";
clearanceM: number | null;
description: string;
evidence: ProgramEvidence;
};
export type ArchitecturalNeed = {
reference: string;
kind: "window" | "portal" | "wall-run" | "open-center" | "natural-light" | "ceiling-light";
quantity: number;
priority: ProgramPriority;
evidence: ProgramEvidence;
};
export type RoomProgram = {
version: "qway.room-program/1";
archetype: string;
archetypeRevision: string;
purpose: string;
capacity: number;
style: string;
zones: FunctionalZone[];
needs: ProgramNeed[];
rules: ProgramRule[];
architecture: ArchitecturalNeed[];
exclusions: {
category: string;
evidence: {
origin: "explicit";
confidence: number;
explanation: string;
};
}[];
uncertainties: string[];
};
/** Derived geometric evidence. Never accepted as an authoring instruction. */
export type ProgramCheckStatus = "satisfied" | "failed" | "unknown" | "unsupported";
export type ProgramPairEvidence = {
subject: string;
target: string | null;
status: ProgramCheckStatus;
/** @maxLength 2000 */
message: string;
residuals: Record<string, number>;
};
export type ProgramRuleCheck = {
reference: string;
kind: ProgramRule["kind"];
priority: ProgramPriority;
strength: "hard" | "soft";
status: ProgramCheckStatus;
/** @maxLength 2000 */
message: string;
pairs: ProgramPairEvidence[];
};
export type RoomProgramVerification = {
policy: "qway.room-program-geometry/1" | "qway.room-program-geometry/2" | "qway.room-program-geometry/3";
actor: {
radiusM: number;
heightM: number;
};
rooms: {
room: string;
archetypeRevision: string;
layout?: ProgramLayoutEvidence;
inventory: {
reference: string;
priority: ProgramPriority;
requestedUnits: number;
resolvedUnits: number;
status: ProgramCheckStatus;
}[];
rules: ProgramRuleCheck[];
architecture: {
reference: string;
kind: ArchitecturalNeed["kind"];
priority: ProgramPriority;
requested: number;
verified: number;
status: ProgramCheckStatus;
/** @maxLength 2000 */
message: string;
}[];
}[];
};
/** Bounded deterministic search provenance, not a geometric success assertion. */
export type ProgramLayoutEvidence = {
policy: "qway.room-program-layout/1";
strategy: "bounded-geometric-search";
candidateBudget: number;
candidatesTested: number;
passesPerformed: number;
initialRules: {
reference: string;
status: ProgramCheckStatus;
}[];
changedInstances: string[];
relaxedConstraints: string[];
termination: "stationary" | "budget-exhausted" | "pass-limit" | "zero-score";
};
room-program.d.ts
TypeScript
import type { ProgramRepair, RoomProgram } from "./room-program-types.js";
export type * from "./room-program-types.js";
export declare function validateProgramRepair(value: unknown): ProgramRepair;
/** Checks intent integrity only. Satisfied geometry requires separate evaluators. */
export declare function validateRoomProgram(value: unknown): RoomProgram;
types.d.ts
TypeScript
import type { MaterialDefinition } from "@quay/contracts";
import type { AssetSnapshot, SceneDocument, Transform } from "@quay/contracts";
import type { PreparedPhysics } from "./physics-types.js";
import type { SizingDecision } from "./archetypes.js";
import type { WrightResolved } from "./wright-types.js";
export type { PreparedPhysics, PreparedBody, ColliderShape, } from "./physics-types.js";
/** UTF-16 source metadata, not a parser dependency. */
type Span = {
start: number;
end: number;
line: number;
column: number;
};
export type CompilerDiagnostic = {
code: string;
severity: "error" | "warning" | "info";
message: string;
span: Span | null;
identity: string | null;
};
export type Dependency = {
assetId: string;
manifestId: string;
analysisRevision: string;
contentHash: string;
};
export type FeatureReference = {
identity: string;
manifestId: string | null;
featureId: string | null;
kind: "object" | "surface" | "component" | "collider";
};
export type PhysicalComponent = {
motion: "static" | "dynamic" | "kinematic";
collision: "solid" | "sensor" | "none";
controller: "none" | "character";
collider: FeatureReference | null;
shape?: "auto" | "box" | "convex-hull" | "decomposition" | "triangle-mesh";
massKg: number | null;
friction: number | null;
restitution: number | null;
provenance: Record<string, "instance" | "asset-override" | "profile" | "inference" | "fallback">;
};
export type SemanticObject = {
materialId?: string;
region?: "center" | "perimeter";
actor?: {
policy: "quay.actor-box/1";
size: [number, number, number];
eye: [number, number, number];
manipulationOrigin: [number, number, number];
reachM: number;
};
animation?: {
policy: "quay.animation/1";
clipIndex: number;
clipName: string | null;
mode: "in-place" | "articulated";
speed: number;
loop: boolean;
offsetSeconds: number;
};
normalization?: AssetSnapshot["normalization"];
orientation?: {
policy: "quay.orientation/1" | "quay.orientation/2";
quaternion: [number, number, number, number];
up: string | null;
front: string | null;
confidence: number;
evidence: string[];
};
identity: string;
alias: string;
label: string;
/** @maxLength 2000 */
notes?: string;
assetId: string;
manifestId: string;
role: string;
visible: boolean;
pose: Partial<Transform>;
size: [number, number, number] | null;
sizing?: SizingDecision;
architecture?: {
boundary: "left" | "right" | "back" | "front";
section: "full" | "opening-left" | "opening-right" | "opening-header" | "opening-sill";
opening: string | null;
};
physics: PhysicalComponent;
interaction: {
capabilities: ("grab" | "open" | "close" | "toggle" | "walk" | "animate")[];
enabled: boolean;
cooldownSeconds: number;
};
span: Span;
};
export type SemanticWallMountedImage = {
materialId?: string;
identity: string;
alias: string;
label: string;
assetId: string;
wallInstanceId: string;
uri: string;
sha256: string;
byteLength: number;
mediaType: "image/png" | "image/jpeg" | "image/webp";
displayName: string;
position: [number, number];
size: [number, number];
surfaceOffset: number;
preserveAspectRatio: boolean;
span: Span;
};
export type InteractiveLabelAction = {
kind: "none";
} | {
kind: "pdf" | "html" | "audio" | "video";
assetId: string;
uri: string;
sha256: string;
byteLength: number;
mediaType: string;
displayName: string;
title: string | null;
posterUri: string | null;
captionsUri: string | null;
autoplay: boolean;
loop: boolean;
muted: boolean;
volume: number;
restartOnOpen: boolean;
startSeconds: number;
endSeconds: number | null;
} | {
kind: "ridley";
target: string;
} | {
kind: "external-link";
/** @maxLength 2048 */
url: string;
};
/** A presentation-only child of an object. It never enters layout or physics. */
export type InteractiveLabel = {
identity: string;
alias: string;
/** Semantic object or wall/floor poster identity; posters remain render-only. */
parentObjectId: string;
/** @maxLength 200 */
text: string;
icon: string | null;
anchor: "above" | "center" | "front" | "left" | "right" | "custom";
offset: [number, number, number];
maxDistance: number | null;
billboard: boolean;
theme: "default" | "cool" | "warm";
action: InteractiveLabelAction;
span: Span;
};
export type SemanticRelation = {
identity: string;
kind: "on" | "inside" | "beside" | "against" | "facing" | "attached-to" | "keep-clear" | "reachable-from";
subject: FeatureReference;
target: FeatureReference | null;
temporal: "initial" | "monitor" | "maintain";
strength: "hard" | "soft";
weight: number;
parameters: Record<string, string | number | number[]>;
sourceCommand: string;
span: Span;
};
export type Versions = {
compiler: "quay.compiler/1";
layout: "quay.legacy-layout-adapter/1" | "quay.semantic-layout/1" | "quay.semantic-layout/2";
policy: "quay.static-policy/1" | "quay.physical-policy/1";
};
export type SemanticProgram = {
materials?: MaterialDefinition[];
assetPolicy?: "project-user-standard";
composition?: "quay.room-composition/1";
version: "quay.semantic/1";
sceneId: string;
name: string;
seed: number;
room: {
identity: string | null;
size: [number, number, number];
};
profile: "static" | "physical";
objects: SemanticObject[];
wallImages?: SemanticWallMountedImage[];
interactiveLabels?: InteractiveLabel[];
relations: SemanticRelation[];
bindings: Record<string, string>;
dependencies: Dependency[];
versions: Versions;
};
export type RelationEvaluation = {
identity: string;
status: "satisfied" | "failed" | "unknown" | "unsupported";
message: string;
residuals: Record<string, number>;
};
/** Projection owns transforms exactly once. Semantic intent never contains runtime handles. */
export type SceneDocumentV2 = {
wright?: WrightResolved;
schema: "quay.scene";
schemaVersion: "2.0.0-draft.1";
semantic: SemanticProgram;
projection: SceneDocument;
evaluations: RelationEvaluation[];
diagnostics: CompilerDiagnostic[];
provenance: {
sourceHash: string;
versions: Versions;
dependencies: Dependency[];
};
readiness: "static-preview";
physics?: PreparedPhysics;
};
wright-types.d.ts
TypeScript
import type { ProgramProducer, ProgramRepair, RoomProgram, RoomProgramVerification } from "./room-program-types.js";
/** Rigid room frames preserve metres, gravity and object normalization. */
export type RoomFrame = {
position: [number, number, number];
quaternion: [number, number, number, number];
};
/** Requested contents and source-identity bindings, never an alternate scene. */
export type FurnishingNeed = {
identity: string;
category: string;
quantity: number;
capacity: number | null;
assetAlias: string | null;
placement: "auto" | "center" | "perimeter";
relation: "on" | "seating" | "near-window" | null;
target: string | null;
/** One group per requested unit; modular furnishings can use several objects. */
instances: string[][];
};
export type RoomFurnishing = {
/** Accepted functional intent and exact editorial input; never refresh on load. */
roomProgram?: {
repair?: ProgramRepair;
enrichment?: ProgramProducer;
intent: RoomProgram;
archetypeSnapshot: RoomProgram;
/** Room-local need reference -> existing FurnishingNeed identity. */
bindings: Record<string, string>;
};
version: "qway.furnishing/1";
purpose: string;
capacity: number;
style: string;
needs: FurnishingNeed[];
};
export type RoomBackdropSource = {
kind: "image";
assetId: string;
uri: string;
mediaType: "image/png" | "image/jpeg" | "image/webp";
sha256: string;
byteLength: number;
} | {
kind: "asset";
uri: null;
assetId: string;
};
export type RoomBackdrop = {
materialId?: string;
identity: string;
/** Human-authored semantic description, not a renderable object label. */
/** @maxLength 200 */
semantic: string;
source: RoomBackdropSource;
side: "north" | "south" | "east" | "west";
mode: "architectural";
fit: "cover" | "contain";
projection: "flat";
distance: number;
lighting: "unlit" | "lit";
enabled: boolean;
};
export type RoomBackdropMap = {
north?: RoomBackdrop;
south?: RoomBackdrop;
east?: RoomBackdrop;
west?: RoomBackdrop;
};
export type WrightRoom = {
furnishing?: RoomFurnishing;
identity: string;
/** @maxLength 100 */
alias: string;
/** @maxLength 200 */
label: string;
level: string | null;
parent: string | null;
size: [number, number, number];
frame: RoomFrame;
/** Room-owned exterior views, keyed by room-local cardinal side. */
backdrop?: RoomBackdrop | RoomBackdropMap;
};
export type WrightPortal = {
identity: string;
/** @maxLength 100 */
alias: string;
from: string;
to: string;
/** Frame in the from-room's coordinates; local X width, Y height, Z normal. */
frame: RoomFrame;
width: number;
height: number;
traversable: boolean;
door: string | null;
};
/** An exterior entrance belongs to one real room; no fabricated outside room. */
export type WrightEntrance = {
identity: string;
/** @maxLength 100 */
alias: string;
room: string;
/** Room-local X width, Y height, Z outward normal. */
frame: RoomFrame;
width: number;
height: number;
traversable: boolean;
door: string | null;
};
export type WrightInput = {
version: "wright.world/1";
identity: string;
rooms: WrightRoom[];
levels: {
identity: string;
label: string;
}[];
portals: WrightPortal[];
entrances?: WrightEntrance[];
/** Object UUID -> room UUID. No independent object registry or transforms. */
membership: Record<string, string>;
};
export type WrightResolved = {
version: "wright.resolved/1";
topology: WrightInput;
worldFrames: Record<string, RoomFrame>;
/** Compiled room-local poses remain reproducible when world frames move. */
localPoses: Record<string, RoomFrame & {
scale: [number, number, number];
}>;
/** Independently measured functional-program evidence, never authorable. */
programVerification?: RoomProgramVerification;
/** Derived from resolved geometry, never an authorable topology assertion. */
verification?: {
policy: "wright.portal-geometry/1";
actor: {
radius: number;
height: number;
};
portals: {
identity: string;
requestedAperture: "clear" | "collision" | "unknown";
actorPassage: "clear" | "collision" | "unknown";
}[];
entrances?: {
identity: string;
requestedAperture: "clear" | "collision" | "unknown";
actorPassage: "clear" | "collision" | "unknown";
}[];
circulation: {
room: string;
status: "ready" | "unresolved" | "unsupported" | "not-requested";
entryCount: number;
reachableSamples: number;
routeOutcomes: string[];
}[];
/** Conservative world-space occupancy after subtracting only proven empty
* volumes. Runtime still expands these boxes by its actual actor radius. */
navigationBoxes: Record<string, {
min: [number, number, number];
max: [number, number, number];
}[]>;
};
diagnostics: {
code: string;
severity: "error" | "warning";
identity: string | null;
message: string;
}[];
};
wright.d.ts
TypeScript
import type { WrightInput } from "./wright-types.js";
export type * from "./wright-types.js";
/** Structural and graph validation only. Geometric feasibility is independent. */
export declare function validateWright(value: unknown, objects?: ReadonlySet<string>): WrightInput;
@quay/semantic-compiler
| Import path | Declaration |
|---|---|
| @quay/semantic-compiler/ridley | ./dist/ridley.d.ts |
| @quay/semantic-compiler/capture | ./dist/capture.d.ts |
| @quay/semantic-compiler/contract | ./dist/validation.d.ts |
| @quay/semantic-compiler | ./dist/index.d.ts |
audio.d.ts
TypeScript
import type { Command, Value } from "@quay/scene-language";
import type { CompilerDiagnostic } from "@quay/scene-contracts";
import { type AudioResource, type MusicCommand } from "@quay/scene-contracts/audio";
/** Source explicitly adopts immutable resources. Asset names never resolve identity. */
export declare function compileAudio(roots: Command[], available: AudioResource[], occupiedAliases: string[], previous: Record<string, string>): {
diagnostics: CompilerDiagnostic[];
resources: AudioResource[];
bindings: Record<string, string>;
reference: (value: Value | undefined, command: Command) => string;
music: (command: Command, timingArguments?: string[]) => MusicCommand;
};
capture.d.ts
TypeScript
import type { ProjectDocument } from "./types.js";
import type { Transform } from "@quay/contracts";
export type CaptureInput = {
sourceHash: string;
revision: number;
poses: Record<string, Transform>;
};
/** Explicit source edit only. The caller must compile/save the resulting draft.
* Relations are preserved unless their exact identities are explicitly selected. */
export declare function captureToSource(project: ProjectDocument, source: string, capture: CaptureInput, removeRelations?: string[]): Promise<string>;
compile.d.ts
TypeScript
import type { SpatialContext } from "./spatial/context.js";
import type { Compilation, CompileInput, Versions } from "./types.js";
export declare const VERSIONS: Versions;
/** No clock, random identities, network or mutable catalog reads. Inputs are explicit snapshots. */
export declare function compile(input: CompileInput, spatial?: SpatialContext): Promise<Compilation>;
direction.d.ts
TypeScript
import type { CompilerDiagnostic, SceneDocumentV2 } from "@quay/scene-contracts";
import type { DirectionProfile, RoomDirectionDocument } from "@quay/scene-contracts/cinematic";
/** The repository's global, versioned interpretation of the Direction Manual.
* It is deliberately data-free at runtime: this policy is consumed only here. */
export declare const DIRECTION_MANUAL: "ridley.direction-manual/1";
/** Deterministically compiles WRIGHT/QWAY/RIDLEY/style inputs into presets, never GPU values. */
export declare function compileDirection(world: SceneDocumentV2, profile: DirectionProfile | undefined, cinematicCount: number, dialogueCount: number): {
document: RoomDirectionDocument;
diagnostics: CompilerDiagnostic[];
};
experience.d.ts
TypeScript
import type { Command } from "@quay/scene-language";
import type { compileAudio } from "./audio.js";
import type { compilePersonas } from "./personas.js";
import type { CompilerDiagnostic, SceneDocumentV2 } from "@quay/scene-contracts";
import { type ExperienceDocument } from "@quay/scene-contracts/experience";
/** Closed, typed lowering of the experience root. It cannot author transforms. */
export declare function compileExperience(roots: Command[], world: SceneDocumentV2, sourceHash: string, objectAliases: [string, string][], previous: Record<string, string>, films: string[], audio?: ReturnType<typeof compileAudio>, personas?: Awaited<ReturnType<typeof compilePersonas>>): {
document: ExperienceDocument | null;
diagnostics: CompilerDiagnostic[];
};
hash.d.ts
Reference
export declare function hashSource(source: string): Promise<string>;
export declare function derivedIdentity(key: string): Promise<string>;
index.d.ts
Reference
export * from "./types.js";
export * from "./compile.js";
export * from "./hash.js";
export * from "./project.js";
export * from "./validation.js";
export * from "./manipulation.js";
export { roomLocalTransform } from "./wright.js";
export { solveSemantic } from "./spatial/solve.js";
export { evaluate } from "./spatial/evaluate.js";
export { body, collision, regionCollision, surfaces, authoringTransform, } from "./spatial/geometry.js";
export { clearOpeningCandidate } from "./opening-candidate.js";
export * from "./material-authoring.js";
layout.d.ts
TypeScript
import type { CompileInput, CompilerDiagnostic, SceneDocumentV2, SemanticProgram } from "./types.js";
import type { SpatialContext } from "./spatial/context.js";
export declare function project(program: SemanticProgram, input: CompileInput, sourceHash: string, diagnostics: CompilerDiagnostic[], spatial?: SpatialContext): SceneDocumentV2;
legacy-layout.d.ts
TypeScript
import type { CompileInput, CompilerDiagnostic, SceneDocumentV2, SemanticProgram } from "./types.js";
/** Pinned Phase 4 compatibility adapter. Never reinterpret historical projects silently. */
export declare function project(program: SemanticProgram, input: CompileInput, sourceHash: string, diagnostics: CompilerDiagnostic[]): SceneDocumentV2;
manipulation.d.ts
TypeScript
import type { AssetManifest } from "@quay/asset-analysis/contract";
import type { Transform } from "@quay/contracts";
import type { SceneDocumentV2 } from "./types.js";
/** Authoring-only mapping. Uses the same measured frames as layout/evaluation.
* This proposes parameters; only the subsequent independent compile can accept them. */
export declare function supportDragOffset(scene: SceneDocumentV2, manifests: AssetManifest[], identity: string, desired: Transform): {
relationId: string;
offset: [number, number];
} | null;
material-authoring.d.ts
TypeScript
import { type MaterialDefinition } from "@quay/contracts";
export declare function materialSource(material: MaterialDefinition): string;
/** Edits only source spans; identity and bindings remain authoritative. */
export declare function editMaterialSource(source: string, bindings: Record<string, string>, targetId: string | null, material: MaterialDefinition | null): string;
export declare function presetMaterial(identity: string, preset: string): MaterialDefinition;
material-migration.d.ts
TypeScript
import type { ProjectDocument } from "./types.js";
/** No solver, manifest refresh, clock, network, GLB mutation or random IDs. */
export declare function migrateProjectMaterials(value: ProjectDocument): Promise<ProjectDocument>;
opening-candidate.d.ts
TypeScript
import { type Body } from "./spatial/geometry.js";
/** Bounded proposal for a NEW automatic portal, not a certified manifest feature.
* Final world verification independently includes both frames and all obstacles. */
export declare function clearOpeningCandidate(body: Body): {
width: number;
height: number;
} | null;
orientation.d.ts
TypeScript
import type { AssetSnapshot } from "@quay/contracts";
import type { AssetManifest } from "@quay/asset-analysis/contract";
export type Axis = "+X" | "-X" | "+Y" | "-Y" | "+Z" | "-Z";
export type OrientationDecision = {
policy: "quay.orientation/1" | "quay.orientation/2";
quaternion: [number, number, number, number];
up: Axis | null;
front: Axis | null;
confidence: number;
evidence: string[];
};
/** Rest geometry only. Joint labels are semantic clues, accepted only alongside
* a real skin and coherent measured joint positions. Symmetric solids cannot
* identify their front. No longest-axis-as-up rule or source mutation. */
export declare function resolveOrientation(manifest: AssetManifest, asset: AssetSnapshot, semanticClass: string | undefined, explicit?: {
up?: Axis;
front?: Axis;
}, archetype?: {
up?: Axis;
front?: Axis;
}): OrientationDecision;
personas.d.ts
TypeScript
import type { Command } from "@quay/scene-language";
import type { CompilerDiagnostic } from "@quay/scene-contracts";
import { type PersonaResource, type NpcBinding } from "@quay/scene-contracts/persona";
export declare function compilePersonas(roots: Command[], available: PersonaResource[], objectAliases: [string, string][], occupied: string[], previous: Record<string, string>): Promise<{
diagnostics: CompilerDiagnostic[];
resources: PersonaResource[];
npcs: NpcBinding[];
bindings: Record<string, string>;
conversation: (c: Command) => {
actor: string;
profileId: string;
};
}>;
physical-profile.d.ts
TypeScript
import type { AssetManifest } from "@quay/asset-analysis/contract";
import type { PhysicalComponent } from "./types.js";
/** Role is explicitly authored/accepted, never taken from untrusted node names.
* Constants are versioned gameplay policy, not measured material properties. */
export declare function physicalProfile(role: string, manifest: AssetManifest, physical: boolean, semanticClass?: string, assetCategory?: string): PhysicalComponent;
physics-types.d.ts
Reference
/** Compatibility re-export: resolved physics types live outside authoring. */
export type { PreparedPhysics, PreparedBody, ColliderShape, } from "@quay/scene-contracts";
prepare-physics.d.ts
TypeScript
import type { CompileInput, SceneDocumentV2, PreparedPhysics, PreparedBody } from "./types.js";
type Part = PreparedBody["colliders"][number];
/** Exact bounded star-kernel tetrahedral decomposition, never a pretend V-HACD.
* Requires closed consistently wound welded edges and a center behind every face.
* General concavity without a verified kernel is unsupported. */
export declare function decompose(vertices: number[], indices: number[]): Part[];
export declare function preparePhysics(scene: SceneDocumentV2, input: CompileInput): PreparedPhysics;
export {};
project.d.ts
TypeScript
import type { CompileInput, ProjectDocument } from "./types.js";
export declare function createProject(projectId: string, now: string): Promise<ProjectDocument>;
/** A pure authoring transaction. Failed drafts never replace accepted source/scene/bindings. */
export declare function reviseProject(previous: ProjectDocument, input: CompileInput, expectedRevision: number, now: string): Promise<ProjectDocument>;
ridley.d.ts
TypeScript
import type { SceneDocumentV2, CompilerDiagnostic } from "@quay/scene-contracts";
import type { CameraMovement, CinematicDocument, RidleyInput, RidleyProject, ShotType } from "@quay/scene-contracts/cinematic";
import type { PersonaResource } from "@quay/scene-contracts/persona";
import type { AudioResource } from "@quay/scene-contracts/audio";
import type { ExperienceDocument } from "@quay/scene-contracts/experience";
export declare const SHOTS: readonly ShotType[];
export declare const MOVEMENTS: readonly CameraMovement[];
export type RIDLEYProgram = {
document: CinematicDocument | null;
experience: ExperienceDocument | null;
diagnostics: CompilerDiagnostic[];
};
/** Aliases are views of existing objects, never a second actor registry. */
export declare function cinematicAliases(world: SceneDocumentV2): [string, string][];
/** Semantic lowering only. Camera geometry is resolved against the live player. */
export declare function compileRidley(source: string, world: SceneDocumentV2, previousBindings?: Record<string, string>, clips?: Record<string, number[]>, audioResources?: AudioResource[], personaResources?: PersonaResource[], styleProfile?: RidleyInput["styleProfile"]): Promise<RIDLEYProgram>;
export declare function reviseRidley(input: RidleyInput, world: SceneDocumentV2, previous: RidleyProject | undefined, clips: Record<string, number[]>): Promise<RidleyProject>;
/** Timeline edits replace only the named value span and reject stale drafts. */
export declare function editRidleyTiming(source: string, expected: string, id: string, key: "at" | "duration", seconds: number): string;
room-program-cost.d.ts
TypeScript
import { Box3 } from "three";
import type { RoomFurnishing } from "@quay/scene-contracts/wright";
import type { Body } from "./spatial/geometry.js";
/** Cheap bounded proposal score only: a free endpoint is NOT a connected route.
* Final verification still requires the actual entrance network and path search. */
export declare function functionalApproachCost(furnishing: RoomFurnishing, bodies: ReadonlyMap<string, Body>, size: readonly number[], approaches?: readonly Box3[]): number;
room-program-evaluation.d.ts
TypeScript
import type { RoomFurnishing, WrightResolved } from "@quay/scene-contracts/wright";
import type { ProgramRuleCheck, RoomProgramVerification } from "@quay/scene-contracts/room-program";
import type { Body } from "./spatial/geometry.js";
import { type ProgramRoomRegion } from "./room-program-interior.js";
/** Quantification is over every requested unit, not merely the first matching
* object. Missing geometry cannot disappear through filtering undefined bodies. */
export declare function evaluateProgramRules(furnishing: RoomFurnishing, bodies: ReadonlyMap<string, Body>, room?: ProgramRoomRegion): ProgramRuleCheck[];
/** Final arbitrary-pose inspection. A solver's success flag is never an input. */
export declare function verifyRoomPrograms(world: WrightResolved, bodies: readonly Body[]): RoomProgramVerification;
room-program-interior.d.ts
TypeScript
import type { ProgramRule } from "@quay/scene-contracts/room-program";
import type { RoomFrame } from "@quay/scene-contracts/wright";
import { type Body } from "./spatial/geometry.js";
import type { ProgramPredicateEvidence } from "./room-program-predicates.js";
export type ProgramRoomRegion = {
size: readonly number[];
frame?: RoomFrame;
};
/** Derived central-interior evidence, never a candidate placement or route test.
* World dimensions/frame own the region; imported GLB dimensions do not define it.
* 0.35m boundary separation is not a walking/ergonomic clearance certificate. */
export declare function evaluateProgramInterior(rule: ProgramRule, subject: Body, room?: ProgramRoomRegion): ProgramPredicateEvidence;
room-program-navigation.d.ts
TypeScript
import { Vector3 } from "three";
import type { WrightResolved, WrightRoom } from "@quay/scene-contracts/wright";
import type { ProgramPairEvidence, ProgramRule, ProgramRuleCheck } from "@quay/scene-contracts/room-program";
import { type Body } from "./spatial/geometry.js";
type Entry = {
identity: string;
point: Vector3;
};
/** Versioned candidate locations, not route certificates. Shared by proposal
* scoring and the independent final route evaluator. */
export declare function functionalApproachPoints(body: Body, category: string, floorY: number): Vector3[];
/** Bounded same-floor navigation evidence. Actor proxies are declared policy,
* not inferred human anatomy, wheelchair compliance or a manipulation solver. */
export declare function programNavigation(world: WrightResolved, room: WrightRoom, bodies: readonly Body[]): {
approach: (body: Body, category: string) => ProgramPairEvidence;
entries: Entry[];
linked: boolean;
unsupported: string | undefined;
};
export declare function evaluateProgramNavigation(rule: ProgramRule, world: WrightResolved, room: WrightRoom, bodies: readonly Body[], navigation: ReturnType<typeof programNavigation>): ProgramRuleCheck;
export {};
room-program-predicates.d.ts
TypeScript
import type { ProgramRule } from "@quay/scene-contracts/room-program";
import type { RelationEvaluation } from "./types.js";
import { type Body } from "./spatial/geometry.js";
/** Derived evidence only. No placement proposal, source edit, or physics state. */
export type ProgramPredicateEvidence = Omit<RelationEvaluation, "identity"> & {
subject: string;
target: string | null;
};
/** Versioned qualitative adjacency: a 0.75m maximum horizontal bounds gap.
* This is not an exact ergonomic/seat-height or anatomical certificate. */
export declare function evaluateProgramPair(rule: ProgramRule, a: Body, b: Body): ProgramPredicateEvidence;
/** Finite real wall patches, including their holes, not just the room perimeter.
* A cabinet's normalized front must face away from the supporting wall plane. */
export declare function evaluateProgramWall(rule: ProgramRule, a: Body, walls: readonly Body[]): ProgramPredicateEvidence;
/** Geometric target choice for a quantified subject, independent of proposal order. */
export declare function bestProgramTarget(rule: ProgramRule, subject: Body, targets: readonly Body[]): ProgramPredicateEvidence;
room-program-proposals.d.ts
TypeScript
import type { Transform } from "@quay/contracts";
import type { CompileInput } from "./types.js";
import { type Body } from "./spatial/geometry.js";
/** Bounded wall-facing proposals, not satisfaction evidence. Room-local cardinal
* shell candidates are inspected against actual finite wall geometry by a
* separate evaluator. Explicit authored components remain locked by the solver. */
export declare function proposePerimeter(current: Body, size: readonly number[], input: CompileInput): Transform[];
sizing.d.ts
TypeScript
import type { ArchetypeProfile, SizingDecision } from "@quay/scene-contracts/archetypes";
import type { AssetSnapshot, Vec3 } from "@quay/contracts";
import type { AssetManifest } from "@quay/asset-analysis/contract";
declare const axes: {
readonly width: 0;
readonly height: 1;
readonly depth: 2;
};
type Bounds = AssetSnapshot["normalization"]["rawBounds"];
/** Explicit inputs only: no catalog lookup, network, random IDs or source mutation. */
export declare function resolveSizing(input: {
bounds: Bounds;
correction?: [number, number, number, number];
profile: ArchetypeProfile | null;
manifest?: AssetManifest;
override?: {
dimension: keyof typeof axes;
targetM: number;
reference?: "whole-bounds" | "withers";
};
}): {
decision: SizingDecision;
normalization: {
rawBounds: {
min: Vec3;
max: Vec3;
};
scale: Vec3;
baseOffset: Vec3;
forwardCorrection: import("@quay/contracts").Quaternion;
};
};
export {};
types.d.ts
TypeScript
import type { AssetSnapshot } from "@quay/contracts";
import type { RamsProject } from "@quay/scene-contracts/rams";
import type { WrightInput } from "@quay/scene-contracts/wright";
import type { AssetManifest } from "@quay/asset-analysis/contract";
import type { ArchetypeProfile } from "@quay/scene-contracts/archetypes";
import type { RidleyInput, RidleyProject } from "@quay/scene-contracts/cinematic";
import type { CompilerDiagnostic, Dependency, Versions, SemanticProgram, SceneDocumentV2 } from "@quay/scene-contracts";
export type * from "@quay/scene-contracts";
export type Compilation = {
sourceHash: string;
diagnostics: CompilerDiagnostic[];
semantic: SemanticProgram | null;
scene: SceneDocumentV2 | null;
};
export type CompileInput = {
ramsSource?: string;
/** Explicit history operation; omission must never remove an existing world. */
resetWright?: boolean;
wright?: WrightInput;
ridley?: RidleyInput;
archetypes?: ArchetypeProfile[];
layoutVersion?: Versions["layout"];
previous?: SceneDocumentV2;
search?: {
maxCandidates?: number;
maxPasses?: number;
};
source: string;
bindings: Record<string, string>;
assets: AssetSnapshot[];
manifests: AssetManifest[];
};
export type ProjectDocument = {
rams?: RamsProject;
wright?: WrightInput;
ridley?: RidleyProject;
schema: "quay.project";
schemaVersion: "2.0.0-draft.1";
projectId: string;
revision: number;
createdAt: string;
updatedAt: string;
draft: {
source: string;
sourceHash: string;
diagnostics: CompilerDiagnostic[];
};
accepted: null | {
source: string;
sourceHash: string;
bindings: Record<string, string>;
dependencies: Dependency[];
versions: Versions;
scene: SceneDocumentV2;
};
};
validation.d.ts
Reference
export type { PreparedBody, PreparedPhysics, ColliderShape, } from "./physics-types.js";
import type { ProjectDocument } from "./types.js";
export type { ProjectDocument, SceneDocumentV2, SemanticProgram, } from "./types.js";
export { validateResolvedScene } from "@quay/scene-contracts";
export declare function validateProject(value: unknown): Promise<ProjectDocument>;
withers.d.ts
TypeScript
import type { AssetManifest } from "@quay/asset-analysis/contract";
/** Semantic approximation, NOT an anatomical surface measurement. A real skin
* plus bilateral fore-limb roots locates the shoulder region. The bone midpoint
* is below the skin: estimate dorsal tissue extent as half shoulder separation.
* This deliberately exposes low confidence rather than equating head/ear bounds
* with withers or pretending a bone center is the external shoulder surface. */
export declare function approximateWithers(manifest: AssetManifest, correction: [number, number, number, number], floor: number, totalHeight: number): {
sourceReferenceM: number;
method: "rig-shoulder-envelope-approximation/1";
confidence: number;
evidence: string[];
};
worker.d.ts
Reference
export {};
world-compile.d.ts
TypeScript
import type { LanguageProgram } from "@quay/scene-language";
import type { Compilation, CompileInput } from "./types.js";
/** Local QWAY compilation is unchanged. WRIGHT composes its rigid frames only. */
export declare function compileWorld(input: CompileInput, program: LanguageProgram, sourceHash: string): Promise<Compilation>;
world-verification.d.ts
TypeScript
import type { WrightResolved } from "@quay/scene-contracts/wright";
import { type Body } from "./spatial/geometry.js";
/** Independent resolved-geometry inspection. A requested portal neither creates a
* hole nor proves passage. A narrower evidenced actor passage does not satisfy a
* larger requested aperture. No source edits or asset geometry mutation. */
export declare function verifyWorldPortals(world: WrightResolved, bodies: readonly Body[]): NonNullable<WrightResolved["verification"]>;
wright.d.ts
Reference
export { roomLocalTransform, verifyWorldFrames, resolveWright, } from "@quay/spatial/wright";
@quay/rams
| Import path | Declaration |
|---|---|
| @quay/rams | ./dist/index.d.ts |
| @quay/rams/style.css | ./src/style.css |
bridge.d.ts
TypeScript
import { type SemanticSnapshot } from "@quay/runtime";
import type { RamsAction, RamsConfig } from "@quay/scene-contracts/rams";
export declare function allowedAction(value: unknown, config: RamsConfig, snapshot: SemanticSnapshot | null): value is RamsAction;
export declare function chatReply(input: string, config: RamsConfig, snapshot: SemanticSnapshot | null, context: {
lastObjectId: string | null;
previousRoomId: string | null;
roomId: string | null;
}): {
text: string;
actions: {
label: string;
action: RamsAction;
}[];
execute: RamsAction | undefined;
};
contact.d.ts
TypeScript
import type { RamsConfig } from "@quay/scene-contracts/rams";
export type ContactMessage = {
name: string;
email: string;
subject: string;
message: string;
privacy: true;
fields: Record<string, string>;
spamToken?: string;
};
export type ContactTransport = (message: ContactMessage, signal: AbortSignal) => Promise<void>;
export declare function httpContact(endpoint: string): ContactTransport;
export declare function mountContact(host: HTMLElement, config: RamsConfig["contact"], transport?: ContactTransport, antiSpam?: (signal: AbortSignal) => Promise<string>): () => void;
fragments.d.ts
TypeScript
import type { RamsFragment } from "@quay/scene-contracts/rams";
/** An opaque origin, no network, no parent DOM; scripts can only request typed actions. */
export declare function mountFragment(host: HTMLElement, fragment: RamsFragment, title: string, request: (action: unknown) => void): () => void;
index.d.ts
Reference
export * from "./shell.js";
export * from "./contact.js";
export * from "./bridge.js";
export * from "./fragments.js";
shell.d.ts
TypeScript
import { WorldPlayer, type WorldPlayerOptions } from "@quay/runtime/worldpack";
import type { WorldSource } from "@quay/worldpack";
import { type RamsConfig, type RamsAction } from "@quay/scene-contracts/rams";
import { type ContactTransport } from "./contact.js";
export type RamsOptions = {
config: RamsConfig;
source?: WorldSource;
playerOptions?: WorldPlayerOptions;
createPlayer?: (host: HTMLElement, source: WorldSource, options: WorldPlayerOptions) => WorldPlayer;
contactTransport?: ContactTransport;
antiSpam?: (signal: AbortSignal) => Promise<string>;
history?: boolean;
basePath?: string;
};
/** Owns web UI only. Overlay and configuration changes never recreate the player. */
export declare function mountRams(host: HTMLElement, options: RamsOptions): {
root: HTMLElement;
viewport: HTMLDivElement;
ready: Promise<void>;
dispatch: (action: RamsAction) => Promise<void>;
readonly player: WorldPlayer | null;
update(next: RamsConfig): void;
dispose(): void;
};
site-entry.d.ts
TypeScript
import "./style.css";