fetch-xhr-shim 0.0.1-beta

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 (51) hide show
  1. package/dist/cjs/dev.js +55 -0
  2. package/dist/cjs/encoding/TextDecoderP.js +179 -0
  3. package/dist/cjs/encoding/TextEncoderP.js +121 -0
  4. package/dist/cjs/event-system/AbortControllerP.js +28 -0
  5. package/dist/cjs/event-system/AbortSignalP.js +117 -0
  6. package/dist/cjs/event-system/CustomEventP.js +35 -0
  7. package/dist/cjs/event-system/EventP.js +125 -0
  8. package/dist/cjs/event-system/EventTargetP.js +181 -0
  9. package/dist/cjs/event-system/ProgressEventP.js +54 -0
  10. package/dist/cjs/fetch-api/BodyImpl.js +176 -0
  11. package/dist/cjs/fetch-api/HeadersP.js +184 -0
  12. package/dist/cjs/fetch-api/RequestP.js +188 -0
  13. package/dist/cjs/fetch-api/ResponseP.js +93 -0
  14. package/dist/cjs/fetch-api/fetchP.js +129 -0
  15. package/dist/cjs/file-system/BlobP.js +171 -0
  16. package/dist/cjs/file-system/FileP.js +53 -0
  17. package/dist/cjs/file-system/FileReaderP.js +201 -0
  18. package/dist/cjs/fixes.js +243 -0
  19. package/dist/cjs/index.js +59 -0
  20. package/dist/cjs/network/FormDataP.js +308 -0
  21. package/dist/cjs/network/URLSearchParamsP.js +235 -0
  22. package/dist/cjs/polyfill.js +87 -0
  23. package/dist/cjs/utils.js +70 -0
  24. package/dist/dev.d.ts +145 -0
  25. package/dist/esm/dev.js +13 -0
  26. package/dist/esm/encoding/TextDecoderP.js +175 -0
  27. package/dist/esm/encoding/TextEncoderP.js +118 -0
  28. package/dist/esm/event-system/AbortControllerP.js +25 -0
  29. package/dist/esm/event-system/AbortSignalP.js +112 -0
  30. package/dist/esm/event-system/CustomEventP.js +32 -0
  31. package/dist/esm/event-system/EventP.js +121 -0
  32. package/dist/esm/event-system/EventTargetP.js +174 -0
  33. package/dist/esm/event-system/ProgressEventP.js +51 -0
  34. package/dist/esm/fetch-api/BodyImpl.js +172 -0
  35. package/dist/esm/fetch-api/HeadersP.js +176 -0
  36. package/dist/esm/fetch-api/RequestP.js +184 -0
  37. package/dist/esm/fetch-api/ResponseP.js +90 -0
  38. package/dist/esm/fetch-api/fetchP.js +125 -0
  39. package/dist/esm/file-system/BlobP.js +164 -0
  40. package/dist/esm/file-system/FileP.js +50 -0
  41. package/dist/esm/file-system/FileReaderP.js +197 -0
  42. package/dist/esm/fixes.js +239 -0
  43. package/dist/esm/index.js +17 -0
  44. package/dist/esm/network/FormDataP.js +301 -0
  45. package/dist/esm/network/URLSearchParamsP.js +231 -0
  46. package/dist/esm/polyfill.js +85 -0
  47. package/dist/esm/utils.js +60 -0
  48. package/dist/fetch-xhr-shim.cjs.min.js +1 -0
  49. package/dist/fetch-xhr-shim.esm.min.js +1 -0
  50. package/dist/index.d.ts +300 -0
  51. package/package.json +59 -0
@@ -0,0 +1,197 @@
1
+ import { isBlob } from './BlobP.js';
2
+ import { setState, _Symbol, DOMException as DOMExceptionE, checkArgsLength } from '../utils.js';
3
+ import { emitProgressEvent } from '../event-system/ProgressEventP.js';
4
+ import { EventTargetP, attachFn, executeFn } from '../event-system/EventTargetP.js';
5
+
6
+ class FileReaderP extends EventTargetP {
7
+ static get EMPTY() { return 0; }
8
+ static get LOADING() { return 1; }
9
+ static get DONE() { return 2; }
10
+ constructor() {
11
+ super();
12
+ setState(this, "__FileReader__", new FileReaderState(this));
13
+ }
14
+ get EMPTY() { return 0; }
15
+ get LOADING() { return 1; }
16
+ get DONE() { return 2; }
17
+ get error() { return state(this).error; }
18
+ get readyState() { return state(this).readyState; }
19
+ get result() { return state(this).result; }
20
+ abort() {
21
+ if (state(this).pos === 2 /* FRCycle.LOADING */)
22
+ execAbort(this);
23
+ }
24
+ readAsArrayBuffer(blob) {
25
+ check(this, "readAsArrayBuffer", arguments.length, blob);
26
+ read(this, blob.size, () => blob.arrayBuffer());
27
+ }
28
+ readAsBinaryString(blob) {
29
+ check(this, "readAsBinaryString", arguments.length, blob);
30
+ read(this, blob.size, () => blob.arrayBuffer().then(res => {
31
+ let str = [];
32
+ let buf = new Uint8Array(res);
33
+ for (let i = 0; i < buf.length; ++i) {
34
+ str.push(String.fromCharCode(buf[i]));
35
+ }
36
+ return str.join("");
37
+ }));
38
+ }
39
+ readAsDataURL(blob) {
40
+ check(this, "readAsDataURL", arguments.length, blob);
41
+ read(this, blob.size, () => blob.arrayBuffer().then(res => {
42
+ return "data:" + (blob.type || "application/octet-stream") + ";base64," + Uint8Array_toBase64(new Uint8Array(res));
43
+ }));
44
+ }
45
+ readAsText(blob, encoding) {
46
+ check(this, "readAsText", arguments.length, blob);
47
+ if (typeof TextDecoder === "function") {
48
+ let decoder = new TextDecoder(encoding);
49
+ read(this, blob.size, () => blob.arrayBuffer().then(r => decoder.decode(r)));
50
+ }
51
+ else {
52
+ if (encoding !== undefined) {
53
+ let _encoding = "" + encoding;
54
+ if (["utf-8", "utf8", "unicode-1-1-utf-8"].indexOf(_encoding.toLowerCase()) === -1) {
55
+ console.warn(`Ignoring the execution of 'readAsText' on 'FileReader': encoding ('${_encoding}') not implemented.`);
56
+ }
57
+ }
58
+ read(this, blob.size, () => blob.text());
59
+ }
60
+ }
61
+ get onabort() { return state(this).onabort; }
62
+ set onabort(value) { state(this).onabort = value; state(this).attach("abort"); }
63
+ get onerror() { return state(this).onerror; }
64
+ set onerror(value) { state(this).onerror = value; state(this).attach("error"); }
65
+ get onload() { return state(this).onload; }
66
+ set onload(value) { state(this).onload = value; state(this).attach("load"); }
67
+ get onloadend() { return state(this).onloadend; }
68
+ set onloadend(value) { state(this).onloadend = value; state(this).attach("loadend"); }
69
+ get onloadstart() { return state(this).onloadstart; }
70
+ set onloadstart(value) { state(this).onloadstart = value; state(this).attach("loadstart"); }
71
+ get onprogress() { return state(this).onprogress; }
72
+ set onprogress(value) { state(this).onprogress = value; state(this).attach("progress"); }
73
+ /** @internal */ toString() { return "[object FileReader]"; }
74
+ /** @internal */ get [_Symbol.toStringTag]() { return "FileReader"; }
75
+ /** @internal */ get __MPHTTPX__() { return { chain: ["FileReader", "EventTarget"] }; }
76
+ }
77
+ /** @internal */
78
+ class FileReaderState {
79
+ constructor(target) {
80
+ this.pos = 0 /* FRCycle.EMPTY */;
81
+ this.readyState = 0 /* EMPTY */;
82
+ this.result = null;
83
+ this.error = null;
84
+ this.onabort = null;
85
+ this.onerror = null;
86
+ this.onload = null;
87
+ this.onloadend = null;
88
+ this.onloadstart = null;
89
+ this.onprogress = null;
90
+ this.attach = attachFn(target, getHandlers(target));
91
+ }
92
+ }
93
+ function getHandlers(t) {
94
+ return {
95
+ onabort: (ev) => { executeFn(t, t.onabort, ev); },
96
+ onerror: (ev) => { executeFn(t, t.onerror, ev); },
97
+ onload: (ev) => { executeFn(t, t.onload, ev); },
98
+ onloadend: (ev) => { executeFn(t, t.onloadend, ev); },
99
+ onloadstart: (ev) => { executeFn(t, t.onloadstart, ev); },
100
+ onprogress: (ev) => { executeFn(t, t.onprogress, ev); },
101
+ };
102
+ }
103
+ function state(target) {
104
+ return target.__FileReader__;
105
+ }
106
+ function check(reader, kind, actual, blob) {
107
+ checkArgsLength(actual, 1, "FileReader", kind);
108
+ if (!isBlob(blob))
109
+ throw new TypeError("Failed to execute '" + kind + "' on 'FileReader': parameter 1 is not of type 'Blob'.");
110
+ if (reader.readyState === 1 /* LOADING */)
111
+ throw new DOMExceptionE(`Failed to execute '${kind}' on 'FileReader': The object is already busy reading Blobs.`, "InvalidStateError");
112
+ }
113
+ function read(reader, size, launch) {
114
+ execLoadstart(reader, size, launch);
115
+ }
116
+ function execLoadstart(reader, size, launch) {
117
+ let s = state(reader);
118
+ s.pos = 1 /* FRCycle.LOADSTART */;
119
+ s.error = null;
120
+ s.result = null;
121
+ const callback = () => { emitProgressEvent(reader, "loadstart", 0, size); return launch(); };
122
+ return execLoading(reader, size, callback);
123
+ }
124
+ function execLoading(reader, size, launch) {
125
+ let s = state(reader);
126
+ s.pos = 2 /* FRCycle.LOADING */;
127
+ s.readyState = 1 /* LOADING */;
128
+ return Promise.resolve().then(() => {
129
+ if (s.pos !== 2 /* FRCycle.LOADING */)
130
+ return;
131
+ return launch().then(r => execDone(reader, size, r)).catch(err => execError(reader, err));
132
+ });
133
+ }
134
+ function execDone(reader, size, result) {
135
+ let s = state(reader);
136
+ if (s.pos !== 2 /* FRCycle.LOADING */)
137
+ return;
138
+ s.pos = 3 /* FRCycle.DONE */;
139
+ s.result = result;
140
+ s.readyState = 2; /* DONE */
141
+ execLoad(reader, size);
142
+ }
143
+ function execLoad(reader, size) {
144
+ state(reader).pos = 4 /* FRCycle.LOAD */;
145
+ emitProgressEvent(reader, "load", size, size);
146
+ execLoadend(reader, size);
147
+ }
148
+ function execAbort(reader) {
149
+ let s = state(reader);
150
+ s.pos = 5 /* FRCycle.ABORT */;
151
+ s.error = new DOMExceptionE("An ongoing operation was aborted, typically with a call to abort().", "AbortError");
152
+ s.result = null;
153
+ s.readyState = 2 /* DONE */;
154
+ emitProgressEvent(reader, "abort");
155
+ execLoadend(reader);
156
+ }
157
+ function execError(reader, err) {
158
+ let s = state(reader);
159
+ if (s.pos !== 2 /* FRCycle.LOADING */)
160
+ return;
161
+ s.pos = 6 /* FRCycle.ERROR */;
162
+ s.error = err;
163
+ s.result = null;
164
+ s.readyState = 2 /* DONE */;
165
+ emitProgressEvent(reader, "error");
166
+ execLoadend(reader);
167
+ }
168
+ function execLoadend(reader, size = 0) {
169
+ state(reader).pos = 7 /* FRCycle.LOADEND */;
170
+ emitProgressEvent(reader, "loadend", size, size);
171
+ }
172
+ function Uint8Array_toBase64(input) {
173
+ let byteToCharMap = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=";
174
+ let output = [];
175
+ for (var i = 0; i < input.length; i += 3) {
176
+ let byte1 = input[i];
177
+ let haveByte2 = i + 1 < input.length;
178
+ let byte2 = haveByte2 ? input[i + 1] : 0;
179
+ let haveByte3 = i + 2 < input.length;
180
+ let byte3 = haveByte3 ? input[i + 2] : 0;
181
+ let outByte1 = byte1 >> 2;
182
+ let outByte2 = ((byte1 & 0x03) << 4) | (byte2 >> 4);
183
+ let outByte3 = ((byte2 & 0x0F) << 2) | (byte3 >> 6);
184
+ let outByte4 = byte3 & 0x3F;
185
+ if (!haveByte3) {
186
+ outByte4 = 64;
187
+ if (!haveByte2) {
188
+ outByte3 = 64;
189
+ }
190
+ }
191
+ output.push(byteToCharMap[outByte1], byteToCharMap[outByte2], byteToCharMap[outByte3], byteToCharMap[outByte4]);
192
+ }
193
+ return output.join("");
194
+ }
195
+ const FileReaderE = (typeof FileReader !== "undefined" && FileReader) || FileReaderP;
196
+
197
+ export { FileReaderE as FileReader, FileReaderP, Uint8Array_toBase64 };
@@ -0,0 +1,239 @@
1
+ import { fetchP } from './fetch-api/fetchP.js';
2
+ import { Payload } from './fetch-api/BodyImpl.js';
3
+ import { FormData_toBlob } from './network/FormDataP.js';
4
+ import { isEventTarget } from './event-system/EventTargetP.js';
5
+ import { isPolyfillType, DOMException as DOMExceptionE, setState, isSequence } from './utils.js';
6
+
7
+ function fixFetch(fetchFunc) {
8
+ const fetchFn = fetchFunc || (typeof fetch !== "undefined" && fetch);
9
+ if (!fetchFn || fetchFn === fetchP)
10
+ return fetchP;
11
+ if ("__MPHTTPX__Polyfill__" in fetchFn)
12
+ return fetchFn;
13
+ function isHeadersLike(value) {
14
+ return !!value
15
+ && typeof value === "object"
16
+ && "has" in value
17
+ && typeof value.has === "function"
18
+ && "set" in value
19
+ && typeof value.set === "function";
20
+ }
21
+ function setContentType(init, contentType) {
22
+ if (init.headers) {
23
+ if (isHeadersLike(init.headers)) {
24
+ if (!init.headers.has("Content-Type")) {
25
+ init.headers.set("Content-Type", contentType);
26
+ }
27
+ }
28
+ else if (isSequence(init.headers)) {
29
+ let hasContentType = false;
30
+ let _headers = Array.isArray(init.headers) ? init.headers : Array.from(init.headers);
31
+ for (let i = 0; i < _headers.length; ++i) {
32
+ let header = _headers[i];
33
+ if (isSequence(header)) {
34
+ let pair = Array.isArray(header) ? header : Array.from(header);
35
+ if (pair.length >= 2 && String(pair[0]).toLowerCase() === "content-type") {
36
+ hasContentType = true;
37
+ break;
38
+ }
39
+ }
40
+ }
41
+ if (!hasContentType) {
42
+ _headers.push(["Content-Type", contentType]);
43
+ init.headers = _headers;
44
+ }
45
+ }
46
+ else {
47
+ if (typeof init.headers === "object") {
48
+ let hasContentType = false;
49
+ let names = Object.getOwnPropertyNames(init.headers);
50
+ for (let i = 0; i < names.length; ++i) {
51
+ let name = names[i];
52
+ if (name.toLowerCase() === "content-type") {
53
+ hasContentType = true;
54
+ break;
55
+ }
56
+ }
57
+ if (!hasContentType) {
58
+ init.headers["Content-Type"] = contentType;
59
+ }
60
+ }
61
+ }
62
+ }
63
+ else {
64
+ init.headers = { "Content-Type": contentType };
65
+ }
66
+ }
67
+ function _fetch(input, init) {
68
+ if (isPolyfillType("Request", input)) {
69
+ return fetchP(input, init);
70
+ }
71
+ if (init && init.headers && isPolyfillType("Headers", init.headers)) {
72
+ if (typeof Headers !== "undefined" && Headers && !("__MPHTTPX__" in Headers.prototype)) {
73
+ let headers = new Headers();
74
+ init.headers.forEach((value, name) => { headers.append(name, value); });
75
+ init.headers = headers;
76
+ }
77
+ else {
78
+ let headers = {};
79
+ init.headers.forEach((value, name) => { headers[name] = value; });
80
+ init.headers = headers;
81
+ }
82
+ }
83
+ return new Promise((resolve, reject) => {
84
+ if (init && init.body && isPolyfillType("FormData", init.body)) {
85
+ init.body = FormData_toBlob(init.body);
86
+ }
87
+ if (init && init.body && isPolyfillType("Blob", init.body)) {
88
+ let payload = new Payload(init.body);
89
+ if (payload.type) {
90
+ setContentType(init, payload.type);
91
+ }
92
+ let removeFn = null;
93
+ let aborted = false;
94
+ let processing = true;
95
+ if (input && typeof input === "object" && "signal" in input && isEventTarget(input.signal)) {
96
+ let abortFn = () => { if (processing) {
97
+ aborted = true;
98
+ } removeFn(); };
99
+ removeFn = () => { input.signal.removeEventListener("abort", abortFn); };
100
+ input.signal.addEventListener("abort", abortFn);
101
+ }
102
+ payload.promise.then(r => {
103
+ init.body = r !== "" ? r : null;
104
+ if (!aborted) {
105
+ resolve(fetchFn(input, init));
106
+ }
107
+ else {
108
+ reject(new DOMExceptionE("The user aborted a request.", "AbortError"));
109
+ }
110
+ processing = false;
111
+ })
112
+ .catch((e) => {
113
+ reject(new TypeError("Failed to fetch"));
114
+ console.error(e);
115
+ processing = false;
116
+ })
117
+ .then(() => { if (removeFn) {
118
+ removeFn();
119
+ } }); // finally
120
+ }
121
+ else {
122
+ if (init && init.body && isPolyfillType("URLSearchParams", init.body)) {
123
+ setContentType(init, "application/x-www-form-urlencoded;charset=UTF-8");
124
+ }
125
+ resolve(fetchFn(input, init));
126
+ }
127
+ });
128
+ }
129
+ _fetch["__MPHTTPX__Polyfill__"] = true;
130
+ return _fetch;
131
+ }
132
+ function fixXMLHttpRequest(XHRClass) {
133
+ const Klass = XHRClass || (typeof XMLHttpRequest !== "undefined" && XMLHttpRequest);
134
+ if (!Klass || "__MPHTTPX__Polyfill__" in Klass || "__MPHTTPX__" in Klass.prototype)
135
+ return;
136
+ const _abort = Klass.prototype.abort;
137
+ const _open = Klass.prototype.open;
138
+ const _send = Klass.prototype.send;
139
+ const _setRequestHeader = Klass.prototype.setRequestHeader;
140
+ Klass.prototype.abort = function () {
141
+ if (state(this).processing) {
142
+ state(this).aborted = true;
143
+ }
144
+ _abort.call(this);
145
+ state(this).hasContentType = false;
146
+ };
147
+ Klass.prototype.open = function (method, url, async = true, username = null, password = null) {
148
+ if (state(this).processing) {
149
+ state(this).aborted = true;
150
+ }
151
+ _open.call(this, method, url, async, username, password);
152
+ state(this).hasContentType = false;
153
+ };
154
+ Klass.prototype.send = function (body) {
155
+ if (isPolyfillType("FormData", body)) {
156
+ body = FormData_toBlob(body);
157
+ if (!state(this).hasContentType) {
158
+ this.setRequestHeader("Content-Type", body.type);
159
+ }
160
+ }
161
+ if (isPolyfillType("Blob", body)) {
162
+ let payload = new Payload(body);
163
+ if (payload.type && !state(this).hasContentType) {
164
+ this.setRequestHeader("Content-Type", payload.type);
165
+ }
166
+ const withCredentials = this.withCredentials;
167
+ state(this).processing = true;
168
+ payload.promise.then((function (r) {
169
+ if (!state(this).aborted) {
170
+ if (withCredentials !== this.withCredentials) {
171
+ console.warn("Illegal to set the 'withCredentials' property on 'XMLHttpRequest': The value may only be set if the object's state is UNSENT or OPENED.");
172
+ this.withCredentials = withCredentials;
173
+ }
174
+ _send.call(this, r !== "" ? r : undefined);
175
+ }
176
+ state(this).aborted = false;
177
+ state(this).processing = false;
178
+ }).bind(this))
179
+ .catch((function (e) {
180
+ console.error(e);
181
+ state(this).aborted = false;
182
+ state(this).processing = false;
183
+ }).bind(this));
184
+ }
185
+ else {
186
+ if (isPolyfillType("URLSearchParams", body) && !state(this).hasContentType)
187
+ this.setRequestHeader("Content-Type", "application/x-www-form-urlencoded;charset=UTF-8");
188
+ _send.call(this, body);
189
+ }
190
+ };
191
+ Klass.prototype.setRequestHeader = function (name, value) {
192
+ if (state(this).processing) {
193
+ throw new DOMExceptionE("Failed to execute 'setRequestHeader' on 'XMLHttpRequest': The object's state must be OPENED.", "InvalidStateError");
194
+ }
195
+ _setRequestHeader.call(this, name, value);
196
+ if (String(name).toLowerCase() === "content-type")
197
+ state(this).hasContentType = true;
198
+ };
199
+ // @ts-ignore
200
+ Klass["__MPHTTPX__Polyfill__"] = true;
201
+ class XMLHttpRequestState {
202
+ constructor() {
203
+ this.aborted = false;
204
+ this.processing = false;
205
+ this.hasContentType = false;
206
+ }
207
+ }
208
+ function state(target) {
209
+ const prop = "__XMLHttpRequest_Polyfill__";
210
+ // @ts-ignore
211
+ if (!(prop in target)) {
212
+ setState(target, prop, new XMLHttpRequestState());
213
+ }
214
+ return target[prop];
215
+ }
216
+ }
217
+ function fixWebSocket(WSClass) {
218
+ const Klass = WSClass || (typeof WebSocket !== "undefined" && WebSocket);
219
+ if (!Klass || "__MPHTTPX__Polyfill__" in Klass || "__MPHTTPX__" in Klass.prototype)
220
+ return;
221
+ const _send = Klass.prototype.send;
222
+ Klass.prototype.send = function (data) {
223
+ if (isPolyfillType("Blob", data)) {
224
+ let payload = new Payload(data);
225
+ payload.promise.then(r => {
226
+ if (this.readyState !== 1 /* OPEN */)
227
+ return;
228
+ _send.call(this, r);
229
+ });
230
+ }
231
+ else {
232
+ _send.call(this, data);
233
+ }
234
+ };
235
+ // @ts-ignore
236
+ Klass["__MPHTTPX__Polyfill__"] = true;
237
+ }
238
+
239
+ export { fixFetch, fixWebSocket, fixXMLHttpRequest };
@@ -0,0 +1,17 @@
1
+ export { TextEncoder, TextEncoderP } from './encoding/TextEncoderP.js';
2
+ export { TextDecoder, TextDecoderP } from './encoding/TextDecoderP.js';
3
+ export { EventTarget, EventTargetP } from './event-system/EventTargetP.js';
4
+ export { Event, EventP } from './event-system/EventP.js';
5
+ export { CustomEvent, CustomEventP } from './event-system/CustomEventP.js';
6
+ export { AbortController, AbortControllerP } from './event-system/AbortControllerP.js';
7
+ export { AbortSignal, AbortSignalP } from './event-system/AbortSignalP.js';
8
+ export { Blob, BlobP, setReadableStreamClass } from './file-system/BlobP.js';
9
+ export { File, FileP } from './file-system/FileP.js';
10
+ export { FileReader, FileReaderP } from './file-system/FileReaderP.js';
11
+ export { URLSearchParams, URLSearchParamsP } from './network/URLSearchParamsP.js';
12
+ export { FormData, FormDataP } from './network/FormDataP.js';
13
+ export { fetch, fetchP, setXMLHttpRequestClass } from './fetch-api/fetchP.js';
14
+ export { Headers, HeadersP } from './fetch-api/HeadersP.js';
15
+ export { Request, RequestP } from './fetch-api/RequestP.js';
16
+ export { Response, ResponseP } from './fetch-api/ResponseP.js';
17
+ export { fixFetch, fixWebSocket, fixXMLHttpRequest } from './fixes.js';