// WorkerConnection（Phase 1 引擎抽象与 Worker 化）。
// offscreen 文档用它托管 asr.worker / translation.worker：请求以 sessionId + sequence
// 封装，响应按 sequence 匹配；旧 session、过期或乱序响应直接丢弃。
// 音频推送使用 transferable ArrayBuffer，postMessage 结构克隆 + transfer，不经过 JSON。
import { createSequenceCounter, createSessionId, encodeWorkerRequest, isWorkerEnvelope, isWorkerEventMessage, isWorkerResponseMessage } from "./worker-protocol.js";
export function createModuleWorker(url) {
    const worker = new Worker(url, { type: "module" });
    let messageListener;
    let failureListener;
    worker.onmessage = (event) => messageListener?.(event.data);
    worker.onerror = (event) => failureListener?.(event);
    return {
        postMessage: (message, transfer) => worker.postMessage(message, transfer ? { transfer } : undefined),
        onMessage: (listener) => { messageListener = listener; },
        onFailure: (listener) => { failureListener = listener; },
        terminate: () => worker.terminate(),
    };
}
export class WorkerConnection {
    sessionId;
    endpoint;
    onFailure;
    sequence = createSequenceCounter();
    pending = new Map();
    eventListeners = new Set();
    lastEventSequence = 0;
    disposed = false;
    constructor(sessionId = createSessionId(), endpoint, onFailure) {
        this.sessionId = sessionId;
        this.endpoint = endpoint;
        this.onFailure = onFailure;
        endpoint.onMessage((data) => this.accept(data));
        endpoint.onFailure((cause) => {
            this.rejectAll(new Error("worker_lane_failed"));
            this.onFailure?.(cause);
        });
    }
    request(request, transfer) {
        if (this.disposed)
            return Promise.reject(new Error("worker_terminated"));
        const sequence = this.sequence();
        const message = encodeWorkerRequest(this.sessionId, sequence, request);
        return new Promise((resolve, reject) => {
            this.pending.set(sequence, { resolve: resolve, reject });
            try {
                this.endpoint.postMessage(message, transfer);
            }
            catch (error) {
                this.pending.delete(sequence);
                reject(error instanceof Error ? error : new Error(String(error)));
            }
        });
    }
    onEvent(listener) {
        this.eventListeners.add(listener);
    }
    get disposedState() {
        return this.disposed;
    }
    pendingCount() {
        return this.pending.size;
    }
    terminate() {
        if (this.disposed)
            return;
        this.disposed = true;
        this.rejectAll(new Error("worker_terminated"));
        this.endpoint.terminate();
    }
    accept(data) {
        if (!isWorkerEnvelope(data))
            return;
        if (data.sessionId !== this.sessionId)
            return; // 旧 session：直接丢弃
        if (isWorkerResponseMessage(data)) {
            const entry = this.pending.get(data.sequence);
            if (!entry)
                return; // 过期或乱序响应：直接丢弃
            this.pending.delete(data.sequence);
            if (data.response.ok === true)
                entry.resolve(data.response.result);
            else
                entry.reject(new Error(data.response.error));
            return;
        }
        if (isWorkerEventMessage(data)) {
            if (data.sequence <= this.lastEventSequence)
                return;
            this.lastEventSequence = data.sequence;
            for (const listener of this.eventListeners)
                listener(data.event);
        }
    }
    rejectAll(error) {
        for (const entry of this.pending.values())
            entry.reject(error);
        this.pending.clear();
    }
}
