Files
skills/docs/foundation/flow/streams/src/utils/stream/create-data-stream/create-data-stream.md
2026-05-29 08:20:56 +01:00

2.7 KiB

createDataStream

(no submodules)

Purpose

createDataStream is the canonical bridge from "I have a typed in-memory value" to "I have a ReadableStream<Uint8Array>". It is the read-side counter to processDataStream: each accepts a transformer that bridges between the domain type T and the byte representation, and they compose cleanly when a pipeline needs to enter and leave the byte world without callers spelling out the encode/decode boilerplate.

The transformer runs once when the function is called. The function returns a Promise<ReadableStream<Uint8Array>> so that asynchronous serialisation (JSON.stringify of a complex value, msgpack encoding, gzip pre-compression) fits naturally into the call signature without forcing every consumer to wrap the producer in a start() callback.

Features

  • Sync and async transformer functions both supported.
  • Pluggable chunk size via the underlying uint8ArrayToStream.
  • Type-safe generic input — the compiler infers T from the value supplied.
  • Propagates transformer errors as the rejection of the returned promise.

Usage: Basic Example

import { createDataStream } from "@suaveplan/streams/utils/stream/create-data-stream/create-data-stream";

const stream = await createDataStream(
    { hello: "world" },
    (obj) => new TextEncoder().encode(JSON.stringify(obj))
);

Usage: Advanced Example

import { createDataStream } from "@suaveplan/streams/utils/stream/create-data-stream/create-data-stream";
import { encode } from "@msgpack/msgpack";

interface Telemetry {
    ts: number;
    metrics: Record<string, number>;
}

async function telemetryStream(t: Telemetry) {
    return createDataStream<Telemetry>(t, (v) => encode(v), {
        chunkSize: 4096,
    });
}

const stream = await telemetryStream({
    ts: Date.now(),
    metrics: { rps: 42, p99: 18.7 },
});

API Reference

createDataStream<T>(data, transformer, options?)

  • data: T — value to serialise.
  • transformer: (data: T) => Uint8Array | Promise<Uint8Array> — encoder.
  • options?: { chunkSize?: number } — emission chunk size, forwarded to uint8ArrayToStream.
  • Returns — Promise<ReadableStream<Uint8Array>>.
  • Throws — anything the transformer throws (rejected promise).

Implementation Notes

  • The transformer runs exactly once before the stream is constructed, so the byte count is known up-front; this lets downstream sinks pre-allocate when they want to.
  • The function does not accept an AbortSignal — cancellation belongs to the drain side (streamToUint8Array, processDataStream) where it can actually influence work in flight.
  • Universal: zero environment dependencies.