import { s as LifecycleCapability } from "./capability-runner-BUBa6Ake.js";

//#region src/streams/types.d.ts
/**
 * JSON-serializable data accepted as stream chunks and metadata.
 *
 * @experimental The API surface may change before stabilizing.
 */
type StreamJson =
  | string
  | number
  | boolean
  | null
  | StreamJson[]
  | {
      [key: string]: StreamJson;
    };
/**
 * States a stream moves through. A stream is `streaming` from `open()` until
 * its producer settles it; both terminal states keep the chunk log readable.
 *
 * @experimental The API surface may change before stabilizing.
 */
type StreamState = "streaming" | "completed" | "errored";
/**
 * One durable chunk. `seq` is the stream's monotonic cursor: 0-based,
 * assigned at append time, and stable across replays.
 *
 * @experimental The API surface may change before stabilizing.
 */
interface StreamChunk {
  readonly seq: number;
  readonly chunk: StreamJson;
}
/**
 * Read-only status of one stream — the recovery-evidence surface a Task's
 * `recover` callback consults.
 *
 * @experimental The API surface may change before stabilizing.
 */
interface StreamStatus {
  streamId: string;
  state: StreamState;
  /** The next sequence number to be assigned == durable chunk count. */
  cursor: number;
  /** Application lookup key assigned at `open()`, when one was. */
  tag?: string;
  metadata?: Record<string, StreamJson>;
  /** Reason recorded by `error()`, when the state is `errored`. */
  error?: string;
  createdAt: number;
  /**
   * Last write activity: advances with every append and with settlement.
   * The liveness signal retention policies key off — a `streaming` stream
   * whose `updatedAt` is old has a producer that stopped appending. (For a
   * live stream this is derived from the chunk log's newest entry; the
   * stored row is only stamped at open and settle.)
   */
  updatedAt: number;
  closedAt?: number;
}
/**
 * Producer handle returned by `Streams.open()`. Appends are synchronous
 * durable writes; a terminal stream rejects further appends.
 *
 * @experimental The API surface may change before stabilizing.
 */
interface StreamWriter {
  readonly streamId: string;
  /** The next sequence number to be assigned. */
  readonly cursor: number;
  /** Durably append one chunk and wake live readers. Returns its `seq`. */
  append(chunk: StreamJson): number;
  /**
   * Settle the stream as completed. No-op if already terminal or deleted:
   * `options.commit` runs only when this call ends the stream.
   */
  close(options?: StreamSettleOptions): void;
  /** Settle the stream as errored. Same no-op contract as {@link close}. */
  error(reason?: string, options?: StreamSettleOptions): void;
}
/**
 * The cutover: settle a stream, run the caller's own synchronous writes
 * (typically persisting the finished message), and discard the stream's
 * rows, all in ONE SQLite transaction. A crash leaves either the live
 * stream or the finished message, never neither. `commit` must not await
 * and must not throw for a reason it wants ignored: a throw rolls the
 * settle back and leaves the stream live.
 *
 * Settlement stays idempotent: on a stream already terminal or deleted,
 * `commit` does not run and nothing is discarded. Events and reader wakeups
 * fire after the transaction commits, never for a rolled-back cutover.
 *
 * @experimental The API surface may change before stabilizing.
 */
interface StreamSettleOptions {
  /** Synchronous writes to commit with the settlement. */
  readonly commit?: () => void;
  /**
   * Delete the stream's rows in the same transaction. The stream ceases
   * to exist (`status()` returns null); readers tailing it end. Use when
   * the chunks have been handed off, so nothing is left to sweep later.
   */
  readonly discard?: boolean;
}
/** Options accepted by `Streams.open()`. */
interface StreamOpenOptions {
  /** JSON metadata retained with the stream. */
  metadata?: Record<string, StreamJson>;
  /**
   * Indexed application lookup key, set once at creation. Deliberately not
   * unique: an operation that produces successive streams (a retried turn, a
   * regenerated reply) stamps each with the same tag, and
   * `list({ tag, limit: 1 })` finds the latest. Reopening a live stream with
   * a *different* tag throws — a config conflict, not a new stream.
   */
  tag?: string;
}
/** Options accepted by `Streams.read()`. */
interface StreamReadOptions {
  /** First sequence number to yield (inclusive). Defaults to 0. */
  from?: number;
  /** Abort a read that is tailing a live stream. */
  signal?: AbortSignal;
}
/** Options accepted by `Streams.readBatches()`. */
interface StreamReadBatchesOptions extends StreamReadOptions {
  /** Maximum chunks per yielded batch. Defaults to 100. */
  batchSize?: number;
  /**
   * Invoked once, the first time the reader reaches the durable tail —
   * i.e. every chunk stored so far has been yielded. Distinct from the
   * stream ending: a live stream is "up to date" while tailing. Useful as a
   * transition signal (flush replayed UI, show a live indicator).
   */
  onUpToDate?: () => void;
}
/** Filters accepted by `Streams.list()`. */
interface StreamListOptions {
  state?: StreamState | StreamState[];
  /** Only streams opened with this exact tag (indexed). */
  tag?: string;
  limit?: number;
}
/**
 * @internal Raw `cf_agents_streams` SQLite row.
 *
 * While `state` is `streaming`, `chunk_count` and `updated_at` are NOT
 * maintained per append (appends write only the chunk log; the log's tail
 * is authoritative — see `Streams.#tail`). Both are stamped exact by the
 * settle UPDATE, so terminal rows read straight through. Consumers of a
 * live row must derive cursor/liveness rather than trust these columns.
 */
type StreamRow = {
  stream_id: string;
  state: StreamState;
  tag: string | null;
  metadata: string | null;
  error_message: string | null;
  chunk_count: number;
  created_at: number;
  updated_at: number;
  closed_at: number | null;
};
/** @internal One chunk as read back from a `cf_agents_stream_blocks` row. */
type StreamChunkRow = {
  stream_id: string;
  seq: number;
  chunk: string;
  created_at: number;
};
//#endregion
//#region src/streams/streams.d.ts
/** Default ceiling for one serialized chunk (1 MiB). */
declare const DEFAULT_MAX_CHUNK_BYTES = 1048576;
/**
 * Policy for a Streams capability.
 *
 * @experimental The API surface may change before stabilizing.
 */
interface StreamsOptions {
  /** Ceiling for one serialized chunk. Default: 1 MiB. */
  readonly maxChunkBytes?: number;
}
/**
 * @internal Synchronous operations returned by
 * {@link Streams.__DO_NOT_USE_WILL_BREAK__sync}. For same-isolate first-party
 * machinery only (the chat `ResumableStream` adapter); every method bypasses
 * `lifecycle.ready()`, so the caller owns startup ordering.
 */
interface StreamsSyncInternal {
  /** Idempotent DDL — safe to call before the Lifecycle starts. */
  ensureTables(): void;
  getStream(streamId: string): StreamRow | undefined;
  /** Insert a live stream row (no idempotency — caller checks first). */
  insertStream(
    streamId: string,
    tag: string | null,
    metadata: Record<string, StreamJson> | undefined
  ): void;
  /** The read-fenced append: one chunk insert at the log tail, reader wakeup. */
  append(streamId: string, chunk: StreamJson): number;
  /**
   * The newest chunk's timestamp, or null for an empty log. One PK-served
   * read — the per-append liveness signal retention sweeps verify against
   * (a live row's `updated_at` is set at open and not bumped by appends).
   */
  lastChunkAt(streamId: string): number | null;
  /**
   * Segments durably appended so far: the chunk log's tail, read in the
   * calling synchronous block. Zero for an unknown stream.
   */
  cursor(streamId: string): number;
  /**
   * Observe every deletion of a stream's rows — the public `delete()`, the
   * aperture's own deletes, and a cutover's discard — with the row and its
   * cursor as they were just before removal, in the same synchronous block
   * (and, for a cutover, the same transaction). Hooks must be synchronous
   * and must not await: the cutover runs them inside `transactionSync`.
   * The chat adapter uses this to keep its recovery progress marker exact
   * however a chat row leaves the table. Returns the unsubscribe: an owner
   * constructed again (a host whose startup retried) must drop its earlier
   * hook, or a deletion is observed once per construction.
   */
  onDelete(hook: (row: StreamRow, cursor: number) => void): () => void;
  /**
   * Idempotent settlement with events and reader wakeup. With `options`,
   * the settle, the caller's `commit` writes and the log discard run in
   * one SQLite transaction (see {@link StreamSettleOptions}). Returns
   * whether the stream transitioned; on a repeat or a deleted stream the
   * `commit` callback does not run.
   */
  settle(
    streamId: string,
    state: "completed" | "errored",
    reason: string | null,
    options?: StreamSettleOptions
  ): boolean;
  /** Delete a stream and its chunks regardless of state. */
  deleteUnchecked(streamId: string): void;
  /** Delete many streams and their chunks regardless of state, silently. */
  deleteMany(streamIds: string[]): void;
  /**
   * One page of a stream's chunk log from `fromSeq` (inclusive), ordered by
   * seq. Paged rather than read-it-all so replaying a large stream holds
   * one page of segment bodies in memory, not the whole turn.
   */
  readChunks(
    streamId: string,
    fromSeq: number,
    limit: number
  ): StreamChunkRow[];
  /** Every stream row, newest first (created_at, then insertion order). */
  listRows(): StreamRow[];
  /**
   * Every row carrying a tag, newest first, optionally narrowed to one
   * state. Tags are non-unique and the table is shared across producers,
   * so callers apply their own ownership filter (e.g. chat's metadata
   * marker) rather than trusting the newest row.
   */
  rowsByTag(tag: string, state?: StreamState): StreamRow[];
  /**
   * Import one historical stream row verbatim (migrations, test seeding):
   * explicit timestamps and count, no events, no wakeups.
   */
  importStream(row: {
    streamId: string;
    state: StreamState;
    tag: string | null;
    metadata: Record<string, StreamJson> | undefined;
    chunkCount: number;
    createdAt: number;
    updatedAt: number;
    closedAt: number | null;
  }): void;
  /**
   * Import one historical chunk at the log's tail: one INSERT, nothing else.
   * The stream row is not touched — importers pass the final `chunkCount`
   * and `updatedAt` to {@link importStream}, so the row is exact at rest
   * without a per-chunk row write.
   */
  importChunk(streamId: string, chunk: StreamJson, createdAt: number): void;
}
/**
 * Durable incremental output for a Lifecycle Object.
 *
 * `open()` a stream, `append()` chunks (synchronous durable writes that wake
 * live readers), and settle it with `close()` or `error()`. `read()` replays
 * persisted chunks from a cursor and then tails live appends; `status()`
 * reports the state and cursor — the recovery evidence a Task's `recover`
 * callback consults after its producer was interrupted.
 *
 * @experimental The API surface may change before stabilizing.
 */
declare class Streams extends LifecycleCapability {
  #private;
  constructor(options?: StreamsOptions);
  /** Migrate stream storage during Lifecycle startup. */
  onStart(): Promise<void>;
  /**
   * Open a stream for writing. Idempotent on the id: reopening a live stream
   * returns a writer positioned at its current cursor; reopening a terminal
   * stream throws {@link StreamClosedError}.
   */
  open(streamId: string, options?: StreamOpenOptions): Promise<StreamWriter>;
  /**
   * Replay persisted chunks from `from` (inclusive), then tail live appends
   * until the stream settles. Ends when the stream reaches a terminal state
   * and every durable chunk has been yielded; a read of an `errored` stream
   * still yields its chunks and then simply ends — consult {@link status}
   * for the terminal outcome. Aborting `options.signal` throws its reason.
   */
  read(
    streamId: string,
    options?: StreamReadOptions
  ): AsyncGenerator<StreamChunk, void, undefined>;
  /**
   * Batched form of {@link read}: yields non-empty arrays of consecutive
   * chunks instead of one chunk at a time. Replay yields up to
   * `options.batchSize` chunks per array; a live tail yields everything
   * that accumulated since the last wakeup as one array — so a consumer
   * paying per write (an SSE flush, an RPC hop, a history append) pays
   * once per backlog, not once per chunk. Same lifecycle as {@link read}:
   * ends when the stream settles and every durable chunk has been
   * yielded; aborting `options.signal` throws its reason.
   */
  readBatches(
    streamId: string,
    options?: StreamReadBatchesOptions
  ): AsyncGenerator<StreamChunk[], void, undefined>;
  /** Read one stream's state and cursor, or null when it does not exist. */
  status(streamId: string): Promise<StreamStatus | null>;
  /** List streams, newest first. */
  list(options?: StreamListOptions): Promise<StreamStatus[]>;
  /**
   * Delete one terminal stream and its chunk log.
   *
   * @returns True when a terminal stream was deleted; false when none
   * exists. Throws on a live stream — settle it first.
   */
  delete(streamId: string): Promise<boolean>;
  /**
   * @internal Synchronous storage operations for same-isolate first-party
   * machinery — today the chat `ResumableStream` adapter, whose whole public
   * surface is synchronous and constructed before the Lifecycle starts.
   * Bypasses `lifecycle.ready()`: the caller owns startup ordering. The
   * invariant-bearing writes (append fence, settlement, wakeups, events) go
   * through the same private methods as the public API, so live readers and
   * diagnostics observe aperture writes exactly like capability writes. Will
   * break without notice; never use from application code.
   */
  __DO_NOT_USE_WILL_BREAK__sync(): StreamsSyncInternal;
}
//#endregion
export {
  StreamJson as a,
  StreamReadBatchesOptions as c,
  StreamState as d,
  StreamStatus as f,
  StreamChunk as i,
  StreamReadOptions as l,
  Streams as n,
  StreamListOptions as o,
  StreamWriter as p,
  StreamsOptions as r,
  StreamOpenOptions as s,
  DEFAULT_MAX_CHUNK_BYTES as t,
  StreamSettleOptions as u
};
//# sourceMappingURL=streams-BcE8JP2X.d.ts.map
