Event log
The event log is Chronicle’s primary event sequence and is documented in the shared Chronicle docs.
- Events and event logs
- Appending events
- Appending many events
- Optimistic concurrency
- Getting events
- Observing appends
- Event redaction
- Closing streams
- TypeScript client setup
TypeScript client notes
Section titled “TypeScript client notes”- An append without route options leaves the route to the kernel. Clients before this change sent a
Defaultroute themselves, so existing streams need attention; follow Preserve existing append routes before upgrading. appendandappendManydo not throw on a constraint violation, concurrency violation, or append error.appendreturns oneAppendResult;appendManyreturns an array with one per event. CheckisSuccesson each result, or readconstraintViolations,concurrencyViolation, anderrors.AppendOptionsacceptssourceType,streamType,streamId,subject,occurred,correlationId,tags,namedTags,concurrencyScope, andconcurrencyScopes. Rich batch entries override shared metadata; concurrency scopes remain independent.- Structured named tags are
NamedTagvalues: a nonblank name and an exact, possibly empty, value. Pass them asnamedTagsonAppendOptions(shared by every event) or on anEventForEventSourceIdentry (that event only). Each event gets its own tags first, then the shared ones, keeping the first occurrence of each exact name and value pair. An invalid tag throwsInvalidNamedTagbefore anything is sent. An append that carries named tags uses the kernel’s dedicated named-tag call, so a kernel without named-tag support rejects it instead of dropping the tags. Read them back fromcontext.namedTagson read and delivered events. - Batches cannot combine non-empty named tags with any registered
eventSourceentry, even when the tags and registered source belong to different events. The client throwsNamedTagsWithRegisteredEventSourceNotSupportedbefore any RPC because the kernel’s named-tag batch operation drops registered source routing (kernel issue). Singleappendcalls support this combination; batches with an emptynamedTagsarray or without registered sources are unaffected. eventLog.redact(sequenceNumber, reason)andeventLog.redactForEventSource(eventSourceId, reason, eventTypes?)permanently rewrite an event’s (or an entire event source’s) content — a destructive GDPR/compliance erasure, never a field-level mask.eventLog.getForEventSourceIdAndEventTypes(eventSourceId, eventTypes, ...)andeventLog.getFromSequenceNumber(sequenceNumber, eventSourceId?, eventTypes?)read appended events back, filtered by event source and/or event type.- Route arguments on
getForEventSourceIdAndEventTypesandgetTailSequenceNumberdo not default to the legacyDefaultroute. An omitted dimension does not narrow the read, so it also returns the events the kernel routed for an append with no route options. Pass the dimensions explicitly to scope a read to one stream; see Preserve existing append routes. eventLog.getNextSequenceNumber()returns the sequence number the next append will receive (EventSequenceNumber.firstwhen the sequence is empty).eventLog.completeStream(eventStreamType, eventStreamId)permanently closes a non-default stream; further appends to it are rejected with aStreamClosedconstraint violation.eventLog.appendOperationsis a hot, multicastAsyncIterableof every append this event log instance makes, together with its result.appendResult.waitForCompletion(timeoutMs?)waits for every observer affected by an append to catch up or fail before you read a read model back. Pass{ timeoutMs?, signal? }instead to cancel the underlying wait RPC when the caller aborts; the signal and timeout are combined so either cancels it. It resolves immediately for an unsuccessful append and rejects when the timeout (5 seconds by default) or caller cancellation occurs. See Failed Partitions.appendMany(events: EventForEventSourceId[], options?)sends everyoptions.concurrencyScopeslabel, including labels that are not append targets. A target without an explicit entry uses the sharedconcurrencyScopeoption. The kernel requires at least one event per batch; a scope-only batch is rejected.- Use
EventSequenceNumber.beforeFirst.valueassequenceNumberwhen a scope must assert that no matching event exists. It is sent as the wireExpectsNoMatchingEventflag, not as a sequence number;EventSequenceNumber.unset.valuemeans no expected revision. On a kernel that does not support the flag, the check is skipped, so verify server compatibility before relying on this for a first append.