Skip to content

API reference > @kontsedal/olas-react > createStreamingTransform

createStreamingTransform() function ​

Web-Streams transformer that interleaves flush() output into an HTML stream. Wraps renderToReadableStream (or any otherReadableStream<Uint8Array> producing HTML), so each batch of entries that resolved reaches the client as the stream goes.

A batch goes only where React's hydration never sees it: directly inside<body> for a whole document, or at the top level for a fragment React hydrates into a container, outside every <Suspense> boundary's content, and right after a tag or a comment. So never inside a tag, an attribute, a comment, raw text or a text node, and never inside an element React hydrates. React writes in fixed-size chunks, which can end anywhere, so the transform tracks the markup it passes through (htmlBoundary). Each chunk gets the pending batch at its first such point, so data goes out before the markup that reads it. A chunk with no such point holds the batch; entries keep collecting in the hydrator meanwhile, so the held batch goes out whole.

Pipe React's own stream through the transform, and put any HTML template of your own around its output. A template inside the transform puts the page inside an element the transform cannot tell from React's, and every batch waits for the end.

Works in Node, the Edge runtime, Cloudflare Workers, Deno, and the browser — anywhere Web Streams are available.

tsx
const { plugin, flush } = createStreamingHydrator()

// One root per request, carrying the plugin, and the SAME root renders.
// A plugin on a root nothing renders captures no entries. The root needs a
// query engine, or there is no cache to capture. On the server, render
// through `OlasProvider`: a `HydrationBoundary` builds its root in render
// and disposes it in an effect, and effects do not run on the server.
const root = createRoot(appDef, { deps, queries: queryEngine(), plugins: [plugin] })
const stream = await renderToReadableStream(
  <OlasProvider root={root}>
    <App />
  </OlasProvider>,
  { bootstrapScriptContent: OLAS_BOOTSTRAP_SCRIPT },
)
const interleaved = stream.pipeThrough(createStreamingTransform(flush))
return new Response(interleaved, { headers: { 'content-type': 'text/html' } })

The transformer drains one final time on close, so entries that settled after the last chunk still reach the client. A stream that ends inside markup gets no final batch, since no script can go there.

Signature:

typescript
export declare function createStreamingTransform(flush: () => string): TransformStream<Uint8Array, Uint8Array>;

Parameters ​

Parameter

Type

Description

flush

() => string

Returns:

TransformStream<Uint8Array, Uint8Array>

Released under the MIT License.