"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.SqliteError = exports.Database = void 0;
exports.connect = connect;
const database_common_1 = require("@sivukhin/database-common");
Object.defineProperty(exports, "SqliteError", { enumerable: true, get: function () { return database_common_1.SqliteError; } });
const _index_1 = require("#index");
let workerRequestId = 0;
class Database extends database_common_1.DatabasePromise {
    files;
    constructor(db, files, opts = {}) {
        super(db, opts);
        this.files = files;
    }
    async close() {
        let currentId = workerRequestId;
        workerRequestId += this.files.length;
        let tasks = [];
        for (const file of this.files) {
            _index_1.MainWorker.postMessage({ __turso__: "unregister", path: file, id: currentId });
            tasks.push(waitFor(currentId));
            currentId += 1;
        }
        await Promise.all(tasks);
        this.db.close();
    }
}
exports.Database = Database;
function waitFor(id) {
    let waitResolve, waitReject;
    const callback = msg => {
        if (msg.data.id == id) {
            if (msg.data.error != null) {
                waitReject(msg.data.error);
            }
            else {
                waitResolve();
            }
            cleanup();
        }
    };
    const cleanup = () => _index_1.MainWorker.removeEventListener("message", callback);
    _index_1.MainWorker.addEventListener("message", callback);
    const result = new Promise((resolve, reject) => {
        waitResolve = resolve;
        waitReject = reject;
    });
    return result;
}
/**
 * Creates a new database connection asynchronously.
 *
 * @param {string} path - Path to the database file.
 * @param {Object} opts - Options for database behavior.
 * @returns {Promise<Database>} - A promise that resolves to a Database instance.
 */
async function connect(path, opts = {}) {
    if (path == ":memory:") {
        const db = await (0, _index_1.connect)(path, { tracing: opts.tracing });
        return new Database(db, [], opts);
    }
    await (0, _index_1.initThreadPool)();
    if (_index_1.MainWorker == null) {
        throw new Error("panic: MainWorker is not set");
    }
    let currentId = workerRequestId;
    workerRequestId += 2;
    let dbHandlePromise = waitFor(currentId);
    let walHandlePromise = waitFor(currentId + 1);
    _index_1.MainWorker.postMessage({ __turso__: "register", path: `${path}`, id: currentId });
    _index_1.MainWorker.postMessage({ __turso__: "register", path: `${path}-wal`, id: currentId + 1 });
    await Promise.all([dbHandlePromise, walHandlePromise]);
    const db = await (0, _index_1.connect)(path, { tracing: opts.tracing });
    const files = [path, `${path}-wal`];
    return new Database(db, files, opts);
}
