webpeerjs 0.1.3 → 0.1.5

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "webpeerjs",
3
- "version": "0.1.3",
3
+ "version": "0.1.5",
4
4
  "description": "WebPEER.js is decentralized P2P JS library for communication between applications in browser.",
5
5
  "main": "./dist/umd/webpeerjs.js",
6
6
  "module": "./src/webpeerjs.js",
@@ -19,8 +19,8 @@
19
19
  "start": "npm run dev",
20
20
  "dev": "vite serve test",
21
21
  "demo": "vite serve demo",
22
- "eslint": "eslint ./src",
23
- "eslint:fix": "eslint ./src --fix",
22
+ "eslint": "eslint -c ./config/eslint.config.mjs ./src",
23
+ "eslint:fix": "eslint -c ./config/eslint.config.mjs ./src --fix",
24
24
  "removedir": "node -e \"var fs = require('fs'); try{process.argv.slice(1).map((fpath) => fs.rmdirSync(fpath, { recursive: true }))}catch(err){console.log(`Dist not found`)}; process.exit(0);\"",
25
25
  "build-all": "tsc -p config/tsconfig-rollup.json && rollup -c temp/config/rollup.config.build.js && echo {\"type\": \"commonjs\"}>dist\\umd\\package.json && echo {\"type\": \"module\"}>dist\\esm\\package.json",
26
26
  "build-types": "tsc -p config/tsconfig-esm.json",
package/src/config.js CHANGED
@@ -1,18 +1,19 @@
1
1
  //! WebPEER.js -- https://github.com/nuzulul/webpeerjs
2
+
2
3
  const prefix = 'webpeerjs'
3
4
  export const CONFIG_PREFIX = prefix
4
5
  export const CONFIG_PROTOCOL = '/'+prefix+'/1.0.0'
5
6
  export const CONFIG_BLOCKSTORE_PATH = prefix+'-blockstore'
6
7
  export const CONFIG_DATASTORE_PATH = prefix+'-datastore'
7
8
  export const CONFIG_DBSTORE_PATH = prefix+'-dbstore'
8
- export const CONFIG_MAX_CONNECTIONS = 100
9
+ export const CONFIG_MAX_CONNECTIONS = 50
9
10
  export const CONFIG_MIN_CONNECTIONS = 0
10
11
  export const CONFIG_DISCOVER_RELAYS = 1
11
12
  export const CONFIG_PEER_DISCOVERY_UNIVERSAL_CONNECTIVITY = 'universal-connectivity-browser-peer-discovery'
12
13
  export const CONFIG_PEER_DISCOVERY_GLOBAL = '_peer-discovery._p2p._pubsub'
13
14
  export const CONFIG_PEER_DISCOVERY_WEBPEERJS= prefix+'-peer-discovery'
14
15
  export const CONFIG_PUBSUB_PEER_DISCOVERY_HYBRID = [CONFIG_PEER_DISCOVERY_UNIVERSAL_CONNECTIVITY]
15
- export const CONFIG_PUBSUB_PEER_DISCOVERY_WEBPEER = [CONFIG_PEER_DISCOVERY_GLOBAL, CONFIG_PEER_DISCOVERY_WEBPEERJS]
16
+ export const CONFIG_PUBSUB_PEER_DISCOVERY_WEBPEER = [CONFIG_PEER_DISCOVERY_WEBPEERJS]
16
17
  export const CONFIG_PUPSUB_PEER_DATA = ['_'+prefix+'-peer-data_']
17
18
  export const CONFIG_PUPSUB_TOPIC = prefix+'-room'
18
19
  export const CONFIG_DELEGATED_API = 'https://delegated-ipfs.dev'
@@ -20,7 +21,16 @@ export const CONFIG_DNS_RESOLVER = 'https://dns.google/resolve'
20
21
  export const CONFIG_KNOWN_BOOTSTRAP_DNS = '_dnsaddr.bootstrap.libp2p.io'
21
22
  export const CONFIG_JOIN_ROOM_VERSION = 1
22
23
  export const CONFIG_TIMEOUT_DIAL_KNOWN_PEERS = 15000
23
- export const CONFIG_RUN_ON_TRANSIENT_CONNECTION = true
24
+ export const CONFIG_RUN_ON_TRANSIENT_CONNECTION = false
25
+ export const CONFIG_WEBRTC_STUN_URLS = 'stun:stun.l.google.com:19302'
26
+ export const CONFIG_WEBRTC_STUN_URLS_BACKUP = 'stun:global.stun.twilio.com:3478'
27
+ export const CONFIG_WEBRTC_TURN_HOST = 'dHVybjpyZWxheTEuZXhwcmVzc3R1cm4uY29tOjM0Nzg='
28
+ export const CONFIG_WEBRTC_TURN_USER = 'ZWZJSllZNjdDNElRMzFZQUlP'
29
+ export const CONFIG_WEBRTC_TURN_PWD = 'Vk01SmdhODlkYjJaWU9aSA=='
30
+ export const CONFIG_WEBRTC_TURN_HOST_BACKUP = 'dHVybjpzdGFuZGFyZC5yZWxheS5tZXRlcmVkLmNhOjgw'
31
+ export const CONFIG_WEBRTC_TURN_USER_BACKUP = 'ZmZlNmIxOThjOGMxYjM5ODg1OWFiOGY4'
32
+ export const CONFIG_WEBRTC_TURN_PWD_BACKUP = 'aWpkQjVTcTIwREVsZzdDRg=='
33
+ export const CONFIG_MESSAGE_SIZE_LIMIT = 10240 // 10KB
24
34
 
25
35
  // this list comes from https://github.com/ipfs/kubo/blob/196887cbe5fbcd41243c1dfb0db681a1cc2914ff/config/bootstrap_peers.go
26
36
  export const CONFIG_KNOWN_DEFAULT_BOOTSTRAP_ADDRESSES = [
package/src/utils.js CHANGED
@@ -1,4 +1,5 @@
1
1
  //! WebPEER.js -- https://github.com/nuzulul/webpeerjs
2
+
2
3
  import * as config from './config'
3
4
  import { Peer as PBPeer } from './peer'
4
5
  import { Key } from 'interface-datastore'
package/src/webpeerjs.js CHANGED
@@ -1,4 +1,5 @@
1
1
  //! WebPEER.js -- https://github.com/nuzulul/webpeerjs
2
+
2
3
  import * as config from './config'
3
4
  import {
4
5
  mkErr,
@@ -95,6 +96,12 @@ class webpeerjs{
95
96
  //map of peer exchange data
96
97
  #peerexchangedata
97
98
 
99
+ //track last connect to webpeer network
100
+ #lastTimeConnectToNetwork
101
+
102
+ //arr to track on connect event
103
+ #onConnectQueue
104
+
98
105
  id
99
106
  status
100
107
  IPFS
@@ -124,6 +131,8 @@ class webpeerjs{
124
131
  this.#isDialEnabled = true
125
132
  this.#msgIdtracker = []
126
133
  this.#peerexchangedata = new Map()
134
+ this.#lastTimeConnectToNetwork = new Date().getTime()
135
+ this.#onConnectQueue = []
127
136
 
128
137
  this.peers = (function(f) {
129
138
  return f
@@ -184,6 +193,14 @@ class webpeerjs{
184
193
 
185
194
  if(this.#webPeersId.includes(id)){
186
195
 
196
+ setTimeout(()=>{
197
+ this.#ping()
198
+ },10000)
199
+
200
+ setTimeout(()=>{
201
+ this.#ping()
202
+ },15000)
203
+
187
204
  let address = [addr]
188
205
 
189
206
  if(this.#connectedPeers.has(id)){
@@ -194,7 +211,7 @@ class webpeerjs{
194
211
  }
195
212
  else{
196
213
  //add to connected webpeers
197
- this.#onConnectFn(id)
214
+ this.#onConnectFnUpdate(id)
198
215
  const now = new Date().getTime()
199
216
  const metadata = {addrs:address,last:now}
200
217
  this.#connectedPeers.set(id,metadata)
@@ -216,12 +233,25 @@ class webpeerjs{
216
233
  if (event.detail.type !== 'signed') {
217
234
  return
218
235
  }
236
+
219
237
  if(config.CONFIG_JOIN_ROOM_VERSION == 1){
220
238
  const topic = event.detail.topic
221
239
  const senderPeerId = event.detail.from.toString()
222
240
 
223
241
  try{
224
242
 
243
+ //track last connect to webpeer network
244
+ if(config.CONFIG_PUBSUB_PEER_DISCOVERY_WEBPEER.includes(topic)){
245
+ const now = new Date().getTime()
246
+ const limit = 15*1000
247
+ const lastConnectTime = now - this.#lastTimeConnectToNetwork
248
+ if(lastConnectTime > limit){
249
+ //console.log('need re announce')
250
+ this.#announce()
251
+ }
252
+ this.#lastTimeConnectToNetwork = now
253
+ }
254
+
225
255
  //if it is webpeer
226
256
  if(this.#webPeersId.includes(senderPeerId)){
227
257
 
@@ -234,7 +264,7 @@ class webpeerjs{
234
264
  }
235
265
  else{
236
266
  //add to connected webpeers
237
- this.#onConnectFn(senderPeerId)
267
+ this.#onConnectFnUpdate(senderPeerId)
238
268
  const address = this.#webPeersAddrs.get(senderPeerId)
239
269
  const now = new Date().getTime()
240
270
  const metadata = {addrs:address,last:now}
@@ -278,6 +308,20 @@ class webpeerjs{
278
308
 
279
309
  //parse the message over pupsub peer discovery
280
310
  const peer = PBPeer.decode(event.detail.data)
311
+
312
+ //detect libp2p pupsub peer discovery
313
+ if(peer.addrs.length > 1 && this.#libp2p.getPeers().length < config.CONFIG_MAX_CONNECTIONS){
314
+ let mddrs = []
315
+ for(const uaddr of peer.addrs){
316
+ const mddr = multiaddr(uaddr)
317
+ if(mddr.toString().includes('webtransport') && mddr.toString().includes('certhash')){
318
+ mddrs.push(mddr)
319
+ }
320
+ }
321
+ this.#dialMultiaddress(mddrs)
322
+ //console.log('dial '+senderPeerId,mddrs.toString())
323
+ }
324
+
281
325
  const msg = uint8ArrayToString(peer.addrs[0])
282
326
  const json = JSON.parse(msg)
283
327
  const prefix = json.prefix
@@ -287,9 +331,10 @@ class webpeerjs{
287
331
  const msgId = json.msgId
288
332
  const signal = json.signal
289
333
  const id = json.id
290
- //console.log(`from ${id}:${signal} = ${message}`)
334
+ const address = json.address
335
+ //console.log(`from ${id}:${signal} = ${msg}`)
336
+
291
337
  if(id != senderPeerId)return
292
- let address = json.address
293
338
 
294
339
  //detect special webpeer identity
295
340
  if(prefix === config.CONFIG_PREFIX){
@@ -299,7 +344,7 @@ class webpeerjs{
299
344
 
300
345
  //add to connected webpeers
301
346
  if(!this.#connectedPeers.has(id)){
302
- this.#onConnectFn(id)
347
+ this.#onConnectFnUpdate(id)
303
348
  address = []
304
349
  const now = new Date().getTime()
305
350
  const metadata = {addrs:address,last:now}
@@ -365,13 +410,16 @@ class webpeerjs{
365
410
  }
366
411
  else if(prefix === 'hybrid'){
367
412
 
368
- if(address.length>0 && !this.#connections.has(id)){
413
+ //console.log('hybrid' +id,address)
414
+ const limit = config.CONFIG_MAX_CONNECTIONS / 2
415
+ if(address.length>0 && ((!this.#connections.has(id))||(this.#connectedPeers.size < limit))){
369
416
  let mddrs = []
370
417
  for(const addr of address){
371
418
  const mddr = multiaddr(addr)
372
419
  mddrs.push(mddr)
373
420
  }
374
421
  this.#dialMultiaddress(mddrs)
422
+ //console.log('dial '+id,mddrs.toString())
375
423
  }
376
424
 
377
425
  }
@@ -450,7 +498,12 @@ class webpeerjs{
450
498
  count++
451
499
  this.#trackDisconnect.set(id,count)
452
500
  //console.log(this.#trackDisconnect)
453
- if(count>10){
501
+ if(count>5){
502
+ if(config.CONFIG_KNOWN_BOOTSTRAP_PUBLIC_IDS.includes(id)){
503
+ return
504
+ }
505
+ }
506
+ else if(count>10){
454
507
  if(this.#dbstoreData.has(id)){
455
508
  this.#dbstoreData.delete(id)
456
509
  }
@@ -618,6 +671,7 @@ class webpeerjs{
618
671
 
619
672
  setInterval(()=>{
620
673
  this.#peerDiscoveryHybrid()
674
+ this.#trackHybridPeersConnection()
621
675
  },10e3)
622
676
 
623
677
 
@@ -700,9 +754,9 @@ class webpeerjs{
700
754
  const msgId = (new Date()).getTime()
701
755
  const data = JSON.stringify({prefix:config.CONFIG_PREFIX,room,message,id:this.#libp2p.peerId.toString(),msgId})
702
756
  const arr = uint8ArrayFromString(data)
703
- const sizelimit = 102400 // 100KB
757
+ const sizelimit = config.CONFIG_MESSAGE_SIZE_LIMIT
704
758
  if(arr.byteLength > sizelimit){
705
- throw mkErr('data too large')
759
+ throw mkErr('message too large')
706
760
  }
707
761
  const peer = {
708
762
  publicKey: this.#libp2p.peerId.publicKey,
@@ -737,6 +791,39 @@ class webpeerjs{
737
791
  /*
738
792
  PRIVATE FUNCTION
739
793
  */
794
+
795
+ #trackHybridPeersConnection(){
796
+ let isConnectedToHybridPeers = false
797
+ for(const id of config.CONFIG_KNOWN_BOOTSTRAP_HYBRID_IDS){
798
+ if(this.#isConnected(id))isConnectedToHybridPeers = true
799
+ }
800
+ if(!isConnectedToHybridPeers){
801
+ for(const id of config.CONFIG_KNOWN_BOOTSTRAP_HYBRID_IDS){
802
+ if(this.status !== 'connected' && this.#connections.has(id))
803
+ {
804
+ let mddrs = []
805
+ const addr = this.#connections.get(id)
806
+ const mddr = multiaddr(addr)
807
+ mddrs.push(mddr)
808
+ this.#dialMultiaddress(mddrs)
809
+ }
810
+ }
811
+ }
812
+ }
813
+
814
+ //prevent double on connect event
815
+ #onConnectFnUpdate(id){
816
+ if(!this.#onConnectQueue.includes(id)){
817
+ this.#onConnectQueue.push(id)
818
+ this.#onConnectFn(id)
819
+ setTimeout(()=>{
820
+ const index = this.#onConnectQueue.indexOf(id)
821
+ if (index > -1) {
822
+ this.#onConnectQueue.splice(index, 1)
823
+ }
824
+ },5000)
825
+ }
826
+ }
740
827
 
741
828
  #updatePeers(){
742
829
  this.#connectedPeersArr.length = 0
@@ -794,7 +881,7 @@ class webpeerjs{
794
881
  if(!this.#webPeersId.includes(id))this.#webPeersId.push(id)
795
882
 
796
883
  //add to connected webpeers
797
- this.#onConnectFn(id)
884
+ this.#onConnectFnUpdate(id)
798
885
  const now = new Date().getTime()
799
886
  const metadata = {addrs:address,last:now}
800
887
  this.#connectedPeers.set(id,metadata)
@@ -921,7 +1008,7 @@ class webpeerjs{
921
1008
  if(!this.#webPeersId.includes(id))this.#webPeersId.push(id)
922
1009
 
923
1010
  //add to connected webpeers
924
- this.#onConnectFn(id)
1011
+ this.#onConnectFnUpdate(id)
925
1012
  const now = new Date().getTime()
926
1013
  const metadata = {addrs:address,last:now}
927
1014
  this.#connectedPeers.set(id,metadata)
@@ -1032,7 +1119,7 @@ class webpeerjs{
1032
1119
 
1033
1120
 
1034
1121
  //add multiaddr address to queue list
1035
- #dialMultiaddress(mddrs){
1122
+ async #dialMultiaddress(mddrs){
1036
1123
  if(mddrs.length>0){
1037
1124
 
1038
1125
  const id = mddrs[0].toString().split('/').pop()
@@ -1044,16 +1131,31 @@ class webpeerjs{
1044
1131
  return
1045
1132
  }
1046
1133
 
1134
+ if(this.status === 'connected' && config.CONFIG_KNOWN_BOOTSTRAP_PUBLIC_IDS.includes(id))return
1135
+
1047
1136
  const webPeerCount = this.#connectedPeers.size
1048
1137
  const allPeerCount = this.#libp2p.getPeers().length
1049
1138
  const nodePeerCount = allPeerCount - webPeerCount
1050
1139
  const limitCount = config.CONFIG_MAX_CONNECTIONS / 2
1051
1140
 
1052
1141
  if(this.#webPeersId.includes(id)){
1053
- if(webPeerCount>limitCount)return
1142
+ if(webPeerCount>limitCount){
1143
+ return
1144
+ }
1054
1145
  }
1055
1146
  else{
1056
- if(nodePeerCount>limitCount)return
1147
+ if((nodePeerCount>(limitCount-5))||(allPeerCount>(config.CONFIG_MAX_CONNECTIONS-5))){
1148
+ //close random peers
1149
+ let peers = []
1150
+ for(const peer of this.#libp2p.getPeers()){
1151
+ peers.push(peer.toString())
1152
+ }
1153
+ const randomKey = Math.floor(Math.random() * peers.length)
1154
+ const randompeerid = peers[randomKey]
1155
+ if(!config.CONFIG_KNOWN_BOOTSTRAP_HYBRID_IDS.includes(id)){
1156
+ await this.#libp2p.hangUp(peerIdFromString(randompeerid))
1157
+ }
1158
+ }
1057
1159
  }
1058
1160
 
1059
1161
  if(this.#webPeersId.includes(id) || config.CONFIG_KNOWN_BOOTSTRAP_PEERS_IDS.includes(id) || config.CONFIG_KNOWN_BOOTSTRAP_HYBRID_IDS.includes(id)){
@@ -1069,7 +1171,7 @@ class webpeerjs{
1069
1171
  //dial multiaddr address in queue list
1070
1172
  #dialQueueList(){
1071
1173
 
1072
- if(!this.#isDialEnabled || !navigator.onLine)return
1174
+ if(!this.#isDialEnabled || !navigator.onLine || (document.visibilityState === 'hidden' && ('ontouchstart' in document.documentElement)) )return
1073
1175
 
1074
1176
  const mddrsToDial = 5
1075
1177
 
@@ -1361,13 +1463,13 @@ class webpeerjs{
1361
1463
  #dialKnownPeers(){
1362
1464
  setTimeout(()=>{
1363
1465
  this.#dialSavedKnownID()
1364
- setTimeout(()=>{this.#dialUpdateSavedKnownID()},50000)
1365
- setTimeout(()=>{this.#findHybridPeer()},60000)
1466
+ setTimeout(()=>{this.#dialUpdateSavedKnownID()},20000)
1467
+ setTimeout(()=>{this.#findHybridPeer()},30000)
1366
1468
  setTimeout(()=>{
1367
1469
  const peers = this.#libp2p.getPeers().length
1368
1470
  if(peers == 0){
1369
1471
  this.#dialKnownID()
1370
- setTimeout(()=>{this.#findHybridPeer()},60000)
1472
+ setTimeout(()=>{this.#findHybridPeer()},30000)
1371
1473
  setTimeout(()=>{
1372
1474
  const peers = this.#libp2p.getPeers().length
1373
1475
  if(peers == 0){
@@ -1701,6 +1803,102 @@ class webpeerjs{
1701
1803
  listenaddress.push('/webrtc')
1702
1804
  }
1703
1805
 
1806
+ const turnurls = atob(config.CONFIG_WEBRTC_TURN_HOST)
1807
+ const turnusername = atob(config.CONFIG_WEBRTC_TURN_USER)
1808
+ const turncredential = atob(config.CONFIG_WEBRTC_TURN_PWD)
1809
+
1810
+ const turnurlsbackup = atob(config.CONFIG_WEBRTC_TURN_HOST_BACKUP)
1811
+ const turnusernamebackup = atob(config.CONFIG_WEBRTC_TURN_USER_BACKUP)
1812
+ const turncredentialbackup = atob(config.CONFIG_WEBRTC_TURN_PWD_BACKUP)
1813
+
1814
+ const ice = await new Promise((resolve)=>{
1815
+
1816
+ let stun = false
1817
+ let turn = false
1818
+
1819
+ const timeout = setTimeout(()=>{
1820
+ let ice = []
1821
+ if(stun){
1822
+ ice.push(stun)
1823
+ }else{
1824
+ const backup = {
1825
+ urls: config.CONFIG_WEBRTC_STUN_URLS_BACKUP
1826
+ }
1827
+ ice.push(backup)
1828
+ }
1829
+ if(turn){
1830
+ ice.push(turn)
1831
+ }else{
1832
+ const backup = {
1833
+ urls: turnurlsbackup,
1834
+ username: turnusernamebackup,
1835
+ credential: turncredentialbackup
1836
+ }
1837
+ ice.push(backup)
1838
+ }
1839
+ resolve(ice)
1840
+ },5000)
1841
+
1842
+ function check(){
1843
+ if(stun && turn){
1844
+ let ice = []
1845
+ ice.push(stun)
1846
+ ice.push(turn)
1847
+ clearTimeout(timeout)
1848
+ resolve(ice)
1849
+ }
1850
+ }
1851
+
1852
+ //test ice servers
1853
+
1854
+ const iceServers = [
1855
+ {
1856
+ urls: config.CONFIG_WEBRTC_STUN_URLS
1857
+ },
1858
+ {
1859
+ urls: turnurls,
1860
+ username: turnusername,
1861
+ credential: turncredential
1862
+ }
1863
+ ];
1864
+
1865
+ const pc = new RTCPeerConnection({
1866
+ iceServers
1867
+ });
1868
+
1869
+ pc.onicecandidate = (e) => {
1870
+ if (!e.candidate) return;
1871
+
1872
+ //console.log(e.candidate.candidate);
1873
+
1874
+ // stun works
1875
+ if(e.candidate.type == "srflx"){
1876
+ //console.log('publicip',e.candidate.address);
1877
+ stun = {
1878
+ urls: config.CONFIG_WEBRTC_STUN_URLS
1879
+ }
1880
+ check()
1881
+ }
1882
+
1883
+ // turn works
1884
+ if(e.candidate.type == "relay"){
1885
+ turn = {
1886
+ urls: turnurls,
1887
+ username: turnusername,
1888
+ credential: turncredential
1889
+ }
1890
+ check()
1891
+ }
1892
+ };
1893
+
1894
+ pc.onicecandidateerror = (e) => {
1895
+ //console.error(e);
1896
+ };
1897
+
1898
+ pc.createDataChannel('webpeerjs');
1899
+ pc.createOffer().then(offer => pc.setLocalDescription(offer));
1900
+ })
1901
+
1704
1902
  //create libp2p instance
1705
1903
  const libp2p = await createLibp2p({
1706
1904
  addresses: {
@@ -1711,11 +1909,7 @@ class webpeerjs{
1711
1909
  webSockets(),
1712
1910
  webRTC({
1713
1911
  rtcConfiguration: {
1714
- iceServers: [
1715
- {
1716
- urls: ['stun:stun.l.google.com:19302', 'stun:global.stun.twilio.com:3478'],
1717
- },
1718
- ],
1912
+ iceServers: ice,
1719
1913
  },
1720
1914
  }),
1721
1915
  circuitRelayTransport({