import type { EngineInternals } from './internals.ts'; /** * Discriminator for `replayWorkflowFeed` / `snapshotWorkflowFeedTail` * / `subscribeWorkflowFeedCommits`. Mirrored by `EventSelector` in * `src/server/workflow-event-feed.ts` so the core engine takes no * dependency on the server package. */ export type WorkflowFeedSelector = 'events' | 'tokens'; /** * Hard-coded stream key for the `tokens` selector. Every transport that * exposes the token feed — `engine.getStreamChunks(id, 'tokens')` and the REST * SSE / WebSocket stream-chunk routes layered on it — keys its stored chunks * under this single value, so a resumption cursor issued by one transport * round-trips through another. */ export declare const TOKENS_STREAM_KEY = "tokens"; /** Record `kind` for every token stream chunk emitted by the feed. */ export declare const STREAM_CHUNK_KIND = "stream:chunk"; /** * Record `kind` emitted when a subscriber resumes from a cursor below the * event-log compaction watermark. The `[cursor, watermark.sequence)` records * were truncated, so the feed reports an explicit boundary marker (rather than * silently skipping) before continuing from the surviving records. `sequence` * is the watermark sequence (the first surviving record). */ export declare const COMPACTION_BOUNDARY_KIND = "workflow:compaction-boundary"; /** * A committed workflow-feed record surfaced to subscribers of * `subscribeWorkflowFeedCommits()`. Fires after the storage commit resolves, so * replay and live delivery share the same committed sequence authority. The * same shape covers both selectors — consumers filter on `selector` before * interpreting `payload`. * * - `events` selector: `kind` is the durable log entry type * (e.g. `'workflow:checkpoint'`). `sequence` / `timestamp` come * from the `WorkflowLogEntry` written inside the batch. * - `tokens` selector: `kind` is always `'stream:chunk'`. * `sequence` is the chunk index; `timestamp` is wall-clock at * write time. */ export type WorkflowFeedRecord = { readonly workflowId: string; readonly selector: WorkflowFeedSelector; readonly kind: string; readonly sequence: number; readonly timestamp: number; readonly payload: unknown; }; export type WorkflowFeedRecordValue = WorkflowFeedRecord; /** * Listener signature for `subscribeWorkflowFeedCommits()`. Returning * `void | Promise` is explicit: an async listener's rejected * promise is caught by the notifier and discarded, exactly like a * sync throw. This is the only correct shape for a notifier called * from a hot path — an escaped unhandled rejection would surface as * a test-runner or Node process-level crash. */ export type WorkflowFeedListener = (record: WorkflowFeedRecord) => void | Promise; /** * Iterate over the workflow's post-commit records for a given selector. */ export declare function replayWorkflowFeed(internals: EngineInternals, workflowId: string, selector: WorkflowFeedSelector, afterSequence: number): AsyncIterable; /** * Snapshot the current tail sequence for the selector. */ export declare function snapshotWorkflowFeedTail(internals: EngineInternals, workflowId: string, selector: WorkflowFeedSelector): Promise; /** * Subscribe to post-commit workflow-feed notifications. */ export declare function subscribeWorkflowFeedCommits(internals: EngineInternals, workflowId: string, selector: WorkflowFeedSelector, listener: WorkflowFeedListener): () => void; /** * Replay committed workflow event-log entries after a durable sequence cursor. */ export declare function replayWorkflowEventLog(internals: EngineInternals, workflowId: string, afterSequence: number): AsyncIterable; /** * Replay committed token stream chunks after a durable sequence cursor. */ export declare function replayWorkflowTokens(internals: EngineInternals, workflowId: string, afterSequence: number): AsyncIterable; /** * Dispatch a committed record to every listener registered for * `(workflowId, selector)`. */ export declare function notifyWorkflowFeedCommit(internals: EngineInternals, workflowId: string, selector: WorkflowFeedSelector, record: WorkflowFeedRecord): void;