import type { XRGripSpace, XRHandSpace, XRTargetRaySpace } from 'three';
import type { XRControllerModel } from 'three/examples/jsm/webxr/XRControllerModelFactory.js';
import type { XRHandModel } from 'three/examples/jsm/webxr/XRHandModelFactory.js';
import type { XRControllerEvents, XRHandEvents } from '../types.js';
export type XRHandInputSource = XRInputSource & {
    hand: XRHand;
};
export type XRInputSourceStateBase = {
    id: string;
    inputSource: XRInputSource;
    handedness: XRHandedness;
    isPrimary: boolean;
    targetRay: XRTargetRaySpace;
};
export type XRControllerSourceState = XRInputSourceStateBase & {
    type: 'controller';
    grip: XRGripSpace;
    model: XRControllerModel;
};
export type XRHandSourceState = Omit<XRInputSourceStateBase, 'inputSource'> & {
    type: 'hand';
    inputSource: XRHandInputSource;
    hand: XRHandSpace;
    model: XRHandModel;
};
export type XRGazeSourceState = XRInputSourceStateBase & {
    type: 'gaze';
};
export type XRTransientPointerSourceState = XRInputSourceStateBase & {
    type: 'transientPointer';
};
export type XRScreenInputSourceState = XRInputSourceStateBase & {
    type: 'screenInput';
};
export type XRInputSourceState = XRControllerSourceState | XRHandSourceState | XRGazeSourceState | XRTransientPointerSourceState | XRScreenInputSourceState;
declare class InputSourcesState {
    current: readonly XRInputSourceState[];
}
export declare const inputSources: InputSourcesState;
export type ControllerSubscriber = {
    type: 'controller';
    handedness: XRHandedness;
    callbacks: XRControllerEvents;
};
export type HandSubscriber = {
    type: 'hand';
    handedness: 'left' | 'right';
    callbacks: XRHandEvents;
};
export type Subscriber = ControllerSubscriber | HandSubscriber;
/**
 * Registers callbacks with the module-level XR input-source dispatcher.
 *
 * This does not subscribe to a specific `XRInputSource`, `XRSession`, or
 * Three.js object. Instead, the subscriber is stored in the internal
 * `subscribers` set and receives events for whichever current input-source
 * state matches its `type` and `handedness`.
 *
 * For example, a `{ type: 'controller', handedness: 'left' }` subscriber will
 * receive forwarded events for the current left controller, even if the
 * underlying `XRInputSource` instance disconnects and reconnects.
 *
 * Returns a cleanup function that removes the subscriber from the dispatcher.
 */
export declare const addSubscriber: (sub: Subscriber) => () => void;
export declare const dispatchEvent: (state: XRInputSourceState, eventType: string, event: unknown) => void;
export declare const createInputSourceEvent: (state: XRInputSourceState, type: string, extra?: Record<string, unknown>) => {
    type: string;
    data: XRInputSource | XRHandInputSource;
    inputSource: XRInputSource | XRHandInputSource;
    target: XRTargetRaySpace | XRHandSpace;
};
export declare const dispatchInputSourceStateEvent: (state: XRInputSourceState, eventType: string, event: unknown, options?: {
    dispatchSpaces?: boolean;
}) => void;
type ResolveOptions = {
    isPrimary?: boolean;
};
export declare const getInputSourceState: (inputSource: XRInputSource, options?: ResolveOptions) => XRInputSourceState | undefined;
export declare const getControllerState: (handedness: XRHandedness, options?: ResolveOptions) => XRControllerSourceState | undefined;
export declare const getHandState: (handedness: "left" | "right", options?: ResolveOptions) => XRHandSourceState | undefined;
export declare const dispatchInputSourceEvent: (inputSource: XRInputSource, eventType: string, event: unknown) => void;
export declare const dispatchXRInputSourceEvent: (event: XRInputSourceEvent) => void;
export {};
