@heyputer/puter.js 2.1.6 → 2.1.7

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 (57) hide show
  1. package/dist/puter.cjs +2 -2
  2. package/index.d.ts +14 -14
  3. package/package.json +1 -1
  4. package/src/index.js +91 -91
  5. package/src/lib/APICallLogger.js +20 -21
  6. package/src/lib/EventListener.js +10 -10
  7. package/src/lib/filesystem/APIFS.js +11 -19
  8. package/src/lib/filesystem/CacheFS.js +25 -25
  9. package/src/lib/filesystem/PostMessageFS.js +11 -11
  10. package/src/lib/filesystem/definitions.js +11 -10
  11. package/src/lib/path.js +505 -446
  12. package/src/lib/polyfills/fileReaderPoly.js +40 -0
  13. package/src/lib/polyfills/localStorage.js +30 -33
  14. package/src/lib/polyfills/xhrshim.js +206 -207
  15. package/src/lib/utils.js +160 -151
  16. package/src/lib/xdrpc.js +9 -9
  17. package/src/modules/AI.js +416 -290
  18. package/src/modules/Apps.js +56 -56
  19. package/src/modules/Auth.js +17 -17
  20. package/src/modules/Debug.js +1 -1
  21. package/src/modules/Drivers.js +41 -41
  22. package/src/modules/FSItem.js +64 -62
  23. package/src/modules/FileSystem/index.js +22 -23
  24. package/src/modules/FileSystem/operations/copy.js +7 -7
  25. package/src/modules/FileSystem/operations/deleteFSEntry.js +14 -12
  26. package/src/modules/FileSystem/operations/getReadUrl.js +16 -14
  27. package/src/modules/FileSystem/operations/mkdir.js +11 -11
  28. package/src/modules/FileSystem/operations/move.js +12 -12
  29. package/src/modules/FileSystem/operations/read.js +10 -10
  30. package/src/modules/FileSystem/operations/readdir.js +28 -28
  31. package/src/modules/FileSystem/operations/rename.js +11 -11
  32. package/src/modules/FileSystem/operations/sign.js +33 -30
  33. package/src/modules/FileSystem/operations/space.js +7 -7
  34. package/src/modules/FileSystem/operations/stat.js +25 -25
  35. package/src/modules/FileSystem/operations/symlink.js +15 -17
  36. package/src/modules/FileSystem/operations/upload.js +151 -122
  37. package/src/modules/FileSystem/operations/write.js +16 -12
  38. package/src/modules/FileSystem/utils/getAbsolutePathForApp.js +10 -6
  39. package/src/modules/Hosting.js +29 -29
  40. package/src/modules/KV.js +23 -23
  41. package/src/modules/OS.js +15 -15
  42. package/src/modules/Perms.js +19 -21
  43. package/src/modules/PuterDialog.js +46 -48
  44. package/src/modules/Threads.js +17 -20
  45. package/src/modules/UI.js +156 -156
  46. package/src/modules/Util.js +3 -3
  47. package/src/modules/Workers.js +52 -49
  48. package/src/modules/networking/PSocket.js +38 -38
  49. package/src/modules/networking/PTLS.js +54 -47
  50. package/src/modules/networking/PWispHandler.js +49 -47
  51. package/src/modules/networking/parsers.js +110 -108
  52. package/src/modules/networking/requests.js +67 -78
  53. package/src/services/APIAccess.js +9 -9
  54. package/src/services/FSRelay.js +6 -6
  55. package/src/services/Filesystem.js +8 -8
  56. package/src/services/NoPuterYet.js +2 -2
  57. package/src/services/XDIncoming.js +1 -1
@@ -1,32 +1,31 @@
1
1
  /*
2
2
  * Copyright (C) 2024-present Puter Technologies Inc.
3
- *
3
+ *
4
4
  * This file is part of Puter.
5
- *
5
+ *
6
6
  * Puter is free software: you can redistribute it and/or modify
7
7
  * it under the terms of the GNU Affero General Public License as published
8
8
  * by the Free Software Foundation, either version 3 of the License, or
9
9
  * (at your option) any later version.
10
- *
10
+ *
11
11
  * This program is distributed in the hope that it will be useful,
12
12
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13
13
  * MERCHANTABILITY or FITNESS FOR PARTICULAR PURPOSE. See the
14
14
  * GNU Affero General Public License for more details.
15
- *
15
+ *
16
16
  * You should have received a copy of the GNU Affero General Public License
17
17
  * along with this program. If not, see <https://www.gnu.org/licenses/>.
18
18
  */
19
19
 
20
-
21
20
  /**
22
21
  * APICallLogger provides centralized logging for all API calls made by the puter-js SDK.
23
22
  * It logs API calls in a simple format: service - operation - params - result
24
23
  */
25
24
  class APICallLogger {
26
- constructor(config = {}) {
25
+ constructor (config = {}) {
27
26
  this.config = {
28
27
  enabled: config.enabled ?? false,
29
- ...config
28
+ ...config,
30
29
  };
31
30
  }
32
31
 
@@ -34,21 +33,21 @@ class APICallLogger {
34
33
  * Updates the logger configuration
35
34
  * @param {Object} newConfig - New configuration options
36
35
  */
37
- updateConfig(newConfig) {
36
+ updateConfig (newConfig) {
38
37
  this.config = { ...this.config, ...newConfig };
39
38
  }
40
39
 
41
40
  /**
42
41
  * Enables API call logging
43
42
  */
44
- enable() {
43
+ enable () {
45
44
  this.config.enabled = true;
46
45
  }
47
46
 
48
47
  /**
49
48
  * Disables API call logging
50
49
  */
51
- disable() {
50
+ disable () {
52
51
  this.config.enabled = false;
53
52
  }
54
53
 
@@ -56,7 +55,7 @@ class APICallLogger {
56
55
  * Checks if logging is enabled for the current configuration
57
56
  * @returns {boolean}
58
57
  */
59
- isEnabled() {
58
+ isEnabled () {
60
59
  return this.config.enabled;
61
60
  }
62
61
 
@@ -64,20 +63,20 @@ class APICallLogger {
64
63
  * Logs the completion of an API request in a simple format
65
64
  * @param {Object} options - Request completion options
66
65
  */
67
- logRequest(options = {}) {
68
- if (!this.isEnabled()) return;
66
+ logRequest (options = {}) {
67
+ if ( ! this.isEnabled() ) return;
69
68
 
70
- const {
71
- service = 'unknown',
69
+ const {
70
+ service = 'unknown',
72
71
  operation = 'unknown',
73
72
  params = {},
74
73
  result = null,
75
- error = null
74
+ error = null,
76
75
  } = options;
77
76
 
78
77
  // Format params as a readable string
79
78
  let paramsStr = '{}';
80
- if (params && Object.keys(params).length > 0) {
79
+ if ( params && Object.keys(params).length > 0 ) {
81
80
  try {
82
81
  paramsStr = JSON.stringify(params);
83
82
  } catch (e) {
@@ -87,8 +86,8 @@ class APICallLogger {
87
86
 
88
87
  // Format the log message with bold params
89
88
  const logMessage = `${service} - ${operation} - \x1b[1m${paramsStr}\x1b[22m`;
90
-
91
- if (error) {
89
+
90
+ if ( error ) {
92
91
  console.error(logMessage, { error: error.message || error, result });
93
92
  } else {
94
93
  console.log(logMessage, result);
@@ -99,10 +98,10 @@ class APICallLogger {
99
98
  * Gets current logging statistics
100
99
  * @returns {Object}
101
100
  */
102
- getStats() {
101
+ getStats () {
103
102
  return {
104
103
  enabled: this.config.enabled,
105
- config: { ...this.config }
104
+ config: { ...this.config },
106
105
  };
107
106
  }
108
107
  }
@@ -5,20 +5,20 @@ export default class EventListener {
5
5
  // Map of eventName -> array of listeners
6
6
  #eventListeners;
7
7
 
8
- constructor(eventNames) {
8
+ constructor (eventNames) {
9
9
  this.#eventNames = eventNames;
10
10
 
11
11
  this.#eventListeners = (() => {
12
12
  const map = new Map();
13
- for (let eventName of this.#eventNames) {
13
+ for ( let eventName of this.#eventNames ) {
14
14
  map[eventName] = [];
15
15
  }
16
16
  return map;
17
17
  })();
18
18
  }
19
19
 
20
- emit(eventName, data) {
21
- if (!this.#eventNames.includes(eventName)) {
20
+ emit (eventName, data) {
21
+ if ( ! this.#eventNames.includes(eventName) ) {
22
22
  console.error(`Event name '${eventName}' not supported`);
23
23
  return;
24
24
  }
@@ -27,8 +27,8 @@ export default class EventListener {
27
27
  });
28
28
  }
29
29
 
30
- on(eventName, callback) {
31
- if (!this.#eventNames.includes(eventName)) {
30
+ on (eventName, callback) {
31
+ if ( ! this.#eventNames.includes(eventName) ) {
32
32
  console.error(`Event name '${eventName}' not supported`);
33
33
  return;
34
34
  }
@@ -36,14 +36,14 @@ export default class EventListener {
36
36
  return this;
37
37
  }
38
38
 
39
- off(eventName, callback) {
40
- if (!this.#eventNames.includes(eventName)) {
39
+ off (eventName, callback) {
40
+ if ( ! this.#eventNames.includes(eventName) ) {
41
41
  console.error(`Event name '${eventName}' not supported`);
42
42
  return;
43
43
  }
44
44
  const listeners = this.#eventListeners[eventName];
45
- const index = listeners.indexOf(callback)
46
- if (index !== -1) {
45
+ const index = listeners.indexOf(callback);
46
+ if ( index !== -1 ) {
47
47
  listeners.splice(index, 1);
48
48
  }
49
49
  return this;
@@ -1,6 +1,6 @@
1
1
  import * as utils from '../utils.js';
2
- import putility from "@heyputer/putility";
3
- import { TeePromise } from "@heyputer/putility/src/libs/promise.js";
2
+ import putility from '@heyputer/putility';
3
+ import { TeePromise } from '@heyputer/putility/src/libs/promise.js';
4
4
  import getAbsolutePathForApp from '../../modules/FileSystem/utils/getAbsolutePathForApp.js';
5
5
  import { TFilesystem } from './definitions.js';
6
6
 
@@ -16,17 +16,13 @@ export class PuterAPIFilesystem extends putility.AdvancedBase {
16
16
  this.ensure_auth_();
17
17
  const tp = new TeePromise();
18
18
 
19
-
20
- const xhr = new utils.initXhr('/stat', this.api_info.APIOrigin, undefined, "post", "text/plain;actually=json");
21
- utils.setupXhrEventHandlers(xhr, undefined, undefined,
22
- tp.resolve.bind(tp),
23
- tp.reject.bind(tp),
24
- );
19
+ const xhr = new utils.initXhr('/stat', this.api_info.APIOrigin, undefined, 'post', 'text/plain;actually=json');
20
+ utils.setupXhrEventHandlers(xhr, undefined, undefined, tp.resolve.bind(tp), tp.reject.bind(tp));
25
21
 
26
22
  let dataToSend = {};
27
- if (options.uid !== undefined) {
23
+ if ( options.uid !== undefined ) {
28
24
  dataToSend.uid = options.uid;
29
- } else if (options.path !== undefined) {
25
+ } else if ( options.path !== undefined ) {
30
26
  // If dirPath is not provided or it's not starting with a slash, it means it's a relative path
31
27
  // in that case, we need to prepend the app's root directory to it
32
28
  dataToSend.path = getAbsolutePathForApp(options.path);
@@ -38,7 +34,6 @@ export class PuterAPIFilesystem extends putility.AdvancedBase {
38
34
  dataToSend.return_size = options.returnSize;
39
35
  dataToSend.auth_token = this.api_info.authToken;
40
36
 
41
-
42
37
  xhr.send(JSON.stringify(dataToSend));
43
38
 
44
39
  return await tp;
@@ -47,22 +42,19 @@ export class PuterAPIFilesystem extends putility.AdvancedBase {
47
42
  this.ensure_auth_();
48
43
  const tp = new TeePromise();
49
44
 
50
- const xhr = new utils.initXhr('/readdir', this.api_info.APIOrigin, undefined, "post", "text/plain;actually=json");
51
- utils.setupXhrEventHandlers(xhr, undefined, undefined,
52
- tp.resolve.bind(tp),
53
- tp.reject.bind(tp),
54
- );
45
+ const xhr = new utils.initXhr('/readdir', this.api_info.APIOrigin, undefined, 'post', 'text/plain;actually=json');
46
+ utils.setupXhrEventHandlers(xhr, undefined, undefined, tp.resolve.bind(tp), tp.reject.bind(tp));
55
47
 
56
48
  xhr.send(JSON.stringify({ path: getAbsolutePathForApp(options.path), auth_token: this.api_info.authToken }));
57
49
 
58
50
  return await tp;
59
51
  },
60
- }
61
- }
52
+ },
53
+ };
62
54
 
63
55
  ensure_auth_ () {
64
56
  // TODO: remove reference to global 'puter'; get 'env' via context
65
- if ( ! this.api_info.authToken && puter.env === 'web' ) {
57
+ if ( !this.api_info.authToken && puter.env === 'web' ) {
66
58
  try {
67
59
  this.ui.authenticateWithPuter();
68
60
  } catch (e) {
@@ -1,7 +1,7 @@
1
- import putility from "@heyputer/putility";
2
- import { RWLock } from "@heyputer/putility/src/libs/promise.js";
3
- import { ProxyFilesystem, TFilesystem } from "./definitions.js";
4
- import { uuidv4 } from "../utils.js";
1
+ import putility from '@heyputer/putility';
2
+ import { RWLock } from '@heyputer/putility/src/libs/promise.js';
3
+ import { ProxyFilesystem, TFilesystem } from './definitions.js';
4
+ import { uuidv4 } from '../utils.js';
5
5
 
6
6
  export const ROOT_UUID = '00000000-0000-0000-0000-000000000000';
7
7
  const TTL = 5 * 1000;
@@ -59,7 +59,7 @@ export class CacheFS extends putility.AdvancedBase {
59
59
  if ( uuid === internal_identifier ) return;
60
60
  this.assocs_uuid_[uuid] = internal_identifier;
61
61
  }
62
-
62
+
63
63
  }
64
64
 
65
65
  export class CachedFilesystem extends ProxyFilesystem {
@@ -82,9 +82,9 @@ export class CachedFilesystem extends ProxyFilesystem {
82
82
 
83
83
  let values_requested = {};
84
84
  for ( const mod of modifiers ) {
85
- const optionsKey = 'return' +
86
- mod.charAt(0).toUpperCase() +
87
- mod.slice(1);
85
+ const optionsKey = `return${
86
+ mod.charAt(0).toUpperCase()
87
+ }${mod.slice(1)}`;
88
88
  if ( ! o[optionsKey] ) continue;
89
89
  values_requested[mod] = true;
90
90
  }
@@ -97,8 +97,8 @@ export class CachedFilesystem extends ProxyFilesystem {
97
97
  }
98
98
  }
99
99
  return true;
100
- }
101
-
100
+ };
101
+
102
102
  let cached_stat;
103
103
  if ( cent && cent.stat && cent.stat_exp > Date.now() ) {
104
104
  const l = await cent.locks.stat.rlock();
@@ -123,7 +123,7 @@ export class CachedFilesystem extends ProxyFilesystem {
123
123
  const entry = await this.delegate.stat(o);
124
124
 
125
125
  // We might have new information to identify a relevant cache entry
126
- let cent_replaced = !! cent;
126
+ let cent_replaced = !!cent;
127
127
  cent = this.cacheFS.get_entry_ei([entry.uid, entry.path]);
128
128
  if ( cent ) {
129
129
  if ( cent_replaced ) l.unlock();
@@ -134,7 +134,7 @@ export class CachedFilesystem extends ProxyFilesystem {
134
134
  cent = this.cacheFS.add_entry({ id: entry.uid });
135
135
  this.cacheFS.assoc_path(entry.path, cent.id);
136
136
  this.cacheFS.assoc_uuid(entry.uid, cent.id);
137
-
137
+
138
138
  l = await cent.locks.stat.wlock();
139
139
  }
140
140
 
@@ -160,21 +160,21 @@ export class CachedFilesystem extends ProxyFilesystem {
160
160
 
161
161
  for ( const id of cent.members ) {
162
162
  const member = this.cacheFS.get_entry_ei(id);
163
- if ( ! member || ! member.stat || member.stat_exp <= Date.now() ) {
163
+ if ( !member || !member.stat || member.stat_exp <= Date.now() ) {
164
164
  console.log('NO MEMBER OR STAT', member);
165
165
  stats = null;
166
166
  break;
167
167
  }
168
168
  console.log('member', member);
169
- if ( ! o.no_assocs && ! member.stat_has.subdomains ) {
169
+ if ( !o.no_assocs && !member.stat_has.subdomains ) {
170
170
  stats = null;
171
171
  break;
172
172
  }
173
- if ( ! o.no_assocs && ! member.stat_has.apps ) {
173
+ if ( !o.no_assocs && !member.stat_has.apps ) {
174
174
  stats = null;
175
175
  break;
176
176
  }
177
- if ( ! o.no_thumbs && ! member.stat_has.thumbnail ) {
177
+ if ( !o.no_thumbs && !member.stat_has.thumbnail ) {
178
178
  stats = null;
179
179
  break;
180
180
  }
@@ -219,14 +219,14 @@ export class CachedFilesystem extends ProxyFilesystem {
219
219
  // });
220
220
  entry_cent.stat = entry;
221
221
  entry_cent.stat_has = {
222
- subdomains: ! o.no_assocs,
223
- apps: ! o.no_assocs,
224
- thumbnail: ! o.no_thumbs,
225
- }
226
- entry_cent.stat_exp = Date.now() + 1000*3;
222
+ subdomains: !o.no_assocs,
223
+ apps: !o.no_assocs,
224
+ thumbnail: !o.no_thumbs,
225
+ };
226
+ entry_cent.stat_exp = Date.now() + 1000 * 3;
227
227
  }
228
228
 
229
- cent.members = []
229
+ cent.members = [];
230
230
  for ( const id of cent_ids ) {
231
231
  cent.members.push(id);
232
232
  }
@@ -237,7 +237,7 @@ export class CachedFilesystem extends ProxyFilesystem {
237
237
  console.log('CACHE ENTRY?', cent);
238
238
 
239
239
  return entries;
240
- }
241
- }
242
- }
240
+ },
241
+ },
242
+ };
243
243
  }
@@ -1,13 +1,13 @@
1
- import putility from "@heyputer/putility";
2
- import { TFilesystem } from "./definitions.js";
1
+ import putility from '@heyputer/putility';
2
+ import { TFilesystem } from './definitions.js';
3
3
 
4
4
  const example = {
5
- "id": "f485f1ba-de07-422c-8c4b-c2da057d4a44",
6
- "uid": "f485f1ba-de07-422c-8c4b-c2da057d4a44",
7
- "is_dir": true,
8
- "immutable": true,
9
- "name": "Test",
10
- };
5
+ 'id': 'f485f1ba-de07-422c-8c4b-c2da057d4a44',
6
+ 'uid': 'f485f1ba-de07-422c-8c4b-c2da057d4a44',
7
+ 'is_dir': true,
8
+ 'immutable': true,
9
+ 'name': 'Test',
10
+ };
11
11
 
12
12
  export class PostMessageFilesystem extends putility.AdvancedBase {
13
13
  constructor ({ rpc, messageTarget }) {
@@ -34,7 +34,7 @@ export class PostMessageFilesystem extends putility.AdvancedBase {
34
34
  }, '*');
35
35
 
36
36
  return await tp;
37
- }
38
- }
39
- }
37
+ },
38
+ },
39
+ };
40
40
  }
@@ -1,4 +1,4 @@
1
- import putility from "@heyputer/putility";
1
+ import putility from '@heyputer/putility';
2
2
 
3
3
  export const TFilesystem = 'TFilesystem';
4
4
 
@@ -10,17 +10,18 @@ export const IFilesystem = {
10
10
  parameters: {
11
11
  path: {
12
12
  alias: 'uid',
13
- }
14
- }
15
- }
16
- }
13
+ },
14
+ },
15
+ },
16
+ },
17
17
 
18
18
  };
19
19
 
20
20
  export class ProxyFilesystem extends putility.AdvancedBase {
21
21
  static PROPERTIES = {
22
- delegate: () => {},
23
- }
22
+ delegate: () => {
23
+ },
24
+ };
24
25
  // TODO: constructor implied by properties
25
26
  constructor ({ delegate }) {
26
27
  super();
@@ -33,7 +34,7 @@ export class ProxyFilesystem extends putility.AdvancedBase {
33
34
  },
34
35
  readdir: async function (o) {
35
36
  return this.delegate.readdir(o);
36
- }
37
- }
38
- }
37
+ },
38
+ },
39
+ };
39
40
  }