@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.
package/package.json CHANGED
@@ -1,10 +1,9 @@
1
1
  {
2
2
  "name": "@leofcoin/peernet",
3
- "version": "0.12.1",
3
+ "version": "0.13.0",
4
4
  "description": "",
5
5
  "main": "dist/commonjs/peernet.js",
6
- "module": "dist/module/peernet.js",
7
- "browser": "dist/browser/peernet.js",
6
+ "module": "src/module/peernet.js",
8
7
  "scripts": {
9
8
  "build": "npm run c && webpack",
10
9
  "test": "node test/index.js",
@@ -23,13 +22,14 @@
23
22
  "license": "MIT",
24
23
  "browserslist": "> 0.5%, last 2 versions, not dead",
25
24
  "dependencies": {
26
- "@leofcoin/codec-format-interface": "^1.1.1",
27
- "@leofcoin/generate-account": "^1.0.2",
25
+ "@leofcoin/codec-format-interface": "^1.2.5",
26
+ "@leofcoin/generate-account": "^1.0.4",
28
27
  "@leofcoin/multi-wallet": "^2.1.2",
29
- "@leofcoin/peernet-swarm": "^0.3.1",
28
+ "@leofcoin/peernet-swarm": "^0.3.3",
30
29
  "@leofcoin/storage": "^2.3.0",
31
30
  "@vandeurenglenn/base32": "^1.1.0",
32
31
  "@vandeurenglenn/base58": "^1.1.0",
32
+ "@vandeurenglenn/debug": "^1.0.0",
33
33
  "@vandeurenglenn/is-hex": "^1.0.0",
34
34
  "@vandeurenglenn/little-pubsub": "^1.3.1",
35
35
  "keccak": "^3.0.1",
@@ -41,10 +41,7 @@
41
41
  "varint": "^6.0.0"
42
42
  },
43
43
  "devDependencies": {
44
- "@babel/plugin-proposal-private-methods": "^7.16.11",
45
- "@rollup/plugin-eslint": "^8.0.1",
46
44
  "@rollup/plugin-json": "^4.1.0",
47
- "@vandeurenglenn/debug": "^1.0.0",
48
45
  "coveralls": "^3.1.1",
49
46
  "eslint": "^7.31.0",
50
47
  "eslint-config-google": "^0.14.0",
@@ -56,7 +53,6 @@
56
53
  "tape": "^5.2.2",
57
54
  "vm-browserify": "^1.1.2",
58
55
  "webpack": "^5.72.0",
59
- "webpack-cli": "^4.9.2",
60
- "webpack-node-externals": "^3.0.0"
56
+ "webpack-cli": "^4.9.2"
61
57
  }
62
58
  }
package/rollup.config.js CHANGED
@@ -1,5 +1,4 @@
1
1
  import { execSync } from 'child_process';
2
- import lint from '@rollup/plugin-eslint'
3
2
  import json from '@rollup/plugin-json'
4
3
  import modify from 'rollup-plugin-modify'
5
4
 
@@ -10,7 +9,7 @@ try {
10
9
  }
11
10
  export default [{
12
11
  input: ['src/peernet.js', 'src/messages/dht.js',
13
- 'src/messages/peernet-message.js', 'src/messages/dht-response.js', 'src/messages/request.js',
12
+ 'src/messages/peernet.js', 'src/messages/dht-response.js', 'src/messages/request.js',
14
13
  'src/messages/response.js'],
15
14
  output: {
16
15
  dir: 'dist/commonjs',
@@ -26,25 +25,7 @@ export default [{
26
25
  }, {
27
26
  input: 'src/peernet.js',
28
27
  output: {
29
- dir: 'dist/browser/',
30
- format: 'cjs'
31
- },
32
- plugins: [
33
- json(),
34
- modify({
35
- "import fetch from 'node-fetch'": '',
36
- HTTP_IMPORT: ``,
37
- SUBTLE_IMPORT: `const { subtle } = crypto`
38
- }),
39
- // lint({
40
- // fix: true,
41
- // exclude: ['package.json', "package-lock.json"]
42
- // })
43
- ]
44
- }, {
45
- input: 'src/peernet.js',
46
- output: {
47
- file: 'dist/module/peernet.js',
28
+ dir: 'dist/module',
48
29
  format: 'es'
49
30
  },
50
31
  plugins: [
@@ -1,6 +1,5 @@
1
- import MultiWallet from './../../node_modules/@leofcoin/multi-wallet/src/index'
2
- import { CodecHash as Hash } from '@leofcoin/codec-format-interface'
3
- import PeernetMessage from './../messages/peernet-message.js'
1
+ import MultiWallet from '@leofcoin/multi-wallet'
2
+ import { CodecHash } from '@leofcoin/codec-format-interface'
4
3
 
5
4
  export default class MessageHandler {
6
5
  constructor(network) {
@@ -17,7 +16,7 @@ export default class MessageHandler {
17
16
  * @return signature
18
17
  */
19
18
  async hashAndSignMessage(message) {
20
- const hasher = new Hash(message, {name: 'peernet-message'})
19
+ const hasher = new CodecHash(message, {name: 'peernet-message'})
21
20
  let identity = await walletStore.get('identity')
22
21
  identity = JSON.parse(new TextDecoder().decode(identity))
23
22
  const wallet = new MultiWallet(this.network)
@@ -40,7 +39,7 @@ export default class MessageHandler {
40
39
  data,
41
40
  }
42
41
  const signature = await this.hashAndSignMessage(message)
43
- const node = await new PeernetMessage({
42
+ const node = await new globalThis.peernet.protos['peernet-message']({
44
43
  ...message,
45
44
  signature,
46
45
  })
File without changes
@@ -0,0 +1,21 @@
1
+ import proto from './../proto/file.proto.js'
2
+ import { FormatInterface } from '@leofcoin/codec-format-interface'
3
+
4
+ /**
5
+ * @extends {CodecFormat}
6
+ */
7
+ export default class PeernetFile extends FormatInterface {
8
+ get keys() {
9
+ return ['path', 'content', 'links']
10
+ }
11
+
12
+ get messageName() {
13
+ return 'PeernetFile'
14
+ }
15
+ /**
16
+ * @param {Buffer|String|Object|DataMessage} data - The data needed to create the DataMessage
17
+ */
18
+ constructor(data) {
19
+ super(data, proto, {name: 'peernet-file'})
20
+ }
21
+ }
File without changes
@@ -0,0 +1,13 @@
1
+ export { default as PeernetMessage } from './messages/peernet.js'
2
+ export { default as DHTMessage } from './messages/dht.js'
3
+ export { default as DHTMessageResponse } from './messages/dht-response.js'
4
+ export { default as DataMessage } from './messages/data.js'
5
+ export { default as PsMessage } from './messages/ps.js'
6
+ export { default as PeerMessage } from './messages/peer.js'
7
+ export { default as RequestMessage } from './messages/request.js'
8
+ export { default as ResponseMessage } from './messages/response.js'
9
+ export { default as PeerMessageResponse } from './messages/peer-response.js'
10
+ export { default as DataMessageResponse } from './messages/data-response.js'
11
+ export { default as ChatMessage } from './messages/chat.js'
12
+ export { default as PeernetFile } from './messages/file.js'
13
+ // export { default as FolderMessageResponse } from './messages/folder-response.js'
package/src/peernet.js CHANGED
@@ -1,28 +1,17 @@
1
1
  import '@vandeurenglenn/debug'
2
- import Client from './../node_modules/@leofcoin/peernet-swarm/dist/es/client.js'
3
- import LeofcoinStorage from '@leofcoin/storage'
4
- import PeernetMessage from './messages/peernet-message.js'
5
- import DHTMessage from './messages/dht.js'
6
- import DHTMessageResponse from './messages/dht-response.js'
7
- import DataMessage from './messages/data.js'
8
- import PsMessage from './messages/ps.js'
9
- import PeerMessage from './messages/peer.js'
10
- import RequestMessage from './messages/request.js'
11
- import ResponseMessage from './messages/response.js'
12
- import PeerMessageResponse from './messages/peer-response.js'
13
- import DataMessageResponse from './messages/data-response.js'
14
- import ChatMessage from './messages/chat-message.js'
2
+ import PubSub from '@vandeurenglenn/little-pubsub'
15
3
  import PeerDiscovery from './discovery/peer-discovery'
16
4
  import DHT from './dht/dht.js'
17
- import { CodecHash as Hash, codecs} from '@leofcoin/codec-format-interface'
5
+ import { CodecHash, codecs} from '@leofcoin/codec-format-interface'
18
6
  import { protoFor, target } from './utils/utils.js'
19
- import generateAccount from './../node_modules/@leofcoin/generate-account/dist/module/generate-account'
20
7
  import MessageHandler from './handlers/message.js'
21
8
  import dataHandler from './handlers/data.js'
22
9
  import { encapsulatedError, dhtError,
23
10
  nothingFoundError } from './errors/errors.js'
24
11
 
12
+ import {parse} from 'path'
25
13
  globalThis.leofcoin = globalThis.leofcoin || {}
14
+ globalThis.pubsub = globalThis.pubsub || new PubSub()
26
15
  globalThis.globalSub = globalThis.globalSub || new PubSub({verbose: true})
27
16
 
28
17
  /**
@@ -69,16 +58,12 @@ export default class Peernet {
69
58
  return ['account', 'wallet', 'block', 'transaction', 'chain', 'data', 'message']
70
59
  }
71
60
 
72
- get protos() {
73
- return globalThis.peernet.protos
74
- }
75
-
76
61
  get codecs() {
77
62
  return codecs
78
63
  }
79
64
 
80
65
  addProto(name, proto) {
81
- if (!this.protos[name]) this.protos[name] = proto
66
+ if (!globalThis.peernet.protos[name]) globalThis.peernet.protos[name] = proto
82
67
  }
83
68
 
84
69
  addCodec(name, codec) {
@@ -86,6 +71,10 @@ export default class Peernet {
86
71
  }
87
72
 
88
73
  async addStore(name, prefix, root, isPrivate = true) {
74
+ if (!globalThis.LeofcoinStorage) {
75
+ const importee = await import(/* webpackChunkName: "storage" */ '@leofcoin/storage')
76
+ globalThis.LeofcoinStorage = importee.default
77
+ }
89
78
  if (name === 'block' || name === 'transaction' || name === 'chain' ||
90
79
  name === 'data' || name === 'message') isPrivate = false
91
80
 
@@ -93,7 +82,7 @@ export default class Peernet {
93
82
  if (this.hasDaemon) {
94
83
  Storage = LeofcoinStorageClient
95
84
  } else {
96
- Storage = globalThis.LeofcoinStorage?.default ? globalThis.LeofcoinStorage.default : LeofcoinStorage
85
+ Storage = LeofcoinStorage
97
86
  }
98
87
  globalThis[`${name}Store`] = globalThis[`${name}Store`] ||
99
88
  await new Storage(name, root)
@@ -158,6 +147,22 @@ export default class Peernet {
158
147
  this.storePrefix = options.storePrefix
159
148
  this.root = options.root
160
149
 
150
+ const {
151
+ RequestMessage,
152
+ ResponseMessage,
153
+ PeerMessage,
154
+ PeerMessageResponse,
155
+ PeernetMessage,
156
+ DHTMessage,
157
+ DHTMessageResponse,
158
+ DataMessage,
159
+ DataMessageResponse,
160
+ PsMessage,
161
+ ChatMessage,
162
+ PeernetFile
163
+ // FolderMessageResponse
164
+ } = await import(/* webpackChunkName: "messages" */ './messages.js')
165
+
161
166
  /**
162
167
  * proto Object containing protos
163
168
  * @type {Object}
@@ -167,6 +172,7 @@ export default class Peernet {
167
172
  * @property {DataMessage} protos[peernet-data] messageNode
168
173
  * @property {DataMessageResponse} protos[peernet-data-response] messageNode
169
174
  */
175
+
170
176
  globalThis.peernet.protos = {
171
177
  'peernet-request': RequestMessage,
172
178
  'peernet-response': ResponseMessage,
@@ -179,6 +185,7 @@ export default class Peernet {
179
185
  'peernet-data-response': DataMessageResponse,
180
186
  'peernet-ps': PsMessage,
181
187
  'chat-message': ChatMessage,
188
+ 'peernet-file': PeernetFile
182
189
  }
183
190
 
184
191
  this._messageHandler = new MessageHandler(this.network)
@@ -205,6 +212,9 @@ export default class Peernet {
205
212
  }
206
213
  } catch (e) {
207
214
  if (e.code === 'ERR_NOT_FOUND') {
215
+
216
+ const importee = await import(/* webpackChunkName: "generate-account" */ '@leofcoin/generate-account')
217
+ const generateAccount = importee.default
208
218
  const wallet = {}
209
219
  const {identity, accounts, config} = await generateAccount(this.network)
210
220
  walletStore.put('version', new TextEncoder().encode(1))
@@ -238,11 +248,13 @@ export default class Peernet {
238
248
  */
239
249
  pubsub.subscribe('peer:data', dataHandler)
240
250
 
251
+
252
+ const importee = await import(/* webpackChunkName: "peernet-swarm" */ '@leofcoin/peernet-swarm')
241
253
  /**
242
254
  * @access public
243
255
  * @type {PeernetClient}
244
256
  */
245
- this.client = new Client(this.id)
257
+ this.client = new importee.default(this.id)
246
258
  if (globalThis.onbeforeunload) {
247
259
  globalThis.addEventListener('beforeunload', async () => this.client.close());
248
260
  }
@@ -284,7 +296,7 @@ export default class Peernet {
284
296
  if (store.private) has = false
285
297
  else has = await store.has(hash)
286
298
  }
287
- const data = await new DHTMessageResponse({hash, has})
299
+ const data = await new globalThis.peernet.protos['peernet-dht-response']({hash, has})
288
300
  const node = await this.prepareMessage(from, data.encoded)
289
301
 
290
302
  this.sendMessage(peer, id, node.encoded)
@@ -300,7 +312,7 @@ export default class Peernet {
300
312
  data = await store.get(hash)
301
313
 
302
314
  if (data) {
303
- data = await new DataMessageResponse({hash, data});
315
+ data = await new globalThis.peernet.protos['peernet-data-response']({hash, data});
304
316
 
305
317
  const node = await this.prepareMessage(from, data.encoded)
306
318
  this.sendMessage(peer, id, node.encoded)
@@ -329,7 +341,7 @@ export default class Peernet {
329
341
  */
330
342
  async walk(hash) {
331
343
  if (!hash) throw new Error('hash expected, received undefined')
332
- const data = await new DHTMessage({hash})
344
+ const data = await new globalThis.peernet.protos['peernet-dht']({hash})
333
345
  const clientId = this.client.id
334
346
  const walk = async peer => {
335
347
  const node = await this.prepareMessage(peer.peerId, data.encoded)
@@ -437,7 +449,7 @@ export default class Peernet {
437
449
  if (peer.peerId === id) return peer
438
450
  })
439
451
 
440
- let data = await new DataMessage({hash, store: store?.name ? store?.name : store});
452
+ let data = await new globalThis.peernet.protos['peernet-data']({hash, store: store?.name ? store?.name : store});
441
453
 
442
454
  const node = await this.prepareMessage(id, data.encoded)
443
455
  if (closest[0]) data = await closest[0].request(node.encoded)
@@ -515,6 +527,76 @@ export default class Peernet {
515
527
  }
516
528
  }
517
529
 
530
+ get folder() {
531
+ return {
532
+ /**
533
+ * Get content for given data hash
534
+ *
535
+ * @param {String} hash
536
+ */
537
+ get: async (hash) => {
538
+ debug(`get data ${hash}`)
539
+ const data = await dataStore.has(hash)
540
+ if (data) return await dataStore.get(hash)
541
+ return this.requestData(hash, 'data')
542
+ },
543
+ /**
544
+ * put data content
545
+ *
546
+ * @param {String} hash
547
+ * @param {Buffer} data
548
+ */
549
+ put: async (hash, data) => await dataStore.put(hash, data),
550
+ /**
551
+ * @param {String} hash
552
+ * @return {Boolean}
553
+ */
554
+ has: async (hash) => await dataStore.has(hash),
555
+ }
556
+ }
557
+
558
+ async addFolder(files) {
559
+ const links = []
560
+ for (const file of files) {
561
+ const fileNode = await new globalThis.peernet.protos['peernet-file'](file)
562
+ const hash = await fileNode.hash
563
+ await dataStore.put(hash, fileNode.encoded)
564
+ links.push({hash, path: file.path})
565
+ }
566
+ const node = await new globalThis.peernet.protos['peernet-file']({path: '/', links})
567
+ const hash = await node.hash
568
+ await dataStore.put(hash, node.encoded)
569
+
570
+ return hash
571
+ }
572
+
573
+ async ls(hash) {
574
+ let data
575
+ const has = await dataStore.has(hash)
576
+ if (has) data = await dataStore.get(hash)
577
+ else data = await this.requestData(hash, 'data')
578
+
579
+ const node = await new peernet.protos['peernet-file'](data)
580
+ const paths = []
581
+ if (node.decoded?.links.length === 0) throw new Error(`${hash} is a file`)
582
+ for (const {path, hash} of node.decoded.links) {
583
+ paths.push({path, hash})
584
+ }
585
+
586
+ return paths
587
+ }
588
+
589
+ async cat(hash) {
590
+ let data
591
+ const has = await dataStore.has(hash)
592
+ if (has) data = await dataStore.get(hash)
593
+ else data = await this.requestData(hash, 'data')
594
+ const node = await new peernet.protos['peernet-file'](data)
595
+ const paths = []
596
+ if (node.decoded?.links.length > 0) throw new Error(`${hash} is a directory`)
597
+ return node.decoded.content
598
+ }
599
+
518
600
  /**
519
601
  * goes trough given stores and tries to find data for given hash
520
602
  * @param {Array} stores
@@ -583,7 +665,7 @@ export default class Peernet {
583
665
  if (topic instanceof Uint8Array === false) topic = new TextEncoder().encode(topic)
584
666
  if (data instanceof Uint8Array === false) data = new TextEncoder().encode(JSON.stringify(data))
585
667
  const id = Math.random().toString(36).slice(-12)
586
- data = await new PsMessage({data, topic})
668
+ data = await new globalThis.peernet.protos['peernet-ps']({data, topic})
587
669
  for (const peer of this.connections) {
588
670
  if (peer.peerId !== this.peerId) {
589
671
  const node = await this.prepareMessage(peer.peerId, data.encoded)
@@ -594,7 +676,7 @@ export default class Peernet {
594
676
  }
595
677
 
596
678
  createHash(data, name) {
597
- return new Hash(data, {name})
679
+ return new CodeHash(data, {name})
598
680
  }
599
681
 
600
682
  /**
@@ -0,0 +1,14 @@
1
+ export default `
2
+ // PeernetFolder
3
+ message PeernetFileLink {
4
+ required string hash = 1;
5
+ required string path = 2;
6
+ optional string size = 3;
7
+ }
8
+
9
+ message PeernetFile {
10
+ required string path = 1;
11
+ optional string content = 2;
12
+ repeated PeernetFileLink links = 3;
13
+ }
14
+ `
package/test.js CHANGED
@@ -1,35 +1,47 @@
1
- const Client = require('./dist/commonjs/peernet.js')
1
+ const Client = require('./dist/commonjs/peernet.js');
2
2
 
3
- const client = new Client({root: '.peernet/test'})
4
3
 
5
- pubsub.subscribe('peer:connected', async peer => {
6
- chainStore.put('localBlock', '00000')
7
- const request = new globalThis.peernet.protos['peernet-request']({
8
- request:'lastBlock'
9
- })
10
- const to = peer.id
11
- await peernet.data.put('hello', 'hi')
12
- console.log(request);
13
- const node = await peernet.prepareMessage(to, request.encoded)
14
- console.log({node});
15
- let response = await peer.request(node.encoded)
16
- console.log({response});
17
- const keys = Object.keys(response)
18
- const uint8Array = new Uint8Array(keys.length)
19
- for (const key of keys) {
20
- uint8Array[Number(key)] = response[key]
21
- }
22
- const proto = new globalThis.peernet.protos['peernet-message'](uint8Array)
23
- console.log(proto.decoded.data);
24
- response = new globalThis.peernet.protos['peernet-response'](proto.decoded.data)
25
- console.log({response});
4
+ (async () => {
5
+ const client = await new Client({root: '.peernet/test'})
26
6
 
27
- const block = new TextDecoder().decode(response.decoded.response)
28
- console.log(block);
29
- const task = () => setTimeout(() => {
30
- console.log(peernet.connections[0]?.connected);
31
- console.log(pubsub.subscribers);
7
+ peernet.addFolder([{
8
+ path: 'assets/asset.png',
9
+ content: 'png'
10
+ }, {
11
+ path: 'index.html',
12
+ content: 'html'
13
+ }]).then(hash => peernet.ls(hash).then(paths => peernet.cat(paths[0].hash).then(content => console.log(content))))
14
+
15
+ pubsub.subscribe('peer:connected', async peer => {
16
+ chainStore.put('localBlock', '00000')
17
+ const request = await new globalThis.peernet.protos['peernet-request']({
18
+ request:'lastBlock'
19
+ })
20
+ const to = peer.id
21
+ await peernet.data.put('hello', 'hi')
22
+ console.log(request);
23
+ const node = await peernet.prepareMessage(to, request.encoded)
24
+ console.log({node});
25
+ let response = await peer.request(node.encoded)
26
+ console.log({response});
27
+ const keys = Object.keys(response)
28
+ const uint8Array = new Uint8Array(keys.length)
29
+ for (const key of keys) {
30
+ uint8Array[Number(key)] = response[key]
31
+ }
32
+ const proto = await new globalThis.peernet.protos['peernet-message'](uint8Array)
33
+ console.log(proto.decoded.data);
34
+ response = await new globalThis.peernet.protos['peernet-response'](proto.decoded.data)
35
+ console.log({response});
36
+
37
+ const block = new TextDecoder().decode(response.decoded.response)
38
+ console.log(block);
39
+ const task = () => setTimeout(() => {
40
+ console.log(peernet.connections[0]?.connected);
41
+ console.log(pubsub.subscribers);
42
+ task()
43
+ }, 5000);
32
44
  task()
33
- }, 5000);
34
- task()
35
- })
45
+ })
46
+
47
+ })()
package/webpack.config.js CHANGED
@@ -1,7 +1,7 @@
1
1
  const path = require('path');
2
2
  const webpack = require('webpack');
3
3
  module.exports = [{
4
- entry: './dist/browser/peernet.js',
4
+ entry: './src/peernet.js',
5
5
  mode: 'production',
6
6
  plugins: [
7
7
  // Work around for Buffer is undefined:
@@ -26,6 +26,9 @@ module.exports = [{
26
26
  optimization: {
27
27
  minimize: false
28
28
  },
29
+ experiments: {
30
+ outputModule: true
31
+ },
29
32
  resolve: {
30
33
  extensions: [ '.ts', '.js' ],
31
34
  fallback: {
@@ -41,9 +44,9 @@ resolve: {
41
44
  },
42
45
  output: {
43
46
  library: {
44
- name: 'Peernet',
45
- type: 'global'
47
+ type: 'module'
46
48
  },
49
+ chunkFilename: '[name].js',
47
50
  filename: 'peernet.js',
48
51
  path: path.resolve(__dirname, 'dist', 'browser'),
49
52
  },