Current storage APIs

Source review: 5 October 2026, including local changes awaiting qualification. The implementation scope is code present in the repositories. It does not establish that each target has been released or passed the same persistence tests. Tidemark owns the target architecture; implementation gates define what would qualify it.

Local object storage

reaktor-db provides ObjectDatabase, namespaced ObjectStore, observable ObjectState<T>, StoredObject<T> and encoded RawObject. The SQLDelight implementation stores JSON payloads under (store_name, key). Raw export/import can preserve an object without loading its application type. These APIs are an existing persistence substrate; they do not implement the proposed cross-store DataDescriptor planner.

An ObjectStore owns typed reads, writes, updates, deletes and singleton state handles. It rejects incompatible state types for the same key. Its memory cache and persisted retention policy have different effects: LRU eviction removes a memory entry; expiration can delete persisted data. Choose retention deliberately for user records and pending commands.

The keyed update gate serializes access within that store instance. It is not distributed compare-and-swap, a cross-process lock or an atomic read-modify-write protocol across devices. Concurrent authorities need a provider transaction/version check or an explicit ownership protocol. Database events identify local, external, sync and migration origins, but emitting an event does not constitute durable cross-device delivery.

Unreadable encoded data must remain distinguishable from a missing object. UnreadableObjectException preserves that distinction so a decoder failure cannot silently turn into a default value and overwrite recoverable bytes. Account switching, retention, reset, migration and backups must preserve this rule.

Target inventory

TargetPresent sourceQualification boundary
JVMSQLDelight/JDBC SQLite object database factory and shared JSON implementationFile/process ownership, cancellation, transaction behavior and recovery require tests for the selected deployment
AndroidAndroid SQL adapter and platform driver dependenciesDevice lifecycle, migration, process death and account isolation need device evidence
iOSDarwin SQL adapter and native driver dependenciesNative lifecycle, migration, protected storage and interruption need device evidence
BrowserSQLite/Wasm worker, OPFS storage and openWebSqliteObjectDatabase in the current working treePublish the worker/Wasm assets and qualify supported browsers, reload, tab concurrency, quota/eviction and upgrades before claiming parity
Cloudflare/server storesProvider bindings and adapters in reaktor-cloudflare, plus JVM Postgres/Bolt accessThese are separate bindings; importing reaktor-db does not provide one universal transaction or sync engine

The Android/Darwin adapter APIs and the newer object-database factory are different surfaces. A driver dependency or platform source set alone is insufficient evidence that a product has integrated the complete object-store path.

Browser persistence and legacy migration

The current browser implementation replaces the earlier IndexedDB object backend with SQLite through a dedicated module Worker. The worker uses SQLite's OPFS synchronous-access-handle pool and Web Locks to coordinate access to a database name. It rejects unsupported storage/lock APIs; it does not silently substitute an ephemeral store. Serve the worker and SQLite assets at the URLs used by the factory, and verify that the deployed origin and browser allow these APIs.

The migration imports encoded records from reaktor-objects-<name>, keeps existing SQLite records when keys collide, verifies copied values and records completion in reaktor_web_migrations. That marker is outside the object tables cleared by clearAll, preventing a later reset from importing the old database again. Legacy IndexedDB bytes remain for recovery. Plan their eventual removal separately, after verifying the upgrade; leaving them indefinitely also has privacy and retention consequences.

OPFS is origin-local browser storage. A successful transaction is not a guarantee against browser eviction or user deletion, and local persistence is not remote backup. Request persistent storage where available, report quota failures, retain acknowledged server versions, and qualify private mode and offline/reconnect behavior. See the sync contract for the proposed authority and convergence requirements.

Graph access and tenancy

GraphDb.tenant(...) supplies a tenant-bound graph surface. MandatoryTenantParameterization validates supported query shapes and binds the tenant parameter. Read/write policy helpers reject additional unsafe shapes; registered MemgraphInspection recipes supply bounded operator reads through a separate authorized inspector path.

These checks are guardrails over the admitted query vocabulary, not a proof of isolation for arbitrary Cypher, procedures or direct driver access. Keep the raw driver out of untrusted handlers, enforce authority at the executor, and test adversarial read and write shapes. A product may make Memgraph its record authority, as Manna does; graph storage is not universally a derived cache. Multitenancy describes current auth propagation and the remaining binding work.

Snapshot transfer is not synchronization

The existing SyncAdapter backs up a SQL database, uploads snapshot bytes over HTTP, downloads bytes and restores a database. It has no general operation journal, conflict resolver, resumable incremental replication, projection watermark or multi-device convergence protocol. Treat it as snapshot transfer and qualify each adapter's backup/restore behavior. Do not advertise it as Tidemark's offline sync engine.

Product sync implementations can be stronger without establishing a framework-wide guarantee. Manna's record stream and workspace command handling belong to its own authority/revision protocol until extracted and qualified as reusable bindings.

Source map

Repository areaOwns
reaktor-db/.../core/ObjectDatabase.kt, ObjectStore.kt, ObjectState.ktObject operations, events, cache/state coordination and decoding behavior
reaktor-db/.../core/JsonSqliteObjectDatabase.kt and SQLDelight schemaEncoded object persistence
reaktor-db/src/jsMain/.../WebSqliteObjectDatabase.kt, src/jsMain/resources/reaktor-sqlite-worker.mjsBrowser SQLite opening, OPFS coordination and legacy import
reaktor-db/.../graph/GraphDbPolicy.kt, JVM GraphDb.ktTenant query policies and Bolt access
reaktor-db/.../adapters/SyncAdapter.ktWhole-database snapshot transfer
reaktor-cloudflareCloudflare bindings and provider APIs

Use Data inspection for operator tools, and durable jobs for work that must survive an isolate or process exit.