@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,676 @@
|
|
|
1
|
+
import {
|
|
2
|
+
kState,
|
|
3
|
+
kType,
|
|
4
|
+
isBrandCheck,
|
|
5
|
+
createPromiseCallback,
|
|
6
|
+
dequeueValue,
|
|
7
|
+
enqueueValueWithSize,
|
|
8
|
+
extractHighWaterMark,
|
|
9
|
+
extractSizeAlgorithm,
|
|
10
|
+
peekQueueValue,
|
|
11
|
+
resetQueue,
|
|
12
|
+
setPromiseHandled,
|
|
13
|
+
nonOpCancel,
|
|
14
|
+
nonOpStart,
|
|
15
|
+
nonOpWrite
|
|
16
|
+
} from "./util.js";
|
|
17
|
+
const _AbortController = typeof globalThis.AbortController === "function" ? globalThis.AbortController : class AbortControllerShim {
|
|
18
|
+
signal = { aborted: false, reason: void 0, addEventListener() {
|
|
19
|
+
}, removeEventListener() {
|
|
20
|
+
} };
|
|
21
|
+
abort(reason) {
|
|
22
|
+
this.signal.aborted = true;
|
|
23
|
+
this.signal.reason = reason;
|
|
24
|
+
}
|
|
25
|
+
};
|
|
26
|
+
const kAbort = /* @__PURE__ */ Symbol("kAbort");
|
|
27
|
+
const kCloseSentinel = /* @__PURE__ */ Symbol("kCloseSentinel");
|
|
28
|
+
const kError = /* @__PURE__ */ Symbol("kError");
|
|
29
|
+
const kSkipThrow = /* @__PURE__ */ Symbol("kSkipThrow");
|
|
30
|
+
class WritableStream {
|
|
31
|
+
[kType] = "WritableStream";
|
|
32
|
+
[kState];
|
|
33
|
+
constructor(sink = {}, strategy = {}) {
|
|
34
|
+
if (sink != null && typeof sink !== "object") {
|
|
35
|
+
throw new TypeError("sink must be an object");
|
|
36
|
+
}
|
|
37
|
+
if (strategy != null && typeof strategy !== "object") {
|
|
38
|
+
throw new TypeError("strategy must be an object");
|
|
39
|
+
}
|
|
40
|
+
const type = sink?.type;
|
|
41
|
+
if (type !== void 0) {
|
|
42
|
+
throw new RangeError(`Invalid type: ${type}`);
|
|
43
|
+
}
|
|
44
|
+
this[kState] = createWritableStreamState();
|
|
45
|
+
const size = extractSizeAlgorithm(strategy?.size);
|
|
46
|
+
const highWaterMark = extractHighWaterMark(strategy?.highWaterMark, 1);
|
|
47
|
+
setupWritableStreamDefaultControllerFromSink(this, sink, highWaterMark, size);
|
|
48
|
+
}
|
|
49
|
+
get locked() {
|
|
50
|
+
if (!isWritableStream(this)) throw new TypeError("Invalid this");
|
|
51
|
+
return isWritableStreamLocked(this);
|
|
52
|
+
}
|
|
53
|
+
abort(reason) {
|
|
54
|
+
if (!isWritableStream(this)) return Promise.reject(new TypeError("Invalid this"));
|
|
55
|
+
if (isWritableStreamLocked(this)) {
|
|
56
|
+
return Promise.reject(new TypeError("WritableStream is locked"));
|
|
57
|
+
}
|
|
58
|
+
return writableStreamAbort(this, reason);
|
|
59
|
+
}
|
|
60
|
+
close() {
|
|
61
|
+
if (!isWritableStream(this)) return Promise.reject(new TypeError("Invalid this"));
|
|
62
|
+
if (isWritableStreamLocked(this)) {
|
|
63
|
+
return Promise.reject(new TypeError("WritableStream is locked"));
|
|
64
|
+
}
|
|
65
|
+
if (writableStreamCloseQueuedOrInFlight(this)) {
|
|
66
|
+
return Promise.reject(new TypeError("Failure closing WritableStream"));
|
|
67
|
+
}
|
|
68
|
+
return writableStreamClose(this);
|
|
69
|
+
}
|
|
70
|
+
getWriter() {
|
|
71
|
+
if (!isWritableStream(this)) throw new TypeError("Invalid this");
|
|
72
|
+
return new WritableStreamDefaultWriter(this);
|
|
73
|
+
}
|
|
74
|
+
get [Symbol.toStringTag]() {
|
|
75
|
+
return "WritableStream";
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
class WritableStreamDefaultWriter {
|
|
79
|
+
[kType] = "WritableStreamDefaultWriter";
|
|
80
|
+
[kState];
|
|
81
|
+
constructor(stream) {
|
|
82
|
+
if (!isWritableStream(stream)) {
|
|
83
|
+
throw new TypeError("Expected a WritableStream");
|
|
84
|
+
}
|
|
85
|
+
this[kState] = {
|
|
86
|
+
stream: void 0,
|
|
87
|
+
close: { promise: void 0, resolve: void 0, reject: void 0 },
|
|
88
|
+
ready: { promise: void 0, resolve: void 0, reject: void 0 }
|
|
89
|
+
};
|
|
90
|
+
setupWritableStreamDefaultWriter(this, stream);
|
|
91
|
+
}
|
|
92
|
+
get closed() {
|
|
93
|
+
if (!isWritableStreamDefaultWriter(this)) return Promise.reject(new TypeError("Invalid this"));
|
|
94
|
+
return this[kState].close.promise;
|
|
95
|
+
}
|
|
96
|
+
get desiredSize() {
|
|
97
|
+
if (!isWritableStreamDefaultWriter(this)) throw new TypeError("Invalid this");
|
|
98
|
+
if (this[kState].stream === void 0) {
|
|
99
|
+
throw new TypeError("Writer is not bound to a WritableStream");
|
|
100
|
+
}
|
|
101
|
+
return writableStreamDefaultWriterGetDesiredSize(this);
|
|
102
|
+
}
|
|
103
|
+
get ready() {
|
|
104
|
+
if (!isWritableStreamDefaultWriter(this)) return Promise.reject(new TypeError("Invalid this"));
|
|
105
|
+
return this[kState].ready.promise;
|
|
106
|
+
}
|
|
107
|
+
abort(reason) {
|
|
108
|
+
if (!isWritableStreamDefaultWriter(this)) return Promise.reject(new TypeError("Invalid this"));
|
|
109
|
+
if (this[kState].stream === void 0) {
|
|
110
|
+
return Promise.reject(new TypeError("Writer is not bound to a WritableStream"));
|
|
111
|
+
}
|
|
112
|
+
return writableStreamDefaultWriterAbort(this, reason);
|
|
113
|
+
}
|
|
114
|
+
close() {
|
|
115
|
+
if (!isWritableStreamDefaultWriter(this)) return Promise.reject(new TypeError("Invalid this"));
|
|
116
|
+
const { stream } = this[kState];
|
|
117
|
+
if (stream === void 0) {
|
|
118
|
+
return Promise.reject(new TypeError("Writer is not bound to a WritableStream"));
|
|
119
|
+
}
|
|
120
|
+
if (writableStreamCloseQueuedOrInFlight(stream)) {
|
|
121
|
+
return Promise.reject(new TypeError("Failure to close WritableStream"));
|
|
122
|
+
}
|
|
123
|
+
return writableStreamDefaultWriterClose(this);
|
|
124
|
+
}
|
|
125
|
+
releaseLock() {
|
|
126
|
+
if (!isWritableStreamDefaultWriter(this)) throw new TypeError("Invalid this");
|
|
127
|
+
const { stream } = this[kState];
|
|
128
|
+
if (stream === void 0) return;
|
|
129
|
+
writableStreamDefaultWriterRelease(this);
|
|
130
|
+
}
|
|
131
|
+
write(chunk) {
|
|
132
|
+
if (!isWritableStreamDefaultWriter(this)) return Promise.reject(new TypeError("Invalid this"));
|
|
133
|
+
if (this[kState].stream === void 0) {
|
|
134
|
+
return Promise.reject(new TypeError("Writer is not bound to a WritableStream"));
|
|
135
|
+
}
|
|
136
|
+
return writableStreamDefaultWriterWrite(this, chunk);
|
|
137
|
+
}
|
|
138
|
+
get [Symbol.toStringTag]() {
|
|
139
|
+
return "WritableStreamDefaultWriter";
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
class WritableStreamDefaultController {
|
|
143
|
+
[kType] = "WritableStreamDefaultController";
|
|
144
|
+
[kState];
|
|
145
|
+
constructor(skipThrowSymbol) {
|
|
146
|
+
if (skipThrowSymbol !== kSkipThrow) {
|
|
147
|
+
throw new TypeError("Illegal constructor");
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
[kAbort](reason) {
|
|
151
|
+
const result = this[kState].abortAlgorithm(reason);
|
|
152
|
+
writableStreamDefaultControllerClearAlgorithms(this);
|
|
153
|
+
return result;
|
|
154
|
+
}
|
|
155
|
+
[kError]() {
|
|
156
|
+
resetQueue(this);
|
|
157
|
+
}
|
|
158
|
+
get signal() {
|
|
159
|
+
if (!isWritableStreamDefaultController(this)) throw new TypeError("Invalid this");
|
|
160
|
+
return this[kState].abortController.signal;
|
|
161
|
+
}
|
|
162
|
+
error(error) {
|
|
163
|
+
if (!isWritableStreamDefaultController(this)) throw new TypeError("Invalid this");
|
|
164
|
+
if (this[kState].stream[kState].state !== "writable") return;
|
|
165
|
+
writableStreamDefaultControllerError(this, error);
|
|
166
|
+
}
|
|
167
|
+
get [Symbol.toStringTag]() {
|
|
168
|
+
return "WritableStreamDefaultController";
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
const isWritableStream = isBrandCheck("WritableStream");
|
|
172
|
+
const isWritableStreamDefaultWriter = isBrandCheck("WritableStreamDefaultWriter");
|
|
173
|
+
const isWritableStreamDefaultController = isBrandCheck("WritableStreamDefaultController");
|
|
174
|
+
function createEmptyPromiseRecord() {
|
|
175
|
+
return { promise: void 0, resolve: void 0, reject: void 0 };
|
|
176
|
+
}
|
|
177
|
+
function createWritableStreamState() {
|
|
178
|
+
return {
|
|
179
|
+
close: Promise.withResolvers(),
|
|
180
|
+
closeRequest: createEmptyPromiseRecord(),
|
|
181
|
+
inFlightWriteRequest: createEmptyPromiseRecord(),
|
|
182
|
+
inFlightCloseRequest: createEmptyPromiseRecord(),
|
|
183
|
+
pendingAbortRequest: {
|
|
184
|
+
abort: createEmptyPromiseRecord(),
|
|
185
|
+
reason: void 0,
|
|
186
|
+
wasAlreadyErroring: false
|
|
187
|
+
},
|
|
188
|
+
backpressure: false,
|
|
189
|
+
controller: void 0,
|
|
190
|
+
state: "writable",
|
|
191
|
+
storedError: void 0,
|
|
192
|
+
writeRequests: [],
|
|
193
|
+
writer: void 0
|
|
194
|
+
};
|
|
195
|
+
}
|
|
196
|
+
function isWritableStreamLocked(stream) {
|
|
197
|
+
return stream[kState].writer !== void 0;
|
|
198
|
+
}
|
|
199
|
+
function setupWritableStreamDefaultWriter(writer, stream) {
|
|
200
|
+
if (isWritableStreamLocked(stream)) {
|
|
201
|
+
throw new TypeError("WritableStream is locked");
|
|
202
|
+
}
|
|
203
|
+
writer[kState].stream = stream;
|
|
204
|
+
stream[kState].writer = writer;
|
|
205
|
+
switch (stream[kState].state) {
|
|
206
|
+
case "writable":
|
|
207
|
+
if (!writableStreamCloseQueuedOrInFlight(stream) && stream[kState].backpressure) {
|
|
208
|
+
writer[kState].ready = Promise.withResolvers();
|
|
209
|
+
} else {
|
|
210
|
+
writer[kState].ready = {
|
|
211
|
+
promise: Promise.resolve(),
|
|
212
|
+
resolve: void 0,
|
|
213
|
+
reject: void 0
|
|
214
|
+
};
|
|
215
|
+
}
|
|
216
|
+
writer[kState].close = Promise.withResolvers();
|
|
217
|
+
break;
|
|
218
|
+
case "erroring":
|
|
219
|
+
writer[kState].ready = {
|
|
220
|
+
promise: Promise.reject(stream[kState].storedError),
|
|
221
|
+
resolve: void 0,
|
|
222
|
+
reject: void 0
|
|
223
|
+
};
|
|
224
|
+
setPromiseHandled(writer[kState].ready.promise);
|
|
225
|
+
writer[kState].close = Promise.withResolvers();
|
|
226
|
+
break;
|
|
227
|
+
case "closed":
|
|
228
|
+
writer[kState].ready = {
|
|
229
|
+
promise: Promise.resolve(),
|
|
230
|
+
resolve: void 0,
|
|
231
|
+
reject: void 0
|
|
232
|
+
};
|
|
233
|
+
writer[kState].close = {
|
|
234
|
+
promise: Promise.resolve(),
|
|
235
|
+
resolve: void 0,
|
|
236
|
+
reject: void 0
|
|
237
|
+
};
|
|
238
|
+
break;
|
|
239
|
+
default:
|
|
240
|
+
writer[kState].ready = {
|
|
241
|
+
promise: Promise.reject(stream[kState].storedError),
|
|
242
|
+
resolve: void 0,
|
|
243
|
+
reject: void 0
|
|
244
|
+
};
|
|
245
|
+
writer[kState].close = {
|
|
246
|
+
promise: Promise.reject(stream[kState].storedError),
|
|
247
|
+
resolve: void 0,
|
|
248
|
+
reject: void 0
|
|
249
|
+
};
|
|
250
|
+
setPromiseHandled(writer[kState].ready.promise);
|
|
251
|
+
setPromiseHandled(writer[kState].close.promise);
|
|
252
|
+
}
|
|
253
|
+
}
|
|
254
|
+
function writableStreamAbort(stream, reason) {
|
|
255
|
+
const { state, controller } = stream[kState];
|
|
256
|
+
if (state === "closed" || state === "errored") return Promise.resolve();
|
|
257
|
+
controller[kState].abortController.abort(reason);
|
|
258
|
+
if (stream[kState].pendingAbortRequest.abort.promise !== void 0) {
|
|
259
|
+
return stream[kState].pendingAbortRequest.abort.promise;
|
|
260
|
+
}
|
|
261
|
+
let wasAlreadyErroring = false;
|
|
262
|
+
if (state === "erroring") {
|
|
263
|
+
wasAlreadyErroring = true;
|
|
264
|
+
reason = void 0;
|
|
265
|
+
}
|
|
266
|
+
const abort = Promise.withResolvers();
|
|
267
|
+
stream[kState].pendingAbortRequest = { abort, reason, wasAlreadyErroring };
|
|
268
|
+
if (!wasAlreadyErroring) writableStreamStartErroring(stream, reason);
|
|
269
|
+
return abort.promise;
|
|
270
|
+
}
|
|
271
|
+
function writableStreamClose(stream) {
|
|
272
|
+
const { state, writer, backpressure, controller } = stream[kState];
|
|
273
|
+
if (state === "closed" || state === "errored") {
|
|
274
|
+
return Promise.reject(new TypeError("WritableStream is closed"));
|
|
275
|
+
}
|
|
276
|
+
stream[kState].closeRequest = Promise.withResolvers();
|
|
277
|
+
const { promise } = stream[kState].closeRequest;
|
|
278
|
+
if (writer !== void 0 && backpressure && state === "writable") {
|
|
279
|
+
writer[kState].ready.resolve?.();
|
|
280
|
+
}
|
|
281
|
+
writableStreamDefaultControllerClose(controller);
|
|
282
|
+
return promise;
|
|
283
|
+
}
|
|
284
|
+
function writableStreamUpdateBackpressure(stream, backpressure) {
|
|
285
|
+
const { writer } = stream[kState];
|
|
286
|
+
if (writer !== void 0 && stream[kState].backpressure !== backpressure) {
|
|
287
|
+
if (backpressure) {
|
|
288
|
+
writer[kState].ready = Promise.withResolvers();
|
|
289
|
+
} else {
|
|
290
|
+
writer[kState].ready.resolve?.();
|
|
291
|
+
}
|
|
292
|
+
}
|
|
293
|
+
stream[kState].backpressure = backpressure;
|
|
294
|
+
}
|
|
295
|
+
function writableStreamStartErroring(stream, reason) {
|
|
296
|
+
const { controller, writer } = stream[kState];
|
|
297
|
+
stream[kState].state = "erroring";
|
|
298
|
+
stream[kState].storedError = reason;
|
|
299
|
+
if (writer !== void 0) {
|
|
300
|
+
writableStreamDefaultWriterEnsureReadyPromiseRejected(writer, reason);
|
|
301
|
+
}
|
|
302
|
+
if (!writableStreamHasOperationMarkedInFlight(stream) && controller[kState].started) {
|
|
303
|
+
writableStreamFinishErroring(stream);
|
|
304
|
+
}
|
|
305
|
+
}
|
|
306
|
+
function writableStreamRejectCloseAndClosedPromiseIfNeeded(stream) {
|
|
307
|
+
if (stream[kState].closeRequest.promise !== void 0) {
|
|
308
|
+
stream[kState].closeRequest.reject?.(stream[kState].storedError);
|
|
309
|
+
stream[kState].closeRequest = { promise: void 0, resolve: void 0, reject: void 0 };
|
|
310
|
+
}
|
|
311
|
+
setPromiseHandled(stream[kState].close.promise);
|
|
312
|
+
stream[kState].close.reject?.(stream[kState].storedError);
|
|
313
|
+
const { writer } = stream[kState];
|
|
314
|
+
if (writer !== void 0) {
|
|
315
|
+
setPromiseHandled(writer[kState].close.promise);
|
|
316
|
+
writer[kState].close.reject?.(stream[kState].storedError);
|
|
317
|
+
}
|
|
318
|
+
}
|
|
319
|
+
function writableStreamMarkFirstWriteRequestInFlight(stream) {
|
|
320
|
+
const writeRequest = stream[kState].writeRequests.shift();
|
|
321
|
+
stream[kState].inFlightWriteRequest = writeRequest;
|
|
322
|
+
}
|
|
323
|
+
function writableStreamMarkCloseRequestInFlight(stream) {
|
|
324
|
+
stream[kState].inFlightCloseRequest = stream[kState].closeRequest;
|
|
325
|
+
stream[kState].closeRequest = { promise: void 0, resolve: void 0, reject: void 0 };
|
|
326
|
+
}
|
|
327
|
+
function writableStreamHasOperationMarkedInFlight(stream) {
|
|
328
|
+
return stream[kState].inFlightWriteRequest.promise !== void 0 || stream[kState].inFlightCloseRequest.promise !== void 0;
|
|
329
|
+
}
|
|
330
|
+
function writableStreamFinishInFlightWriteWithError(stream, error) {
|
|
331
|
+
stream[kState].inFlightWriteRequest.reject?.(error);
|
|
332
|
+
stream[kState].inFlightWriteRequest = { promise: void 0, resolve: void 0, reject: void 0 };
|
|
333
|
+
writableStreamDealWithRejection(stream, error);
|
|
334
|
+
}
|
|
335
|
+
function writableStreamFinishInFlightWrite(stream) {
|
|
336
|
+
stream[kState].inFlightWriteRequest.resolve?.();
|
|
337
|
+
stream[kState].inFlightWriteRequest = { promise: void 0, resolve: void 0, reject: void 0 };
|
|
338
|
+
}
|
|
339
|
+
function writableStreamFinishInFlightCloseWithError(stream, error) {
|
|
340
|
+
stream[kState].inFlightCloseRequest.reject?.(error);
|
|
341
|
+
stream[kState].inFlightCloseRequest = { promise: void 0, resolve: void 0, reject: void 0 };
|
|
342
|
+
if (stream[kState].pendingAbortRequest.abort.promise !== void 0) {
|
|
343
|
+
stream[kState].pendingAbortRequest.abort.reject?.(error);
|
|
344
|
+
stream[kState].pendingAbortRequest = {
|
|
345
|
+
abort: { promise: void 0, resolve: void 0, reject: void 0 },
|
|
346
|
+
reason: void 0,
|
|
347
|
+
wasAlreadyErroring: false
|
|
348
|
+
};
|
|
349
|
+
}
|
|
350
|
+
writableStreamDealWithRejection(stream, error);
|
|
351
|
+
}
|
|
352
|
+
function writableStreamFinishInFlightClose(stream) {
|
|
353
|
+
stream[kState].inFlightCloseRequest.resolve?.();
|
|
354
|
+
stream[kState].inFlightCloseRequest = { promise: void 0, resolve: void 0, reject: void 0 };
|
|
355
|
+
if (stream[kState].state === "erroring") {
|
|
356
|
+
stream[kState].storedError = void 0;
|
|
357
|
+
if (stream[kState].pendingAbortRequest.abort.promise !== void 0) {
|
|
358
|
+
stream[kState].pendingAbortRequest.abort.resolve?.();
|
|
359
|
+
stream[kState].pendingAbortRequest = {
|
|
360
|
+
abort: { promise: void 0, resolve: void 0, reject: void 0 },
|
|
361
|
+
reason: void 0,
|
|
362
|
+
wasAlreadyErroring: false
|
|
363
|
+
};
|
|
364
|
+
}
|
|
365
|
+
}
|
|
366
|
+
stream[kState].state = "closed";
|
|
367
|
+
if (stream[kState].writer !== void 0) {
|
|
368
|
+
stream[kState].writer[kState].close.resolve?.();
|
|
369
|
+
}
|
|
370
|
+
stream[kState].close.resolve?.();
|
|
371
|
+
}
|
|
372
|
+
function writableStreamFinishErroring(stream) {
|
|
373
|
+
stream[kState].state = "errored";
|
|
374
|
+
stream[kState].controller[kError]();
|
|
375
|
+
const storedError = stream[kState].storedError;
|
|
376
|
+
for (const req of stream[kState].writeRequests) {
|
|
377
|
+
req.reject?.(storedError);
|
|
378
|
+
}
|
|
379
|
+
stream[kState].writeRequests = [];
|
|
380
|
+
if (stream[kState].pendingAbortRequest.abort.promise === void 0) {
|
|
381
|
+
writableStreamRejectCloseAndClosedPromiseIfNeeded(stream);
|
|
382
|
+
return;
|
|
383
|
+
}
|
|
384
|
+
const abortRequest = stream[kState].pendingAbortRequest;
|
|
385
|
+
stream[kState].pendingAbortRequest = {
|
|
386
|
+
abort: { promise: void 0, resolve: void 0, reject: void 0 },
|
|
387
|
+
reason: void 0,
|
|
388
|
+
wasAlreadyErroring: false
|
|
389
|
+
};
|
|
390
|
+
if (abortRequest.wasAlreadyErroring) {
|
|
391
|
+
abortRequest.abort.reject?.(storedError);
|
|
392
|
+
writableStreamRejectCloseAndClosedPromiseIfNeeded(stream);
|
|
393
|
+
return;
|
|
394
|
+
}
|
|
395
|
+
stream[kState].controller[kAbort](abortRequest.reason).then(
|
|
396
|
+
() => {
|
|
397
|
+
abortRequest.abort.resolve?.();
|
|
398
|
+
writableStreamRejectCloseAndClosedPromiseIfNeeded(stream);
|
|
399
|
+
},
|
|
400
|
+
(error) => {
|
|
401
|
+
abortRequest.abort.reject?.(error);
|
|
402
|
+
writableStreamRejectCloseAndClosedPromiseIfNeeded(stream);
|
|
403
|
+
}
|
|
404
|
+
);
|
|
405
|
+
}
|
|
406
|
+
function writableStreamDealWithRejection(stream, error) {
|
|
407
|
+
if (stream[kState].state === "writable") {
|
|
408
|
+
writableStreamStartErroring(stream, error);
|
|
409
|
+
return;
|
|
410
|
+
}
|
|
411
|
+
writableStreamFinishErroring(stream);
|
|
412
|
+
}
|
|
413
|
+
function writableStreamCloseQueuedOrInFlight(stream) {
|
|
414
|
+
return stream[kState].closeRequest.promise !== void 0 || stream[kState].inFlightCloseRequest.promise !== void 0;
|
|
415
|
+
}
|
|
416
|
+
function writableStreamAddWriteRequest(stream) {
|
|
417
|
+
const { promise, resolve, reject } = Promise.withResolvers();
|
|
418
|
+
stream[kState].writeRequests.push({ promise, resolve, reject });
|
|
419
|
+
return promise;
|
|
420
|
+
}
|
|
421
|
+
function writableStreamDefaultWriterWrite(writer, chunk) {
|
|
422
|
+
const { stream } = writer[kState];
|
|
423
|
+
const { controller } = stream[kState];
|
|
424
|
+
const chunkSize = writableStreamDefaultControllerGetChunkSize(controller, chunk);
|
|
425
|
+
if (stream !== writer[kState].stream) {
|
|
426
|
+
return Promise.reject(new TypeError("Mismatched WritableStreams"));
|
|
427
|
+
}
|
|
428
|
+
const { state } = stream[kState];
|
|
429
|
+
if (state === "errored") return Promise.reject(stream[kState].storedError);
|
|
430
|
+
if (writableStreamCloseQueuedOrInFlight(stream) || state === "closed") {
|
|
431
|
+
return Promise.reject(new TypeError("WritableStream is closed"));
|
|
432
|
+
}
|
|
433
|
+
if (state === "erroring") return Promise.reject(stream[kState].storedError);
|
|
434
|
+
const promise = writableStreamAddWriteRequest(stream);
|
|
435
|
+
writableStreamDefaultControllerWrite(controller, chunk, chunkSize);
|
|
436
|
+
return promise;
|
|
437
|
+
}
|
|
438
|
+
function writableStreamDefaultWriterRelease(writer) {
|
|
439
|
+
const { stream } = writer[kState];
|
|
440
|
+
const releasedError = new TypeError("Writer has been released");
|
|
441
|
+
writableStreamDefaultWriterEnsureReadyPromiseRejected(writer, releasedError);
|
|
442
|
+
writableStreamDefaultWriterEnsureClosedPromiseRejected(writer, releasedError);
|
|
443
|
+
stream[kState].writer = void 0;
|
|
444
|
+
writer[kState].stream = void 0;
|
|
445
|
+
}
|
|
446
|
+
function writableStreamDefaultWriterGetDesiredSize(writer) {
|
|
447
|
+
const { stream } = writer[kState];
|
|
448
|
+
switch (stream[kState].state) {
|
|
449
|
+
case "errored":
|
|
450
|
+
case "erroring":
|
|
451
|
+
return null;
|
|
452
|
+
case "closed":
|
|
453
|
+
return 0;
|
|
454
|
+
}
|
|
455
|
+
return writableStreamDefaultControllerGetDesiredSize(stream[kState].controller);
|
|
456
|
+
}
|
|
457
|
+
function writableStreamDefaultWriterEnsureReadyPromiseRejected(writer, error) {
|
|
458
|
+
if (writer[kState].ready.reject) {
|
|
459
|
+
writer[kState].ready.reject(error);
|
|
460
|
+
writer[kState].ready.resolve = void 0;
|
|
461
|
+
writer[kState].ready.reject = void 0;
|
|
462
|
+
} else {
|
|
463
|
+
writer[kState].ready = {
|
|
464
|
+
promise: Promise.reject(error),
|
|
465
|
+
resolve: void 0,
|
|
466
|
+
reject: void 0
|
|
467
|
+
};
|
|
468
|
+
}
|
|
469
|
+
setPromiseHandled(writer[kState].ready.promise);
|
|
470
|
+
}
|
|
471
|
+
function writableStreamDefaultWriterEnsureClosedPromiseRejected(writer, error) {
|
|
472
|
+
if (writer[kState].close.reject) {
|
|
473
|
+
writer[kState].close.reject(error);
|
|
474
|
+
writer[kState].close.resolve = void 0;
|
|
475
|
+
writer[kState].close.reject = void 0;
|
|
476
|
+
} else {
|
|
477
|
+
writer[kState].close = {
|
|
478
|
+
promise: Promise.reject(error),
|
|
479
|
+
resolve: void 0,
|
|
480
|
+
reject: void 0
|
|
481
|
+
};
|
|
482
|
+
}
|
|
483
|
+
setPromiseHandled(writer[kState].close.promise);
|
|
484
|
+
}
|
|
485
|
+
function writableStreamDefaultWriterCloseWithErrorPropagation(writer) {
|
|
486
|
+
const { stream } = writer[kState];
|
|
487
|
+
const { state } = stream[kState];
|
|
488
|
+
if (writableStreamCloseQueuedOrInFlight(stream) || state === "closed") {
|
|
489
|
+
return Promise.resolve();
|
|
490
|
+
}
|
|
491
|
+
if (state === "errored") return Promise.reject(stream[kState].storedError);
|
|
492
|
+
return writableStreamDefaultWriterClose(writer);
|
|
493
|
+
}
|
|
494
|
+
function writableStreamDefaultWriterClose(writer) {
|
|
495
|
+
return writableStreamClose(writer[kState].stream);
|
|
496
|
+
}
|
|
497
|
+
function writableStreamDefaultWriterAbort(writer, reason) {
|
|
498
|
+
return writableStreamAbort(writer[kState].stream, reason);
|
|
499
|
+
}
|
|
500
|
+
function writableStreamDefaultControllerWrite(controller, chunk, chunkSize) {
|
|
501
|
+
try {
|
|
502
|
+
enqueueValueWithSize(controller, chunk, chunkSize);
|
|
503
|
+
} catch (error) {
|
|
504
|
+
writableStreamDefaultControllerErrorIfNeeded(controller, error);
|
|
505
|
+
return;
|
|
506
|
+
}
|
|
507
|
+
const { stream } = controller[kState];
|
|
508
|
+
if (!writableStreamCloseQueuedOrInFlight(stream) && stream[kState].state === "writable") {
|
|
509
|
+
writableStreamUpdateBackpressure(stream, writableStreamDefaultControllerGetBackpressure(controller));
|
|
510
|
+
}
|
|
511
|
+
writableStreamDefaultControllerAdvanceQueueIfNeeded(controller);
|
|
512
|
+
}
|
|
513
|
+
function writableStreamDefaultControllerProcessWrite(controller, chunk) {
|
|
514
|
+
const { stream, writeAlgorithm } = controller[kState];
|
|
515
|
+
writableStreamMarkFirstWriteRequestInFlight(stream);
|
|
516
|
+
writeAlgorithm(chunk, controller).then(
|
|
517
|
+
() => {
|
|
518
|
+
writableStreamFinishInFlightWrite(stream);
|
|
519
|
+
const { state } = stream[kState];
|
|
520
|
+
dequeueValue(controller);
|
|
521
|
+
if (!writableStreamCloseQueuedOrInFlight(stream) && state === "writable") {
|
|
522
|
+
writableStreamUpdateBackpressure(stream, writableStreamDefaultControllerGetBackpressure(controller));
|
|
523
|
+
}
|
|
524
|
+
writableStreamDefaultControllerAdvanceQueueIfNeeded(controller);
|
|
525
|
+
},
|
|
526
|
+
(error) => {
|
|
527
|
+
if (stream[kState].state === "writable") {
|
|
528
|
+
writableStreamDefaultControllerClearAlgorithms(controller);
|
|
529
|
+
}
|
|
530
|
+
writableStreamFinishInFlightWriteWithError(stream, error);
|
|
531
|
+
}
|
|
532
|
+
);
|
|
533
|
+
}
|
|
534
|
+
function writableStreamDefaultControllerProcessClose(controller) {
|
|
535
|
+
const { closeAlgorithm, queue, stream } = controller[kState];
|
|
536
|
+
writableStreamMarkCloseRequestInFlight(stream);
|
|
537
|
+
dequeueValue(controller);
|
|
538
|
+
const sinkClosePromise = closeAlgorithm();
|
|
539
|
+
writableStreamDefaultControllerClearAlgorithms(controller);
|
|
540
|
+
sinkClosePromise.then(
|
|
541
|
+
() => writableStreamFinishInFlightClose(stream),
|
|
542
|
+
(error) => writableStreamFinishInFlightCloseWithError(stream, error)
|
|
543
|
+
);
|
|
544
|
+
}
|
|
545
|
+
function writableStreamDefaultControllerGetDesiredSize(controller) {
|
|
546
|
+
return controller[kState].highWaterMark - controller[kState].queueTotalSize;
|
|
547
|
+
}
|
|
548
|
+
function writableStreamDefaultControllerGetChunkSize(controller, chunk) {
|
|
549
|
+
const { stream, sizeAlgorithm } = controller[kState];
|
|
550
|
+
if (sizeAlgorithm === void 0) return 1;
|
|
551
|
+
try {
|
|
552
|
+
return sizeAlgorithm(chunk);
|
|
553
|
+
} catch (error) {
|
|
554
|
+
writableStreamDefaultControllerErrorIfNeeded(controller, error);
|
|
555
|
+
return 1;
|
|
556
|
+
}
|
|
557
|
+
}
|
|
558
|
+
function writableStreamDefaultControllerErrorIfNeeded(controller, error) {
|
|
559
|
+
if (controller[kState].stream[kState].state === "writable") {
|
|
560
|
+
writableStreamDefaultControllerError(controller, error);
|
|
561
|
+
}
|
|
562
|
+
}
|
|
563
|
+
function writableStreamDefaultControllerError(controller, error) {
|
|
564
|
+
writableStreamDefaultControllerClearAlgorithms(controller);
|
|
565
|
+
writableStreamStartErroring(controller[kState].stream, error);
|
|
566
|
+
}
|
|
567
|
+
function writableStreamDefaultControllerClose(controller) {
|
|
568
|
+
enqueueValueWithSize(controller, kCloseSentinel, 0);
|
|
569
|
+
writableStreamDefaultControllerAdvanceQueueIfNeeded(controller);
|
|
570
|
+
}
|
|
571
|
+
function writableStreamDefaultControllerClearAlgorithms(controller) {
|
|
572
|
+
controller[kState].writeAlgorithm = void 0;
|
|
573
|
+
controller[kState].closeAlgorithm = void 0;
|
|
574
|
+
controller[kState].abortAlgorithm = void 0;
|
|
575
|
+
controller[kState].sizeAlgorithm = void 0;
|
|
576
|
+
}
|
|
577
|
+
function writableStreamDefaultControllerGetBackpressure(controller) {
|
|
578
|
+
return writableStreamDefaultControllerGetDesiredSize(controller) <= 0;
|
|
579
|
+
}
|
|
580
|
+
function writableStreamDefaultControllerAdvanceQueueIfNeeded(controller) {
|
|
581
|
+
const { queue, started, stream } = controller[kState];
|
|
582
|
+
if (!started || stream[kState].inFlightWriteRequest.promise !== void 0) return;
|
|
583
|
+
if (stream[kState].state === "erroring") {
|
|
584
|
+
writableStreamFinishErroring(stream);
|
|
585
|
+
return;
|
|
586
|
+
}
|
|
587
|
+
if (!queue.length) return;
|
|
588
|
+
const value = peekQueueValue(controller);
|
|
589
|
+
if (value === kCloseSentinel) {
|
|
590
|
+
writableStreamDefaultControllerProcessClose(controller);
|
|
591
|
+
} else {
|
|
592
|
+
writableStreamDefaultControllerProcessWrite(controller, value);
|
|
593
|
+
}
|
|
594
|
+
}
|
|
595
|
+
function setupWritableStreamDefaultControllerFromSink(stream, sink, highWaterMark, sizeAlgorithm) {
|
|
596
|
+
const controller = new WritableStreamDefaultController(kSkipThrow);
|
|
597
|
+
const start = sink?.start;
|
|
598
|
+
const write = sink?.write;
|
|
599
|
+
const close = sink?.close;
|
|
600
|
+
const abort = sink?.abort;
|
|
601
|
+
const startAlgorithm = start ? start.bind(sink, controller) : nonOpStart;
|
|
602
|
+
const writeAlgorithm = write ? createPromiseCallback("sink.write", write, sink) : nonOpWrite;
|
|
603
|
+
const closeAlgorithm = close ? createPromiseCallback("sink.close", close, sink) : nonOpCancel;
|
|
604
|
+
const abortAlgorithm = abort ? createPromiseCallback("sink.abort", abort, sink) : nonOpCancel;
|
|
605
|
+
setupWritableStreamDefaultController(
|
|
606
|
+
stream,
|
|
607
|
+
controller,
|
|
608
|
+
startAlgorithm,
|
|
609
|
+
writeAlgorithm,
|
|
610
|
+
closeAlgorithm,
|
|
611
|
+
abortAlgorithm,
|
|
612
|
+
highWaterMark,
|
|
613
|
+
sizeAlgorithm
|
|
614
|
+
);
|
|
615
|
+
}
|
|
616
|
+
function setupWritableStreamDefaultController(stream, controller, startAlgorithm, writeAlgorithm, closeAlgorithm, abortAlgorithm, highWaterMark, sizeAlgorithm) {
|
|
617
|
+
controller[kState] = {
|
|
618
|
+
abortAlgorithm,
|
|
619
|
+
closeAlgorithm,
|
|
620
|
+
highWaterMark,
|
|
621
|
+
queue: [],
|
|
622
|
+
queueTotalSize: 0,
|
|
623
|
+
abortController: new _AbortController(),
|
|
624
|
+
sizeAlgorithm,
|
|
625
|
+
started: false,
|
|
626
|
+
stream,
|
|
627
|
+
writeAlgorithm
|
|
628
|
+
};
|
|
629
|
+
stream[kState].controller = controller;
|
|
630
|
+
writableStreamUpdateBackpressure(stream, writableStreamDefaultControllerGetBackpressure(controller));
|
|
631
|
+
const startResult = startAlgorithm();
|
|
632
|
+
new Promise((r) => r(startResult)).then(
|
|
633
|
+
() => {
|
|
634
|
+
controller[kState].started = true;
|
|
635
|
+
writableStreamDefaultControllerAdvanceQueueIfNeeded(controller);
|
|
636
|
+
},
|
|
637
|
+
(error) => {
|
|
638
|
+
controller[kState].started = true;
|
|
639
|
+
writableStreamDealWithRejection(stream, error);
|
|
640
|
+
}
|
|
641
|
+
);
|
|
642
|
+
}
|
|
643
|
+
function createWritableStream(start, write, close, abort, highWaterMark = 1, size = () => 1) {
|
|
644
|
+
const stream = Object.create(WritableStream.prototype);
|
|
645
|
+
stream[kType] = "WritableStream";
|
|
646
|
+
stream[kState] = createWritableStreamState();
|
|
647
|
+
const controller = new WritableStreamDefaultController(kSkipThrow);
|
|
648
|
+
setupWritableStreamDefaultController(
|
|
649
|
+
stream,
|
|
650
|
+
controller,
|
|
651
|
+
start,
|
|
652
|
+
write,
|
|
653
|
+
close,
|
|
654
|
+
abort,
|
|
655
|
+
highWaterMark,
|
|
656
|
+
size
|
|
657
|
+
);
|
|
658
|
+
return stream;
|
|
659
|
+
}
|
|
660
|
+
export {
|
|
661
|
+
WritableStream,
|
|
662
|
+
WritableStreamDefaultController,
|
|
663
|
+
WritableStreamDefaultWriter,
|
|
664
|
+
createWritableStream,
|
|
665
|
+
isWritableStream,
|
|
666
|
+
isWritableStreamDefaultController,
|
|
667
|
+
isWritableStreamDefaultWriter,
|
|
668
|
+
isWritableStreamLocked,
|
|
669
|
+
writableStreamAbort,
|
|
670
|
+
writableStreamClose,
|
|
671
|
+
writableStreamCloseQueuedOrInFlight,
|
|
672
|
+
writableStreamDefaultControllerErrorIfNeeded,
|
|
673
|
+
writableStreamDefaultWriterCloseWithErrorPropagation,
|
|
674
|
+
writableStreamDefaultWriterRelease,
|
|
675
|
+
writableStreamDefaultWriterWrite
|
|
676
|
+
};
|