1Getting started
1.1Choosing the database
XJog ships with two persistence adapters, and an additional mock adapter for testing purposes. Writing new persistence adapters is not difficult either, should it be necessary. You will find a comparison of the adapters in table 1. PostgreSQL is recommended for production use.
Note that in addition to the regular persistence adapters, there are delta persistence adapters. Recording deltas is optional, and a separate adapter makes it possible to store delta data separately.
Adapter | Connection pooling | Notifications | Use cases |
---|---|---|---|
PostgreSQL | Yes | Listeners | Server-side, production |
SQLite | Yes | Polling | Local applications, experimenting |
Mock | No | Callbacks | Unit testing, development |
1.2Installing
XJog is available as an npm package xjog
at the npm registry. In addition to the XJog
itself, you will need to install some additional packages depending on which database you are planning to
use.
Database | Required packages | Required for deltas |
---|---|---|
PostgreSQL |
|
|
SQLite |
|
|
Mock | (None) |
|
Listing 1 shows how to install XJog to your Node project translated to shell commands.
# PostgreSQL
yarn add xjog \
pg@^8.7.3 node-pg-migrate@^6.2.1 \
pg-listen@^1.7.0 rfc6902@5.0.1
npm install yarn add xjog \
pg@^8.7.3 node-pg-migrate@^6.2.1 \
pg-listen@^1.7.0 rfc6902@5.0.1
# SQLite
yarn add xjog \
sqlite@^4.0.23 sqlite3@^5.0.3 \
rfc6902@5.0.1
npm install xjog \
sqlite@^4.0.23 sqlite3@^5.0.3 \
rfc6902@5.0.1
1.3Hello, world
Let's create a simple machine and register it with XJog. Then we will run until we reach a final state and then clean up.
Let's start with creating the instance (listing 2). We'll be using in-memory SQLite database. This way the example is self-sufficient and ready to run.
const persistence = await PostgreSQLPersistenceAdapter.connect();
const xJog = new XJog({ persistence });
await xJog.start();
The next step is to configure a machine using the createMachine
function, and to register it
with XJog. This machine will determine how the chart will behave. In our example we only have two states,
shy
and confident
. When our chart collects enough courage, it yelps "Hello, world!" and then
retires as a confident chart.
const machine = await xJog.registerMachine(
createMachine({
id: 'hello world',
initial: 'shy',
states: {
'shy': {
on: {
'get courage': {
actions: () => console.log("Hello, world!"),
target: 'confident'
},
},
},
'confident': {
type: 'final'
},
},
}),
);
After registering the machine, we have to instantiate a chart (listing 4).
While we're at it, let's send the chart an event and check what the state is after that.
const chart = await machine.createChart();
const state = await chart.send('get courage');
assert(state.matches('confident')).toEqual(true);
As a result, when running, we should also see "Hello, world!" printed in the console.
One more thing to add is the cleanup. We'll wrap the whole thing in try-finally
to make sure
it's called in both successful and failing paths.
const persistence = await PostgreSQLPersistenceAdapter.connect();
const xJog = new XJog({ persistence });
await xJog.start();
try {
const machine = await xJog.registerMachine(
…
);
…
await xJog.start();
…
} finally {
await xJog?.shutdown();
}
And there we are!