/**
 * data-stream — attribute-driven data ingestion, signal-backed.
 *
 * Public API surface: read the shared registry (`streams`) or await a
 * stream's registration (`whenStream`). The internal MutationObserver
 * + transport machinery (HTTP / SSE / WS / JSON / CSV / TSV / JSONL /
 * text) is implementation-only — consumers see the signal + the events
 * (`stream-load`, `stream-error`) on the element.
 *
 * @see ../USAGE.md
 */

import type { ReadonlySignal, Signal } from './signals.js';

/**
 * One entry in the shared streams registry. `signal.value` carries the
 * parsed payload (shape depends on the transport's `parse` option).
 * `refs` is the active subscriber count; the registry tears the entry
 * down when it returns to 0.
 */
export interface StreamEntry {
  /** Signal whose `.value` carries the parsed payload. Subscribe with `effect()`. */
  signal: ReadonlySignal<unknown>;
  /** Active subscriber count. */
  refs: number;
  /** Transport metadata — opaque to consumers. */
  transport: unknown;
  /** Resolved options for the stream — opaque to consumers. */
  opts: unknown;
}

/**
 * Read-only public view of the streams registry. App code can do:
 *
 *     import { streams } from '@adia-ai/web-components/core/data-stream';
 *     streams.get('rev')?.signal.value
 *
 * Subscribe via `effect()` on the entry's `signal`.
 */
export const streams: {
  get(id: string): StreamEntry | undefined;
  has(id: string): boolean;
  keys(): MapIterator<string>;
  size(): number;
};

/**
 * Resolves with the stream entry once it's registered. If the stream
 * already exists, resolves synchronously on the next microtask; if not,
 * resolves the moment the first DOM consumer (or any caller of
 * acquireStream) creates it. Useful for cross-package adapters
 * (streams-bridge, A2UI surfaces) that may run before the DOM source
 * has connected. The promise never rejects — pair with AbortSignal at
 * the caller if you need cancellation.
 */
export function whenStream(id: string): Promise<StreamEntry>;
