The event stream
Why a stitch returns an async iterable of typed events — start, progress, drift, result, done — instead of Promise<bytes>.
A stitch returns an async iterable of typed events —
start → progress → drift → result → done — not Promise<bytes>. Awaiting it
gives you just the final value; iterating its stream gives you everything that
happened on the way there.
Why it's shaped this way
A single Promise<bytes> collapses a call to two outcomes — it resolved, or it
threw — and throws away the story in between: the retry that succeeded on the
third attempt, the throttle that paused for 400ms, the field that silently
changed shape. That story is exactly what an agent needs to reason about a call,
and what an operator needs to debug one.
So a stitch is a single source that you can read at the altitude you need:
import { } from 'stitchapi';
const = ({ : 'https://api.example.com', : '/search' });
// Await it for just the value…
const = await ({ : { : 'mango' } });
// …or iterate the typed event stream for everything that happened.
for await (const of ({ : { : 'mango' } }).()) {
if (. === 'progress') .(., .);
if (. === 'drift')
.(.., ..);
if (. === 'result') .(.);
}The events form a fixed spine — start, then any number of progress (auth,
throttle, retry, pagination) and drift findings, then exactly one terminal
result or error, then done. The union is discriminated on type, so
narrowing one field tells the compiler the shape of the rest.
How it relates
The stream is what every cross-cutting feature reports through:
retry, throttle,
and auth emit progress; leveled drift emits
drift. It is also the seam observability plugs into — a
trace sink is just a consumer of these
same events, which is how console logs, JSONL, and
OTLP spans all come from one source without
the call site knowing.