/**
 * Main-thread client for the WASM-in-a-Worker architecture.
 *
 * All queries are posted as messages and awaited as promises; the heavy work
 * runs off the main thread. The API mirrors the in-process `Database` class
 * so consumers can choose the execution model without rewriting their code.
 */
import { LoraError } from "./types.js";
/**
 * Build a Database client that proxies to the supplied worker.
 *
 * Typical browser usage:
 * ```ts
 * const worker = new Worker(new URL("./worker.js", import.meta.url), { type: "module" });
 * const db = createWorkerDatabase(worker);
 * const result = await db.execute("MATCH (n) RETURN n");
 * ```
 */
export function createWorkerDatabase(worker) {
    let nextId = 1;
    const pending = new Map();
    worker.addEventListener("message", (event) => {
        const { id, body } = event.data;
        const p = pending.get(id);
        if (!p)
            return;
        pending.delete(id);
        if (body.ok) {
            p.resolve(body.result);
        }
        else {
            p.reject(new LoraError(body.error.message, body.error.code));
        }
    });
    worker.addEventListener("error", (event) => {
        const message = event.message ?? "worker errored";
        for (const p of pending.values()) {
            p.reject(new LoraError(message, "WORKER_ERROR"));
        }
        pending.clear();
    });
    function call(body) {
        const id = nextId++;
        return new Promise((resolve, reject) => {
            pending.set(id, { resolve: resolve, reject });
            const msg = { id, body };
            worker.postMessage(msg);
        });
    }
    return {
        execute(query, params) {
            return call({ op: "execute", query, params: params ?? null });
        },
        async clear() {
            await call({ op: "clear" });
        },
        nodeCount() {
            return call({ op: "nodeCount" });
        },
        relationshipCount() {
            return call({ op: "relationshipCount" });
        },
        async dispose() {
            await call({ op: "dispose" });
            worker.terminate();
        },
    };
}
//# sourceMappingURL=worker-client.js.map