@heyputer/puter.js 2.1.6 → 2.1.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.
- package/dist/puter.cjs +2 -2
- package/index.d.ts +103 -626
- package/package.json +1 -1
- package/src/index.js +91 -91
- package/src/lib/APICallLogger.js +20 -21
- package/src/lib/EventListener.js +10 -10
- package/src/lib/filesystem/APIFS.js +11 -19
- package/src/lib/filesystem/CacheFS.js +25 -25
- package/src/lib/filesystem/PostMessageFS.js +11 -11
- package/src/lib/filesystem/definitions.js +11 -10
- package/src/lib/path.js +505 -446
- package/src/lib/polyfills/fileReaderPoly.js +40 -0
- package/src/lib/polyfills/localStorage.js +30 -33
- package/src/lib/polyfills/xhrshim.js +206 -207
- package/src/lib/utils.js +160 -151
- package/src/lib/xdrpc.js +9 -9
- package/src/modules/AI.js +416 -290
- package/src/modules/Apps.js +56 -56
- package/src/modules/Auth.js +17 -17
- package/src/modules/Debug.js +1 -1
- package/src/modules/Drivers.js +41 -41
- package/src/modules/FSItem.js +64 -62
- package/src/modules/FileSystem/index.js +22 -23
- package/src/modules/FileSystem/operations/copy.js +7 -7
- package/src/modules/FileSystem/operations/deleteFSEntry.js +14 -12
- package/src/modules/FileSystem/operations/getReadUrl.js +16 -14
- package/src/modules/FileSystem/operations/mkdir.js +11 -11
- package/src/modules/FileSystem/operations/move.js +12 -12
- package/src/modules/FileSystem/operations/read.js +10 -10
- package/src/modules/FileSystem/operations/readdir.js +28 -28
- package/src/modules/FileSystem/operations/rename.js +11 -11
- package/src/modules/FileSystem/operations/sign.js +33 -30
- package/src/modules/FileSystem/operations/space.js +7 -7
- package/src/modules/FileSystem/operations/stat.js +25 -25
- package/src/modules/FileSystem/operations/symlink.js +15 -17
- package/src/modules/FileSystem/operations/upload.js +151 -122
- package/src/modules/FileSystem/operations/write.js +16 -12
- package/src/modules/FileSystem/utils/getAbsolutePathForApp.js +10 -6
- package/src/modules/Hosting.js +29 -29
- package/src/modules/KV.js +23 -23
- package/src/modules/OS.js +15 -15
- package/src/modules/Perms.js +19 -21
- package/src/modules/PuterDialog.js +46 -48
- package/src/modules/Threads.js +17 -20
- package/src/modules/UI.js +156 -156
- package/src/modules/Util.js +3 -3
- package/src/modules/Workers.js +52 -49
- package/src/modules/networking/PSocket.js +38 -38
- package/src/modules/networking/PTLS.js +54 -47
- package/src/modules/networking/PWispHandler.js +49 -47
- package/src/modules/networking/parsers.js +110 -108
- package/src/modules/networking/requests.js +67 -78
- package/src/services/APIAccess.js +9 -9
- package/src/services/FSRelay.js +6 -6
- package/src/services/Filesystem.js +8 -8
- package/src/services/NoPuterYet.js +2 -2
- package/src/services/XDIncoming.js +1 -1
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
function toBase64FromBuffer(buffer) {
|
|
2
|
+
const bytes = new Uint8Array(buffer);
|
|
3
|
+
// use the requested reduce logic
|
|
4
|
+
const binary = bytes.reduce((data, byte) => data + String.fromCharCode(byte), '');
|
|
5
|
+
return typeof btoa === 'function' ? btoa(binary) : Buffer.from(binary, 'binary').toString('base64');
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
export class FileReaderPoly {
|
|
9
|
+
constructor() {
|
|
10
|
+
this.result = null;
|
|
11
|
+
this.error = null;
|
|
12
|
+
this.onloadend = null;
|
|
13
|
+
}
|
|
14
|
+
readAsDataURL(blob) {
|
|
15
|
+
const self = this;
|
|
16
|
+
(async function () {
|
|
17
|
+
try {
|
|
18
|
+
let buffer;
|
|
19
|
+
if (blob && typeof blob.arrayBuffer === 'function') {
|
|
20
|
+
buffer = await blob.arrayBuffer();
|
|
21
|
+
} else if (blob instanceof ArrayBuffer) {
|
|
22
|
+
buffer = blob;
|
|
23
|
+
} else if (ArrayBuffer.isView(blob)) {
|
|
24
|
+
buffer = blob.buffer;
|
|
25
|
+
} else {
|
|
26
|
+
buffer = new Uint8Array(0).buffer;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
const base64 = toBase64FromBuffer(buffer);
|
|
30
|
+
const mime = (blob && blob.type) || 'application/octet-stream';
|
|
31
|
+
self.result = 'data:' + mime + ';base64,' + base64;
|
|
32
|
+
if (typeof self.onloadend === 'function') self.onloadend();
|
|
33
|
+
} catch (err) {
|
|
34
|
+
self.error = err;
|
|
35
|
+
if (typeof self.onloadend === 'function') self.onloadend();
|
|
36
|
+
}
|
|
37
|
+
})();
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
|
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
// https://github.com/gr2m/localstorage-memory under MIT
|
|
2
2
|
|
|
3
3
|
const root = {};
|
|
4
|
-
var localStorageMemory = {}
|
|
5
|
-
var cache = {}
|
|
4
|
+
var localStorageMemory = {};
|
|
5
|
+
var cache = {};
|
|
6
6
|
|
|
7
7
|
/**
|
|
8
8
|
* number of stored items.
|
|
9
9
|
*/
|
|
10
|
-
localStorageMemory.length = 0
|
|
10
|
+
localStorageMemory.length = 0;
|
|
11
11
|
|
|
12
12
|
/**
|
|
13
13
|
* returns item for passed key, or null
|
|
@@ -17,12 +17,12 @@ localStorageMemory.length = 0
|
|
|
17
17
|
* @returns {String|null}
|
|
18
18
|
*/
|
|
19
19
|
localStorageMemory.getItem = function (key) {
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
20
|
+
if ( key in cache ) {
|
|
21
|
+
return cache[key];
|
|
22
|
+
}
|
|
23
23
|
|
|
24
|
-
|
|
25
|
-
}
|
|
24
|
+
return null;
|
|
25
|
+
};
|
|
26
26
|
|
|
27
27
|
/**
|
|
28
28
|
* sets item for key to passed value, as String
|
|
@@ -34,16 +34,16 @@ localStorageMemory.getItem = function (key) {
|
|
|
34
34
|
* @returns {undefined}
|
|
35
35
|
*/
|
|
36
36
|
localStorageMemory.setItem = function (key, value) {
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
37
|
+
if ( typeof value === 'undefined' ) {
|
|
38
|
+
localStorageMemory.removeItem(key);
|
|
39
|
+
} else {
|
|
40
|
+
if ( ! (cache.hasOwnProperty(key)) ) {
|
|
41
|
+
localStorageMemory.length++;
|
|
42
|
+
}
|
|
43
43
|
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
}
|
|
44
|
+
cache[key] = `${ value}`;
|
|
45
|
+
}
|
|
46
|
+
};
|
|
47
47
|
|
|
48
48
|
/**
|
|
49
49
|
* removes item for passed key
|
|
@@ -53,11 +53,11 @@ localStorageMemory.setItem = function (key, value) {
|
|
|
53
53
|
* @returns {undefined}
|
|
54
54
|
*/
|
|
55
55
|
localStorageMemory.removeItem = function (key) {
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
}
|
|
56
|
+
if ( cache.hasOwnProperty(key) ) {
|
|
57
|
+
delete cache[key];
|
|
58
|
+
localStorageMemory.length--;
|
|
59
|
+
}
|
|
60
|
+
};
|
|
61
61
|
|
|
62
62
|
/**
|
|
63
63
|
* returns name of key at passed index
|
|
@@ -67,8 +67,8 @@ localStorageMemory.removeItem = function (key) {
|
|
|
67
67
|
* @returns {String|null}
|
|
68
68
|
*/
|
|
69
69
|
localStorageMemory.key = function (index) {
|
|
70
|
-
|
|
71
|
-
}
|
|
70
|
+
return Object.keys(cache)[index] || null;
|
|
71
|
+
};
|
|
72
72
|
|
|
73
73
|
/**
|
|
74
74
|
* removes all stored items and sets length to 0
|
|
@@ -76,17 +76,14 @@ localStorageMemory.key = function (index) {
|
|
|
76
76
|
* @returns {undefined}
|
|
77
77
|
*/
|
|
78
78
|
localStorageMemory.clear = function () {
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
}
|
|
79
|
+
cache = {};
|
|
80
|
+
localStorageMemory.length = 0;
|
|
81
|
+
};
|
|
82
82
|
|
|
83
|
-
if (typeof exports === 'object') {
|
|
84
|
-
|
|
83
|
+
if ( typeof exports === 'object' ) {
|
|
84
|
+
module.exports = localStorageMemory;
|
|
85
85
|
} else {
|
|
86
|
-
|
|
86
|
+
root.localStorage = localStorageMemory;
|
|
87
87
|
}
|
|
88
88
|
|
|
89
|
-
|
|
90
89
|
export default localStorageMemory;
|
|
91
|
-
|
|
92
|
-
|
|
@@ -3,30 +3,30 @@
|
|
|
3
3
|
/* global module */
|
|
4
4
|
/* global EventTarget, AbortController, DOMException */
|
|
5
5
|
|
|
6
|
-
const sReadyState = Symbol(
|
|
7
|
-
const sHeaders = Symbol(
|
|
8
|
-
const sRespHeaders = Symbol(
|
|
9
|
-
const sAbortController = Symbol(
|
|
10
|
-
const sMethod = Symbol(
|
|
11
|
-
const sURL = Symbol(
|
|
12
|
-
const sMIME = Symbol(
|
|
13
|
-
const sDispatch = Symbol(
|
|
14
|
-
const sErrored = Symbol(
|
|
15
|
-
const sTimeout = Symbol(
|
|
16
|
-
const sTimedOut = Symbol(
|
|
17
|
-
const sIsResponseText = Symbol(
|
|
6
|
+
const sReadyState = Symbol('readyState');
|
|
7
|
+
const sHeaders = Symbol('headers');
|
|
8
|
+
const sRespHeaders = Symbol('response headers');
|
|
9
|
+
const sAbortController = Symbol('AbortController');
|
|
10
|
+
const sMethod = Symbol('method');
|
|
11
|
+
const sURL = Symbol('URL');
|
|
12
|
+
const sMIME = Symbol('MIME');
|
|
13
|
+
const sDispatch = Symbol('dispatch');
|
|
14
|
+
const sErrored = Symbol('errored');
|
|
15
|
+
const sTimeout = Symbol('timeout');
|
|
16
|
+
const sTimedOut = Symbol('timedOut');
|
|
17
|
+
const sIsResponseText = Symbol('isResponseText');
|
|
18
18
|
|
|
19
19
|
// SO: https://stackoverflow.com/questions/49129643/how-do-i-merge-an-array-of-uint8arrays
|
|
20
|
-
function mergeUint8Arrays(...arrays) {
|
|
21
|
-
|
|
22
|
-
|
|
20
|
+
function mergeUint8Arrays (...arrays) {
|
|
21
|
+
const totalSize = arrays.reduce((acc, e) => acc + e.length, 0);
|
|
22
|
+
const merged = new Uint8Array(totalSize);
|
|
23
23
|
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
24
|
+
arrays.forEach((array, i, arrays) => {
|
|
25
|
+
const offset = arrays.slice(0, i).reduce((acc, e) => acc + e.length, 0);
|
|
26
|
+
merged.set(array, offset);
|
|
27
|
+
});
|
|
28
28
|
|
|
29
|
-
|
|
29
|
+
return merged;
|
|
30
30
|
}
|
|
31
31
|
|
|
32
32
|
/**
|
|
@@ -34,200 +34,199 @@ function mergeUint8Arrays(...arrays) {
|
|
|
34
34
|
* @this {XMLHttpRequest}
|
|
35
35
|
* @param {Uint8Array} bytes
|
|
36
36
|
*/
|
|
37
|
-
async function parseBody(bytes) {
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
case
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
case
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
case
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
case
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
37
|
+
async function parseBody (bytes) {
|
|
38
|
+
const responseType = this.responseType || 'text';
|
|
39
|
+
const textde = new TextDecoder();
|
|
40
|
+
const finalMIME = this[sMIME] || this[sRespHeaders].get('content-type') || 'text/plain';
|
|
41
|
+
switch ( responseType ) {
|
|
42
|
+
case 'text':
|
|
43
|
+
this.response = textde.decode(bytes);
|
|
44
|
+
break;
|
|
45
|
+
case 'blob':
|
|
46
|
+
this.response = new Blob([bytes], { type: finalMIME });
|
|
47
|
+
break;
|
|
48
|
+
case 'arraybuffer':
|
|
49
|
+
this.response = bytes.buffer;
|
|
50
|
+
break;
|
|
51
|
+
case 'json':
|
|
52
|
+
this.response = JSON.parse(textde.decode(bytes));
|
|
53
|
+
break;
|
|
54
|
+
}
|
|
55
55
|
}
|
|
56
56
|
|
|
57
57
|
const XMLHttpRequestShim = class XMLHttpRequest extends EventTarget {
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
this[sAbortController].abort();
|
|
135
|
-
this.status = 0;
|
|
136
|
-
this.readyState = this.constructor.UNSENT;
|
|
137
|
-
}
|
|
138
|
-
open(method, url) {
|
|
139
|
-
this.status = 0;
|
|
140
|
-
this[sMethod] = method;
|
|
141
|
-
this[sURL] = url;
|
|
142
|
-
this.readyState = this.constructor.OPENED;
|
|
143
|
-
}
|
|
144
|
-
setRequestHeader(header, value) {
|
|
145
|
-
header = String(header).toLowerCase();
|
|
146
|
-
if (typeof this[sHeaders][header] === "undefined") {
|
|
147
|
-
this[sHeaders][header] = String(value);
|
|
148
|
-
} else {
|
|
149
|
-
this[sHeaders][header] += `, ${value}`;
|
|
150
|
-
}
|
|
151
|
-
}
|
|
152
|
-
overrideMimeType(mimeType) {
|
|
153
|
-
this[sMIME] = String(mimeType);
|
|
154
|
-
}
|
|
155
|
-
getAllResponseHeaders() {
|
|
156
|
-
if (this[sErrored] || this.readyState < this.constructor.HEADERS_RECEIVED) return "";
|
|
157
|
-
return Array.from(this[sRespHeaders].entries().map(([header, value]) => `${header}: ${value}`)).join("\r\n");
|
|
158
|
-
}
|
|
159
|
-
getResponseHeader(headerName) {
|
|
160
|
-
const value = this[sRespHeaders].get(String(headerName).toLowerCase());
|
|
161
|
-
return typeof value === "string" ? value : null;
|
|
162
|
-
}
|
|
163
|
-
send(body = null) {
|
|
164
|
-
if (this.timeout > 0) {
|
|
165
|
-
this[sTimeout] = setTimeout(() => {
|
|
166
|
-
this[sTimedOut] = true;
|
|
58
|
+
onreadystatechange () {
|
|
59
|
+
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
set readyState (value) {
|
|
63
|
+
if ( this[sReadyState] === value ) return; // dont do anything if "value" is already the internal value
|
|
64
|
+
this[sReadyState] = value;
|
|
65
|
+
this.dispatchEvent(new Event('readystatechange'));
|
|
66
|
+
this.onreadystatechange(new Event('readystatechange'));
|
|
67
|
+
|
|
68
|
+
}
|
|
69
|
+
get readyState () {
|
|
70
|
+
return this[sReadyState];
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
constructor () {
|
|
74
|
+
super();
|
|
75
|
+
this.readyState = this.constructor.UNSENT;
|
|
76
|
+
this.response = null;
|
|
77
|
+
this.responseType = '';
|
|
78
|
+
this.responseURL = '';
|
|
79
|
+
this.status = 0;
|
|
80
|
+
this.statusText = '';
|
|
81
|
+
this.timeout = 0;
|
|
82
|
+
this.withCredentials = false;
|
|
83
|
+
this[sHeaders] = Object.create(null);
|
|
84
|
+
this[sHeaders].accept = '*/*';
|
|
85
|
+
this[sRespHeaders] = Object.create(null);
|
|
86
|
+
this[sAbortController] = new AbortController();
|
|
87
|
+
this[sMethod] = '';
|
|
88
|
+
this[sURL] = '';
|
|
89
|
+
this[sMIME] = '';
|
|
90
|
+
this[sErrored] = false;
|
|
91
|
+
this[sTimeout] = 0;
|
|
92
|
+
this[sTimedOut] = false;
|
|
93
|
+
this[sIsResponseText] = true;
|
|
94
|
+
}
|
|
95
|
+
static get UNSENT () {
|
|
96
|
+
return 0;
|
|
97
|
+
}
|
|
98
|
+
static get OPENED () {
|
|
99
|
+
return 1;
|
|
100
|
+
}
|
|
101
|
+
static get HEADERS_RECEIVED () {
|
|
102
|
+
return 2;
|
|
103
|
+
}
|
|
104
|
+
static get LOADING () {
|
|
105
|
+
return 3;
|
|
106
|
+
}
|
|
107
|
+
static get DONE () {
|
|
108
|
+
return 4;
|
|
109
|
+
}
|
|
110
|
+
upload = {
|
|
111
|
+
addEventListener () {
|
|
112
|
+
// stub, doesn't do anything since its not possible to monitor with fetch and http/1.1
|
|
113
|
+
},
|
|
114
|
+
};
|
|
115
|
+
get responseText () {
|
|
116
|
+
if ( this[sErrored] ) return null;
|
|
117
|
+
if ( this.readyState < this.constructor.HEADERS_RECEIVED ) return '';
|
|
118
|
+
if ( this[sIsResponseText] ) return this.response;
|
|
119
|
+
throw new DOMException('Response type not set to text', 'InvalidStateError');
|
|
120
|
+
}
|
|
121
|
+
get responseXML () {
|
|
122
|
+
throw new Error('XML not supported');
|
|
123
|
+
}
|
|
124
|
+
[sDispatch] (evt) {
|
|
125
|
+
const attr = `on${evt.type}`;
|
|
126
|
+
if ( typeof this[attr] === 'function' ) {
|
|
127
|
+
this.addEventListener(evt.type, this[attr].bind(this), {
|
|
128
|
+
once: true,
|
|
129
|
+
});
|
|
130
|
+
}
|
|
131
|
+
this.dispatchEvent(evt);
|
|
132
|
+
}
|
|
133
|
+
abort () {
|
|
167
134
|
this[sAbortController].abort();
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
}).then(async resp => {
|
|
184
|
-
this.responseURL = resp.url;
|
|
185
|
-
this.status = resp.status;
|
|
186
|
-
this.statusText = resp.statusText;
|
|
187
|
-
this[sRespHeaders] = resp.headers;
|
|
188
|
-
this.readyState = this.constructor.HEADERS_RECEIVED;
|
|
189
|
-
|
|
190
|
-
if (resp.headers.get("content-type").includes("application/x-ndjson") || this.streamRequestBadForPerformance) {
|
|
191
|
-
let bytes = new Uint8Array();
|
|
192
|
-
for await (const chunk of resp.body) {
|
|
193
|
-
this.readyState = this.constructor.LOADING;
|
|
194
|
-
|
|
195
|
-
bytes = mergeUint8Arrays(bytes, chunk);
|
|
196
|
-
parseBody.call(this, bytes);
|
|
197
|
-
this[sDispatch](new CustomEvent("progress"));
|
|
135
|
+
this.status = 0;
|
|
136
|
+
this.readyState = this.constructor.UNSENT;
|
|
137
|
+
}
|
|
138
|
+
open (method, url) {
|
|
139
|
+
this.status = 0;
|
|
140
|
+
this[sMethod] = method;
|
|
141
|
+
this[sURL] = url;
|
|
142
|
+
this.readyState = this.constructor.OPENED;
|
|
143
|
+
}
|
|
144
|
+
setRequestHeader (header, value) {
|
|
145
|
+
header = String(header).toLowerCase();
|
|
146
|
+
if ( typeof this[sHeaders][header] === 'undefined' ) {
|
|
147
|
+
this[sHeaders][header] = String(value);
|
|
148
|
+
} else {
|
|
149
|
+
this[sHeaders][header] += `, ${value}`;
|
|
198
150
|
}
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
151
|
+
}
|
|
152
|
+
overrideMimeType (mimeType) {
|
|
153
|
+
this[sMIME] = String(mimeType);
|
|
154
|
+
}
|
|
155
|
+
getAllResponseHeaders () {
|
|
156
|
+
if ( this[sErrored] || this.readyState < this.constructor.HEADERS_RECEIVED ) return '';
|
|
157
|
+
return Array.from(this[sRespHeaders].entries().map(([header, value]) => `${header}: ${value}`)).join('\r\n');
|
|
158
|
+
}
|
|
159
|
+
getResponseHeader (headerName) {
|
|
160
|
+
const value = this[sRespHeaders].get(String(headerName).toLowerCase());
|
|
161
|
+
return typeof value === 'string' ? value : null;
|
|
162
|
+
}
|
|
163
|
+
send (body = null) {
|
|
164
|
+
if ( this.timeout > 0 ) {
|
|
165
|
+
this[sTimeout] = setTimeout(() => {
|
|
166
|
+
this[sTimedOut] = true;
|
|
167
|
+
this[sAbortController].abort();
|
|
168
|
+
}, this.timeout);
|
|
203
169
|
}
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
170
|
+
const responseType = this.responseType || 'text';
|
|
171
|
+
this[sIsResponseText] = responseType === 'text';
|
|
172
|
+
|
|
173
|
+
this.setRequestHeader('user-agent', 'puter-js/1.0');
|
|
174
|
+
this.setRequestHeader('origin', 'https://puter.work');
|
|
175
|
+
this.setRequestHeader('referer', 'https://puter.work/');
|
|
176
|
+
|
|
177
|
+
fetch(this[sURL], {
|
|
178
|
+
method: this[sMethod] || 'GET',
|
|
179
|
+
signal: this[sAbortController].signal,
|
|
180
|
+
headers: this[sHeaders],
|
|
181
|
+
credentials: this.withCredentials ? 'include' : 'same-origin',
|
|
182
|
+
body,
|
|
183
|
+
}).then(async resp => {
|
|
184
|
+
this.responseURL = resp.url;
|
|
185
|
+
this.status = resp.status;
|
|
186
|
+
this.statusText = resp.statusText;
|
|
187
|
+
this[sRespHeaders] = resp.headers;
|
|
188
|
+
this.readyState = this.constructor.HEADERS_RECEIVED;
|
|
189
|
+
|
|
190
|
+
if ( resp.headers.get('content-type').includes('application/x-ndjson') || this.streamRequestBadForPerformance ) {
|
|
191
|
+
let bytes = new Uint8Array();
|
|
192
|
+
for await ( const chunk of resp.body ) {
|
|
193
|
+
this.readyState = this.constructor.LOADING;
|
|
194
|
+
|
|
195
|
+
bytes = mergeUint8Arrays(bytes, chunk);
|
|
196
|
+
parseBody.call(this, bytes);
|
|
197
|
+
this[sDispatch](new CustomEvent('progress'));
|
|
198
|
+
}
|
|
199
|
+
} else {
|
|
200
|
+
const bytesChunks = [];
|
|
201
|
+
for await ( const chunk of resp.body ) {
|
|
202
|
+
bytesChunks.push(chunk);
|
|
203
|
+
}
|
|
204
|
+
parseBody.call(this, mergeUint8Arrays(...bytesChunks));
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
this.readyState = this.constructor.DONE;
|
|
208
|
+
this[sDispatch](new CustomEvent('load'));
|
|
209
|
+
}, err => {
|
|
210
|
+
let eventName = 'abort';
|
|
211
|
+
if ( err.name !== 'AbortError' ) {
|
|
212
|
+
this[sErrored] = true;
|
|
213
|
+
eventName = 'error';
|
|
214
|
+
} else if ( this[sTimedOut] ) {
|
|
215
|
+
eventName = 'timeout';
|
|
216
|
+
}
|
|
217
|
+
this.readyState = this.constructor.DONE;
|
|
218
|
+
this[sDispatch](new CustomEvent(eventName));
|
|
219
|
+
}).finally(() => this[sDispatch](new CustomEvent('loadend'))).finally(() => {
|
|
220
|
+
clearTimeout(this[sTimeout]);
|
|
221
|
+
this[sDispatch](new CustomEvent('loadstart'));
|
|
222
|
+
});
|
|
223
|
+
}
|
|
224
|
+
};
|
|
226
225
|
|
|
227
|
-
if (typeof module ===
|
|
228
|
-
|
|
226
|
+
if ( typeof module === 'object' && module.exports ) {
|
|
227
|
+
module.exports = XMLHttpRequestShim;
|
|
229
228
|
} else {
|
|
230
|
-
|
|
229
|
+
(globalThis || self).XMLHttpRequestShim = XMLHttpRequestShim;
|
|
231
230
|
}
|
|
232
231
|
|
|
233
|
-
export default XMLHttpRequestShim
|
|
232
|
+
export default XMLHttpRequestShim;
|