Skip to content

Resolving the event source ID

Every event belongs to an event source, such as one task. The integration takes the event source from the command unless you say otherwise.

Command declaresEvent source ID
getEventSourceId()Its result; this takes precedence
A @key() fieldThat field’s value
NeitherA new UUID for each execution

The key is the same one Arc resolves for the command context, so read models and aggregates loaded for the command use the same event source.

getEventSourceId() accepts a string, a Fundamentals Guid, or a concept wrapping a primitive or Guid; Arc converts it to the event source ID string. Unsupported objects fail with The command provided an invalid event source id, rather than producing an ambiguous object name. An empty string counts as no value, and the @key() field is used instead.

tuple(eventSourceIdResponse(id), event) appends the event to id and returns id as the command’s response, overriding the key. An ordinary tuple(event, 'message') still appends to the command key.

import { eventForEventSourceId } from '@cratis/arc.chronicle';
handle() {
return eventForEventSourceId({ eventSourceId: 'routed', event: new Registered(),
eventSourceType: 'Override', subject: 'subject-1', tags: ['tag-1'] });
}

This excerpt is from the package’s scenario spec. The explicit route, subject, occurred time, and tags override command defaults. The value is branded, so an ordinary DTO with event and eventSourceId fields is never mistaken for an event. The SDK’s @tag and @tags on event classes still apply.

Class decorators from @cratis/arc.chronicle set routing defaults for every event a command returns:

DecoratorSets
@eventSourceType('Task', { concurrency? })The event source type
@eventStreamType('Onboarding', { concurrency? })The event stream type
@eventStreamId('main', { concurrency? })The event stream ID
@eventSubject('subject')The compliance subject; see Subject

{ concurrency: true } reads that dimension’s tail immediately before the append and scopes it; see Concurrency.