@heyputer/puter.js 2.0.12 → 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/README.md +15 -0
- package/dist/puter.cjs +4 -0
- package/index.d.ts +23 -5
- package/package.json +6 -5
- package/src/index.js +19 -9
- package/src/init.cjs +4 -1
- 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 -28
- 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 -1
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,28 +95,37 @@ 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
|
-
console.log(args);
|
|
108
|
-
|
|
109
118
|
// key cannot be undefined or null
|
|
110
119
|
if ( args.key === undefined || args.key === null ){
|
|
111
120
|
throw { message: 'Key cannot be undefined', code: 'key_undefined' };
|
|
112
121
|
}
|
|
113
122
|
// key size cannot be larger than MAX_KEY_SIZE
|
|
114
123
|
if ( args.key.length > this.MAX_KEY_SIZE ){
|
|
115
|
-
throw { message:
|
|
124
|
+
throw { message: `Key size cannot be larger than ${this.MAX_KEY_SIZE}`, code: 'key_too_large' };
|
|
116
125
|
}
|
|
117
126
|
// value size cannot be larger than MAX_VALUE_SIZE
|
|
118
127
|
if ( args.value && args.value.length > this.MAX_VALUE_SIZE ){
|
|
119
|
-
throw { message:
|
|
128
|
+
throw { message: `Value size cannot be larger than ${this.MAX_VALUE_SIZE}`, code: 'value_too_large' };
|
|
120
129
|
}
|
|
121
130
|
return args;
|
|
122
131
|
},
|
|
@@ -145,7 +154,7 @@ class KV{
|
|
|
145
154
|
preprocess: (args) => {
|
|
146
155
|
// key size cannot be larger than MAX_KEY_SIZE
|
|
147
156
|
if ( args.key.length > this.MAX_KEY_SIZE ){
|
|
148
|
-
throw ({ message:
|
|
157
|
+
throw ({ message: `Key size cannot be larger than ${this.MAX_KEY_SIZE}`, code: 'key_too_large' });
|
|
149
158
|
}
|
|
150
159
|
|
|
151
160
|
return args;
|
|
@@ -164,11 +173,11 @@ class KV{
|
|
|
164
173
|
}
|
|
165
174
|
|
|
166
175
|
options.key = args[0];
|
|
167
|
-
options.
|
|
176
|
+
options.pathAndAmountMap = !args[1] ? { '': 1 } : typeof args[1] === 'number' ? { '': args[1] } : args[1];
|
|
168
177
|
|
|
169
178
|
// key size cannot be larger than MAX_KEY_SIZE
|
|
170
179
|
if ( options.key.length > this.MAX_KEY_SIZE ){
|
|
171
|
-
throw ({ message:
|
|
180
|
+
throw ({ message: `Key size cannot be larger than ${this.MAX_KEY_SIZE}`, code: 'key_too_large' });
|
|
172
181
|
}
|
|
173
182
|
|
|
174
183
|
return utils.make_driver_method(['key'], 'puter-kvstore', undefined, 'incr').call(this, options);
|
|
@@ -183,37 +192,53 @@ class KV{
|
|
|
183
192
|
}
|
|
184
193
|
|
|
185
194
|
options.key = args[0];
|
|
186
|
-
options.
|
|
195
|
+
options.pathAndAmountMap = !args[1] ? { '': 1 } : typeof args[1] === 'number' ? { '': args[1] } : args[1];
|
|
187
196
|
|
|
188
197
|
// key size cannot be larger than MAX_KEY_SIZE
|
|
189
198
|
if ( options.key.length > this.MAX_KEY_SIZE ){
|
|
190
|
-
throw ({ message:
|
|
199
|
+
throw ({ message: `Key size cannot be larger than ${this.MAX_KEY_SIZE}`, code: 'key_too_large' });
|
|
191
200
|
}
|
|
192
201
|
|
|
193
202
|
return utils.make_driver_method(['key'], 'puter-kvstore', undefined, 'decr').call(this, options);
|
|
194
203
|
};
|
|
195
204
|
|
|
196
|
-
|
|
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) => {
|
|
197
214
|
let options = {};
|
|
198
|
-
options.key =
|
|
199
|
-
options.ttl =
|
|
215
|
+
options.key = key;
|
|
216
|
+
options.ttl = ttl;
|
|
200
217
|
|
|
201
218
|
// key size cannot be larger than MAX_KEY_SIZE
|
|
202
219
|
if ( options.key.length > this.MAX_KEY_SIZE ){
|
|
203
|
-
throw ({ message:
|
|
220
|
+
throw ({ message: `Key size cannot be larger than ${this.MAX_KEY_SIZE}`, code: 'key_too_large' });
|
|
204
221
|
}
|
|
205
222
|
|
|
206
223
|
return utils.make_driver_method(['key', 'ttl'], 'puter-kvstore', undefined, 'expire').call(this, options);
|
|
207
224
|
};
|
|
208
225
|
|
|
209
|
-
|
|
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) => {
|
|
210
236
|
let options = {};
|
|
211
|
-
options.key =
|
|
212
|
-
options.timestamp =
|
|
213
|
-
|
|
237
|
+
options.key = key;
|
|
238
|
+
options.timestamp = timestamp;
|
|
214
239
|
// key size cannot be larger than MAX_KEY_SIZE
|
|
215
240
|
if ( options.key.length > this.MAX_KEY_SIZE ){
|
|
216
|
-
throw ({ message:
|
|
241
|
+
throw ({ message: `Key size cannot be larger than ${this.MAX_KEY_SIZE}`, code: 'key_too_large' });
|
|
217
242
|
}
|
|
218
243
|
|
|
219
244
|
return utils.make_driver_method(['key', 'timestamp'], 'puter-kvstore', undefined, 'expireAt').call(this, options);
|
|
@@ -225,7 +250,7 @@ class KV{
|
|
|
225
250
|
preprocess: (args) => {
|
|
226
251
|
// key size cannot be larger than this.MAX_KEY_SIZE
|
|
227
252
|
if ( args.key.length > this.MAX_KEY_SIZE ){
|
|
228
|
-
throw ({ message:
|
|
253
|
+
throw ({ message: `Key size cannot be larger than ${this.MAX_KEY_SIZE}`, code: 'key_too_large' });
|
|
229
254
|
}
|
|
230
255
|
|
|
231
256
|
return args;
|
|
@@ -294,7 +319,7 @@ function globMatch(pattern, str) {
|
|
|
294
319
|
.replace(/\\\]/g, ']') // Replace ] with ]
|
|
295
320
|
.replace(/\\\^/g, '^'); // Replace ^ with ^
|
|
296
321
|
|
|
297
|
-
let re = new RegExp(
|
|
322
|
+
let re = new RegExp(`^${regexPattern}$`);
|
|
298
323
|
return re.test(str);
|
|
299
324
|
}
|
|
300
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
|
}
|