import { SharedObject } from './SharedObject.js';
interface ThreadXOptions {
    /**
     * The ID of the worker. Must be unique across all workers.
     *
     * Should be an integer value between 1 and 899.
     *
     * @internalRemarks
     * The reason for the 899 limit is the way we generate unique IDs for
     * BufferStructs. See `BufferStruct.ts` for more details.
     */
    workerId: number;
    workerName: string;
    sharedObjectFactory?: (buffer: SharedArrayBuffer) => SharedObject | null;
    onObjectShared?: (sharedObject: SharedObject) => void;
    onBeforeObjectForgotten?: (sharedObject: SharedObject) => void;
    onMessage?: (message: any) => Promise<any>;
}
declare global {
    class DedicatedWorkerGlobalScope {
        DedicatedWorkerGlobalScope: typeof DedicatedWorkerGlobalScope;
        postMessage(message: any, transfer?: Transferable[]): void;
        addEventListener<K extends keyof WindowEventHandlersEventMap>(type: K, listener: (this: WindowEventHandlers, ev: WindowEventHandlersEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void;
        addEventListener(type: string, listener: EventListenerOrEventListenerObject | null, options?: boolean | AddEventListenerOptions): void;
    }
    interface WindowOrWorkerGlobalScope {
        THREADX?: ThreadX;
        DedicatedWorkerGlobalScope?: typeof DedicatedWorkerGlobalScope;
    }
}
/**
 * Created to define a common interface for both Worker parents (`self`) and
 * Worker instances
 */
interface WorkerCommon {
    postMessage(message: any, transfer?: Transferable[]): void;
    addEventListener<K extends keyof WindowEventHandlersEventMap>(type: K, listener: (this: WindowEventHandlers, ev: WindowEventHandlersEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void;
    addEventListener(type: string, listener: EventListenerOrEventListenerObject | null, options?: boolean | AddEventListenerOptions): void;
    terminate?(): void;
}
interface ForgetOptions {
    /**
     * If true, no warning will be logged if the object is not found.
     */
    silent?: boolean;
}
export declare class ThreadX {
    static init(options: ThreadXOptions): ThreadX;
    static destroy(): void;
    /**
     * Get the Worker ID of the current worker
     *
     * @remarks
     * This is only valid after ThreadX.init() has been called.
     */
    static get workerId(): number;
    /**
     * Get the Worker Name of the current thread
     *
     * @remarks
     * This is only valid after ThreadX.init() has been called.
     */
    static get workerName(): string;
    static get instance(): ThreadX;
    readonly workerId: number;
    readonly workerName: string;
    readonly sharedObjectFactory?: (buffer: SharedArrayBuffer) => SharedObject | null;
    private readonly onSharedObjectCreated?;
    private readonly onBeforeObjectForgotten?;
    /**
     * User-defined message handler
     */
    private readonly onUserMessage?;
    readonly sharedObjects: Map<number, SharedObject>;
    /**
     * WeakMap of SharedObjects to additional metadata
     */
    private sharedObjectData;
    readonly workers: Map<string, WorkerCommon>;
    private workerReadyPromises;
    private pendingAsyncMsgs;
    private nextAsyncMsgId;
    private nextUniqueId;
    /**
     * Suppress emitting events from SharedObjects
     *
     * @remarks
     * This is used to prevent infinite loops when emitting events from a SharedObject
     * that is shared with another worker.
     *
     * We set this to true when we receive a SharedObjectEmitMessage from another worker
     * and set it back to false after we have emitted the event on the SharedObject.
     */
    private suppressSharedObjectEmit;
    private constructor();
    registerWorker(workerName: string, worker: WorkerCommon): void;
    closeWorker(workerName: string): void;
    closeWorkerAsync(workerName: string, timeout?: number): Promise<'graceful' | 'forced'>;
    private listenForWorkerMessages;
    /**
     * Share a SharedObject with a worker
     *
     * @param workerName Worker to share with
     * @param sharedObject
     */
    shareObjects(workerName: string, sharedObjects: SharedObject[]): Promise<void>;
    /**
     * Tell ThreadX to forget about SharedObjects
     *
     * @remarks
     * This causes ThreadX on the current worker and the worker that the object
     * is shared with to forget about the object. It is up to the worker code to
     * actually make sure that no other references to the SharedObjects exist so
     * that they can be garbage collected.
     *
     * A worker can implement the onObjectForgotten() callback to be notified
     * when a SharedObject is forgotten.
     *
     * @param sharedObject
     * @param options Options
     */
    forgetObjects(sharedObjects: SharedObject[], options?: ForgetOptions): Promise<void>;
    sendMessage(workerName: string, message: Record<string, unknown>, transfer?: Transferable[] | undefined): void;
    sendMessageAsync(workerName: string, message: Record<string, unknown>, transfer?: Transferable[] | undefined, options?: {
        skipResponseWait?: boolean;
    }): Promise<any>;
    private onMessage;
    getSharedObjectById(id: number): SharedObject | null;
    /**
     * Generates an ID that is unique across all ThreadX workers.
     *
     * @remarks
     * The ID is based on the `workerId` set in the `ThreadXOptions` and an
     * incrementing counter. For the ID to actually be unique the `workerId` must
     * also be unique.
     *
     * @returns A unique ID
     */
    generateUniqueId(): number;
    /**
     * Emit an event from a SharedObject to all other workers
     *
     * @internalRemarks
     * For internal ThreadX use only.
     *
     * Since we aren't sure what workers are sharing a SharedObject we need to
     * emit the event to all workers. (TODO: Possible optimization?)
     *
     * @param sharedObject
     * @param eventName
     * @param data
     * @returns
     */
    __sharedObjectEmit(sharedObject: SharedObject, eventName: string, data: Record<string, unknown>): void;
}
export {};
