Strategies
The kernel session documented on the Noydb reference works with zero add-ons. Every capability beyond it — history, sync, transactions, multi-user access, aggregation, and the rest — is an opt-in strategy you pass to createNoydb() through a with*() factory, and that tree-shakes out of your bundle when unused. Each strategy unlocks a set of methods; a method that needs a strategy throws a *NotEnabledError (or a documented equivalent) until you configure it. The plain-option keys you pass alongside these are on Configuration.
This directory is the full map, grouped by where the methods each slot unlocks appear — on the db session (client-level), on a vault, or on a collection. The full set is thirty-two slots: twenty-seven single-value strategies and five array-valued ones (guards, deferred numbering, derivations, materialized views, overlays — each takes a list of handles, marked (array) below).
Client-level
Strategies whose methods land on the db session itself.
| Strategy slot | with*() factory | What it unlocks | Service |
|---|---|---|---|
| Multi-user access | withTeam() | db.grant() / db.revoke() / db.rotate() — grant or revoke a keyring, rotate a vault's collection DEKs in place | team |
| Sovereign custody | withCustody() | owner-only db.grantCustodian() / db.revokeCustodian() plus the vault.custody.* facade (incl. liberate()) | custody |
| Multi-record atomic writes | withTransactions() | db.transaction(fn) — all-or-nothing writes across vaults and collections (dry-run + amendment overloads) | transactions |
| Snapshot lifecycle | withSnapshots({ store }) | db.snapshot() / db.listSnapshots() / db.restoreSnapshot() into a snapshot store (integrity-verified on restore) | snapshots |
| Replication + presence | withSync() | db.push() / db.pull() / db.sync() / db.syncStatus(), the sync-transaction overload, and collection.presence() | sync |
| Session policy | withSession() | enforces the configured sessionPolicy — idle / absolute timeouts, lock-on-background, global token revocation | session |
Notes. Without withTeam() the floor is single-user and all three methods throw TeamNotEnabledError; custody methods throw CustodyNotEnabledError; setting sessionPolicy without withSession() throws at createNoydb(). See also session-tiers and Permissions & keyring.
Vault-level
Strategies whose methods land on a vault handle.
| Strategy slot | with*() factory | What it unlocks | Service |
|---|---|---|---|
| Cold storage | withArchive({ store }) | vault.archive() / vault.restore() / vault.listArchived() against a second store | archive |
| GDPR erasure | withForget({ subjects }) | vault.forget(subjectId) crypto-shred + vault.rebuildSubjectIndex() (forces perRecordKeys, needs the history ledger) | forget |
| Localization | withI18n() | i18nText / dictKey field resolution and validation, plus vault.dictionary(name) | i18n |
| Accounting periods | withPeriods() | vault.openPeriod() / vault.closePeriod() / vault.listPeriods() and the closed-period write guard | periods |
| Vault frames | withShadow() | vault.frame() | shadow |
| Consent audit | withConsent() | a per-operation audit trail into _consent_audit, read via vault.consentAudit() | consent |
| Document attestation | withAttestation() | vault.issueAttestation() / getDocumentSigningPublicKey() / revokeAttestation() / unrevokeAttestation() / getRevokedDocIds() / publishRevocationList() | attestation |
| Record-scoped sealing | withSealedRecord() | grantor-side vault.sealRecordToHost() / revokeSealedRecord() / rotateRecordCek() (host-side opener stays ungated) | sealed-record |
| Data sovereignty | withPortability() | the vault.user.* export / withdrawal surface: exportMyAccessibleData(), unilateralWithdrawal(), requestWithdrawal(), listWithdrawalRequests(), approveWithdrawal(), rejectWithdrawal() | portability |
| Credential broker | withBroker(config) | vault.broker() — .enroll() / .rotate() / .credentialSource() | broker |
| Atomic sequences | withSequence() | vault.sequence(name) — .next() / .peek() / .seedTo(), a CAS-backed monotonic counter | sequence |
| Partition extraction | withCargo() | source-side extractPartition(vault, …) that lifts a re-keyed slice out as a portable partition | transferable partitions |
| Materialized views (array) | withMaterializedView(...) | each handle registers a persisted, incrementally-maintained view; refresh with vault.refreshView(), read via vault.collection() | materialized-views |
| Gap-free serials (array) | withDeferredNumbering(...) | each declares a numbering series; vault.sequence(series).next({ for }) reserves a slot, vault.runNumberingPass(series) assigns gap-free serials | numbering |
Notes. Missing-strategy throws: vault.forget() → ForgetStrategyNotConfiguredError; vault.broker() → BrokerNotEnabledError; sealed-record → SealedRecordNotEnabledError; portability → PortabilityNotEnabledError; sequence → SequenceNotEnabledError; cargo → CargoNotEnabledError; attestation → AttestationNotEnabledError. The recipient-side partition adopt / decrypt functions stay ungated.
Collection-level
Strategies whose methods land on a collection (or its query builder).
| Strategy slot | with*() factory | What it unlocks | Service |
|---|---|---|---|
| Versioning + audit ledger | withHistory() | collection.history() / getVersion() / revert() / diff() / clearHistory() / pruneRecordHistory(), per-record snapshots, and the hash-chained ledger (vault.ledger(), vault.at()) | history |
| Binary attachments | withBlobs() | collection.blob(id) storage for large binary fields | blobs |
| Secondary indexes | withIndexing() | eager == / in fast-paths on declared indexes, .lazyQuery(), and index rebuild / reconcile | indexing |
| Grouping + rollups | withReduce() | .aggregate() and .groupBy() on a query | aggregate |
| Conflict-free merges | withCrdt() | the merge engine for CRDT collections (lww-map / rga / yjs) | crdt |
| Hierarchical access tiers | withTiers() | collection.putAtTier() / getAtTier() / listAtTier() / elevate() / demote() | tiers |
| Classified fields | withClassified() | collection.reveal() for digest-only classified fields | classified |
| Search + retrieval | withSearch() | collection.search() / retrieve() / similarTo() / warmIndex() / flushIndex() and put-time embedding-vector compute | search |
| Bounded working set | withLazy() | lazy mode's bounded-LRU working set for prefetch: false collections | lazy |
| Write guards (array) | withGuard(...) | each handle registers a collection.put() invariant, dispatched in registration order | guards |
| Projections (array) | withDerivation(...) | each projects a source collection's writes into an output on put(); backfill with vault.deriveAll() | derivations |
| Overlays (array) | withOverlayedView(...) | each layers a computed overlay onto a base collection's reads (read through vault.collection()) | overlay-views |
Notes. Without their strategy: CRDT collections throw on the first put / sync-merge; reveal() → ClassifiedNotEnabledError; tier methods → TiersNotEnabledError; search methods → SearchNotEnabledError; history snapshots and prune / clear become silent no-ops while the read APIs throw; queries fall back to linear scans and .lazyQuery() throws.
See also
- Configuration — every non-strategy option key you pass to
createNoydb(). - Noydb — the strategy-free kernel surface these slots build on.