@orbitalfoundation/store
v0.1.0
Published
The toolbox: durable-store implementations of contracts declared by orbital concept packages (filespace nodes, streams messages). Tools, not concepts — never on the bus, no vocabulary; composition roots choose and inject.
Maintainers
Readme
@orbitalfoundation/store
The toolbox: durable-store implementations of the small contracts declared by orbital's concept packages. Currently: MongoDB adapters for the filespace node-store contract and the streams message-log contract, sharing one client.
Tools, not concepts
The rule this package exists to embody:
Concepts own contracts and vocabulary; tools implement contracts; composition roots choose tools.
Concepts are bus citizens — filespace, streams, spatial, agents — and each declares the store contract it needs, because the contract is part of the concept's meaning. Tools (mongo today; sqlite, search or vector indexes tomorrow) merely implement those contracts. This package is never on the bus, reserves no vocabulary, and nothing depends on its existence — only on the contracts. A first-class citizen in orbital is something with bus citizenship, not something with a package.json; this is a shipping crate, not a room in the house.
Package boundaries inside tool-land follow dependency weight, not rank: if a future adapter drags heavy native deps, it gets its own package so this one stays light.
Use
import { makeMongoStores } from '@orbitalfoundation/store';
import { attach as filespace } from '@orbitalfoundation/filespace';
import { attach as streams } from '@orbitalfoundation/streams';
const mongo = await makeMongoStores({ url: 'mongodb://127.0.0.1:27017', dbName: 'orbital' });
filespace(bus, { store: mongo.nodes, ... });
streams(bus, { messages: mongo.messages, ... });
// mongo.close() on shutdownNo server required — the CLI, a headless sim, or a test composes the same way. orbital-server does exactly this when orbital.config.json says "store": { "kind": "mongo", ... }.
Implementation notes: _id is the slug, so first-come claimRoot atomicity rides the primary key; message seq is an atomic per-room counter; the memory stores' mongo-ish selector dialect makes query() a pass-through; internal fields (_id, _parent) never leak out of the adapter.
Test
npm test # contract tests against a real mongod; skips cleanly when none is reachable