import type { AttributeChange, ExperimentalSetAttributesResult } from './attributes.js'; import type { CreateEventParams, CreateEventRequest, Event, EventResult, GetEventParams, ListEventsByCorrelationIdParams, ListEventsParams, RunCreatedEventRequest } from './events.js'; import type { GetHookParams, Hook, ListHooksParams } from './hooks.js'; import type { Queue } from './queue.js'; import type { GetWorkflowRunParams, ListWorkflowRunsParams, WorkflowRun, WorkflowRunWithoutData } from './runs.js'; import type { GetChunksOptions, PaginatedResponse, StreamChunksResponse, StreamInfoResponse } from './shared.js'; import type { GetStepParams, ListWorkflowRunStepsParams, Step, StepWithoutData } from './steps.js'; export interface Streamer { /** * Override the default flush interval (in milliseconds) for buffered stream writes. * Chunks are accumulated in a buffer and flushed together on this interval. * * The default is 10ms, which is appropriate for HTTP-based backends where * each flush is a network round-trip. For backends with sub-millisecond writes * (e.g., Redis, local filesystem), a lower value (or 0 for immediate flushing) reduces * end-to-end stream latency. * * Not supported by all worlds. */ streamFlushIntervalMs?: number; streams: { write(runId: string, name: string, chunk: string | Uint8Array): Promise; /** * Write multiple chunks to a stream in a single operation. * This is an optional optimization for world implementations that can * batch multiple writes efficiently (e.g., single HTTP request for world-vercel). * * If not implemented, the caller should fall back to sequential write() calls. * * @param runId - The run ID * @param name - The stream name * @param chunks - Array of chunks to write, in order */ writeMulti?(runId: string, name: string, chunks: (string | Uint8Array)[]): Promise; close(runId: string, name: string): Promise; /** * Read from a stream starting at the given chunk index. * Positive values skip that many chunks from the start (0-based). * Negative values start that many chunks before the current end * (e.g. -3 on a 10-chunk stream starts at chunk 7). Clamped to 0. */ get(runId: string, name: string, startIndex?: number): Promise>; list(runId: string): Promise; /** * Fetch stream chunks with cursor-based pagination. * * Unlike `get` (which returns a live `ReadableStream` that waits * for new chunks in real-time), `getChunks` returns a snapshot of currently * available chunks in a standard paginated response. * * @param runId - The workflow run ID that owns the stream * @param name - The stream name/ID * @param options - Pagination options (limit defaults to 100, max 1000) * @returns Paginated chunks with a `done` flag indicating stream completion */ getChunks(runId: string, name: string, options?: GetChunksOptions): Promise; /** * Retrieve lightweight metadata about a stream. * * Returns the tail index (index of the last known chunk, 0-based) and * whether the stream is complete. This is useful for resolving a negative * `startIndex` into an absolute position before connecting to a stream. * * @param runId - The workflow run ID that owns the stream * @param name - The stream name/ID */ getInfo(runId: string, name: string): Promise; }; } /** * Storage interface for workflow data. * * Workflow storage models an append-only event log, so all state changes are handled through `events.create()`. * Run/Step/Hook entities provide materialized views into the current state, but entities can't be modified directly. * * User-originated state changes are also handled via events: * - run_cancelled event for run cancellation * - hook_disposed event for explicit hook disposal (optional) * * Note: Hooks are automatically disposed by the World implementation when a workflow * reaches a terminal state (run_completed, run_failed, run_cancelled). This releases * hook tokens for reuse by future workflows. The hook_disposed event is only needed * for explicit disposal before workflow completion. */ export interface Storage { runs: { get(id: string, params: GetWorkflowRunParams & { resolveData: 'none'; }): Promise; get(id: string, params?: GetWorkflowRunParams & { resolveData?: 'all'; }): Promise; get(id: string, params?: GetWorkflowRunParams): Promise; list(params: ListWorkflowRunsParams & { resolveData: 'none'; }): Promise>; list(params?: ListWorkflowRunsParams & { resolveData?: 'all'; }): Promise>; list(params?: ListWorkflowRunsParams): Promise>; /** * Apply a batch of attribute changes to a run. Merge semantics: * - `value: string` upserts the key * - `value: null` removes the key * - keys not listed in `changes` are untouched * * Returns the post-merge attribute snapshot on the run. * * Pass `options.allowReservedAttributes: true` to permit keys * starting with the reserved `$` prefix. Default behavior rejects * those keys so user code can't accidentally collide with * framework / tooling namespaces; framework callers that own a * sub-namespace flip this on. * * OPTIONAL. World implementations may omit this method; the SDK * helper (`setAttributes` in `@workflow/core`) feature-detects its * absence and no-ops with a one-time warning so third-party / * community worlds keep working without adopting the experimental * API. * * EXPERIMENTAL: this method exists as a stopgap until the * `attr_set` event type lands in a future spec version. When that * happens, `setAttributes` will dispatch through `events.create` * instead, and this method is expected to be removed. See the * `attributes-mvp` changelog entry for the migration shape. */ experimentalSetAttributes?(runId: string, changes: AttributeChange[], options?: { allowReservedAttributes?: boolean; }): Promise; }; steps: { get(runId: string, stepId: string, params: GetStepParams & { resolveData: 'none'; }): Promise; get(runId: string, stepId: string, params?: GetStepParams & { resolveData?: 'all'; }): Promise; get(runId: string, stepId: string, params?: GetStepParams): Promise; list(params: ListWorkflowRunStepsParams & { resolveData: 'none'; }): Promise>; list(params: ListWorkflowRunStepsParams & { resolveData?: 'all'; }): Promise>; list(params: ListWorkflowRunStepsParams): Promise>; }; events: { /** * Create a run_created event to start a new workflow run. * The runId may be provided by the client or left as null for the server to generate. * * @param runId - Client-generated runId, or null for server-generated * @param data - The run_created event data * @param params - Optional parameters for event creation * @returns Promise resolving to the created event and run entity */ create(runId: string | null, data: RunCreatedEventRequest, params?: CreateEventParams): Promise; /** * Create an event for an existing workflow run and atomically update the entity. * Returns both the event and the affected entity (run/step/hook). * * @param runId - The workflow run ID (required for all events except run_created) * @param data - The event to create * @param params - Optional parameters for event creation * @returns Promise resolving to the created event and affected entity */ create(runId: string, data: CreateEventRequest, params?: CreateEventParams): Promise; get(runId: string, eventId: string, params?: GetEventParams): Promise; list(params: ListEventsParams): Promise>; listByCorrelationId(params: ListEventsByCorrelationIdParams): Promise>; }; hooks: { get(hookId: string, params?: GetHookParams): Promise; getByToken(token: string, params?: GetHookParams): Promise; list(params: ListHooksParams): Promise>; }; } /** * The "World" interface represents how Workflows are able to communicate with the outside world. */ export interface World extends Queue, Streamer, Storage { /** * The highest spec version this World supports. * * When set, `start()` creates runs at this version so world-specific * features (e.g., CBOR queue transport) are enabled automatically. * When omitted, runs default to `SPEC_VERSION_SUPPORTS_EVENT_SOURCING` (2), * the safe baseline that all worlds — including community worlds on * older @workflow/world versions — are expected to handle. */ specVersion?: number; /** * Whether calling `process.exit(1)` from a queue handler is observed by * the World as a delivery failure that will be retried. * * Set to `true` for worlds running inside a managed serverless platform * (e.g. `world-vercel`) where the platform fails the invocation when the * function process exits non-zero, and the queue redelivers the message * via a separate fresh invocation. * * Set to `false` (the default) for in-process worlds (e.g. `world-local`, * dev servers) where calling `process.exit()` would terminate the host * process — including the user's `pnpm dev` — without producing a * redelivery. Such worlds should instead surface failures via the event * log and return normally. * * The core runtime reads this when deciding how to handle an exhausted * replay budget: when `true` it exits so the queue redelivers; when * `false` it writes `run_failed` best-effort and returns. See * `packages/core/src/runtime/replay-budget.ts`. */ processExitTriggersQueueRedelivery?: boolean; /** * A function that will be called to start any background tasks needed by the World implementation. * For example, in the case of a queue backed World, this would start the queue processing. */ start?(): Promise; /** * Release any resources held by the World implementation (connection pools, listeners, etc.). * After calling `close()`, the World instance should not be used again. * * This is important for CLI commands and short-lived processes that need to exit cleanly * without relying on `process.exit()`. */ close?(): Promise; /** * Resolve the most recent deployment ID for the current deployment's environment. * * Used when `deploymentId: 'latest'` is passed to `start()`. The implementation * determines the latest deployment that shares the same environment (e.g., same * "production" target or same git branch for "preview" deployments) as the * current deployment. * * Not all World implementations support this — it is only implemented by * world-vercel where deployment routing is meaningful. */ resolveLatestDeploymentId?(): Promise; /** * Retrieve the AES-256 encryption key for a specific workflow run. * * The returned key is a ready-to-use 32-byte AES-256 key. The World * implementation handles all key retrieval and derivation internally * (e.g., HKDF from a deployment key). The core encryption module uses * this key directly for AES-GCM encrypt/decrypt operations. * * Two overloads: * * - `getEncryptionKeyForRun(run)` — Preferred. Pass a `WorkflowRun` when * the run entity already exists. The World reads any context it needs * (e.g., `deploymentId`) directly from the run. * * - `getEncryptionKeyForRun(runId, context?)` — Used when the run entity * is not locally available, such as `start()` before run creation or a * forwarded writable stream carrying its owning deployment context. The * `context` parameter carries opaque world-specific data (e.g., * `{ deploymentId }` for world-vercel) needed to resolve the correct key. * When `context` is omitted, the World assumes the current deployment. * * When not implemented, encryption is disabled — data is stored unencrypted. */ getEncryptionKeyForRun?(run: WorkflowRun): Promise; getEncryptionKeyForRun?(runId: string, context?: Record): Promise; } //# sourceMappingURL=interfaces.d.ts.map