From b3c72dea0307277fec56daa3bf95dee19e1ef0ce Mon Sep 17 00:00:00 2001 From: Etan Joseph Heyman Date: Sun, 15 Mar 2026 03:02:06 +0200 Subject: [PATCH 1/2] fix: tighten node engine range for node:sqlite compat (#206) --- apps/server/package.json | 2 +- apps/server/src/persistence/Layers/Sqlite.ts | 32 +++++++++++++++++++- 2 files changed, 32 insertions(+), 2 deletions(-) diff --git a/apps/server/package.json b/apps/server/package.json index 546a2c3b68..a6ffd53b8b 100644 --- a/apps/server/package.json +++ b/apps/server/package.json @@ -44,6 +44,6 @@ "vitest": "catalog:" }, "engines": { - "node": "^22.13 || ^23.4 || >=24.10" + "node": "^22.16 || ^23.11 || >=24.10" } } diff --git a/apps/server/src/persistence/Layers/Sqlite.ts b/apps/server/src/persistence/Layers/Sqlite.ts index 33f99482d9..1a0c9e9c92 100644 --- a/apps/server/src/persistence/Layers/Sqlite.ts +++ b/apps/server/src/persistence/Layers/Sqlite.ts @@ -16,11 +16,38 @@ const defaultSqliteClientLoaders = { node: () => import("../NodeSqliteClient.ts"), } satisfies Record Promise>; +/** + * Verify that the current Node.js version includes the `node:sqlite` APIs + * used by `NodeSqliteClient` — specifically `StatementSync.columns()` (added + * in Node 22.16.0 / 23.11.0). + * + * @see https://github.com/nodejs/node/pull/57490 + */ +function checkNodeSqliteCompat(): void { + const parts = process.versions.node.split(".").map(Number); + const major = parts[0] ?? 0; + const minor = parts[1] ?? 0; + const supported = + (major === 22 && minor >= 16) || + (major === 23 && minor >= 11) || + major >= 24; + + if (!supported) { + throw new Error( + `Node.js ${process.versions.node} is missing required node:sqlite APIs ` + + `(StatementSync.columns). Upgrade to Node.js >=22.16, >=23.11, or >=24.`, + ); + } +} + const makeRuntimeSqliteLayer = ( config: RuntimeSqliteLayerConfig, ): Layer.Layer => Effect.gen(function* () { const runtime = process.versions.bun !== undefined ? "bun" : "node"; + if (runtime === "node") { + checkNodeSqliteCompat(); + } const loader = defaultSqliteClientLoaders[runtime]; const clientModule = yield* Effect.promise(loader); return clientModule.layer(config); @@ -41,7 +68,10 @@ export const makeSqlitePersistenceLive = (dbPath: string) => const path = yield* Path.Path; yield* fs.makeDirectory(path.dirname(dbPath), { recursive: true }); - return Layer.provideMerge(setup, makeRuntimeSqliteLayer({ filename: dbPath })); + return Layer.provideMerge( + setup, + makeRuntimeSqliteLayer({ filename: dbPath }), + ); }).pipe(Layer.unwrap); export const SqlitePersistenceMemory = Layer.provideMerge( From b2a41a9a9acfbd3e7364799e206f9ee93ee62018 Mon Sep 17 00:00:00 2001 From: Julius Marminge Date: Sat, 14 Mar 2026 19:17:14 -0700 Subject: [PATCH 2/2] move --- apps/server/src/persistence/Layers/Sqlite.ts | 32 +------------------ .../src/persistence/NodeSqliteClient.ts | 24 ++++++++++++++ 2 files changed, 25 insertions(+), 31 deletions(-) diff --git a/apps/server/src/persistence/Layers/Sqlite.ts b/apps/server/src/persistence/Layers/Sqlite.ts index 1a0c9e9c92..33f99482d9 100644 --- a/apps/server/src/persistence/Layers/Sqlite.ts +++ b/apps/server/src/persistence/Layers/Sqlite.ts @@ -16,38 +16,11 @@ const defaultSqliteClientLoaders = { node: () => import("../NodeSqliteClient.ts"), } satisfies Record Promise>; -/** - * Verify that the current Node.js version includes the `node:sqlite` APIs - * used by `NodeSqliteClient` — specifically `StatementSync.columns()` (added - * in Node 22.16.0 / 23.11.0). - * - * @see https://github.com/nodejs/node/pull/57490 - */ -function checkNodeSqliteCompat(): void { - const parts = process.versions.node.split(".").map(Number); - const major = parts[0] ?? 0; - const minor = parts[1] ?? 0; - const supported = - (major === 22 && minor >= 16) || - (major === 23 && minor >= 11) || - major >= 24; - - if (!supported) { - throw new Error( - `Node.js ${process.versions.node} is missing required node:sqlite APIs ` + - `(StatementSync.columns). Upgrade to Node.js >=22.16, >=23.11, or >=24.`, - ); - } -} - const makeRuntimeSqliteLayer = ( config: RuntimeSqliteLayerConfig, ): Layer.Layer => Effect.gen(function* () { const runtime = process.versions.bun !== undefined ? "bun" : "node"; - if (runtime === "node") { - checkNodeSqliteCompat(); - } const loader = defaultSqliteClientLoaders[runtime]; const clientModule = yield* Effect.promise(loader); return clientModule.layer(config); @@ -68,10 +41,7 @@ export const makeSqlitePersistenceLive = (dbPath: string) => const path = yield* Path.Path; yield* fs.makeDirectory(path.dirname(dbPath), { recursive: true }); - return Layer.provideMerge( - setup, - makeRuntimeSqliteLayer({ filename: dbPath }), - ); + return Layer.provideMerge(setup, makeRuntimeSqliteLayer({ filename: dbPath })); }).pipe(Layer.unwrap); export const SqlitePersistenceMemory = Layer.provideMerge( diff --git a/apps/server/src/persistence/NodeSqliteClient.ts b/apps/server/src/persistence/NodeSqliteClient.ts index b121764fcc..1d6e22d9b0 100644 --- a/apps/server/src/persistence/NodeSqliteClient.ts +++ b/apps/server/src/persistence/NodeSqliteClient.ts @@ -50,11 +50,35 @@ export interface SqliteMemoryClientConfig extends Omit< "filename" | "readonly" > {} +/** + * Verify that the current Node.js version includes the `node:sqlite` APIs + * used by `NodeSqliteClient` — specifically `StatementSync.columns()` (added + * in Node 22.16.0 / 23.11.0). + * + * @see https://github.com/nodejs/node/pull/57490 + */ +const checkNodeSqliteCompat = () => { + const parts = process.versions.node.split(".").map(Number); + const major = parts[0] ?? 0; + const minor = parts[1] ?? 0; + const supported = (major === 22 && minor >= 16) || (major === 23 && minor >= 11) || major >= 24; + + if (!supported) { + return Effect.die( + `Node.js ${process.versions.node} is missing required node:sqlite APIs ` + + `(StatementSync.columns). Upgrade to Node.js >=22.16, >=23.11, or >=24.`, + ); + } + return Effect.void; +}; + const makeWithDatabase = ( options: SqliteClientConfig, openDatabase: () => DatabaseSync, ): Effect.Effect => Effect.gen(function* () { + yield* checkNodeSqliteCompat(); + const compiler = Statement.makeCompilerSqlite(options.transformQueryNames); const transformRows = options.transformResultNames ? Statement.defaultTransforms(options.transformResultNames).array