DSL for defining discoverable Chronicle captures.
A capture turns data that arrives from outside the event log — an external API, a webhook,
or another event store's public events — into events appended to this event store. The DSL
compiles at build time to Capture Declaration Language
(CDL) text, the same text format the Chronicle kernel's Workbench and SaveCapture accept.
Example
defmodule MyApp.Captures.InvoiceCapture do
use Chronicle.Captures.Capture, name: "InvoiceCapture"
api_source "InvoicingApi", route: "/invoices", poll: "10m"
key "id"
append MyApp.Events.InvoiceStatusChanged, when: "status" do
set :status, "$.status"
end
endOptions for use Chronicle.Captures.Capture
:name— the capture's name. Defaults to the module's last segment.:id— the capture's stable id (a GUID string). Defaults to a deterministic UUIDv5 derived from the module's full name, so re-registering the same module updates the same kernel-side capture instead of creating a new one.:start— whentrue,Chronicle.Captures.Registrarstarts the capture after registering it (opt-in; defaults tofalse, leaving a freshly saved capture stopped).
Sources (exactly one is required)
api_source/1,2— polls an External Service by name. Options::route,:poll(e.g.poll: "10m").webhook_source/1— an inbound webhook at the given path.events_source/1— captures from the public events of another event store, given as a list of registeredChronicle.Events.EventTypemodules.
Only api_source and events_source captures are run by the Chronicle engine as of
Chronicle 19.6; see the CDL documentation linked above.
Key
key/1 names the property path (on the captured item) used to identify and diff it between
observations. For an events_source, use "$eventSourceId" to key on the incoming event's
event source.
Map (optional)
map do ... end declares operations applied to the captured item before append reads it:
map do
rename :full_name, :fornavn
template :greeting, "Hello, ${fornavn}"
translate :status, :status, [{"aktiv", "active"}, {"inaktiv", "inactive"}]
split :full_name, by: ",", into: [:first_name, :last_name]
endAppend
The kernel's CDL parser requires an append's event type to start with an uppercase letter
(letters, digits, and underscores only - no hyphens), even though it is otherwise free to
register event types with any id. Register the event type you intend to append from a
capture with a matching id (id: "InvoiceStatusChanged" rather than
id: "invoice-status-changed"); append/2,3 raises ArgumentError at compile time
otherwise, rather than letting the capture fail validation on the kernel.
append/2,3 declares an event to append when its when: condition matches. set/2 inside
its block maps a target field of the event's struct from a source expression ("$.path" for
the current payload, "$previous.path" for the previous one, "$context.<property>" for
the capture/event context, "$env.VARIABLE" for an environment lookup):
append MyApp.Events.CustomerChanged, when: {:any, ["firstName", "lastName"]} do
set :first_name, "$.firstName"
endwhen: accepts:
- a string —
when: "status"(fires when that property changes) {:any, [...]}/{:all, [...]}—"p1 or p2"/"p1 and p2"{:transition, property, from, to}—"status from a to b":added/:removed{:expression, "template"}— a raw CDL expression
Nested and children scopes
nested :billing_address do
map do
rename :street, :"fakturaAdresse.gate"
end
append MyApp.Events.BillingAddressChanged, when: "street" do
set :street, "$.street"
end
end
children :line_items, identified_by: :line_number do
append MyApp.Events.ItemAdded, when: :added do
set :line_number, "$.lineNumber"
end
endIntrospection
MyApp.Captures.InvoiceCapture.__chronicle_capture__(:id)
MyApp.Captures.InvoiceCapture.__chronicle_capture__(:name)
MyApp.Captures.InvoiceCapture.__chronicle_capture__(:declaration)Registering with Chronicle.Client
{Chronicle.Client,
...
captures: [MyApp.Captures.InvoiceCapture]}Or use otp_app: auto-discovery — modules that export __chronicle_capture__/1 are
discovered automatically. See Chronicle.Captures.Registrar for how registration happens.
Summary
Functions
Declares an API source, polling the named External Service.
Appends an event when its when: condition matches. See the moduledoc.
Declares a child collection scope, identified by a per-item key. See the moduledoc.
Declares an events source, capturing from the public events of another event store.
Names the property path used to identify and diff a captured item.
Declares map operations for the capture's root scope. See the moduledoc.
Declares a nested object scope. See the moduledoc.
Declares an inbound webhook source at the given path.
Functions
Declares an API source, polling the named External Service.
Appends an event when its when: condition matches. See the moduledoc.
Declares a child collection scope, identified by a per-item key. See the moduledoc.
Declares an events source, capturing from the public events of another event store.
events is a list of registered Chronicle.Events.EventType modules.
Names the property path used to identify and diff a captured item.
Declares map operations for the capture's root scope. See the moduledoc.
Declares a nested object scope. See the moduledoc.
Declares an inbound webhook source at the given path.