@heyputer/puter.js 2.0.13 → 2.0.14
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 +4 -0
- package/index.d.ts +23 -5
- package/package.json +6 -5
- package/src/index.js +3 -7
- package/src/modules/FileSystem/index.js +173 -10
- package/src/modules/FileSystem/operations/copy.js +0 -3
- package/src/modules/FileSystem/operations/mkdir.js +1 -4
- package/src/modules/FileSystem/operations/move.js +2 -6
- package/src/modules/FileSystem/operations/readdir.js +3 -7
- package/src/modules/FileSystem/operations/rename.js +1 -2
- package/src/modules/FileSystem/operations/stat.js +1 -5
- package/src/modules/FileSystem/operations/upload.js +1 -4
- package/src/modules/FileSystem/operations/write.js +1 -4
- package/src/modules/KV.js +53 -26
- package/src/modules/UI.js +30 -2
- package/src/modules/networking/PTLS.js +4 -0
- package/src/services/XDIncoming.js +1 -1
- package/dist/puter.js +0 -4
package/src/modules/KV.js
CHANGED
|
@@ -19,7 +19,7 @@ const gui_cache_keys = [
|
|
|
19
19
|
];
|
|
20
20
|
class KV{
|
|
21
21
|
MAX_KEY_SIZE = 1024;
|
|
22
|
-
MAX_VALUE_SIZE =
|
|
22
|
+
MAX_VALUE_SIZE = 399 * 1024;
|
|
23
23
|
|
|
24
24
|
/**
|
|
25
25
|
* Creates a new instance with the given authentication token, API origin, and app ID,
|
|
@@ -50,7 +50,7 @@ class KV{
|
|
|
50
50
|
args: {
|
|
51
51
|
key: gui_cache_keys,
|
|
52
52
|
},
|
|
53
|
-
auth_token: this.authToken
|
|
53
|
+
auth_token: this.authToken,
|
|
54
54
|
}),
|
|
55
55
|
});
|
|
56
56
|
const arr_values = await resp.json();
|
|
@@ -95,14 +95,25 @@ class KV{
|
|
|
95
95
|
}
|
|
96
96
|
|
|
97
97
|
/**
|
|
98
|
-
*
|
|
99
|
-
*
|
|
100
|
-
*
|
|
101
|
-
*
|
|
102
|
-
*
|
|
103
|
-
*
|
|
98
|
+
* @typedef {function(key: string, value: any, expireAt?: number): Promise<boolean>} SetFunction
|
|
99
|
+
* Resolves to 'true' on success, or rejects with an error on failure.
|
|
100
|
+
* @param {string} key - Cannot be undefined or null. Cannot be larger than 1KB.
|
|
101
|
+
* @param {any} value - Cannot be larger than 399KB.
|
|
102
|
+
* @param {number} [expireAt] - Optional expiration time for the key. Note that clients with a clock that is not in sync with the server may experience issues with this method.
|
|
103
|
+
* @memberof KV
|
|
104
104
|
*/
|
|
105
|
+
|
|
106
|
+
/** @type {SetFunction} */
|
|
105
107
|
set = utils.make_driver_method(['key', 'value', 'expireAt'], 'puter-kvstore', undefined, 'set', {
|
|
108
|
+
/**
|
|
109
|
+
*
|
|
110
|
+
* @param {object} args
|
|
111
|
+
* @param {string} args.key
|
|
112
|
+
* @param {any} args.value
|
|
113
|
+
* @param {number} [args.expireAt]
|
|
114
|
+
* @memberof [KV]
|
|
115
|
+
* @returns
|
|
116
|
+
*/
|
|
106
117
|
preprocess: (args) => {
|
|
107
118
|
// key cannot be undefined or null
|
|
108
119
|
if ( args.key === undefined || args.key === null ){
|
|
@@ -110,11 +121,11 @@ class KV{
|
|
|
110
121
|
}
|
|
111
122
|
// key size cannot be larger than MAX_KEY_SIZE
|
|
112
123
|
if ( args.key.length > this.MAX_KEY_SIZE ){
|
|
113
|
-
throw { message:
|
|
124
|
+
throw { message: `Key size cannot be larger than ${this.MAX_KEY_SIZE}`, code: 'key_too_large' };
|
|
114
125
|
}
|
|
115
126
|
// value size cannot be larger than MAX_VALUE_SIZE
|
|
116
127
|
if ( args.value && args.value.length > this.MAX_VALUE_SIZE ){
|
|
117
|
-
throw { message:
|
|
128
|
+
throw { message: `Value size cannot be larger than ${this.MAX_VALUE_SIZE}`, code: 'value_too_large' };
|
|
118
129
|
}
|
|
119
130
|
return args;
|
|
120
131
|
},
|
|
@@ -143,7 +154,7 @@ class KV{
|
|
|
143
154
|
preprocess: (args) => {
|
|
144
155
|
// key size cannot be larger than MAX_KEY_SIZE
|
|
145
156
|
if ( args.key.length > this.MAX_KEY_SIZE ){
|
|
146
|
-
throw ({ message:
|
|
157
|
+
throw ({ message: `Key size cannot be larger than ${this.MAX_KEY_SIZE}`, code: 'key_too_large' });
|
|
147
158
|
}
|
|
148
159
|
|
|
149
160
|
return args;
|
|
@@ -162,11 +173,11 @@ class KV{
|
|
|
162
173
|
}
|
|
163
174
|
|
|
164
175
|
options.key = args[0];
|
|
165
|
-
options.
|
|
176
|
+
options.pathAndAmountMap = !args[1] ? { '': 1 } : typeof args[1] === 'number' ? { '': args[1] } : args[1];
|
|
166
177
|
|
|
167
178
|
// key size cannot be larger than MAX_KEY_SIZE
|
|
168
179
|
if ( options.key.length > this.MAX_KEY_SIZE ){
|
|
169
|
-
throw ({ message:
|
|
180
|
+
throw ({ message: `Key size cannot be larger than ${this.MAX_KEY_SIZE}`, code: 'key_too_large' });
|
|
170
181
|
}
|
|
171
182
|
|
|
172
183
|
return utils.make_driver_method(['key'], 'puter-kvstore', undefined, 'incr').call(this, options);
|
|
@@ -181,37 +192,53 @@ class KV{
|
|
|
181
192
|
}
|
|
182
193
|
|
|
183
194
|
options.key = args[0];
|
|
184
|
-
options.
|
|
195
|
+
options.pathAndAmountMap = !args[1] ? { '': 1 } : typeof args[1] === 'number' ? { '': args[1] } : args[1];
|
|
185
196
|
|
|
186
197
|
// key size cannot be larger than MAX_KEY_SIZE
|
|
187
198
|
if ( options.key.length > this.MAX_KEY_SIZE ){
|
|
188
|
-
throw ({ message:
|
|
199
|
+
throw ({ message: `Key size cannot be larger than ${this.MAX_KEY_SIZE}`, code: 'key_too_large' });
|
|
189
200
|
}
|
|
190
201
|
|
|
191
202
|
return utils.make_driver_method(['key'], 'puter-kvstore', undefined, 'decr').call(this, options);
|
|
192
203
|
};
|
|
193
204
|
|
|
194
|
-
|
|
205
|
+
/**
|
|
206
|
+
* Set a time to live (in seconds) on a key. After the time to live has expired, the key will be deleted.
|
|
207
|
+
* Prefer this over expireAt if you want timestamp to be set by the server, to avoid issues with clock drift.
|
|
208
|
+
* @param {string} key - The key to set the expiration on.
|
|
209
|
+
* @param {number} ttl - The ttl
|
|
210
|
+
* @memberof [KV]
|
|
211
|
+
* @returns
|
|
212
|
+
*/
|
|
213
|
+
expire = async (key, ttl) => {
|
|
195
214
|
let options = {};
|
|
196
|
-
options.key =
|
|
197
|
-
options.ttl =
|
|
215
|
+
options.key = key;
|
|
216
|
+
options.ttl = ttl;
|
|
198
217
|
|
|
199
218
|
// key size cannot be larger than MAX_KEY_SIZE
|
|
200
219
|
if ( options.key.length > this.MAX_KEY_SIZE ){
|
|
201
|
-
throw ({ message:
|
|
220
|
+
throw ({ message: `Key size cannot be larger than ${this.MAX_KEY_SIZE}`, code: 'key_too_large' });
|
|
202
221
|
}
|
|
203
222
|
|
|
204
223
|
return utils.make_driver_method(['key', 'ttl'], 'puter-kvstore', undefined, 'expire').call(this, options);
|
|
205
224
|
};
|
|
206
225
|
|
|
207
|
-
|
|
226
|
+
/**
|
|
227
|
+
*
|
|
228
|
+
* Set the expiration for a key as a UNIX timestamp (in seconds). After the time has passed, the key will be deleted.
|
|
229
|
+
* Note that clients with a clock that is not in sync with the server may experience issues with this method.
|
|
230
|
+
* @param {string} key - The key to set the expiration on.
|
|
231
|
+
* @param {number} timestamp - The timestamp (in seconds since epoch) when the key will expire.
|
|
232
|
+
* @memberof [KV]
|
|
233
|
+
* @returns
|
|
234
|
+
*/
|
|
235
|
+
expireAt = async (key, timestamp) => {
|
|
208
236
|
let options = {};
|
|
209
|
-
options.key =
|
|
210
|
-
options.timestamp =
|
|
211
|
-
|
|
237
|
+
options.key = key;
|
|
238
|
+
options.timestamp = timestamp;
|
|
212
239
|
// key size cannot be larger than MAX_KEY_SIZE
|
|
213
240
|
if ( options.key.length > this.MAX_KEY_SIZE ){
|
|
214
|
-
throw ({ message:
|
|
241
|
+
throw ({ message: `Key size cannot be larger than ${this.MAX_KEY_SIZE}`, code: 'key_too_large' });
|
|
215
242
|
}
|
|
216
243
|
|
|
217
244
|
return utils.make_driver_method(['key', 'timestamp'], 'puter-kvstore', undefined, 'expireAt').call(this, options);
|
|
@@ -223,7 +250,7 @@ class KV{
|
|
|
223
250
|
preprocess: (args) => {
|
|
224
251
|
// key size cannot be larger than this.MAX_KEY_SIZE
|
|
225
252
|
if ( args.key.length > this.MAX_KEY_SIZE ){
|
|
226
|
-
throw ({ message:
|
|
253
|
+
throw ({ message: `Key size cannot be larger than ${this.MAX_KEY_SIZE}`, code: 'key_too_large' });
|
|
227
254
|
}
|
|
228
255
|
|
|
229
256
|
return args;
|
|
@@ -292,7 +319,7 @@ function globMatch(pattern, str) {
|
|
|
292
319
|
.replace(/\\\]/g, ']') // Replace ] with ]
|
|
293
320
|
.replace(/\\\^/g, '^'); // Replace ^ with ^
|
|
294
321
|
|
|
295
|
-
let re = new RegExp(
|
|
322
|
+
let re = new RegExp(`^${regexPattern}$`);
|
|
296
323
|
return re.test(str);
|
|
297
324
|
}
|
|
298
325
|
|
package/src/modules/UI.js
CHANGED
|
@@ -275,6 +275,7 @@ class UI extends EventListener {
|
|
|
275
275
|
// Bind the message event listener to the window
|
|
276
276
|
let lastDraggedOverElement = null;
|
|
277
277
|
(globalThis.document) && window.addEventListener('message', async (e) => {
|
|
278
|
+
if (!e.data) return;
|
|
278
279
|
// `error`
|
|
279
280
|
if(e.data.error){
|
|
280
281
|
throw e.data.error;
|
|
@@ -395,6 +396,12 @@ class UI extends EventListener {
|
|
|
395
396
|
this.#callbackFunctions[e.data.original_msg_id](appDataItem);
|
|
396
397
|
}
|
|
397
398
|
}
|
|
399
|
+
// instancesOpenSucceeded
|
|
400
|
+
else if(e.data.msg === 'instancesOpenSucceeded'){
|
|
401
|
+
if(e.data.original_msg_id && this.#callbackFunctions[e.data.original_msg_id]){
|
|
402
|
+
this.#callbackFunctions[e.data.original_msg_id](e.data.instancesOpen);
|
|
403
|
+
}
|
|
404
|
+
}
|
|
398
405
|
// readAppDataFileSucceeded
|
|
399
406
|
else if(e.data.msg === 'readAppDataFileSucceeded'){
|
|
400
407
|
let appDataItem = new FSItem(e.data.item);
|
|
@@ -657,6 +664,12 @@ class UI extends EventListener {
|
|
|
657
664
|
})
|
|
658
665
|
}
|
|
659
666
|
|
|
667
|
+
instancesOpen = function(callback) {
|
|
668
|
+
return new Promise((resolve) => {
|
|
669
|
+
this.#postMessageWithCallback('getInstancesOpen', resolve, { });
|
|
670
|
+
})
|
|
671
|
+
}
|
|
672
|
+
|
|
660
673
|
socialShare = function(url, message, options, callback) {
|
|
661
674
|
return new Promise((resolve) => {
|
|
662
675
|
this.#postMessageWithCallback('socialShare', resolve, { url, message, options });
|
|
@@ -917,6 +930,18 @@ class UI extends EventListener {
|
|
|
917
930
|
})
|
|
918
931
|
}
|
|
919
932
|
|
|
933
|
+
showWindow = function() {
|
|
934
|
+
this.#postMessageWithObject('showWindow');
|
|
935
|
+
}
|
|
936
|
+
|
|
937
|
+
hideWindow = function() {
|
|
938
|
+
this.#postMessageWithObject('hideWindow');
|
|
939
|
+
}
|
|
940
|
+
|
|
941
|
+
toggleWindow = function() {
|
|
942
|
+
this.#postMessageWithObject('toggleWindow');
|
|
943
|
+
}
|
|
944
|
+
|
|
920
945
|
setMenubar = function(spec) {
|
|
921
946
|
this.#postMessageWithObject('setMenubar', spec);
|
|
922
947
|
}
|
|
@@ -1541,9 +1566,12 @@ class UI extends EventListener {
|
|
|
1541
1566
|
* console.log(`Current language: ${currentLang}`); // e.g., "Current language: fr"
|
|
1542
1567
|
*/
|
|
1543
1568
|
getLanguage() {
|
|
1544
|
-
//
|
|
1569
|
+
// resolve with the current language code if in GUI environment
|
|
1545
1570
|
if(this.env === 'gui'){
|
|
1546
|
-
|
|
1571
|
+
// resolve with the current language code
|
|
1572
|
+
return new Promise((resolve) => {
|
|
1573
|
+
resolve(window.locale);
|
|
1574
|
+
});
|
|
1547
1575
|
}
|
|
1548
1576
|
|
|
1549
1577
|
return new Promise((resolve) => {
|
|
@@ -11,6 +11,10 @@ export class PTLSSocket extends PSocket {
|
|
|
11
11
|
super(...args);
|
|
12
12
|
super.on("open", (async() => {
|
|
13
13
|
if (!rustls) {
|
|
14
|
+
// Safari exists unfortunately without good ReadableStream support. Until that is fixed we need this.
|
|
15
|
+
if (!globalThis.ReadableByteStreamController) {
|
|
16
|
+
await import( /* webpackIgnore: true */ "https://unpkg.com/web-streams-polyfill@3.0.2/dist/polyfill.js");
|
|
17
|
+
}
|
|
14
18
|
rustls = (await import( /* webpackIgnore: true */ "https://puter-net.b-cdn.net/rustls.js"))
|
|
15
19
|
await rustls.default("https://puter-net.b-cdn.net/rustls.wasm")
|
|
16
20
|
}
|