@yume-chan/stream-extra 0.0.23 → 0.0.24
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/CHANGELOG.json +18 -0
- package/CHANGELOG.md +10 -1
- package/LICENSE +1 -1
- package/esm/concat.d.ts +4 -3
- package/esm/concat.d.ts.map +1 -1
- package/esm/concat.js +6 -4
- package/esm/concat.js.map +1 -1
- package/esm/consumable.d.ts +30 -42
- package/esm/consumable.d.ts.map +1 -1
- package/esm/consumable.js +96 -143
- package/esm/consumable.js.map +1 -1
- package/esm/distribution.d.ts +3 -2
- package/esm/distribution.d.ts.map +1 -1
- package/esm/distribution.js +22 -18
- package/esm/distribution.js.map +1 -1
- package/esm/encoding.d.ts +21 -0
- package/esm/encoding.d.ts.map +1 -0
- package/esm/encoding.js +4 -0
- package/esm/encoding.js.map +1 -0
- package/esm/index.d.ts +3 -1
- package/esm/index.d.ts.map +1 -1
- package/esm/index.js +3 -1
- package/esm/index.js.map +1 -1
- package/esm/maybe-consumable.d.ts +21 -0
- package/esm/maybe-consumable.d.ts.map +1 -0
- package/esm/maybe-consumable.js +62 -0
- package/esm/maybe-consumable.js.map +1 -0
- package/esm/stream.d.ts +4 -4
- package/esm/stream.d.ts.map +1 -1
- package/esm/struct-deserialize.d.ts +1 -1
- package/esm/struct-deserialize.d.ts.map +1 -1
- package/esm/struct-deserialize.js.map +1 -1
- package/esm/struct-serialize.d.ts +1 -1
- package/esm/struct-serialize.d.ts.map +1 -1
- package/esm/task.d.ts +5 -0
- package/esm/task.d.ts.map +1 -0
- package/esm/task.js +9 -0
- package/esm/task.js.map +1 -0
- package/esm/types.d.ts +32 -32
- package/esm/types.d.ts.map +1 -1
- package/package.json +8 -10
- package/src/concat.ts +6 -4
- package/src/consumable.ts +144 -230
- package/src/distribution.ts +30 -20
- package/src/encoding.ts +39 -0
- package/src/index.ts +3 -1
- package/src/maybe-consumable.ts +101 -0
- package/src/stream.ts +4 -4
- package/src/struct-deserialize.ts +2 -2
- package/src/struct-serialize.ts +1 -1
- package/src/task.ts +21 -0
- package/src/types.ts +32 -32
- package/tsconfig.build.tsbuildinfo +1 -1
- package/esm/decode-utf8.d.ts +0 -5
- package/esm/decode-utf8.d.ts.map +0 -1
- package/esm/decode-utf8.js +0 -12
- package/esm/decode-utf8.js.map +0 -1
- package/src/decode-utf8.ts +0 -13
package/src/concat.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { PromiseResolver } from "@yume-chan/async";
|
|
2
|
+
import { EMPTY_UINT8_ARRAY } from "@yume-chan/struct";
|
|
2
3
|
|
|
3
4
|
import type { ReadableStreamDefaultController } from "./stream.js";
|
|
4
5
|
import { ReadableStream, WritableStream } from "./stream.js";
|
|
@@ -81,9 +82,10 @@ export interface ConcatBufferReadableStream
|
|
|
81
82
|
* A `TransformStream` that concatenates `Uint8Array`s.
|
|
82
83
|
*
|
|
83
84
|
* If you want to decode the result as string,
|
|
84
|
-
* prefer `.pipeThrough(new
|
|
85
|
-
* than `.pipeThough(new ConcatBufferStream()).pipeThrough(new
|
|
86
|
-
* because
|
|
85
|
+
* prefer `.pipeThrough(new TextDecoderStream()).pipeThrough(new ConcatStringStream())`,
|
|
86
|
+
* than `.pipeThough(new ConcatBufferStream()).pipeThrough(new TextDecoderStream())`,
|
|
87
|
+
* because of JavaScript engine optimizations,
|
|
88
|
+
* concatenating strings is faster than concatenating `Uint8Array`s.
|
|
87
89
|
*/
|
|
88
90
|
export class ConcatBufferStream {
|
|
89
91
|
#segments: Uint8Array[] = [];
|
|
@@ -99,7 +101,7 @@ export class ConcatBufferStream {
|
|
|
99
101
|
let offset = 0;
|
|
100
102
|
switch (this.#segments.length) {
|
|
101
103
|
case 0:
|
|
102
|
-
result =
|
|
104
|
+
result = EMPTY_UINT8_ARRAY;
|
|
103
105
|
break;
|
|
104
106
|
case 1:
|
|
105
107
|
result = this.#segments[0]!;
|
package/src/consumable.ts
CHANGED
|
@@ -5,30 +5,17 @@ import type {
|
|
|
5
5
|
WritableStreamDefaultController,
|
|
6
6
|
WritableStreamDefaultWriter,
|
|
7
7
|
} from "./stream.js";
|
|
8
|
-
import {
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
}
|
|
13
|
-
|
|
14
|
-
interface Console {
|
|
15
|
-
createTask(name: string): Task;
|
|
16
|
-
}
|
|
8
|
+
import {
|
|
9
|
+
ReadableStream as NativeReadableStream,
|
|
10
|
+
WritableStream as NativeWritableStream,
|
|
11
|
+
} from "./stream.js";
|
|
12
|
+
import type { Task } from "./task.js";
|
|
13
|
+
import { createTask } from "./task.js";
|
|
17
14
|
|
|
18
|
-
|
|
19
|
-
|
|
15
|
+
function isPromiseLike(value: unknown): value is PromiseLike<unknown> {
|
|
16
|
+
return typeof value === "object" && value !== null && "then" in value;
|
|
20
17
|
}
|
|
21
18
|
|
|
22
|
-
// `createTask` allows browser DevTools to track the call stack across async boundaries.
|
|
23
|
-
const { console } = globalThis as unknown as GlobalExtension;
|
|
24
|
-
const createTask: Console["createTask"] =
|
|
25
|
-
console.createTask?.bind(console) ??
|
|
26
|
-
(() => ({
|
|
27
|
-
run(callback) {
|
|
28
|
-
return callback();
|
|
29
|
-
},
|
|
30
|
-
}));
|
|
31
|
-
|
|
32
19
|
export class Consumable<T> {
|
|
33
20
|
readonly #task: Task;
|
|
34
21
|
readonly #resolver: PromiseResolver<void>;
|
|
@@ -51,11 +38,23 @@ export class Consumable<T> {
|
|
|
51
38
|
this.#resolver.reject(error);
|
|
52
39
|
}
|
|
53
40
|
|
|
54
|
-
|
|
41
|
+
tryConsume<U>(callback: (value: T) => U) {
|
|
55
42
|
try {
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
43
|
+
let result = this.#task.run(() => callback(this.value));
|
|
44
|
+
if (isPromiseLike(result)) {
|
|
45
|
+
result = result.then(
|
|
46
|
+
(value) => {
|
|
47
|
+
this.#resolver.resolve();
|
|
48
|
+
return value;
|
|
49
|
+
},
|
|
50
|
+
(e) => {
|
|
51
|
+
this.#resolver.reject(e);
|
|
52
|
+
throw e;
|
|
53
|
+
},
|
|
54
|
+
) as U;
|
|
55
|
+
} else {
|
|
56
|
+
this.#resolver.resolve();
|
|
57
|
+
}
|
|
59
58
|
return result;
|
|
60
59
|
} catch (e) {
|
|
61
60
|
this.#resolver.reject(e);
|
|
@@ -64,228 +63,143 @@ export class Consumable<T> {
|
|
|
64
63
|
}
|
|
65
64
|
}
|
|
66
65
|
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
super({
|
|
79
|
-
async transform(chunk, controller) {
|
|
80
|
-
await enqueue(controller, chunk);
|
|
81
|
-
},
|
|
82
|
-
});
|
|
66
|
+
export namespace Consumable {
|
|
67
|
+
export interface WritableStreamSink<in T> {
|
|
68
|
+
start?(
|
|
69
|
+
controller: WritableStreamDefaultController,
|
|
70
|
+
): void | PromiseLike<void>;
|
|
71
|
+
write?(
|
|
72
|
+
chunk: T,
|
|
73
|
+
controller: WritableStreamDefaultController,
|
|
74
|
+
): void | PromiseLike<void>;
|
|
75
|
+
abort?(reason: unknown): void | PromiseLike<void>;
|
|
76
|
+
close?(): void | PromiseLike<void>;
|
|
83
77
|
}
|
|
84
|
-
}
|
|
85
78
|
|
|
86
|
-
export class
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
>
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
});
|
|
97
|
-
}
|
|
98
|
-
}
|
|
99
|
-
|
|
100
|
-
export interface ConsumableReadableStreamController<T> {
|
|
101
|
-
enqueue(chunk: T): Promise<void>;
|
|
102
|
-
close(): void;
|
|
103
|
-
error(reason: any): void;
|
|
104
|
-
}
|
|
105
|
-
|
|
106
|
-
export interface ConsumableReadableStreamSource<T> {
|
|
107
|
-
start?(
|
|
108
|
-
controller: ConsumableReadableStreamController<T>,
|
|
109
|
-
): void | PromiseLike<void>;
|
|
110
|
-
pull?(
|
|
111
|
-
controller: ConsumableReadableStreamController<T>,
|
|
112
|
-
): void | PromiseLike<void>;
|
|
113
|
-
cancel?(reason: any): void | PromiseLike<void>;
|
|
114
|
-
}
|
|
115
|
-
|
|
116
|
-
export class ConsumableReadableStream<T> extends ReadableStream<Consumable<T>> {
|
|
117
|
-
constructor(
|
|
118
|
-
source: ConsumableReadableStreamSource<T>,
|
|
119
|
-
strategy?: QueuingStrategy<T>,
|
|
120
|
-
) {
|
|
121
|
-
let wrappedController:
|
|
122
|
-
| ConsumableReadableStreamController<T>
|
|
123
|
-
| undefined;
|
|
124
|
-
|
|
125
|
-
let wrappedStrategy: QueuingStrategy<Consumable<T>> | undefined;
|
|
126
|
-
if (strategy) {
|
|
127
|
-
wrappedStrategy = {};
|
|
128
|
-
if ("highWaterMark" in strategy) {
|
|
129
|
-
wrappedStrategy.highWaterMark = strategy.highWaterMark;
|
|
130
|
-
}
|
|
131
|
-
if ("size" in strategy) {
|
|
132
|
-
wrappedStrategy.size = (chunk) => {
|
|
133
|
-
return strategy.size!(chunk.value);
|
|
134
|
-
};
|
|
135
|
-
}
|
|
79
|
+
export class WritableStream<in T> extends NativeWritableStream<
|
|
80
|
+
Consumable<T>
|
|
81
|
+
> {
|
|
82
|
+
static async write<T>(
|
|
83
|
+
writer: WritableStreamDefaultWriter<Consumable<T>>,
|
|
84
|
+
value: T,
|
|
85
|
+
) {
|
|
86
|
+
const consumable = new Consumable(value);
|
|
87
|
+
await writer.write(consumable);
|
|
88
|
+
await consumable.consumed;
|
|
136
89
|
}
|
|
137
90
|
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
91
|
+
constructor(
|
|
92
|
+
sink: WritableStreamSink<T>,
|
|
93
|
+
strategy?: QueuingStrategy<T>,
|
|
94
|
+
) {
|
|
95
|
+
let wrappedStrategy: QueuingStrategy<Consumable<T>> | undefined;
|
|
96
|
+
if (strategy) {
|
|
97
|
+
wrappedStrategy = {};
|
|
98
|
+
if ("highWaterMark" in strategy) {
|
|
99
|
+
wrappedStrategy.highWaterMark = strategy.highWaterMark;
|
|
100
|
+
}
|
|
101
|
+
if ("size" in strategy) {
|
|
102
|
+
wrappedStrategy.size = (chunk) => {
|
|
103
|
+
return strategy.size!(
|
|
104
|
+
chunk instanceof Consumable ? chunk.value : chunk,
|
|
105
|
+
);
|
|
151
106
|
};
|
|
107
|
+
}
|
|
108
|
+
}
|
|
152
109
|
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
110
|
+
super(
|
|
111
|
+
{
|
|
112
|
+
start(controller) {
|
|
113
|
+
return sink.start?.(controller);
|
|
114
|
+
},
|
|
115
|
+
async write(chunk, controller) {
|
|
116
|
+
await chunk.tryConsume((chunk) =>
|
|
117
|
+
sink.write?.(chunk, controller),
|
|
118
|
+
);
|
|
119
|
+
},
|
|
120
|
+
abort(reason) {
|
|
121
|
+
return sink.abort?.(reason);
|
|
122
|
+
},
|
|
123
|
+
close() {
|
|
124
|
+
return sink.close?.();
|
|
125
|
+
},
|
|
160
126
|
},
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
127
|
+
wrappedStrategy,
|
|
128
|
+
);
|
|
129
|
+
}
|
|
164
130
|
}
|
|
165
|
-
}
|
|
166
|
-
|
|
167
|
-
export interface ConsumableWritableStreamSink<T> {
|
|
168
|
-
start?(
|
|
169
|
-
controller: WritableStreamDefaultController,
|
|
170
|
-
): void | PromiseLike<void>;
|
|
171
|
-
write?(
|
|
172
|
-
chunk: T,
|
|
173
|
-
controller: WritableStreamDefaultController,
|
|
174
|
-
): void | PromiseLike<void>;
|
|
175
|
-
abort?(reason: any): void | PromiseLike<void>;
|
|
176
|
-
close?(): void | PromiseLike<void>;
|
|
177
|
-
}
|
|
178
131
|
|
|
179
|
-
export
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
) {
|
|
184
|
-
const consumable = new Consumable(value);
|
|
185
|
-
await writer.write(consumable);
|
|
186
|
-
await consumable.consumed;
|
|
132
|
+
export interface ReadableStreamController<T> {
|
|
133
|
+
enqueue(chunk: T): Promise<void>;
|
|
134
|
+
close(): void;
|
|
135
|
+
error(reason: unknown): void;
|
|
187
136
|
}
|
|
188
137
|
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
wrappedStrategy.highWaterMark = strategy.highWaterMark;
|
|
198
|
-
}
|
|
199
|
-
if ("size" in strategy) {
|
|
200
|
-
wrappedStrategy.size = (chunk) => {
|
|
201
|
-
return strategy.size!(chunk.value);
|
|
202
|
-
};
|
|
203
|
-
}
|
|
204
|
-
}
|
|
205
|
-
|
|
206
|
-
super(
|
|
207
|
-
{
|
|
208
|
-
start(controller) {
|
|
209
|
-
return sink.start?.(controller);
|
|
210
|
-
},
|
|
211
|
-
async write(chunk, controller) {
|
|
212
|
-
await chunk.tryConsume((value) =>
|
|
213
|
-
sink.write?.(value, controller),
|
|
214
|
-
);
|
|
215
|
-
},
|
|
216
|
-
abort(reason) {
|
|
217
|
-
return sink.abort?.(reason);
|
|
218
|
-
},
|
|
219
|
-
close() {
|
|
220
|
-
return sink.close?.();
|
|
221
|
-
},
|
|
222
|
-
},
|
|
223
|
-
wrappedStrategy,
|
|
224
|
-
);
|
|
138
|
+
export interface ReadableStreamSource<T> {
|
|
139
|
+
start?(
|
|
140
|
+
controller: ReadableStreamController<T>,
|
|
141
|
+
): void | PromiseLike<void>;
|
|
142
|
+
pull?(
|
|
143
|
+
controller: ReadableStreamController<T>,
|
|
144
|
+
): void | PromiseLike<void>;
|
|
145
|
+
cancel?(reason: unknown): void | PromiseLike<void>;
|
|
225
146
|
}
|
|
226
|
-
}
|
|
227
147
|
|
|
228
|
-
export
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
controller: ConsumableReadableStreamController<O>,
|
|
238
|
-
): void | PromiseLike<void>;
|
|
239
|
-
}
|
|
148
|
+
export class ReadableStream<T> extends NativeReadableStream<Consumable<T>> {
|
|
149
|
+
static async enqueue<T>(
|
|
150
|
+
controller: { enqueue: (chunk: Consumable<T>) => void },
|
|
151
|
+
chunk: T,
|
|
152
|
+
) {
|
|
153
|
+
const output = new Consumable(chunk);
|
|
154
|
+
controller.enqueue(output);
|
|
155
|
+
await output.consumed;
|
|
156
|
+
}
|
|
240
157
|
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
|
248
|
-
|
|
158
|
+
constructor(
|
|
159
|
+
source: ReadableStreamSource<T>,
|
|
160
|
+
strategy?: QueuingStrategy<T>,
|
|
161
|
+
) {
|
|
162
|
+
let wrappedController: ReadableStreamController<T> | undefined;
|
|
163
|
+
|
|
164
|
+
let wrappedStrategy: QueuingStrategy<Consumable<T>> | undefined;
|
|
165
|
+
if (strategy) {
|
|
166
|
+
wrappedStrategy = {};
|
|
167
|
+
if ("highWaterMark" in strategy) {
|
|
168
|
+
wrappedStrategy.highWaterMark = strategy.highWaterMark;
|
|
169
|
+
}
|
|
170
|
+
if ("size" in strategy) {
|
|
171
|
+
wrappedStrategy.size = (chunk) => {
|
|
172
|
+
return strategy.size!(chunk.value);
|
|
173
|
+
};
|
|
174
|
+
}
|
|
175
|
+
}
|
|
249
176
|
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
177
|
+
super(
|
|
178
|
+
{
|
|
179
|
+
async start(controller) {
|
|
180
|
+
wrappedController = {
|
|
181
|
+
async enqueue(chunk) {
|
|
182
|
+
await ReadableStream.enqueue(controller, chunk);
|
|
183
|
+
},
|
|
184
|
+
close() {
|
|
185
|
+
controller.close();
|
|
186
|
+
},
|
|
187
|
+
error(reason) {
|
|
188
|
+
controller.error(reason);
|
|
189
|
+
},
|
|
190
|
+
};
|
|
191
|
+
|
|
192
|
+
await source.start?.(wrappedController);
|
|
255
193
|
},
|
|
256
|
-
|
|
257
|
-
|
|
194
|
+
async pull() {
|
|
195
|
+
await source.pull?.(wrappedController!);
|
|
258
196
|
},
|
|
259
|
-
|
|
260
|
-
|
|
197
|
+
async cancel(reason) {
|
|
198
|
+
await source.cancel?.(reason);
|
|
261
199
|
},
|
|
262
|
-
}
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
async transform(chunk) {
|
|
267
|
-
await chunk.tryConsume((value) =>
|
|
268
|
-
transformer.transform?.(value, wrappedController!),
|
|
269
|
-
);
|
|
270
|
-
chunk.consume();
|
|
271
|
-
},
|
|
272
|
-
async flush() {
|
|
273
|
-
await transformer.flush?.(wrappedController!);
|
|
274
|
-
},
|
|
275
|
-
});
|
|
276
|
-
}
|
|
277
|
-
}
|
|
278
|
-
|
|
279
|
-
export class ConsumableInspectStream<T> extends TransformStream<
|
|
280
|
-
Consumable<T>,
|
|
281
|
-
Consumable<T>
|
|
282
|
-
> {
|
|
283
|
-
constructor(callback: (value: T) => void) {
|
|
284
|
-
super({
|
|
285
|
-
transform(chunk, controller) {
|
|
286
|
-
callback(chunk.value);
|
|
287
|
-
controller.enqueue(chunk);
|
|
288
|
-
},
|
|
289
|
-
});
|
|
200
|
+
},
|
|
201
|
+
wrappedStrategy,
|
|
202
|
+
);
|
|
203
|
+
}
|
|
290
204
|
}
|
|
291
205
|
}
|
package/src/distribution.ts
CHANGED
|
@@ -1,4 +1,6 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { Consumable } from "./consumable.js";
|
|
2
|
+
import { MaybeConsumable } from "./maybe-consumable.js";
|
|
3
|
+
import { TransformStream } from "./stream.js";
|
|
2
4
|
|
|
3
5
|
/**
|
|
4
6
|
* Splits or combines buffers to specified size.
|
|
@@ -25,7 +27,7 @@ export class BufferCombiner {
|
|
|
25
27
|
*/
|
|
26
28
|
*push(data: Uint8Array): Generator<Uint8Array, void, void> {
|
|
27
29
|
let offset = 0;
|
|
28
|
-
let available = data.
|
|
30
|
+
let available = data.length;
|
|
29
31
|
|
|
30
32
|
if (this.#offset !== 0) {
|
|
31
33
|
if (available >= this.#available) {
|
|
@@ -77,34 +79,42 @@ export class BufferCombiner {
|
|
|
77
79
|
}
|
|
78
80
|
}
|
|
79
81
|
|
|
80
|
-
export class DistributionStream extends
|
|
81
|
-
Uint8Array
|
|
82
|
-
Uint8Array
|
|
82
|
+
export class DistributionStream extends TransformStream<
|
|
83
|
+
MaybeConsumable<Uint8Array>,
|
|
84
|
+
MaybeConsumable<Uint8Array>
|
|
83
85
|
> {
|
|
84
86
|
constructor(size: number, combine = false) {
|
|
85
87
|
const combiner = combine ? new BufferCombiner(size) : undefined;
|
|
86
88
|
super({
|
|
87
89
|
async transform(chunk, controller) {
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
available
|
|
90
|
+
await MaybeConsumable.tryConsume(chunk, async (chunk) => {
|
|
91
|
+
if (combiner) {
|
|
92
|
+
for (const buffer of combiner.push(chunk)) {
|
|
93
|
+
await Consumable.ReadableStream.enqueue(
|
|
94
|
+
controller,
|
|
95
|
+
buffer,
|
|
96
|
+
);
|
|
97
|
+
}
|
|
98
|
+
} else {
|
|
99
|
+
let offset = 0;
|
|
100
|
+
let available = chunk.length;
|
|
101
|
+
while (available > 0) {
|
|
102
|
+
const end = offset + size;
|
|
103
|
+
await Consumable.ReadableStream.enqueue(
|
|
104
|
+
controller,
|
|
105
|
+
chunk.subarray(offset, end),
|
|
106
|
+
);
|
|
107
|
+
offset = end;
|
|
108
|
+
available -= size;
|
|
109
|
+
}
|
|
100
110
|
}
|
|
101
|
-
}
|
|
111
|
+
});
|
|
102
112
|
},
|
|
103
|
-
|
|
113
|
+
flush(controller) {
|
|
104
114
|
if (combiner) {
|
|
105
115
|
const data = combiner.flush();
|
|
106
116
|
if (data) {
|
|
107
|
-
|
|
117
|
+
controller.enqueue(data);
|
|
108
118
|
}
|
|
109
119
|
}
|
|
110
120
|
},
|
package/src/encoding.ts
ADDED
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import type { TransformStream } from "./stream.js";
|
|
2
|
+
|
|
3
|
+
export interface TextDecoderOptions {
|
|
4
|
+
fatal?: boolean;
|
|
5
|
+
ignoreBOM?: boolean;
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
declare class TextDecoderStreamType extends TransformStream<
|
|
9
|
+
ArrayBufferView | ArrayBuffer,
|
|
10
|
+
string
|
|
11
|
+
> {
|
|
12
|
+
constructor(label?: string, options?: TextDecoderOptions);
|
|
13
|
+
|
|
14
|
+
readonly encoding: string;
|
|
15
|
+
readonly fatal: boolean;
|
|
16
|
+
readonly ignoreBOM: boolean;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
declare class TextEncoderStreamType extends TransformStream<
|
|
20
|
+
string,
|
|
21
|
+
Uint8Array
|
|
22
|
+
> {
|
|
23
|
+
constructor();
|
|
24
|
+
|
|
25
|
+
readonly encoding: string;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
interface GlobalExtension {
|
|
29
|
+
TextDecoderStream: typeof TextDecoderStreamType;
|
|
30
|
+
TextEncoderStream: typeof TextEncoderStreamType;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
const Global = globalThis as unknown as GlobalExtension;
|
|
34
|
+
|
|
35
|
+
export const TextDecoderStream = Global.TextDecoderStream;
|
|
36
|
+
export type TextDecoderStream = TextDecoderStreamType;
|
|
37
|
+
|
|
38
|
+
export const TextEncoderStream = Global.TextEncoderStream;
|
|
39
|
+
export type TextEncoderStream = TextEncoderStreamType;
|
package/src/index.ts
CHANGED
|
@@ -2,15 +2,17 @@ export * from "./buffered-transform.js";
|
|
|
2
2
|
export * from "./buffered.js";
|
|
3
3
|
export * from "./concat.js";
|
|
4
4
|
export * from "./consumable.js";
|
|
5
|
-
export * from "./decode-utf8.js";
|
|
6
5
|
export * from "./distribution.js";
|
|
7
6
|
export * from "./duplex.js";
|
|
7
|
+
export * from "./encoding.js";
|
|
8
8
|
export * from "./inspect.js";
|
|
9
|
+
export * from "./maybe-consumable.js";
|
|
9
10
|
export * from "./pipe-from.js";
|
|
10
11
|
export * from "./push-readable.js";
|
|
11
12
|
export * from "./split-string.js";
|
|
12
13
|
export * from "./stream.js";
|
|
13
14
|
export * from "./struct-deserialize.js";
|
|
14
15
|
export * from "./struct-serialize.js";
|
|
16
|
+
export * from "./task.js";
|
|
15
17
|
export * from "./wrap-readable.js";
|
|
16
18
|
export * from "./wrap-writable.js";
|