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 CHANGED
@@ -1,6 +1,6 @@
1
1
  ## Web Streams Shim Library
2
2
 
3
- This README provides an overview of the features in this Web Streams Shim Library, which is designed to create parity between the streaming interfaces within modern runtimes.
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.prototype`](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.prototype`](https://developer.mozilla.org/en-US/docs/Web/API/ReadableStream) | `values()` | An alias for `[Symbol.asyncIterator]` for explicit iteration. |
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
  ![ReadableStream.asyncIterator](https://caniuse.smokestack.workers.dev/?feature=api.ReadableStream.@@asyncIterator)
23
23
  ![ReadableStream.values](https://caniuse.smokestack.workers.dev/?feature=api.ReadableStream.values)
@@ -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
- ![Symbol.asyncIterator](https://caniuse.smokestack.workers.dev/?feature=api.ReadableStream.from)
33
+ ![ReadableStream.from](https://caniuse.smokestack.workers.dev/?feature=api.ReadableStream.from)
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.prototype` | [`body`](https://developer.mozilla.org/en-US/docs/Web/API/Request/body) (Getter) | 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.prototype` | [`body`](https://developer.mozilla.org/en-US/docs/Web/API/Response/body) (Getter) | 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.prototype`](https://developer.mozilla.org/en-US/docs/Web/API/Request/bytes), [`Response.prototype`](https://developer.mozilla.org/en-US/docs/Web/API/Response/bytes), [`Blob.prototype`](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. |
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
  ![Request.body](https://caniuse.smokestack.workers.dev/?feature=api.Request.body)
46
46
  ![Response.body](https://caniuse.smokestack.workers.dev/?feature=api.Response.body)
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
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "web-streams-shim",
3
- "version": "1.0.3",
3
+ "version": "1.0.4",
4
4
  "description": "",
5
5
  "main": "web-streams-core.js",
6
6
  "scripts": {
@@ -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
  })();