Datastore

The datastore is a lightweight data persistence interface. It is used by Eventicle to store state for various components. You can also use it in your Eventicle components to perform CRUD and simple queries.

If you need more advanced querying capabilities, you can use whichever data persistence technology is most appropriate in your component.

Datastore usage assumes that the underlying implementation can store and query schemaless document style data. For example, MongoDB or Postgres JSONB.

Create

Create a new data Record
import { dataStore } from '@eventicle/eventiclejs';
import { Record } from '@eventicle/eventiclejs/dist/datastore';

...

const record: Record = await dataStore().createEntity(
    "system",         (1)
    "my-data-type",   (2)
    {}                (3)
);
1 The tenancy key. If your system is single tenant, ignore this
2 The data type. eg saga-instance
3 The content of the record. Datastore accepts any JSON data type.

Save

Save an existing data Record
import { dataStore } from '@eventicle/eventiclejs';
import { Record } from '@eventicle/eventiclejs/dist/datastore';

...

const record: Record = ... // obtain an existing data record from the

record.content.myData = "hello"  (1)

await dataStore().saveEntity(
    "system",         (2)
    "my-data-type",   (3)
    record            (4)
);
1 Mutate the content as required. Will persist on calling saveEntity
2 The tenancy key. If your system is single tenant, ignore this
3 The data type. eg saga-instance
4 An existing Record to persist.

findEntity/ findEntityPaginated

Transactions

The transaction API on the Datastore ensures that any underlying ACID/ transactional commit system is used for datastore operations.

Transaction that successfully commits
const ret: Record = await dataStore().transaction(async () => {
    //.. do work within the transaction

    return datastore().createEntity(...)
})

console.log(ret.content)
Transaction that Rolls Back
const ret: Record = await dataStore().transaction(async () => {
    // .. do work within the transaction

})

console.log(ret.content)

TransactionData

TransactionOptions

TransactionListener

Components may need to be aware when transactions commit in order to perform work once the datastore is consistent.

Notably, eventClient implementations that are transaction aware register a TransactionListener to ensure that they can delay sending events until after the wrapping transaction is successfully committed to the datastore. This ensures that local data changes are fully consistent before events are sent out, preventing a race.

Data Types

The following data types are persisted using the datastore by Eventicle.

You should consider them reserved.

Data Type Datatore type Description

Aggregate Root State

aggregate-events-[type]

The raw state of the Aggregate Root, stored as the in order events that have been generated by it.

Saga State

saga-instance

The runtime state of a particular Saga instance (created during the startsOn for the Saga)

Saga notification listener

saga-notify-intent

A record that is used to match saga instances against an incoming event. Can match multiple saga instances for a single event