declare module "@yawn/core" {
  export type RowFormat = "f32" | "u32" | "i32";
  export interface RowDescriptor {
    name: string;
    rows: number;
    stride: number;
    format: RowFormat;
    offset: number;
    bytes: number;
  }
  export class SharedRows {
    readonly buffer: SharedArrayBuffer;
    readonly descriptor: RowDescriptor;
    readonly name: string;
    readonly rows: number;
    readonly stride: number;
    readonly format: RowFormat;
    readonly view: Float32Array | Uint32Array | Int32Array;
    row(index: number): Float32Array | Uint32Array | Int32Array;
    read(index: number): number[];
    write(index: number, values: ArrayLike<number>): this;
    share(): { buffer: SharedArrayBuffer; descriptor: RowDescriptor };
  }
  export interface ProfileFrame {
    frame: number;
    milliseconds: number;
    readbackMilliseconds: number;
    adapter: string;
    canvas: { width: number; height: number };
    passes: Array<{ name: string; milliseconds: number }>;
  }
  export class YawnCore {
    constructor(canvas: HTMLCanvasElement, options?: { arenaBytes?: number; debug?: boolean });
    readonly ready: Promise<void>;
    createRows(options: { name: string; rows: number; stride: number; format: RowFormat }): Promise<SharedRows>;
    createRowsBatch(rows: Array<{ name: string; rows: number; stride: number; format: RowFormat }>): Promise<SharedRows[]>;
    deleteRows(name: string): Promise<void>;
    allocateObject(name: string): Promise<number>;
    deleteObject(name: string, id: number): Promise<void>;
    compileGraph(serialized: string): Promise<string>;
    switchLoadout(id: string): Promise<void>;
    play(): Promise<void>;
    pause(): Promise<void>;
    setFps(fps: number): Promise<void>;
    setProfiler(enabled: boolean): Promise<boolean>;
    onProfile(listener: (frame: ProfileFrame) => void): () => void;
    array(name: string): SharedRows;
    dispose(): void;
  }
}

declare module "@yawn/handles" {
  import { SharedRows, YawnCore } from "@yawn/core";

  export interface SceneOptions { arenaBytes?: number; debug?: boolean; fps?: number; hdr?: boolean }
  export class Scene {
    constructor(canvas: HTMLCanvasElement, options?: SceneOptions);
    readonly core: YawnCore;
    readonly ready: Promise<this>;
    readonly hdr: boolean;
    array(name: string): SharedRows;
    ensureRows(name: string, rows: number, stride: number, format: "f32" | "u32" | "i32"): Promise<SharedRows>;
    reserve(additional: { nodes?: number; materials?: number }): Promise<void>;
    batchWrites<T>(operation: () => T): T;
    batchGraphUpdates<T>(operation: () => T | Promise<T>): Promise<T>;
    dispose(): void;
  }

  export interface Vector3View { x: number; y: number; z: number; set(values: ArrayLike<number>): void }
  export interface RotorView extends Vector3View { w: number }
  export interface NodeOptions { position?: ArrayLike<number>; rotor?: ArrayLike<number>; scale?: ArrayLike<number> }
  export class Node {
    constructor(scene: Scene, options?: NodeOptions);
    readonly scene: Scene;
    readonly ready: Promise<this>;
    readonly id: number;
    readonly position: Vector3View;
    readonly rotor: RotorView;
    readonly scale: Vector3View;
    setPosition(value: ArrayLike<number>): this;
    setRotor(value: ArrayLike<number>): this;
    setScale(value: ArrayLike<number>): this;
    translate(x: number, y: number, z: number): this;
    rotateX(radians: number): this;
    rotateY(radians: number): this;
    rotateZ(radians: number): this;
    dispose(): Promise<void>;
  }

  export interface PBRMaterialOptions {
    baseColor?: ArrayLike<number>;
    metallic?: number;
    roughness?: number;
    emissive?: ArrayLike<number>;
  }
  export class PBRMaterial {
    constructor(scene: Scene, options?: PBRMaterialOptions);
    readonly ready: Promise<this>;
    readonly id: number;
    metallic: number;
    roughness: number;
    readonly baseColor: { 0: number; 1: number; 2: number; 3: number };
    dispose(): Promise<void>;
  }

  export type VertexKind = "positions" | "normals" | "tangents" | "uvs" | "colors" | "indices";
  export interface MeshOptions extends NodeOptions {
    geometryId?: number;
    material?: PBRMaterial;
    vertexData?: Partial<Record<VertexKind, ArrayLike<number>>>;
    visible?: boolean;
  }
  export class Mesh extends Node {
    constructor(scene: Scene, options?: MeshOptions);
    geometryId: number;
    vertexCount: number;
    indexCount: number;
    isVisible: boolean;
    material: PBRMaterial;
    clone(options?: Omit<MeshOptions, "geometryId" | "vertexData">): Mesh;
    setVertexData(kind: VertexKind, data: ArrayLike<number>): Promise<this>;
    setMaterialForFaces(material: PBRMaterial, faces: number | number[]): Promise<this>;
  }

  export interface CameraOptions extends NodeOptions { fov?: number; near?: number; far?: number; aspect?: number }
  export class Camera extends Node {
    fov: number;
    near: number;
    far: number;
    aspect: number;
  }
  export class ArcRotateCamera extends Camera {
    constructor(scene: Scene, options?: CameraOptions & { target?: Node; alpha?: number; beta?: number; radius?: number; controls?: { element: HTMLElement; pointer?: boolean; controller?: boolean } });
    alpha: number;
    beta: number;
    radius: number;
  }
  export class FreeCamera extends Camera {
    constructor(scene: Scene, options?: CameraOptions & { controls?: { element: HTMLElement; keyboard?: boolean; pointer?: boolean; controller?: boolean; speed?: number } });
  }
  export class FollowCamera extends Camera {
    constructor(scene: Scene, options?: CameraOptions & { target?: Node; distance?: number; height?: number; smoothing?: number });
  }

  export interface LightOptions extends NodeOptions { color?: ArrayLike<number>; intensity?: number }
  export class PointLight extends Node { constructor(scene: Scene, options?: LightOptions & { range?: number }); intensity: number; range: number }
  export class AmbientLight extends Node { constructor(scene: Scene, options?: LightOptions); intensity: number }
  export class DirectionalLight extends Node { constructor(scene: Scene, options?: LightOptions); intensity: number }
  export class SpotLight extends Node { constructor(scene: Scene, options?: LightOptions & { range?: number; innerAngle?: number; outerAngle?: number }) }
  export class RectAreaLight extends Node { constructor(scene: Scene, options?: LightOptions & { width?: number; height?: number }) }

  export class ComputePass { constructor(options: Record<string, unknown>); readonly id: string }
  export class FXAA { constructor(scene: Scene, options?: Record<string, unknown>); readonly ready: Promise<this>; dispose(): Promise<void> }
  export class ColorGrading extends FXAA { constructor(scene: Scene, options?: { toneMap?: "aces" | "reinhard" | "linear"; amount?: number }) }
  export class DynamicExposure extends FXAA { constructor(scene: Scene, options?: { exposure?: number }) }
  export class SSAO extends FXAA { constructor(scene: Scene, options?: { amount?: number }) }
  export function importGltf(scene: Scene, url: string | URL): Promise<Mesh[]>;
}

declare const canvas: HTMLCanvasElement;
declare function log(...values: unknown[]): void;
