import type { InputBackend, PointerType, VirtualJoystickConfig } from './input-snapshot'; export declare function coercePointerType(raw: string): PointerType; /** * Options accepted by `attachBrowserInputBackend`. */ export interface BrowserInputBackendOptions { /** Optional host-owned UI root. Events in this root never reach gameplay. */ readonly uiRoot?: Node; /** * Optional document handle (testing override). Defaults to `document`. * Plan-strategy section 9 row 7 (`document.hasFocus()` semantics) * relies on this to decide whether the up-edge set should be cleared * when focus is lost. */ readonly document?: Document; /** * Optional window handle (testing override). Defaults to `window`. * Used to attach key listeners (capturing focus loss) without * requiring the canvas itself to receive keyboard events. */ readonly window?: Window; /** * Neutral gate for the auto PointerLock-on-click. When provided and it * returns false, the click handler skips `requestPointerLock()` — the host * decides whether a click should capture the cursor right now. Defaults to * always-locking (returns true), so the standalone game runtime keeps its * MVP behaviour unchanged. This predicate is deliberately host-opaque: the * backend never learns WHY locking is (dis)allowed — it only asks. A host * that mounts this canvas in a non-game context (e.g. an editor viewport * that owns the cursor for orbit/pick) supplies a predicate that returns * false there. The input package carries zero knowledge of those contexts. */ readonly pointerLockAllowed?: () => boolean; /** * Optional navigator handle (testing override). Defaults to * `globalThis.navigator`. Used to poll `navigator.getGamepads()` each * frame. Mirrors the `document`/`window` override pattern. */ readonly navigator?: { getGamepads?(): (Gamepad | null)[]; }; /** * Optional virtual joystick configurations (M3). When provided, the * backend auto-binds the first pointerdown within each config's region * and derives per-frame VirtualAxisSample outputs via deriveVirtualAxes. */ readonly virtualJoysticks?: readonly VirtualJoystickConfig[]; /** * Optional SDL controller DB text loader (M3 D-13 test injection). When * omitted, the backend dynamic-imports the vendored 554KB DB from * `@forgeax/engine-input/controller-db-data` on first sight of a * non-standard gamepad (D-2 lazy-load: the 554KB never sits in the * default path). Tests inject a synthetic DB string to avoid loading the * real vendored file. Returns the raw gamecontrollerdb.txt contents. */ readonly loadControllerDb?: () => Promise; /** * Optional monotonic clock (M5 D-3 test injection). Defaults to * `() => performance.now()`. The gesture recognizer advances all timers * (long-press duration, double-tap / swipe windows) off this clock, NOT * off pointer-event arrival, so recognition stays decoupled from event * frequency (AC-16). Tests inject a fake clock for deterministic timing, * mirroring the `document` / `window` / `navigator` override pattern. */ readonly now?: () => number; /** * Optional lock provider (D-2). When provided, pointer-lock requests * route through requestLock() / exitLock() instead of the W3C * requestPointerLock / exitPointerLock API. The backend remains * host-opaque -- it never learns whether the provider wraps Tauri * native-grab, postMessage, or any other mechanism. */ readonly lockProvider?: PointerLockProvider; /** * Optional callback for lock request failures (D-4). When W3C * requestPointerLock rejects or lockProvider.requestLock/exitLock * throws/rejects, the backend calls this with a detail object. * Without this callback, failures are silently caught (backward * compatible but contrary to charter P3). */ readonly onLockError?: (detail: { path: 'w3c' | 'provider'; cause: unknown; }) => void; } /** * Lock provider interface (D-2). A host injects this to replace the * W3C Pointer Lock API path. requestLock() may return void (fire-and-forget, * D-7 optimistic placement) or Promise (awaitable). exitLock() is * called when the backend needs to release the lock (ESC / blur / detach / * setPointerLockAllowed(false)). */ export interface PointerLockProvider { /** * Request pointer lock. The backend optimistically sets providerLocked=true * when this is called (D-7). On throw/reject, the backend calls onLockError * and rolls back providerLocked. */ requestLock(): void | Promise; /** Release pointer lock. */ exitLock(): void; } /** * Attach DOM listeners (keydown / keyup / mousedown / mouseup / * pointerlockchange / mousemove inside lock / blur) to `canvas` and the * surrounding window. Returns a `detach` callable that: * * - removes all listeners * - exits PointerLock if currently locked * - drops every internal accumulator * * The returned object also implements the `InputBackend` protocol -- the * runtime inserts it under `INPUT_BACKEND_KEY` and adds the * `InputFrameStartScan` system, which reads it back each tick. * Calling `detach()` and the protocol's `detach()` are equivalent * (idempotent; double-detach is safe -- charter P3). */ export declare function attachBrowserInputBackend(canvas: HTMLCanvasElement, options?: BrowserInputBackendOptions): (() => void) & { backend: InputBackend; }; //# sourceMappingURL=browser-backend.d.ts.map