import SQLiteESMFactory from '@journeyapps/wa-sqlite/dist/wa-sqlite.mjs' import * as SQLite from '@journeyapps/wa-sqlite' import { SCHEMA_SQL } from './schema.js' let db = null let sqlite3 = null const tableListeners = new Map() let initPromise = null export function initDatabase() { if (initPromise) return initPromise initPromise = _init() return initPromise } async function _init() { const module = await SQLiteESMFactory() sqlite3 = SQLite.Factory(module) db = await sqlite3.open_v2(':memory:') for (const sql of SCHEMA_SQL.split(';').filter(s => s.trim())) { await sqlite3.exec(db, sql) } return db } export function notifyTableChanged(table) { tableListeners.get(table)?.forEach(cb => cb()) } export function onTableChange(table, cb) { if (!tableListeners.has(table)) tableListeners.set(table, new Set()) tableListeners.get(table).add(cb) return () => tableListeners.get(table).delete(cb) } export async function execSQL(sql, params = []) { if (!db) throw new Error('DB not initialized') const results = [] if (params.length === 0) { await sqlite3.exec(db, sql, (row, cols) => { results.push(Object.fromEntries(cols.map((c, i) => [c, row[i]]))) }) } else { for await (const stmt of sqlite3.statements(db, sql)) { sqlite3.bind_collection(stmt, params) const cols = sqlite3.column_names(stmt) while ((await sqlite3.step(stmt)) === SQLite.SQLITE_ROW) { results.push(Object.fromEntries(cols.map((c, i) => [c, sqlite3.column(stmt, i)]))) } } } return results }