Ismael Celis
ismaelcelis.com
Ismael Celis
@ismaelcelis.com
But for a state-stored projector you can also test with existing state and one event at a time
November 11, 2025 at 3:58 PM
I think this is a pretty nice way to test event-sourced projectors
November 11, 2025 at 2:58 PM
Autonomous components communicating by reading and appending messages to a log. This temporal decoupling is what enables the logical boundaries that most micro-services fail to achieve. Blocking direct calls = temporal coupling.
November 9, 2025 at 12:50 AM
TBH this is not much simpler than just testing the actors directly.
November 8, 2025 at 10:45 PM
Just a small custom class and a helper method
November 8, 2025 at 10:45 PM
Playing with Given, When, Then helpers to test event-sourced Actors.

GIVEN these previous events
WHEN I dispatch a new command
THEN I expect these new events

Pure, behaviour tests, no database in sight.
November 8, 2025 at 6:09 PM
It's a little Rack app. You require your domain's boot file (to load in your own Sourced reactors), and then launch it with your preferred server. Or you mount it in your own app's router.
November 8, 2025 at 2:57 PM
And the detailed history
November 8, 2025 at 12:19 PM
The result
November 8, 2025 at 12:19 PM
But it still appends events every step of the way, so you can register other consumers that monitor their execution.
November 8, 2025 at 12:19 PM
You can call it like a function, and even wait for termination
November 8, 2025 at 12:19 PM
Sourced's durable workflows are just event-sourced reactors under the hood, so they can participate in "conversations" with other actors just as well. This example holiday booking runs and retries steps sequentially.
November 8, 2025 at 12:19 PM
I'll never get tired of rebuilding event sourced projections
November 7, 2025 at 7:10 PM
The Todo List (the green box) can be a materialised projection, which can also service the UI, or it can just be an actor that re-hydrates itself from event history and decides when it's right to send web hooks.
November 7, 2025 at 12:21 PM
The TODO List pattern in Event Sourcing is such a simple way to orchestrate integrations with third parties, for example sending and tracking web hooks
November 7, 2025 at 11:46 AM
This is a simple "command handler" using this lower-level API. Given an AddProduct message, count how many products the cart has by counting the ProductAdded events in its history. If the product limit of 10 has been reached, return an error event. Otherwise add the product. No "aggregate" in sight!
November 6, 2025 at 2:09 PM
This mixin does little else than writing these methods for you, which is all that's needed to become a message consumer/producer.
November 6, 2025 at 1:36 PM
I wrote a quick mixin with a basic ".on(message)" DSL to facilitate building message handlers that don't require full Event Sourcing semantics. Handler methods can still request full event history for a stream, so you can still build ES on top of this, if needed.
November 6, 2025 at 1:33 PM
Got the Todo App demo working with the new event-sourced architecture, too. Again no UX changes, but it's good to have a couple of different demos to test-drive changes to the library.
November 5, 2025 at 5:41 PM
The UX is the same as before, but the only endpoint that was previously immediately consistent is now eventual as well, and there's a major concurrency bug fixed. This is a projection being re-built based on event history.
November 4, 2025 at 4:55 PM
Ok. Got the old Coffeeshop demo app working with the new architecture. Everything is eventually consistent, and all aspects of the UI are reactive (yet server-rendered).
November 4, 2025 at 4:55 PM
Here, a synchronous-looking Durable Execution API on top of the same underlying interface. Those "durable" methods are actually executed and retried by multiple background workers.
November 3, 2025 at 10:47 PM
Higher-level semantics and DSLs can still be implemented on top of this basic building block. Here, an "Actor" implements "decide, evolve, react" semantics on top of the core messaging primitive. (more about the pattern, here ismaelcelis.com/posts/decide...)
November 3, 2025 at 10:47 PM
The runtime expects a very simple interface, and it will load messages, pass them to each handler, append any new messages, and ACK the last handled message, everything eventually-consistent and with the right ordering guarantees.
November 3, 2025 at 10:47 PM
Very close to finishing The Big Refactor ™️ of my Ruby Event Sourcing library (just in time for next week's talks!). Previous interfaces remain mostly the same, but most of the heavy-lifting has been pushed down into the runtime.
November 3, 2025 at 10:47 PM