Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions agents/eventuous-expert.md
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,7 @@ Determine the target language from the project context:
- Recommend KurrentDB as the default event store unless the user specifies otherwise
- Prefer functional command services (`CommandService<TState>`) for simple cases; aggregate-based (`CommandService<TAggregate, TState, TId>`) when business invariants require it
- Use `IEventReader.LoadAggregate<>()` and `IEventWriter.StoreAggregate<>()` extension methods — `IAggregateStore` is deprecated
- Read whole streams with `IEventReader.ReadStreamToEnd()` (paged, bounded memory) — never `ReadEvents` with `int.MaxValue` as the count
- Use `.NoContext()` for all async calls (`ConfigureAwait(false)`)
- Event types are registered automatically via source generation (no manual `TypeMap` calls)
- Follow the default stream naming convention: `{AggregateType}-{AggregateId}`
Expand Down
2 changes: 2 additions & 0 deletions skills/eventuous-dotnet-kurrentdb/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,8 @@ services.AddEventStore<KurrentDBEventStore>();

`KurrentDBEventStore` implements `IEventStore` (which combines `IEventReader` and `IEventWriter`). `AddEventStore<T>()` registers all three interfaces, with tracing wrappers when diagnostics are enabled.

Reads stream events as they arrive from the server — a read holds at most one deserialized event at a time regardless of the requested count. Non-deserializable `$`-prefixed system events are skipped, with follow-up reads compensating so the requested count is still delivered. To read a whole stream, use the `ReadStreamToEnd` extension method instead of `ReadEvents` with `int.MaxValue`.

The legacy class `EsdbEventStore` is obsolete -- use `KurrentDBEventStore` instead.

## Subscriptions
Expand Down
18 changes: 18 additions & 0 deletions skills/eventuous-dotnet/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -250,6 +250,24 @@ Extracting ID from stream name (useful in projections): `ctx.Stream.GetId()`.

---

## Reading Event Streams

`IEventReader.ReadEvents`/`ReadEventsBackwards` return `IAsyncEnumerable<StreamEvent>` and read a fixed number of events. `KurrentDBEventStore` streams events as they arrive (holds one deserialized event at a time); relational stores buffer events proportional to `count` per call, so keep the count bounded.

Reader contract (all stores): a read yields exactly `count` events unless the stream end is reached, so a short read means end of stream; reading past the end of an existing stream returns an empty sequence, and only a missing stream throws `StreamNotFound`.

To read a whole stream, use the `ReadStreamToEnd` extension method — never `ReadEvents` with `int.MaxValue` as the count:

```csharp
await foreach (var evt in eventReader.ReadStreamToEnd(streamName, StreamReadPosition.Start, cancellationToken: ct)) {
// One event at a time, memory bounded by page size (default 500)
}
```

Options: `pageSize` tunes the page size (must be positive, throws `ArgumentOutOfRangeException` otherwise); `failIfNotFound: false` yields nothing instead of throwing `StreamNotFound`. The `ReadStream` extension method does the same paged read and returns `StreamEvent[]` if you need the whole stream as an array.

---

## HTTP API

### Controller-Based
Expand Down