@vinumcms/adapters
v0.20.0
Published
Store, MediaStore and Mailer implementations. One file per adapter.
Readme
@vinumcms/adapters
One file per adapter, each implementing one interface.
import { denoKvStore } from "@vinumcms/adapters/deno-kv"; // production Store, Deno
import { fsStore } from "@vinumcms/adapters/fs"; // a JSON file, any runtime
import { memoryStore } from "@vinumcms/adapters/memory"; // tests
import { fsMedia } from "@vinumcms/adapters/fs-media"; // MediaStore on disk
import { resendMailer, noopMailer } from "@vinumcms/adapters/resend";fsStore is the one to reach for on Node. denoKvStore needs Deno and
memoryStore forgets everything on restart, which left nothing that survived
react-router dev. One JSON file, atomic rename, and a lock file so two
processes — a dev server and vinumcms mcp, say — can write it without losing
each other's edits. O(n) per write: right for hundreds of pages, wrong for tens
of thousands.
memoryStore is the reference implementation of Store and the conformance
suite lives with it — including the case that matters most, two concurrent
read-modify-writes where exactly one commits.
Testing your own. The contract ships as runnable cases with no test-framework dependency, so point them at your adapter under whatever runner you use:
import { storeConformance } from "@vinumcms/adapters/conformance";
for (const c of storeConformance()) {
it(`${c.group} — ${c.name}`, () => c.run(() => myStore()));
}The last case is the one that matters: two concurrent read-modify-writes where exactly one commits. An adapter can pass everything else and fail that one.
Your runner must understand TypeScript — vitest and deno test do; bare
node --test does not, because Node will not strip types under node_modules.
Writing your own. Store is five methods — get, list, set, delete
and an optimistic atomic — over a Deno-KV-shaped key/value API. MediaStore
is put/get/delete over bytes. Mailer is anything with a send. The
types are exported from @vinumcms/core
and memoryStore is the reference implementation to read.
Setup and theming live in @vinumcms/admin.
