package port import "time" // StreamEvent represents an event to be published on a stream. // Events are delivered to SSE clients and can be replayed using Last-Event-ID. type StreamEvent struct { // ID uniquely identifies this event for Last-Event-ID reconnection support. // Format: "{streamID}:{sequence}". Populated by the publisher on Publish(). ID string // Type identifies the event category (e.g., "build.output", "build.completed"). // Use the BuildEvent* constants from the worker package for build events. Type string // TaskID associates the event with a specific task for filtering and replay. // Defaults to the stream ID if not explicitly set. TaskID string // Timestamp records when the event was created or published. // Populated by the publisher if zero when Publish() is called. Timestamp time.Time // Sequence is a monotonically increasing number within a stream. // Used for ordering and detecting missed events. Sequence int64 // Data contains the event-specific payload as key-value pairs. // Contents vary by event type. Data map[string]any } // StreamPublisher defines operations for managing SSE event streams. type StreamPublisher interface { // Subscribe creates a subscription to events for the given stream ID. // Returns a channel that will receive events and a cleanup function. Subscribe(streamID string) (<-chan StreamEvent, func()) // SubscribeFromID creates a subscription starting from a specific event ID. // This is used for reconnection with Last-Event-ID support. // Events since lastEventID will be replayed before new events are delivered. SubscribeFromID(streamID string, lastEventID string) (<-chan StreamEvent, func()) // Publish sends an event to all subscribers of a stream. // Returns the generated event ID. Publish(streamID string, event StreamEvent) string // Close closes a stream and all its subscriptions. Close(streamID string) }