Skip to content

SurrealDB Driver

The SurrealDB driver persists events to a SurrealDB database using the official surrealdb JavaScript SDK (v2). It supports SurrealDB server 3.x.

import { createEventStore, createAggregateRoot } from '@requence/event-sourcing/surreal'
import { Surreal } from 'surrealdb'
const db = new Surreal()
await db.connect(process.env.SURREALDB_URL!)
await db.use({ namespace: 'app', database: 'app' })
const eventStore = createEventStore({
database: db,
aggregateRoots: [userAggregateRoot],
})

The driver uses SCHEMAFULL tables mirroring the PostgreSQL layout:

TablePurpose
eventsAppend-only event log with position, stream, and metadata
event_sourcing_countersCounter record providing the gapless global event position
checkpointsLast-processed position (and optimistic-concurrency version) per projection/process manager
aggregate_root_snapshotsCached aggregate state for fast rehydration
projection_snapshotsCached projection state for snapshot-based projections
projection_applied_eventsCounter for snapshot frequency tracking

By default the driver creates the schema itself: idempotent DEFINE ... IF NOT EXISTS statements run lazily before the first operation. Pass initSchema: false to opt out and manage the schema yourself — the DDL is exported for that purpose:

import { initSchema, SCHEMA_STATEMENTS } from '@requence/event-sourcing/surreal'
await initSchema(db) // or run SCHEMA_STATEMENTS through your own tooling
const eventStore = createEventStore({
// Required — connected Surreal instance (namespace/database selected) or factory
database: db,
// Required — one or more aggregate roots
aggregateRoots: [user, project],
// Optional — disable automatic schema creation (default: true)
initSchema: false,
// Optional — distributed lock for multi-instance deployments
lock: redisLock(redis),
// Optional — disable automatic initialization
autoInit: false,
// Optional — callback invoked after events are appended
onEventsAppended(events) {
// e.g. broadcast via WebSocket
},
// Optional — replay and refresh progress callbacks
onProjectionReplay: { /* ... */ },
onProcessManagerRefresh: { /* ... */ },
// Optional — post-process events before persistence
postProcessEvent(event, aggregateRoot) {
return event
},
})