Skip to content

GH-985: InMemoryDocumentStore implements IEventStore - #988

Merged
jeremydmiller merged 1 commit into
mainfrom
GH-985-inmemory-ieventstore
Oct 9, 2026
Merged

jeremydmiller merged 1 commit into
mainfrom
GH-985-inmemory-ieventstore

Conversation

@jeremydmiller

Copy link
Copy Markdown
Member

Closes #985. Part of #955.

The in-memory prototyping store now implements IEventStore<IInMemoryDocumentSession, IInMemoryQuerySession>, and AddInMemoryStoreForPrototyping registers it as IEventStore. Store-agnostic helpers written against IEventStore (Bobcat's CritterStack layer, services.EventStore()) now work on a stub-first app instead of throwing "No JasperFx.Events.IEventStore is registered".

What the issue asked for, mapped to the change:

  • Opening a session: AllDatabases() returns one InMemoryEventDatabase, and OpenSession(database[, tenantId]) opens a lightweight session.
  • OpenReadOnlyEventStore() returns a query session's Events, which now also implements IReadOnlyEventStore:
    • FetchStreamAsync was already there.
    • QueryEventsAsync(EventQuery) supports every filter except tags (DCB). Tag filters throw rather than being ignored. Paging uses long arithmetic, so PageSize = int.MaxValue is safe.
    • QueryStreamStates() is LINQ-to-objects and works with the shared async terminators.
    • Because it's also the session's IQueryEventStore, AggregateStreamAsync<T> works directly, the same as on Marten.
  • Session Events: already IEventOperations + IQueryEventStore.
  • Projection waits: projections run inline, so WaitForNonStaleProjectionDataAsync returns immediately and AllShards() / AllProjectionProgress() are empty.
  • Out of scope: the daemon, subscriptions, compaction and dead letters throw NotSupportedException with the store's usual "switch to Marten, Polecat or Fisher" message.

The compliance fixture's EventStore now returns the store. I didn't enroll EventQueryCompliance or StreamStateQueryCompliance: they register tag types and archive or compact streams, which this store doesn't support. Instead, InMemoryIEventStoreTests has 9 facts that only use the IEventStore contract, along the same path Bobcat takes.

Tests

  • EventStoreTests: 286 passed, 22 skipped, on net9.0 and net10.0
  • InMemoryEventStoreTests: 117 passed, 7 skipped (all async-daemon facts, same as before)

Follow-up: add an in-memory lane to WolverineFx.Bobcat's tests once this ships.

🤖 Generated with Claude Code

https://claude.ai/code/session_01J8KxC18Q51z5w4u6YARwe4

The in-memory prototyping store now implements
IEventStore<IInMemoryDocumentSession, IInMemoryQuerySession> and is
registered as IEventStore by AddInMemoryStoreForPrototyping, so the
store-agnostic helpers written against IEventStore (Bobcat's
GivenEvents/ThenEvents, services.EventStore()) work on a stub-first app.

- AllDatabases() returns a single InMemoryEventDatabase; OpenSession
  opens a lightweight session on the store
- OpenReadOnlyEventStore() is a query session's Events, which now also
  implements IReadOnlyEventStore: QueryEventsAsync (every filter but
  tags, which are refused) and QueryStreamStates
- Projections are inline, so the database is never stale and reports
  no async shards; daemon, subscription and compaction members refuse
  with NotSupportedException
- The compliance fixture's EventStore now returns the store

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01J8KxC18Q51z5w4u6YARwe4
@jeremydmiller
jeremydmiller merged commit 0b9a389 into main Oct 9, 2026
1 check passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

JasperFx.Events.InMemory: InMemoryDocumentStore should implement IEventStore so store-agnostic test helpers work on the prototyping store

1 participant