@playstack/event-store
Castore-based event sourcing with injected time, upcasting, concurrency, projections, and checkpoints.
Pro. Covered by the Playstack Pro License. Registry access is required; check preview availability before installing. See package access.
@playstack/event-store configures native Castore event stores with injected time, read-time upcasting, optimistic concurrency, projections, checkpoints, and Playstack testing conventions.
Install
After confirming preview access, install the package at your application's shared Playstack version:
npm install --save-exact @playstack/event-store@0.1.0-beta.1Check the peer requirements below before choosing a runtime or provider.
Install and create a store
import { createEventStore } from '@playstack/event-store'
export const orders = createEventStore({
eventStoreId: 'orders',
eventTypes: [orderCreated, itemAdded, orderSubmitted],
reducer: orderReducer,
eventStorageAdapter: storage,
clock,
upcast: orderUpcaster,
onEventPushed: publishOrderBridgeEvent,
})The returned value is Castore’s native EventStore; aggregate APIs, commands, event types, query options, and escape hatches remain available directly.
Store configuration
PlaystackEventStoreOptions property | Required | Purpose |
|---|---|---|
eventStoreId | Yes | Stable Castore store identifier. |
eventTypes | Yes | Aggregate event type definitions. |
reducer | Yes | Rebuilds aggregate state from events. |
eventStorageAdapter | For persistence | Castore-compatible storage bridge. |
clock | No | Supplies missing event timestamps; defaults to system time. |
upcast | No | Transforms historical events on read; identity by default. |
simulateSideEffect | No | Native Castore command simulation hook. |
onEventPushed | No | Native Castore append observer; bridge only intentionally selected events. |
createUpcaster composes explicit version steps while preserving event metadata. Appends retain Castore’s optimistic concurrency behavior and expose ConcurrencyError helpers.
Projection bridges
| Contract | Members |
|---|---|
ProjectionEventSource | read({ after, limit, eventStoreId? }). |
ProjectionAdapter | Stable id and idempotent apply(event). |
ProjectionCheckpointStore | read, advance, and reset by projection ID. |
SnapshotStore | read, write, and delete by aggregate ID. |
Projection delivery is at-least-once. ProjectionRunner skips positions at or behind its checkpoint but checkpoint advancement is intentionally not transactionally coupled to the destination write, so every adapter must apply an event idempotently.
Snapshot policy is explicit: never by default or { kind: 'every', events }. Snapshots optimize loading; the persisted event stream remains authoritative.
Persistence and testing
@playstack/event-store/prisma provides structural Postgres event storage and checkpoint adapters. The application owns its generated client, connection lifecycle, schema composition, and migrations. @playstack/event-store/testing provides a clocked in-memory adapter.
Boundary
Choose event sourcing per aggregate. This package does not make every Playstack domain event event-sourced; regular @playstack/events integration envelopes remain the default cross-package seam.
API entry points and requirements
Reference snapshot: @playstack/event-store@0.1.0-beta.1. Import only the entry point your runtime needs. Paths below are relative to the installed package; use Go to Definition in your editor to inspect exact parameters, return types and overloads. Do not import the declaration-file paths directly.
| Public entry point | Declaration file |
|---|---|
@playstack/event-store | ./dist/index.d.ts |
@playstack/event-store/prisma | ./dist/prisma.d.ts |
@playstack/event-store/testing | ./dist/testing.d.ts |
@playstack/event-store/playstack.artifacts.json | No TypeScript declaration (asset or metadata export). |
@playstack/event-store/package.json | No TypeScript declaration (asset or metadata export). |
Node.js engine requirement: >=20. This is not a claim that every entry point works in browsers or Workers.
Peer dependencies
This package declares no peer dependencies. Its ordinary dependencies are resolved by the package manager.
For a complete first program, start with Getting started. For API lookup and partial-example conventions, see Reading the reference. Provider failures, lifecycle requirements and application responsibilities remain described in the guide above; types alone do not establish production safety.