web-streams-shim 1.0.6 → 1.0.8

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.
@@ -0,0 +1,100 @@
1
+ /**
2
+ * Record Stream Extensions - Minimal stream() method polyfills
3
+ *
4
+ * Adds stream() method to Request, Response, and Blob objects as a convenient
5
+ * alias for the .body property. This is a lightweight alternative to the full
6
+ * web-streams-extensions.js that only adds the stream() method.
7
+ *
8
+ * Also adds Blob.body property for API consistency with Request/Response.
9
+ *
10
+ * Use this instead of web-streams-extensions.js when you only need the
11
+ * stream() alias and don't want the other non-standard extensions.
12
+ *
13
+ * @note Non-standard convenience method
14
+ */
15
+ (() => {
16
+ const Q = fn => {
17
+ try {
18
+ return fn?.()
19
+ } catch {}
20
+ };
21
+ const constructPrototype = newClass => {
22
+ try {
23
+ if (newClass?.prototype) return newClass;
24
+ const constProto = newClass?.constructor?.prototype;
25
+ if (constProto) {
26
+ newClass.prototype = Q(() => constProto?.bind?.(constProto)) ?? Object.create(Object(constProto));
27
+ return newClass;
28
+ }
29
+ newClass.prototype = Q(() => newClass?.bind?.(newClass)) ?? Object.create(Object(newClass));
30
+ } catch (e) {
31
+ console.warn(e, newClass);
32
+ }
33
+ };
34
+ const extend = (thisClass, superClass) => {
35
+ try {
36
+ constructPrototype(thisClass);
37
+ constructPrototype(superClass);
38
+ Object.setPrototypeOf(
39
+ thisClass.prototype,
40
+ superClass?.prototype ??
41
+ superClass?.constructor?.prototype ??
42
+ superClass
43
+ );
44
+ Object.setPrototypeOf(thisClass, superClass);
45
+
46
+ } catch (e) {
47
+ console.warn(e, {
48
+ thisClass,
49
+ superClass
50
+ });
51
+ }
52
+ return thisClass;
53
+ };
54
+ const makeStringer = str => {
55
+ const stringer = () => str;
56
+ ['valueOf', 'toString', 'toLocaleString', Symbol.toPrimitive].forEach(x => {
57
+ stringer[x] = stringer;
58
+ });
59
+ stringer[Symbol.toStringTag] = str;
60
+ return stringer;
61
+ };
62
+ const setStrings = (obj) => {
63
+ let type = 'function';
64
+ if(String(obj).trim().startsWith('class')||/^[A-Z]|^.[A-Z]/.test(obj?.name)){
65
+ type = 'class';
66
+ }
67
+ if(String(obj).trim().startsWith('async')||/async/i.test(obj?.name)){
68
+ type = 'async function';
69
+ }
70
+ for (const str of ['toString', 'toLocaleString', Symbol.toStringTag]) {
71
+ Object.defineProperty(obj, str, {
72
+ value: makeStringer(`${type} ${obj.name} { [polyfill code] }`),
73
+ configurable: true,
74
+ writable: true,
75
+ enumerable: false,
76
+ });
77
+ }
78
+ return obj;
79
+ };
80
+
81
+ for (const record of [Q(() => Request), Q(() => Response)]) {
82
+ (() => {
83
+ let currentRecord = record;
84
+ while(currentRecord.__proto__.name === currentRecord.name) {
85
+ currentRecord = currentRecord.__proto__;
86
+ }
87
+ (currentRecord?.prototype ?? {}).stream ??= extend(setStrings(function stream() {
88
+ return this.body;
89
+ }), Q(() => ReadableStream) ?? {});
90
+ })();
91
+ }
92
+ if(!('body' in Blob.prototype)){
93
+ Object.defineProperty(Blob.prototype,'body',{
94
+ get:extend(setStrings(function body(){return this.stream();})),
95
+ set:()=>{},
96
+ configurable:true,
97
+ enumerable:false
98
+ });
99
+ }
100
+ })();
@@ -1,9 +1,37 @@
1
+ /**
2
+ * File Constructor Polyfill
3
+ *
4
+ * Provides a File class implementation for environments that lack it, such as:
5
+ * - Cloudflare Workers
6
+ * - Google Apps Script
7
+ * - Some serverless edge runtimes
8
+ * - Older Node.js versions (pre-20)
9
+ *
10
+ * The File class extends Blob and adds file-specific properties:
11
+ * - name: The file name
12
+ * - lastModified: Timestamp in milliseconds
13
+ * - lastModifiedDate: Date object (deprecated but included for compatibility)
14
+ * - webkitRelativePath: Empty string (for compatibility)
15
+ *
16
+ * This is a functional implementation that allows File objects to be created
17
+ * and used in environments where the native File constructor is missing.
18
+ *
19
+ * @note This is a complete implementation, not a partial shim
20
+ */
1
21
  (() => {
2
22
  const Q = fn => {
3
23
  try {
4
24
  return fn?.()
5
25
  } catch {}
6
26
  };
27
+ const setHidden = (obj, prop, value) => {
28
+ Object.defineProperty(obj, prop, {
29
+ value,
30
+ writable: true,
31
+ enumerable: false,
32
+ configurable: true
33
+ });
34
+ }
7
35
  const $global = Q(() => globalThis) ?? Q(() => global) ?? Q(() => self) ?? Q(() => window) ?? this;
8
36
  if (typeof File === 'undefined') {
9
37
  // Sham File class extending Blob
@@ -18,9 +46,9 @@
18
46
  super(bits, blobOptions);
19
47
 
20
48
  // Add File-specific properties
21
- this['&name'] = filename;
22
- this['&lastModified'] = lastModified;
23
- this['&lastModifiedDate'] = new Date(lastModified);
49
+ setHidden(this, '&name', filename);
50
+ setHidden(this, '&lastModified', lastModified);
51
+ setHidden(this, '&lastModifiedDate', new Date(lastModified));
24
52
  }
25
53
 
26
54
  get name() {
@@ -1,3 +1,24 @@
1
+ /**
2
+ * Location Constructor Polyfill
3
+ *
4
+ * Provides a Location class implementation for environments that lack it, such as:
5
+ * - Cloudflare Workers
6
+ * - Deno Deploy
7
+ * - Vercel Edge Runtime
8
+ * - Service Workers in some contexts
9
+ * - Node.js and other server environments
10
+ *
11
+ * The Location class extends URL and adds browser Location API compatibility:
12
+ * - ancestorOrigins: Empty list (server environments have no origin hierarchy)
13
+ * - assign(url): Updates the href (no navigation in server context)
14
+ * - reload(forceReload): No-op with console log (no page to reload)
15
+ * - replace(url): Updates the href (no navigation in server context)
16
+ *
17
+ * This allows code written for browsers to run in serverless environments
18
+ * without modification, though navigation methods are no-ops.
19
+ *
20
+ * @note Methods like reload() don't actually navigate - use URL directly for parsing
21
+ */
1
22
  (() => {
2
23
  const Q = fn => {
3
24
  try {
@@ -1,17 +1,122 @@
1
- (()=>{
2
- const typeMap = {
3
- blob:Blob,
4
- text:TextDecoder,
5
- json:JSON,
6
- arrayBuffer:ArrayBuffer,
7
- stream:ReadableStream,
8
- formData:FormData,
9
- byte:Uint8Array,
10
- slice:Blob
11
- };
12
- const getMap = {
13
- url:URL,
14
- headers:Headers,
15
- body:ReadableStream
16
- };
1
+ /**
2
+ * Type Extensions - Sets up prototype chains for Web API methods
3
+ * Extends methods on Request, Response, and Blob to inherit from the class
4
+ * of the type they return (e.g., Response.prototype.blob extended with Blob)
5
+ * This provides better runtime type traceability and debugging experience
6
+ */
7
+ (() => {
8
+ const Q = fn => {
9
+ try {
10
+ return fn?.()
11
+ } catch {}
12
+ };
13
+ const constructPrototype = newClass => {
14
+ try {
15
+ if (newClass?.prototype) return newClass;
16
+ const constProto = newClass?.constructor?.prototype;
17
+ if (constProto) {
18
+ newClass.prototype = Q(() => constProto?.bind?.(constProto)) ?? Object.create(Object(constProto));
19
+ return newClass;
20
+ }
21
+ newClass.prototype = Q(() => newClass?.bind?.(newClass)) ?? Object.create(Object(newClass));
22
+ } catch (e) {
23
+ console.warn(e, newClass);
24
+ }
25
+ };
26
+ const extend = (thisClass, superClass) => {
27
+ try {
28
+ constructPrototype(thisClass);
29
+ constructPrototype(superClass);
30
+ Object.setPrototypeOf(
31
+ thisClass.prototype,
32
+ superClass?.prototype ??
33
+ superClass?.constructor?.prototype ??
34
+ superClass
35
+ );
36
+ Object.setPrototypeOf(thisClass, superClass);
37
+
38
+ } catch (e) {
39
+ console.warn(e, {
40
+ thisClass,
41
+ superClass
42
+ });
43
+ }
44
+ return thisClass;
45
+ };
46
+
47
+ /**
48
+ * Map of method names to their return type constructors
49
+ * Methods that return specific types get extended with those types' prototypes
50
+ */
51
+ const typeMap = {
52
+ blob: Q(() => Blob),
53
+ text: Q(() => TextDecoder),
54
+ json: Q(() => JSON),
55
+ arrayBuffer: Q(() => ArrayBuffer),
56
+ stream: Q(() => ReadableStream),
57
+ formData: Q(() => FormData),
58
+ bytes: Q(() => Uint8Array),
59
+ slice: Q(() => Blob)
60
+ };
61
+
62
+ /**
63
+ * Map of getter property names to their return type constructors
64
+ */
65
+ const getterMap = {
66
+ url: Q(() => URL),
67
+ headers: Q(() => Headers),
68
+ body: Q(() => ReadableStream)
69
+ };
70
+
71
+ /**
72
+ * Extend methods on Request, Response, and Blob prototypes
73
+ * to inherit from their return type constructors
74
+ */
75
+ for (const record of [Q(() => Request), Q(() => Response), Q(() => Blob)]) {
76
+ if (!record) continue;
77
+
78
+ // Extend methods that return typed values
79
+ for (const [methodName, TypeClass] of Object.entries(typeMap)) {
80
+ const method = record.prototype?.[methodName];
81
+ if (method && TypeClass) {
82
+ try {
83
+ extend(method, TypeClass);
84
+ } catch (e) {
85
+ console.warn(`Failed to extend ${record.name}.prototype.${methodName}`, e);
86
+ }
87
+ }
88
+ }
89
+
90
+ // Extend getter properties
91
+ for (const [propName, TypeClass] of Object.entries(getterMap)) {
92
+ const descriptor = Object.getOwnPropertyDescriptor(record.prototype, propName);
93
+ if (descriptor?.get && TypeClass) {
94
+ try {
95
+ extend(descriptor.get, TypeClass);
96
+ } catch (e) {
97
+ console.warn(`Failed to extend ${record.name}.prototype.${propName} getter`, e);
98
+ }
99
+ }
100
+ }
101
+ }
102
+
103
+ // Also extend ArrayBuffer methods if present
104
+ const arrayBufferMethods = {
105
+ bytes: Q(() => Uint8Array),
106
+ slice: Q(() => ArrayBuffer)
107
+ };
108
+
109
+ if (Q(() => ArrayBuffer)) {
110
+ for (const [methodName, TypeClass] of Object.entries(arrayBufferMethods)) {
111
+ const method = ArrayBuffer.prototype?.[methodName];
112
+ if (method && TypeClass) {
113
+ try {
114
+ extend(method, TypeClass);
115
+ } catch (e) {
116
+ console.warn(`Failed to extend ArrayBuffer.prototype.${methodName}`, e);
117
+ }
118
+ }
119
+ }
120
+ }
17
121
  })();
122
+
@@ -0,0 +1,57 @@
1
+ /**
2
+ * TypeScript definitions for web-streams-shim extensions
3
+ * Additional non-standard convenience methods for Web Streams
4
+ */
5
+
6
+ /// <reference lib="dom" />
7
+ /// <reference path="./web-streams-core.d.ts" />
8
+
9
+ /**
10
+ * Extended Request interface with additional streaming utilities
11
+ */
12
+ interface Request {
13
+ /**
14
+ * Returns the body as a ReadableStream (alias for body property)
15
+ * Non-standard convenience method
16
+ * @returns The request body as a ReadableStream
17
+ */
18
+ stream(): ReadableStream<Uint8Array>;
19
+ }
20
+
21
+ /**
22
+ * Extended Response interface with additional streaming utilities
23
+ */
24
+ interface Response {
25
+ /**
26
+ * Returns the body as a ReadableStream (alias for body property)
27
+ * Non-standard convenience method
28
+ * @returns The response body as a ReadableStream
29
+ */
30
+ stream(): ReadableStream<Uint8Array>;
31
+ }
32
+
33
+ /**
34
+ * Extended Blob interface with body property and streaming support
35
+ */
36
+ interface Blob {
37
+ /**
38
+ * Returns the blob content as a ReadableStream
39
+ * Non-standard convenience method that matches Request/Response API
40
+ * @returns The blob content as a ReadableStream
41
+ */
42
+ stream(): ReadableStream<Uint8Array>;
43
+
44
+ /**
45
+ * The blob content as a ReadableStream
46
+ * Non-standard property that matches Request/Response API
47
+ */
48
+ body: ReadableStream<Uint8Array>;
49
+
50
+ /**
51
+ * Indicates whether the blob body has been consumed
52
+ * Non-standard property that matches Request/Response API
53
+ */
54
+ bodyUsed: boolean;
55
+ }
56
+
57
+ export {};