atomservices
v0.15.4
Published
A lightweight, strictly-typed Event Sourcing toolkit for Node.js and TypeScript. Designed for high-performance aggregate rehydration and flexible consistency models.
Readme
atomservices
A lightweight, strictly-typed Event Sourcing toolkit for Node.js and TypeScript. Designed for high-performance aggregate rehydration and flexible consistency models.
Core Architecture
atomservices manages the lifecycle of a domain event through a structured pipeline that ensures data integrity and consistency.
- Event Definition: Define strictly typed schemas for payloads and metadata using
IEvent. - Persistence: Events are first appended to the Event Store (The Source of Truth).
- Notification: Once stored, events are distributed via the Event Bus to registered Handlers for side effects.
Consistency Models
The library's dispatch method is designed to support both Eventual and Strong consistency models depending on your business requirements.
1. Strong Consistency
If you need to ensure that all side effects (handlers) have completed successfully before proceeding, use the notified callback. This "upgrades" the asynchronous bus into a strongly consistent flow.
// Achieving Strong Consistency
await new Promise<void>((resolve, reject) => {
service.dispatch(myEvent, (err) => {
if (err) reject(err); // Fails if Store OR Handlers fail
else resolve(); // Success: Stored AND Handled
});
});
2. Eventual Consistency
If you only care that the event is safely persisted and want handlers to run in the background, simply await the dispatch without a callback.
// Achieving Eventual Consistency
await service.dispatch(myEvent);
// Resolves as soon as the Store appends the event.
Quick Start
1. Define an Event
Use EventBuilder to create a type-safe factory. It handles _id and _createdAt generation automatically.
import { IEvent, EventBuilder } from 'atomservices';
interface UserCreated extends IEvent<{ email: string }> {}
const buildUserCreated = EventBuilder<UserCreated>({
EventName: "UserCreated",
AggregateType: "User"
});
2. Initialize the Service
The createService function initializes your infrastructure lazily and wires up handlers to the bus.
import { createService, InstantEventBus } from 'atomservices';
const service = createService({
EventStore: myEventStore, // Implements IEventStore
EventBus: new InstantEventBus(), // Local memory implementation
EventHandlers: [myHandler] // List of IEventHandler
});
3. Dispatch an Event
await service.dispatch(buildUserCreated({
_version: 1,
_createdBy: "admin-uuid",
payloads: { email: "[email protected]" }
}));
API Reference
IEvent: The core data contract.EventBuilder: Factory pattern with automatic UUID and timestamp generation.createService: Orchestrates the persistence and publication flow.InstantEventBus: High-performance local memory event bus usingPromise.allfor handler execution.IReducer: Pure function type for aggregate state rehydration.
License
ISC
