Skip to content

DocumentStore

The main class. Handles document creation, editing, versioning, and sync.

Constructor

typescript
import { DocumentStore, SurrealdbPersistence } from 'document-store';

const store = new DocumentStore({
    storage: new SurrealdbPersistence('surrealkv://./data'),

    // Optional: cryptographic signatures
    sign: async (uid, hash, claim) => { ... },
    verify: async (uid, hash, signature, claim) => { ... },

    // Optional: require signatures (default: true when sign/verify provided)
    requireSignatures: true,

    // Optional: custom permission resolver
    permissionResolver: async (permission, context) => { ... },

    // Optional: schema validation
    schemaValidator: myValidator,
});

Options

OptionTypeDescription
storageSurrealdbPersistence | SqlitePersistence | MongoDbPersistenceStorage backend (required)
sign(uid, hash, claim) => SignResultSign documents on create/edit
verify(uid, hash, signature, claim) => booleanVerify signatures on inject
requireSignaturesbooleanRequire valid signatures (default: true when callbacks set)
permissionResolverfunctionCustom permission resolver for write rules — see Write Rules
shareResolver(share, accessorUid, doc) => booleanCustom share logic fallback — see Share Policies
schemaValidatorSchemaValidatorContent validation on add() and edit() — see Schemas guide

registerType(schema)

Register a document type. Must be called before adding documents of that type. Accepts a full schema or a minimal type name with options.

Full schema

typescript
store.registerType({
    type: 'discussion',
    meta: { label: { en: 'Discussion' } },
    fields: {
        name: { type: 'string', required: true },
        members: {
            type: 'array',
            membership: { userField: 'userId', roleField: 'role', roleHierarchy: ['admin', 'member'] },
            temporal: { table: 'discussion_members', key: 'userId' },
            items: {
                userId: { type: 'uid', required: true },
                role: { type: 'enum', values: ['admin', 'member'] },
            },
        },
    },
    write: { '*': { allow: 'uid' } },
});

Creates the rendered table, extracts membership config for token computation, and creates temporal tables. See Schemas guide for full schema reference.

Minimal registration

typescript
store.registerType('bookmark');

Render options

Controls rendered timestamp aliases. System fields (time, updated, uid, parent, hash) and content fields are always included.

typescript
store.registerType('activity', {
    render: { createdAt: 'created', updatedAt: 'modified' }
});
OptionTypeDefaultEffect
createdAtboolean | stringtrueRender creation timestamp alias. true = createdAt, string = custom name, false = disabled
updatedAtboolean | stringtrueRender last-edit timestamp alias. true = updatedAt, string = custom name, false = disabled

add(type, doc) → EditResult

Create a new document.

typescript
const [errors, hash] = await store.add('bookmark', {
    uid,
    url: 'https://example.com',
    title: 'Example',
    share: { public: { license: 'SRL' } },
    write: { '*': 'uid' },
});

Returns [errors, null] on failure or [null, hash] on success.

addMany(type, docs) → [errors, hashes]

Create multiple documents atomically.

typescript
const [errors, hashes] = await store.addMany('bookmark', [
    { uid, url: 'https://a.com', title: 'A' },
    { uid, url: 'https://b.com', title: 'B' },
]);

edit(uid, filter, update) → EditResult

Apply an update to a document.

typescript
const [errors, newHash] = await store.edit(uid, { hash }, {
    $set: { title: 'Updated' }
});

See Editing guide for all operators.

save(uid, hash, content) → EditResult

Replace document content. The store computes the minimal diff.

typescript
const [errors, newHash] = await store.save(uid, hash, {
    title: 'New Title',
    url: 'https://example.com',
});

delete(uid, hash)

Soft-delete a document and its children.

typescript
await store.delete(uid, hash);

restore(uid, hash)

Restore a soft-deleted document and its children.

typescript
await store.restore(uid, hash);

Reads — query your database directly

Document-store renders documents into your database. For reads, query the database directly using its native tools. See Querying guide.

type(type) → DSCollection

Get a type-bound collection for writes.

typescript
const bookmarks = store.type<Bookmark>('bookmark');
await bookmarks.add({ uid, url, title });

versions(hash)

Get the full version history of a document.

typescript
const { original, versions, edits } = await store.versions(hash);

get(hash) → SyncItem

Get a document for P2P transmission (CBOR-encoded).

typescript
const syncItem = await store.get(hash);
// { hash, data (Buffer), time, signed }

inject(syncItem)

Receive and apply a document from a peer.

typescript
await store.inject(syncItem);

getShared(accessorUid, timestamp) → SyncItem[]

Get documents the accessor has access to, newer than timestamp.

typescript
const items = await store.getShared(peerUidHex, lastSyncTime);

find(query, section?) → Buffer[]

Full-text search across documents with registered search functions. Returns matching document hashes.

typescript
// Search all sections
const hashes = await store.find('search term');

// Search a specific section
const hashes = await store.find('javascript', 'tags');

See Search guide for details on registering search functions and keyword extraction.