using System.Collections.Generic; using Svrnty.CQRS.Events.Abstractions.Notifications; using Svrnty.CQRS.Events.Abstractions.Delivery; using Svrnty.CQRS.Events.Delivery; using Svrnty.CQRS.Events.Abstractions.EventStore; using System.Threading; using System.Threading.Tasks; using Svrnty.CQRS.Events.Abstractions; namespace Svrnty.CQRS.Events.Core; /// /// Default implementation of IEventEmitter that stores events and triggers delivery. /// public sealed class EventEmitter : IEventEmitter { private readonly IEventStore _eventStore; private readonly IEventDeliveryService _deliveryService; private readonly IEventNotifier? _eventNotifier; public EventEmitter( IEventStore eventStore, IEventDeliveryService deliveryService, IEventNotifier? eventNotifier = null) { _eventStore = eventStore; _deliveryService = deliveryService; _eventNotifier = eventNotifier; } public async Task EmitAsync(ICorrelatedEvent @event, CancellationToken cancellationToken = default) { // Store the event and get its sequence number var sequence = await _eventStore.AppendAsync(@event, cancellationToken); // Deliver to subscribers (handles subscription state updates) await _deliveryService.DeliverEventAsync(@event, sequence, cancellationToken); // Notify active streams (real-time push to connected clients) if (_eventNotifier != null) { await _eventNotifier.NotifyAsync(@event, sequence, cancellationToken); } return sequence; } public async Task> EmitBatchAsync(IEnumerable events, CancellationToken cancellationToken = default) { // Store all events var sequences = await _eventStore.AppendBatchAsync(events, cancellationToken); // Deliver each event to subscribers foreach (var @event in events) { if (sequences.TryGetValue(@event.EventId, out var sequence)) { await _deliveryService.DeliverEventAsync(@event, sequence, cancellationToken); // Notify active streams if (_eventNotifier != null) { await _eventNotifier.NotifyAsync(@event, sequence, cancellationToken); } } } return sequences; } }