Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 12 additions & 0 deletions incubation-js.md
Original file line number Diff line number Diff line change
Expand Up @@ -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<string>` yielding safely decoded text chunks.
* `mapStream`: A `ReadableStream<Object>` yielding the Index Shift Map JS objects (with `hydrated-start`, `original-start`, etc.).
* `bodyStream`: A `ReadableStream<Uint8Array>` 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**.
Expand All @@ -20,6 +22,16 @@ This document captures the formal architectural decisions and API designs specif
## 1.1 Implementation Blueprint

```javascript
/**
* @param {ReadableStream<Uint8Array | string>} templateStream
* @param {Object} [data={}]
* @param {Array<ReadableStream<Uint8Array> | Blob | any>} [streams=[]]
* @returns {{
* resolvedStream: ReadableStream<string>,
* mapStream: ReadableStream<object>,
* bodyStream: ReadableStream<Uint8Array>
* }}
*/
export function hydrate(templateStream, data = {}, streams = []) {
let resolvedController, mapController, bodyController;

Expand Down