Skip to content

Release v3.4.0

Choose a tag to compare

@github-actions github-actions released this 18 Sep 06:28
8af16ac

Ports Chronicle's read model variations feature (Cratis/Chronicle#3956, shipped for the .NET
client in Cratis/Chronicle#4062, and for Kotlin/Java and TypeScript in
Cratis/Chronicle.Kotlin#85 and Cratis/Chronicle.TypeScript#75) to the Elixir client, with
documentation snippets for both authoring styles.

Added

Both Chronicle.ReadModels.ReadModel (model-bound) and Chronicle.Projections.Projection
(declarative) gain two new macros:

  • variant_of/2 declares a read model or projection to be one of several mutually exclusive
    representations of the same logical entity. Entering one variant removes the entity from every
    sibling variant.
  • enters_on/1,2 names the event(s) that may create or resurrect a variant. Every other event a
    variant projects from — whether via from/2 directly or merged in from a global handler — is
    automatically reclassified into an update-only join, so it can update an already-active
    instance but can never create or resurrect one.

A new Chronicle.Projections.GlobalHandler macro shares a mapping across every variant of a
group without repeating it on each variant module. A mapping that targets a member some variant
lacks is a declaration error (GlobalHandlerPropertyNotOnVariant), not a silently skipped
mapping. A global handler module is discovered through a new __chronicle_global_handler__/1
introspection function and the Chronicle.Client :global_handlers option, and is never
registered as its own projection.

Chronicle.Projections.VariantReclassifier applies the same merge-then-reclassify-then-cross-wire
pipeline as the other clients, operating on the already-built ProjectionDefinition structs
shared by both authoring styles.

Note on current kernel support

A variant's own key is what the reclassified self-join correlates on. The kernel does not honor
$eventSourceId in a property mapping yet (Cratis/Chronicle#3924 — a pre-existing gap that
already affects from/2's :key/:event_source_id generally, not something introduced here).
The definition shape this ships is otherwise complete and verified; it starts working end-to-end
the day that is fixed, with no changes needed on this side.