@gjsify/web-streams 0.1.0
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 +30 -0
- package/lib/esm/index.js +121 -0
- package/lib/esm/queuing-strategies.js +56 -0
- package/lib/esm/readable-stream.js +1064 -0
- package/lib/esm/text-decoder-stream.js +126 -0
- package/lib/esm/text-encoder-stream.js +46 -0
- package/lib/esm/transform-stream.js +336 -0
- package/lib/esm/util.js +161 -0
- package/lib/esm/writable-stream.js +676 -0
- package/lib/types/index.d.ts +77 -0
- package/lib/types/queuing-strategies.d.ts +18 -0
- package/lib/types/readable-stream.d.ts +61 -0
- package/lib/types/text-decoder-stream.d.ts +16 -0
- package/lib/types/text-encoder-stream.d.ts +15 -0
- package/lib/types/transform-stream.d.ts +21 -0
- package/lib/types/util.d.ts +40 -0
- package/lib/types/writable-stream.d.ts +49 -0
- package/package.json +44 -0
- package/src/index.spec.ts +2043 -0
- package/src/index.ts +131 -0
- package/src/queuing-strategies.ts +67 -0
- package/src/readable-stream.ts +1337 -0
- package/src/test.mts +6 -0
- package/src/text-decoder-stream.ts +183 -0
- package/src/text-encoder-stream.ts +62 -0
- package/src/transform-stream.ts +410 -0
- package/src/util.ts +170 -0
- package/src/writable-stream.ts +773 -0
- package/tsconfig.json +32 -0
- package/tsconfig.tsbuildinfo +1 -0
|
@@ -0,0 +1,126 @@
|
|
|
1
|
+
import { TransformStream } from "./transform-stream.js";
|
|
2
|
+
function hasStreamingSupport() {
|
|
3
|
+
try {
|
|
4
|
+
const td = new TextDecoder();
|
|
5
|
+
td.decode(new Uint8Array([195]), { stream: true });
|
|
6
|
+
return true;
|
|
7
|
+
} catch {
|
|
8
|
+
return false;
|
|
9
|
+
}
|
|
10
|
+
}
|
|
11
|
+
const supportsStreaming = hasStreamingSupport();
|
|
12
|
+
function incompleteUtf8Tail(buf) {
|
|
13
|
+
const len = buf.length;
|
|
14
|
+
if (len === 0) return 0;
|
|
15
|
+
for (let i = 1; i <= Math.min(3, len); i++) {
|
|
16
|
+
const b = buf[len - i];
|
|
17
|
+
if ((b & 128) === 0) {
|
|
18
|
+
return 0;
|
|
19
|
+
}
|
|
20
|
+
if ((b & 192) !== 128) {
|
|
21
|
+
let expectedLen;
|
|
22
|
+
if ((b & 224) === 192) expectedLen = 2;
|
|
23
|
+
else if ((b & 240) === 224) expectedLen = 3;
|
|
24
|
+
else if ((b & 248) === 240) expectedLen = 4;
|
|
25
|
+
else return 0;
|
|
26
|
+
if (i < expectedLen) {
|
|
27
|
+
return i;
|
|
28
|
+
}
|
|
29
|
+
return 0;
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
return 0;
|
|
33
|
+
}
|
|
34
|
+
class TextDecoderStream {
|
|
35
|
+
#decoder;
|
|
36
|
+
#transform;
|
|
37
|
+
constructor(label, options) {
|
|
38
|
+
this.#decoder = new TextDecoder(label, options);
|
|
39
|
+
if (supportsStreaming) {
|
|
40
|
+
this.#transform = new TransformStream({
|
|
41
|
+
transform: (chunk, controller) => {
|
|
42
|
+
const bytes = toUint8Array(chunk);
|
|
43
|
+
const decoded = this.#decoder.decode(bytes, { stream: true });
|
|
44
|
+
if (decoded) {
|
|
45
|
+
controller.enqueue(decoded);
|
|
46
|
+
}
|
|
47
|
+
},
|
|
48
|
+
flush: (controller) => {
|
|
49
|
+
const final = this.#decoder.decode();
|
|
50
|
+
if (final) {
|
|
51
|
+
controller.enqueue(final);
|
|
52
|
+
}
|
|
53
|
+
},
|
|
54
|
+
cancel: () => {
|
|
55
|
+
this.#decoder.decode();
|
|
56
|
+
}
|
|
57
|
+
});
|
|
58
|
+
} else {
|
|
59
|
+
let pendingBytes = new Uint8Array(0);
|
|
60
|
+
this.#transform = new TransformStream({
|
|
61
|
+
transform: (chunk, controller) => {
|
|
62
|
+
const incoming = toUint8Array(chunk);
|
|
63
|
+
let combined;
|
|
64
|
+
if (pendingBytes.length > 0) {
|
|
65
|
+
combined = new Uint8Array(pendingBytes.length + incoming.length);
|
|
66
|
+
combined.set(pendingBytes, 0);
|
|
67
|
+
combined.set(incoming, pendingBytes.length);
|
|
68
|
+
} else {
|
|
69
|
+
combined = incoming;
|
|
70
|
+
}
|
|
71
|
+
const tail = incompleteUtf8Tail(combined);
|
|
72
|
+
let decodable;
|
|
73
|
+
if (tail > 0) {
|
|
74
|
+
decodable = combined.slice(0, combined.length - tail);
|
|
75
|
+
pendingBytes = combined.slice(combined.length - tail);
|
|
76
|
+
} else {
|
|
77
|
+
decodable = combined;
|
|
78
|
+
pendingBytes = new Uint8Array(0);
|
|
79
|
+
}
|
|
80
|
+
if (decodable.length > 0) {
|
|
81
|
+
const decoded = this.#decoder.decode(decodable);
|
|
82
|
+
if (decoded) {
|
|
83
|
+
controller.enqueue(decoded);
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
},
|
|
87
|
+
flush: (controller) => {
|
|
88
|
+
if (pendingBytes.length > 0) {
|
|
89
|
+
const decoded = this.#decoder.decode(pendingBytes);
|
|
90
|
+
if (decoded) {
|
|
91
|
+
controller.enqueue(decoded);
|
|
92
|
+
}
|
|
93
|
+
pendingBytes = new Uint8Array(0);
|
|
94
|
+
}
|
|
95
|
+
},
|
|
96
|
+
cancel: () => {
|
|
97
|
+
pendingBytes = new Uint8Array(0);
|
|
98
|
+
}
|
|
99
|
+
});
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
get encoding() {
|
|
103
|
+
return this.#decoder.encoding;
|
|
104
|
+
}
|
|
105
|
+
get fatal() {
|
|
106
|
+
return this.#decoder.fatal;
|
|
107
|
+
}
|
|
108
|
+
get ignoreBOM() {
|
|
109
|
+
return this.#decoder.ignoreBOM;
|
|
110
|
+
}
|
|
111
|
+
get readable() {
|
|
112
|
+
return this.#transform.readable;
|
|
113
|
+
}
|
|
114
|
+
get writable() {
|
|
115
|
+
return this.#transform.writable;
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
function toUint8Array(chunk) {
|
|
119
|
+
if (chunk instanceof Uint8Array) return chunk;
|
|
120
|
+
if (chunk instanceof ArrayBuffer) return new Uint8Array(chunk);
|
|
121
|
+
if (ArrayBuffer.isView(chunk)) return new Uint8Array(chunk.buffer, chunk.byteOffset, chunk.byteLength);
|
|
122
|
+
throw new TypeError("chunk must be a BufferSource");
|
|
123
|
+
}
|
|
124
|
+
export {
|
|
125
|
+
TextDecoderStream
|
|
126
|
+
};
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import { TransformStream } from "./transform-stream.js";
|
|
2
|
+
class TextEncoderStream {
|
|
3
|
+
#pendingHighSurrogate = null;
|
|
4
|
+
#encoder = new TextEncoder();
|
|
5
|
+
#transform;
|
|
6
|
+
constructor() {
|
|
7
|
+
this.#transform = new TransformStream({
|
|
8
|
+
transform: (chunk, controller) => {
|
|
9
|
+
chunk = String(chunk);
|
|
10
|
+
if (chunk === "") {
|
|
11
|
+
return;
|
|
12
|
+
}
|
|
13
|
+
if (this.#pendingHighSurrogate !== null) {
|
|
14
|
+
chunk = this.#pendingHighSurrogate + chunk;
|
|
15
|
+
}
|
|
16
|
+
const lastCodeUnit = chunk.charCodeAt(chunk.length - 1);
|
|
17
|
+
if (55296 <= lastCodeUnit && lastCodeUnit <= 56319) {
|
|
18
|
+
this.#pendingHighSurrogate = chunk.slice(-1);
|
|
19
|
+
chunk = chunk.slice(0, -1);
|
|
20
|
+
} else {
|
|
21
|
+
this.#pendingHighSurrogate = null;
|
|
22
|
+
}
|
|
23
|
+
if (chunk) {
|
|
24
|
+
controller.enqueue(this.#encoder.encode(chunk));
|
|
25
|
+
}
|
|
26
|
+
},
|
|
27
|
+
flush: (controller) => {
|
|
28
|
+
if (this.#pendingHighSurrogate !== null) {
|
|
29
|
+
controller.enqueue(new Uint8Array([239, 191, 189]));
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
});
|
|
33
|
+
}
|
|
34
|
+
get encoding() {
|
|
35
|
+
return "utf-8";
|
|
36
|
+
}
|
|
37
|
+
get readable() {
|
|
38
|
+
return this.#transform.readable;
|
|
39
|
+
}
|
|
40
|
+
get writable() {
|
|
41
|
+
return this.#transform.writable;
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
export {
|
|
45
|
+
TextEncoderStream
|
|
46
|
+
};
|
|
@@ -0,0 +1,336 @@
|
|
|
1
|
+
import {
|
|
2
|
+
kState,
|
|
3
|
+
kType,
|
|
4
|
+
isBrandCheck,
|
|
5
|
+
createPromiseCallback,
|
|
6
|
+
extractHighWaterMark,
|
|
7
|
+
extractSizeAlgorithm,
|
|
8
|
+
nonOpFlush,
|
|
9
|
+
nonOpCancel
|
|
10
|
+
} from "./util.js";
|
|
11
|
+
import {
|
|
12
|
+
createReadableStream,
|
|
13
|
+
readableStreamDefaultControllerCanCloseOrEnqueue,
|
|
14
|
+
readableStreamDefaultControllerClose,
|
|
15
|
+
readableStreamDefaultControllerEnqueue,
|
|
16
|
+
readableStreamDefaultControllerError,
|
|
17
|
+
readableStreamDefaultControllerGetDesiredSize,
|
|
18
|
+
readableStreamDefaultControllerHasBackpressure
|
|
19
|
+
} from "./readable-stream.js";
|
|
20
|
+
import {
|
|
21
|
+
createWritableStream,
|
|
22
|
+
writableStreamDefaultControllerErrorIfNeeded
|
|
23
|
+
} from "./writable-stream.js";
|
|
24
|
+
const kSkipThrow = /* @__PURE__ */ Symbol("kSkipThrow");
|
|
25
|
+
class TransformStream {
|
|
26
|
+
[kType] = "TransformStream";
|
|
27
|
+
[kState];
|
|
28
|
+
constructor(transformer = {}, writableStrategy = {}, readableStrategy = {}) {
|
|
29
|
+
if (transformer != null && typeof transformer !== "object") {
|
|
30
|
+
throw new TypeError("transformer must be an object");
|
|
31
|
+
}
|
|
32
|
+
if (writableStrategy != null && typeof writableStrategy !== "object") {
|
|
33
|
+
throw new TypeError("writableStrategy must be an object");
|
|
34
|
+
}
|
|
35
|
+
if (readableStrategy != null && typeof readableStrategy !== "object") {
|
|
36
|
+
throw new TypeError("readableStrategy must be an object");
|
|
37
|
+
}
|
|
38
|
+
const readableType = transformer?.readableType;
|
|
39
|
+
const writableType = transformer?.writableType;
|
|
40
|
+
const start = transformer?.start;
|
|
41
|
+
if (readableType !== void 0) {
|
|
42
|
+
throw new RangeError(`Invalid readableType: ${readableType}`);
|
|
43
|
+
}
|
|
44
|
+
if (writableType !== void 0) {
|
|
45
|
+
throw new RangeError(`Invalid writableType: ${writableType}`);
|
|
46
|
+
}
|
|
47
|
+
const readableHighWaterMark = extractHighWaterMark(readableStrategy?.highWaterMark, 0);
|
|
48
|
+
const readableSize = extractSizeAlgorithm(readableStrategy?.size);
|
|
49
|
+
const writableHighWaterMark = extractHighWaterMark(writableStrategy?.highWaterMark, 1);
|
|
50
|
+
const writableSize = extractSizeAlgorithm(writableStrategy?.size);
|
|
51
|
+
const startPromise = Promise.withResolvers();
|
|
52
|
+
initializeTransformStream(
|
|
53
|
+
this,
|
|
54
|
+
startPromise,
|
|
55
|
+
writableHighWaterMark,
|
|
56
|
+
writableSize,
|
|
57
|
+
readableHighWaterMark,
|
|
58
|
+
readableSize
|
|
59
|
+
);
|
|
60
|
+
setupTransformStreamDefaultControllerFromTransformer(this, transformer);
|
|
61
|
+
if (start !== void 0) {
|
|
62
|
+
startPromise.resolve(start.call(transformer, this[kState].controller));
|
|
63
|
+
} else {
|
|
64
|
+
startPromise.resolve();
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
get readable() {
|
|
68
|
+
if (!isTransformStream(this)) throw new TypeError("Invalid this");
|
|
69
|
+
return this[kState].readable;
|
|
70
|
+
}
|
|
71
|
+
get writable() {
|
|
72
|
+
if (!isTransformStream(this)) throw new TypeError("Invalid this");
|
|
73
|
+
return this[kState].writable;
|
|
74
|
+
}
|
|
75
|
+
get [Symbol.toStringTag]() {
|
|
76
|
+
return "TransformStream";
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
class TransformStreamDefaultController {
|
|
80
|
+
[kType] = "TransformStreamDefaultController";
|
|
81
|
+
[kState];
|
|
82
|
+
constructor(skipThrowSymbol) {
|
|
83
|
+
if (skipThrowSymbol !== kSkipThrow) {
|
|
84
|
+
throw new TypeError("Illegal constructor");
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
get desiredSize() {
|
|
88
|
+
if (!isTransformStreamDefaultController(this)) throw new TypeError("Invalid this");
|
|
89
|
+
const { stream } = this[kState];
|
|
90
|
+
const { readable } = stream[kState];
|
|
91
|
+
const readableController = readable[kState].controller;
|
|
92
|
+
return readableStreamDefaultControllerGetDesiredSize(readableController);
|
|
93
|
+
}
|
|
94
|
+
enqueue(chunk) {
|
|
95
|
+
if (!isTransformStreamDefaultController(this)) throw new TypeError("Invalid this");
|
|
96
|
+
transformStreamDefaultControllerEnqueue(this, chunk);
|
|
97
|
+
}
|
|
98
|
+
error(reason) {
|
|
99
|
+
if (!isTransformStreamDefaultController(this)) throw new TypeError("Invalid this");
|
|
100
|
+
transformStreamDefaultControllerError(this, reason);
|
|
101
|
+
}
|
|
102
|
+
terminate() {
|
|
103
|
+
if (!isTransformStreamDefaultController(this)) throw new TypeError("Invalid this");
|
|
104
|
+
transformStreamDefaultControllerTerminate(this);
|
|
105
|
+
}
|
|
106
|
+
get [Symbol.toStringTag]() {
|
|
107
|
+
return "TransformStreamDefaultController";
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
const isTransformStream = isBrandCheck("TransformStream");
|
|
111
|
+
const isTransformStreamDefaultController = isBrandCheck("TransformStreamDefaultController");
|
|
112
|
+
async function defaultTransformAlgorithm(chunk, controller) {
|
|
113
|
+
transformStreamDefaultControllerEnqueue(controller, chunk);
|
|
114
|
+
}
|
|
115
|
+
function initializeTransformStream(stream, startPromise, writableHighWaterMark, writableSizeAlgorithm, readableHighWaterMark, readableSizeAlgorithm) {
|
|
116
|
+
const startAlgorithm = () => startPromise.promise;
|
|
117
|
+
const writable = createWritableStream(
|
|
118
|
+
startAlgorithm,
|
|
119
|
+
(chunk) => transformStreamDefaultSinkWriteAlgorithm(stream, chunk),
|
|
120
|
+
() => transformStreamDefaultSinkCloseAlgorithm(stream),
|
|
121
|
+
(reason) => transformStreamDefaultSinkAbortAlgorithm(stream, reason),
|
|
122
|
+
writableHighWaterMark,
|
|
123
|
+
writableSizeAlgorithm
|
|
124
|
+
);
|
|
125
|
+
const readable = createReadableStream(
|
|
126
|
+
startAlgorithm,
|
|
127
|
+
() => transformStreamDefaultSourcePullAlgorithm(stream),
|
|
128
|
+
(reason) => transformStreamDefaultSourceCancelAlgorithm(stream, reason),
|
|
129
|
+
readableHighWaterMark,
|
|
130
|
+
readableSizeAlgorithm
|
|
131
|
+
);
|
|
132
|
+
stream[kState] = {
|
|
133
|
+
readable,
|
|
134
|
+
writable,
|
|
135
|
+
controller: void 0,
|
|
136
|
+
backpressure: void 0,
|
|
137
|
+
backpressureChange: {
|
|
138
|
+
promise: void 0,
|
|
139
|
+
resolve: void 0,
|
|
140
|
+
reject: void 0
|
|
141
|
+
}
|
|
142
|
+
};
|
|
143
|
+
transformStreamSetBackpressure(stream, true);
|
|
144
|
+
}
|
|
145
|
+
function transformStreamError(stream, error) {
|
|
146
|
+
const { readable } = stream[kState];
|
|
147
|
+
readableStreamDefaultControllerError(readable[kState].controller, error);
|
|
148
|
+
transformStreamErrorWritableAndUnblockWrite(stream, error);
|
|
149
|
+
}
|
|
150
|
+
function transformStreamErrorWritableAndUnblockWrite(stream, error) {
|
|
151
|
+
const { controller, writable } = stream[kState];
|
|
152
|
+
transformStreamDefaultControllerClearAlgorithms(controller);
|
|
153
|
+
writableStreamDefaultControllerErrorIfNeeded(writable[kState].controller, error);
|
|
154
|
+
transformStreamUnblockWrite(stream);
|
|
155
|
+
}
|
|
156
|
+
function transformStreamUnblockWrite(stream) {
|
|
157
|
+
if (stream[kState].backpressure) {
|
|
158
|
+
transformStreamSetBackpressure(stream, false);
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
function transformStreamSetBackpressure(stream, backpressure) {
|
|
162
|
+
if (stream[kState].backpressureChange.promise !== void 0) {
|
|
163
|
+
stream[kState].backpressureChange.resolve?.();
|
|
164
|
+
}
|
|
165
|
+
stream[kState].backpressureChange = Promise.withResolvers();
|
|
166
|
+
stream[kState].backpressure = backpressure;
|
|
167
|
+
}
|
|
168
|
+
function setupTransformStreamDefaultController(stream, controller, transformAlgorithm, flushAlgorithm, cancelAlgorithm) {
|
|
169
|
+
controller[kState] = {
|
|
170
|
+
stream,
|
|
171
|
+
transformAlgorithm,
|
|
172
|
+
flushAlgorithm,
|
|
173
|
+
cancelAlgorithm,
|
|
174
|
+
finishPromise: void 0
|
|
175
|
+
};
|
|
176
|
+
stream[kState].controller = controller;
|
|
177
|
+
}
|
|
178
|
+
function setupTransformStreamDefaultControllerFromTransformer(stream, transformer) {
|
|
179
|
+
const controller = new TransformStreamDefaultController(kSkipThrow);
|
|
180
|
+
const transform = transformer?.transform;
|
|
181
|
+
const flush = transformer?.flush;
|
|
182
|
+
const cancel = transformer?.cancel;
|
|
183
|
+
const transformAlgorithm = transform ? createPromiseCallback("transformer.transform", transform, transformer) : defaultTransformAlgorithm;
|
|
184
|
+
const flushAlgorithm = flush ? createPromiseCallback("transformer.flush", flush, transformer) : nonOpFlush;
|
|
185
|
+
const cancelAlgorithm = cancel ? createPromiseCallback("transformer.cancel", cancel, transformer) : nonOpCancel;
|
|
186
|
+
setupTransformStreamDefaultController(
|
|
187
|
+
stream,
|
|
188
|
+
controller,
|
|
189
|
+
transformAlgorithm,
|
|
190
|
+
flushAlgorithm,
|
|
191
|
+
cancelAlgorithm
|
|
192
|
+
);
|
|
193
|
+
}
|
|
194
|
+
function transformStreamDefaultControllerClearAlgorithms(controller) {
|
|
195
|
+
controller[kState].transformAlgorithm = void 0;
|
|
196
|
+
controller[kState].flushAlgorithm = void 0;
|
|
197
|
+
controller[kState].cancelAlgorithm = void 0;
|
|
198
|
+
}
|
|
199
|
+
function transformStreamDefaultControllerEnqueue(controller, chunk) {
|
|
200
|
+
const { stream } = controller[kState];
|
|
201
|
+
const { readable } = stream[kState];
|
|
202
|
+
const readableController = readable[kState].controller;
|
|
203
|
+
if (!readableStreamDefaultControllerCanCloseOrEnqueue(readableController)) {
|
|
204
|
+
throw new TypeError("Unable to enqueue");
|
|
205
|
+
}
|
|
206
|
+
try {
|
|
207
|
+
readableStreamDefaultControllerEnqueue(readableController, chunk);
|
|
208
|
+
} catch (error) {
|
|
209
|
+
transformStreamErrorWritableAndUnblockWrite(stream, error);
|
|
210
|
+
throw readable[kState].storedError;
|
|
211
|
+
}
|
|
212
|
+
const backpressure = readableStreamDefaultControllerHasBackpressure(readableController);
|
|
213
|
+
if (backpressure !== stream[kState].backpressure) {
|
|
214
|
+
transformStreamSetBackpressure(stream, true);
|
|
215
|
+
}
|
|
216
|
+
}
|
|
217
|
+
function transformStreamDefaultControllerError(controller, error) {
|
|
218
|
+
transformStreamError(controller[kState].stream, error);
|
|
219
|
+
}
|
|
220
|
+
async function transformStreamDefaultControllerPerformTransform(controller, chunk) {
|
|
221
|
+
try {
|
|
222
|
+
const transformAlgorithm = controller[kState].transformAlgorithm;
|
|
223
|
+
if (transformAlgorithm === void 0) return;
|
|
224
|
+
return await transformAlgorithm(chunk, controller);
|
|
225
|
+
} catch (error) {
|
|
226
|
+
transformStreamError(controller[kState].stream, error);
|
|
227
|
+
throw error;
|
|
228
|
+
}
|
|
229
|
+
}
|
|
230
|
+
function transformStreamDefaultControllerTerminate(controller) {
|
|
231
|
+
const { stream } = controller[kState];
|
|
232
|
+
const { readable } = stream[kState];
|
|
233
|
+
readableStreamDefaultControllerClose(readable[kState].controller);
|
|
234
|
+
transformStreamErrorWritableAndUnblockWrite(stream, new TypeError("TransformStream has been terminated"));
|
|
235
|
+
}
|
|
236
|
+
function transformStreamDefaultSinkWriteAlgorithm(stream, chunk) {
|
|
237
|
+
const { controller } = stream[kState];
|
|
238
|
+
if (stream[kState].backpressure) {
|
|
239
|
+
const backpressureChange = stream[kState].backpressureChange.promise;
|
|
240
|
+
return backpressureChange.then(() => {
|
|
241
|
+
const { writable } = stream[kState];
|
|
242
|
+
if (writable[kState].state === "erroring") {
|
|
243
|
+
throw writable[kState].storedError;
|
|
244
|
+
}
|
|
245
|
+
return transformStreamDefaultControllerPerformTransform(controller, chunk);
|
|
246
|
+
});
|
|
247
|
+
}
|
|
248
|
+
return transformStreamDefaultControllerPerformTransform(controller, chunk);
|
|
249
|
+
}
|
|
250
|
+
async function transformStreamDefaultSinkAbortAlgorithm(stream, reason) {
|
|
251
|
+
const { controller, readable } = stream[kState];
|
|
252
|
+
if (controller[kState].finishPromise !== void 0) {
|
|
253
|
+
return controller[kState].finishPromise;
|
|
254
|
+
}
|
|
255
|
+
const { promise, resolve, reject } = Promise.withResolvers();
|
|
256
|
+
controller[kState].finishPromise = promise;
|
|
257
|
+
const cancelPromise = controller[kState].cancelAlgorithm(reason);
|
|
258
|
+
transformStreamDefaultControllerClearAlgorithms(controller);
|
|
259
|
+
cancelPromise.then(
|
|
260
|
+
() => {
|
|
261
|
+
if (readable[kState].state === "errored") {
|
|
262
|
+
reject(readable[kState].storedError);
|
|
263
|
+
} else {
|
|
264
|
+
readableStreamDefaultControllerError(readable[kState].controller, reason);
|
|
265
|
+
resolve();
|
|
266
|
+
}
|
|
267
|
+
},
|
|
268
|
+
(error) => {
|
|
269
|
+
readableStreamDefaultControllerError(readable[kState].controller, error);
|
|
270
|
+
reject(error);
|
|
271
|
+
}
|
|
272
|
+
);
|
|
273
|
+
return controller[kState].finishPromise;
|
|
274
|
+
}
|
|
275
|
+
function transformStreamDefaultSinkCloseAlgorithm(stream) {
|
|
276
|
+
const { readable, controller } = stream[kState];
|
|
277
|
+
if (controller[kState].finishPromise !== void 0) {
|
|
278
|
+
return controller[kState].finishPromise;
|
|
279
|
+
}
|
|
280
|
+
const { promise, resolve, reject } = Promise.withResolvers();
|
|
281
|
+
controller[kState].finishPromise = promise;
|
|
282
|
+
const flushPromise = controller[kState].flushAlgorithm(controller);
|
|
283
|
+
transformStreamDefaultControllerClearAlgorithms(controller);
|
|
284
|
+
flushPromise.then(
|
|
285
|
+
() => {
|
|
286
|
+
if (readable[kState].state === "errored") {
|
|
287
|
+
reject(readable[kState].storedError);
|
|
288
|
+
} else {
|
|
289
|
+
readableStreamDefaultControllerClose(readable[kState].controller);
|
|
290
|
+
resolve();
|
|
291
|
+
}
|
|
292
|
+
},
|
|
293
|
+
(error) => {
|
|
294
|
+
readableStreamDefaultControllerError(readable[kState].controller, error);
|
|
295
|
+
reject(error);
|
|
296
|
+
}
|
|
297
|
+
);
|
|
298
|
+
return controller[kState].finishPromise;
|
|
299
|
+
}
|
|
300
|
+
function transformStreamDefaultSourcePullAlgorithm(stream) {
|
|
301
|
+
transformStreamSetBackpressure(stream, false);
|
|
302
|
+
return stream[kState].backpressureChange.promise;
|
|
303
|
+
}
|
|
304
|
+
function transformStreamDefaultSourceCancelAlgorithm(stream, reason) {
|
|
305
|
+
const { controller, writable } = stream[kState];
|
|
306
|
+
if (controller[kState].finishPromise !== void 0) {
|
|
307
|
+
return controller[kState].finishPromise;
|
|
308
|
+
}
|
|
309
|
+
const { promise, resolve, reject } = Promise.withResolvers();
|
|
310
|
+
controller[kState].finishPromise = promise;
|
|
311
|
+
const cancelPromise = controller[kState].cancelAlgorithm(reason);
|
|
312
|
+
transformStreamDefaultControllerClearAlgorithms(controller);
|
|
313
|
+
cancelPromise.then(
|
|
314
|
+
() => {
|
|
315
|
+
if (writable[kState].state === "errored") {
|
|
316
|
+
reject(writable[kState].storedError);
|
|
317
|
+
} else {
|
|
318
|
+
writableStreamDefaultControllerErrorIfNeeded(writable[kState].controller, reason);
|
|
319
|
+
transformStreamUnblockWrite(stream);
|
|
320
|
+
resolve();
|
|
321
|
+
}
|
|
322
|
+
},
|
|
323
|
+
(error) => {
|
|
324
|
+
writableStreamDefaultControllerErrorIfNeeded(writable[kState].controller, error);
|
|
325
|
+
transformStreamUnblockWrite(stream);
|
|
326
|
+
reject(error);
|
|
327
|
+
}
|
|
328
|
+
);
|
|
329
|
+
return controller[kState].finishPromise;
|
|
330
|
+
}
|
|
331
|
+
export {
|
|
332
|
+
TransformStream,
|
|
333
|
+
TransformStreamDefaultController,
|
|
334
|
+
isTransformStream,
|
|
335
|
+
isTransformStreamDefaultController
|
|
336
|
+
};
|
package/lib/esm/util.js
ADDED
|
@@ -0,0 +1,161 @@
|
|
|
1
|
+
const kState = /* @__PURE__ */ Symbol("kState");
|
|
2
|
+
const kType = /* @__PURE__ */ Symbol("kType");
|
|
3
|
+
function isBrandCheck(brand) {
|
|
4
|
+
return (value) => {
|
|
5
|
+
return value != null && typeof value === "object" && value[kState] !== void 0 && value[kType] === brand;
|
|
6
|
+
};
|
|
7
|
+
}
|
|
8
|
+
function dequeueValue(controller) {
|
|
9
|
+
const { value, size } = controller[kState].queue.shift();
|
|
10
|
+
controller[kState].queueTotalSize = Math.max(0, controller[kState].queueTotalSize - size);
|
|
11
|
+
return value;
|
|
12
|
+
}
|
|
13
|
+
function resetQueue(controller) {
|
|
14
|
+
controller[kState].queue = [];
|
|
15
|
+
controller[kState].queueTotalSize = 0;
|
|
16
|
+
}
|
|
17
|
+
function peekQueueValue(controller) {
|
|
18
|
+
return controller[kState].queue[0].value;
|
|
19
|
+
}
|
|
20
|
+
function enqueueValueWithSize(controller, value, size) {
|
|
21
|
+
size = +size;
|
|
22
|
+
if (typeof size !== "number" || size < 0 || Number.isNaN(size) || size === Infinity) {
|
|
23
|
+
throw new RangeError(`Invalid size: ${size}`);
|
|
24
|
+
}
|
|
25
|
+
controller[kState].queue.push({ value, size });
|
|
26
|
+
controller[kState].queueTotalSize += size;
|
|
27
|
+
}
|
|
28
|
+
function extractHighWaterMark(value, defaultHWM) {
|
|
29
|
+
if (value === void 0) return defaultHWM;
|
|
30
|
+
value = +value;
|
|
31
|
+
if (typeof value !== "number" || Number.isNaN(value) || value < 0) {
|
|
32
|
+
throw new RangeError(`Invalid highWaterMark: ${value}`);
|
|
33
|
+
}
|
|
34
|
+
return value;
|
|
35
|
+
}
|
|
36
|
+
function extractSizeAlgorithm(size) {
|
|
37
|
+
if (size === void 0) return () => 1;
|
|
38
|
+
if (typeof size !== "function") {
|
|
39
|
+
throw new TypeError("strategy.size must be a function");
|
|
40
|
+
}
|
|
41
|
+
return size;
|
|
42
|
+
}
|
|
43
|
+
function cloneAsUint8Array(view) {
|
|
44
|
+
const buffer = view.buffer;
|
|
45
|
+
const byteOffset = view.byteOffset;
|
|
46
|
+
const byteLength = view.byteLength;
|
|
47
|
+
return new Uint8Array(buffer.slice(byteOffset, byteOffset + byteLength));
|
|
48
|
+
}
|
|
49
|
+
function ArrayBufferViewGetBuffer(view) {
|
|
50
|
+
return view.buffer;
|
|
51
|
+
}
|
|
52
|
+
function ArrayBufferViewGetByteLength(view) {
|
|
53
|
+
return view.byteLength;
|
|
54
|
+
}
|
|
55
|
+
function ArrayBufferViewGetByteOffset(view) {
|
|
56
|
+
return view.byteOffset;
|
|
57
|
+
}
|
|
58
|
+
function setPromiseHandled(promise) {
|
|
59
|
+
promise.then(() => {
|
|
60
|
+
}, () => {
|
|
61
|
+
});
|
|
62
|
+
}
|
|
63
|
+
function createPromiseCallback(name, fn, thisArg) {
|
|
64
|
+
if (typeof fn !== "function") {
|
|
65
|
+
throw new TypeError(`${name} must be a function`);
|
|
66
|
+
}
|
|
67
|
+
return async (...args) => fn.call(thisArg, ...args);
|
|
68
|
+
}
|
|
69
|
+
async function nonOpFlush() {
|
|
70
|
+
}
|
|
71
|
+
function nonOpStart() {
|
|
72
|
+
}
|
|
73
|
+
async function nonOpPull() {
|
|
74
|
+
}
|
|
75
|
+
async function nonOpCancel() {
|
|
76
|
+
}
|
|
77
|
+
async function nonOpWrite() {
|
|
78
|
+
}
|
|
79
|
+
const AsyncIteratorPrototype = Object.getPrototypeOf(
|
|
80
|
+
Object.getPrototypeOf(async function* () {
|
|
81
|
+
}).prototype
|
|
82
|
+
);
|
|
83
|
+
const AsyncIterator = {
|
|
84
|
+
__proto__: AsyncIteratorPrototype,
|
|
85
|
+
next: void 0,
|
|
86
|
+
return: void 0
|
|
87
|
+
};
|
|
88
|
+
function createAsyncFromSyncIterator(syncIteratorRecord) {
|
|
89
|
+
const syncIterable = {
|
|
90
|
+
[Symbol.iterator]: () => syncIteratorRecord.iterator
|
|
91
|
+
};
|
|
92
|
+
const asyncIterator = (async function* () {
|
|
93
|
+
return yield* syncIterable;
|
|
94
|
+
})();
|
|
95
|
+
const nextMethod = asyncIterator.next;
|
|
96
|
+
return { iterator: asyncIterator, nextMethod, done: false };
|
|
97
|
+
}
|
|
98
|
+
function getIterator(obj, kind = "sync", method) {
|
|
99
|
+
if (method === void 0) {
|
|
100
|
+
if (kind === "async") {
|
|
101
|
+
method = obj[Symbol.asyncIterator];
|
|
102
|
+
if (method == null) {
|
|
103
|
+
const syncMethod = obj[Symbol.iterator];
|
|
104
|
+
if (syncMethod === void 0) {
|
|
105
|
+
throw new TypeError("Object is not iterable");
|
|
106
|
+
}
|
|
107
|
+
const syncIteratorRecord = getIterator(obj, "sync", syncMethod);
|
|
108
|
+
return createAsyncFromSyncIterator(syncIteratorRecord);
|
|
109
|
+
}
|
|
110
|
+
} else {
|
|
111
|
+
method = obj[Symbol.iterator];
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
if (method === void 0) {
|
|
115
|
+
throw new TypeError("Object is not iterable");
|
|
116
|
+
}
|
|
117
|
+
const iterator = method.call(obj);
|
|
118
|
+
if (typeof iterator !== "object" || iterator === null) {
|
|
119
|
+
throw new TypeError("The iterator method must return an object");
|
|
120
|
+
}
|
|
121
|
+
const nextMethod = iterator.next;
|
|
122
|
+
return { iterator, nextMethod, done: false };
|
|
123
|
+
}
|
|
124
|
+
function iteratorNext(iteratorRecord, value) {
|
|
125
|
+
let result;
|
|
126
|
+
if (value === void 0) {
|
|
127
|
+
result = iteratorRecord.nextMethod.call(iteratorRecord.iterator);
|
|
128
|
+
} else {
|
|
129
|
+
result = iteratorRecord.nextMethod.call(iteratorRecord.iterator, value);
|
|
130
|
+
}
|
|
131
|
+
if (typeof result !== "object" || result === null) {
|
|
132
|
+
throw new TypeError("The iterator.next() method must return an object");
|
|
133
|
+
}
|
|
134
|
+
return result;
|
|
135
|
+
}
|
|
136
|
+
export {
|
|
137
|
+
ArrayBufferViewGetBuffer,
|
|
138
|
+
ArrayBufferViewGetByteLength,
|
|
139
|
+
ArrayBufferViewGetByteOffset,
|
|
140
|
+
AsyncIterator,
|
|
141
|
+
cloneAsUint8Array,
|
|
142
|
+
createAsyncFromSyncIterator,
|
|
143
|
+
createPromiseCallback,
|
|
144
|
+
dequeueValue,
|
|
145
|
+
enqueueValueWithSize,
|
|
146
|
+
extractHighWaterMark,
|
|
147
|
+
extractSizeAlgorithm,
|
|
148
|
+
getIterator,
|
|
149
|
+
isBrandCheck,
|
|
150
|
+
iteratorNext,
|
|
151
|
+
kState,
|
|
152
|
+
kType,
|
|
153
|
+
nonOpCancel,
|
|
154
|
+
nonOpFlush,
|
|
155
|
+
nonOpPull,
|
|
156
|
+
nonOpStart,
|
|
157
|
+
nonOpWrite,
|
|
158
|
+
peekQueueValue,
|
|
159
|
+
resetQueue,
|
|
160
|
+
setPromiseHandled
|
|
161
|
+
};
|