mirror of
https://github.com/diegosouzapw/OmniRoute.git
synced 2026-09-20 22:02:19 +03:00
Right precedent — #7494 fixed exactly this for the sql.js adapter and the `node:sqlite` one never got the same treatment, even though it is the default driver whenever better-sqlite3 is unavailable. `/api/db-backups/import` opening a throwaway adapter per request makes it reachable. I reformatted the changelog fragment to the `changelog.d` convention (`- **fix(scope):** …`) before merging — `check:changelog-integrity` rejects a fragment that does not start with a markdown bullet, which is the same gate your #13158 was about. Wording is yours, unchanged in substance. --- Validated in one consolidated worktree cut from `release/v3.8.51`, boarded together with the other 13 PRs of this batch — zero merge conflicts between them. - `typecheck:core` clean - complexity 2799 / baseline 3218 and cognitive-complexity 1265 / baseline 1437 — both under baseline - 71 focused assertions green across the 13 test files this batch adds or touches ⚠️ base-red inherited: #12732 — `Docs Gates (fast-path)`, `Merge integrity`, `No new ESLint warnings`, `Unit Tests fast-path` and `Fast Quality Gates` all reproduce on the pure `release/v3.8.51` tip (provider count 356 vs the 358 the modules define, SKILL.md drift, and `open-sse/utils/stream.ts` at 3115 > frozen 3098). None of them touch this diff. Thanks @anhtahaylove — the root-cause write-up, the measured before/after numbers and the red-before-green proof on every one of these made the batch reviewable as a unit.
69 lines
2.2 KiB
TypeScript
69 lines
2.2 KiB
TypeScript
import type { SqliteAdapter } from "./types";
|
|
import {
|
|
createNodeSqliteAdapterFromDatabase,
|
|
type NodeSqliteDatabaseLike,
|
|
} from "./nodeSqliteShared";
|
|
|
|
const CHECKPOINT_INTERVAL_MS = 60_000;
|
|
|
|
export async function createNodeSqliteAdapter(filePath: string): Promise<SqliteAdapter> {
|
|
// Suprimir ExperimentalWarning
|
|
const origEmit = process.emit.bind(process);
|
|
(process as NodeJS.Process).emit = function (name: string, ...args: unknown[]) {
|
|
if (
|
|
name === "warning" &&
|
|
args[0] !== null &&
|
|
typeof args[0] === "object" &&
|
|
"name" in (args[0] as object) &&
|
|
(args[0] as { name: string }).name === "ExperimentalWarning"
|
|
) {
|
|
return false;
|
|
}
|
|
return origEmit(name as never, ...(args as never[]));
|
|
} as typeof process.emit;
|
|
|
|
const { DatabaseSync } = (await import("node:sqlite" as never)) as {
|
|
DatabaseSync: new (path: string) => NodeSqliteDatabaseLike;
|
|
};
|
|
|
|
const db = new DatabaseSync(filePath);
|
|
|
|
const checkpointTimer = setInterval(() => {
|
|
try {
|
|
db.exec("PRAGMA wal_checkpoint(TRUNCATE)");
|
|
} catch {}
|
|
}, CHECKPOINT_INTERVAL_MS);
|
|
(checkpointTimer as unknown as NodeJS.Timeout).unref?.();
|
|
|
|
// Declared before gracefulClose so the close path can detach them. Without
|
|
// this, every closed adapter leaves three closures pinned on `process` --
|
|
// each holding this adapter and its DatabaseSync handle alive -- and short-
|
|
// lived adapters (POST /api/db-backups/import opens one per request) trip
|
|
// Node's MaxListenersExceededWarning. #7494 fixed exactly this for sql.js.
|
|
const onBeforeExit = () => {
|
|
adapter.close();
|
|
};
|
|
const onSignal = () => {
|
|
adapter.close();
|
|
process.exit(0);
|
|
};
|
|
|
|
function gracefulClose() {
|
|
clearInterval(checkpointTimer as unknown as NodeJS.Timeout);
|
|
try {
|
|
db.exec("PRAGMA wal_checkpoint(TRUNCATE)");
|
|
} catch {}
|
|
process.removeListener("beforeExit", onBeforeExit);
|
|
process.removeListener("SIGINT", onSignal);
|
|
process.removeListener("SIGTERM", onSignal);
|
|
}
|
|
|
|
const adapter = createNodeSqliteAdapterFromDatabase(db, filePath, gracefulClose);
|
|
|
|
process.once("beforeExit", onBeforeExit);
|
|
process.once("SIGINT", onSignal);
|
|
process.once("SIGTERM", onSignal);
|
|
|
|
return adapter;
|
|
}
|