@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
package/src/index.ts
ADDED
|
@@ -0,0 +1,131 @@
|
|
|
1
|
+
// WHATWG Streams API for GJS
|
|
2
|
+
// Reference: refs/node/lib/internal/webstreams/
|
|
3
|
+
// Copyright (c) Node.js contributors. MIT license.
|
|
4
|
+
// Reimplemented for GJS — pure TypeScript, no native bindings.
|
|
5
|
+
//
|
|
6
|
+
// On Node.js (and any environment with native Web Streams), this module
|
|
7
|
+
// re-exports the native globals for zero overhead.
|
|
8
|
+
// On GJS, it provides a full polyfill and registers globals.
|
|
9
|
+
|
|
10
|
+
import { WritableStream, WritableStreamDefaultWriter, WritableStreamDefaultController } from './writable-stream.js';
|
|
11
|
+
import { ReadableStream, ReadableStreamDefaultReader, ReadableStreamDefaultController } from './readable-stream.js';
|
|
12
|
+
import { TransformStream, TransformStreamDefaultController } from './transform-stream.js';
|
|
13
|
+
import { ByteLengthQueuingStrategy, CountQueuingStrategy } from './queuing-strategies.js';
|
|
14
|
+
import { TextEncoderStream } from './text-encoder-stream.js';
|
|
15
|
+
import { TextDecoderStream } from './text-decoder-stream.js';
|
|
16
|
+
|
|
17
|
+
// Validate that a native stream class produces functional instances.
|
|
18
|
+
// GJS may expose stream constructors that return objects missing core methods
|
|
19
|
+
// (e.g. ReadableStream exists but instances lack getReader()).
|
|
20
|
+
function isNativeStreamUsable(Ctor: unknown, method: string): boolean {
|
|
21
|
+
try {
|
|
22
|
+
if (typeof Ctor !== 'function') return false;
|
|
23
|
+
return typeof (Ctor as any).prototype[method] === 'function';
|
|
24
|
+
} catch {
|
|
25
|
+
return false;
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
// Use native if available and functional (Node.js 18+), polyfill otherwise
|
|
30
|
+
const _ReadableStream = isNativeStreamUsable(globalThis.ReadableStream, 'getReader')
|
|
31
|
+
? globalThis.ReadableStream
|
|
32
|
+
: ReadableStream;
|
|
33
|
+
const _WritableStream = isNativeStreamUsable(globalThis.WritableStream, 'getWriter')
|
|
34
|
+
? globalThis.WritableStream
|
|
35
|
+
: WritableStream;
|
|
36
|
+
const _TransformStream = isNativeStreamUsable(globalThis.TransformStream, 'readable')
|
|
37
|
+
? globalThis.TransformStream
|
|
38
|
+
: TransformStream;
|
|
39
|
+
const _ByteLengthQueuingStrategy = typeof globalThis.ByteLengthQueuingStrategy === 'function'
|
|
40
|
+
? globalThis.ByteLengthQueuingStrategy
|
|
41
|
+
: ByteLengthQueuingStrategy;
|
|
42
|
+
const _CountQueuingStrategy = typeof globalThis.CountQueuingStrategy === 'function'
|
|
43
|
+
? globalThis.CountQueuingStrategy
|
|
44
|
+
: CountQueuingStrategy;
|
|
45
|
+
const _TextEncoderStream = typeof globalThis.TextEncoderStream === 'function'
|
|
46
|
+
? globalThis.TextEncoderStream
|
|
47
|
+
: TextEncoderStream;
|
|
48
|
+
const _TextDecoderStream = typeof globalThis.TextDecoderStream === 'function'
|
|
49
|
+
? globalThis.TextDecoderStream
|
|
50
|
+
: TextDecoderStream;
|
|
51
|
+
|
|
52
|
+
// Register globals — replace broken native implementations with polyfill
|
|
53
|
+
if (!isNativeStreamUsable(globalThis.ReadableStream, 'getReader')) {
|
|
54
|
+
(globalThis as any).ReadableStream = ReadableStream;
|
|
55
|
+
}
|
|
56
|
+
if (!isNativeStreamUsable(globalThis.WritableStream, 'getWriter')) {
|
|
57
|
+
(globalThis as any).WritableStream = WritableStream;
|
|
58
|
+
}
|
|
59
|
+
if (!isNativeStreamUsable(globalThis.TransformStream, 'readable')) {
|
|
60
|
+
(globalThis as any).TransformStream = TransformStream;
|
|
61
|
+
}
|
|
62
|
+
if (typeof globalThis.ByteLengthQueuingStrategy === 'undefined') {
|
|
63
|
+
(globalThis as any).ByteLengthQueuingStrategy = ByteLengthQueuingStrategy;
|
|
64
|
+
}
|
|
65
|
+
if (typeof globalThis.CountQueuingStrategy === 'undefined') {
|
|
66
|
+
(globalThis as any).CountQueuingStrategy = CountQueuingStrategy;
|
|
67
|
+
}
|
|
68
|
+
if (typeof globalThis.TextEncoderStream === 'undefined') {
|
|
69
|
+
(globalThis as any).TextEncoderStream = TextEncoderStream;
|
|
70
|
+
}
|
|
71
|
+
if (typeof globalThis.TextDecoderStream === 'undefined') {
|
|
72
|
+
(globalThis as any).TextDecoderStream = TextDecoderStream;
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
export {
|
|
76
|
+
_WritableStream as WritableStream,
|
|
77
|
+
_ReadableStream as ReadableStream,
|
|
78
|
+
_TransformStream as TransformStream,
|
|
79
|
+
_ByteLengthQueuingStrategy as ByteLengthQueuingStrategy,
|
|
80
|
+
_CountQueuingStrategy as CountQueuingStrategy,
|
|
81
|
+
_TextEncoderStream as TextEncoderStream,
|
|
82
|
+
_TextDecoderStream as TextDecoderStream,
|
|
83
|
+
};
|
|
84
|
+
|
|
85
|
+
// Re-export class types for direct import
|
|
86
|
+
export { WritableStreamDefaultWriter, WritableStreamDefaultController } from './writable-stream.js';
|
|
87
|
+
export { ReadableStreamDefaultReader, ReadableStreamDefaultController } from './readable-stream.js';
|
|
88
|
+
export { TransformStreamDefaultController } from './transform-stream.js';
|
|
89
|
+
|
|
90
|
+
// Re-export internals needed by other packages
|
|
91
|
+
export {
|
|
92
|
+
isWritableStream,
|
|
93
|
+
isWritableStreamLocked,
|
|
94
|
+
writableStreamAbort,
|
|
95
|
+
writableStreamClose,
|
|
96
|
+
writableStreamCloseQueuedOrInFlight,
|
|
97
|
+
writableStreamDefaultWriterCloseWithErrorPropagation,
|
|
98
|
+
writableStreamDefaultControllerErrorIfNeeded,
|
|
99
|
+
createWritableStream,
|
|
100
|
+
} from './writable-stream.js';
|
|
101
|
+
|
|
102
|
+
export {
|
|
103
|
+
isReadableStream,
|
|
104
|
+
isReadableStreamLocked,
|
|
105
|
+
readableStreamCancel,
|
|
106
|
+
readableStreamClose,
|
|
107
|
+
readableStreamError,
|
|
108
|
+
readableStreamDefaultControllerClose,
|
|
109
|
+
readableStreamDefaultControllerEnqueue,
|
|
110
|
+
readableStreamDefaultControllerError,
|
|
111
|
+
readableStreamDefaultControllerGetDesiredSize,
|
|
112
|
+
readableStreamDefaultControllerCanCloseOrEnqueue,
|
|
113
|
+
readableStreamDefaultControllerHasBackpressure,
|
|
114
|
+
setupReadableStreamDefaultController,
|
|
115
|
+
createReadableStream,
|
|
116
|
+
} from './readable-stream.js';
|
|
117
|
+
|
|
118
|
+
export {
|
|
119
|
+
isTransformStream,
|
|
120
|
+
isTransformStreamDefaultController,
|
|
121
|
+
} from './transform-stream.js';
|
|
122
|
+
|
|
123
|
+
export default {
|
|
124
|
+
WritableStream: _WritableStream,
|
|
125
|
+
ReadableStream: _ReadableStream,
|
|
126
|
+
TransformStream: _TransformStream,
|
|
127
|
+
ByteLengthQueuingStrategy: _ByteLengthQueuingStrategy,
|
|
128
|
+
CountQueuingStrategy: _CountQueuingStrategy,
|
|
129
|
+
TextEncoderStream: _TextEncoderStream,
|
|
130
|
+
TextDecoderStream: _TextDecoderStream,
|
|
131
|
+
};
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
// WHATWG Streams — ByteLengthQueuingStrategy and CountQueuingStrategy
|
|
2
|
+
// Adapted from refs/node/lib/internal/webstreams/queuingstrategies.js
|
|
3
|
+
// Copyright (c) Node.js contributors. MIT license.
|
|
4
|
+
|
|
5
|
+
const byteSizeFunction = Object.defineProperty(
|
|
6
|
+
(chunk: any) => chunk.byteLength,
|
|
7
|
+
'name',
|
|
8
|
+
{ value: 'size' },
|
|
9
|
+
);
|
|
10
|
+
|
|
11
|
+
const countSizeFunction = Object.defineProperty(
|
|
12
|
+
() => 1,
|
|
13
|
+
'name',
|
|
14
|
+
{ value: 'size' },
|
|
15
|
+
);
|
|
16
|
+
|
|
17
|
+
export class ByteLengthQueuingStrategy {
|
|
18
|
+
#highWaterMark: number;
|
|
19
|
+
|
|
20
|
+
constructor(init: { highWaterMark: number }) {
|
|
21
|
+
if (init == null || typeof init !== 'object') {
|
|
22
|
+
throw new TypeError('init must be an object');
|
|
23
|
+
}
|
|
24
|
+
if (init.highWaterMark === undefined) {
|
|
25
|
+
throw new TypeError('init.highWaterMark is required');
|
|
26
|
+
}
|
|
27
|
+
this.#highWaterMark = +init.highWaterMark;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
get highWaterMark(): number {
|
|
31
|
+
return this.#highWaterMark;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
get size(): (chunk: any) => number {
|
|
35
|
+
return byteSizeFunction;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
get [Symbol.toStringTag]() {
|
|
39
|
+
return 'ByteLengthQueuingStrategy';
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
export class CountQueuingStrategy {
|
|
44
|
+
#highWaterMark: number;
|
|
45
|
+
|
|
46
|
+
constructor(init: { highWaterMark: number }) {
|
|
47
|
+
if (init == null || typeof init !== 'object') {
|
|
48
|
+
throw new TypeError('init must be an object');
|
|
49
|
+
}
|
|
50
|
+
if (init.highWaterMark === undefined) {
|
|
51
|
+
throw new TypeError('init.highWaterMark is required');
|
|
52
|
+
}
|
|
53
|
+
this.#highWaterMark = +init.highWaterMark;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
get highWaterMark(): number {
|
|
57
|
+
return this.#highWaterMark;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
get size(): (chunk: any) => number {
|
|
61
|
+
return countSizeFunction;
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
get [Symbol.toStringTag]() {
|
|
65
|
+
return 'CountQueuingStrategy';
|
|
66
|
+
}
|
|
67
|
+
}
|