Read the Flashpoint database with node:sqlite

better-sqlite3 has no prebuilt binary for the image's Node version and
node:24-slim can't compile it. The built-in module needs no native build.
This commit is contained in:
2026-10-11 02:07:00 -07:00
parent aadd6fe776
commit 52e90ba164
4 changed files with 6 additions and 41 deletions
-33
View File
@@ -6,14 +6,12 @@
"": {
"name": "flashpoint-session-manager",
"dependencies": {
"better-sqlite3": "^13.0.3",
"dockerode": "^5.0.1",
"http-proxy": "^1.18.1",
"tar-stream": "^3.2.2",
"yauzl": "^3.4.0"
},
"devDependencies": {
"@types/better-sqlite3": "^9.6.0",
"@types/dockerode": "^4.0.2",
"@types/http-proxy": "^1.17.17",
"@types/node": "^26.6.5",
@@ -151,16 +149,6 @@
"integrity": "sha512-b1UQwcEZ4yCnMCD8DAL1VlbvBJE9/IX4FTIp7BG1xYpf29SLazLSrqUkj4w7Y5y7cCVP6E5tcqqcI0xemPkHug==",
"license": "BSD-3-Clause"
},
"node_modules/@types/better-sqlite3": {
"version": "9.6.0",
"resolved": "https://registry.npmjs.org/@types/better-sqlite3/-/better-sqlite3-9.6.0.tgz",
"integrity": "sha512-ZEEwBSgMu7GYJOynoagg5X9JbxfL6dTJDsgViJIqh67jV44kyOr9RXfmFjLK5rzC4MWssP06t9hu/JwGDnUbCg==",
"dev": true,
"license": "MIT",
"dependencies": {
"@types/node": "*"
}
},
"node_modules/@types/docker-modem": {
"version": "3.0.6",
"resolved": "https://registry.npmjs.org/@types/docker-modem/-/docker-modem-3.0.6.tgz",
@@ -766,18 +754,6 @@
"tweetnacl": "^0.14.3"
}
},
"node_modules/better-sqlite3": {
"version": "13.0.3",
"resolved": "https://registry.npmjs.org/better-sqlite3/-/better-sqlite3-13.0.3.tgz",
"integrity": "sha512-RbOBxmLBG8uvFUc15X9+9SFemKcQ0WBuISBVkpuiaUB2qblC8UWlHEjdWVoZ8AdhSwmoEgsiXKfopX0CQxaACQ==",
"license": "MIT",
"dependencies": {
"node-addon-api": "^8.0.0"
},
"engines": {
"node": ">=22"
}
},
"node_modules/bl": {
"version": "4.1.0",
"resolved": "https://registry.npmjs.org/bl/-/bl-4.1.0.tgz",
@@ -1093,15 +1069,6 @@
"license": "MIT",
"optional": true
},
"node_modules/node-addon-api": {
"version": "8.9.2",
"resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-8.9.2.tgz",
"integrity": "sha512-VijLXbi3UACN69I0JVXJsX4tjACjNoQDgv2gTF6sx2wWEi8tkSg2eX8p5gSIFi8z2+DL3oHmY6OyKce38SDolg==",
"license": "MIT",
"engines": {
"node": "^18 || ^20 || >= 21"
}
},
"node_modules/once": {
"version": "1.4.0",
"resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz",
-2
View File
@@ -11,14 +11,12 @@
"node": ">=22.18"
},
"dependencies": {
"better-sqlite3": "^13.0.3",
"dockerode": "^5.0.1",
"http-proxy": "^1.18.1",
"tar-stream": "^3.2.2",
"yauzl": "^3.4.0"
},
"devDependencies": {
"@types/better-sqlite3": "^9.6.0",
"@types/dockerode": "^4.0.2",
"@types/http-proxy": "^1.17.17",
"@types/node": "^26.6.5",
+4 -4
View File
@@ -1,7 +1,7 @@
import { readFile } from 'node:fs/promises';
import path from 'node:path';
import { buffer } from 'node:stream/consumers';
import Database from 'better-sqlite3';
import { DatabaseSync } from 'node:sqlite';
import yauzl from 'yauzl';
/** Launch applications fp-launch can stream, lowercased. */
@@ -23,11 +23,11 @@ interface LaunchRow {
/** Looks up streamable games in a Flashpoint install. */
export class GameCatalog {
private readonly root: string;
private readonly db: Database.Database;
private readonly db: DatabaseSync;
constructor(root: string) {
this.root = root;
this.db = new Database(path.join(root, 'Data', 'flashpoint.sqlite'), { readonly: true, fileMustExist: true });
this.db = new DatabaseSync(path.join(root, 'Data', 'flashpoint.sqlite'), { readOnly: true });
}
/** Returns the display size for a streamable game, or null if it can't be streamed. */
@@ -40,7 +40,7 @@ export class GameCatalog {
from game g left join game_data d on d.id = g.activeDataId
where g.id = ?`,
)
.get(gameId) as LaunchRow | undefined;
.get(gameId) as unknown as LaunchRow | undefined;
if (!row || !STREAMABLE_APPS.has(row.app.toLowerCase())) {
return null;
}
+2 -2
View File
@@ -4,7 +4,7 @@ import { tmpdir } from 'node:os';
import path from 'node:path';
import { finished } from 'node:stream/promises';
import { test } from 'node:test';
import Database from 'better-sqlite3';
import { DatabaseSync } from 'node:sqlite';
import yazl from 'yazl';
import { appletSize, GameCatalog } from '../src/games.ts';
@@ -26,7 +26,7 @@ test('GameCatalog sizes streamable games from their GameZIP or htdocs', async ()
zip.end();
await finished(zip.outputStream.pipe(createWriteStream(path.join(root, 'Data', 'Games', 'zip-1690495544502.zip'))));
const db = new Database(path.join(root, 'Data', 'flashpoint.sqlite'));
const db = new DatabaseSync(path.join(root, 'Data', 'flashpoint.sqlite'));
db.exec(`
create table game (id, applicationPath, launchCommand, activeDataId);
create table game_data (id integer primary key, applicationPath, launchCommand, dateAdded);