first commit
This commit is contained in:
@@ -0,0 +1,69 @@
|
||||
# from-array
|
||||
|
||||
<!-- begin:auto-docs -->
|
||||
_(no submodules)_
|
||||
<!-- end:auto-docs -->
|
||||
## Purpose
|
||||
|
||||
Converts a JavaScript array into a WHATWG `ReadableStream`. Each array element is enqueued as a separate chunk in index order. The stream is closed automatically after all elements are pushed. This factory is the simplest entry point for creating a stream from in-memory data and is the building block for test fixtures and benchmark pipelines throughout the package.
|
||||
|
||||
The `highWaterMark` option controls the WHATWG backpressure queue depth. Keeping it at the default (`1`) applies maximum backpressure, ensuring the consumer controls the pull rate. Higher values pre-buffer more chunks, which is useful when the consumer is consistently slower than the source.
|
||||
|
||||
## Features
|
||||
|
||||
- Converts any `T[]` to `ReadableStream<T>`
|
||||
- `AbortSignal` support: errors the stream immediately when the signal fires
|
||||
- Configurable `highWaterMark` via `ReadableOptions`
|
||||
- Zero external runtime dependencies
|
||||
|
||||
## Usage: Basic Example
|
||||
|
||||
```ts
|
||||
import { fromArray } from "@suaveplan/streams/readable/from-array/from-array";
|
||||
|
||||
const stream = fromArray([1, 2, 3]);
|
||||
const reader = stream.getReader();
|
||||
|
||||
let result;
|
||||
while (!(result = await reader.read()).done) {
|
||||
console.log(result.value); // 1, 2, 3
|
||||
}
|
||||
```
|
||||
|
||||
## Usage: Advanced Example
|
||||
|
||||
```ts
|
||||
import { fromArray } from "@suaveplan/streams/readable/from-array/from-array";
|
||||
import { mapStream } from "@suaveplan/streams/transforms/map-stream/map-stream";
|
||||
import { toArray } from "@suaveplan/streams/sinks/to-array/to-array";
|
||||
|
||||
const ac = new AbortController();
|
||||
const stream = fromArray(["a", "b", "c"], { signal: ac.signal, highWaterMark: 4 });
|
||||
const result = await toArray(stream.pipeThrough(mapStream((x) => x.toUpperCase())));
|
||||
console.log(result); // ["A", "B", "C"]
|
||||
|
||||
// Cancellation: abort mid-flight
|
||||
const longStream = fromArray(new Array(1_000_000).fill(0), { signal: ac.signal });
|
||||
ac.abort();
|
||||
const reader = longStream.getReader();
|
||||
const { done } = await reader.read().catch(() => ({ done: true }));
|
||||
console.log(done); // true (stream was aborted)
|
||||
```
|
||||
|
||||
## API Reference
|
||||
|
||||
### `fromArray<T>(items: T[], options?: ReadableOptions): ReadableStream<T>`
|
||||
|
||||
**Parameters**:
|
||||
|
||||
- `items` — the source array; elements are enqueued in insertion order.
|
||||
- `options.signal` — optional `AbortSignal`; errors the stream on abort.
|
||||
- `options.highWaterMark` — WHATWG queue depth (default: `1`).
|
||||
|
||||
**Returns**: `ReadableStream<T>` that emits each element and then closes.
|
||||
|
||||
**Throws**: never directly; the stream's reader will throw the abort reason when the signal fires.
|
||||
|
||||
## Implementation Notes
|
||||
|
||||
The `pull` callback checks `signal.aborted` on every pull cycle rather than using an `abort` event listener. This avoids the need to clean up listeners and keeps the implementation leak-free. When the signal fires between two pull cycles the worst case is one additional chunk being enqueued before the abort is detected — this is acceptable because WHATWG streams do not guarantee atomic cancellation at the chunk boundary.
|
||||
Reference in New Issue
Block a user