mem-evoq
View SourceIn-memory event-store adapter for evoq.
Why this exists
evoq is backend-agnostic. The production adapter is reckon-evoq, which targets reckon-db. For tests, demos, and as a reference implementation of the evoq_event_store adapter behaviour, this package provides an in-memory adapter that has no disk persistence and no clustering — process restart loses state, which is the intended semantic.
Pairs with evoq for:
- Writing integration tests against the full dispatch → store → emit → project cycle without spinning up Khepri/Ra
- Demos that fit in 30 lines of Erlang
- A second concrete implementation of the
evoq_event_storecontract (proof that the contract is implementable; not specific to reckon-db) - Testing your integrity-violation handling: mem-evoq supports optional integrity exactly as reckon-db does
Installation
%% rebar.config
{deps, [
{evoq, "~> 1.15"},
{mem_evoq, "~> 0.1"}
]}.Quick start
{ok, _} = application:ensure_all_started(mem_evoq),
ok = application:set_env(evoq, event_store_adapter, mem_evoq_adapter),
{ok, _} = mem_evoq:start_store(my_test_store),
%% Any evoq dispatch now targets the in-memory store.
%% When done:
ok = mem_evoq:stop_store(my_test_store).Or talk to the adapter directly without evoq in the loop:
{ok, _} = mem_evoq:start_store(direct_demo),
{ok, 1} = mem_evoq_adapter:append(
direct_demo, <<"order$1">>, -1, %% -1 = ?NO_STREAM
[#{event_type => <<"order_placed">>, data => #{total => 42}},
#{event_type => <<"order_confirmed">>, data => #{}}]),
{ok, [_, _]} = mem_evoq_adapter:read(
direct_demo, <<"order$1">>, 0, 10, forward).With integrity enabled
mem-evoq mirrors reckon-db's tamper-resistance behaviour so you can test integrity-violation handling without infrastructure:
Key = crypto:strong_rand_bytes(32),
{ok, _} = mem_evoq:start_store(secure_demo, #{
integrity => #{enabled => true, key => Key}
}),
{ok, 0} = mem_evoq_adapter:append(
secure_demo, <<"audit$1">>, -1,
[#{event_type => <<"login_attempted">>, data => #{user => <<"a">>}}]),
%% Strict read verifies the full chain.
{ok, [_]} = mem_evoq_adapter:read(
secure_demo, <<"audit$1">>, 0, 10, forward, #{verify => strict}).Events written under this store carry prev_event_hash and mac. Reads verify both. A tampered event surfaces as {error, {integrity_violation, _}}. See Integrity guide for verification modes, snapshot anchoring, and subscription catch-up behaviour.
Limitations
| Concern | mem-evoq | reckon-db |
|---|---|---|
| Persistence | ✘ — process restart loses state | ✓ disk-backed (Khepri/Ra) |
| Clustering / replication | ✘ single process | ✓ Raft consensus |
| Tamper-resistance | ✓ identical primitives, opt-in per store | ✓ identical primitives, opt-in per store |
| Subscription fan-out | ✓ live + catch-up | ✓ live + catch-up |
| Snapshots | ✓ save/load/list/delete + anchor | ✓ |
| Read filters | by stream / event_type / pattern / tags | full reckon-db filter taxonomy |
| Scavenging / archive | ✘ | ✓ |
| Capability tokens / per-region keys / vault | ✘ | ✓ |
| Key rotation | ✘ — restart with the new key | ✓ |
For anything in the right column not matched on the left, pair evoq with reckon-evoq + reckon-db.
Related packages
- evoq — the CQRS / Event Sourcing framework this is an adapter for
- reckon-evoq — production adapter targeting reckon-db
- reckon-gater — shared types and integrity primitives both adapters consume
- reckon-db — the production event store
License
Apache 2.0 — see LICENSE.