@leofcoin/peernet 0.17.1 → 0.18.0

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 (39) hide show
  1. package/exports/browser/client-13d9b3de.js +645 -0
  2. package/exports/browser/{index-019272d8.js → index-19803d3b.js} +38 -923
  3. package/exports/browser/{index-3a25de4d.js → index-73b8d9b9.js} +3 -1
  4. package/exports/browser/{messages-4850566c.js → messages-bb950ed7.js} +51 -130
  5. package/exports/browser/peernet-24ed8563.js +2978 -0
  6. package/exports/browser/peernet.js +1 -1
  7. package/exports/{messages-796c4d5c.js → messages-d8852e16.js} +50 -129
  8. package/exports/peernet.js +1 -1
  9. package/package.json +2 -2
  10. package/src/messages/chat.js +0 -3
  11. package/src/messages/data-response.js +0 -3
  12. package/src/messages/data.js +0 -3
  13. package/src/messages/dht-response.js +0 -3
  14. package/src/messages/dht.js +0 -6
  15. package/src/messages/file-link.js +18 -0
  16. package/src/messages/file.js +0 -3
  17. package/src/messages/peer-response.js +0 -3
  18. package/src/messages/peer.js +0 -4
  19. package/src/messages/peernet.js +0 -3
  20. package/src/messages/ps.js +0 -4
  21. package/src/messages/request.js +0 -3
  22. package/src/messages/response.js +0 -3
  23. package/src/proto/chat-message.proto.js +6 -7
  24. package/src/proto/data-response.proto.js +3 -6
  25. package/src/proto/data.proto.js +3 -6
  26. package/src/proto/dht-response.proto.js +3 -6
  27. package/src/proto/dht.proto.js +3 -6
  28. package/src/proto/file-link.proto.js +5 -0
  29. package/src/proto/file.proto.js +4 -13
  30. package/src/proto/peer-response.proto.js +2 -5
  31. package/src/proto/peer.proto.js +2 -5
  32. package/src/proto/peernet.proto.js +7 -9
  33. package/src/proto/ps.proto.js +4 -6
  34. package/src/proto/request.proto.js +2 -5
  35. package/src/proto/response.proto.js +2 -5
  36. package/test.js +2 -2
  37. package/test2.js +1 -1
  38. package/exports/browser/client-29660363.js +0 -690
  39. package/exports/browser/peernet-379769d5.js +0 -2896
@@ -1,690 +0,0 @@
1
- import { L as LittlePubSub } from './peernet-379769d5.js';
2
- import './value-40634404.js';
3
-
4
- var clientApi = _pubsub => {
5
-
6
- const subscribe = (topic, cb) => {
7
- _pubsub.subscribe(topic, cb);
8
- };
9
-
10
- const unsubscribe = (topic, cb) => {
11
- _pubsub.unsubscribe(topic, cb);
12
- };
13
-
14
- const publish = (topic, value) => {
15
- _pubsub.publish(topic, value);
16
- };
17
-
18
- const connectionState = (state) => {
19
- switch (state) {
20
- case 0:
21
- return 'connecting'
22
- case 1:
23
- return 'open'
24
- case 2:
25
- return 'closing'
26
- case 3:
27
- return 'closed'
28
- }
29
- };
30
- /**
31
- * @param {string} type
32
- * @param {string} name
33
- * @param {object} params
34
- */
35
- const request = (client, request) => {
36
- return new Promise((resolve, reject) => {
37
-
38
- const state = connectionState(client.readyState);
39
- if (state !== 'open') return reject(`coudn't send request to ${client.id}, no open connection found.`)
40
-
41
- request.id = Math.random().toString(36).slice(-12);
42
- const handler = result => {
43
- if (result && result.error) return reject(result.error)
44
- resolve({result, id: request.id, handler});
45
- unsubscribe(request.id, handler);
46
- };
47
- subscribe(request.id, handler);
48
- send(client, request);
49
- });
50
- };
51
-
52
- const send = async (client, request) => {
53
- return client.send(JSON.stringify(request))
54
- };
55
-
56
- const pubsub = client => {
57
- return {
58
- publish: (topic = 'pubsub', value) => {
59
- return send(client, {url: 'pubsub', params: { topic, value }})
60
- },
61
- subscribe: (topic = 'pubsub', cb) => {
62
- subscribe(topic, cb);
63
- return send(client, {url: 'pubsub', params: { topic, subscribe: true }})
64
- },
65
- unsubscribe: (topic = 'pubsub', cb) => {
66
- unsubscribe(topic, cb);
67
- return send(client, {url: 'pubsub', params: { topic, unsubscribe: true }})
68
- },
69
- subscribers: _pubsub.subscribers
70
- }
71
- };
72
-
73
- const server = (client) => {
74
- return {
75
- uptime: async () => {
76
- try {
77
- const { result, id, handler } = await request(client, {url: 'uptime'});
78
- unsubscribe(id, handler);
79
- return result
80
- } catch (e) {
81
- throw e
82
- }
83
- },
84
- ping: async () => {
85
- try {
86
- const now = new Date().getTime();
87
- const { result, id, handler } = await request(client, {url: 'ping'});
88
- unsubscribe(id, handler);
89
- return (Number(result) - now)
90
- } catch (e) {
91
- throw e
92
- }
93
- }
94
- }
95
- };
96
-
97
- const peernet = (client) => {
98
- return {
99
- join: async (params) => {
100
- try {
101
- params.join = true;
102
- const requested = { url: 'peernet', params };
103
- const { result, id, handler } = await request(client, requested);
104
- unsubscribe(id, handler);
105
- return result
106
- } catch (e) {
107
- throw e
108
- }
109
- },
110
- leave: async (params) => {
111
- try {
112
- params.join = false;
113
- const requested = { url: 'peernet', params };
114
- const { result, id, handler } = await request(client, requested);
115
- unsubscribe(id, handler);
116
- return result
117
- } catch (e) {
118
- throw e
119
- }
120
- }
121
- }
122
- };
123
-
124
- return { send, request, pubsub, server, subscribe, unsubscribe, publish, peernet, connectionState }
125
- };
126
-
127
- if (!globalThis.PubSub) globalThis.PubSub = LittlePubSub;
128
- if (!globalThis.pubsub) globalThis.pubsub = new LittlePubSub({verbose: false});
129
-
130
- const socketRequestClient = (url, protocols = 'echo-protocol', options = { retry: true, timeout: 10_000, times: 10 }) => {
131
- let { retry, timeout, times } = options;
132
- if (retry === undefined) retry = true;
133
- if (timeout === undefined) timeout = 10_000;
134
- if (times === undefined) times = 10;
135
-
136
- const api = clientApi(pubsub);
137
-
138
- let tries = 0;
139
-
140
- const onerror = error => {
141
- if (pubsub.subscribers['error']) {
142
- pubsub.publish('error', error);
143
- } else {
144
- console.error(error);
145
- }
146
- };
147
-
148
- const onmessage = message => {
149
- const {value, url, status, id} = JSON.parse(message.data.toString());
150
- const publisher = id ? id : url;
151
- if (status === 200) {
152
- pubsub.publish(publisher, value);
153
- } else {
154
- pubsub.publish(publisher, {error: value});
155
- }
156
- };
157
-
158
- const clientConnection = client => {
159
- const startTime = new Date().getTime();
160
- return {
161
- client,
162
- request: async req => {
163
- const { result, id, handler } = await api.request(client, req);
164
- pubsub.unsubscribe(id, handler);
165
- return result
166
- },
167
- send: req => api.send(client, req),
168
- subscribe: api.subscribe,
169
- unsubscribe: api.unsubscribe,
170
- subscribers: api.subscribers,
171
- publish: api.publish,
172
- pubsub: api.pubsub(client),
173
- uptime: () => {
174
- const now = new Date().getTime();
175
- return (now - startTime)
176
- },
177
- peernet: api.peernet(client),
178
- server: api.server(client),
179
- connectionState: () => api.connectionState(client.readyState),
180
- close: exit => {
181
- // client.onclose = message => {
182
- // if (exit) process.exit()
183
- // }
184
- client.close();
185
- }
186
- }
187
- };
188
-
189
- return new Promise(async (resolve, reject) => {
190
- const init = async () => {
191
- let ws;
192
- if (typeof process === 'object' && !globalThis.WebSocket) {
193
- ws = (await import('./browser-2f0b2829.js').then(function (n) { return n.b; })).default;
194
- ws = ws.w3cwebsocket;
195
- } else {
196
- ws = WebSocket;
197
- }
198
- const client = new ws(url, protocols);
199
-
200
- client.onmessage = onmessage;
201
- client.onerror = onerror;
202
-
203
- client.onopen = () => {
204
- tries = 0;
205
- resolve(clientConnection(client));
206
- };
207
- client.onclose = message => {
208
- tries++;
209
- if (!retry) return reject(options)
210
- if (tries > times) {
211
- console.log(`${protocols} Client Closed`);
212
- console.error(`could not connect to - ${url}/`);
213
- return resolve(clientConnection(client))
214
- }
215
- if (message.code === 1006) {
216
- console.log(`Retrying in ${timeout} ms`);
217
- setTimeout(() => {
218
- return init();
219
- }, timeout);
220
- }
221
- };
222
- };
223
- return init();
224
- });
225
- };
226
-
227
- class Peer {
228
- #connection
229
- #connected = false
230
- #messageQue = []
231
- #chunksQue = {}
232
- #channel
233
- #peerId
234
- #channelName
235
- #chunkSize = 16 * 1024 // 16384
236
- #queRunning = false
237
- #MAX_BUFFERED_AMOUNT = 16 * 1024 * 1024
238
-
239
- get connection() {
240
- return this.#connection
241
- }
242
-
243
- get connected() {
244
- return this.#connected
245
- }
246
-
247
- get readyState() {
248
- return this.#channel?.readyState
249
- }
250
-
251
- /**
252
- * @params {Object} options
253
- * @params {string} options.channelName - this peerid : otherpeer id
254
- */
255
- constructor(options = {}) {
256
- this._in = this._in.bind(this);
257
- this.offerOptions = options.offerOptions;
258
- this.initiator = options.initiator;
259
- this.streams = options.streams;
260
- this.socketClient = options.socketClient;
261
- this.id = options.id;
262
- this.to = options.to;
263
- this.bw = {
264
- up: 0,
265
- down: 0
266
- };
267
-
268
- this.#channelName = options.channelName;
269
-
270
- this.#peerId = options.peerId;
271
- this.options = options;
272
- return this.#init()
273
- }
274
-
275
- get peerId() {
276
- return this.#peerId
277
- }
278
-
279
- set socketClient(value) {
280
- // this.socketClient?.pubsub.unsubscribe('signal', this._in)
281
- this._socketClient = value;
282
- this._socketClient.pubsub.subscribe('signal', this._in);
283
- }
284
-
285
- get socketClient() {
286
- return this._socketClient
287
- }
288
-
289
- splitMessage(message) {
290
- const chunks = [];
291
- message = pako.deflate(message);
292
- const size = message.byteLength || message.length;
293
- let offset = 0;
294
- return new Promise((resolve, reject) => {
295
- const splitMessage = () => {
296
- const chunk = message.slice(offset, offset + this.#chunkSize > size ? size : offset + this.#chunkSize);
297
- offset += this.#chunkSize;
298
- chunks.push(chunk);
299
- if (offset < size) return splitMessage()
300
- else resolve({chunks, size});
301
- };
302
-
303
- splitMessage();
304
- })
305
- }
306
-
307
- async #runQue() {
308
- this.#queRunning = true;
309
- if (this.#messageQue.length > 0 && this.#channel?.bufferedAmount + this.#messageQue[0]?.length < this.#MAX_BUFFERED_AMOUNT) {
310
- const message = this.#messageQue.shift();
311
-
312
- switch (this.#channel?.readyState) {
313
- case 'open':
314
- await this.#channel.send(message);
315
- if (this.#messageQue.length > 0) return this.#runQue()
316
- else this.#queRunning = false;
317
- break;
318
- case 'closed':
319
- case 'closing':
320
- this.#messageQue = [];
321
- this.#queRunning = false;
322
- debug('channel already closed, this usually means a bad implementation, try checking the readyState or check if the peer is connected before sending');
323
- break;
324
- case undefined:
325
- this.#messageQue = [];
326
- this.#queRunning = false;
327
- debug(`trying to send before a channel is created`);
328
- break;
329
- }
330
-
331
-
332
- } else {
333
- return setTimeout(() => this.#runQue(), 50)
334
- }
335
- }
336
-
337
- #trySend({ size, id, chunks }) {
338
- let offset = 0;
339
-
340
- for (const chunk of chunks) {
341
- const start = offset;
342
- const end = offset + chunk.length;
343
-
344
- const message = new TextEncoder().encode(JSON.stringify({ size, id, chunk, start, end }));
345
- this.#messageQue.push(message);
346
- }
347
-
348
- if (!this.queRunning) return this.#runQue()
349
- }
350
-
351
- async send(message, id) {
352
- const { chunks, size } = await this.splitMessage(message);
353
- return this.#trySend({ size, id, chunks })
354
- }
355
-
356
- request(data) {
357
- return new Promise((resolve, reject) => {
358
- const id = Math.random().toString(36).slice(-12);
359
-
360
- const _onData = message => {
361
- if (message.id === id) {
362
- resolve(message.data);
363
- pubsub.unsubscribe(`peer:data`, _onData);
364
- }
365
- };
366
-
367
- pubsub.subscribe(`peer:data`, _onData);
368
-
369
- // cleanup subscriptions
370
- // setTimeout(() => {
371
- // pubsub.unsubscribe(`peer:data-request-${id}`, _onData)
372
- // }, 5000);
373
-
374
- this.send(data, id);
375
- })
376
- }
377
-
378
- async #init() {
379
- try {
380
-
381
- if (!globalThis.pako) {
382
- const importee = await import(/* webpackChunkName: "pako" */ './pako.esm-aa674ebf.js');
383
- globalThis.pako = importee.default;
384
- }
385
-
386
- const iceServers = [{
387
- urls: 'stun:stun.l.google.com:19302' // Google's public STUN server
388
- }, {
389
- urls: "stun:openrelay.metered.ca:80",
390
- }, {
391
- urls: "turn:openrelay.metered.ca:443",
392
- username: "openrelayproject",
393
- credential: "openrelayproject",
394
- }, {
395
- urls: "turn:openrelay.metered.ca:443?transport=tcp",
396
- username: "openrelayproject",
397
- credential: "openrelayproject",
398
- }];
399
-
400
- this.#connection = new wrtc.RTCPeerConnection({iceServers});
401
-
402
- this.#connection.onicecandidate = ({ candidate }) => {
403
- if (candidate) {
404
- this.address = candidate.address;
405
- this.port = candidate.port;
406
- this.protocol = candidate.protocol;
407
- this.ipFamily = this.address.includes('::') ? 'ipv6': 'ipv4';
408
- this._sendMessage({candidate});
409
- }
410
- };
411
- // if (this.initiator) this.#connection.onnegotiationneeded = () => {
412
- // console.log('create offer');
413
- this.#connection.ondatachannel = (message) => {
414
- message.channel.onopen = () => {
415
- this.#connected = true;
416
- // debug(`peer:connected ${this}`)
417
- pubsub.publish('peer:connected', this);
418
- };
419
- message.channel.onclose = () => this.close.bind(this);
420
-
421
- message.channel.onmessage = (message) => {
422
- this._handleMessage(this.id, message);
423
- };
424
- this.#channel = message.channel;
425
- };
426
- if (this.initiator) {
427
-
428
- this.#channel = this.#connection.createDataChannel('messageChannel');
429
- this.#channel.onopen = () => {
430
- this.#connected = true;
431
- pubsub.publish('peer:connected', this);
432
- // this.#channel.send('hi')
433
- };
434
- this.#channel.onclose = () => this.close.bind(this);
435
-
436
- this.#channel.onmessage = (message) => {
437
- this._handleMessage(this.peerId, message);
438
- };
439
-
440
- const offer = await this.#connection.createOffer();
441
- await this.#connection.setLocalDescription(offer);
442
-
443
- this._sendMessage({'sdp': this.#connection.localDescription});
444
- }
445
- } catch (e) {
446
- console.log(e);
447
- }
448
-
449
- return this
450
- }
451
-
452
- _handleMessage(peerId, message) {
453
- // debug(`incoming message from ${peerId}`)
454
-
455
- message = JSON.parse(new TextDecoder().decode(message.data));
456
- // allow sharding (multiple peers share data)
457
- pubsub.publish('peernet:shard', message);
458
- const { id } = message;
459
-
460
- if (!this.#chunksQue[id]) this.#chunksQue[id] = [];
461
-
462
- if (message.size > this.#chunksQue[id].length || message.size === this.#chunksQue[id].length) {
463
- for (const value of Object.values(message.chunk)) {
464
- this.#chunksQue[id].push(value);
465
- }
466
- }
467
-
468
- if (message.size === this.#chunksQue[id].length) {
469
- let data = new Uint8Array(Object.values(this.#chunksQue[id]));
470
- delete this.#chunksQue[id];
471
- data = pako.inflate(data);
472
- pubsub.publish('peer:data', { id, data, from: this.peerId });
473
- }
474
- this.bw.down += message.byteLength || message.length;
475
- }
476
-
477
- _sendMessage(message) {
478
- this.socketClient.send({url: 'signal', params: {
479
- to: this.to,
480
- from: this.id,
481
- channelName: this.options.channelName,
482
- ...message
483
- }});
484
- }
485
-
486
- async _in(message, data) {
487
- // message = JSON.parse(message);
488
- if (!this.#connection || message.to !== this.id || message.from !== this.#peerId) return
489
- // if (data.videocall) return this._startStream(true, false); // start video and audio stream
490
- // if (data.call) return this._startStream(true, true); // start audio stream
491
- if (this.#connection?.signalinState === 'stable' && this.#connection?.remoteDescription !== null && this.#connection?.localDescription !== null) return
492
-
493
-
494
- if (message.candidate) {
495
- // debug(`incoming candidate ${this.#channelName}`)
496
- // debug(message.candidate.candidate)
497
- this.remoteAddress = message.candidate.address;
498
- this.remotePort = message.candidate.port;
499
- this.remoteProtocol = message.candidate.protocol;
500
- this.remoteIpFamily = this.remoteAddress?.includes('::') ? 'ipv6': 'ipv4';
501
- return this.#connection.addIceCandidate(new wrtc.RTCIceCandidate(message.candidate));
502
- }
503
- try {
504
- if (message.sdp) {
505
- if (message.sdp.type === 'offer') {
506
- // debug(`incoming offer ${this.#channelName}`)
507
- await this.#connection.setRemoteDescription(new wrtc.RTCSessionDescription(message.sdp));
508
- const answer = await this.#connection.createAnswer();
509
- await this.#connection.setLocalDescription(answer);
510
- this._sendMessage({'sdp': this.#connection.localDescription});
511
- }
512
- if (message.sdp.type === 'answer') {
513
- // debug(`incoming answer ${this.#channelName}`)
514
- await this.#connection.setRemoteDescription(new wrtc.RTCSessionDescription(message.sdp));
515
- }
516
- }
517
- } catch (e) {
518
- console.log(e);
519
- }
520
- }
521
-
522
- close() {
523
- // debug(`closing ${this.peerId}`)
524
- this.#connected = false;
525
- this.#channel?.close();
526
- this.#connection?.close();
527
-
528
- this.socketClient.pubsub.unsubscribe('signal', this._in);
529
- }
530
- }
531
-
532
- class Client {
533
- #peerConnection
534
- #connections = {}
535
- #stars = {}
536
-
537
- get connections() {
538
- return { ...this.#connections }
539
- }
540
-
541
- get peers() {
542
- return Object.entries(this.#connections)
543
- }
544
-
545
- constructor(id, networkVersion = 'peach', stars = ['wss://peach.leofcoin.org']) {
546
- this.id = id || Math.random().toString(36).slice(-12);
547
- this.peerJoined = this.peerJoined.bind(this);
548
- this.peerLeft = this.peerLeft.bind(this);
549
- this.starLeft = this.starLeft.bind(this);
550
- this.starJoined = this.starJoined.bind(this);
551
- this.networkVersion = networkVersion;
552
-
553
- this._init(stars);
554
- }
555
-
556
- async _init(stars = []) {
557
- this.starsConfig = stars;
558
- // reconnectJob()
559
-
560
- if (!globalThis.RTCPeerConnection) globalThis.wrtc = await import(/* webpackChunkName: "wrtc" */ './browser-3c1d0477.js').then(function (n) { return n.b; });
561
- else globalThis.wrtc = {
562
- RTCPeerConnection,
563
- RTCSessionDescription,
564
- RTCIceCandidate
565
- };
566
-
567
- for (const star of stars) {
568
- try {
569
- this.socketClient = await socketRequestClient(star, this.networkVersion);
570
- const id = await this.socketClient.request({url: 'id', params: {from: this.id}});
571
- this.socketClient.peerId = id;
572
- this.#stars[id] = this.socketClient;
573
- } catch (e) {
574
- if (stars.indexOf(star) === stars.length -1 && !this.socketClient) throw new Error(`No star available to connect`);
575
- }
576
- }
577
- const peers = await this.socketClient.peernet.join({id: this.id});
578
- for (const id of peers) {
579
- if (id !== this.id && !this.#connections[id]) this.#connections[id] = await new Peer({channelName: `${id}:${this.id}`, socketClient: this.socketClient, id: this.id, to: id, peerId: id});
580
- }
581
- this.setupListeners();
582
- }
583
-
584
- setupListeners() {
585
- this.socketClient.subscribe('peer:joined', this.peerJoined);
586
- this.socketClient.subscribe('peer:left', this.peerLeft);
587
- this.socketClient.subscribe('star:left', this.starLeft);
588
- }
589
-
590
- starJoined(id) {
591
- if (this.#stars[id]) {
592
- this.#stars[id].close();
593
- delete this.#stars[id];
594
- }
595
- console.log(`star ${id} joined`);
596
- }
597
-
598
- async starLeft(id) {
599
- if (this.#stars[id]) {
600
- this.#stars[id].close();
601
- delete this.#stars[id];
602
- }
603
- if (this.socketClient?.peerId === id) {
604
-
605
- this.socketClient.unsubscribe('peer:joined', this.peerJoined);
606
- this.socketClient.unsubscribe('peer:left', this.peerLeft);
607
- this.socketClient.unsubscribe('star:left', this.starLeft);
608
- this.socketClient.close();
609
- this.socketClient = undefined;
610
-
611
- for (const star of this.starsConfig) {
612
- try {
613
- this.socketClient = await socketRequestClient(star, this.networkVersion);
614
- if (!this.socketClient?.client?._connection.connected) return
615
- const id = await this.socketClient.request({url: 'id', params: {from: this.id}});
616
- this.#stars[id] = this.socketClient;
617
-
618
- this.socketClient.peerId = id;
619
-
620
- const peers = await this.socketClient.peernet.join({id: this.id});
621
- this.setupListeners();
622
- for (const id of peers) {
623
- if (id !== this.id) {
624
- // close connection
625
- if (this.#connections[id]) {
626
- if (this.#connections[id].connected) await this.#connections[id].close();
627
- delete this.#connections[id];
628
- }
629
- // reconnect
630
- if (id !== this.id) this.#connections[id] = await new Peer({channelName: `${id}:${this.id}`, socketClient: this.socketClient, id: this.id, to: id, peerId: id});
631
- }
632
-
633
- }
634
- } catch (e) {
635
- console.log(e);
636
- if (this.starsConfig.indexOf(star) === this.starsConfig.length -1 && !this.socketClient) throw new Error(`No star available to connect`);
637
- }
638
- }
639
- }
640
- debug(`star ${id} left`);
641
- }
642
-
643
- peerLeft(peer) {
644
- const id = peer.peerId || peer;
645
- if (this.#connections[id]) {
646
- this.#connections[id].close();
647
- delete this.#connections[id];
648
- }
649
- debug(`peer ${id} left`);
650
- }
651
-
652
- async peerJoined(peer, signal) {
653
- const id = peer.peerId || peer;
654
- if (this.#connections[id]) {
655
- if (this.#connections[id].connected) this.#connections[id].close();
656
- delete this.#connections[id];
657
- }
658
- // RTCPeerConnection
659
- this.#connections[id] = await new Peer({initiator: true, channelName: `${this.id}:${id}`, socketClient: this.socketClient, id: this.id, to: id, peerId: id});
660
- debug(`peer ${id} joined`);
661
- }
662
-
663
- removePeer(peer) {
664
- const id = peer.peerId || peer;
665
- if (this.#connections[id]) {
666
- this.#connections[id].connected && this.#connections[id].close();
667
- delete this.#connections[id];
668
- }
669
- debug(`peer ${id} removed`);
670
- }
671
-
672
- async close() {
673
-
674
- this.socketClient.unsubscribe('peer:joined', this.peerJoined);
675
- this.socketClient.unsubscribe('peer:left', this.peerLeft);
676
- this.socketClient.unsubscribe('star:left', this.starLeft);
677
-
678
- const promises = [
679
- Object.values(this.#connections).map(connection => connection.close()),
680
- Object.values(this.#stars).map(connection => connection.close()),
681
- this.socketClient.close()
682
- ];
683
-
684
- return Promise.allSettled(promises)
685
-
686
- }
687
-
688
- }
689
-
690
- export { Client as default };