TerminusdbStore — TerminusDB versioned document/graph store

Read this page in the documentation

TerminusdbStore — TerminusDB versioned document/graph store Overview TerminusDB is an immutable, versioned document/graph database with a git-like data model: every write produces a new commit on a branch, and the full commit history is retained, so past states are always reconstructable and the store is effectively append-only/auditable. Documents are typed JSON objects; queries are expressed in WOQL (the Web Object Query Language). TerminusDB is not a SQL Dialect, so TerminusdbStore implements the minimal NoSqlStore marker interface (src/nosql/store.ts) — connection lifecycle plus a getClient() escape hatch — plus the shared ledger surface (append/get/history/verify/query). Identity: Property | Value | --------- | ---------------------------------- | name | 'terminusdb' | library | '@terminusdb/terminusdb-client' | The store wraps a WOQLClient from the official @terminusdb/terminusdb-client package. Lazy loading — not a hard dependency @terminusdb/terminusdb-client is not a hard dependency of this package. It is loaded lazily via require() inside connect(), rather than a top-level import. Importing this module therefore does not require the package to be installed — it is only needed when a TerminusDB store is actually connected. On construction, the module resolves the client from mod.WOQLClient ?? mod.default?.WOQLClient ?? mod.default, builds new WOQLClient(url, { user, key, organization }), and calls the client's connect() if present. Injected client TerminusdbStoreOptions accepts a pre-built, already-connected client (a TerminusClientLike). When provided, connect() uses it verbatim and skips the require/construction. This is how the test suite injects a mock WOQLClient (no package, no network). If a db was configured, connect() still calls client.db(db) regardless of injection. Connection Build a store from connection options and call connect(). All options are optional. Option | Type | Purpose | -------------- | -------------------- | -------------------------------------------------------------- | url | string | Server URL. Defaults to 'http://localhost:6363'. | user | string | Username. | key | string | API key / password. | organization | string | Organization. | db | string | Database (data product) to select on connect via client.db(db). | client | TerminusClientLike | A pre-built, connected WOQLClient. When set, the package is not required. | Injected-client form Methods Every ledger method wraps failures in a DatabaseError (via DatabaseError.from, prefixing the message with the failing action). Using any method before connect() (or after disconnect()) throws a ConnectionError. Document ids are composed as <table>/<id>, unless the id already contains a / (then it passes through unchanged). Lifecycle Method | Signature | Behavior | ------------- | ---------------------------------- | ----------------------------------------------------------------------------------------------------------------------------- | connect | connect(): Promise<void> | Uses an injected client if provided, otherwise lazy-requires the package and builds a WOQLClient. Selects db if configured. Idempotent. Wraps failures in ConnectionError. | disconnect | disconnect(): Promise<void> | Clears the client and connected state (no network call). | isConnected | isConnected(): boolean | true only when connected and a client is present. | getClient | getClient(): TerminusClientLike | Returns the underlying WOQLClient for operations not wrapped here. Throws ConnectionError if not connected. | Ledger surface Method | Signature | client call | Behavior | --------- | -------------------------------------------------------------------------------------------- | ----------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------ | append | append(table: string, data: Record<string, unknown>): Promise<unknown> | addDocument({ '@type': table, ...data }, undefined, undefined, 'append <table>') | Inserts data as a new typed document (a new commit). Returns whatever addDocument reports (typically inserted id(s)). | get | get(table: string, id: string): Promise<unknown> | getDocument({ id: '<table>/<id>' }) | Fetches the current revision of document <table>/<id>. | history | history(table: string, id: string): Promise<unknown> | query({ '@type': 'CommitHistory', document: '<table>/<id>' }) | Runs a commit-history WOQL query over the immutable commit graph for the document. | verify | verify(table: string, id: string): Promise<{ id: string; exists: boolean; document: unknown }> | getDocument({ id }) (catching errors → null) | Reads the document back; returns { id, exists: document != null, document }. Presence in the commit graph is the provenance guarantee. | query | query(woql: unknown, commitMsg?: string): Promise<unknown> | query(woql, commitMsg) | Raw WOQL query object passthrough. | Note: verify establishes provenance by re-reading the document from the immutable store (TerminusDB never mutates past commits); it does not compute a separate cryptographic proof. Example Verification status Unit / mock-verified only. The tests in tests/nosql/terminusdb.test.ts inject a mock WOQLClient via TerminusdbStoreOptions.client, so connect() never loads @terminusdb/terminusdb-client and no network is touched. Jest spies assert each ledger method routes to addDocument/getDocument/query with the composed <table>/<id> id. What this proves: connect() selects the configured db (client.db('mydb')). append calls addDocument({ '@type': 'Person', name: 'Ada' }, undefined, undefined, 'append Person'). get composes Person/ada and passes a full id (Person/ada) through unchanged. history runs the CommitHistory WOQL query; query passes a raw WOQL object through with commitMsg. verify returns { id, exists, document }, reporting exists: false (and document: null) when getDocument rejects. Lifecycle: connecting via injected client, disconnect(), and ConnectionError from getClient() / reads before connect(). Error handling: client failures wrapped in DatabaseError. What this does not prove: live execution against a real TerminusDB server, or the correctness of WOQL commit-history queries end to end. The call/response shape is verified against the client's documented contract, but execution over the wire has not been exercised here. Related reading All data stores — the full catalogue, grouped by purpose Database types — where this sits among the 22 categories