diff --git a/incubation-js.md b/incubation-js.md index 542f229..a790c21 100644 --- a/incubation-js.md +++ b/incubation-js.md @@ -9,9 +9,11 @@ This document captures the formal architectural decisions and API designs specif * **Polymorphic Inputs** * To support Node.js, Deno, and the Browser, the `template` input must support polymorphic types: `String` (for in-memory DX), `ReadableStream` (the Web standard), and `AsyncIterable` (for universal compatibility). * **Triple Stream Output (The Plain Object Signature)** + * To output both the resolved text and the source map without breaking the single-pass rule, the `hydrate` function will return a structured plain object: `{ resolvedStream, mapStream, bodyStream }`. * `resolvedStream`: A `ReadableStream` yielding safely decoded text chunks. * `mapStream`: A `ReadableStream` yielding the Index Shift Map JS objects (with `hydrated-start`, `original-start`, etc.). * `bodyStream`: A `ReadableStream` yielding raw binary byte chunks for the network handoff. + * This avoids anti-patterns like attaching custom subfields to a single stream object and makes downstream consumer routing trivial via destructuring. * **Synchronous Stream Composition & Detached Processing** * **Synchronous Return (Early Return):** The core `hydrate` function must be entirely synchronous (i.e., drop the `async` keyword from the main signature). It must immediately instantiate the `ReadableStream` objects and return the `{ resolvedStream, mapStream, bodyStream }` object before any data is actually read. This is the gold standard for stream pipelines, allowing downstream consumers to synchronously wire up their entire pipeline (e.g., `.pipeTo()`) in a single execution tick without blocking `await` calls. * **Detached Background Worker:** The actual stream consumption, chunk processing, and state machine logic must be pushed into a detached, background asynchronous function. This function is invoked by the main `hydrate` function but **never awaited**. @@ -20,6 +22,16 @@ This document captures the formal architectural decisions and API designs specif ## 1.1 Implementation Blueprint ```javascript +/** + * @param {ReadableStream} templateStream + * @param {Object} [data={}] + * @param {Array | Blob | any>} [streams=[]] + * @returns {{ + * resolvedStream: ReadableStream, + * mapStream: ReadableStream, + * bodyStream: ReadableStream + * }} + */ export function hydrate(templateStream, data = {}, streams = []) { let resolvedController, mapController, bodyController;