Returning events
A command decides what happened; the integration appends it. Return the event from handle(), and Arc appends it only after authorization, validation, and provide() have passed.
Return an event
Section titled “Return an event”This excerpt is from the compiled kernel suite, in the shape you would write it in your application:
import { field } from '@cratis/fundamentals';import { eventType } from '@cratis/chronicle/events';import { command, key } from '@cratis/arc.core';
@eventType()export class TaskCreated { @field(String) title: string; constructor(title: string) { this.title = title; }}
@command()export class CreateTask { @field(String) @key() id = ''; @field(String) title = '';
handle(): TaskCreated { return new TaskCreated(this.title); }}With Chronicle registered, POST /api/create-task appends one TaskCreated to the event source named by the command’s @key() field, in the tenant’s namespace. The command result carries no response, because the event was consumed on the server.
What is appended
Section titled “What is appended”handle() returns | Result |
|---|---|
| A registered event | Appended to the command’s event source |
| An array of registered events | Appended in one SDK batch |
| An array of ordinary objects | An ordinary response, not events |
tuple(event, 'message') | The event is appended to the command key, and 'message' is the response |
tuple(eventSourceIdResponse(id), event) | The event is appended to id, and id is returned to the caller |
eventForEventSourceId({ eventSourceId, event, ... }) | Appended to that event source with explicit routing |
eventsWithConcurrencyScopes(events, scopes) | Appended with exact concurrency scopes; see Concurrency |
The integration is a response value handler: it recognizes registered event instances and branded values, and everything else keeps its ordinary meaning. A command can return Chronicle events together with command operations in a tuple(...): the operations run first, and the event batch decides whether they are compensated; see Events and command operations. An event or operation can’t be the command’s client response.
The event source, routing decorators, and explicit targets are covered in Resolving the event source ID. Everything else an appended event carries, such as its subject, causation, and correlation ID, is listed in Event metadata.
Low-level definitions
Section titled “Low-level definitions”The older defineChronicleCommand remains. It takes a client, an event store, a tenant namespace resolver, and produce() returning { events, response }, and appends immediately with its own rejection mapping. Use the model-bound path for new commands. Neither route makes the SDK’s observer completion synchronous with an append acknowledgment.