lightbase-better-sqlite3
v0.2.0
Published
Drop-in replacement for better-sqlite3 with a TRUE synchronous API (worker-thread + Atomics bridge) backed by Lightbase.
Maintainers
Readme
@lightbase/better-sqlite3
Drop-in replacement for better-sqlite3 backed by Lightbase. Apps already written against better-sqlite3's synchronous API keep working with one change: the import and connection string — no codebase digging required.
The sync-async bridge
The synchronous methods are real. A dedicated worker thread owns the HTTP
calls; a statement call posts a job to the worker, blocks on Atomics.wait,
and the worker writes the response into a shared buffer and wakes the caller.
From your code's point of view stmt.get(id) is a plain synchronous function
returning the row — exactly like better-sqlite3.
Environments without worker threads (edge runtimes) use AsyncDatabase: the
identical surface, promise-based.
Install / use
No npm registry needed — copy the better-sqlite3/ folder (or install it
with a git path) and require it:
// Before (better-sqlite3)
const Database = require('better-sqlite3');
const db = new Database('./my.db');
// After (Lightbase)
const Database = require('@lightbase/better-sqlite3');
const db = new Database('lightbase://your-host?project=my-app&key=lb_live_xxx');
const row = db.prepare('SELECT * FROM users WHERE id = ?').get(123); // sync, really
db.prepare('INSERT INTO users (name) VALUES (?)').run('Alice'); // sync, really
const rows = db.prepare('SELECT * FROM users').all(); // sync, reallyConnection string formats:
lightbase://host:port?project=PROJECT&key=API_KEYlightbases://host:port?project=PROJECT&key=API_KEY(force TLS)
API surface
| better-sqlite3 | @lightbase/better-sqlite3 | Notes |
|---|---|---|
| db.prepare(sql).run(...p) | same | { changes, lastInsertRowid } |
| db.prepare(sql).get(...p) | same | row or undefined |
| db.prepare(sql).all(...p) | same | array of rows |
| db.prepare(sql).iterate(...p) | same | sync iterator |
| db.exec(script) | same | multi-statement, fail-fast |
| db.pragma(str) | same | real rows (e.g. table_info) |
| db.transaction(fn) | same | writes flush atomically server-side |
| db.close() | same | terminates the bridge worker |
| async variants | runAsync/getAsync/allAsync/iterateAsync | edge-safe |
| — | db.batch(stmts, { transaction: true }) | one round-trip, all-or-nothing |
Transactions
db.transaction(fn) records the writes issued inside fn and flushes them
in a single server-side WAL transaction when the outermost transaction
returns — either every write lands or none does. Reads inside fn execute
immediately against committed (pre-transaction) state. Nested transaction
wrappers flatten into the outer batch.
const insertMany = db.transaction((items) => {
for (const item of items) {
db.prepare('INSERT INTO items (name) VALUES (?)').run(item.name);
}
});
insertMany(['a', 'b', 'c']); // atomicSQL dialect
The full SQL compatibility surface (aggregates count/sum/avg/min/max,
GROUP BY + HAVING, BETWEEN, NOT IN, scalar functions, CASE WHEN,
CREATE/DROP TABLE, CREATE/DROP INDEX, positional and named parameters
? :name @name $name) is documented in the Lightbase server repository
under src/core/compat/sql.ts.
BismiLLAH
Built with the Lightbase core working protocol: every deliverable opens with BismiLLAH and closes in gratitude.
