@ccheever/exact-ibex-runtime 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.
Files changed (161) hide show
  1. package/package.json +63 -0
  2. package/src/abort/AbortController.ts +23 -0
  3. package/src/abort/AbortSignal.ts +152 -0
  4. package/src/abort/index.ts +2 -0
  5. package/src/accessibility.ts +12 -0
  6. package/src/arraybuffer-detach.ts +109 -0
  7. package/src/base64/base64.ts +168 -0
  8. package/src/base64/index.ts +1 -0
  9. package/src/blob/Blob.ts +259 -0
  10. package/src/blob/File.ts +59 -0
  11. package/src/blob/FormData.ts +323 -0
  12. package/src/blob/index.ts +3 -0
  13. package/src/bootstrap.ts +1946 -0
  14. package/src/broadcast/BroadcastChannel.ts +280 -0
  15. package/src/broadcast/index.ts +5 -0
  16. package/src/cache/Cache.ts +349 -0
  17. package/src/cache/CacheStorage.ts +89 -0
  18. package/src/cache/index.ts +27 -0
  19. package/src/camera/index.ts +6202 -0
  20. package/src/camera/processor.worker.ts +194 -0
  21. package/src/camera/scene.ts +195 -0
  22. package/src/clipboard/Clipboard.ts +129 -0
  23. package/src/clipboard/ClipboardItem.ts +97 -0
  24. package/src/clipboard/index.ts +6 -0
  25. package/src/clone/index.ts +1 -0
  26. package/src/clone/structuredClone.ts +389 -0
  27. package/src/clone/transferableSymbols.ts +2 -0
  28. package/src/compression/CompressionStream.ts +146 -0
  29. package/src/compression/DecompressionStream.ts +342 -0
  30. package/src/compression/index.ts +4 -0
  31. package/src/console/Console.ts +341 -0
  32. package/src/console/index.ts +2 -0
  33. package/src/core/accessibility-state.ts +263 -0
  34. package/src/core/accessibility.ts +184 -0
  35. package/src/core/agent-state.ts +37 -0
  36. package/src/core/diagnostics-logs.ts +144 -0
  37. package/src/core/host-call-bridge.ts +16 -0
  38. package/src/core/i18n-helpers.ts +189 -0
  39. package/src/core/locale-state.ts +253 -0
  40. package/src/core/locale.ts +95 -0
  41. package/src/crypto/Crypto.ts +2743 -0
  42. package/src/crypto/index.ts +1 -0
  43. package/src/diagnostics/logs.ts +7 -0
  44. package/src/encoding/TextDecoder.ts +1181 -0
  45. package/src/encoding/TextDecoderStream.ts +58 -0
  46. package/src/encoding/TextEncoder.ts +180 -0
  47. package/src/encoding/TextEncoderStream.ts +39 -0
  48. package/src/encoding/index.ts +8 -0
  49. package/src/events/CloseEvent.ts +91 -0
  50. package/src/events/DOMException.ts +409 -0
  51. package/src/events/ErrorEvent.ts +39 -0
  52. package/src/events/Event.ts +151 -0
  53. package/src/events/EventTarget.ts +280 -0
  54. package/src/events/FocusEvent.ts +27 -0
  55. package/src/events/KeyboardEvent.ts +46 -0
  56. package/src/events/MessageEvent.ts +61 -0
  57. package/src/events/ProgressEvent.ts +33 -0
  58. package/src/events/PromiseRejectionEvent.ts +31 -0
  59. package/src/events/index.ts +52 -0
  60. package/src/eventsource/EventSource.ts +371 -0
  61. package/src/eventsource/index.ts +2 -0
  62. package/src/fetch/Headers.ts +642 -0
  63. package/src/fetch/Request.ts +760 -0
  64. package/src/fetch/Response.ts +543 -0
  65. package/src/fetch/body.ts +1256 -0
  66. package/src/fetch/cookie-jar.ts +566 -0
  67. package/src/fetch/demo.ts +207 -0
  68. package/src/fetch/errors.ts +101 -0
  69. package/src/fetch/fetch.ts +2610 -0
  70. package/src/fetch/index.ts +101 -0
  71. package/src/fetch/native-bridge.ts +65 -0
  72. package/src/fetch/types.ts +258 -0
  73. package/src/filereader/FileReader.ts +236 -0
  74. package/src/filereader/index.ts +1 -0
  75. package/src/fs/Dirent.ts +39 -0
  76. package/src/fs/ExactFile.ts +450 -0
  77. package/src/fs/Stats.ts +80 -0
  78. package/src/fs/index.ts +944 -0
  79. package/src/fs/promises.ts +386 -0
  80. package/src/fs/shared.ts +328 -0
  81. package/src/http-server/index.js +697 -0
  82. package/src/http-server/index.ts +27 -0
  83. package/src/identity.generated.ts +14 -0
  84. package/src/index.ts +283 -0
  85. package/src/indexeddb/IDBCursor.ts +188 -0
  86. package/src/indexeddb/IDBDatabase.ts +343 -0
  87. package/src/indexeddb/IDBFactory.ts +269 -0
  88. package/src/indexeddb/IDBIndex.ts +194 -0
  89. package/src/indexeddb/IDBKeyRange.ts +109 -0
  90. package/src/indexeddb/IDBObjectStore.ts +468 -0
  91. package/src/indexeddb/IDBRequest.ts +163 -0
  92. package/src/indexeddb/IDBTransaction.ts +207 -0
  93. package/src/indexeddb/index.ts +34 -0
  94. package/src/indexeddb/utils.ts +52 -0
  95. package/src/inspect/index.ts +1 -0
  96. package/src/inspect/inspect.ts +465 -0
  97. package/src/internal/detect.ts +104 -0
  98. package/src/locale.ts +10 -0
  99. package/src/location/index.ts +1059 -0
  100. package/src/locks/LockManager.ts +460 -0
  101. package/src/locks/index.ts +12 -0
  102. package/src/media/VideoFrame.ts +58 -0
  103. package/src/messaging/MessageChannel.ts +31 -0
  104. package/src/messaging/MessagePort.ts +180 -0
  105. package/src/messaging/index.ts +2 -0
  106. package/src/messaging.ts +247 -0
  107. package/src/native/NativeModules.ts +354 -0
  108. package/src/native/index.ts +1 -0
  109. package/src/navigator/Navigator.ts +351 -0
  110. package/src/navigator/index.ts +1 -0
  111. package/src/node/Buffer.ts +1786 -0
  112. package/src/node/index.ts +4 -0
  113. package/src/node/path.ts +495 -0
  114. package/src/node/process.ts +2528 -0
  115. package/src/performance/Performance.ts +532 -0
  116. package/src/performance/index.ts +21 -0
  117. package/src/polyfills/array.ts +236 -0
  118. package/src/polyfills/arraybuffer.ts +172 -0
  119. package/src/polyfills/groupby.ts +85 -0
  120. package/src/polyfills/index.ts +85 -0
  121. package/src/polyfills/intl.ts +1956 -0
  122. package/src/polyfills/iterator.ts +479 -0
  123. package/src/polyfills/promise.ts +37 -0
  124. package/src/polyfills/set.ts +245 -0
  125. package/src/polyfills/string.ts +85 -0
  126. package/src/polyfills/typedarray.ts +110 -0
  127. package/src/promise-rejection-tracking.ts +464 -0
  128. package/src/react-native/index.ts +388 -0
  129. package/src/runtime-entry.ts +55 -0
  130. package/src/scheduling/AnimationFrame.ts +105 -0
  131. package/src/scheduling/IdleCallback.ts +167 -0
  132. package/src/scheduling/index.ts +13 -0
  133. package/src/security/Capabilities.ts +1146 -0
  134. package/src/security/Permissions.ts +392 -0
  135. package/src/security/capability-bits.generated.ts +63 -0
  136. package/src/security/index.ts +16 -0
  137. package/src/sqlite/Database.ts +456 -0
  138. package/src/sqlite/Statement.ts +206 -0
  139. package/src/sqlite/constants.ts +79 -0
  140. package/src/sqlite/errors.ts +25 -0
  141. package/src/sqlite/index.ts +34 -0
  142. package/src/sqlite/module.js +438 -0
  143. package/src/storage/Storage.ts +291 -0
  144. package/src/storage/StorageManager.ts +91 -0
  145. package/src/storage/index.ts +3 -0
  146. package/src/stream-compat.ts +47 -0
  147. package/src/streams/ReadableStream.ts +4131 -0
  148. package/src/streams/TransformStream.ts +375 -0
  149. package/src/streams/WritableStream.ts +866 -0
  150. package/src/streams/index.ts +41 -0
  151. package/src/timers/Timers.ts +296 -0
  152. package/src/timers/index.ts +11 -0
  153. package/src/url/URL.ts +656 -0
  154. package/src/url/URLPattern.ts +850 -0
  155. package/src/url/URLSearchParams.ts +244 -0
  156. package/src/url/index.ts +9 -0
  157. package/src/websocket/WebSocket.ts +770 -0
  158. package/src/websocket/WebSocketError.ts +52 -0
  159. package/src/websocket/WebSocketStream.ts +628 -0
  160. package/src/websocket/index.ts +7 -0
  161. package/src/window/index.ts +872 -0
@@ -0,0 +1,866 @@
1
+ // @ts-nocheck
2
+ /**
3
+ * WritableStream - WHATWG Streams API Implementation
4
+ *
5
+ * @see https://streams.spec.whatwg.org/#ws-class
6
+ *
7
+ * This implementation supports:
8
+ * - Underlying sink with start/write/close/abort
9
+ * - Queuing strategy with backpressure
10
+ * - WritableStreamDefaultWriter with ready/closed promises
11
+ * - WritableStreamDefaultController with error()
12
+ * - Proper state machine: writable -> closing -> closed, or errored
13
+ * - Symbol.toStringTag
14
+ */
15
+
16
+ // Capture Promise methods at module load time to be immune to monkey-patching
17
+ const originalPromiseThen = Promise.prototype.then;
18
+ const originalPromiseResolve = Promise.resolve.bind(Promise);
19
+ const originalPromiseReject = Promise.reject.bind(Promise);
20
+
21
+ function promiseThen<T, TResult1 = T, TResult2 = never>(
22
+ promise: PromiseLike<T>,
23
+ onFulfilled?: ((value: T) => TResult1 | PromiseLike<TResult1>) | null,
24
+ onRejected?: ((reason: any) => TResult2 | PromiseLike<TResult2>) | null
25
+ ): Promise<TResult1 | TResult2> {
26
+ return originalPromiseThen.call(promise, onFulfilled, onRejected);
27
+ }
28
+
29
+ function markPromiseHandled(promise: PromiseLike<any>): void {
30
+ originalPromiseThen.call(promise, undefined, () => {});
31
+ }
32
+
33
+ // ============================================================================
34
+ // Types
35
+ // ============================================================================
36
+
37
+ export interface UnderlyingSink<W = any> {
38
+ start?: (controller: WritableStreamDefaultController) => void | Promise<void>;
39
+ write?: (chunk: W, controller: WritableStreamDefaultController) => void | Promise<void>;
40
+ close?: () => void | Promise<void>;
41
+ abort?: (reason?: any) => void | Promise<void>;
42
+ type?: undefined;
43
+ }
44
+
45
+ export interface QueuingStrategy<W = any> {
46
+ highWaterMark?: number;
47
+ size?: (chunk: W) => number;
48
+ }
49
+
50
+ export interface StreamPipeOptions {
51
+ preventClose?: boolean;
52
+ preventAbort?: boolean;
53
+ preventCancel?: boolean;
54
+ signal?: AbortSignal;
55
+ }
56
+
57
+ type WritableStreamState = 'writable' | 'closing' | 'closed' | 'errored';
58
+ type PromiseState = 'pending' | 'fulfilled' | 'rejected';
59
+ type PromiseRecord<T> = {
60
+ promise: Promise<T>;
61
+ state: PromiseState;
62
+ resolve: (value: T | PromiseLike<T>) => void;
63
+ reject: (reason?: any) => void;
64
+ };
65
+
66
+ // ============================================================================
67
+ // Internal helpers
68
+ // ============================================================================
69
+
70
+ /** Create a deferred promise with exposed resolve/reject */
71
+ function createDeferred<T = undefined>(): {
72
+ promise: Promise<T>;
73
+ state: PromiseState;
74
+ resolve: (value: T | PromiseLike<T>) => void;
75
+ reject: (reason?: any) => void;
76
+ } {
77
+ const record: PromiseRecord<T> = {
78
+ promise: originalPromiseResolve(undefined as T),
79
+ state: 'pending',
80
+ resolve: function (_value: T | PromiseLike<T>) {},
81
+ reject: function (_reason?: any) {},
82
+ };
83
+
84
+ record.promise = new Promise<T>(function (res, rej) {
85
+ record.resolve = function (value: T | PromiseLike<T>) {
86
+ if (record.state !== 'pending') {
87
+ return;
88
+ }
89
+ record.state = 'fulfilled';
90
+ res(value);
91
+ };
92
+ record.reject = function (reason?: any) {
93
+ if (record.state !== 'pending') {
94
+ return;
95
+ }
96
+ record.state = 'rejected';
97
+ rej(reason);
98
+ };
99
+ });
100
+
101
+ return record;
102
+ }
103
+
104
+ function createHandledRejectedPromise<T = never>(reason: any): Promise<T> {
105
+ const p = new Promise<T>(function (_resolve, reject) {
106
+ queueMicrotask(function () {
107
+ reject(reason);
108
+ });
109
+ });
110
+ markPromiseHandled(p);
111
+ return p;
112
+ }
113
+
114
+ function createResolvedPromiseRecord<T>(value: T): PromiseRecord<T> {
115
+ return {
116
+ promise: originalPromiseResolve(value),
117
+ state: 'fulfilled',
118
+ resolve: function (_value: T | PromiseLike<T>) {},
119
+ reject: function (_reason?: any) {},
120
+ };
121
+ }
122
+
123
+ function createRejectedPromiseRecord<T = never>(reason: any): PromiseRecord<T> {
124
+ return {
125
+ promise: createHandledRejectedPromise<T>(reason),
126
+ state: 'rejected',
127
+ resolve: function (_value: T | PromiseLike<T>) {},
128
+ reject: function (_reason?: any) {},
129
+ };
130
+ }
131
+
132
+ function createReleasedWriterError(): TypeError {
133
+ return new TypeError('Writer has been released');
134
+ }
135
+
136
+ function isCallable(value: unknown): value is (...args: any[]) => any {
137
+ return typeof value === "function";
138
+ }
139
+
140
+ function toNumber(value: unknown): number {
141
+ return Number(value);
142
+ }
143
+
144
+ function validateHighWaterMark(highWaterMark: unknown, defaultValue: number): number {
145
+ if (highWaterMark === undefined) {
146
+ return defaultValue;
147
+ }
148
+
149
+ const normalized = toNumber(highWaterMark);
150
+ if (
151
+ Number.isNaN(normalized) ||
152
+ normalized < 0
153
+ ) {
154
+ throw new RangeError("The highWaterMark option must be a non-negative number");
155
+ }
156
+
157
+ return normalized;
158
+ }
159
+
160
+ function validateQueuingStrategySize(value: unknown): (chunk: any) => number {
161
+ if (value === undefined) {
162
+ return function () {
163
+ return 1;
164
+ };
165
+ }
166
+
167
+ if (!isCallable(value)) {
168
+ throw new TypeError("size must be a function");
169
+ }
170
+
171
+ return value;
172
+ }
173
+
174
+ function validateSinkMethod(sink: any, member: "start" | "write" | "close" | "abort"): void {
175
+ const method = sink[member];
176
+ if (method !== undefined && !isCallable(method)) {
177
+ throw new TypeError(`WritableStream underlying sink ${member} must be a function`);
178
+ }
179
+ }
180
+
181
+ // ============================================================================
182
+ // WritableStreamDefaultController
183
+ // ============================================================================
184
+
185
+ export class WritableStreamDefaultController {
186
+ /** @internal */
187
+ _stream: WritableStream<any> | undefined;
188
+ /** @internal */
189
+ _abortReason: any;
190
+ /** @internal */
191
+ _abortController: AbortController;
192
+
193
+ /** @internal */
194
+ constructor() {
195
+ this._abortController = new AbortController();
196
+ }
197
+
198
+ get signal(): AbortSignal {
199
+ return this._abortController.signal;
200
+ }
201
+
202
+ error(e?: any): void {
203
+ const stream = this._stream;
204
+ if (stream === undefined) {
205
+ throw new TypeError('Controller has no associated stream');
206
+ }
207
+ if (stream._state !== 'writable') {
208
+ return;
209
+ }
210
+ stream._errorStream(e);
211
+ }
212
+
213
+ get [Symbol.toStringTag](): string {
214
+ return 'WritableStreamDefaultController';
215
+ }
216
+ }
217
+
218
+ // ============================================================================
219
+ // WritableStreamDefaultWriter
220
+ // ============================================================================
221
+
222
+ export class WritableStreamDefaultWriter<W = any> {
223
+ /** @internal */
224
+ _stream: WritableStream<W> | undefined;
225
+ /** @internal */
226
+ _releasedError: TypeError | undefined;
227
+ /** @internal */
228
+ _closedPromise: Promise<undefined>;
229
+ /** @internal */
230
+ _closedResolve!: (value?: any) => void;
231
+ /** @internal */
232
+ _closedReject!: (reason: any) => void;
233
+ /** @internal */
234
+ _closedPromiseRecord!: PromiseRecord<undefined>;
235
+ /** @internal */
236
+ _readyPromise: Promise<undefined>;
237
+ /** @internal */
238
+ _readyResolve!: (value?: any) => void;
239
+ /** @internal */
240
+ _readyReject!: (reason: any) => void;
241
+ /** @internal */
242
+ _readyPromiseRecord!: PromiseRecord<undefined>;
243
+
244
+ /** @internal */
245
+ _setClosedPromiseRecord(record: PromiseRecord<undefined>): void {
246
+ this._closedPromiseRecord = record;
247
+ this._closedPromise = record.promise;
248
+ this._closedResolve = record.resolve;
249
+ this._closedReject = record.reject as (reason: any) => void;
250
+ }
251
+
252
+ /** @internal */
253
+ _setReadyPromiseRecord(record: PromiseRecord<undefined>): void {
254
+ this._readyPromiseRecord = record;
255
+ this._readyPromise = record.promise;
256
+ this._readyResolve = record.resolve;
257
+ this._readyReject = record.reject as (reason: any) => void;
258
+ }
259
+
260
+ /** @internal */
261
+ _ensureClosedPromiseRejected(reason: any): void {
262
+ const record = this._closedPromiseRecord;
263
+ if (record.state === 'pending') {
264
+ markPromiseHandled(record.promise);
265
+ record.reject(reason);
266
+ return;
267
+ }
268
+
269
+ this._setClosedPromiseRecord(createRejectedPromiseRecord(reason));
270
+ }
271
+
272
+ /** @internal */
273
+ _ensureReadyPromiseRejected(reason: any): void {
274
+ const record = this._readyPromiseRecord;
275
+ if (record.state === 'pending') {
276
+ markPromiseHandled(record.promise);
277
+ record.reject(reason);
278
+ return;
279
+ }
280
+
281
+ this._setReadyPromiseRecord(createRejectedPromiseRecord(reason));
282
+ }
283
+
284
+ constructor(stream: WritableStream<W>) {
285
+ if (!(stream instanceof WritableStream)) {
286
+ throw new TypeError('WritableStreamDefaultWriter can only be constructed with a WritableStream instance');
287
+ }
288
+ if (stream._writer !== undefined) {
289
+ throw new TypeError('This stream already has a writer');
290
+ }
291
+
292
+ stream._writer = this;
293
+ this._stream = stream;
294
+
295
+ const state = stream._state;
296
+
297
+ if (state === 'writable') {
298
+ // Closed promise waits for close
299
+ this._setClosedPromiseRecord(createDeferred<undefined>());
300
+
301
+ // Ready depends on backpressure
302
+ if (stream._backpressure) {
303
+ this._setReadyPromiseRecord(createDeferred<undefined>());
304
+ } else {
305
+ this._setReadyPromiseRecord(createResolvedPromiseRecord(undefined));
306
+ }
307
+ } else if (state === 'closing') {
308
+ // Closing: ready is resolved (no more writes), closed waits
309
+ this._setReadyPromiseRecord(createResolvedPromiseRecord(undefined));
310
+ this._setClosedPromiseRecord(createDeferred<undefined>());
311
+ } else if (state === 'closed') {
312
+ this._setClosedPromiseRecord(createResolvedPromiseRecord(undefined));
313
+ this._setReadyPromiseRecord(createResolvedPromiseRecord(undefined));
314
+ } else {
315
+ // errored
316
+ const storedError = stream._storedError;
317
+ this._setClosedPromiseRecord(createRejectedPromiseRecord(storedError));
318
+ this._setReadyPromiseRecord(createRejectedPromiseRecord(storedError));
319
+ }
320
+ }
321
+
322
+ get closed(): Promise<undefined> {
323
+ markPromiseHandled(this._closedPromise);
324
+ return this._closedPromise;
325
+ }
326
+
327
+ get ready(): Promise<undefined> {
328
+ markPromiseHandled(this._readyPromise);
329
+ return this._readyPromise;
330
+ }
331
+
332
+ get desiredSize(): number | null {
333
+ if (this._stream === undefined) {
334
+ throw this._releasedError ?? createReleasedWriterError();
335
+ }
336
+ const state = this._stream._state;
337
+ if (state === 'errored') return null;
338
+ if (state === 'closed' || state === 'closing') return 0;
339
+ return this._stream._strategyHWM - (this._stream._queueTotalSize + this._stream._inFlightWriteSize);
340
+ }
341
+
342
+ write(chunk?: W): Promise<void> {
343
+ if (this._stream === undefined) {
344
+ return createHandledRejectedPromise(this._releasedError ?? createReleasedWriterError());
345
+ }
346
+ if (this._stream._state !== 'writable') {
347
+ if (this._stream._state === 'errored') {
348
+ return createHandledRejectedPromise(this._stream._storedError);
349
+ }
350
+ return createHandledRejectedPromise(new TypeError('The stream is not in the writable state and cannot be written to'));
351
+ }
352
+
353
+ return this._stream._writeChunk(chunk as W);
354
+ }
355
+
356
+ close(): Promise<void> {
357
+ if (this._stream === undefined) {
358
+ return createHandledRejectedPromise(this._releasedError ?? createReleasedWriterError());
359
+ }
360
+
361
+ const stream = this._stream;
362
+
363
+ if (stream._state !== 'writable') {
364
+ if (stream._state === 'closed') {
365
+ return createHandledRejectedPromise(new TypeError('The stream is already closed'));
366
+ }
367
+ if (stream._state === 'closing') {
368
+ return createHandledRejectedPromise(new TypeError('The stream is already closing'));
369
+ }
370
+ return createHandledRejectedPromise(new TypeError('The stream is not writable'));
371
+ }
372
+
373
+ const p = stream._closeStream();
374
+ markPromiseHandled(p);
375
+ return p;
376
+ }
377
+
378
+ abort(reason?: any): Promise<void> {
379
+ if (this._stream === undefined) {
380
+ return createHandledRejectedPromise(this._releasedError ?? createReleasedWriterError());
381
+ }
382
+
383
+ const p = this._stream._abortStream(reason);
384
+ markPromiseHandled(p);
385
+ return p;
386
+ }
387
+
388
+ releaseLock(): void {
389
+ if (this._stream === undefined) return;
390
+
391
+ const stream = this._stream;
392
+ const releasedError = createReleasedWriterError();
393
+ this._releasedError = releasedError;
394
+
395
+ // Promise reactions must observe ready rejecting before closed.
396
+ this._ensureReadyPromiseRejected(releasedError);
397
+ this._ensureClosedPromiseRejected(releasedError);
398
+
399
+ stream._writer = undefined;
400
+ this._stream = undefined;
401
+ }
402
+
403
+ get [Symbol.toStringTag](): string {
404
+ return 'WritableStreamDefaultWriter';
405
+ }
406
+ }
407
+
408
+ // ============================================================================
409
+ // WritableStream
410
+ // ============================================================================
411
+
412
+ export class WritableStream<W = any> {
413
+ /** @internal */
414
+ _state: WritableStreamState = 'writable';
415
+ /** @internal */
416
+ _storedError: any;
417
+ /** @internal */
418
+ _writer: WritableStreamDefaultWriter<W> | undefined;
419
+ /** @internal */
420
+ _controller: WritableStreamDefaultController;
421
+ /** @internal */
422
+ _writeAlgorithm: ((chunk: W, controller: WritableStreamDefaultController) => Promise<void>) | undefined;
423
+ /** @internal */
424
+ _closeAlgorithm: (() => Promise<void>) | undefined;
425
+ /** @internal */
426
+ _abortAlgorithm: ((reason?: any) => Promise<void>) | undefined;
427
+ /** @internal */
428
+ _started: boolean = false;
429
+ /** @internal */
430
+ _writing: boolean = false;
431
+ /** @internal */
432
+ _inFlightWriteRequest: {
433
+ resolve: () => void;
434
+ reject: (reason: any) => void;
435
+ } | undefined;
436
+ /** @internal */
437
+ _inFlightWriteSize: number = 0;
438
+ /** @internal */
439
+ _inFlightCloseRequest: {
440
+ resolve: () => void;
441
+ reject: (reason: any) => void;
442
+ } | undefined;
443
+ /** @internal */
444
+ _writeRequests: Array<{
445
+ chunk: W;
446
+ resolve: () => void;
447
+ reject: (reason: any) => void;
448
+ }> = [];
449
+ /** @internal */
450
+ _pendingAbortRequest: {
451
+ reason: any;
452
+ resolve: () => void;
453
+ reject: (reason: any) => void;
454
+ } | undefined;
455
+ /** @internal */
456
+ _backpressure: boolean = false;
457
+ /** @internal */
458
+ _aborting: boolean = false;
459
+ /** @internal */
460
+ _strategyHWM: number;
461
+ /** @internal */
462
+ _strategySizeAlgorithm: (chunk: W) => number;
463
+ /** @internal */
464
+ _queue: Array<{ chunk: W; size: number }> = [];
465
+ /** @internal */
466
+ _queueTotalSize: number = 0;
467
+
468
+ constructor(
469
+ underlyingSink?: UnderlyingSink<W>,
470
+ strategy?: QueuingStrategy<W>
471
+ ) {
472
+ const sink = underlyingSink === undefined ? {} : Object(underlyingSink);
473
+ const sinkAsAny = sink as any;
474
+ if (sink.type !== undefined) {
475
+ throw new TypeError("Unsupported underlying sink type");
476
+ }
477
+ const strat = strategy === undefined ? {} : Object(strategy);
478
+
479
+ if (sink.start !== undefined) {
480
+ validateSinkMethod(sink, "start");
481
+ }
482
+ if (sink.write !== undefined) {
483
+ validateSinkMethod(sink, "write");
484
+ }
485
+ if (sink.close !== undefined) {
486
+ validateSinkMethod(sink, "close");
487
+ }
488
+ if (sink.abort !== undefined) {
489
+ validateSinkMethod(sink, "abort");
490
+ }
491
+
492
+ this._controller = new WritableStreamDefaultController();
493
+ this._controller._stream = this;
494
+
495
+ this._strategyHWM = validateHighWaterMark((strat as any).highWaterMark, 1);
496
+ this._strategySizeAlgorithm = validateQueuingStrategySize((strat as any).size);
497
+
498
+ this._writeAlgorithm = sink.write
499
+ ? function (chunk: W, controller: WritableStreamDefaultController) {
500
+ try {
501
+ return originalPromiseResolve(sinkAsAny.write(chunk, controller));
502
+ } catch (e) {
503
+ return createHandledRejectedPromise(e);
504
+ }
505
+ }
506
+ : undefined;
507
+ this._closeAlgorithm = sink.close
508
+ ? function () {
509
+ try {
510
+ return originalPromiseResolve(sinkAsAny.close());
511
+ } catch (e) {
512
+ return createHandledRejectedPromise(e);
513
+ }
514
+ }
515
+ : undefined;
516
+ this._abortAlgorithm = sink.abort
517
+ ? function (reason?: any) {
518
+ try {
519
+ return originalPromiseResolve(sinkAsAny.abort(reason));
520
+ } catch (e) {
521
+ return createHandledRejectedPromise(e);
522
+ }
523
+ }
524
+ : undefined;
525
+
526
+ // Update backpressure
527
+ this._updateBackpressure();
528
+
529
+ // Run start algorithm
530
+ const self = this;
531
+ if (sink.start) {
532
+ let startResult: any;
533
+ try {
534
+ startResult = sinkAsAny.start(this._controller);
535
+ } catch (startError) {
536
+ // Per spec: if start throws synchronously, the stream transitions to
537
+ // errored state asynchronously — the constructor must NOT throw.
538
+ promiseThen(originalPromiseResolve(), function () {
539
+ self._started = true;
540
+ self._errorStream(startError);
541
+ });
542
+ return;
543
+ }
544
+ promiseThen(originalPromiseResolve(startResult),
545
+ function () {
546
+ self._started = true;
547
+ self._advanceQueueIfNeeded();
548
+ },
549
+ function (e) {
550
+ self._started = true;
551
+ self._errorStream(e);
552
+ }
553
+ );
554
+ } else {
555
+ // If there is no start, mark as started on next microtask
556
+ promiseThen(originalPromiseResolve(), function () {
557
+ self._started = true;
558
+ self._advanceQueueIfNeeded();
559
+ });
560
+ }
561
+ }
562
+
563
+ get locked(): boolean {
564
+ return this._writer !== undefined;
565
+ }
566
+
567
+ async abort(reason?: any): Promise<void> {
568
+ if (this.locked) {
569
+ throw new TypeError('Cannot abort a locked stream');
570
+ }
571
+ return await this._abortStream(reason);
572
+ }
573
+
574
+ async close(): Promise<void> {
575
+ if (this.locked) {
576
+ throw new TypeError('Cannot close a locked stream');
577
+ }
578
+ if (this._state !== 'writable') {
579
+ if (this._state === 'closed') {
580
+ throw new TypeError('The stream is already closed');
581
+ }
582
+ throw new TypeError('The stream is not writable');
583
+ }
584
+ return await this._closeStream();
585
+ }
586
+
587
+ getWriter(): WritableStreamDefaultWriter<W> {
588
+ return new WritableStreamDefaultWriter(this);
589
+ }
590
+
591
+ get [Symbol.toStringTag](): string {
592
+ return 'WritableStream';
593
+ }
594
+
595
+ // ============================================================================
596
+ // Internal methods
597
+ // ============================================================================
598
+
599
+ /** @internal */
600
+ _writeChunk(chunk: W): Promise<void> {
601
+ let size: number;
602
+ try {
603
+ const sizeAlgorithm = this._strategySizeAlgorithm;
604
+ size = toNumber(sizeAlgorithm(chunk));
605
+ } catch (error) {
606
+ return originalPromiseReject(error);
607
+ }
608
+
609
+ if (
610
+ Number.isNaN(size) ||
611
+ !Number.isFinite(size) ||
612
+ size < 0
613
+ ) {
614
+ return originalPromiseReject(new RangeError("The size returned by the size() algorithm must be a non-negative finite number"));
615
+ }
616
+
617
+ const self = this;
618
+ const p = new Promise<void>(function (resolve, reject) {
619
+ self._writeRequests.push({ chunk: chunk, resolve: resolve, reject: reject });
620
+ self._queue.push({ chunk: chunk, size: size });
621
+ self._queueTotalSize += size;
622
+ self._updateBackpressure();
623
+ self._advanceQueueIfNeeded();
624
+ });
625
+ markPromiseHandled(p);
626
+ return p;
627
+ }
628
+
629
+ /** @internal */
630
+ _closeStream(): Promise<void> {
631
+ this._state = 'closing';
632
+
633
+ const self = this;
634
+ return new Promise(function (resolve, reject) {
635
+ self._inFlightCloseRequest = { resolve: resolve, reject: reject };
636
+ self._advanceQueueIfNeeded();
637
+ });
638
+ }
639
+
640
+ /** @internal */
641
+ async _abortStream(reason?: any): Promise<void> {
642
+ if (this._state === 'closed' || this._state === 'errored') {
643
+ return;
644
+ }
645
+ if (this._aborting) {
646
+ return;
647
+ }
648
+ this._aborting = true;
649
+
650
+ // Signal abort on controller
651
+ this._controller._abortReason = reason;
652
+ this._controller._abortController.abort(reason);
653
+
654
+ if (this._state === 'closing') {
655
+ const inFlightCloseRequest = this._inFlightCloseRequest;
656
+ if (inFlightCloseRequest) {
657
+ inFlightCloseRequest.reject(reason);
658
+ this._inFlightCloseRequest = undefined;
659
+ }
660
+ }
661
+
662
+ // Reject all pending write requests
663
+ const inFlightWriteRequest = this._inFlightWriteRequest;
664
+ if (inFlightWriteRequest) {
665
+ inFlightWriteRequest.reject(reason);
666
+ this._inFlightWriteRequest = undefined;
667
+ }
668
+ this._inFlightWriteSize = 0;
669
+ this._writing = false;
670
+ for (var i = 0; i < this._writeRequests.length; i++) {
671
+ this._writeRequests[i].reject(reason);
672
+ }
673
+ this._writeRequests = [];
674
+ this._queue = [];
675
+ this._queueTotalSize = 0;
676
+
677
+ // Run the abort algorithm
678
+ if (this._abortAlgorithm) {
679
+ try {
680
+ await this._abortAlgorithm(reason);
681
+ } catch (e) {
682
+ this._aborting = false;
683
+ this._state = 'errored';
684
+ this._storedError = e;
685
+ this._notifyWriterError(e);
686
+ throw e;
687
+ }
688
+ }
689
+
690
+ this._aborting = false;
691
+ this._state = 'errored';
692
+ this._storedError = reason;
693
+ this._notifyWriterError(reason);
694
+ }
695
+
696
+ /** @internal */
697
+ _errorStream(e: any): void {
698
+ if (this._state !== 'writable' && this._state !== 'closing') return;
699
+
700
+ this._state = 'errored';
701
+ this._storedError = e;
702
+
703
+ // Reject all pending write requests
704
+ const inFlightWriteRequest = this._inFlightWriteRequest;
705
+ if (inFlightWriteRequest) {
706
+ inFlightWriteRequest.reject(e);
707
+ this._inFlightWriteRequest = undefined;
708
+ }
709
+ this._inFlightWriteSize = 0;
710
+ this._writing = false;
711
+ for (var i = 0; i < this._writeRequests.length; i++) {
712
+ this._writeRequests[i].reject(e);
713
+ }
714
+ this._writeRequests = [];
715
+ this._queue = [];
716
+ this._queueTotalSize = 0;
717
+
718
+ // If there was an in-flight close request, reject it too
719
+ const inFlightClose = this._inFlightCloseRequest;
720
+ if (inFlightClose) {
721
+ inFlightClose.reject(e);
722
+ this._inFlightCloseRequest = undefined;
723
+ }
724
+
725
+ this._notifyWriterError(e);
726
+ }
727
+
728
+ /** @internal */
729
+ _notifyWriterError(e: any): void {
730
+ const writer = this._writer;
731
+ if (writer) {
732
+ writer._ensureReadyPromiseRejected(e);
733
+ writer._ensureClosedPromiseRejected(e);
734
+ }
735
+ }
736
+
737
+ /** @internal */
738
+ _advanceQueueIfNeeded(): void {
739
+ if (!this._started) return;
740
+ if (this._writing) return;
741
+ if (this._aborting) return;
742
+
743
+ if (this._state === 'errored') {
744
+ return;
745
+ }
746
+
747
+ // Process close if closing and queue is empty
748
+ if (this._state === 'closing' && this._queue.length === 0) {
749
+ this._finishClose();
750
+ return;
751
+ }
752
+
753
+ // Process next write from queue
754
+ if (this._queue.length === 0) return;
755
+ if (this._state !== 'writable' && this._state !== 'closing') return;
756
+
757
+ const entry = this._queue.shift()!;
758
+ this._queueTotalSize -= entry.size;
759
+
760
+ const writeRequest = this._writeRequests.shift();
761
+ this._inFlightWriteRequest = writeRequest;
762
+ this._inFlightWriteSize = entry.size;
763
+ this._writing = true;
764
+
765
+ const self = this;
766
+ const writeAlgorithm = this._writeAlgorithm;
767
+ const writePromise = writeAlgorithm
768
+ ? writeAlgorithm(entry.chunk, this._controller)
769
+ : originalPromiseResolve();
770
+
771
+ promiseThen(writePromise,
772
+ function () {
773
+ self._writing = false;
774
+ self._inFlightWriteSize = 0;
775
+ const inFlightWriteRequest = self._inFlightWriteRequest;
776
+ self._inFlightWriteRequest = undefined;
777
+ if (inFlightWriteRequest) {
778
+ inFlightWriteRequest.resolve();
779
+ }
780
+ self._updateBackpressure();
781
+ self._advanceQueueIfNeeded();
782
+ },
783
+ function (reason) {
784
+ self._writing = false;
785
+ self._inFlightWriteSize = 0;
786
+ const inFlightWriteRequest = self._inFlightWriteRequest;
787
+ self._inFlightWriteRequest = undefined;
788
+ if (inFlightWriteRequest) {
789
+ inFlightWriteRequest.reject(reason);
790
+ }
791
+ self._errorStream(reason);
792
+ }
793
+ );
794
+ }
795
+
796
+ /** @internal */
797
+ _finishClose(): void {
798
+ const closeAlgorithm = this._closeAlgorithm;
799
+ let closePromise: Promise<void>;
800
+ try {
801
+ closePromise = closeAlgorithm ? closeAlgorithm() : originalPromiseResolve();
802
+ } catch (e) {
803
+ // The close algorithm threw synchronously; treat as a rejected promise.
804
+ closePromise = originalPromiseReject(e);
805
+ }
806
+
807
+ const self = this;
808
+ promiseThen(closePromise,
809
+ function () {
810
+ if (self._state !== 'closing') {
811
+ return;
812
+ }
813
+ self._state = 'closed';
814
+
815
+ const closeRequest = self._inFlightCloseRequest;
816
+ if (closeRequest) {
817
+ closeRequest.resolve();
818
+ self._inFlightCloseRequest = undefined;
819
+ }
820
+
821
+ const writer = self._writer;
822
+ if (writer) {
823
+ writer._closedResolve?.(undefined);
824
+ }
825
+ },
826
+ function (e) {
827
+ if (self._state !== 'closing') {
828
+ return;
829
+ }
830
+ self._state = 'errored';
831
+ self._storedError = e;
832
+
833
+ const closeRequest = self._inFlightCloseRequest;
834
+ if (closeRequest) {
835
+ closeRequest.reject(e);
836
+ self._inFlightCloseRequest = undefined;
837
+ }
838
+
839
+ self._notifyWriterError(e);
840
+ }
841
+ );
842
+ }
843
+
844
+ /** @internal */
845
+ _updateBackpressure(): void {
846
+ const desiredSize = this._strategyHWM - (this._queueTotalSize + this._inFlightWriteSize);
847
+ const backpressure = desiredSize <= 0;
848
+
849
+ if (backpressure !== this._backpressure) {
850
+ this._backpressure = backpressure;
851
+
852
+ const writer = this._writer;
853
+ if (writer) {
854
+ if (backpressure) {
855
+ // Create a new pending ready promise
856
+ if (writer._readyPromiseRecord.state !== 'pending') {
857
+ writer._setReadyPromiseRecord(createDeferred<undefined>());
858
+ }
859
+ } else if (writer._readyPromiseRecord.state === 'pending') {
860
+ // Resolve the ready promise
861
+ writer._readyResolve?.(undefined);
862
+ }
863
+ }
864
+ }
865
+ }
866
+ }