← Về thư mục
📄 / / var / lib / containerd / io.containerd.snapshotter.v1.overlayfs / snapshots / 271 / fs / packages / @openmaic / storage / README.md

@openmaic/storage

The MAIC pluggable persistence layer: small, swappable-backend primitives for persisting app state, depending only on @openmaic/dsl.

The DSL owns what persists (document / runtime shape + validation + migration + the asset StorageProvider interface). This package owns where / how it persists — the primitives and their backends. The pluggable seam is the backend, not the database driver: browser backends (the zero-server clone-and-run default), HTTP clients plus a reference server, and PostgreSQL server backends.

Dependency arrow (acyclic)

@openmaic/storage -> @openmaic/dsl

No dependency on React, zustand, or any host app. Backends take their Storage / IDBFactory by injection, so the package is app-agnostic and testable without a browser.

What's in here

Export Role Browser backend
KVStore small device / account-scoped values not owned by the DSL BrowserKVStore over localStorage
StorageProvider (from @openmaic/dsl) the asset seam: put(blob) → ref, resolve(ref) → url, remove(ref) BrowserAssetStore over IndexedDB (assets registry + blobs) + object URLs
kvPersistStorage adapt a KVStore into a zustand persist storage
DocumentStore persist the DSL document aggregate (stage + scenes + embedded agents / quiz / actions + an outline snapshot) BrowserDocumentStore over IndexedDB (normalized stages / scenes / outlines)
RuntimeStore persist what a learner produces while taking a course — sessions + append-only records (chat, quiz attempts, playback facts) BrowserRuntimeStore over IndexedDB (sessions / records)

Upgrading from 0.1.x

Version 0.2.0 removes BrowserAssetProvider outright; it no longer ships. The asset API is now BrowserAssetStore, whose refs are allocated ids and whose data lives in the new maic-asset-pool database.

Reusing a custom dbName created by a 0.1.x provider raises an explicit legacy-schema error rather than corrupting data or operating only partially.

Backend equivalence

Each primitive has one implementation-agnostic contract suite (test/kv-contract.ts, test/asset-contract.ts, test/document-contract.ts, test/runtime-contract.ts). Every backend is proven by running the same suite against it, so browser, HTTP, and PostgreSQL implementations cannot silently diverge from a primitive's semantics. Assets use the single test/asset-contract.ts suite for the allocated-id store: identical bytes never share a caller-visible id. Asset backends must let the suite temporarily instrument the production allocation source while constructing the store through the same factory used by every other contract test. This proves that every successful put consumes exactly one allocator output, independent of whether the bytes already existed, without adding a caller-configurable allocation path.

Roadmap

License

MIT