release: WRNexusJS 0.8.0
Quality / quality (ubuntu-latest) (push) Failing after 21s
Quality / quality (windows-latest) (push) Canceled after 0s

This commit is contained in:
2026-08-02 23:18:51 +05:30
parent 87507edf59
commit 586a6db8ff
625 changed files with 243608 additions and 11210 deletions
+34 -7
View File
@@ -50,12 +50,32 @@ export interface Db {
close(): void | Promise<void>;
}
interface DbLifecycle {
closing: boolean;
active: Set<Promise<unknown>>;
closePromise?: Promise<void>;
}
/** Build a `Db` over a query runner (the driver at top level, or a transaction). */
function dbOver(runner: TxHandle, driver: Driver): Db {
function dbOver(
runner: TxHandle,
driver: Driver,
lifecycle: DbLifecycle,
transactionScope = false,
): Db {
function run<T>(operation: () => Promise<T>): Promise<T> {
if (lifecycle.closing && !transactionScope) {
return Promise.reject(new Error("WRN-DB-CLOSED: database is closing or closed"));
}
const promise = Promise.resolve().then(operation);
lifecycle.active.add(promise);
void promise.finally(() => lifecycle.active.delete(promise)).catch(() => {});
return promise;
}
const db: Db = {
driver,
async all(sql, params = [], model) {
const rows = await runner.query(sql, params);
const rows = await run(() => runner.query(sql, params));
return (model ? rows.map((r) => model.parse(r)) : rows) as never;
},
async one(sql, params = [], model) {
@@ -63,18 +83,25 @@ function dbOver(runner: TxHandle, driver: Driver): Db {
return (rows[0] ?? null) as never;
},
exec(sql, params = []) {
return runner.exec(sql, params);
return run(() => runner.exec(sql, params));
},
async tx(fn) {
// Top level opens a real transaction; inside one, reuse the current tx.
if (runner === driver) return driver.transaction((tx) => fn(dbOver(tx, driver)));
if (runner === driver)
return run(() => driver.transaction((tx) => fn(dbOver(tx, driver, lifecycle, true))));
return fn(db);
},
async createTable(model) {
await runner.exec(createTableSql(model, driver.dialect));
await run(() => runner.exec(createTableSql(model, driver.dialect)));
},
close() {
return driver.close();
if (lifecycle.closePromise) return lifecycle.closePromise;
lifecycle.closing = true;
lifecycle.closePromise = (async () => {
await Promise.allSettled([...lifecycle.active]);
await driver.close();
})();
return lifecycle.closePromise;
},
};
return db;
@@ -82,5 +109,5 @@ function dbOver(runner: TxHandle, driver: Driver): Db {
/** Build a `Db` client from a driver. */
export function createDb(driver: Driver): Db {
return dbOver(driver, driver);
return dbOver(driver, driver, { closing: false, active: new Set() });
}