Options
All
  • Public
  • Public/Protected
  • All
Menu

es-objects

A collection of objects to help you build an event-sourced architecture.

What does it look like?

Here is an example in typescript:

// Create an event bus that will store the events before publishing them
const eventStorage = new InMemoryEventStorage();
const bus = new EventBus(eventStorage);
bus.onError((err) => { console.error(err); });

// Create an entity class, this is where the business logic goes.
class Cat extends Entity<boolean> {
  constructor(id, decisionSequence, publish) {
    super(id, decisionSequence, publish);
  }

  // Based on the current state of the entity (the decision projection) and the called methods and arguments
  // the business logic decides which events to publish
  public async feed() {
    if (this.getDecision()) {
      throw new Error("cat already fed!");
    }
    await this.publishAndApply({ type: "fed" });
  }

  // Those methods are needed by the Entity class
  protected getAggregate() { return "cat"; }
  protected getDecisionReducer() { return catFedReducer; }
}

// This is the reducer that creates a decision projection from a stream of events
// The decision projection should only carry the information we need to take decisions
function catFedReducer(state = false, event) {
  if (event.type === "fed") {
    return true;
  }
  return state;
}

// The store needs an object that provides the decision projection, this one builds it from the published events
const catDecisionProvider = new FromEventsDecisionProvider("cat", catFedReducer, eventStorage);

// The store is the object that will create the entities we need
const catStore = new Store<Cat, boolean>(
  (id, decisionProjection, publish) => new Cat(id, decisionProjection, publish),
  catDecisionProvider,
  (event) => bus.publish(event),
);

// Now everything is set up on the write side, lets add projections to query our events

// This global projection listen to all "cat" events and count the meals served
// It needs a reducer to transform the events into a state:
function nbMealsReducer(state = 0, event) {
  if (event.type === "fed") {
    return state + 1;
  }
  return state;
}
// It will be persisted in a storage
const nbMealsServedProjection = new PersistedReduceProjection<number>(
  nbMealsReducer,
  new InMemoryValueStorage(),
  (e) => e.aggregate === "cat",
);
// Every time an event is published, it will be passed to the projection
bus.onEvent((event) => nbMealsServedProjection.handleEvent(event));

// This entity projection gives a state for each Cat: is it fed?
// For the sake of concision I re-use our catFedReducer
const catFedProjection = new PersistedEntityReduceProjection<boolean>(
  catFedReducer,
  new InMemoryKeyValueStorage(),
  (e) => e.aggregate === "cat",
);
bus.onEvent((event) => catFedProjection.handleEvent(event));

// Let's get a Cat, it has no event yet
const felix = await catStore.get("felix");
// Calling this method will lead to publishing a "fed" event
await felix.feed();

// We can now query our read projections

const nbCatsFed = await nbMealsServedProjection.getState();
expect(nbCatsFed).toBe(1);

const felixFed = await catFedProjection.getState("felix");
expect(felixFed).toEqual(true);

Index

Type aliases

Reducer

Reducer: function

Type declaration

    • (state: T | undefined, event: Event): T
    • Parameters

      • state: T | undefined
      • event: Event

      Returns T

Functions

Const arrayToStream

  • arrayToStream(arr: any[]): Readable

Const consumeStream

  • consumeStream(readable: Readable, handler: function): Promise<void>
  • Parameters

    • readable: Readable
    • handler: function
        • (object: any): void | Promise<void>
        • Parameters

          • object: any

          Returns void | Promise<void>

    Returns Promise<void>

Const duplicate

getInitialState

  • getInitialState<T>(reducer: Reducer<T>): T

makeDecisionReducer

projectFromEvents

  • projectFromEvents<T>(reducer: Reducer<T>, events: Readable): Promise<T>
  • Read a stream of events, pass them to a reducer, returns the final value as the promise resolves.

    Type parameters

    • T

    Parameters

    • reducer: Reducer<T>

      a reducer

    • events: Readable

      a stream of events

    Returns Promise<T>

Object literals

Const INIT_EVENT

INIT_EVENT: object

aggregate

aggregate: string = "__init__"

id

id: string = "__init__"

sequence

sequence: number = -1

Legend

  • Module
  • Object literal
  • Variable
  • Function
  • Function with type parameter
  • Index signature
  • Type alias
  • Enumeration
  • Enumeration member
  • Property
  • Method
  • Interface
  • Interface with type parameter
  • Constructor
  • Property
  • Method
  • Index signature
  • Class
  • Class with type parameter
  • Constructor
  • Property
  • Method
  • Accessor
  • Index signature
  • Inherited constructor
  • Inherited property
  • Inherited method
  • Inherited accessor
  • Protected property
  • Protected method
  • Protected accessor
  • Private property
  • Private method
  • Private accessor
  • Static property
  • Static method

Generated using TypeDoc