UrsulaDatabase
Last updated 29 October 2026
UrsulaDatabase is the connection open() returns: a node:sqlite DatabaseSync with the members below.
UrsulaDatabase
Exported by @tonbo/sqlite-ursula and /tonbo.
class UrsulaDatabase extends DatabaseSync {
readonly name: string;
readonly boundPath: string;
synced(options?: { signal?: AbortSignal }): Promise<void>;
status(): UrsulaStatus;
on(event: "reset", listener: ResetListener): this;
off(event: "reset", listener: ResetListener): this;
close(): void;
}
type ResetListener = (error: UrsulaResetError) => void;Every DatabaseSync method works as in node:sqlite. The ones that run SQL (exec, applyChangeset, and run, get, all and iterate of the statements prepare returns) throw an UrsulaError for a failure of the extension and every other error unchanged. Get a connection only from open(): one constructed directly, as a library may do through db.constructor, is a plain DatabaseSync that classifies nothing.
| Member | What it is |
|---|---|
name | The stream’s path, such as /acme/notes. |
boundPath | The local database file the extension bound, as status().path reports it. |
synced() | Resolves once the stream holds every earlier commit. See synced(). |
status() | The database’s state, synchronously. See Status. |
on("reset", listener), off("reset", listener) | Add or remove a reset listener. Another event name throws TypeError. Both return the database. |
close() | Closes the connection. See close(). |
synced()
synced(options?: { signal?: AbortSignal }): Promise<void>Resolves once the stream holds every commit this process logged before the call, and a round trip that started after the call found this process still the owner. Await it before anything outside the process acts on what you wrote or read; gate() does that for a handler. It does not block the event loop, and it keeps the process alive while it waits.
- Network failures never reject it: it waits. Past
maxPendingBytes, writes fail withbacklog_fullmeanwhile. - It rejects with the
UrsulaResetErroron a reset, and withsignal.reasonwhensignalfires; the commits keep replicating. - On a reader cache (a
readOnlyopen in a process that does not own the stream) it resolves at once: the reader holds no commit. - On a database that retired it rejects with
UrsulaSetupError.
What the stream then holds, and how durably, is on When a commit is durable.
Reset listeners
ResetListener is (error: UrsulaResetError) => void. When the database is reset, its pending synced() calls reject first, then each listener runs once with the reset. A listener that throws does not stop the others: its error is rethrown outside, as an uncaught exception, as an EventEmitter’s would be.
db.on("reset", (error) => {
if (error.action === "stop") process.exit(1); // another process took it over
// reopen or fix: stop taking work, then open() the database again
});After a reset
Every statement of the database throws the UrsulaResetError, reads included, except reads in a read transaction it had open, which keep their snapshot; a write in it still fails. open() the database again, or stop when the action is stop. The new open need not wait for the old connection to close: it works on a copy of the local cache, which carries every commit the old one made. Close the old connection once you no longer need it.
A refused write or a reset rolls SQLite’s whole transaction back. A ROLLBACK that a transaction helper sends afterwards succeeds as a prepared statement, and through exec it throws the same UrsulaError again, so the error you handle is the package’s, not “no transaction is active”.
close()
Closes the connection, synchronously. Once a binding’s last connection closes, the commits left replicate in the background and the binding retires; a process that exits before then leaves them in the local log, and the next open sends them. To use the database again, call the package’s open(): DatabaseSync’s own open() method binds nothing.
Salvage
A local cache an open could not keep is moved into salvage/, and status().salvage lists it. When that happens and what to do with it is on Backups and salvage.