@leofcoin/peernet 0.12.1 → 0.13.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.
@@ -0,0 +1,836 @@
1
+ (self["webpackChunk_leofcoin_peernet"] = self["webpackChunk_leofcoin_peernet"] || []).push([[629],{
2
+
3
+ /***/ 96:
4
+ /***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) {
5
+
6
+ // ESM COMPAT FLAG
7
+ __webpack_require__.r(__webpack_exports__);
8
+
9
+ // EXPORTS
10
+ __webpack_require__.d(__webpack_exports__, {
11
+ "default": function() { return /* binding */ Client; }
12
+ });
13
+
14
+ ;// CONCATENATED MODULE: ./node_modules/socket-request-client/dist/es/index.js
15
+ /* provided dependency */ var process = __webpack_require__(4406);
16
+ /* socket-request-client version 1.6.3 */
17
+ const ENVIRONMENT = {version: '1.6.3', production: true};
18
+
19
+ class LittlePubSub {
20
+ constructor(verbose = true) {
21
+ this.subscribers = {};
22
+ this.verbose = verbose;
23
+ }
24
+ subscribe(event, handler, context) {
25
+ if (typeof context === 'undefined') {
26
+ context = handler;
27
+ }
28
+ this.subscribers[event] = this.subscribers[event] || { handlers: [], value: null};
29
+ this.subscribers[event].handlers.push(handler.bind(context));
30
+ }
31
+ unsubscribe(event, handler, context) {
32
+ if (typeof context === 'undefined') {
33
+ context = handler;
34
+ }
35
+ if (this.subscribers[event]) {
36
+ const index = this.subscribers[event].handlers.indexOf(handler.bind(context));
37
+ this.subscribers[event].handlers.splice(index);
38
+ if (this.subscribers[event].handlers.length === 0) delete this.subscribers[event];
39
+ }
40
+ }
41
+ publish(event, change) {
42
+ if (this.subscribers[event]) {
43
+ if (this.verbose || this.subscribers[event].value !== change) {
44
+ this.subscribers[event].value = change;
45
+ this.subscribers[event].handlers.forEach(handler => {
46
+ handler(change, this.subscribers[event].value);
47
+ });
48
+ }
49
+ }
50
+ }
51
+ }
52
+
53
+ var clientApi = _pubsub => {
54
+ const subscribe = (topic, cb) => {
55
+ _pubsub.subscribe(topic, cb);
56
+ };
57
+ const unsubscribe = (topic, cb) => {
58
+ _pubsub.unsubscribe(topic, cb);
59
+ };
60
+ const publish = (topic, value) => {
61
+ _pubsub.publish(topic, value);
62
+ };
63
+ const _connectionState = (state) => {
64
+ switch (state) {
65
+ case 0:
66
+ return 'connecting'
67
+ case 1:
68
+ return 'open'
69
+ case 2:
70
+ return 'closing'
71
+ case 3:
72
+ return 'closed'
73
+ }
74
+ };
75
+ const request = (client, request) => {
76
+ return new Promise((resolve, reject) => {
77
+ const state = _connectionState(client.readyState);
78
+ if (state !== 'open') return reject(`coudn't send request to ${client.id}, no open connection found.`)
79
+ request.id = Math.random().toString(36).slice(-12);
80
+ const handler = result => {
81
+ if (result && result.error) return reject(result.error)
82
+ resolve({result, id: request.id, handler});
83
+ unsubscribe(request.id, handler);
84
+ };
85
+ subscribe(request.id, handler);
86
+ send(client, request);
87
+ });
88
+ };
89
+ const send = async (client, request) => {
90
+ return client.send(JSON.stringify(request))
91
+ };
92
+ const pubsub = client => {
93
+ return {
94
+ publish: (topic = 'pubsub', value) => {
95
+ return send(client, {url: 'pubsub', params: { topic, value }})
96
+ },
97
+ subscribe: (topic = 'pubsub', cb) => {
98
+ subscribe(topic, cb);
99
+ return send(client, {url: 'pubsub', params: { topic, subscribe: true }})
100
+ },
101
+ unsubscribe: (topic = 'pubsub', cb) => {
102
+ unsubscribe(topic, cb);
103
+ return send(client, {url: 'pubsub', params: { topic, unsubscribe: true }})
104
+ },
105
+ subscribers: _pubsub.subscribers
106
+ }
107
+ };
108
+ const server = (client) => {
109
+ return {
110
+ uptime: async () => {
111
+ try {
112
+ const { result, id, handler } = await request(client, {url: 'uptime'});
113
+ unsubscribe(id, handler);
114
+ return result
115
+ } catch (e) {
116
+ throw e
117
+ }
118
+ },
119
+ ping: async () => {
120
+ try {
121
+ const now = new Date().getTime();
122
+ const { result, id, handler } = await request(client, {url: 'ping'});
123
+ unsubscribe(id, handler);
124
+ return (Number(result) - now)
125
+ } catch (e) {
126
+ throw e
127
+ }
128
+ }
129
+ }
130
+ };
131
+ const peernet = (client) => {
132
+ return {
133
+ join: async (params) => {
134
+ try {
135
+ params.join = true;
136
+ const requested = { url: 'peernet', params };
137
+ const { result, id, handler } = await request(client, requested);
138
+ unsubscribe(id, handler);
139
+ return result
140
+ } catch (e) {
141
+ throw e
142
+ }
143
+ },
144
+ leave: async (params) => {
145
+ try {
146
+ params.join = false;
147
+ const requested = { url: 'peernet', params };
148
+ const { result, id, handler } = await request(client, requested);
149
+ unsubscribe(id, handler);
150
+ return result
151
+ } catch (e) {
152
+ throw e
153
+ }
154
+ }
155
+ }
156
+ };
157
+ return { send, request, pubsub, server, subscribe, unsubscribe, publish, peernet }
158
+ };
159
+
160
+ if (!globalThis.PubSub) globalThis.PubSub = LittlePubSub;
161
+ if (!globalThis.pubsub) globalThis.pubsub = new LittlePubSub({verbose: false});
162
+ const socketRequestClient = (url, protocols = 'echo-protocol', options = { retry: false }) => {
163
+ const { retry } = options;
164
+ const api = clientApi(pubsub);
165
+ let tries = 0;
166
+ const onerror = error => {
167
+ if (pubsub.subscribers['error']) {
168
+ pubsub.publish('error', error);
169
+ } else {
170
+ console.error(error);
171
+ }
172
+ };
173
+ const onmessage = message => {
174
+ const {value, url, status, id} = JSON.parse(message.data.toString());
175
+ const publisher = id ? id : url;
176
+ if (status === 200) {
177
+ pubsub.publish(publisher, value);
178
+ } else {
179
+ pubsub.publish(publisher, {error: value});
180
+ }
181
+ };
182
+ const clientConnection = client => {
183
+ const startTime = new Date().getTime();
184
+ return {
185
+ client,
186
+ request: async req => {
187
+ const { result, id, handler } = await api.request(client, req);
188
+ pubsub.unsubscribe(id, handler);
189
+ return result
190
+ },
191
+ send: req => api.send(client, req),
192
+ subscribe: api.subscribe,
193
+ unsubscribe: api.unsubscribe,
194
+ subscribers: api.subscribers,
195
+ publish: api.publish,
196
+ pubsub: api.pubsub(client),
197
+ uptime: () => {
198
+ const now = new Date().getTime();
199
+ return (now - startTime)
200
+ },
201
+ peernet: api.peernet(client),
202
+ server: api.server(client),
203
+ close: exit => {
204
+ client.close();
205
+ }
206
+ }
207
+ };
208
+ return new Promise((resolve, reject) => {
209
+ const init = () => {
210
+ let ws;
211
+ if (typeof process === 'object' && !globalThis.WebSocket) {
212
+ ws = (__webpack_require__(5840).w3cwebsocket);
213
+ } else {
214
+ ws = WebSocket;
215
+ }
216
+ const client = new ws(url, protocols);
217
+ client.onmessage = onmessage;
218
+ client.onerror = onerror;
219
+ client.onopen = () => {
220
+ tries = 0;
221
+ resolve(clientConnection(client));
222
+ };
223
+ client.onclose = message => {
224
+ tries++;
225
+ if (!retry) return reject(options)
226
+ if (tries > 5) {
227
+ console.log(`${protocols} Client Closed`);
228
+ console.error(`could not connect to - ${url}/`);
229
+ return resolve(clientConnection(client))
230
+ }
231
+ if (message.code === 1006) {
232
+ console.log('Retrying in 10 seconds');
233
+ setTimeout(() => {
234
+ return init();
235
+ }, retry);
236
+ }
237
+ };
238
+ };
239
+ return init();
240
+ });
241
+ };
242
+
243
+
244
+
245
+ // EXTERNAL MODULE: ./node_modules/@vandeurenglenn/debug/debug.js
246
+ var debug_debug = __webpack_require__(307);
247
+ ;// CONCATENATED MODULE: ./node_modules/@leofcoin/peernet-swarm/src/client/peer.js
248
+
249
+
250
+ class Peer {
251
+ #connection
252
+ #connecting = false
253
+ #connected = false
254
+ #channelReady = false
255
+ #destroying = false
256
+ #destroyed = false
257
+ #isNegotiating = false
258
+ #firstNegotiation = true
259
+ #iceComplete = false
260
+ #remoteTracks = []
261
+ #remoteStreams = []
262
+ #pendingCandidates = []
263
+ #senderMap = new Map()
264
+ #messageQue = []
265
+ #chunksQue = {}
266
+ #iceCompleteTimer
267
+ #channel
268
+ #peerId
269
+ #chunkSize = 16 * 1024 // 16384
270
+ #queRunning = false
271
+ #MAX_BUFFERED_AMOUNT = 16 * 1024 * 1024
272
+
273
+ get connection() {
274
+ return this.#connection
275
+ }
276
+
277
+ get connected() {
278
+ return this.#connected
279
+ }
280
+
281
+ get readyState() {
282
+ return this.channel?.readyState
283
+ }
284
+
285
+ /**
286
+ * @params {Object} options
287
+ * @params {string} options.channelName - this peerid : otherpeer id
288
+ */
289
+ constructor(options = {}) {
290
+ this._in = this._in.bind(this);
291
+ this.offerOptions = options.offerOptions
292
+ this.initiator = options.initiator
293
+ this.streams = options.streams
294
+ this.socketClient = options.socketClient
295
+ this.id = options.id
296
+ this.to = options.to
297
+ this.bw = {
298
+ up: 0,
299
+ down: 0
300
+ }
301
+
302
+ this.channelName = options.channelName
303
+
304
+ this.#peerId = options.peerId
305
+ this.options = options
306
+ return this.#init()
307
+ }
308
+
309
+ get peerId() {
310
+ return this.#peerId
311
+ }
312
+
313
+ set socketClient(value) {
314
+ // this.socketClient?.pubsub.unsubscribe('signal', this._in)
315
+ this._socketClient = value
316
+ this._socketClient.pubsub.subscribe('signal', this._in)
317
+ }
318
+
319
+ get socketClient() {
320
+ return this._socketClient
321
+ }
322
+
323
+ splitMessage(message) {
324
+ const chunks = []
325
+ message = pako.deflate(message)
326
+ const size = message.byteLength || message.length
327
+ let offset = 0
328
+ return new Promise((resolve, reject) => {
329
+ const splitMessage = () => {
330
+ const chunk = message.slice(offset, offset + this.#chunkSize > size ? size : offset + this.#chunkSize)
331
+ offset += this.#chunkSize
332
+ chunks.push(chunk)
333
+ if (offset < size) return splitMessage()
334
+ else resolve({chunks, size})
335
+ }
336
+
337
+ splitMessage()
338
+ })
339
+ }
340
+
341
+ async #runQue() {
342
+ this.#queRunning = true
343
+ if (this.#messageQue.length > 0 && this.channel.bufferedAmount + this.#messageQue[0]?.length < this.#MAX_BUFFERED_AMOUNT) {
344
+ const message = this.#messageQue.shift()
345
+
346
+ switch (this.channel?.readyState) {
347
+ case 'open':
348
+ await this.channel.send(message);
349
+ if (this.#messageQue.length > 0) return this.#runQue()
350
+ else this.#queRunning = false
351
+ break;
352
+ case 'closed':
353
+ case 'closing':
354
+ this.#messageQue = []
355
+ this.#queRunning = false
356
+ debug('channel already closed, this usually means a bad implementation, try checking the readyState or check if the peer is connected before sending');
357
+ break;
358
+ case undefined:
359
+ this.#messageQue = []
360
+ this.#queRunning = false
361
+ debug(`trying to send before a channel is created`);
362
+ break;
363
+ }
364
+
365
+
366
+ } else {
367
+ return setTimeout(() => this.#runQue(), 50)
368
+ }
369
+ }
370
+
371
+ #trySend({ size, id, chunks }) {
372
+ let offset = 0
373
+
374
+ for (const chunk of chunks) {
375
+ const start = offset
376
+ const end = offset + chunk.length
377
+
378
+ const message = new TextEncoder().encode(JSON.stringify({ size, id, chunk, start, end }));
379
+ this.#messageQue.push(message)
380
+ }
381
+
382
+ if (!this.queRunning) return this.#runQue()
383
+ }
384
+
385
+ async send(message, id) {
386
+ const { chunks, size } = await this.splitMessage(message)
387
+ return this.#trySend({ size, id, chunks })
388
+ }
389
+
390
+ request(data) {
391
+ return new Promise((resolve, reject) => {
392
+ const id = Math.random().toString(36).slice(-12)
393
+
394
+ const _onData = message => {
395
+ if (message.id === id) {
396
+ resolve(message.data)
397
+ pubsub.unsubscribe(`peer:data`, _onData)
398
+ }
399
+ }
400
+
401
+ pubsub.subscribe(`peer:data`, _onData)
402
+
403
+ // cleanup subscriptions
404
+ // setTimeout(() => {
405
+ // pubsub.unsubscribe(`peer:data-request-${id}`, _onData)
406
+ // }, 5000);
407
+
408
+ this.send(data, id)
409
+ })
410
+ }
411
+
412
+ async #init() {
413
+ try {
414
+
415
+ if (!globalThis.pako) {
416
+ const importee = await __webpack_require__.e(/* import() | pako */ 682).then(__webpack_require__.bind(__webpack_require__, 7885))
417
+ globalThis.pako = importee.default
418
+ }
419
+
420
+
421
+ const iceServers = [{
422
+ urls: 'stun:stun.l.google.com:19302' // Google's public STUN server
423
+ }, {
424
+ urls: "stun:openrelay.metered.ca:80",
425
+ }, {
426
+ urls: "turn:openrelay.metered.ca:443",
427
+ username: "openrelayproject",
428
+ credential: "openrelayproject",
429
+ }, {
430
+ urls: "turn:openrelay.metered.ca:443?transport=tcp",
431
+ username: "openrelayproject",
432
+ credential: "openrelayproject",
433
+ }]
434
+
435
+ this.#connection = new wrtc.RTCPeerConnection({iceServers});
436
+
437
+ this.#connection.onicecandidate = ({ candidate }) => {
438
+ if (candidate) {
439
+ this.address = candidate.address
440
+ this.port = candidate.port
441
+ this.protocol = candidate.protocol
442
+ this.ipFamily = this.address.includes('::') ? 'ipv6': 'ipv4'
443
+ this._sendMessage({candidate})
444
+ }
445
+ }
446
+ // if (this.initiator) this.#connection.onnegotiationneeded = () => {
447
+ // console.log('create offer');
448
+ this.#connection.ondatachannel = (message) => {
449
+ message.channel.onopen = () => {
450
+ this.#connected = true
451
+ pubsub.publish('peer:connected', this)
452
+ }
453
+ message.channel.onclose = () => this.close.bind(this)
454
+
455
+ message.channel.onmessage = (message) => {
456
+ this._handleMessage(this.id, message)
457
+ }
458
+ this.channel = message.channel
459
+ }
460
+ if (this.initiator) {
461
+
462
+ this.channel = this.#connection.createDataChannel('messageChannel')
463
+ this.channel.onopen = () => {
464
+ this.#connected = true
465
+ pubsub.publish('peer:connected', this)
466
+ // this.channel.send('hi')
467
+ }
468
+ this.channel.onclose = () => this.close.bind(this)
469
+
470
+ this.channel.onmessage = (message) => {
471
+ this._handleMessage(this.peerId, message)
472
+ }
473
+
474
+ const offer = await this.#connection.createOffer()
475
+ await this.#connection.setLocalDescription(offer)
476
+
477
+ this._sendMessage({'sdp': this.#connection.localDescription})
478
+ }
479
+ } catch (e) {
480
+ console.log(e);
481
+ }
482
+
483
+ return this
484
+ }
485
+
486
+ _handleMessage(peerId, message) {
487
+ debug(`incoming message from ${peerId}`)
488
+
489
+ message = JSON.parse(new TextDecoder().decode(message.data))
490
+ // allow sharding (multiple peers share data)
491
+ pubsub.publish('peernet:shard', message)
492
+ const { id } = message
493
+
494
+ if (!this.#chunksQue[id]) this.#chunksQue[id] = []
495
+
496
+ if (message.size > this.#chunksQue[id].length || message.size === this.#chunksQue[id].length) {
497
+ for (const value of Object.values(message.chunk)) {
498
+ this.#chunksQue[id].push(value)
499
+ }
500
+ }
501
+
502
+ if (message.size === this.#chunksQue[id].length) {
503
+ let data = new Uint8Array(Object.values(this.#chunksQue[id]))
504
+ delete this.#chunksQue[id]
505
+ data = pako.inflate(data)
506
+ pubsub.publish('peer:data', { id, data })
507
+ }
508
+ this.bw.down += message.byteLength || message.length
509
+ }
510
+
511
+ _sendMessage(message) {
512
+ this.socketClient.send({url: 'signal', params: {
513
+ to: this.to,
514
+ from: this.id,
515
+ channelName: this.options.channelName,
516
+ ...message
517
+ }})
518
+ }
519
+
520
+ async _in(message, data) {
521
+ // message = JSON.parse(message);
522
+ if (message.to !== this.id) return
523
+ // if (data.videocall) return this._startStream(true, false); // start video and audio stream
524
+ // if (data.call) return this._startStream(true, true); // start audio stream
525
+ if (message.candidate) {
526
+ debug(`incoming candidate ${this.channelName}`)
527
+ debug(message.candidate.candidate)
528
+ this.remoteAddress = message.candidate.address
529
+ this.remotePort = message.candidate.port
530
+ this.remoteProtocol = message.candidate.protocol
531
+ this.remoteIpFamily = this.remoteAddress?.includes('::') ? 'ipv6': 'ipv4'
532
+ return this.#connection.addIceCandidate(new wrtc.RTCIceCandidate(message.candidate));
533
+ }
534
+ try {
535
+ if (message.sdp) {
536
+ if (message.sdp.type === 'offer') {
537
+ debug(`incoming offer ${this.channelName}`)
538
+ await this.#connection.setRemoteDescription(new wrtc.RTCSessionDescription(message.sdp))
539
+ const answer = await this.#connection.createAnswer();
540
+ await this.#connection.setLocalDescription(answer)
541
+ this._sendMessage({'sdp': this.#connection.localDescription})
542
+ }
543
+ if (message.sdp.type === 'answer') {
544
+ debug(`incoming answer ${this.channelName}`)
545
+ await this.#connection.setRemoteDescription(new wrtc.RTCSessionDescription(message.sdp))
546
+ }
547
+ }
548
+ } catch (e) {
549
+ console.log(e);
550
+ }
551
+ }
552
+
553
+ close() {
554
+ debug(`closing ${this.peerId}`)
555
+ this.#connected = false
556
+ this.channel?.close()
557
+ this.#connection?.close()
558
+
559
+ this.socketClient.pubsub.unsubscribe('signal', this._in)
560
+ }
561
+ }
562
+
563
+ ;// CONCATENATED MODULE: ./node_modules/@leofcoin/peernet-swarm/src/client/client.js
564
+
565
+
566
+
567
+
568
+ class Client {
569
+ #peerConnection
570
+ #connections = {}
571
+ #stars = {}
572
+
573
+ get connections() {
574
+ return { ...this.#connections }
575
+ }
576
+
577
+ get peers() {
578
+ return Object.entries(this.#connections)
579
+ }
580
+
581
+ constructor(id, identifiers = ['peernet-v0.1.0'], stars = []) {
582
+ this.id = id || Math.random().toString(36).slice(-12);
583
+ if (!Array.isArray(identifiers)) identifiers = [identifiers]
584
+ this.peerJoined = this.peerJoined.bind(this)
585
+ this.peerLeft = this.peerLeft.bind(this)
586
+ this.starLeft = this.starLeft.bind(this)
587
+ this.starJoined = this.starJoined.bind(this)
588
+
589
+ this._init(identifiers, stars)
590
+ }
591
+
592
+ async _init(identifiers, stars = []) {
593
+ if (stars.length === 0) {
594
+ stars.push('wss://star.leofcoin.org')
595
+ }
596
+ this.identifiers = identifiers
597
+ this.starsConfig = stars
598
+ // reconnectJob()
599
+
600
+ if (!globalThis.RTCPeerConnection) globalThis.wrtc = await __webpack_require__.e(/* import() | wrtc */ 228).then(__webpack_require__.t.bind(__webpack_require__, 9326, 19))
601
+ else globalThis.wrtc = {
602
+ RTCPeerConnection,
603
+ RTCSessionDescription,
604
+ RTCIceCandidate
605
+ }
606
+
607
+ for (const star of stars) {
608
+ try {
609
+ this.socketClient = await socketRequestClient(star, identifiers[0])
610
+ const id = await this.socketClient.request({url: 'id', params: {from: this.id}})
611
+ this.socketClient.peerId = id
612
+ this.#stars[id] = this.socketClient
613
+ } catch (e) {
614
+ if (stars.indexOf(star) === stars.length -1 && !this.socketClient) throw new Error(`No star available to connect`);
615
+ }
616
+ }
617
+ const peers = await this.socketClient.peernet.join({id: this.id})
618
+ for (const id of peers) {
619
+ 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})
620
+ }
621
+ this.setupListeners()
622
+ }
623
+
624
+ setupListeners() {
625
+ this.socketClient.subscribe('peer:joined', this.peerJoined)
626
+ this.socketClient.subscribe('peer:left', this.peerLeft)
627
+ this.socketClient.subscribe('star:left', this.starLeft)
628
+ }
629
+
630
+ starJoined(id) {
631
+ if (this.#stars[id]) {
632
+ this.#stars[id].close()
633
+ delete this.#stars[id]
634
+ }
635
+ console.log(`star ${id} joined`);
636
+ }
637
+
638
+ async starLeft(id) {
639
+ if (this.#stars[id]) {
640
+ this.#stars[id].close()
641
+ delete this.#stars[id]
642
+ }
643
+ if (this.socketClient?.peerId === id) {
644
+
645
+ this.socketClient.unsubscribe('peer:joined', this.peerJoined)
646
+ this.socketClient.unsubscribe('peer:left', this.peerLeft)
647
+ this.socketClient.unsubscribe('star:left', this.starLeft)
648
+ this.socketClient.close()
649
+ this.socketClient = undefined
650
+
651
+ for (const star of this.starsConfig) {
652
+ try {
653
+ this.socketClient = await socketRequestClient(star, this.identifiers[0])
654
+ if (!this.socketClient?.client?._connection.connected) return
655
+ const id = await this.socketClient.request({url: 'id', params: {from: this.id}})
656
+ this.#stars[id] = this.socketClient
657
+
658
+ this.socketClient.peerId = id
659
+
660
+ const peers = await this.socketClient.peernet.join({id: this.id})
661
+ this.setupListeners()
662
+ for (const id of peers) {
663
+ if (id !== this.id) {
664
+ // close connection
665
+ if (this.#connections[id]) {
666
+ if (this.#connections[id].connected) await this.#connections[id].close()
667
+ delete this.#connections[id]
668
+ }
669
+ // reconnect
670
+ if (id !== this.id) this.#connections[id] = await new Peer({channelName: `${id}:${this.id}`, socketClient: this.socketClient, id: this.id, to: id, peerId: id})
671
+ }
672
+
673
+ }
674
+ } catch (e) {
675
+ console.log(e);
676
+ if (this.starsConfig.indexOf(star) === this.starsConfig.length -1 && !this.socketClient) throw new Error(`No star available to connect`);
677
+ }
678
+ }
679
+ }
680
+ debug(`star ${id} left`);
681
+ }
682
+
683
+ peerLeft(peer) {
684
+ const id = peer.peerId || peer
685
+ if (this.#connections[id]) {
686
+ this.#connections[id].close()
687
+ delete this.#connections[id]
688
+ }
689
+ debug(`peer ${id} left`)
690
+ }
691
+
692
+ async peerJoined(peer, signal) {
693
+ const id = peer.peerId || peer
694
+ if (this.#connections[id]) {
695
+ if (this.#connections[id].connected) this.#connections[id].close()
696
+ delete this.#connections[id]
697
+ }
698
+ // RTCPeerConnection
699
+ this.#connections[id] = await new Peer({initiator: true, channelName: `${this.id}:${id}`, socketClient: this.socketClient, id: this.id, to: id, peerId: id})
700
+ debug(`peer ${id} joined`)
701
+ }
702
+
703
+ removePeer(peer) {
704
+ const id = peer.peerId || peer
705
+ if (this.#connections[id]) {
706
+ this.#connections[id].connected && this.#connections[id].close()
707
+ delete this.#connections[id]
708
+ }
709
+ debug(`peer ${id} removed`)
710
+ }
711
+
712
+
713
+ }
714
+
715
+
716
+ /***/ }),
717
+
718
+ /***/ 284:
719
+ /***/ (function(module) {
720
+
721
+ var naiveFallback = function () {
722
+ if (typeof self === "object" && self) return self;
723
+ if (typeof window === "object" && window) return window;
724
+ throw new Error("Unable to resolve global `this`");
725
+ };
726
+
727
+ module.exports = (function () {
728
+ if (this) return this;
729
+
730
+ // Unexpected strict mode (may happen if e.g. bundled into ESM module)
731
+
732
+ // Fallback to standard globalThis if available
733
+ if (typeof globalThis === "object" && globalThis) return globalThis;
734
+
735
+ // Thanks @mathiasbynens -> https://mathiasbynens.be/notes/globalthis
736
+ // In all ES5+ engines global object inherits from Object.prototype
737
+ // (if you approached one that doesn't please report)
738
+ try {
739
+ Object.defineProperty(Object.prototype, "__global__", {
740
+ get: function () { return this; },
741
+ configurable: true
742
+ });
743
+ } catch (error) {
744
+ // Unfortunate case of updates to Object.prototype being restricted
745
+ // via preventExtensions, seal or freeze
746
+ return naiveFallback();
747
+ }
748
+ try {
749
+ // Safari case (window.__global__ works, but __global__ does not)
750
+ if (!__global__) return naiveFallback();
751
+ return __global__;
752
+ } finally {
753
+ delete Object.prototype.__global__;
754
+ }
755
+ })();
756
+
757
+
758
+ /***/ }),
759
+
760
+ /***/ 5840:
761
+ /***/ (function(module, __unused_webpack_exports, __webpack_require__) {
762
+
763
+ var _globalThis;
764
+ if (typeof globalThis === 'object') {
765
+ _globalThis = globalThis;
766
+ } else {
767
+ try {
768
+ _globalThis = __webpack_require__(284);
769
+ } catch (error) {
770
+ } finally {
771
+ if (!_globalThis && typeof window !== 'undefined') { _globalThis = window; }
772
+ if (!_globalThis) { throw new Error('Could not determine global this'); }
773
+ }
774
+ }
775
+
776
+ var NativeWebSocket = _globalThis.WebSocket || _globalThis.MozWebSocket;
777
+ var websocket_version = __webpack_require__(9387);
778
+
779
+
780
+ /**
781
+ * Expose a W3C WebSocket class with just one or two arguments.
782
+ */
783
+ function W3CWebSocket(uri, protocols) {
784
+ var native_instance;
785
+
786
+ if (protocols) {
787
+ native_instance = new NativeWebSocket(uri, protocols);
788
+ }
789
+ else {
790
+ native_instance = new NativeWebSocket(uri);
791
+ }
792
+
793
+ /**
794
+ * 'native_instance' is an instance of nativeWebSocket (the browser's WebSocket
795
+ * class). Since it is an Object it will be returned as it is when creating an
796
+ * instance of W3CWebSocket via 'new W3CWebSocket()'.
797
+ *
798
+ * ECMAScript 5: http://bclary.com/2004/11/07/#a-13.2.2
799
+ */
800
+ return native_instance;
801
+ }
802
+ if (NativeWebSocket) {
803
+ ['CONNECTING', 'OPEN', 'CLOSING', 'CLOSED'].forEach(function(prop) {
804
+ Object.defineProperty(W3CWebSocket, prop, {
805
+ get: function() { return NativeWebSocket[prop]; }
806
+ });
807
+ });
808
+ }
809
+
810
+ /**
811
+ * Module exports.
812
+ */
813
+ module.exports = {
814
+ 'w3cwebsocket' : NativeWebSocket ? W3CWebSocket : null,
815
+ 'version' : websocket_version
816
+ };
817
+
818
+
819
+ /***/ }),
820
+
821
+ /***/ 9387:
822
+ /***/ (function(module, __unused_webpack_exports, __webpack_require__) {
823
+
824
+ module.exports = __webpack_require__(9794).version;
825
+
826
+
827
+ /***/ }),
828
+
829
+ /***/ 9794:
830
+ /***/ (function(module) {
831
+
832
+ module.exports = {"version":"1.0.34"};
833
+
834
+ /***/ })
835
+
836
+ }])