Skip to content

Storage

pawaca edited this page Aug 30, 2026 · 1 revision

Storage

Edge replaces the upstream file-based storage backend with Durable Object KV.

Upstream reference: Storage

What Upstream Provides

The storage subsystem persists all data outside session event logs through a capability seam with three layers:

  • Storage Hub (ctx.storage) — coordinates backends and data forms. Performs no I/O itself.
  • Storage Backend — provider implementations (JSON files, SQLite) exposing a kv facet for key-value operations. Each backend owns one medium.
  • Storage Domain (ctx.storageDomain) — typed, schema-validated consumer layer with atomic read-modify-write, versioned units, and domain/changed events after durable confirmation.

Reads are synchronous from memory. Writes queue per domain, persist first, update memory, then emit change events. The kv facet supports units with format version, table declarations, and global singleton slots.

What Edge Changed

Direct Reuse Hub and Domain

Storage (hub) and StorageDomain are installed as-is. Domain declaration, schema validation, atomic writes, change events, and lifecycle management are entirely upstream code.

Replacement Backend → DO KV

DurableObjectStorageBackend implements the upstream StorageBackend interface using Durable Object's storage.get() / storage.put() / storage.list(). All keys are prefixed with dsh-kv: to coexist with other DO storage uses (session SQL tables, credentials, settings).

The backend is registered via ctx.storage.backend.register('durable-object', backend) with a corresponding ctx.provide('storage.backend.durable-object', true) to satisfy inject resolution for downstream plugins.

What Edge Did NOT Change

  • Storage Hub and Domain plugins
  • Domain declaration, schema validation, versioned units
  • Atomic write semantics and change event ordering
  • Consumer API (storageDomain.open() / .get() / .update())

Performance Characteristics

Read path

Reads are synchronous from the in-memory domain state — zero I/O. The backend's loadUnit() populates memory once at open time via storage.list({ prefix }), then all subsequent reads hit the cached Map.

Write path

Writes go through storage.put(key, value) which is a single DO storage operation. DO storage guarantees atomicity per request. Write-then-read consistency is immediate since the memory state updates after the put resolves.

Key space

All domain data shares the dsh-kv: prefix namespace. Current consumers: WorkspaceRegistry (workspace list and ordering), SessionProjectionCache (projection snapshots), and any upstream domain plugin. Key collision is prevented by the unit name in the key path: dsh-kv:{unit}:{table}:{key}.

DO KV Key Map

dsh-kv:{unit}:__version__              → schema version
dsh-kv:{unit}:__global__               → global domain state
dsh-kv:{unit}:{table}:{key}            → domain record

Other DO KV keys outside the storage domain (credentials, settings, model selection) use the dsh-edge: prefix — see the session persistence documentation for the full key map.

Architecture Summary

Component Category Upstream Equivalent
Storage Hub Reuse
Storage Domain Reuse
DurableObjectStorageBackend Replace JSON / SQLite file backend

Key observation: The storage subsystem is a clean capability seam replacement. Edge swaps one backend implementation while the entire Hub + Domain layer runs upstream code unmodified. Business logic never touches DO storage directly — it goes through the upstream domain API.

English

中文

Clone this wiki locally