evtstore
Version:
Event Sourcing with Node.JS
113 lines (75 loc) • 3.08 kB
Markdown
# Event Handlers
Event handlers are typically used to create read model populators and process managers.
The factory functions used to create `Event Handlers` are returned from `createDomain`.
For example:
```ts
const { createHandler } = createDomain(
{ provider }, // provider from createProvider()
{ user, profile, posts } // Aggregates from createAggregate<...>()
)
```
## How It Works
Once the `EventHandler` has been started, the **Event Handler Loop** will:
1. Retrieve the `Bookmark` position using the `Provider`
2. Retrieve events after the `Bookmark` position
3. If there are:
- No events: Wait 500ms and retry Step 2.
- Some events:
1. Process each event and update the remote bookmark after each successful event handled
2. Immediately retry Step 2
## createHandler()
Note that the `Stream` type is inferred from the `Aggregate` stream names when `createDomain` is called.
```ts
function createHandler(bookmark: string, streams: Stream[], options?: HandlerOptions): EventHandler
```
### HandlerOptions
```ts
type HandlerOptions = {
tailStream?: boolean // Defaults to false
alwaysTailStream?: boolean // Defaults to false
continueOnError?: boolean // Defaults to false
}
```
#### continueOnError
When an event handler function throws, the event handler will invoke the `Provider.onError` function then continue processing events.
By default event handlers will stop processing events until the handler no longer throws.
#### tailStream
When the event handler is started for the first time, the handler will begin at the end of the stream(s) history
#### alwaysTailStream
Every time the event handler is started, the handler will begin at the end of the stream(s) history
## EventHandler
### Handler
```ts
type Handler = (aggregateId: string, event: Event, meta: EventMeta) => Promise<void>
```
The `Event` type is narrowed using the `stream` and `eventType` parameters from calling `handle(stream, eventType, handler)`.
### handle
```ts
function handle(stream: string, eventType: string, handler: Handler)
```
The `stream` and `eventType` parameters are literals that are derived when `createDomain` is called.
The `eventType` will only allow event types from the `stream` you passed in.
### start()
Begins the **Event Handler Loop**. Typically called when starting your service.
The handler will
### stop()
Stops processing events. Not typically called.
### runOnce()
Typically used for integration testing.
`runOnce()` will handle all unprocessed events regardless of the `start`/`stop` state of the handler.
### reset()
Resets the internal bookmark of the event handler.
This forces the handler to retrieve the remote state of the bookmark on the next iteration.
## Example
```ts
import { createHandler } from '...'
const userModel = createHandler('users-model', ['users'])
userModel.handle('users', 'userCreated', async (id, event, meta) => {
await mongo.collection('users').insertOne({
userId: id,
name: event.name,
createdAt: meta.timestamp,
})
})
userModel.start()
```