eventstore

A simple filebased eventsourced store

< Back to frontpage

defineStore

defineStore(folder: string, options: object) : store


defineStore(folder, options)

When using defineStore with node.js, the file system is used as the persistence by default.

const {defineStore} = require("@scriptabuild/eventstore");

let store = defineStore("/foldername");

You can supply a options object, to override the following settings:

const {defineStore} = require("@scriptabuild/eventstore");

let options = {
	createHeaders: (() => { /* custom implementation */ }),
	fs: {
		async mkdir(path, mode = 0o777){ /* custom implementation */ },
		async readdir(path, options){ /* custom implementation */ },
		async readFile(file, options){ /* custom implementation */ },
		async appendFile(file, data, options){ /* custom implementation */ }
	},
	console: {
		info(){ /* custom implementation */ },
		log(){ /* custom implementation */ },
		warn(){ /* custom implementation */ },
		error(){ /* custom implementation */ }
};

let store = defineStore("/foldername", options);

async store.ensureFolder()

Ensures that the log folder exists, and creates it if it doesn’t.

const {defineStore} = require("@scriptabuild/eventstore");
let store = defineStore("/foldername");

store.ensureFolder();

NOTE: This function works recursivly, so it will create all missing folders from the root folder an up the folder for the store.

NOTE: This function is not yet completely implemented for Windows, and will throw an exception if it needs to create recursive folders.


async store.log(eventObj)

Writes an event to the eventlog without defining a model. This is for all practical purposes the write-only mode.

const {defineStore} = require("@scriptabuild/eventstore");
let store = defineStore("/foldername");

store.log({name: "some-event-name", data: { /* custom object */ }})

async store.logBlock(action)

Writes an block of events to the eventlog without defining a model. This is for all practical purposes the write-only mode.

With logblock, the events are only written to the log when the block is marked as completed, by calling the markAsComplete() method. When this method is not called, the events are not persisted. This allows for all-or-nothing transactions.

const {defineStore} = require("@scriptabuild/eventstore");
let store = defineStore("/foldername");

store.logBlock((log, markAsComplete) => {
	store.log({name: "some-event-name", data: { /* custom object */ }})
	store.log({name: "some-other-name", data: { /* custom object */ }})
	store.log({name: "some-event-name", data: { /* custom object */ }})
	markAsComplete();
});

async store.replayEventStream(handleEvents)

Allows streaming (and reading) all event in the eventlog without defining a model.

const {defineStore} = require("@scriptabuild/eventstore");
let store = defineStore("/foldername");

store.replayEventStream((event, headers) => {
	console.log(`event: ${event}, headers: ${headers}`);
});

store.defineModel(modelDefinition)

Returns an object used to access the domain model.

This object exposes the following methods:

These methods are described further below in the documentation.

const {defineStore} = require("@scriptabuild/eventstore");
let store = defineStore("/foldername");

let model = store.defineModel(modelDefinition);

modelDefinition is an object with the following properties and functions:

const {defineStore} = require("@scriptabuild/eventstore");
let store = defineStore("/foldername");

let modelDefinition = {
	snapshotName: "some-model-name",
	initializeLogAggregatorData: () => ({});
	createLogAggregator: logAggregatorData => new MyCustomLogAggregator(logAggregatorData),
	createDomainModel: (dispatch, logAggregatorData) => new MyCustomDomainModel(dispatch, logAggregatorData)
}

let model = store.defineModel(modelDefinition);

async model.snapshot()

Saves a snapshot of the current state

//TODO:

async model.getAggregatorData()

Returns a readonly instance of the data in the aggregator. Atempts to change the model inside here will not store the events back to the aggregator nor eventstore.

A domain model is not needed for this.

//TODO:

async model.withReadInstance(action)

Creates a readonly instance of the model. Atempts to change the model inside here will not change the model nor store the events back to the eventstore.

//TODO:

async model.withReadWriteInstance(action, maxRetries)

Creates a read/write instance of the model. Any events fired on the model inside here will be stored to the eventstore.

//TODO: