@leofcoin/peernet 1.0.11 → 1.1.1

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.
@@ -11,4 +11,25 @@ const node = await new Node()
11
11
  const node = await new Node()
12
12
  // gives time to setup things...
13
13
  await node.start()
14
+ ```
15
+
16
+ ## 1.1.0
17
+ ### autoStart
18
+ #### before
19
+ ```js
20
+ const node = await new Node()
21
+ // gives time to setup things...
22
+ await node.start()
23
+ ```
24
+
25
+ #### now
26
+ ```js
27
+ const node = await new Node()
28
+ ```
29
+ or
30
+
31
+ ```js
32
+ const node = await new Node({autoStart: false}) // defaults to true
33
+ // gives time to setup things...
34
+ await node.start()
14
35
  ```
@@ -1,4 +1,4 @@
1
- import { L as LittlePubSub } from './peernet-c184b33c.js';
1
+ import { L as LittlePubSub } from './peernet-4aaa825c.js';
2
2
  import './value-157ab062.js';
3
3
 
4
4
  var clientApi = _pubsub => {
@@ -235,6 +235,9 @@ class Peer {
235
235
  #chunkSize = 16 * 1024; // 16384
236
236
  #queRunning = false;
237
237
  #MAX_BUFFERED_AMOUNT = 16 * 1024 * 1024;
238
+ initiator = false;
239
+ state;
240
+ #makingOffer = false;
238
241
  get connection() {
239
242
  return this.#connection;
240
243
  }
@@ -247,7 +250,7 @@ class Peer {
247
250
  /**
248
251
  * @params {Object} options
249
252
  * @params {string} options.channelName - this peerid : otherpeer id
250
- */
253
+ */
251
254
  constructor(options = {}) {
252
255
  this._in = this._in.bind(this);
253
256
  this.offerOptions = options.offerOptions;
@@ -375,6 +378,69 @@ class Peer {
375
378
  credential: "openrelayproject",
376
379
  }];
377
380
  this.#connection = new wrtc.RTCPeerConnection({ iceServers });
381
+ this.#connection.onnegotiationneeded = async () => {
382
+ try {
383
+ this.#makingOffer = true;
384
+ await this.#connection.setLocalDescription();
385
+ this._sendMessage({ description: this.#connection.localDescription });
386
+ this.#makingOffer = false;
387
+ }
388
+ catch (err) {
389
+ console.error(err);
390
+ }
391
+ };
392
+ this.#connection.oniceconnectionstatechange = () => {
393
+ if (this.#connection.iceConnectionState === "failed") {
394
+ this.#connection.restartIce();
395
+ }
396
+ };
397
+ this.#connection.onconnectionstatechange = () => {
398
+ switch (this.#connection.connectionState) {
399
+ case "new":
400
+ case "checking":
401
+ this.state = "connecting";
402
+ break;
403
+ case "connected":
404
+ this.state = 'connected';
405
+ break;
406
+ case "closed":
407
+ case "disconnected":
408
+ this.state = "disconnected";
409
+ break;
410
+ case "failed":
411
+ this.state = 'failed';
412
+ break;
413
+ default:
414
+ this.state = this.#connection.connectionState;
415
+ break;
416
+ }
417
+ if (this.state === 'connected') {
418
+ this.#connection.ondatachannel = (message) => {
419
+ message.channel.onopen = () => {
420
+ this.#connected = true;
421
+ // debug(`peer:connected ${this}`)
422
+ pubsub.publish('peer:connected', this);
423
+ };
424
+ message.channel.onclose = () => this.close.bind(this);
425
+ message.channel.onmessage = (message) => {
426
+ this._handleMessage(this.id, message);
427
+ };
428
+ this.#channel = message.channel;
429
+ };
430
+ if (this.initiator) {
431
+ this.#channel = this.#connection.createDataChannel('messageChannel');
432
+ this.#channel.onopen = () => {
433
+ this.#connected = true;
434
+ pubsub.publish('peer:connected', this);
435
+ // this.#channel.send('hi')
436
+ };
437
+ this.#channel.onclose = () => this.close.bind(this);
438
+ this.#channel.onmessage = (message) => {
439
+ this._handleMessage(this.peerId, message);
440
+ };
441
+ }
442
+ }
443
+ };
378
444
  this.#connection.onicecandidate = ({ candidate }) => {
379
445
  if (candidate) {
380
446
  this.address = candidate.address;
@@ -386,33 +452,6 @@ class Peer {
386
452
  };
387
453
  // if (this.initiator) this.#connection.onnegotiationneeded = () => {
388
454
  // console.log('create offer');
389
- this.#connection.ondatachannel = (message) => {
390
- message.channel.onopen = () => {
391
- this.#connected = true;
392
- // debug(`peer:connected ${this}`)
393
- pubsub.publish('peer:connected', this);
394
- };
395
- message.channel.onclose = () => this.close.bind(this);
396
- message.channel.onmessage = (message) => {
397
- this._handleMessage(this.id, message);
398
- };
399
- this.#channel = message.channel;
400
- };
401
- if (this.initiator) {
402
- this.#channel = this.#connection.createDataChannel('messageChannel');
403
- this.#channel.onopen = () => {
404
- this.#connected = true;
405
- pubsub.publish('peer:connected', this);
406
- // this.#channel.send('hi')
407
- };
408
- this.#channel.onclose = () => this.close.bind(this);
409
- this.#channel.onmessage = (message) => {
410
- this._handleMessage(this.peerId, message);
411
- };
412
- const offer = await this.#connection.createOffer();
413
- await this.#connection.setLocalDescription(offer);
414
- this._sendMessage({ 'sdp': this.#connection.localDescription });
415
- }
416
455
  }
417
456
  catch (e) {
418
457
  console.log(e);
@@ -449,39 +488,36 @@ class Peer {
449
488
  } });
450
489
  }
451
490
  async _in(message, data) {
452
- // message = JSON.parse(message);
453
- if (!this.#connection || message.to !== this.id || message.from !== this.#peerId)
454
- return;
455
- // if (data.videocall) return this._startStream(true, false); // start video and audio stream
456
- // if (data.call) return this._startStream(true, true); // start audio stream
457
- if (this.#connection?.signalingState === 'stable' && this.#connection?.remoteDescription !== null && this.#connection?.localDescription !== null)
458
- return;
459
- if (message.candidate) {
460
- // debug(`incoming candidate ${this.#channelName}`)
461
- // debug(message.candidate.candidate)
462
- this.remoteAddress = message.candidate.address;
463
- this.remotePort = message.candidate.port;
464
- this.remoteProtocol = message.candidate.protocol;
465
- this.remoteIpFamily = this.remoteAddress?.includes('::') ? 'ipv6' : 'ipv4';
466
- return this.#connection.addIceCandidate(new wrtc.RTCIceCandidate(message.candidate));
467
- }
491
+ let ignoreOffer = false;
468
492
  try {
469
- if (message.sdp) {
470
- if (message.sdp.type === 'offer') {
471
- // debug(`incoming offer ${this.#channelName}`)
472
- await this.#connection.setRemoteDescription(new wrtc.RTCSessionDescription(message.sdp));
473
- const answer = await this.#connection.createAnswer();
474
- await this.#connection.setLocalDescription(answer);
475
- this._sendMessage({ 'sdp': this.#connection.localDescription });
493
+ if (message.description) {
494
+ const offerCollision = message.description.type === "offer" &&
495
+ (this.#makingOffer || this.#connection.signalingState !== "stable");
496
+ ignoreOffer = this.initiator && offerCollision;
497
+ if (ignoreOffer) {
498
+ return;
499
+ }
500
+ await this.#connection.setRemoteDescription(message.description);
501
+ if (message.description.type === "offer") {
502
+ await this.#connection.setLocalDescription();
503
+ this._sendMessage({ description: this.#connection.localDescription });
504
+ }
505
+ }
506
+ else if (message.candidate) {
507
+ try {
508
+ await this.#connection.addIceCandidate(message.candidate);
476
509
  }
477
- if (message.sdp.type === 'answer') {
478
- // debug(`incoming answer ${this.#channelName}`)
479
- await this.#connection.setRemoteDescription(new wrtc.RTCSessionDescription(message.sdp));
510
+ catch (err) {
511
+ if (!ignoreOffer) {
512
+ throw err;
513
+ }
480
514
  }
481
515
  }
482
516
  }
483
517
  catch (e) {
518
+ pubsub.publish('connection closed', this);
484
519
  console.log(e);
520
+ this.close();
485
521
  }
486
522
  }
487
523
  close() {
@@ -539,12 +575,18 @@ class Client {
539
575
  throw new Error(`No star available to connect`);
540
576
  }
541
577
  }
578
+ this.setupListeners();
542
579
  const peers = await this.socketClient.peernet.join({ id: this.id });
543
580
  for (const id of peers) {
544
581
  if (id !== this.id && !this.#connections[id])
545
582
  this.#connections[id] = await new Peer({ channelName: `${id}:${this.id}`, socketClient: this.socketClient, id: this.id, to: id, peerId: id });
546
583
  }
547
- this.setupListeners();
584
+ pubsub.subscribe('connection closed', (peer) => {
585
+ this.removePeer(peer.peerId);
586
+ setTimeout(() => {
587
+ this.peerJoined(peer.peerId);
588
+ }, 1000);
589
+ });
548
590
  }
549
591
  setupListeners() {
550
592
  this.socketClient.subscribe('peer:joined', this.peerJoined);
@@ -581,15 +623,10 @@ class Client {
581
623
  this.setupListeners();
582
624
  for (const id of peers) {
583
625
  if (id !== this.id) {
584
- // close connection
585
- if (this.#connections[id]) {
586
- if (this.#connections[id].connected)
587
- await this.#connections[id].close();
588
- delete this.#connections[id];
626
+ if (!this.#connections[id]) {
627
+ if (id !== this.id)
628
+ this.#connections[id] = await new Peer({ channelName: `${id}:${this.id}`, socketClient: this.socketClient, id: this.id, to: id, peerId: id });
589
629
  }
590
- // reconnect
591
- if (id !== this.id)
592
- this.#connections[id] = await new Peer({ channelName: `${id}:${this.id}`, socketClient: this.socketClient, id: this.id, to: id, peerId: id });
593
630
  }
594
631
  }
595
632
  }
@@ -1,4 +1,4 @@
1
- import { M as MultiWallet, e as encrypt, b as base58$1 } from './peernet-c184b33c.js';
1
+ import { M as MultiWallet, e as encrypt, b as base58$1 } from './peernet-4aaa825c.js';
2
2
  import './value-157ab062.js';
3
3
 
4
4
  /**
@@ -1,4 +1,4 @@
1
- import { F as FormatInterface } from './peernet-c184b33c.js';
1
+ import { F as FormatInterface } from './peernet-4aaa825c.js';
2
2
  import './value-157ab062.js';
3
3
 
4
4
  var proto$b = {
@@ -16082,7 +16082,7 @@ class Identity {
16082
16082
  globalThis.peernet.selectedAccount = new TextDecoder().decode(selected);
16083
16083
  }
16084
16084
  else {
16085
- const importee = await import(/* webpackChunkName: "generate-account" */ './index-a3af83e4.js');
16085
+ const importee = await import(/* webpackChunkName: "generate-account" */ './index-c0652eae.js');
16086
16086
  const { identity, accounts } = await importee.default(password, this.network);
16087
16087
  await globalThis.accountStore.put('public', JSON.stringify({ walletId: identity.walletId }));
16088
16088
  await globalThis.walletStore.put('version', String(1));
@@ -16143,6 +16143,9 @@ class Peernet {
16143
16143
  stars;
16144
16144
  networkVersion;
16145
16145
  bw;
16146
+ autoStart = true;
16147
+ #starting = false;
16148
+ #started = false;
16146
16149
  /**
16147
16150
  * @access public
16148
16151
  * @param {Object} options
@@ -16161,6 +16164,7 @@ class Peernet {
16161
16164
  * @property {String} network - current network
16162
16165
  */
16163
16166
  this.network = options.network || 'leofcoin';
16167
+ this.autoStart = options.autoStart === undefined ? true : options.autoStart;
16164
16168
  this.stars = options.stars;
16165
16169
  const parts = this.network.split(':');
16166
16170
  this.networkVersion = options.networkVersion || parts.length > 1 ? parts[1] : 'mainnet';
@@ -16248,7 +16252,7 @@ class Peernet {
16248
16252
  this.root = options.root;
16249
16253
  const { RequestMessage, ResponseMessage, PeerMessage, PeerMessageResponse, PeernetMessage, DHTMessage, DHTMessageResponse, DataMessage, DataMessageResponse, PsMessage, ChatMessage, PeernetFile
16250
16254
  // FolderMessageResponse
16251
- } = await import(/* webpackChunkName: "messages" */ './messages-c871d6f3.js');
16255
+ } = await import(/* webpackChunkName: "messages" */ './messages-0fcc3d4e.js');
16252
16256
  /**
16253
16257
  * proto Object containing protos
16254
16258
  * @type {Object}
@@ -16307,18 +16311,22 @@ class Peernet {
16307
16311
  process.exit();
16308
16312
  });
16309
16313
  }
16314
+ if (this.autoStart)
16315
+ await this.start();
16310
16316
  return this;
16311
16317
  }
16312
16318
  async start() {
16313
- this.starting = true;
16314
- const importee = await import('./client-0d28cffd.js');
16319
+ if (this.#starting || this.#started)
16320
+ return;
16321
+ this.#starting = true;
16322
+ const importee = await import('./client-ff436f6a.js');
16315
16323
  /**
16316
16324
  * @access public
16317
16325
  * @type {PeernetClient}
16318
16326
  */
16319
16327
  this.client = new importee.default(this.id, this.networkVersion, this.stars);
16320
- this.started = true;
16321
- this.starting = false;
16328
+ this.#started = true;
16329
+ this.#starting = false;
16322
16330
  }
16323
16331
  addRequestHandler(name, method) {
16324
16332
  this.requestProtos[name] = method;
@@ -1,2 +1,2 @@
1
- export { P as default } from './peernet-c184b33c.js';
1
+ export { P as default } from './peernet-4aaa825c.js';
2
2
  import './value-157ab062.js';
@@ -401,6 +401,9 @@ class Peernet {
401
401
  stars;
402
402
  networkVersion;
403
403
  bw;
404
+ autoStart = true;
405
+ #starting = false;
406
+ #started = false;
404
407
  /**
405
408
  * @access public
406
409
  * @param {Object} options
@@ -419,6 +422,7 @@ class Peernet {
419
422
  * @property {String} network - current network
420
423
  */
421
424
  this.network = options.network || 'leofcoin';
425
+ this.autoStart = options.autoStart === undefined ? true : options.autoStart;
422
426
  this.stars = options.stars;
423
427
  const parts = this.network.split(':');
424
428
  this.networkVersion = options.networkVersion || parts.length > 1 ? parts[1] : 'mainnet';
@@ -565,18 +569,22 @@ class Peernet {
565
569
  process.exit();
566
570
  });
567
571
  }
572
+ if (this.autoStart)
573
+ await this.start();
568
574
  return this;
569
575
  }
570
576
  async start() {
571
- this.starting = true;
577
+ if (this.#starting || this.#started)
578
+ return;
579
+ this.#starting = true;
572
580
  const importee = await import('@leofcoin/peernet-swarm/client');
573
581
  /**
574
582
  * @access public
575
583
  * @type {PeernetClient}
576
584
  */
577
585
  this.client = new importee.default(this.id, this.networkVersion, this.stars);
578
- this.started = true;
579
- this.starting = false;
586
+ this.#started = true;
587
+ this.#starting = false;
580
588
  }
581
589
  addRequestHandler(name, method) {
582
590
  this.requestProtos[name] = method;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@leofcoin/peernet",
3
- "version": "1.0.11",
3
+ "version": "1.1.1",
4
4
  "description": "",
5
5
  "main": "src/peernet.js",
6
6
  "exports": {
@@ -29,7 +29,7 @@
29
29
  "@leofcoin/generate-account": "^2.0.0",
30
30
  "@leofcoin/identity-utils": "^1.0.0",
31
31
  "@leofcoin/multi-wallet": "^3.0.1",
32
- "@leofcoin/peernet-swarm": "^0.5.0",
32
+ "@leofcoin/peernet-swarm": "^1.1.0",
33
33
  "@leofcoin/storage": "^3.0.0",
34
34
  "@types/node": "^18.11.18",
35
35
  "@vandeurenglenn/base32": "^1.1.0",
package/src/peernet.ts CHANGED
@@ -43,6 +43,10 @@ export default class Peernet {
43
43
  up: number
44
44
  down: number
45
45
  }
46
+ autoStart: boolean = true
47
+ #starting: boolean = false
48
+ #started: boolean = false
49
+
46
50
  /**
47
51
  * @access public
48
52
  * @param {Object} options
@@ -56,11 +60,12 @@ export default class Peernet {
56
60
  * @example
57
61
  * const peernet = new Peernet({network: 'leofcoin', root: '.leofcoin'});
58
62
  */
59
- constructor(options: options, password) {
63
+ constructor(options, password) {
60
64
  /**
61
65
  * @property {String} network - current network
62
66
  */
63
67
  this.network = options.network || 'leofcoin'
68
+ this.autoStart = options.autoStart === undefined ? true : options.autoStart
64
69
  this.stars = options.stars
65
70
  const parts = this.network.split(':')
66
71
  this.networkVersion = options.networkVersion || parts.length > 1 ? parts[1] : 'mainnet'
@@ -244,19 +249,22 @@ export default class Peernet {
244
249
  process.exit()
245
250
  });
246
251
  }
252
+ if (this.autoStart) await this.start()
247
253
  return this
248
254
  }
249
255
 
250
256
  async start() {
251
- this.starting = true
257
+ if (this.#starting || this.#started) return
258
+
259
+ this.#starting = true
252
260
  const importee = await import('@leofcoin/peernet-swarm/client')
253
261
  /**
254
262
  * @access public
255
263
  * @type {PeernetClient}
256
264
  */
257
265
  this.client = new importee.default(this.id, this.networkVersion, this.stars)
258
- this.started = true
259
- this.starting = false
266
+ this.#started = true
267
+ this.#starting = false
260
268
  }
261
269
 
262
270
  addRequestHandler(name, method) {