Skip to content

JasperFx 2.73.0

Choose a tag to compare

@jeremydmiller jeremydmiller released this 17 Sep 13:20

⚠ Unlisted — use 2.73.1 instead

This release is unlisted on NuGet. EventModelClaim's two-argument constructor stopped
existing here (a defaulted third parameter on a record's primary constructor is binary-breaking),
so an assembly compiled against 2.72.0 that constructs one gets a MissingMethodException.
2.73.1 restores it and is otherwise
identical to what is described below. See the binary-compatibility note at the end of these notes.

Three Event Modeling / event sourcing changes, all additive.

A store-agnostic StubEventStream<T> (#858, #862)

JasperFx.Events.StubEventStream<T> is a stand-in for IEventStream<T> for unit testing a handler that takes a stream handle directly — Wolverine's [WriteAggregate] IEventStream<Account> account. Construct one with the aggregate state the handler should see, call the handler, assert on EventsAppended. No database, and no mocking library.

The stand-in previously existed only as Marten.Events.StubEventStream<T>, built on Marten's StoreOptions / EventGraph, so Polecat and Fisher users wrote their own or mocked the interface — and Received(1).AppendOne(...) proves only that a method was called, leaving which event and what it carried unchecked. EventRegistry builds IEvent envelopes with no store behind it, which is what made this liftable.

Id, Key, StartingVersion, CurrentVersion, Cancellation and AlwaysEnforceConsistency are settable for multi-stream and version-sensitive handlers; TryFastForwardVersion() is inert. Marten.Events.StubEventStream<T> is untouched and keeps compiling.

New docs page: Event Sourcing → Unit Testing Handlers.

A source disagreement names the source, not only the rung (#859, #861)

Pattern: Declared claims Automation; Declared claims Command named neither party and read as one source contradicting itself. EventModelProvenance is a rung, and a rung holds several sources — spec-first work has a declared model file and specs, both Declared by construction.

EventModelClaim now carries a Source beside its Provenance, populated by the merge from the contributing slice's Origin, and Claimant renders the source where there is one and the rung otherwise:

Pattern: file://CritterCrush.emodel.yaml claims Automation; suite://CritterCrush.Specs claims Command

Two anonymous sources on one rung now say so (two Declared sources disagree — kept X, dropped Y) rather than naming the rung twice, and one source genuinely contradicting itself is the only case that reads that way. A source that never stamped Origin renders exactly as before.

ModelCollapse carries its model names as data (#853, #860)

HotspotDescriptor.ModelCollapse recorded which Event Models were folded only inside Text, so a consumer that wanted to act on it — offer a picker, route per model, count them — had to regex a sentence. ServiceName and CollapsedModelNames now sit beside an unchanged Text.

HotspotDescriptor's equality is hand-written as a result, comparing CollapsedModelNames element-wise: a record compares a collection member by reference, which would have broken JSON round-trip equality and hotspot de-duplication. The merge itself de-duplicates on Origin + Text, never on equality.

⚠ One binary-compatibility note

EventModelClaim is a positional record and gained a third parameter (Source, defaulted), so its primary constructor's signature changed. Source-compatible — new EventModelClaim(rung, value) still compiles — but an assembly compiled against 2.72.0 that constructs one will need a recompile rather than a drop-in swap. Construction is almost entirely internal to JasperFx; reading the properties is unaffected.

Packages

Seven packages at 2.73.0: JasperFx, JasperFx.Events, JasperFx.Events.ComplianceTests, JasperFx.Events.SourceGenerator, JasperFx.SourceGenerator, JasperFx.Aspire, JasperFx.Events.MicrosoftExtensionsAI. JasperFx.RuntimeCompiler is versioned independently and stays at 5.0.0.

Full Changelog: V2.72.0...V2.73.0