@heyputer/puter.js 2.1.15 → 2.2.2
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/package.json +2 -3
- package/src/index.js +100 -80
- package/src/lib/utils.js +23 -55
- package/src/modules/AI.js +8 -204
- package/src/modules/Apps.js +6 -5
- package/src/modules/Auth.js +6 -5
- package/src/modules/Debug.js +4 -4
- package/src/modules/Drivers.js +12 -17
- package/src/modules/FileSystem/index.js +10 -23
- package/src/modules/Hosting.js +5 -4
- package/src/modules/KV.js +21 -11
- package/src/modules/OS.js +6 -5
- package/src/modules/Perms.js +4 -3
- package/src/modules/Threads.js +4 -3
- package/src/modules/UI.js +44 -28
- package/src/lib/filesystem/APIFS.js +0 -65
- package/src/lib/filesystem/CacheFS.js +0 -243
- package/src/lib/filesystem/PostMessageFS.js +0 -40
- package/src/lib/filesystem/definitions.js +0 -40
- package/src/services/APIAccess.js +0 -46
- package/src/services/FSRelay.js +0 -20
- package/src/services/Filesystem.js +0 -137
- package/src/services/NoPuterYet.js +0 -20
- package/src/services/XDIncoming.js +0 -44
|
@@ -1,243 +0,0 @@
|
|
|
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
|
-
|
|
6
|
-
export const ROOT_UUID = '00000000-0000-0000-0000-000000000000';
|
|
7
|
-
const TTL = 5 * 1000;
|
|
8
|
-
|
|
9
|
-
export class CacheFS extends putility.AdvancedBase {
|
|
10
|
-
static PROPERTIES = {
|
|
11
|
-
assocs_path_: () => ({}),
|
|
12
|
-
assocs_uuid_: () => ({}),
|
|
13
|
-
entries: () => ({}),
|
|
14
|
-
};
|
|
15
|
-
|
|
16
|
-
get_entry_ei (external_identifier) {
|
|
17
|
-
if ( Array.isArray(external_identifier) ) {
|
|
18
|
-
for ( const ei of external_identifier ) {
|
|
19
|
-
const entry = this.get_entry_ei(ei);
|
|
20
|
-
if ( entry ) return entry;
|
|
21
|
-
}
|
|
22
|
-
return;
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
console.log('GET ENTRY EI', external_identifier);
|
|
26
|
-
|
|
27
|
-
const internal_identifier =
|
|
28
|
-
this.assocs_path_[external_identifier] ||
|
|
29
|
-
this.assocs_uuid_[external_identifier] ||
|
|
30
|
-
external_identifier;
|
|
31
|
-
|
|
32
|
-
if ( ! internal_identifier ) {
|
|
33
|
-
return;
|
|
34
|
-
}
|
|
35
|
-
return this.entries[internal_identifier];
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
add_entry ({ id } = {}) {
|
|
39
|
-
const internal_identifier = id ?? uuidv4();
|
|
40
|
-
const entry = {
|
|
41
|
-
id: internal_identifier,
|
|
42
|
-
stat_has: {},
|
|
43
|
-
stat_exp: 0,
|
|
44
|
-
locks: {
|
|
45
|
-
stat: new RWLock(),
|
|
46
|
-
members: new RWLock(),
|
|
47
|
-
},
|
|
48
|
-
};
|
|
49
|
-
this.entries[internal_identifier] = entry;
|
|
50
|
-
return entry;
|
|
51
|
-
}
|
|
52
|
-
|
|
53
|
-
assoc_path (path, internal_identifier) {
|
|
54
|
-
console.log('ASSOC PATH', path, internal_identifier);
|
|
55
|
-
this.assocs_path_[path] = internal_identifier;
|
|
56
|
-
}
|
|
57
|
-
|
|
58
|
-
assoc_uuid (uuid, internal_identifier) {
|
|
59
|
-
if ( uuid === internal_identifier ) return;
|
|
60
|
-
this.assocs_uuid_[uuid] = internal_identifier;
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
}
|
|
64
|
-
|
|
65
|
-
export class CachedFilesystem extends ProxyFilesystem {
|
|
66
|
-
constructor (o) {
|
|
67
|
-
super(o);
|
|
68
|
-
// this.cacheFS = cacheFS;
|
|
69
|
-
this.cacheFS = new CacheFS();
|
|
70
|
-
}
|
|
71
|
-
static IMPLEMENTS = {
|
|
72
|
-
[TFilesystem]: {
|
|
73
|
-
stat: async function (o) {
|
|
74
|
-
let cent = this.cacheFS.get_entry_ei(o.path ?? o.uid);
|
|
75
|
-
|
|
76
|
-
const modifiers = [
|
|
77
|
-
'subdomains',
|
|
78
|
-
'permissions',
|
|
79
|
-
'versions',
|
|
80
|
-
'size',
|
|
81
|
-
];
|
|
82
|
-
|
|
83
|
-
let values_requested = {};
|
|
84
|
-
for ( const mod of modifiers ) {
|
|
85
|
-
const optionsKey = `return${
|
|
86
|
-
mod.charAt(0).toUpperCase()
|
|
87
|
-
}${mod.slice(1)}`;
|
|
88
|
-
if ( ! o[optionsKey] ) continue;
|
|
89
|
-
values_requested[mod] = true;
|
|
90
|
-
}
|
|
91
|
-
|
|
92
|
-
const satisfactory_cache = cent => {
|
|
93
|
-
for ( const mod of modifiers ) {
|
|
94
|
-
if ( ! values_requested[mod] ) continue;
|
|
95
|
-
if ( ! cent.stat_has[mod] ) {
|
|
96
|
-
return false;
|
|
97
|
-
}
|
|
98
|
-
}
|
|
99
|
-
return true;
|
|
100
|
-
};
|
|
101
|
-
|
|
102
|
-
let cached_stat;
|
|
103
|
-
if ( cent && cent.stat && cent.stat_exp > Date.now() ) {
|
|
104
|
-
const l = await cent.locks.stat.rlock();
|
|
105
|
-
if ( satisfactory_cache(cent) ) {
|
|
106
|
-
cached_stat = cent.stat;
|
|
107
|
-
}
|
|
108
|
-
l.unlock();
|
|
109
|
-
}
|
|
110
|
-
|
|
111
|
-
if ( cached_stat ) {
|
|
112
|
-
console.log('CACHE HIT');
|
|
113
|
-
return cached_stat;
|
|
114
|
-
}
|
|
115
|
-
console.log('CACHE MISS');
|
|
116
|
-
|
|
117
|
-
let l;
|
|
118
|
-
if ( cent ) {
|
|
119
|
-
l = await cent.locks.stat.wlock();
|
|
120
|
-
}
|
|
121
|
-
|
|
122
|
-
console.log('DOING THE STAT', o);
|
|
123
|
-
const entry = await this.delegate.stat(o);
|
|
124
|
-
|
|
125
|
-
// We might have new information to identify a relevant cache entry
|
|
126
|
-
let cent_replaced = !!cent;
|
|
127
|
-
cent = this.cacheFS.get_entry_ei([entry.uid, entry.path]);
|
|
128
|
-
if ( cent ) {
|
|
129
|
-
if ( cent_replaced ) l.unlock();
|
|
130
|
-
l = await cent.locks.stat.wlock();
|
|
131
|
-
}
|
|
132
|
-
|
|
133
|
-
if ( ! cent ) {
|
|
134
|
-
cent = this.cacheFS.add_entry({ id: entry.uid });
|
|
135
|
-
this.cacheFS.assoc_path(entry.path, cent.id);
|
|
136
|
-
this.cacheFS.assoc_uuid(entry.uid, cent.id);
|
|
137
|
-
|
|
138
|
-
l = await cent.locks.stat.wlock();
|
|
139
|
-
}
|
|
140
|
-
|
|
141
|
-
cent.stat = entry;
|
|
142
|
-
cent.stat_has = { ...values_requested };
|
|
143
|
-
// TODO: increase cache TTL once invalidation works
|
|
144
|
-
cent.stat_exp = Date.now() + TTL;
|
|
145
|
-
|
|
146
|
-
l.unlock();
|
|
147
|
-
|
|
148
|
-
console.log('RETRUNING THE ENTRY', entry);
|
|
149
|
-
return entry;
|
|
150
|
-
},
|
|
151
|
-
readdir: async function (o) {
|
|
152
|
-
let cent = this.cacheFS.get_entry_ei([o.path, o.uid]);
|
|
153
|
-
|
|
154
|
-
console.log('CENT', cent, o);
|
|
155
|
-
let stats = null;
|
|
156
|
-
if ( cent && cent.members && cent.members_exp > Date.now() ) {
|
|
157
|
-
console.log('MEMBERS', cent.members);
|
|
158
|
-
stats = [];
|
|
159
|
-
const l = await cent.locks.stat.rlock();
|
|
160
|
-
|
|
161
|
-
for ( const id of cent.members ) {
|
|
162
|
-
const member = this.cacheFS.get_entry_ei(id);
|
|
163
|
-
if ( !member || !member.stat || member.stat_exp <= Date.now() ) {
|
|
164
|
-
console.log('NO MEMBER OR STAT', member);
|
|
165
|
-
stats = null;
|
|
166
|
-
break;
|
|
167
|
-
}
|
|
168
|
-
console.log('member', member);
|
|
169
|
-
if ( !o.no_assocs && !member.stat_has.subdomains ) {
|
|
170
|
-
stats = null;
|
|
171
|
-
break;
|
|
172
|
-
}
|
|
173
|
-
if ( !o.no_assocs && !member.stat_has.apps ) {
|
|
174
|
-
stats = null;
|
|
175
|
-
break;
|
|
176
|
-
}
|
|
177
|
-
if ( !o.no_thumbs && !member.stat_has.thumbnail ) {
|
|
178
|
-
stats = null;
|
|
179
|
-
break;
|
|
180
|
-
}
|
|
181
|
-
console.log('PUSHING', member.stat);
|
|
182
|
-
|
|
183
|
-
stats.push(member.stat);
|
|
184
|
-
}
|
|
185
|
-
|
|
186
|
-
l.unlock();
|
|
187
|
-
}
|
|
188
|
-
|
|
189
|
-
console.log('STATS????', stats);
|
|
190
|
-
if ( stats ) {
|
|
191
|
-
return stats;
|
|
192
|
-
}
|
|
193
|
-
|
|
194
|
-
let l;
|
|
195
|
-
if ( cent ) {
|
|
196
|
-
l = await cent.locks.members.wlock();
|
|
197
|
-
}
|
|
198
|
-
|
|
199
|
-
const entries = await this.delegate.readdir(o);
|
|
200
|
-
if ( ! cent ) {
|
|
201
|
-
cent = this.cacheFS.add_entry(o.uid ? { id: o.uid } : {});
|
|
202
|
-
if ( o.path ) this.cacheFS.assoc_path(o.path, cent.id);
|
|
203
|
-
l = await cent.locks.members.wlock();
|
|
204
|
-
}
|
|
205
|
-
|
|
206
|
-
let cent_ids = [];
|
|
207
|
-
for ( const entry of entries ) {
|
|
208
|
-
let entry_cent = this.cacheFS.get_entry_ei([entry.path, entry.uid]);
|
|
209
|
-
if ( ! entry_cent ) {
|
|
210
|
-
entry_cent = this.cacheFS.add_entry({ id: entry.uid });
|
|
211
|
-
this.cacheFS.assoc_path(entry.path, entry.uid);
|
|
212
|
-
}
|
|
213
|
-
cent_ids.push(entry_cent.id);
|
|
214
|
-
// TODO: update_stat_ is not implemented
|
|
215
|
-
// this.cacheFS.update_stat_(entry_cent, entry, {
|
|
216
|
-
// subdomains: ! o.no_assocs,
|
|
217
|
-
// apps: ! o.no_assocs,
|
|
218
|
-
// thumbnail: ! o.no_thumbs,
|
|
219
|
-
// });
|
|
220
|
-
entry_cent.stat = entry;
|
|
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;
|
|
227
|
-
}
|
|
228
|
-
|
|
229
|
-
cent.members = [];
|
|
230
|
-
for ( const id of cent_ids ) {
|
|
231
|
-
cent.members.push(id);
|
|
232
|
-
}
|
|
233
|
-
cent.members_exp = Date.now() + TTL;
|
|
234
|
-
|
|
235
|
-
l.unlock();
|
|
236
|
-
|
|
237
|
-
console.log('CACHE ENTRY?', cent);
|
|
238
|
-
|
|
239
|
-
return entries;
|
|
240
|
-
},
|
|
241
|
-
},
|
|
242
|
-
};
|
|
243
|
-
}
|
|
@@ -1,40 +0,0 @@
|
|
|
1
|
-
import putility from '@heyputer/putility';
|
|
2
|
-
import { TFilesystem } from './definitions.js';
|
|
3
|
-
|
|
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
|
-
};
|
|
11
|
-
|
|
12
|
-
export class PostMessageFilesystem extends putility.AdvancedBase {
|
|
13
|
-
constructor ({ rpc, messageTarget }) {
|
|
14
|
-
super();
|
|
15
|
-
this.rpc = rpc;
|
|
16
|
-
this.messageTarget = messageTarget;
|
|
17
|
-
}
|
|
18
|
-
static IMPLEMENTS = {
|
|
19
|
-
[TFilesystem]: {
|
|
20
|
-
stat: async function (o) {
|
|
21
|
-
return example;
|
|
22
|
-
},
|
|
23
|
-
readdir: async function (o) {
|
|
24
|
-
const tp = new putility.libs.promise.TeePromise();
|
|
25
|
-
const $callback = this.rpc.registerCallback((result) => {
|
|
26
|
-
tp.resolve(result);
|
|
27
|
-
});
|
|
28
|
-
// return [example];
|
|
29
|
-
this.messageTarget.postMessage({
|
|
30
|
-
$: 'puter-fs',
|
|
31
|
-
$callback,
|
|
32
|
-
op: 'readdir',
|
|
33
|
-
args: o,
|
|
34
|
-
}, '*');
|
|
35
|
-
|
|
36
|
-
return await tp;
|
|
37
|
-
},
|
|
38
|
-
},
|
|
39
|
-
};
|
|
40
|
-
}
|
|
@@ -1,40 +0,0 @@
|
|
|
1
|
-
import putility from '@heyputer/putility';
|
|
2
|
-
|
|
3
|
-
export const TFilesystem = 'TFilesystem';
|
|
4
|
-
|
|
5
|
-
// TODO: UNUSED (eventually putility will support these definitions)
|
|
6
|
-
// This is here so that the idea is not forgotten.
|
|
7
|
-
export const IFilesystem = {
|
|
8
|
-
methods: {
|
|
9
|
-
stat: {
|
|
10
|
-
parameters: {
|
|
11
|
-
path: {
|
|
12
|
-
alias: 'uid',
|
|
13
|
-
},
|
|
14
|
-
},
|
|
15
|
-
},
|
|
16
|
-
},
|
|
17
|
-
|
|
18
|
-
};
|
|
19
|
-
|
|
20
|
-
export class ProxyFilesystem extends putility.AdvancedBase {
|
|
21
|
-
static PROPERTIES = {
|
|
22
|
-
delegate: () => {
|
|
23
|
-
},
|
|
24
|
-
};
|
|
25
|
-
// TODO: constructor implied by properties
|
|
26
|
-
constructor ({ delegate }) {
|
|
27
|
-
super();
|
|
28
|
-
this.delegate = delegate;
|
|
29
|
-
}
|
|
30
|
-
static IMPLEMENTS = {
|
|
31
|
-
[TFilesystem]: {
|
|
32
|
-
stat: async function (o) {
|
|
33
|
-
return this.delegate.stat(o);
|
|
34
|
-
},
|
|
35
|
-
readdir: async function (o) {
|
|
36
|
-
return this.delegate.readdir(o);
|
|
37
|
-
},
|
|
38
|
-
},
|
|
39
|
-
};
|
|
40
|
-
}
|
|
@@ -1,46 +0,0 @@
|
|
|
1
|
-
import putility from '@heyputer/putility';
|
|
2
|
-
|
|
3
|
-
const { TTopics } = putility.traits;
|
|
4
|
-
|
|
5
|
-
/**
|
|
6
|
-
* Manages the auth token and origin used to communicate with
|
|
7
|
-
* Puter's API
|
|
8
|
-
*/
|
|
9
|
-
export class APIAccessService extends putility.concepts.Service {
|
|
10
|
-
static TOPICS = ['update'];
|
|
11
|
-
|
|
12
|
-
static PROPERTIES = {
|
|
13
|
-
auth_token: {
|
|
14
|
-
post_set (v) {
|
|
15
|
-
this.as(TTopics).pub('update');
|
|
16
|
-
},
|
|
17
|
-
},
|
|
18
|
-
api_origin: {
|
|
19
|
-
post_set () {
|
|
20
|
-
this.as(TTopics).pub('update');
|
|
21
|
-
},
|
|
22
|
-
},
|
|
23
|
-
};
|
|
24
|
-
|
|
25
|
-
// TODO: inconsistent! Update all dependents.
|
|
26
|
-
get_api_info () {
|
|
27
|
-
const self = this;
|
|
28
|
-
const o = {};
|
|
29
|
-
[
|
|
30
|
-
['auth_token', 'auth_token'],
|
|
31
|
-
['authToken', 'auth_token'],
|
|
32
|
-
['APIOrigin', 'api_origin'],
|
|
33
|
-
['api_origin', 'api_origin'],
|
|
34
|
-
].forEach(([k1, k2]) => {
|
|
35
|
-
Object.defineProperty(o, k1, {
|
|
36
|
-
get () {
|
|
37
|
-
return self[k2];
|
|
38
|
-
},
|
|
39
|
-
set (v) {
|
|
40
|
-
return self;
|
|
41
|
-
},
|
|
42
|
-
});
|
|
43
|
-
});
|
|
44
|
-
return o;
|
|
45
|
-
}
|
|
46
|
-
}
|
package/src/services/FSRelay.js
DELETED
|
@@ -1,20 +0,0 @@
|
|
|
1
|
-
import putility from '@heyputer/putility';
|
|
2
|
-
|
|
3
|
-
const example = {
|
|
4
|
-
'id': 'f485f1ba-de07-422c-8c4b-c2da057d4a44',
|
|
5
|
-
'uid': 'f485f1ba-de07-422c-8c4b-c2da057d4a44',
|
|
6
|
-
'is_dir': true,
|
|
7
|
-
'immutable': true,
|
|
8
|
-
'name': 'FromParentWindow',
|
|
9
|
-
};
|
|
10
|
-
|
|
11
|
-
export class FSRelayService extends putility.concepts.Service {
|
|
12
|
-
async _init () {
|
|
13
|
-
const services = this._.context.services;
|
|
14
|
-
const util = this._.context.util;
|
|
15
|
-
const svc_xdIncoming = services.get('xd-incoming');
|
|
16
|
-
svc_xdIncoming.register_tagged_listener('puter-fs', event => {
|
|
17
|
-
util.rpc.send(event.source, event.data.$callback, [example]);
|
|
18
|
-
});
|
|
19
|
-
}
|
|
20
|
-
}
|
|
@@ -1,137 +0,0 @@
|
|
|
1
|
-
import putility from '@heyputer/putility';
|
|
2
|
-
import { PuterAPIFilesystem } from '../lib/filesystem/APIFS.js';
|
|
3
|
-
import { CachedFilesystem } from '../lib/filesystem/CacheFS.js';
|
|
4
|
-
import { ProxyFilesystem, TFilesystem } from '../lib/filesystem/definitions.js';
|
|
5
|
-
import { PostMessageFilesystem } from '../lib/filesystem/PostMessageFS.js';
|
|
6
|
-
import io from '../lib/socket.io/socket.io.esm.min.js';
|
|
7
|
-
|
|
8
|
-
export class FilesystemService extends putility.concepts.Service {
|
|
9
|
-
static PROPERTIES = {
|
|
10
|
-
// filesystem:
|
|
11
|
-
};
|
|
12
|
-
|
|
13
|
-
static DEPENDS = ['api-access'];
|
|
14
|
-
static HOOKS = [
|
|
15
|
-
{
|
|
16
|
-
service: 'api-access',
|
|
17
|
-
event: 'update',
|
|
18
|
-
description: `
|
|
19
|
-
re-initialize the socket connection whenever the
|
|
20
|
-
authentication token or API origin is changed.
|
|
21
|
-
`,
|
|
22
|
-
async do () {
|
|
23
|
-
this.initializeSocket();
|
|
24
|
-
},
|
|
25
|
-
},
|
|
26
|
-
];
|
|
27
|
-
|
|
28
|
-
_init () {
|
|
29
|
-
const env = this._.context.env;
|
|
30
|
-
|
|
31
|
-
if ( env === 'app' ) {
|
|
32
|
-
// TODO: uncomment when relay is ready
|
|
33
|
-
// this.init_app_fs_();
|
|
34
|
-
|
|
35
|
-
this.init_top_fs_();
|
|
36
|
-
} else {
|
|
37
|
-
this.init_top_fs_();
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
this.initializeSocket();
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
init_app_fs_ () {
|
|
44
|
-
this.fs_nocache_ = new PostMessageFilesystem({
|
|
45
|
-
messageTarget: globalThis.parent,
|
|
46
|
-
rpc: this._.context.util.rpc,
|
|
47
|
-
}).as(TFilesystem);
|
|
48
|
-
this.filesystem = this.fs_nocache_;
|
|
49
|
-
}
|
|
50
|
-
init_top_fs_ () {
|
|
51
|
-
const api_info = this._.context.services.get('api-access').get_api_info();
|
|
52
|
-
this.fs_nocache_ = new PuterAPIFilesystem({ api_info }).as(TFilesystem);
|
|
53
|
-
this.fs_cache_ = new CachedFilesystem({ delegate: this.fs_nocache_ }).as(TFilesystem);
|
|
54
|
-
// this.filesystem = this.fs_nocache;
|
|
55
|
-
this.fs_proxy_ = new ProxyFilesystem({ delegate: this.fs_nocache_ });
|
|
56
|
-
this.filesystem = this.fs_proxy_.as(TFilesystem);
|
|
57
|
-
}
|
|
58
|
-
|
|
59
|
-
cache_on () {
|
|
60
|
-
this.fs_proxy_.delegate = this.fs_cache_;
|
|
61
|
-
}
|
|
62
|
-
cache_off () {
|
|
63
|
-
this.fs_proxy_.delegate = this.fs_nocache_;
|
|
64
|
-
}
|
|
65
|
-
|
|
66
|
-
async initializeSocket () {
|
|
67
|
-
if ( this.socket ) {
|
|
68
|
-
this.socket.disconnect();
|
|
69
|
-
}
|
|
70
|
-
|
|
71
|
-
const svc_apiAccess = this._.context.services.get('api-access');
|
|
72
|
-
const api_info = svc_apiAccess.get_api_info();
|
|
73
|
-
|
|
74
|
-
if ( api_info.api_origin === undefined ) {
|
|
75
|
-
// This will get called again later with updated information
|
|
76
|
-
return;
|
|
77
|
-
}
|
|
78
|
-
|
|
79
|
-
this.socket = io(api_info.api_origin, {
|
|
80
|
-
auth: { auth_token: api_info.auth_token },
|
|
81
|
-
autoUnref: this._.context.env === 'nodejs',
|
|
82
|
-
});
|
|
83
|
-
|
|
84
|
-
this.bindSocketEvents();
|
|
85
|
-
}
|
|
86
|
-
|
|
87
|
-
bindSocketEvents () {
|
|
88
|
-
this.socket.on('connect', () => {
|
|
89
|
-
if ( puter.debugMode )
|
|
90
|
-
{
|
|
91
|
-
console.log('FileSystem Socket: Connected', this.socket.id);
|
|
92
|
-
}
|
|
93
|
-
});
|
|
94
|
-
|
|
95
|
-
this.socket.on('disconnect', () => {
|
|
96
|
-
if ( puter.debugMode )
|
|
97
|
-
{
|
|
98
|
-
console.log('FileSystem Socket: Disconnected');
|
|
99
|
-
}
|
|
100
|
-
});
|
|
101
|
-
|
|
102
|
-
this.socket.on('reconnect', (attempt) => {
|
|
103
|
-
if ( puter.debugMode )
|
|
104
|
-
{
|
|
105
|
-
console.log('FileSystem Socket: Reconnected', this.socket.id);
|
|
106
|
-
}
|
|
107
|
-
});
|
|
108
|
-
|
|
109
|
-
this.socket.on('reconnect_attempt', (attempt) => {
|
|
110
|
-
if ( puter.debugMode )
|
|
111
|
-
{
|
|
112
|
-
console.log('FileSystem Socket: Reconnection Attemps', attempt);
|
|
113
|
-
}
|
|
114
|
-
});
|
|
115
|
-
|
|
116
|
-
this.socket.on('reconnect_error', (error) => {
|
|
117
|
-
if ( puter.debugMode )
|
|
118
|
-
{
|
|
119
|
-
console.log('FileSystem Socket: Reconnection Error', error);
|
|
120
|
-
}
|
|
121
|
-
});
|
|
122
|
-
|
|
123
|
-
this.socket.on('reconnect_failed', () => {
|
|
124
|
-
if ( puter.debugMode )
|
|
125
|
-
{
|
|
126
|
-
console.log('FileSystem Socket: Reconnection Failed');
|
|
127
|
-
}
|
|
128
|
-
});
|
|
129
|
-
|
|
130
|
-
this.socket.on('error', (error) => {
|
|
131
|
-
if ( puter.debugMode )
|
|
132
|
-
{
|
|
133
|
-
console.error('FileSystem Socket Error:', error);
|
|
134
|
-
}
|
|
135
|
-
});
|
|
136
|
-
}
|
|
137
|
-
}
|
|
@@ -1,20 +0,0 @@
|
|
|
1
|
-
import putility from '@heyputer/putility';
|
|
2
|
-
|
|
3
|
-
/**
|
|
4
|
-
* Runs commands on the special `globalThis.when_puter_happens` global, for
|
|
5
|
-
* situations where the `puter` global doesn't exist soon enough.
|
|
6
|
-
*/
|
|
7
|
-
export class NoPuterYetService extends putility.concepts.Service {
|
|
8
|
-
_init () {
|
|
9
|
-
if ( ! globalThis.when_puter_happens ) return;
|
|
10
|
-
if ( puter && puter.env !== 'gui' ) return;
|
|
11
|
-
|
|
12
|
-
if ( ! Array.isArray(globalThis.when_puter_happens) ) {
|
|
13
|
-
globalThis.when_puter_happens = [globalThis.when_puter_happens];
|
|
14
|
-
}
|
|
15
|
-
|
|
16
|
-
for ( const fn of globalThis.when_puter_happens ) {
|
|
17
|
-
fn({ context: this._.context });
|
|
18
|
-
}
|
|
19
|
-
}
|
|
20
|
-
}
|
|
@@ -1,44 +0,0 @@
|
|
|
1
|
-
import putility from '@heyputer/putility';
|
|
2
|
-
|
|
3
|
-
const TeePromise = putility.libs.promise.TeePromise;
|
|
4
|
-
|
|
5
|
-
/**
|
|
6
|
-
* Manages message events from the window object.
|
|
7
|
-
*/
|
|
8
|
-
export class XDIncomingService extends putility.concepts.Service {
|
|
9
|
-
_construct () {
|
|
10
|
-
this.filter_listeners_ = [];
|
|
11
|
-
this.tagged_listeners_ = {};
|
|
12
|
-
}
|
|
13
|
-
|
|
14
|
-
_init () {
|
|
15
|
-
globalThis.addEventListener('message', async event => {
|
|
16
|
-
for ( const fn of this.filter_listeners_ ) {
|
|
17
|
-
const tp = new TeePromise();
|
|
18
|
-
fn(event, tp);
|
|
19
|
-
if ( await tp ) return;
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
const data = event.data;
|
|
23
|
-
if ( ! data ) return;
|
|
24
|
-
const tag = data.$;
|
|
25
|
-
if ( ! tag ) return;
|
|
26
|
-
if ( ! this.tagged_listeners_[tag] ) return;
|
|
27
|
-
|
|
28
|
-
for ( const fn of this.tagged_listeners_[tag] ) {
|
|
29
|
-
fn({ data, source: event.source });
|
|
30
|
-
}
|
|
31
|
-
});
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
register_filter_listener (fn) {
|
|
35
|
-
this.filter_listeners_.push(fn);
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
register_tagged_listener (tag, fn) {
|
|
39
|
-
if ( ! this.tagged_listeners_[tag] ) {
|
|
40
|
-
this.tagged_listeners_[tag] = [];
|
|
41
|
-
}
|
|
42
|
-
this.tagged_listeners_[tag].push(fn);
|
|
43
|
-
}
|
|
44
|
-
}
|