SDK

API reference

A compact reference for @mdbase-dev/sdk: connect, the client, writes, status, files and errors.

This page lists the main public API. The package’s TypeScript declarations are the full reference.

connect()

Signature
connect(options: ClientOptions): Promise<MdbaseClient>

interface ClientOptions {
  connector: Connector;
  app: { name: string; version: string };
  timezone?: string;              // IANA zone for writes and queries; default: the host's
  features?: string[];            // optional features to request, such as "presence"
  reconnect?: false | { minDelayMs?: number; maxDelayMs?: number }; // on by default
  waitForDevice?: boolean;        // Private: wait for a device instead of failing
  onWaiting?: (why: MdbaseError) => void;
  signal?: AbortSignal;
}

Connectors: relayConnector and nextRelayConnector (remote, through the relay or to the hosted replica), inProcessConnector, localLinkConnector, and from @mdbase-dev/sdk/node, ipcConnector and connectDaemonLocalhost. In tests, new MemoryReplica().connector().

Reads

MethodReturns
get(ref, include?, signal?)RecordView; throws not_found
find(ref, include?, signal?)RecordView | null
readMany(refs, …)Several records in one call
query(query, include?, signal?)One QueryResult page; cursor when there is more
pages(query, include?, signal?, { onReset })An async iterator over every page
live(query, include?)A LiveQuery: records, stale, complete, ready, subscribe(fn), setQuery(q), close()
changes(cursor?, limit?){ changes, cursor, reset }
watchChanges(cursor, onChanges)A stop function with ready and state
backlinks(…)Records that link to a record
describe()Types, contracts and settings of the collection
queryContract({ id, version }, options?)Records through a contract’s field names
validate(refs?)Validation issues per record
views.list(), views.execute(…)Saved views

A RecordRef is a record ID, { path }, or a RecordView. Include is { body, effective, document, links, diagnostics }, each a boolean.

Writes

MethodNotes
create({ id?, type?, path?, frontmatter?, body?, document? }, options?)The ID is minted locally and usable at once
update(ref, { patch, unset, add, remove, body, bodyEdits, ifRevision }, options?)Pass a RecordView to merge field by field
replaceDocument(ref, source, options?)Replace the whole Markdown source
rename(view, to, { updateRefs, ifRevision })updateRefs defaults to true
delete(ref, { ifRevision })
preflightRename(view, to), preflightDelete(ref)What the change would touch
receipt(mutationId), awaitReceipt(mutationId, timeoutMs?)The current receipt; or wait until it leaves pending
pendingWrites()Writes still waiting
records.open(ref, { autosave, timeoutMs, signal, recovery })A record session lease; see Editing records
WriteOptions
interface WriteOptions {
  mutationId?: string;            // default: a new UUIDv7
  conflictMode?: "record" | "reject";
  timezone?: string;
  include?: Include;
  dryRun?: boolean;
  wait?: "pending" | "confirmed" | "published";
  signal?: AbortSignal;
}

Every write resolves to a Write: state, receipt, records (the optimistic view), mutationId, onReceipt(fn), confirmed and published (promises). confirmed rejects with an MdbaseError if the write is rejected or its outcome is unknown. published settles when a file-backed replica has written the change to disk, which can be before confirmation.

Status and link

MemberNotes
getStatus(), onStatus(fn), statusSyncStatus: mode, confirmedThrough, headKnown, pending, holds, unresolved, connection, installing
summarizeStatus(status){ kind, text, pending, holds, conflicts, confirmedThrough }
link, onLink(fn)"open", "reconnecting" or "closed"
helloWhat the replica reported at connect, including the grant’s role and capabilities
close()Close the client and its subscriptions

Holds and conflicts

MemberNotes
listHolds(), onHolds(fn)Hold[]: id, path, reason, mine, theirs
resolveHold(id, how, use?)how: keep_mine, take_theirs, use, delete, keep_both
describeHold(hold, { collectionId }), holdNotice(holds)Plain-language text and the actions that apply
listConflicts(recordId?), onConflicts(fn)ConflictEntry[]
resolveConflict(entry, field, value), dismissConflict(entry)Choose a value, or keep what the record has

Files

Member of db.filesNotes
list({ folder, media }), listPage(…), get(ref)FileView: id, path, size, digest, media, state
upload(path, source, { onProgress, transferId, fileId, ifRevision, signal })source: Uint8Array, ArrayBuffer or Blob
download(ref), downloadStream(ref, { range })download is capped at 64 MiB
move(view, to), delete(ref)Both take ifRevision

createMdbase

createMdbase(declaration) is the entry point for web apps. Its snapshot has a phase that says what to show; when phase.kind is "ready", phase.connection is the open connection. Its actions include start, signIn, select, forget, signOut and close.

new MdbaseConnect(declaration) is the same entry under its previous name. Its application() returns an object with getSnapshot, subscribe, start, authorize, select, assess, configure, clearSelection, forget, setForeground and close. connection(collectionId) returns a connection whose records is an MdbaseClient. See Connect a browser app for its current status.

Other exports

  • toPlain, toValue, valueEquals, uuidv7: values and IDs.
  • loadOrCreateClientKey, indexedDbKeyStorage, memoryKeyStorage: your app’s session key.
  • isConfirmed(receipt): whether a receipt is confirmed.
  • TimersApi: see Notifications and timers.
  • @mdbase-dev/sdk/testing: MemoryReplica, createApplicationFixture.

Errors

Failures throw MdbaseError with code, recovery, and often reason, details, issues or retryAfterMs. Use isMdbaseError(e, code?). Branch on code and reason; message is for developers. Each code has one recovery.

CodeRecoveryWhen
invalid_requestfix_requestMalformed parameters, unsafe paths, an expired query cursor
invalid_recordfix_requestThe write fails validation; see issues
not_foundrefreshNo such record, file, hold or transfer
conflictresolve_conflictThe current state doesn’t allow this write: revision, path_taken, duplicate_value, …
unauthenticatedreauthorizeNo session, an expired one, or a revoked grant
forbiddenreauthorizeThe grant lacks the capability, or the role doesn’t allow it
collection_invalidrepair_collectionThe collection’s config or type files can’t be loaded
unavailableretryThe replica can’t be reached, for example no device online
rate_limitedretryToo many requests; see retryAfterMs
quota_exceededfree_spaceThe collection is over its storage quota
too_largefix_requestA request or file over its limit
upgrade_requiredupgradeThis SDK version is too old for the replica or collection
outcome_unknownresolve_outcomeA write’s outcome can’t be determined; read again and decide
cancellednoneYou cancelled the request
internalcontact_supportA bug; the request may be retried once