Skip to main content

What stays on the device

Every stack writes documents that describe this device's copy of the database rather than its contents. Replicating them is never right: two devices each write their own, so they collide on identical ids with unrelated revisions. The sync layer filters them automatically. This page is the list.

Always local

KindMatchWhy
id~systemCarries this database's schemaVersion, dbInfo and startupTime, read on every mount. A peer's copy would claim patches this device has not applied.
id~crypto-engine-configPins a database to its encryption setting and holds the key canary. A peer's copy says nothing about this one.
idlastDocIdA local id counter, vestigial since ids became random.
prefix_local/PouchDB never replicates local documents. Listed so the predicate is usable outside a replication filter.
prefix_design/Mango indexes, built on demand per device.
prefix~lock-Guards an in-flight class-model propagation on this device.
prefix~log-This client's own diagnostic records.
class~lockThe propagation lock document.
class~JobRunRecords that this client ran a job. Both devices write their own.
classany class declared ephemeralDocuments describe one run of one client. Filled in from the stack's own class models.
shapeno ~class, no ~domain, and a log field with level and messageLog records written before they carried a prefix.

Seeded everywhere, so sent nowhere

Patches are applied by every client independently, so every document they seed already exists on every client: DocStack's own class models, Group-Admin, AuthMod-Classic, the bootstrap class and domain models, the system user. Sending them costs quota and invites conflicts, two devices writing the same id independently, for no information gained. Their ids are derived from the system patches at build time (SYSTEM_SEEDED_DOC_IDS) and kept local; the ids seeded by the application's own patches are added the same way when stack.sync() runs.

The distinction that matters is not "is this DocStack's own?" but "can the peer already reconstruct this?". A user created at runtime, a group an administrator added, an application-created document of any of DocStack's classes: those bind two instances together and always replicate. Access scope documents follow the same rule: shipped in a patch they are seeded everywhere and stay home, written at runtime they travel, and in either case they carry a sealed key and a public policy, nothing a remote can open.

Local by default, replicable on request

ClassOption to replicate it
~UserSessioninternalDocs: { replicateSessions: true }
patch (the ledger of applied patches)internalDocs: { replicatePatchLedger: true }
the seeded documents aboveinternalDocs: { replicateSystemDocuments: true }

Widening the list

stack.sync({
remote,
internalDocs: {
extraDocIds: ['Draft'], // keep a class model local too
extraIdPrefixes: ['~scratch-'], // anything with this id prefix
extraClasses: ['Scratch'], // anything with this ~class
},
});

extraDocIds, extraIdPrefixes and extraClasses add to the lists above. extraSeededDocIds marks ids the application's patches seed; stack.sync() fills it in from the configured patches, so it is rarely set by hand.

internalDocs: false replicates everything, ~system included. It exists for stack-to-stack mirroring of a whole database and is otherwise a bad idea.

The data model rides along

When classes.include narrows replication to an allow-list, the class models, domains, users, groups, auth modules and job definitions ride along automatically, so the remote stays a database the next device can open. includeDataModel: false turns that off. The full list is exported as DATA_MODEL_CLASSES. See Filter what replicates.

Exports

@docstack/client exports the constants and predicates so an application can apply the same judgement outside replication: INTERNAL_DOC_IDS, INTERNAL_DOC_ID_PREFIXES, INTERNAL_DOC_CLASSES, OPTIONAL_INTERNAL_DOC_CLASSES, SYSTEM_SEEDED_DOC_IDS, DATA_MODEL_CLASSES, isInternalDoc(doc, options?), resolveInternalClasses(options?), createReplicationFilter(options?).