web-streams-shim 1.0.3 → 1.0.4
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 +7 -7
- package/Record-body.js +9 -0
- package/extensions/Recod-stream.js +77 -0
- package/extensions/web-streams-extensions.js +131 -0
- package/package.json +1 -1
- package/web-streams-core.js +10 -0
package/README.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
## Web Streams Shim Library
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
The Web Streams Shim Library is designed to create parity between the streaming interfaces within modern runtimes. This does not polyfill the interfaces if they are missing entirely. For that you will want [web-streams-polyfill](https://www.npmjs.com/package/web-streams-polyfill) which is not affiliated with the project.
|
|
4
4
|
|
|
5
5
|
This library provides essential polyfills and shims to ensure modern Web Streams functionality is available and compliant across environments where native support is missing or incomplete, particularly focusing on `ReadableStream`, `Request`, `Response`, and `Blob` objects.
|
|
6
6
|
|
|
@@ -16,8 +16,8 @@ The library adds **comprehensive support for modern JavaScript iteration pattern
|
|
|
16
16
|
|
|
17
17
|
| Target | Method/Property | Description |
|
|
18
18
|
| :--- | :--- | :--- |
|
|
19
|
-
| [`ReadableStream
|
|
20
|
-
| [`ReadableStream
|
|
19
|
+
| [`ReadableStream`](https://developer.mozilla.org/en-US/docs/Web/API/ReadableStream) | `[Symbol.asyncIterator]` | Allows the stream to be directly iterable in `for-await-of` loops. |
|
|
20
|
+
| [`ReadableStream`](https://developer.mozilla.org/en-US/docs/Web/API/ReadableStream) | `values()` | An alias for `[Symbol.asyncIterator]` for explicit iteration. |
|
|
21
21
|
|
|
22
22
|

|
|
23
23
|

|
|
@@ -30,7 +30,7 @@ The library adds the static method for creating streams from existing data sourc
|
|
|
30
30
|
| :--- | :--- | :--- |
|
|
31
31
|
| [`ReadableStream`](https://developer.mozilla.org/en-US/docs/Web/API/ReadableStream) | [`from(obj)`](https://developer.mozilla.org/en-US/docs/Web/API/ReadableStream/from_static) | **Creates a new `ReadableStream` from any iterable or async iterable object**. It handles both synchronous and asynchronous iterators, including objects that yield `Promise`-like values. |
|
|
32
32
|
|
|
33
|
-

|
|
34
34
|
|
|
35
35
|
### 3. Fetch and Body Integration Shims
|
|
36
36
|
|
|
@@ -38,9 +38,9 @@ These shims ensure `Request` and `Response` objects (Records) consistently expos
|
|
|
38
38
|
|
|
39
39
|
| Target | Method/Property | Description |
|
|
40
40
|
| :--- | :--- | :--- |
|
|
41
|
-
| `Request
|
|
42
|
-
| `Response
|
|
43
|
-
| [`Request
|
|
41
|
+
| `Request` | [`body`](https://developer.mozilla.org/en-US/docs/Web/API/Request/body) | Polyfills the `body` property to return a **`ReadableStream` representation of the body content**. This is crucial for environments where `fetch` exists but streaming is absent. |
|
|
42
|
+
| `Response` | [`body`](https://developer.mozilla.org/en-US/docs/Web/API/Response/body) | Provides the body content as a `ReadableStream`. The implementation clones the original record, converts the body to a `Blob`, gets the blob's stream, and enqueues chunks via a controller. |
|
|
43
|
+
| [`Request`](https://developer.mozilla.org/en-US/docs/Web/API/Request/bytes), [`Response`](https://developer.mozilla.org/en-US/docs/Web/API/Response/bytes), [`Blob`](https://developer.mozilla.org/en-US/docs/Web/API/Blob/bytes) | `bytes()` | Adds the `bytes()` method, which **asynchronously returns the object's body/content as a `Uint8Array`**. It achieves this by calling the native `arrayBuffer()` and wrapping the result. |
|
|
44
44
|
|
|
45
45
|

|
|
46
46
|

|
package/Record-body.js
CHANGED
|
@@ -267,6 +267,15 @@
|
|
|
267
267
|
configurable: true,
|
|
268
268
|
enumerable: true,
|
|
269
269
|
});
|
|
270
|
+
if('bodyUsed' in record.prototype)return;
|
|
271
|
+
Object.defineProperty(record.prototype, "bodyUsed", {
|
|
272
|
+
get:setStrings(function bodyUsed(){
|
|
273
|
+
return this.body?.locked;
|
|
274
|
+
}),
|
|
275
|
+
set:()=>{},
|
|
276
|
+
configurable:true,
|
|
277
|
+
enumerable:true
|
|
278
|
+
});
|
|
270
279
|
})();
|
|
271
280
|
|
|
272
281
|
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
|
|
2
|
+
(() => {
|
|
3
|
+
const Q = fn => {
|
|
4
|
+
try {
|
|
5
|
+
return fn?.()
|
|
6
|
+
} catch {}
|
|
7
|
+
};
|
|
8
|
+
const constructPrototype = newClass => {
|
|
9
|
+
try {
|
|
10
|
+
if (newClass?.prototype) return newClass;
|
|
11
|
+
const constProto = newClass?.constructor?.prototype;
|
|
12
|
+
if (constProto) {
|
|
13
|
+
newClass.prototype = Q(() => constProto?.bind?.(constProto)) ?? Object.create(Object(constProto));
|
|
14
|
+
return newClass;
|
|
15
|
+
}
|
|
16
|
+
newClass.prototype = Q(() => newClass?.bind?.(newClass)) ?? Object.create(Object(newClass));
|
|
17
|
+
} catch (e) {
|
|
18
|
+
console.warn(e, newClass);
|
|
19
|
+
}
|
|
20
|
+
};
|
|
21
|
+
const extend = (thisClass, superClass) => {
|
|
22
|
+
try {
|
|
23
|
+
constructPrototype(thisClass);
|
|
24
|
+
constructPrototype(superClass);
|
|
25
|
+
Object.setPrototypeOf(
|
|
26
|
+
thisClass.prototype,
|
|
27
|
+
superClass?.prototype ??
|
|
28
|
+
superClass?.constructor?.prototype ??
|
|
29
|
+
superClass
|
|
30
|
+
);
|
|
31
|
+
Object.setPrototypeOf(thisClass, superClass);
|
|
32
|
+
|
|
33
|
+
} catch (e) {
|
|
34
|
+
console.warn(e, {
|
|
35
|
+
thisClass,
|
|
36
|
+
superClass
|
|
37
|
+
});
|
|
38
|
+
}
|
|
39
|
+
return thisClass;
|
|
40
|
+
};
|
|
41
|
+
const makeStringer = str => {
|
|
42
|
+
const stringer = () => str;
|
|
43
|
+
['valueOf', 'toString', 'toLocaleString', Symbol.toPrimitive].forEach(x => {
|
|
44
|
+
stringer[x] = stringer;
|
|
45
|
+
});
|
|
46
|
+
stringer[Symbol.toStringTag] = str;
|
|
47
|
+
return stringer;
|
|
48
|
+
};
|
|
49
|
+
const setStrings = (obj, name) => {
|
|
50
|
+
for (const str of ['toString', 'toLocaleString', Symbol.toStringTag]) {
|
|
51
|
+
Object.defineProperty(obj, str, {
|
|
52
|
+
value: makeStringer(`function ${obj.name}() { [polyfill code] }`),
|
|
53
|
+
configurable: true,
|
|
54
|
+
writable: true,
|
|
55
|
+
enumerable: false,
|
|
56
|
+
});
|
|
57
|
+
}
|
|
58
|
+
return obj;
|
|
59
|
+
};
|
|
60
|
+
|
|
61
|
+
for (const record of [Q(() => Request), Q(() => Response)]) {
|
|
62
|
+
(() => {
|
|
63
|
+
while(record.__proto__.name === record.name) record = record.__proto__;
|
|
64
|
+
(record?.prototype ?? {}).stream ??= extend(setStrings(function stream() {
|
|
65
|
+
return this.body;
|
|
66
|
+
}), Q(() => ReadableStream) ?? {});
|
|
67
|
+
})();
|
|
68
|
+
}
|
|
69
|
+
if(!('body' in Blob.prototype)){
|
|
70
|
+
Object.defineProperty(Blob.prototype,'body',{
|
|
71
|
+
get:extend(setStrings(function body(){return this.stream();},ReadableStream)),
|
|
72
|
+
set:()=>{},
|
|
73
|
+
configurable:true,
|
|
74
|
+
enumerable:false
|
|
75
|
+
});
|
|
76
|
+
}
|
|
77
|
+
})();
|
|
@@ -0,0 +1,131 @@
|
|
|
1
|
+
|
|
2
|
+
(() => {
|
|
3
|
+
const Q = fn => {
|
|
4
|
+
try {
|
|
5
|
+
return fn?.()
|
|
6
|
+
} catch {}
|
|
7
|
+
};
|
|
8
|
+
const constructPrototype = newClass => {
|
|
9
|
+
try {
|
|
10
|
+
if (newClass?.prototype) return newClass;
|
|
11
|
+
const constProto = newClass?.constructor?.prototype;
|
|
12
|
+
if (constProto) {
|
|
13
|
+
newClass.prototype = Q(() => constProto?.bind?.(constProto)) ?? Object.create(Object(constProto));
|
|
14
|
+
return newClass;
|
|
15
|
+
}
|
|
16
|
+
newClass.prototype = Q(() => newClass?.bind?.(newClass)) ?? Object.create(Object(newClass));
|
|
17
|
+
} catch (e) {
|
|
18
|
+
console.warn(e, newClass);
|
|
19
|
+
}
|
|
20
|
+
};
|
|
21
|
+
const extend = (thisClass, superClass) => {
|
|
22
|
+
try {
|
|
23
|
+
constructPrototype(thisClass);
|
|
24
|
+
constructPrototype(superClass);
|
|
25
|
+
Object.setPrototypeOf(
|
|
26
|
+
thisClass.prototype,
|
|
27
|
+
superClass?.prototype ??
|
|
28
|
+
superClass?.constructor?.prototype ??
|
|
29
|
+
superClass
|
|
30
|
+
);
|
|
31
|
+
Object.setPrototypeOf(thisClass, superClass);
|
|
32
|
+
|
|
33
|
+
} catch (e) {
|
|
34
|
+
console.warn(e, {
|
|
35
|
+
thisClass,
|
|
36
|
+
superClass
|
|
37
|
+
});
|
|
38
|
+
}
|
|
39
|
+
return thisClass;
|
|
40
|
+
};
|
|
41
|
+
const makeStringer = str => {
|
|
42
|
+
const stringer = () => str;
|
|
43
|
+
['valueOf', 'toString', 'toLocaleString', Symbol.toPrimitive].forEach(x => {
|
|
44
|
+
stringer[x] = stringer;
|
|
45
|
+
});
|
|
46
|
+
stringer[Symbol.toStringTag] = str;
|
|
47
|
+
return stringer;
|
|
48
|
+
};
|
|
49
|
+
const setStrings = (obj, name) => {
|
|
50
|
+
for (const str of ['toString', 'toLocaleString', Symbol.toStringTag]) {
|
|
51
|
+
Object.defineProperty(obj, str, {
|
|
52
|
+
value: makeStringer(`function ${obj.name}() { [polyfill code] }`),
|
|
53
|
+
configurable: true,
|
|
54
|
+
writable: true,
|
|
55
|
+
enumerable: false,
|
|
56
|
+
});
|
|
57
|
+
}
|
|
58
|
+
return obj;
|
|
59
|
+
};
|
|
60
|
+
|
|
61
|
+
for (const record of [Q(() => Request), Q(() => Response)]) {
|
|
62
|
+
(() => {
|
|
63
|
+
while (record.__proto__.name === record.name) record = record.__proto__;
|
|
64
|
+
(record?.prototype ?? {}).stream ??= extend(setStrings(function stream() {
|
|
65
|
+
return this.body;
|
|
66
|
+
}), Q(() => ReadableStream) ?? {});
|
|
67
|
+
})();
|
|
68
|
+
}
|
|
69
|
+
for (const record of [Q(() => Request), Q(() => Response), Q(() => Blob)]) {
|
|
70
|
+
(() => {
|
|
71
|
+
while (record.__proto__.name === record.name) record = record.__proto__;
|
|
72
|
+
record.prototype[Symbol.asyncIterator] ??= extend(setStrings(Object.defineProperty(function asyncIterator() {
|
|
73
|
+
return this.stream()[Symbol.asyncIterator]();
|
|
74
|
+
}, 'name', {
|
|
75
|
+
value: 'Symbol.asyncIterator',
|
|
76
|
+
configurable: true,
|
|
77
|
+
writable: true,
|
|
78
|
+
enumerable: true,
|
|
79
|
+
})), ReadableStream.prototype[Symbol.asyncIterator]);
|
|
80
|
+
record.prototype.values ??= extend(setStrings(function values() {
|
|
81
|
+
return this[Symbol.asyncIterator]();
|
|
82
|
+
}), ReadableStream.prototype.values);
|
|
83
|
+
})();
|
|
84
|
+
}
|
|
85
|
+
if (!('body' in Blob.prototype)) {
|
|
86
|
+
Object.defineProperty(Blob.prototype, 'body', {
|
|
87
|
+
get: extend(setStrings(function body() {
|
|
88
|
+
return this.stream();
|
|
89
|
+
}, ReadableStream)),
|
|
90
|
+
set: () => {},
|
|
91
|
+
configurable: true,
|
|
92
|
+
enumerable: true
|
|
93
|
+
});
|
|
94
|
+
}
|
|
95
|
+
if (!('bodyUsed' in Blob.prototype)) {
|
|
96
|
+
Object.defineProperty(Blob.prototype, "bodyUsed", {
|
|
97
|
+
get: setStrings(function bodyUsed() {
|
|
98
|
+
return this.body?.locked;
|
|
99
|
+
}),
|
|
100
|
+
set: () => {},
|
|
101
|
+
configurable: true,
|
|
102
|
+
enumerable: true
|
|
103
|
+
});
|
|
104
|
+
}
|
|
105
|
+
Blob.prototype.blob ??= extend(setStrings(function blob() {
|
|
106
|
+
return this;
|
|
107
|
+
}), Blob);
|
|
108
|
+
Blob.prototype.clone ??= extend(setStrings(function clone() {
|
|
109
|
+
return this.slice();
|
|
110
|
+
}), Blob);
|
|
111
|
+
Blob.prototype.formData ??= extend(setStrings(function formData() {
|
|
112
|
+
return new Response(this).formData();
|
|
113
|
+
}), FormData);
|
|
114
|
+
Blob.prototype.json ??= extend(setStrings(function json() {
|
|
115
|
+
return new Response(this).json();
|
|
116
|
+
}), JSON);
|
|
117
|
+
ArrayBuffer.prototype.bytes ??= extend(setStrings(function bytes() {
|
|
118
|
+
return new Uint8Array(this);
|
|
119
|
+
}), Uint8Array);
|
|
120
|
+
ArrayBuffer.prototype[Symbol.iterator] ??= extend(setStrings(Object.defineProperty(function iterator() {
|
|
121
|
+
return this.bytes()[Symbol.iterator]();
|
|
122
|
+
}, 'name', {
|
|
123
|
+
value: 'Symbol.iterator',
|
|
124
|
+
configurable: true,
|
|
125
|
+
writable: true,
|
|
126
|
+
enumerable: true,
|
|
127
|
+
})), Uint8Array.prototype[Symbol.iterator]);
|
|
128
|
+
ArrayBuffer.prototype.values ??= extend(setStrings(function values() {
|
|
129
|
+
return this[Symbol.iterator]();
|
|
130
|
+
}), Uint8Array.prototype.values);
|
|
131
|
+
})();
|
package/package.json
CHANGED
package/web-streams-core.js
CHANGED
|
@@ -635,6 +635,15 @@
|
|
|
635
635
|
configurable: true,
|
|
636
636
|
enumerable: true,
|
|
637
637
|
});
|
|
638
|
+
if('bodyUsed' in record.prototype)return;
|
|
639
|
+
Object.defineProperty(record.prototype, "bodyUsed", {
|
|
640
|
+
get:setStrings(function bodyUsed(){
|
|
641
|
+
return this.body?.locked;
|
|
642
|
+
}),
|
|
643
|
+
set:()=>{},
|
|
644
|
+
configurable:true,
|
|
645
|
+
enumerable:true
|
|
646
|
+
});
|
|
638
647
|
})();
|
|
639
648
|
|
|
640
649
|
|
|
@@ -839,5 +848,6 @@
|
|
|
839
848
|
return $ReadableStreamDefaultReader(stream)
|
|
840
849
|
},$ReadableStreamDefaultReader.prototype)
|
|
841
850
|
},$ReadableStreamDefaultReader));
|
|
851
|
+
globalThis.ReadableStreamDefaultReader.prototype.constructor = globalThis.ReadableStreamDefaultReader;
|
|
842
852
|
}
|
|
843
853
|
})();
|