ProvendbStore — ProvenDB versioned documents + proofs (HTTP/JSON)

Read this page in the documentation

ProvendbStore — ProvenDB versioned documents + proofs (HTTP/JSON) Overview ProvenDB is a MongoDB-compatible database that adds immutable, versioned documents plus cryptographic proofs: every write is captured at a monotonically increasing version, and ProvenDB can produce a Merkle proof that a document (or a whole query result) existed at a given version, anchored into a public blockchain. That makes it append-only/auditable on top of a familiar document API. ProvenDB is not a SQL Dialect, so ProvendbStore 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 | 'provendb' | library | 'fetch' | HTTP proof API over fetch While ProvenDB exposes a Mongo wire protocol, its distinguishing feature — versioned documents and proofs — is surfaced here over its REST/HTTP proof API using the global fetch — so library === 'fetch' — via a tiny ProvendbHttpClient (get(path) + post(path, body?) returning parsed JSON). connect() builds a fetch-backed client with createProvendbFetchClient(baseURL, headers); there is no external package to install. The fetch client sends JSON on POST (Content-Type: application/json plus any configured headers; omits the body when undefined) and throws Error("HTTP <status> <statusText>") on a non-OK response. Injected client ProvendbStoreOptions accepts a pre-built client (any ProvendbHttpClient). When provided, connect() uses it directly and baseURL is ignored. This is how the test suite injects an in-memory mock client (no network) that records each GET/POST and returns canned responses. Connection Build a store from connection options and call connect(). All options are optional. Option | Type | Purpose | --------- | ------------------------ | ----------------------------------------------------------------------- | baseURL | string | ProvenDB HTTP API base URL. Defaults to 'http://localhost:8080'. Ignored when client is provided. | headers | Record<string, string> | Extra HTTP headers (e.g. an API token). | client | ProvendbHttpClient | A pre-built HTTP client. When set, baseURL is ignored. | Injected-client form Methods Every ledger method calls the HTTP client and 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. collection and id are encodeURIComponent-escaped into the path. Lifecycle Method | Signature | Behavior | ------------- | --------------------------------- | ------------------------------------------------------------------------------------------------------------- | connect | connect(): Promise<void> | Uses an injected client if provided, otherwise builds a fetch-backed client from baseURL/headers. Idempotent. | 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(): ProvendbHttpClient | Returns the underlying (internal or injected) HTTP client. Throws ConnectionError if not connected. | Ledger surface Method | Signature | HTTP call | Behavior | --------- | ---------------------------------------------------------------------------------------------------- | ----------------------------------------------------------- | ------------------------------------------------------------------------------------------------ | append | append(collection: string, data: Record<string, unknown>): Promise<unknown> | POST /collections/<c>/documents (body data) | Inserts data at a new version. Returns the inserted document (incl. id/version). | get | get(collection: string, id: string): Promise<unknown> | GET /collections/<c>/documents/<id> | Reads the current version of document id. | history | history(collection: string, id: string): Promise<unknown> | GET /collections/<c>/documents/<id>/versions | Returns every version of the document. | verify | verify(collection: string, id: string): Promise<unknown> | POST /collections/<c>/documents/<id>/proof (no body) | Requests a cryptographic proof — returns the Merkle proof + public-blockchain anchor for the document's state at its version. | query | query(collection: string, query?: Record<string, unknown>, options?: Record<string, unknown>): Promise<unknown> | POST /collections/<c>/query (body { query, options }) | Runs a Mongo-style filter query. query is the Mongo filter (defaults to {}); options carries projection/sort/limit and an optional historical version. | Note: verify is the one method here that returns a real cryptographic artifact — ProvenDB generates the Merkle proof and blockchain anchor server-side. This store surfaces it; it does not re-check the anchor itself. Example Verification status Unit / mock-verified only. The tests in tests/nosql/provendb.test.ts inject an in-memory mock ProvendbHttpClient via ProvendbStoreOptions.client, so no network is touched. The mock records every GET/POST (path + body) and returns canned responses. What this proves: Each method uses the correct HTTP verb + path (POST .../documents, GET .../documents/<id>, GET .../documents/<id>/versions, POST .../documents/<id>/proof, POST .../query) with the expected body (data, or { query, options }, or undefined for the proof POST). Responses are returned to the caller unchanged (e.g. the { id, version } from append, the proof object from verify). Lifecycle: isConnected() false before connect(), 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 ProvenDB server, or independent validation of the Merkle proof / blockchain anchor. The request/response shape is verified against ProvenDB's documented HTTP 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