@delta-base/server
TypeScript icon, indicating that this package has built-in type declarations

0.2.0 • Public • Published

DeltaBase Server SDK

A TypeScript SDK for interacting with the DeltaBase event sourcing platform.

Features

  • Complete TypeScript API client with full type safety
  • Supports all Delta-Base APIs:
    • Management API - Create and manage event stores
    • Event Store API - Append and read events from streams
    • Event Bus API - Create and manage subscriptions
    • WebSockets API - Real-time communication
  • Comprehensive error handling
  • Modular design for flexibility

Installation

npm install @delta-base/server

Quick Start

import { DeltaBase } from '@delta-base/server';

// Initialize the client
const client = new DeltaBase({
  apiKey: 'your-api-key',
  // baseUrl: 'https://your-custom-endpoint.com' // Optional
});

// Get an EventStore client for a specific event store
const eventStore = client.getEventStore('your-event-store-id');

// Append events to a stream
await eventStore.appendToStream('user-123', [
  {
    type: 'UserCreated',
    data: { userId: '123', name: 'John Doe', email: 'john@example.com' }
  }
]);

// Read events from a stream
const result = await eventStore.readStream('user-123');
console.log(`Stream exists: ${result.streamExists}`);
console.log(`Current version: ${result.currentStreamVersion}`);
console.log(`Events: ${result.events.length}`);

Event Store API

The SDK provides a powerful event store implementation that follows event sourcing principles.

Getting an EventStore Instance

Each EventStore instance is specific to a particular event store ID:

const eventStore = client.getEventStore('your-event-store-id');

Appending Events

// Simple append
await eventStore.appendToStream('stream-id', [
  { type: 'EventType', data: { /* event data */ } }
]);

// With expected version (optimistic concurrency)
await eventStore.appendToStream('stream-id', [
  { type: 'EventType', data: { /* event data */ } }
], {
  expectedStreamVersion: 5n // Expected version as BigInt
});

// Or with special version expectations
await eventStore.appendToStream('stream-id', events, {
  expectedStreamVersion: 'no_stream' // Only if stream doesn't exist
});

Reading Events

// Read all events
const allEvents = await eventStore.readStream('stream-id');

// Read from a specific position
const fromPosition = await eventStore.readStream('stream-id', {
  from: 5n // BigInt position
});

// Read up to a specific position
const toPosition = await eventStore.readStream('stream-id', {
  to: 10n // BigInt position
});

// Limit the number of events
const limitedEvents = await eventStore.readStream('stream-id', {
  from: 0n,
  maxCount: 50n
});

Aggregating Streams

The SDK provides a built-in way to aggregate events into a state:

// Define the shape of your state
interface UserState {
  id: string;
  name: string;
  email: string;
  isActive: boolean;
}

// Define your events
type UserEvent = 
  | { type: 'UserCreated', data: { id: string, name: string, email: string } }
  | { type: 'UserNameChanged', data: { name: string } }
  | { type: 'UserDeactivated', data: {} };

// Aggregate the stream
const result = await eventStore.aggregateStream<UserState, UserEvent>(
  'user-123',
  {
    // Initial state creator
    initialState: () => ({
      id: '',
      name: '',
      email: '',
      isActive: false
    }),
    
    // State evolution function
    evolve: (state, event) => {
      switch (event.type) {
        case 'UserCreated':
          return {
            ...state,
            id: event.data.id,
            name: event.data.name,
            email: event.data.email,
            isActive: true
          };
        case 'UserNameChanged':
          return {
            ...state,
            name: event.data.name
          };
        case 'UserDeactivated':
          return {
            ...state,
            isActive: false
          };
        default:
          return state;
      }
    },
    
    // Optional read options
    read: {
      from: 0n // Start from the beginning
    }
  }
);

console.log(result.state); // The final state
console.log(result.currentStreamVersion); // The stream version
console.log(result.streamExists); // Whether the stream exists

Managing Streams

// List all streams
const streams = await eventStore.listStreams();

// List streams with pattern matching
const filteredStreams = await eventStore.listStreams({
  pattern: 'user-*',
  limit: 20,
  offset: 0
});

// Delete a stream
await eventStore.deleteStream('stream-id');

Management API

The SDK provides management capabilities for creating and configuring event stores:

// Create a new event store
const eventStore = await client.management.createEventStore({
  name: 'my-event-store',
  description: 'My event store for user events'
});

// List all event stores
const eventStores = await client.management.listEventStores();

Event Bus API

The SDK provides capabilities for subscribing to events from an event store through various delivery mechanisms:

// Get an EventBus client for a specific event store
const eventBus = client.getEventBus('your-event-store-id');

// Subscribe with a webhook
const webhookSubscription = await eventBus.subscribe({
  eventFilter: 'user.*',  // Filter pattern for events
  subscriber: {
    type: 'webhook',
    config: {
      url: 'https://example.com/webhook',
      headers: {
        'X-API-Key': 'your-webhook-secret'
      },
      retryPolicy: {
        maxAttempts: 5,
        backoffMinutes: 10
      }
    }
  }
});

// Subscribe with a Durable Object
const doSubscription = await eventBus.subscribe({
  eventFilter: ['order.created', 'order.updated'],  // Multiple patterns
  subscriber: {
    type: 'durable_object',
    config: {
      namespace: 'ORDER_PROCESSOR',
      id: 'order-processor-instance-1'
    }
  }
});

// Subscribe with WebSockets for real-time updates
const wsSubscription = await eventBus.subscribe({
  eventFilter: 'notification.*',
  initialPosition: 'earliest',  // Start from the beginning of the stream
  subscriber: {
    type: 'websocket',
    config: {
      managerId: 'notifications-websocket-manager'
    }
  }
});

// Get details about a subscription
const subscription = await eventBus.getSubscription('sub_123456');
console.log(`Status: ${subscription.status}`);
console.log(`Events pattern: ${subscription.eventFilter}`);
console.log(`Last processed position: ${subscription.lastProcessedEventGlobalPosition}`);

// List all subscriptions
const { subscriptions, totalCount } = await eventBus.listSubscriptions();
console.log(`Total subscriptions: ${totalCount}`);

// List subscriptions with filtering
const filtered = await eventBus.listSubscriptions({
  subscriberType: 'webhook',
  eventFilter: 'user.*',
  limit: 20,
  offset: 0
});

// Unsubscribe when no longer needed
const result = await eventBus.unsubscribe('sub_123456');
console.log(result.message); // "Subscription successfully removed"

Advanced Usage

Type Safety

The SDK is fully typed for improved developer experience:

// Define your event types
type UserEvent = 
  | { type: 'UserCreated', data: { id: string, name: string } }
  | { type: 'UserUpdated', data: { name?: string, email?: string } };

// Use with type safety
await eventStore.appendToStream<UserEvent>('user-123', [
  { 
    type: 'UserCreated', 
    data: { id: '123', name: 'John' } 
  }
]);

// Type-safe reading
const result = await eventStore.readStream<UserEvent>('user-123');
// result.events will be typed as UserEvent[]

License

2025 DeltaBase. All rights reserved.

Package Sidebar

Install

npm i @delta-base/server

Weekly Downloads

10

Version

0.2.0

License

LicenseRef-LICENSE

Unpacked Size

115 kB

Total Files

9

Last publish

Collaborators

  • enrique.ruvalcaba-nibbio
  • robinsantiago
  • fernando-barroso