@solidrt/flux-types 0.0.70 → 0.0.71

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -51,9 +51,11 @@ rely on must be named.
51
51
  `flux:camera`, `flux:microphone`, `flux:audio`, `flux:gpu`, `flux:spatial`,
52
52
  `flux:font`.
53
53
  - Web-standard globals: `console`, `fetch` + `Headers`/`Request`/`Response`,
54
+ `ReadableStream`/`WritableStream`/`TransformStream`,
55
+ `CompressionStream`/`DecompressionStream`,
54
56
  `setTimeout`/`setInterval`/`setImmediate`/`requestIdleCallback`/`queueMicrotask`, `performance`, `WebSocket`,
55
- `TextEncoder`/`TextDecoder`, `crypto.subtle.digest`. These are deliberate subsets matching exactly what
56
- the runtime implements.
57
+ `TextEncoder`/`TextDecoder` and `TextEncoderStream`/`TextDecoderStream`, `crypto.subtle.digest`.
58
+ These are deliberate subsets matching exactly what the runtime implements.
57
59
  - GUI globals (gui-enabled runtime only): `requestAnimationFrame` /
58
60
  `cancelAnimationFrame` (web-standard names, so kept global).
59
61
 
@@ -212,15 +212,25 @@ declare module "flux:rendertree" {
212
212
  */
213
213
  export function prepareText(text: string, options?: MeasureTextOptions): PreparedText
214
214
  /**
215
- * Make the glyph cells of printable ASCII for these font styles ahead of
216
- * their first use, on the engine's worker thread: the type scale an app
217
- * draws its screens in, called at startup under the splash, so a first
218
- * paint in any of them never waits for cells. Each entry names a font
219
- * (family, size, weight, style) as a `<text>` would; `lineHeight`,
220
- * `maxLines`, `carets` and `runs` are ignored. Glyphs outside ASCII are
221
- * made at first use.
215
+ * One font to warm for {@link warmText}: a font (family, size, weight,
216
+ * style) as a `<text>` names it, and optionally a string the app will
217
+ * draw in it.
222
218
  */
223
- export function warmText(styles: MeasureTextOptions[]): void
219
+ export type WarmTextEntry = MeasureTextOptions & { text?: string }
220
+ /**
221
+ * Make glyph cells ahead of their first use, on the engine's worker
222
+ * thread: the type scale an app draws its screens in, called at startup
223
+ * under the splash, so a first paint in any of them does not stop to
224
+ * make them. A cell a text needs that is not in the atlas is made in
225
+ * that frame, so text never draws with glyphs missing; warming only
226
+ * moves that work ahead of time. Each entry names a font as a `<text>`
227
+ * would (`lineHeight`, `maxLines`, `carets` and `runs` are ignored) and
228
+ * warms its printable ASCII; an entry with a `text` also warms the
229
+ * glyphs that string shapes to in the font, a ligature, a curly quote or
230
+ * a letter beyond ASCII included, on whichever face covers it. Anything
231
+ * else is made at first use.
232
+ */
233
+ export function warmText(entries: WarmTextEntry[]): void
224
234
  /** How every text is rendered, for {@link setTextRendering}. */
225
235
  export interface TextRenderingOptions {
226
236
  /**
package/index.d.ts CHANGED
@@ -16,10 +16,13 @@
16
16
 
17
17
  // Web-standard globals. The runtime is QuickJS, not a browser or Node, so it
18
18
  // ships no lib.dom / @types/bun: these declarations are the sole source for
19
- // console, fetch, the Fetch types, timers, WebSocket, the encoders, and crypto.
19
+ // console, fetch, the Fetch types, the streams, the compression streams,
20
+ // timers, WebSocket, the encoders, and crypto.
20
21
  /// <reference path="./standards/console.d.ts" />
21
22
  /// <reference path="./standards/time.d.ts" />
22
23
  /// <reference path="./standards/text.d.ts" />
24
+ /// <reference path="./standards/streams.d.ts" />
25
+ /// <reference path="./standards/compression.d.ts" />
23
26
  /// <reference path="./standards/base64.d.ts" />
24
27
  /// <reference path="./standards/fetch.d.ts" />
25
28
  /// <reference path="./standards/websocket.d.ts" />
package/modules/net.d.ts CHANGED
@@ -68,27 +68,41 @@ declare module "flux:net" {
68
68
  }
69
69
 
70
70
  /**
71
- * A connected TCP stream: a byte duplex. It is its own async iterator, so
72
- * `for await (let chunk of conn)` reads it until end-of-stream.
71
+ * A connected TCP stream: a byte duplex as a `readable`/`writable` pair of
72
+ * web streams, the shape sockets have in every runtime with web streams.
73
+ * `for await (let chunk of conn.readable)` reads it, `conn.readable
74
+ * .pipeTo(other.writable)` is one half of a proxy, and a pipe carries the
75
+ * half-close: when the source ends, the destination's write side closes.
73
76
  */
74
- export class Conn implements AsyncIterable<Uint8Array> {
77
+ export class Conn {
75
78
  /** The remote peer's address, e.g. "192.168.2.37:445". */
76
79
  readonly remoteAddr: string
77
- /** Write all of `data`. Resolves once it is handed to the OS. */
78
- write(data: string | Uint8Array): Promise<void>
79
80
  /**
80
- * Half-close: flush and end the write side, so the peer sees end-of-stream
81
- * while this side keeps reading until the peer closes. The way to signal
82
- * "request done" to protocols that answer after EOF. After it, {@link write}
83
- * throws. Idempotent, and a no-op once the connection is closed.
81
+ * What the peer sends, one chunk per read, pulled only as far as it is
82
+ * read. Ends when the peer ends its write side or closes, or on
83
+ * {@link close}; errors with the reason after `writable.abort(reason)`.
84
+ * `cancel()` stops reading and releases the read half: the write side
85
+ * stays usable and the connection stays open until {@link close}.
84
86
  */
85
- closeWrite(): Promise<void>
87
+ readonly readable: ReadableStream<Uint8Array>
86
88
  /**
87
- * Close the connection now: a pending read ends, the peer sees end-of-stream
88
- * at once. Bytes already handed to the OS still flush.
89
+ * What to send: strings (as UTF-8) or `Uint8Array`s. A write resolves
90
+ * once the OS took the bytes, so a producer faster than the peer reads
91
+ * sees backpressure. `close()` is the half-close: it flushes and ends the
92
+ * write side, so the peer sees end-of-stream while this side keeps
93
+ * reading until the peer closes (the way to say "request done" to a
94
+ * protocol that answers after EOF); a later write rejects. `abort(reason)`
95
+ * tears the connection down with an error: a pending or later read of
96
+ * {@link readable} rejects with the reason. TCP has no abortive
97
+ * half-close, so the peer still sees a plain end-of-stream.
98
+ */
99
+ readonly writable: WritableStream<string | Uint8Array>
100
+ /**
101
+ * Close the connection now: a pending read ends, a pending write rejects,
102
+ * the peer sees end-of-stream at once. Bytes already handed to the OS
103
+ * still flush.
89
104
  */
90
105
  close(): void
91
- [Symbol.asyncIterator](): AsyncIterator<Uint8Array>
92
106
  }
93
107
 
94
108
  /**
package/modules/p2p.d.ts CHANGED
@@ -47,19 +47,39 @@ declare module "flux:p2p" {
47
47
  }
48
48
 
49
49
  /**
50
- * A single bidirectional p2p stream: a byte duplex. It is its own async
51
- * iterator, so `for await (let chunk of stream)` reads the recv half.
50
+ * A single bidirectional p2p stream: a byte duplex as a `readable`/`writable`
51
+ * pair of web streams, the same shape as a `flux:net` `Conn`, so
52
+ * `stream.readable.pipeTo(conn.writable)` bridges the two.
52
53
  */
53
- export class P2pStream implements AsyncIterable<Uint8Array> {
54
+ export class P2pStream {
54
55
  /** The remote peer's endpoint id. */
55
56
  readonly remoteId: string
56
- /** Queue bytes on the send half. */
57
- write(data: string | Uint8Array): void
58
- /** Half-close: end the send half (QUIC FIN) after queued writes flush. The recv half stays open. */
59
- closeWrite(): void
60
- /** Tear the stream down: end the send half and stop reading. */
57
+ /**
58
+ * What the peer sends, one chunk per read, pulled only as far as it is
59
+ * read. Ends when the peer finishes its send half or closes, or on
60
+ * {@link close}; errors when the peer resets the stream, and with the
61
+ * reason after `writable.abort(reason)`. `cancel()` stops reading and
62
+ * releases the recv half, which tells the peer to stop sending (its
63
+ * writes reject); the send side stays usable until {@link close}.
64
+ */
65
+ readonly readable: ReadableStream<Uint8Array>
66
+ /**
67
+ * What to send: strings (as UTF-8) or `Uint8Array`s. A write resolves
68
+ * once the transport took the bytes, paced by QUIC flow control, so a
69
+ * producer faster than the peer reads sees backpressure; a write to a
70
+ * peer that went away or stopped reading rejects. `close()` finishes the
71
+ * send half (QUIC FIN): the peer sees end-of-stream, the recv half stays
72
+ * open for replies, and a later write rejects. `abort(reason)` resets the
73
+ * send half and tears the stream down with an error: the peer's read
74
+ * fails instead of ending, and a pending or later read of
75
+ * {@link readable} here rejects with the reason.
76
+ */
77
+ readonly writable: WritableStream<string | Uint8Array>
78
+ /**
79
+ * Tear the stream down: a pending read ends, the recv half is released and
80
+ * the send half finished.
81
+ */
61
82
  close(): void
62
- [Symbol.asyncIterator](): AsyncIterator<Uint8Array>
63
83
  }
64
84
 
65
85
  /** A bound iroh endpoint with a stable keypair. */
@@ -82,11 +102,15 @@ declare module "flux:p2p" {
82
102
  /**
83
103
  * Dial a peer and open one bidirectional stream over `protocol`. `peer` is
84
104
  * either a `ticket` (preferred; connects directly) or a bare endpoint `id`
85
- * (needs discovery to resolve the address).
105
+ * (needs discovery to resolve the address). The peer sees the stream once
106
+ * this side writes to it (see {@link accept}).
86
107
  */
87
108
  connect(peer: string, protocol: string): Promise<P2pStream>
88
109
  /**
89
110
  * An async-iterable of incoming streams whose protocol matches `protocol`.
111
+ * A dialled stream arrives here with its first bytes (a QUIC stream is
112
+ * announced by its data), so the dialer writes first and the acceptor
113
+ * reads first: two sides that both wait for the other never meet.
90
114
  * Iterating ends when the endpoint is closed.
91
115
  */
92
116
  accept(protocol: string): AsyncIterable<P2pStream>
@@ -5,7 +5,11 @@ declare module "flux:subprocess" {
5
5
  cwd?: string
6
6
  /** Extra env vars, added to / overriding the inherited environment. */
7
7
  env?: Record<string, string>
8
- /** Bytes written to the child's stdin, after which stdin is closed. */
8
+ /**
9
+ * Bytes written to the child's stdin first. With {@link Command.output}
10
+ * stdin is closed after them; with {@link Command.spawn} it stays open for
11
+ * the child's `stdin` stream.
12
+ */
9
13
  stdin?: string | Uint8Array
10
14
  /** Kill the child if it has not exited within this many milliseconds. */
11
15
  timeoutMs?: number
@@ -17,7 +21,8 @@ declare module "flux:subprocess" {
17
21
  /**
18
22
  * `spawn()` only: the child outlives this engine and this process. It is
19
23
  * never killed on drop or reload, has no stdin/stdout/stderr pipes (all
20
- * null: `stdout`/`stderr` iterate to nothing, `write` fails) and runs in
24
+ * null: `stdout`/`stderr` end at once, the first write to `stdin`
25
+ * rejects) and runs in
21
26
  * its own process group, so a Ctrl+C to the parent does not reach it.
22
27
  * `pid`, `kill()` and `status()` still work. Cannot combine with `stdin`.
23
28
  * What a dev tool uses to launch another runtime instance.
@@ -53,14 +58,19 @@ declare module "flux:subprocess" {
53
58
  type Child = {
54
59
  /** The OS process id, if available. */
55
60
  pid: number | undefined
56
- /** Live stdout as an async-iterable of byte chunks. */
57
- stdout: AsyncIterable<Uint8Array>
58
- /** Live stderr as an async-iterable of byte chunks. */
59
- stderr: AsyncIterable<Uint8Array>
60
- /** Queue bytes to the child's stdin. Writes serialize and respect backpressure. */
61
- write(data: string | Uint8Array): Promise<void>
62
- /** Half-close: close the child's stdin (after queued writes drain) so it sees EOF. */
63
- closeWrite(): Promise<void>
61
+ /** Live stdout as a stream of byte chunks, read as far as it is consumed. */
62
+ stdout: ReadableStream<Uint8Array>
63
+ /** Live stderr as a stream of byte chunks, read as far as it is consumed. */
64
+ stderr: ReadableStream<Uint8Array>
65
+ /**
66
+ * The child's stdin as a stream: strings (as UTF-8) or `Uint8Array`s,
67
+ * written after any {@link CommandOptions.stdin}. A write resolves once
68
+ * the pipe took the bytes, so a producer faster than the child reads
69
+ * sees backpressure. `close()` (and `abort()`) closes the pipe after the
70
+ * writes so far, so the child sees EOF; a later write rejects. A body
71
+ * piped in (`response.body.pipeTo(child.stdin)`) closes it at the end.
72
+ */
73
+ stdin: WritableStream<string | Uint8Array>
64
74
  /** Request termination (portable; SIGKILL / TerminateProcess). */
65
75
  kill(): void
66
76
  /** Resolves with the exit status when the child exits. */
@@ -73,7 +83,7 @@ declare module "flux:subprocess" {
73
83
  args: string[]
74
84
  /** Run the child to completion, buffering stdout/stderr. */
75
85
  output(): Promise<CommandOutput>
76
- /** Spawn the child and return a handle with live streams, stdin, and control. */
86
+ /** Spawn the child and return a handle with live stdout/stderr, a stdin stream, and control. */
77
87
  spawn(): Child
78
88
  }
79
89
 
package/modules/test.d.ts CHANGED
@@ -114,9 +114,11 @@ declare module "flux:test" {
114
114
  /**
115
115
  * A number within half a unit of the last of `digits` decimal places
116
116
  * (default 2): the difference is below `10 ** -digits / 2`. The way to
117
- * compare floating point results.
117
+ * compare floating point results. An array of numbers (a point, a
118
+ * normal, a motion) compares to one of the same length entry by entry,
119
+ * and a failure prints both arrays whole.
118
120
  */
119
- toBeCloseTo(expected: number, digits?: number): void
121
+ toBeCloseTo(expected: number | readonly number[], digits?: number): void
120
122
 
121
123
  /**
122
124
  * For a function: calling it throws. With a string, the thrown error's
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@solidrt/flux-types",
3
- "version": "0.0.70",
3
+ "version": "0.0.71",
4
4
  "license": "MIT",
5
5
  "funding": "https://github.com/sponsors/wellawaretech",
6
6
  "author": "Antoine van Wel",
@@ -0,0 +1,32 @@
1
+ // The Compression Streams API: CompressionStream and DecompressionStream,
2
+ // TransformStreams over the deflate formats, with the standard's names and
3
+ // shapes. A chunk written in is an ArrayBuffer or a view of one; what comes
4
+ // out is Uint8Arrays of at most 64 KiB each, produced as the reader pulls,
5
+ // so a small input that inflates to a lot never runs ahead of its reader.
6
+ // The codec runs off the JS thread, a step per piece.
7
+ //
8
+ // Errors are the standard's TypeErrors: an unknown format throws from the
9
+ // constructor; a chunk that is not a buffer, corrupt input, input cut short
10
+ // when the writable side closes, and data after the end of the compressed
11
+ // stream (a second gzip member included) error both sides of the stream.
12
+
13
+ /**
14
+ * The formats: `gzip` (RFC 1952), `deflate` (the zlib format, RFC 1950: a
15
+ * two-byte header and an Adler-32 trailer) and `deflate-raw` (RFC 1951, the
16
+ * bare stream, what a ZIP entry holds).
17
+ */
18
+ type CompressionFormat = "gzip" | "deflate" | "deflate-raw"
19
+
20
+ declare class CompressionStream {
21
+ /** Any other `format` throws a TypeError. */
22
+ constructor(format: CompressionFormat)
23
+ readonly readable: ReadableStream<Uint8Array>
24
+ readonly writable: WritableStream<ArrayBuffer | ArrayBufferView>
25
+ }
26
+
27
+ declare class DecompressionStream {
28
+ /** Any other `format` throws a TypeError. */
29
+ constructor(format: CompressionFormat)
30
+ readonly readable: ReadableStream<Uint8Array>
31
+ readonly writable: WritableStream<ArrayBuffer | ArrayBufferView>
32
+ }
@@ -1,6 +1,6 @@
1
1
  // The Fetch API cluster (Headers, Request, Response, fetch). A deliberate subset
2
2
  // of the WHATWG Fetch standard: flux provides exactly these members and no more
3
- // (no Blob, FormData, ReadableStream, clone(), ...).
3
+ // (no Blob, FormData, clone(), ...). Bodies are ReadableStreams (streams.d.ts).
4
4
  // Grouped in one file because the four share BodyInit/HeadersInit and reference
5
5
  // each other.
6
6
 
@@ -11,11 +11,12 @@
11
11
  type HeadersInit = Record<string, string> | Headers
12
12
 
13
13
  /**
14
- * A message body: a string, raw bytes, or an async-iterable of string/byte
15
- * chunks (e.g. an `async function*`), which is sent as a stream. Any other
16
- * value throws (the web stringifies it).
14
+ * A message body: a string, raw bytes, or a stream of string/byte chunks (a
15
+ * `ReadableStream`, or any async-iterable such as an `async function*`),
16
+ * which is sent as it is produced. Any other value throws (the web
17
+ * stringifies it).
17
18
  */
18
- type BodyInit = string | Uint8Array | AsyncIterable<string | Uint8Array>
19
+ type BodyInit = string | Uint8Array | ReadableStream<string | Uint8Array> | AsyncIterable<string | Uint8Array>
19
20
 
20
21
  /** A subset of the WHATWG Headers API. Names are case-insensitive. */
21
22
  interface Headers {
@@ -89,8 +90,12 @@ interface Request {
89
90
  readonly headers: Headers
90
91
  /** Route params from the matched pattern; an empty object for a JS-constructed Request. */
91
92
  readonly params: Record<string, string>
92
- /** The body as an async-iterable of byte chunks (read once). */
93
- readonly body: AsyncIterable<Uint8Array>
93
+ /**
94
+ * The body as a stream of byte chunks, read once: an incoming request's
95
+ * network stream, read as far as it is consumed; a buffered body as one
96
+ * chunk. Reading it with `for await` is the common form.
97
+ */
98
+ readonly body: ReadableStream<Uint8Array>
94
99
  /** Read the whole body as UTF-8 text. */
95
100
  text(): Promise<string>
96
101
  /** Read the whole body as raw bytes. */
@@ -122,26 +127,38 @@ interface Response {
122
127
  readonly ok: boolean
123
128
  readonly url: string
124
129
  readonly headers: Headers
125
- /** The body as an async-iterable of byte chunks (read once). */
126
- readonly body: AsyncIterable<Uint8Array>
127
- /** Read the whole body as UTF-8 text. */
130
+ /**
131
+ * The body as a stream of byte chunks, read once: a fetched response's
132
+ * network stream, read as far as it is consumed; a buffered body as one
133
+ * chunk; a stream given to the constructor as it is. Reading it with
134
+ * `for await` is the common form.
135
+ */
136
+ readonly body: ReadableStream<Uint8Array>
137
+ /** Read the whole body as UTF-8 text. A stream body is drained. */
128
138
  text(): Promise<string>
129
- /** Read the whole body as raw bytes. */
139
+ /** Read the whole body as raw bytes. A stream body is drained. */
130
140
  bytes(): Promise<Uint8Array>
131
- /** Read the whole body as an ArrayBuffer. */
141
+ /** Read the whole body as an ArrayBuffer. A stream body is drained. */
132
142
  arrayBuffer(): Promise<ArrayBuffer>
133
- /** Read and parse the whole body as JSON. */
143
+ /** Read and parse the whole body as JSON. A stream body is drained. */
134
144
  json(): Promise<any>
135
145
  }
136
146
 
137
147
  declare let Response: {
148
+ /**
149
+ * A stream body (a `ReadableStream`, or any async-iterable of string or
150
+ * byte chunks, wrapped as one) is sent as it is produced: served over
151
+ * chunked transfer encoding, or drained by `text()` and the other
152
+ * readers.
153
+ */
138
154
  new (body?: BodyInit | null, init?: ResponseInit): Response
139
155
  /** Build a JSON response (sets Content-Type to application/json when unset). */
140
156
  json(data: any, init?: ResponseInit): Response
141
157
  }
142
158
 
143
159
  /**
144
- * Fetch a resource over HTTP(S). The body may be a string, Uint8Array, or an
145
- * async-iterable (streamed). Resolves to a {@link Response}.
160
+ * Fetch a resource over HTTP(S). The body may be a string, Uint8Array, or a
161
+ * stream (a `ReadableStream` or any async-iterable, sent as it is
162
+ * produced). Resolves to a {@link Response}.
146
163
  */
147
164
  declare function fetch(url: string, options?: RequestInit): Promise<Response>
@@ -0,0 +1,244 @@
1
+ // The WHATWG Streams subset: ReadableStream, WritableStream, TransformStream
2
+ // and the text streams. The names and shapes are the standard's; what is
3
+ // left out is what a single known app has not needed: no BYOB readers or
4
+ // byte streams (`type: "bytes"`), the only queuing strategy a chunk-count
5
+ // `highWaterMark`, no `pipeTo` options (`preventClose`, `preventAbort`,
6
+ // `preventCancel`, `signal`). Chunks are any JS value; a stream used as a
7
+ // body (`new Response(stream)`, a fetch body) must yield strings or
8
+ // Uint8Arrays.
9
+ //
10
+ // A ReadableStream is async-iterable, so `for await (let chunk of stream)`
11
+ // works, and ending the loop early cancels the stream. `Response.body`,
12
+ // `Request.body` and a child process's `stdout`/`stderr` are ReadableStreams
13
+ // over the runtime's own byte sources: one chunk is pulled per read, so a
14
+ // socket advances only as far as it is read, and cancelling the stream
15
+ // releases it.
16
+
17
+ /** The queuing strategy a stream takes: a chunk count, nothing else. */
18
+ interface QueuingStrategy {
19
+ /**
20
+ * How many chunks the stream queues ahead of its consumer (a readable:
21
+ * before it stops pulling; a writable: before a writer sees
22
+ * backpressure). Defaults to 1.
23
+ */
24
+ highWaterMark?: number
25
+ }
26
+
27
+ interface ReadableStreamDefaultController<R = any> {
28
+ /** The chunks the queue has room for; null once the stream is errored. */
29
+ readonly desiredSize: number | null
30
+ /** Queue a chunk for the reader. Throws once the stream is closed. */
31
+ enqueue(chunk: R): void
32
+ /** End the stream after the queued chunks. */
33
+ close(): void
34
+ /** Error the stream: pending and later reads reject with `e`. */
35
+ error(e?: any): void
36
+ }
37
+
38
+ /** What `new ReadableStream(source)` takes. Each method is optional. */
39
+ interface UnderlyingSource<R = any> {
40
+ /** Runs at construction; a returned promise delays the first pull. */
41
+ start?(controller: ReadableStreamDefaultController<R>): any
42
+ /**
43
+ * Called when the queue has room (and again once a returned promise
44
+ * settles), to produce the next chunk(s).
45
+ */
46
+ pull?(controller: ReadableStreamDefaultController<R>): any
47
+ /** Called when the consumer cancels the stream, with the reason. */
48
+ cancel?(reason?: any): any
49
+ }
50
+
51
+ interface ReadableStreamReadResult<R> {
52
+ value: R | undefined
53
+ done: boolean
54
+ }
55
+
56
+ interface ReadableStreamDefaultReader<R = any> {
57
+ /** Settles when the stream closes; rejects when it errors or the reader is released. */
58
+ readonly closed: Promise<void>
59
+ /** The next chunk, or `{ done: true }` at the end. */
60
+ read(): Promise<ReadableStreamReadResult<R>>
61
+ /** Cancel the stream, as {@link ReadableStream.cancel}. */
62
+ cancel(reason?: any): Promise<void>
63
+ /** Unlock the stream. Pending reads reject. */
64
+ releaseLock(): void
65
+ }
66
+
67
+ interface ReadableStreamIteratorOptions {
68
+ /** Keep the stream open when the loop ends early (`break`, a throw). */
69
+ preventCancel?: boolean
70
+ }
71
+
72
+ /** A pair a stream pipes through; a TransformStream is one. */
73
+ interface ReadableWritablePair<R = any, W = any> {
74
+ readable: ReadableStream<R>
75
+ writable: WritableStream<W>
76
+ }
77
+
78
+ declare class ReadableStream<R = any> {
79
+ /** No `type: "bytes"`; a strategy is a chunk count. */
80
+ constructor(underlyingSource?: UnderlyingSource<R>, strategy?: QueuingStrategy)
81
+ /** True while a reader, a pipe or an iteration holds the stream. */
82
+ readonly locked: boolean
83
+ /**
84
+ * Lock the stream to a reader. One reader at a time: a second call
85
+ * throws until the first is released. No `mode: "byob"`.
86
+ */
87
+ getReader(): ReadableStreamDefaultReader<R>
88
+ /**
89
+ * Discard the stream: the source's `cancel` runs with `reason`, pending
90
+ * reads settle as done. Rejects while the stream is locked.
91
+ */
92
+ cancel(reason?: any): Promise<void>
93
+ /**
94
+ * Read the stream through `transform` and return its readable side. The
95
+ * pipe runs on its own; an error on either side propagates to the other.
96
+ * Throws when either stream is locked. No options.
97
+ */
98
+ pipeThrough<T>(transform: ReadableWritablePair<T, R>, options?: undefined): ReadableStream<T>
99
+ /**
100
+ * Read the stream into `destination` and close it at the end. An errored
101
+ * source aborts the destination, an errored or closed destination cancels
102
+ * the source, and the promise rejects with that error. No options.
103
+ */
104
+ pipeTo(destination: WritableStream<R>, options?: undefined): Promise<void>
105
+ /**
106
+ * Two streams over this one: every chunk goes to both, and the source is
107
+ * cancelled once both are. A slow branch makes the other wait, since
108
+ * chunks are not buffered per branch beyond its own queue.
109
+ */
110
+ tee(): [ReadableStream<R>, ReadableStream<R>]
111
+ /** The async iterator `for await` uses; `preventCancel` keeps `break` from cancelling. */
112
+ values(options?: ReadableStreamIteratorOptions): AsyncIterableIterator<R>
113
+ [Symbol.asyncIterator](): AsyncIterableIterator<R>
114
+ /**
115
+ * A stream over an async (or sync) iterable: one item is pulled per
116
+ * read, and cancelling the stream returns the iterator.
117
+ */
118
+ static from<R>(iterable: AsyncIterable<R> | Iterable<R | PromiseLike<R>>): ReadableStream<R>
119
+ }
120
+
121
+ interface WritableStreamDefaultController {
122
+ /** Error the stream: queued and later writes reject with `e`. */
123
+ error(e?: any): void
124
+ }
125
+
126
+ /** What `new WritableStream(sink)` takes. Each method is optional. */
127
+ interface UnderlyingSink<W = any> {
128
+ /** Runs at construction; a returned promise delays the first write. */
129
+ start?(controller: WritableStreamDefaultController): any
130
+ /**
131
+ * Receives one chunk at a time; the next write waits for a returned
132
+ * promise, which is how a slow sink paces a fast writer.
133
+ */
134
+ write?(chunk: W, controller: WritableStreamDefaultController): any
135
+ /** Runs once after the last write when the stream is closed. */
136
+ close?(): any
137
+ /** Runs when the stream is aborted, with the reason. */
138
+ abort?(reason?: any): any
139
+ }
140
+
141
+ interface WritableStreamDefaultWriter<W = any> {
142
+ /** Fulfilled while the queue has room; a new promise each time it fills. */
143
+ readonly ready: Promise<void>
144
+ /** Settles when the stream closes; rejects when it errors or the writer is released. */
145
+ readonly closed: Promise<void>
146
+ /** The chunks the queue has room for; null once the stream is errored. */
147
+ readonly desiredSize: number | null
148
+ /**
149
+ * Queue a chunk. Resolves once the sink has accepted it, so awaiting each
150
+ * write is one way to see backpressure; `ready` is the other.
151
+ */
152
+ write(chunk: W): Promise<void>
153
+ /** Close the stream after the queued writes; resolves once the sink closed. */
154
+ close(): Promise<void>
155
+ /** Abort the stream, as {@link WritableStream.abort}. */
156
+ abort(reason?: any): Promise<void>
157
+ /** Unlock the stream. A pending `ready` or `closed` rejects. */
158
+ releaseLock(): void
159
+ }
160
+
161
+ declare class WritableStream<W = any> {
162
+ /** A strategy is a chunk count. */
163
+ constructor(underlyingSink?: UnderlyingSink<W>, strategy?: QueuingStrategy)
164
+ /** True while a writer or a pipe holds the stream. */
165
+ readonly locked: boolean
166
+ /**
167
+ * Lock the stream to a writer. One writer at a time: a second call throws
168
+ * until the first is released.
169
+ */
170
+ getWriter(): WritableStreamDefaultWriter<W>
171
+ /**
172
+ * Error the stream with `reason`: queued writes reject, the sink's
173
+ * `abort` runs once a write in flight has finished. Rejects while the
174
+ * stream is locked.
175
+ */
176
+ abort(reason?: any): Promise<void>
177
+ /** Close the stream after the queued writes. Rejects while the stream is locked. */
178
+ close(): Promise<void>
179
+ }
180
+
181
+ interface TransformStreamDefaultController<O = any> {
182
+ /** The readable side's room for chunks; null once it is errored. */
183
+ readonly desiredSize: number | null
184
+ /** Queue a chunk on the readable side. */
185
+ enqueue(chunk: O): void
186
+ /** Error both sides with `e`. */
187
+ error(e?: any): void
188
+ /** Close the readable side and error the writable side. */
189
+ terminate(): void
190
+ }
191
+
192
+ /** What `new TransformStream(transformer)` takes. Each method is optional. */
193
+ interface Transformer<I = any, O = any> {
194
+ /** Runs at construction; a returned promise delays the first chunk. */
195
+ start?(controller: TransformStreamDefaultController<O>): any
196
+ /**
197
+ * Receives each written chunk, to enqueue zero or more chunks on the
198
+ * readable side. Absent, chunks pass through unchanged. A throw errors
199
+ * both sides.
200
+ */
201
+ transform?(chunk: I, controller: TransformStreamDefaultController<O>): any
202
+ /** Runs when the writable side closes, before the readable side does. */
203
+ flush?(controller: TransformStreamDefaultController<O>): any
204
+ }
205
+
206
+ declare class TransformStream<I = any, O = any> {
207
+ /**
208
+ * Strategies are chunk counts: the writable side's defaults to 1, the
209
+ * readable side's to 0, so a chunk is transformed as the reader asks. A
210
+ * write waits while the readable side's queue is full.
211
+ */
212
+ constructor(transformer?: Transformer<I, O>, writableStrategy?: QueuingStrategy, readableStrategy?: QueuingStrategy)
213
+ readonly readable: ReadableStream<O>
214
+ readonly writable: WritableStream<I>
215
+ }
216
+
217
+ /**
218
+ * A TransformStream from UTF-8 bytes (Uint8Array or ArrayBuffer chunks) to
219
+ * strings: a {@link TextDecoder} in `stream` mode, so a multibyte sequence
220
+ * split across chunks decodes whole. Chunks that decode to nothing are not
221
+ * enqueued.
222
+ */
223
+ declare class TextDecoderStream {
224
+ /** As the {@link TextDecoder} constructor: UTF-8 labels only. */
225
+ constructor(label?: string, options?: TextDecoderOptions)
226
+ /** Always "utf-8". */
227
+ readonly encoding: string
228
+ readonly fatal: boolean
229
+ readonly ignoreBOM: boolean
230
+ readonly readable: ReadableStream<string>
231
+ readonly writable: WritableStream<Uint8Array | ArrayBuffer>
232
+ }
233
+
234
+ /**
235
+ * A TransformStream from strings to their UTF-8 bytes. A chunk ending in a
236
+ * high surrogate holds that half for the next chunk, so a surrogate pair
237
+ * split across chunks encodes as one character.
238
+ */
239
+ declare class TextEncoderStream {
240
+ /** Always "utf-8". */
241
+ readonly encoding: string
242
+ readonly readable: ReadableStream<Uint8Array>
243
+ readonly writable: WritableStream<string>
244
+ }
@@ -1,4 +1,5 @@
1
1
  // TextEncoder / TextDecoder. UTF-8 only (the only encoding the runtime needs).
2
+ // Their stream forms, TextEncoderStream / TextDecoderStream, are in streams.d.ts.
2
3
 
3
4
  interface TextEncoder {
4
5
  /** Always "utf-8". */