Files
sausage/host/js/events.md
T

56 lines
2.5 KiB
Markdown

# Durable events
`events.ts` owns event tokens, the event log, the feed, and reactor cursors.
World extensions import its shared tokens from `@earendil-works/sausage-events`.
The loader supplies this synthetic module from its own bundle.
## Transaction contract
`host.emit(tx, token, data)` appends an event inside the caller's transaction.
The event and the caller's document changes commit together.
A failed transaction retains neither change.
The log uses an ownerless conversation that runs no turns.
Entry IDs provide a global order.
`EventLog` records the log conversation and each reactor's cursor on the root conversation.
`host.react(name, tokens, handler, {from})` registers a facet-scoped reactor.
Its durable name is `<extension>/<name>`.
Each handler receives its transaction and a detached event record.
The handler's document changes and cursor advance commit together.
Transactional changes occur exactly once.
External effects can repeat after a crash.
A failed handler rolls back its changes and cursor.
The next matching event commit or reactor start retries the pending event.
Reloads stop the old facet's reactors before the new facet starts.
A replacement with the same name continues from its persisted cursor.
A new reactor starts at the beginning by default.
`from: 'now'` skips existing events only when the reactor lacks a cursor.
## Read contract
`host.eventLog.recent(options)` returns detached records, newest first by default.
It supports token filters, a limit, and an ascending order.
`since` and `before` are exclusive entry IDs.
`host.eventLog.reactors()` returns cursors, lag, activity, and the latest handler failure.
`EventFeed` stores the newest 100 events, oldest first.
The existing document observation API can observe this feed.
Event emission updates the feed inside the same transaction.
Notices become `sausage.notice` events.
The host records each distinct notice once per facet load.
This task does not add Ultimate's build or supervisor startup events.
## Tests
`events-test.ts` covers atomic emission, handler rollback, cursor recovery, replacement, and harness reopen.
It also covers filtered reads, detached copies, the bounded feed, and `from: 'now'`.
World facets exchange events through their hosts and continue after a commit reload.
`host/tests/events.rs` kills a child after emission, then verifies one reaction across two restarts.
The world test builds `git.wasm` with the repository's linker setup.
It uses a persistent cache in the executor's target folder.