Skip to content

feat(events): add archive/tombstone/progression seams to Weasel.Storage.Events#360

Merged
jeremydmiller merged 1 commit into
masterfrom
feat/event-auxiliary-seams
Jul 17, 2026
Merged

feat(events): add archive/tombstone/progression seams to Weasel.Storage.Events#360
jeremydmiller merged 1 commit into
masterfrom
feat/event-auxiliary-seams

Conversation

@jeremydmiller

Copy link
Copy Markdown
Member

Extends the closed-shape event-storage hierarchy with dialect-supplied factories for the auxiliary event-store write operations that sit alongside the append/stream lifecycle: archive/un-archive, tombstone (hard delete), and projection-progression upsert.

Why

EventStorage<TId> / IEventStoreSqlDialect already factor the append + stream-version lifecycle so a store provides only its dialect SQL. The archive/tombstone/progression operations are the last event-store write operations with no shared seam — every consuming store keeps them bespoke. This adds that seam so a store (Polecat first; see JasperFx/polecat#318) can route them through the shared runtime.

Shape

These operations are append-mode-independent but their SQL is dialect-specific (SQL Server SYSDATETIMEOFFSET() + MERGE vs Postgres now() + ON CONFLICT), so they follow the same pattern as the existing CreateQuickAppendEventsOperation delegate:

  • New EventAuxiliaryOperations record — three optional IStorageOperation factories.
  • EventStorage<TId> gains an AuxiliaryOperations property plus virtual ArchiveStream / TombstoneStream / UpdateProgress methods that delegate to the factories, or throw NotSupportedException when a dialect doesn't supply them.
  • IEventStoreSqlDialect gains a default interface method BuildAuxiliaryOperations(EventRegistry) => null.
  • EventStorageBuilder assigns the dialect's auxiliary operations onto the built storage.

Compatibility

Purely additive and non-breaking. The dialect method is a default interface member returning null, so existing dialects (Marten's PostgresEventStoreDialect) compile unchanged and keep their bespoke operations; the new EventStorage<TId> methods simply stay throwing until a dialect opts in. No behavior changes for any current consumer. Minor version bump 9.16.4 → 9.17.0.

The seam is exercised end-to-end by the consuming store's event-store test suite (Polecat's, on the follow-up bump), consistent with how the rest of EventStorage<TId> is validated downstream rather than in this repo.

🤖 Generated with Claude Code

…ge.Events

Extend the closed-shape event-storage hierarchy with dialect-supplied factories
for the auxiliary event-store write operations that sit alongside the
append/stream lifecycle: archive/un-archive, tombstone (hard delete), and
projection-progression upsert.

These operations are append-mode-independent but their SQL is dialect-specific
(SQL Server SYSDATETIMEOFFSET() + MERGE vs Postgres now() + ON CONFLICT), so
they follow the same shape as the existing CreateQuickAppendEventsOperation
delegate: the dialect vends an EventAuxiliaryOperations record of factories, and
EventStorage<TId> exposes them through ArchiveStream / TombstoneStream /
UpdateProgress.

- New EventAuxiliaryOperations record (three optional IStorageOperation
  factories).
- EventStorage<TId> gains the AuxiliaryOperations property plus virtual
  ArchiveStream / TombstoneStream / UpdateProgress methods that delegate to the
  factories or throw NotSupportedException when a dialect does not supply them.
- IEventStoreSqlDialect gains a default interface method BuildAuxiliaryOperations
  returning null — additive and non-breaking: existing dialects (Marten's
  Postgres dialect) keep their bespoke operations and compile unchanged.
- EventStorageBuilder assigns the dialect's auxiliary operations onto the built
  storage.

This lets a store (Polecat first) route its last hand-written event-store SQL
through the shared EventStorage<TId> seam instead of bespoke operation classes.
Purely additive; no existing behavior changes. Minor version bump 9.16.4 ->
9.17.0.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
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.

1 participant