webpeerjs 0.0.4 → 0.0.6

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/src/webpeerjs.js CHANGED
@@ -4,11 +4,14 @@ import {
4
4
  PBPeer,
5
5
  uint8ArrayToString,
6
6
  uint8ArrayFromString,
7
- //first,
7
+ first,
8
8
  Key,
9
9
  msgIdFnStrictNoSign,
10
- metrics } from './utils'
11
- //import { createDelegatedRoutingV1HttpApiClient } from '@helia/delegated-routing-v1-http-api-client'
10
+ metrics,
11
+ getDigest,
12
+ mkDebug
13
+ } from './utils'
14
+ import { createDelegatedRoutingV1HttpApiClient } from '@helia/delegated-routing-v1-http-api-client'
12
15
  import { createLibp2p } from 'libp2p'
13
16
  import { IDBDatastore } from 'datastore-idb'
14
17
  import { webTransport } from '@libp2p/webtransport'
@@ -19,7 +22,7 @@ import { circuitRelayTransport } from '@libp2p/circuit-relay-v2'
19
22
  import { gossipsub } from '@chainsafe/libp2p-gossipsub'
20
23
  import { identify, identifyPush } from '@libp2p/identify'
21
24
  import { multiaddr } from '@multiformats/multiaddr'
22
- //import { peerIdFromString } from '@libp2p/peer-id'
25
+ import { peerIdFromString } from '@libp2p/peer-id'
23
26
  import { kadDHT, removePrivateAddressesMapper } from '@libp2p/kad-dht'
24
27
  import { simpleMetrics } from '@libp2p/simple-metrics'
25
28
 
@@ -78,6 +81,9 @@ class webpeerjs{
78
81
  //is dial enabled
79
82
  #isDialEnabled
80
83
 
84
+ //message tracker avoid double
85
+ #msgIdtracker
86
+
81
87
  id
82
88
  status
83
89
  IPFS
@@ -105,6 +111,7 @@ class webpeerjs{
105
111
  this.#trackDisconnect = new Map()
106
112
  this.#dialQueue = []
107
113
  this.#isDialEnabled = true
114
+ this.#msgIdtracker = []
108
115
 
109
116
  this.peers = (function(f) {
110
117
  return f
@@ -123,7 +130,7 @@ class webpeerjs{
123
130
 
124
131
 
125
132
  //listen to peer connect event
126
- this.#libp2p.addEventListener("peer:connect", (evt) => {
133
+ this.#libp2p.addEventListener("peer:connect",async (evt) => {
127
134
 
128
135
  //console.log(`Connected to ${connection.toString()}`);
129
136
 
@@ -133,12 +140,22 @@ class webpeerjs{
133
140
  const connections = this.#libp2p.getConnections().map((con)=>{return {id:con.remotePeer.toString(),addr:con.remoteAddr.toString()}})
134
141
  const connect = connections.find((con)=>con.id == id)
135
142
  const addr = connect.addr
143
+
144
+ if(config.CONFIG_KNOWN_BOOTSTRAP_PEERS_IDS.includes(id) || config.CONFIG_KNOWN_BOOTSTRAP_HYBRID_IDS.includes(id)){
145
+ if(!this.#connections.has(id)&&addr.includes('webtransport')){
146
+ await this.#dbstore.put(new Key(id), new TextEncoder().encode(addr))
147
+ }
148
+ }
149
+
136
150
  this.#connections.set(id,addr)
137
151
 
138
152
  //required by joinRoom version 1 to announce via universal connectivity
139
- if(connection.toString() === config.CONFIG_KNOWN_BOOTSTRAP_PEER_IDS[0]){
153
+ if(config.CONFIG_KNOWN_BOOTSTRAP_HYBRID_IDS.includes(id)){
140
154
  setTimeout(()=>{
141
155
  this.#announce()
156
+ setTimeout(()=>{
157
+ this.#announce()
158
+ },5000)
142
159
  },1000)
143
160
  }
144
161
 
@@ -150,6 +167,7 @@ class webpeerjs{
150
167
 
151
168
  //console.log('on:'+event.detail.topic,event.detail.data)
152
169
  //console.log('from '+event.detail.from.toString(),event)
170
+ //console.log('ontopic:'+event.detail.topic)
153
171
 
154
172
  if (event.detail.type !== 'signed') {
155
173
  return
@@ -177,6 +195,11 @@ class webpeerjs{
177
195
  const now = new Date().getTime()
178
196
  const metadata = {addrs:address,last:now}
179
197
  this.#connectedPeers.set(senderPeerId,metadata)
198
+ this.#connectedPeersArr.length = 0
199
+ for(const peer of this.#connectedPeers){
200
+ const item = {id:peer[0],address:peer[1].addrs}
201
+ this.#connectedPeersArr.push(item)
202
+ }
180
203
  }
181
204
 
182
205
  //dial if not connected
@@ -219,6 +242,7 @@ class webpeerjs{
219
242
  const room = json.room
220
243
  const rooms = json.rooms
221
244
  const message = json.message
245
+ const msgId = json.msgId
222
246
  const signal = json.signal
223
247
  const id = json.id
224
248
  //console.log(`from ${id}:${signal} = ${message}`)
@@ -250,16 +274,21 @@ class webpeerjs{
250
274
  if(room){
251
275
  if(this.#rooms[room]){
252
276
 
253
- //inbound message
254
- if(message){
255
- this.#rooms[room].onMessage(message,id)
256
- }
257
-
258
277
  //update room members
259
278
  if(!this.#rooms[room].members.includes(id)){
260
279
  this.#rooms[room].members.push(id)
261
280
  this.#rooms[room].onMembers(this.#rooms[room].members)
262
281
  }
282
+
283
+ //inbound message
284
+ if(message){
285
+ const msgID = msgId+id
286
+ if(!this.#msgIdtracker.includes(msgID)){
287
+ this.#msgIdtracker.push(msgID)
288
+ this.#rooms[room].onMessage(message,id)
289
+ }
290
+ }
291
+
263
292
  }
264
293
  }
265
294
 
@@ -301,7 +330,7 @@ class webpeerjs{
301
330
 
302
331
  }catch(err){
303
332
  //console.log('from '+event.detail.from.toString())
304
- console.debug(err)
333
+ mkDebug(err)
305
334
  }
306
335
  }else{
307
336
  const json = JSON.parse(topic)
@@ -452,6 +481,7 @@ class webpeerjs{
452
481
 
453
482
  //dial random discovered peers
454
483
  //this.#dialdiscoveredpeers()
484
+
455
485
 
456
486
  onMetrics((data)=>{
457
487
  const signal = metrics(data)
@@ -459,14 +489,39 @@ class webpeerjs{
459
489
 
460
490
  })
461
491
 
462
- setInterval(()=>{
492
+ setTimeout(()=>{
463
493
  this.#dialQueueList()
464
- },5e3)
494
+ setInterval(()=>{
495
+ this.#dialQueueList()
496
+ },5e3)
497
+ },10e3)
498
+
499
+
465
500
 
466
501
  setInterval(()=>{
467
502
  this.#trackLastSeen()
468
503
  },5e3)
469
504
 
505
+
506
+ /*setTimeout(async()=>{
507
+ try{
508
+ //console.log('getClosestPeers')
509
+ const digest = await getDigest()
510
+ //console.log('digest',digest)
511
+ for await (const event of this.#libp2p.services.aminoDHT.getClosestPeers(digest)){
512
+ if (event.name === 'FINAL_PEER'){
513
+ //event.peer.multiaddrs.forEach((ma) => {
514
+ //console.log(event.peer.id.toString(),ma.toString())
515
+ //})
516
+ //console.log(event.peer.id.toString(),event.peer.multiaddrs.toString())
517
+ }
518
+ }
519
+ }
520
+ catch(err){
521
+ console.error('query error', err)
522
+ }
523
+ },60e3)*/
524
+
470
525
  }
471
526
 
472
527
 
@@ -492,6 +547,39 @@ class webpeerjs{
492
547
  PRIVATE FUNCTION
493
548
  */
494
549
 
550
+ #findHybridPeer(){
551
+ setTimeout(async()=>{
552
+ for(const target of config.CONFIG_KNOWN_BOOTSTRAP_HYBRID_IDS){
553
+ if(!this.#isConnected(target)){
554
+ //console.log('findPeer',target)
555
+ const peerId = peerIdFromString(target)
556
+ //const peerInfo = await this.#libp2p.services.aminoDHT.findPeer(peerId)
557
+
558
+ //console.info(peerInfo)
559
+ for await (const event of this.#libp2p.services.aminoDHT.findPeer(peerId)){
560
+ //console.info('findPeer',event)
561
+ if (event.name === 'FINAL_PEER'){
562
+ //console.log(event.peer.id.toString(),event.peer.multiaddrs.toString())
563
+ let mddrs = []
564
+ let addrs = []
565
+ const id = event.peer.id.toString()
566
+ for(const mddr of event.peer.multiaddrs){
567
+ const peeraddr = mddr.toString()+'/p2p/'+id
568
+ const peermddr = multiaddr(peeraddr)
569
+ addrs.push(peeraddr)
570
+ mddrs.push(peermddr)
571
+ }
572
+ this.#dialedKnownBootstrap.set(id,addrs)
573
+ if(!this.#isConnected(id)){
574
+ this.#dialMultiaddress(mddrs)
575
+ }
576
+ }
577
+ }
578
+ }
579
+ }
580
+ },30e3)
581
+ }
582
+
495
583
 
496
584
  //check the last seen in web peer
497
585
  #trackLastSeen(){
@@ -553,7 +641,7 @@ class webpeerjs{
553
641
  return
554
642
  }
555
643
 
556
- if(this.#webPeersId.includes(id) || id == config.CONFIG_KNOWN_BOOTSTRAP_PEER_IDS[0] ){
644
+ if(this.#webPeersId.includes(id) || config.CONFIG_KNOWN_BOOTSTRAP_PEERS_IDS.includes(id) || config.CONFIG_KNOWN_BOOTSTRAP_HYBRID_IDS.includes(id)){
557
645
  this.#dialQueue.unshift(mddrs)
558
646
  }
559
647
  else{
@@ -655,7 +743,8 @@ class webpeerjs{
655
743
  onMessage : () => {},
656
744
  listenMessage : f => (this.#rooms[room] = {...this.#rooms[room], onMessage: f}),
657
745
  sendMessage : async (message) => {
658
- const data = JSON.stringify({prefix:config.CONFIG_PREFIX,room,message,id:this.#libp2p.peerId.toString()})
746
+ const msgId = (new Date()).getTime()
747
+ const data = JSON.stringify({prefix:config.CONFIG_PREFIX,room,message,id:this.#libp2p.peerId.toString(),msgId})
659
748
  const peer = {
660
749
  publicKey: this.#libp2p.peerId.publicKey,
661
750
  addrs: [uint8ArrayFromString(data)],
@@ -704,13 +793,15 @@ class webpeerjs{
704
793
  #dialRandomBootstrap(){
705
794
  setInterval(()=>{
706
795
  //const keys = Array.from(this.#dialedKnownBootstrap.keys())
707
- const keys = config.CONFIG_KNOWN_BOOTSTRAP_PEER_IDS
796
+ const keys = config.CONFIG_KNOWN_BOOTSTRAP_PEERS_IDS
708
797
  const randomKey = Math.floor(Math.random() * keys.length)
709
798
  let ids = []
710
799
  ids.push(keys[randomKey])
711
800
 
712
801
  //universal connectivity id for webpeer discovery and joinRoom version 1 to work
713
- ids.push(config.CONFIG_KNOWN_BOOTSTRAP_PEER_IDS[0])
802
+ for(const id of config.CONFIG_KNOWN_BOOTSTRAP_HYBRID_IDS){
803
+ ids.push(id)
804
+ }
714
805
 
715
806
  for(const id of ids){
716
807
  if(id == undefined)continue
@@ -737,14 +828,16 @@ class webpeerjs{
737
828
  else{
738
829
  const bootstrap = config.CONFIG_KNOWN_BOOTSTRAP_PEERS_ADDRS
739
830
  const index = bootstrap.findIndex((peer)=>peer.Peers[0].ID == id)
740
- const addrs = bootstrap[index].Peers[0].Addrs
741
- let mddrs = []
742
- for(const addr of addrs){
743
- const peeraddr = addr+'/p2p/'+id
744
- const mddr = multiaddr(peeraddr)
745
- mddrs.push(mddr)
831
+ if(index > -1){
832
+ const addrs = bootstrap[index].Peers[0].Addrs
833
+ let mddrs = []
834
+ for(const addr of addrs){
835
+ const peeraddr = addr+'/p2p/'+id
836
+ const mddr = multiaddr(peeraddr)
837
+ mddrs.push(mddr)
838
+ }
839
+ this.#dialMultiaddress(mddrs)
746
840
  }
747
- this.#dialMultiaddress(mddrs)
748
841
  }
749
842
  }
750
843
  }
@@ -775,7 +868,7 @@ class webpeerjs{
775
868
  if(besttime>bestlimit){
776
869
  const addr = remote.toString()
777
870
  const id = peer.toString()
778
- if(!this.#webPeersId.includes(id) && !config.CONFIG_KNOWN_BOOTSTRAP_PEER_IDS.includes(id) && !this.#dbstoreData.get(id) && !addr.includes('p2p-circuit')){
871
+ if(!this.#webPeersId.includes(id) && !config.CONFIG_KNOWN_BOOTSTRAP_PEERS_IDS.includes(id) && !this.#dbstoreData.get(id) && !addr.includes('p2p-circuit') && addr.includes('webtransport')){
779
872
  //await this.#dbstore.delete(new Key(id))
780
873
  await this.#dbstore.put(new Key(id), new TextEncoder().encode(addr))
781
874
  this.#dbstoreData.set(id,addr)
@@ -844,7 +937,7 @@ class webpeerjs{
844
937
  }
845
938
  }
846
939
 
847
- },30*1000)
940
+ },15*1000)
848
941
  }
849
942
 
850
943
 
@@ -866,28 +959,33 @@ class webpeerjs{
866
959
 
867
960
  //dial to all known bootstrap peers and DNS
868
961
  #dialKnownPeers(){
869
- this.#dialKnownBootstrap()
962
+ //this.#dialKnownBootstrap()
870
963
  setTimeout(()=>{
871
- const peers = this.#libp2p.getPeers().length
872
- if(peers == 0){
873
- //currently not needed
874
- //this.#dialKnownID()
875
- setTimeout(()=>{
876
- const peers = this.#libp2p.getPeers().length
877
- if(peers == 0){
878
- //currently not needed
879
- //this.#dialKnownDNS()
880
- setTimeout(()=>{
881
- const peers = this.#libp2p.getPeers().length
882
- if(peers == 0){
883
- //currently not needed
884
- //this.#dialKnownDNSonly()
885
- }
886
- },15000)
887
- }
888
- },15000)
889
- }
890
- },15000)
964
+ this.#dialSavedKnownID()
965
+ this.#findHybridPeer()
966
+ setTimeout(()=>{this.#dialUpdateSavedKnownID()},60000)
967
+ setTimeout(()=>{
968
+ const peers = this.#libp2p.getPeers().length
969
+ if(peers == 0){
970
+ this.#dialKnownID()
971
+ this.#findHybridPeer()
972
+ setTimeout(()=>{
973
+ const peers = this.#libp2p.getPeers().length
974
+ if(peers == 0){
975
+ //currently not needed
976
+ //this.#dialKnownDNS()
977
+ setTimeout(()=>{
978
+ const peers = this.#libp2p.getPeers().length
979
+ if(peers == 0){
980
+ //currently not needed
981
+ //this.#dialKnownDNSonly()
982
+ }
983
+ },15000)
984
+ }
985
+ },15000)
986
+ }
987
+ },15000)
988
+ },5000)
891
989
  }
892
990
 
893
991
 
@@ -914,12 +1012,80 @@ class webpeerjs{
914
1012
  }
915
1013
  }
916
1014
 
1015
+ async #dialSavedKnownID(){
1016
+ let firsttime = true
1017
+ for(const target of config.CONFIG_KNOWN_BOOTSTRAP_PEERS_IDS){
1018
+ if(this.#dbstoreData.has(target)){
1019
+ firsttime = false
1020
+ let mddrs = []
1021
+ let addrs = []
1022
+ const id = target
1023
+ const peeraddr = this.#dbstoreData.get(target)
1024
+ const peermddr = multiaddr(peeraddr)
1025
+ addrs.push(peeraddr)
1026
+ mddrs.push(peermddr)
1027
+ this.#dialedKnownBootstrap.set(id,addrs)
1028
+ if(!this.#isConnected(id)){
1029
+ this.#dialMultiaddress(mddrs)
1030
+ }
1031
+ }
1032
+ }
1033
+ if(firsttime){
1034
+ for(const target of config.CONFIG_KNOWN_BOOTSTRAP_PEERS_IDS){
1035
+ const api = config.CONFIG_DELEGATED_API
1036
+ const delegatedClient = createDelegatedRoutingV1HttpApiClient(api)
1037
+ const peer = await first(delegatedClient.getPeers(peerIdFromString(target)))
1038
+ const address = peer.Addrs
1039
+ const id = peer.ID
1040
+ let mddrs = []
1041
+ let addrs = []
1042
+ for(const addr of address){
1043
+ const peeraddr = addr.toString()+'/p2p/'+id.toString()
1044
+ const peermddr = multiaddr(peeraddr)
1045
+ addrs.push(peeraddr)
1046
+ mddrs.push(peermddr)
1047
+ }
1048
+
1049
+ this.#dialedKnownBootstrap.set(id,addrs)
1050
+ if(!this.#isConnected(id)){
1051
+ this.#dialMultiaddress(mddrs)
1052
+ }
1053
+ }
1054
+ }
1055
+ }
1056
+
1057
+ async #dialUpdateSavedKnownID(){
1058
+ for(const target of config.CONFIG_KNOWN_BOOTSTRAP_PEERS_IDS){
1059
+ if(!this.#connections.has(target)){
1060
+ const api = config.CONFIG_DELEGATED_API
1061
+ const delegatedClient = createDelegatedRoutingV1HttpApiClient(api)
1062
+ const peer = await first(delegatedClient.getPeers(peerIdFromString(target)))
1063
+ const address = peer.Addrs
1064
+ const id = peer.ID
1065
+ let mddrs = []
1066
+ let addrs = []
1067
+ for(const addr of address){
1068
+ const peeraddr = addr.toString()+'/p2p/'+id.toString()
1069
+ const peermddr = multiaddr(peeraddr)
1070
+ addrs.push(peeraddr)
1071
+ mddrs.push(peermddr)
1072
+ }
1073
+
1074
+ this.#dialedKnownBootstrap.set(id,addrs)
1075
+ if(!this.#isConnected(id)){
1076
+ this.#dialMultiaddress(mddrs)
1077
+ }
1078
+ }
1079
+ }
1080
+ }
1081
+
917
1082
 
918
1083
  //dial based on known peers ID
919
- /*async #dialKnownID(){
1084
+ async #dialKnownID(){
1085
+ //console.log('#dialKnownID()')
920
1086
  const api = config.CONFIG_DELEGATED_API
921
1087
  const delegatedClient = createDelegatedRoutingV1HttpApiClient(api)
922
- const BOOTSTRAP_PEER_IDS = config.CONFIG_KNOWN_BOOTSTRAP_PEER_IDS
1088
+ const BOOTSTRAP_PEER_IDS = config.CONFIG_KNOWN_BOOTSTRAP_PEERS_IDS
923
1089
  const peers = await Promise.all(
924
1090
  BOOTSTRAP_PEER_IDS.map((peerId) => first(delegatedClient.getPeers(peerIdFromString(peerId)))),
925
1091
  )
@@ -941,7 +1107,7 @@ class webpeerjs{
941
1107
  this.#dialMultiaddress(mddrs)
942
1108
  }
943
1109
  }
944
- }*/
1110
+ }
945
1111
 
946
1112
 
947
1113
  //dial based on known bootstrap DNS
@@ -1037,7 +1203,7 @@ class webpeerjs{
1037
1203
  return // if we succeed dialing the peer, no need to try another address
1038
1204
  } catch (error) {
1039
1205
  //console.log(`failed to dial webtransport multiaddr: %o`, addr.toString())
1040
- console.debug(error)
1206
+ mkDebug(error)
1041
1207
  }
1042
1208
  }
1043
1209
  }
@@ -1059,7 +1225,7 @@ class webpeerjs{
1059
1225
  return // if we succeed dialing the peer, no need to try another address
1060
1226
  } catch (error) {
1061
1227
  //console.log(`failed to dial websocket multiaddr: %o`, addr)
1062
- console.debug(error)
1228
+ mkDebug(error)
1063
1229
  }
1064
1230
  }
1065
1231
  }
@@ -1069,7 +1235,7 @@ class webpeerjs{
1069
1235
  static async createWebpeer(){
1070
1236
 
1071
1237
  // all libp2p debug logs
1072
- localStorage.setItem('debug', 'libp2p:*')
1238
+ //localStorage.setItem('debug', 'libp2p:*')
1073
1239
 
1074
1240
  const dbstore = new IDBDatastore(config.CONFIG_DBSTORE_PATH)
1075
1241
  await dbstore.open()
@@ -1113,7 +1279,7 @@ class webpeerjs{
1113
1279
  autoDialConcurrency:0,
1114
1280
  autoDialMaxQueueLength:0,
1115
1281
  autoDialPriority:1000,
1116
- autoDialDiscoveredPeersDebounce:30e3,
1282
+ autoDialDiscoveredPeersDebounce:60e3,
1117
1283
  maxParallelDials: 3,
1118
1284
  dialTimeout: 5e3,
1119
1285
  maxIncomingPendingConnections: 5,
@@ -1125,8 +1291,8 @@ class webpeerjs{
1125
1291
  connectionEncryption: [noise()],
1126
1292
  streamMuxers: [
1127
1293
  yamux({
1128
- maxInboundStreams: 50,
1129
- maxOutboundStreams: 50,
1294
+ maxInboundStreams: 20,
1295
+ maxOutboundStreams: 20,
1130
1296
  })
1131
1297
  ],
1132
1298
  connectionGater: {
@@ -1164,6 +1330,7 @@ class webpeerjs{
1164
1330
  allowPublishToZeroTopicPeers: true,
1165
1331
  msgIdFn: msgIdFnStrictNoSign,
1166
1332
  ignoreDuplicatePublishError: true,
1333
+ runOnTransientConnection:true,
1167
1334
  }),
1168
1335
  identify: identify(),
1169
1336
  identifyPush: identifyPush(),