const fs = require("fs"); const path = require("path"); function createSqliteStorage(options) { const sqlitePath = options.sqlitePath; let db = null; function requireDriver() { try { return require("node:sqlite").DatabaseSync; } catch { throw new Error("SQLite storage requires Node.js with built-in 'node:sqlite' (Node 22+)"); } } return { id: "sqlite", async init() { const Database = requireDriver(); fs.mkdirSync(path.dirname(sqlitePath), { recursive: true }); db = new Database(sqlitePath); db.exec("PRAGMA journal_mode = WAL"); db.exec("CREATE TABLE IF NOT EXISTS kv (k TEXT PRIMARY KEY, v TEXT NOT NULL)"); db.exec("CREATE TABLE IF NOT EXISTS logs (k TEXT NOT NULL, ts INTEGER NOT NULL, line TEXT NOT NULL)"); }, async exists(key) { const row = db.prepare("SELECT 1 AS ok FROM kv WHERE k = ? LIMIT 1").get(key); return Boolean(row); }, async readJson(key, fallback = null) { const row = db.prepare("SELECT v FROM kv WHERE k = ? LIMIT 1").get(key); if (!row) { return fallback; } try { return JSON.parse(row.v); } catch { return fallback; } }, async writeJson(key, value) { const raw = JSON.stringify(value); db.prepare("INSERT INTO kv(k, v) VALUES(?, ?) ON CONFLICT(k) DO UPDATE SET v = excluded.v").run(key, raw); }, async appendText(key, text) { db.prepare("INSERT INTO logs(k, ts, line) VALUES(?, ?, ?)").run(key, Date.now(), text); }, async readText(key, fallback = "") { const rows = db.prepare("SELECT line FROM logs WHERE k = ? ORDER BY ts ASC").all(key); if (!rows.length) { return fallback; } return rows.map((row) => row.line).join(""); }, async writeText(key, text) { db.prepare("DELETE FROM logs WHERE k = ?").run(key); if (text) { db.prepare("INSERT INTO logs(k, ts, line) VALUES(?, ?, ?)").run(key, Date.now(), text); } } }; } module.exports = { createSqliteStorage };