@leofcoin/peernet 0.12.2 → 0.13.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.
@@ -1,6 +1,6 @@
1
1
  import { FormatInterface } from '@leofcoin/codec-format-interface';
2
2
 
3
- var proto$a = `
3
+ var proto$b = `
4
4
  // PeernetMessage
5
5
  message PeernetMessage {
6
6
  required bytes data = 1;
@@ -21,16 +21,11 @@ class PeernetMessage extends FormatInterface {
21
21
 
22
22
  constructor(buffer) {
23
23
  const name = 'peernet-message';
24
- super(buffer, proto$a, {name});
24
+ super(buffer, proto$b, {name});
25
25
  }
26
26
  }
27
27
 
28
- var peernet = /*#__PURE__*/Object.freeze({
29
- __proto__: null,
30
- 'default': PeernetMessage
31
- });
32
-
33
- var proto$9 = `
28
+ var proto$a = `
34
29
  // PeernetDHTMessage
35
30
  message PeernetDHTMessage {
36
31
  required string hash = 1;
@@ -60,16 +55,11 @@ class DHTMessage extends FormatInterface {
60
55
 
61
56
  constructor(data) {
62
57
  const name = 'peernet-dht';
63
- super(data, proto$9, {name});
58
+ super(data, proto$a, {name});
64
59
  }
65
60
  }
66
61
 
67
- var dht = /*#__PURE__*/Object.freeze({
68
- __proto__: null,
69
- 'default': DHTMessage
70
- });
71
-
72
- var proto$8 = `
62
+ var proto$9 = `
73
63
  // PeernetDHTMessageResponse
74
64
  message PeernetDHTMessageResponse {
75
65
  required string hash = 1;
@@ -88,16 +78,11 @@ class DHTMessageResponse extends FormatInterface {
88
78
 
89
79
  constructor(data) {
90
80
  const name = 'peernet-dht-response';
91
- super(data, proto$8, {name});
81
+ super(data, proto$9, {name});
92
82
  }
93
83
  }
94
84
 
95
- var dhtResponse = /*#__PURE__*/Object.freeze({
96
- __proto__: null,
97
- 'default': DHTMessageResponse
98
- });
99
-
100
- var proto$7 = `
85
+ var proto$8 = `
101
86
  // PeernetDataMessage
102
87
  message PeernetDataMessage {
103
88
  required string hash = 1;
@@ -120,16 +105,11 @@ class DataMessage extends FormatInterface {
120
105
  * @param {Buffer|String|Object|DataMessage} data - The data needed to create the DataMessage
121
106
  */
122
107
  constructor(data) {
123
- super(data, proto$7, {name: 'peernet-data'});
108
+ super(data, proto$8, {name: 'peernet-data'});
124
109
  }
125
110
  }
126
111
 
127
- var data = /*#__PURE__*/Object.freeze({
128
- __proto__: null,
129
- 'default': DataMessage
130
- });
131
-
132
- var proto$6 = `
112
+ var proto$7 = `
133
113
  // PsMessage
134
114
  message PsMessage {
135
115
  required bytes data = 1;
@@ -147,16 +127,11 @@ class PsMessage extends FormatInterface {
147
127
 
148
128
  constructor(buffer) {
149
129
  const name = 'peernet-ps';
150
- super(buffer, proto$6, {name});
130
+ super(buffer, proto$7, {name});
151
131
  }
152
132
  }
153
133
 
154
- var ps = /*#__PURE__*/Object.freeze({
155
- __proto__: null,
156
- 'default': PsMessage
157
- });
158
-
159
- var proto$5 = `
134
+ var proto$6 = `
160
135
  // PeernetPeerMessage
161
136
  message PeernetPeerMessage {
162
137
  required string id = 1;
@@ -174,16 +149,11 @@ class PeerMessage extends FormatInterface {
174
149
 
175
150
  constructor(data) {
176
151
  const name = 'peernet-peer';
177
- super(data, proto$5, {name});
152
+ super(data, proto$6, {name});
178
153
  }
179
154
  }
180
155
 
181
- var peer = /*#__PURE__*/Object.freeze({
182
- __proto__: null,
183
- 'default': PeerMessage
184
- });
185
-
186
- var proto$4 = `
156
+ var proto$5 = `
187
157
  // PeernetRequestMessage
188
158
  message PeernetRequestMessage {
189
159
  required string request = 1;
@@ -201,16 +171,11 @@ class RequestMessage extends FormatInterface {
201
171
 
202
172
  constructor(data) {
203
173
  const name = 'peernet-request';
204
- super(data, proto$4, {name});
174
+ super(data, proto$5, {name});
205
175
  }
206
176
  }
207
177
 
208
- var request = /*#__PURE__*/Object.freeze({
209
- __proto__: null,
210
- 'default': RequestMessage
211
- });
212
-
213
- var proto$3 = `
178
+ var proto$4 = `
214
179
  // PeernetResponseMessage
215
180
  message PeernetResponseMessage {
216
181
  required bytes response = 1;
@@ -228,16 +193,11 @@ class ResponseMessage extends FormatInterface {
228
193
 
229
194
  constructor(data) {
230
195
  const name = 'peernet-response';
231
- super(data, proto$3, {name});
196
+ super(data, proto$4, {name});
232
197
  }
233
198
  }
234
199
 
235
- var response = /*#__PURE__*/Object.freeze({
236
- __proto__: null,
237
- 'default': ResponseMessage
238
- });
239
-
240
- var proto$2 = `
200
+ var proto$3 = `
241
201
  // PeernetPeerMessageResponse
242
202
  message PeernetPeerMessageResponse {
243
203
  required string id = 1;
@@ -255,16 +215,11 @@ class PeerMessageResponse extends FormatInterface {
255
215
 
256
216
  constructor(data) {
257
217
  const name = 'peernet-peer-response';
258
- super(data, proto$2, {name});
218
+ super(data, proto$3, {name});
259
219
  }
260
220
  }
261
221
 
262
- var peerResponse = /*#__PURE__*/Object.freeze({
263
- __proto__: null,
264
- 'default': PeerMessageResponse
265
- });
266
-
267
- var proto$1 = `
222
+ var proto$2 = `
268
223
  // PeernetDataMessageResponse
269
224
  message PeernetDataMessageResponse {
270
225
  required string hash = 1;
@@ -283,16 +238,11 @@ class DataMessageResponse extends FormatInterface {
283
238
 
284
239
  constructor(data) {
285
240
  const name = 'peernet-data-response';
286
- super(data, proto$1, {name});
241
+ super(data, proto$2, {name});
287
242
  }
288
243
  }
289
244
 
290
- var dataResponse = /*#__PURE__*/Object.freeze({
291
- __proto__: null,
292
- 'default': DataMessageResponse
293
- });
294
-
295
- var proto = `
245
+ var proto$1 = `
296
246
  message ChatMessage {
297
247
  required string value = 1;
298
248
  required string author = 2;
@@ -311,13 +261,42 @@ class ChatMessage extends FormatInterface {
311
261
 
312
262
  constructor(buffer) {
313
263
  const name = 'chat-message';
314
- super(buffer, proto, {name});
264
+ super(buffer, proto$1, {name});
315
265
  }
316
266
  }
317
267
 
318
- var chat = /*#__PURE__*/Object.freeze({
319
- __proto__: null,
320
- 'default': ChatMessage
321
- });
268
+ var proto = `
269
+ // PeernetFolder
270
+ message PeernetFileLink {
271
+ required string hash = 1;
272
+ required string path = 2;
273
+ optional string size = 3;
274
+ }
275
+
276
+ message PeernetFile {
277
+ required string path = 1;
278
+ optional string content = 2;
279
+ repeated PeernetFileLink links = 3;
280
+ }
281
+ `;
282
+
283
+ /**
284
+ * @extends {CodecFormat}
285
+ */
286
+ class PeernetFile extends FormatInterface {
287
+ get keys() {
288
+ return ['path', 'content', 'links']
289
+ }
290
+
291
+ get messageName() {
292
+ return 'PeernetFile'
293
+ }
294
+ /**
295
+ * @param {Buffer|String|Object|DataMessage} data - The data needed to create the DataMessage
296
+ */
297
+ constructor(data) {
298
+ super(data, proto, {name: 'peernet-file'});
299
+ }
300
+ }
322
301
 
323
- export { chat as ChatMessage, dht as DHTMessage, dhtResponse as DHTMessageResponse, data as DataMessage, dataResponse as DataMessageResponse, peer as PeerMessage, peerResponse as PeerMessageResponse, peernet as PeernetMessage, ps as PsMessage, request as RequestMessage, response as ResponseMessage };
302
+ export { ChatMessage, DHTMessage, DHTMessageResponse, DataMessage, DataMessageResponse, PeerMessage, PeerMessageResponse, PeernetFile, PeernetMessage, PsMessage, RequestMessage, ResponseMessage };
@@ -1,6 +1,8 @@
1
1
  import '@vandeurenglenn/debug';
2
+ import PubSub from '@vandeurenglenn/little-pubsub';
2
3
  import { Codec, CodecHash, codecs } from '@leofcoin/codec-format-interface';
3
4
  import MultiWallet from '@leofcoin/multi-wallet';
5
+ import 'path';
4
6
 
5
7
  const protoFor = (data) => {
6
8
  if (!Buffer.isBuffer(data)) data = Buffer.from(data);
@@ -326,6 +328,7 @@ const nothingFoundError = (hash) => {
326
328
  };
327
329
 
328
330
  globalThis.leofcoin = globalThis.leofcoin || {};
331
+ globalThis.pubsub = globalThis.pubsub || new PubSub();
329
332
  globalThis.globalSub = globalThis.globalSub || new PubSub({verbose: true});
330
333
 
331
334
  /**
@@ -372,16 +375,12 @@ class Peernet {
372
375
  return ['account', 'wallet', 'block', 'transaction', 'chain', 'data', 'message']
373
376
  }
374
377
 
375
- get protos() {
376
- return globalThis.peernet.protos
377
- }
378
-
379
378
  get codecs() {
380
379
  return codecs
381
380
  }
382
381
 
383
382
  addProto(name, proto) {
384
- if (!this.protos[name]) this.protos[name] = proto;
383
+ if (!globalThis.peernet.protos[name]) globalThis.peernet.protos[name] = proto;
385
384
  }
386
385
 
387
386
  addCodec(name, codec) {
@@ -476,8 +475,10 @@ class Peernet {
476
475
  DataMessage,
477
476
  DataMessageResponse,
478
477
  PsMessage,
479
- ChatMessage
480
- } = await import(/* webpackChunkName: "messages" */ './messages-421f88db.js');
478
+ ChatMessage,
479
+ PeernetFile
480
+ // FolderMessageResponse
481
+ } = await import(/* webpackChunkName: "messages" */ './messages-bce1b91d.js');
481
482
 
482
483
  /**
483
484
  * proto Object containing protos
@@ -501,6 +502,7 @@ class Peernet {
501
502
  'peernet-data-response': DataMessageResponse,
502
503
  'peernet-ps': PsMessage,
503
504
  'chat-message': ChatMessage,
505
+ 'peernet-file': PeernetFile
504
506
  };
505
507
 
506
508
  this._messageHandler = new MessageHandler(this.network);
@@ -608,7 +610,7 @@ class Peernet {
608
610
  if (store.private) has = false;
609
611
  else has = await store.has(hash);
610
612
  }
611
- const data = await new this.protos['peernet-dht-response']({hash, has});
613
+ const data = await new globalThis.peernet.protos['peernet-dht-response']({hash, has});
612
614
  const node = await this.prepareMessage(from, data.encoded);
613
615
 
614
616
  this.sendMessage(peer, id, node.encoded);
@@ -624,7 +626,7 @@ class Peernet {
624
626
  data = await store.get(hash);
625
627
 
626
628
  if (data) {
627
- data = await new this.protos['peernet-data-response']({hash, data});
629
+ data = await new globalThis.peernet.protos['peernet-data-response']({hash, data});
628
630
 
629
631
  const node = await this.prepareMessage(from, data.encoded);
630
632
  this.sendMessage(peer, id, node.encoded);
@@ -651,7 +653,7 @@ class Peernet {
651
653
  */
652
654
  async walk(hash) {
653
655
  if (!hash) throw new Error('hash expected, received undefined')
654
- const data = await new this.protos['peernet-dht']({hash});
656
+ const data = await new globalThis.peernet.protos['peernet-dht']({hash});
655
657
  this.client.id;
656
658
  const walk = async peer => {
657
659
  const node = await this.prepareMessage(peer.peerId, data.encoded);
@@ -759,7 +761,7 @@ class Peernet {
759
761
  if (peer.peerId === id) return peer
760
762
  });
761
763
 
762
- let data = await new this.protos['peernet-data']({hash, store: store?.name ? store?.name : store});
764
+ let data = await new globalThis.peernet.protos['peernet-data']({hash, store: store?.name ? store?.name : store});
763
765
 
764
766
  const node = await this.prepareMessage(id, data.encoded);
765
767
  if (closest[0]) data = await closest[0].request(node.encoded);
@@ -837,6 +839,75 @@ class Peernet {
837
839
  }
838
840
  }
839
841
 
842
+ get folder() {
843
+ return {
844
+ /**
845
+ * Get content for given data hash
846
+ *
847
+ * @param {String} hash
848
+ */
849
+ get: async (hash) => {
850
+ debug(`get data ${hash}`);
851
+ const data = await dataStore.has(hash);
852
+ if (data) return await dataStore.get(hash)
853
+ return this.requestData(hash, 'data')
854
+ },
855
+ /**
856
+ * put data content
857
+ *
858
+ * @param {String} hash
859
+ * @param {Buffer} data
860
+ */
861
+ put: async (hash, data) => await dataStore.put(hash, data),
862
+ /**
863
+ * @param {String} hash
864
+ * @return {Boolean}
865
+ */
866
+ has: async (hash) => await dataStore.has(hash),
867
+ }
868
+ }
869
+
870
+ async addFolder(files) {
871
+ const links = [];
872
+ for (const file of files) {
873
+ const fileNode = await new globalThis.peernet.protos['peernet-file'](file);
874
+ const hash = await fileNode.hash;
875
+ await dataStore.put(hash, fileNode.encoded);
876
+ links.push({hash, path: file.path});
877
+ }
878
+ const node = await new globalThis.peernet.protos['peernet-file']({path: '/', links});
879
+ const hash = await node.hash;
880
+ await dataStore.put(hash, node.encoded);
881
+
882
+ return hash
883
+ }
884
+
885
+ async ls(hash) {
886
+ let data;
887
+ const has = await dataStore.has(hash);
888
+ if (has) data = await dataStore.get(hash);
889
+ else data = await this.requestData(hash, 'data');
890
+
891
+ const node = await new peernet.protos['peernet-file'](data);
892
+ const paths = [];
893
+ if (node.decoded?.links.length === 0) throw new Error(`${hash} is a file`)
894
+ for (const {path, hash} of node.decoded.links) {
895
+ paths.push({path, hash});
896
+ }
897
+
898
+ return paths
899
+ }
900
+
901
+ async cat(hash) {
902
+ let data;
903
+ const has = await dataStore.has(hash);
904
+ if (has) data = await dataStore.get(hash);
905
+ else data = await this.requestData(hash, 'data');
906
+ const node = await new peernet.protos['peernet-file'](data);
907
+ if (node.decoded?.links.length > 0) throw new Error(`${hash} is a directory`)
908
+ return node.decoded.content
909
+ }
910
+
840
911
  /**
841
912
  * goes trough given stores and tries to find data for given hash
842
913
  * @param {Array} stores
@@ -904,7 +975,7 @@ class Peernet {
904
975
  if (topic instanceof Uint8Array === false) topic = new TextEncoder().encode(topic);
905
976
  if (data instanceof Uint8Array === false) data = new TextEncoder().encode(JSON.stringify(data));
906
977
  const id = Math.random().toString(36).slice(-12);
907
- data = await new this.protos['peernet-ps']({data, topic});
978
+ data = await new globalThis.peernet.protos['peernet-ps']({data, topic});
908
979
  for (const peer of this.connections) {
909
980
  if (peer.peerId !== this.peerId) {
910
981
  const node = await this.prepareMessage(peer.peerId, data.encoded);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@leofcoin/peernet",
3
- "version": "0.12.2",
3
+ "version": "0.13.1",
4
4
  "description": "",
5
5
  "main": "dist/commonjs/peernet.js",
6
6
  "module": "src/module/peernet.js",
@@ -22,7 +22,7 @@
22
22
  "license": "MIT",
23
23
  "browserslist": "> 0.5%, last 2 versions, not dead",
24
24
  "dependencies": {
25
- "@leofcoin/codec-format-interface": "^1.2.0",
25
+ "@leofcoin/codec-format-interface": "^1.2.5",
26
26
  "@leofcoin/generate-account": "^1.0.4",
27
27
  "@leofcoin/multi-wallet": "^2.1.2",
28
28
  "@leofcoin/peernet-swarm": "^0.3.3",
@@ -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
+ }
package/src/messages.js CHANGED
@@ -1,11 +1,13 @@
1
- export * as PeernetMessage from './messages/peernet.js'
2
- export * as DHTMessage from './messages/dht.js'
3
- export * as DHTMessageResponse from './messages/dht-response.js'
4
- export * as DataMessage from './messages/data.js'
5
- export * as PsMessage from './messages/ps.js'
6
- export * as PeerMessage from './messages/peer.js'
7
- export * as RequestMessage from './messages/request.js'
8
- export * as ResponseMessage from './messages/response.js'
9
- export * as PeerMessageResponse from './messages/peer-response.js'
10
- export * as DataMessageResponse from './messages/data-response.js'
11
- export * as ChatMessage from './messages/chat.js'
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,4 +1,5 @@
1
1
  import '@vandeurenglenn/debug'
2
+ import PubSub from '@vandeurenglenn/little-pubsub'
2
3
  import PeerDiscovery from './discovery/peer-discovery'
3
4
  import DHT from './dht/dht.js'
4
5
  import { CodecHash, codecs} from '@leofcoin/codec-format-interface'
@@ -8,7 +9,9 @@ import dataHandler from './handlers/data.js'
8
9
  import { encapsulatedError, dhtError,
9
10
  nothingFoundError } from './errors/errors.js'
10
11
 
12
+ import {parse} from 'path'
11
13
  globalThis.leofcoin = globalThis.leofcoin || {}
14
+ globalThis.pubsub = globalThis.pubsub || new PubSub()
12
15
  globalThis.globalSub = globalThis.globalSub || new PubSub({verbose: true})
13
16
 
14
17
  /**
@@ -55,16 +58,12 @@ export default class Peernet {
55
58
  return ['account', 'wallet', 'block', 'transaction', 'chain', 'data', 'message']
56
59
  }
57
60
 
58
- get protos() {
59
- return globalThis.peernet.protos
60
- }
61
-
62
61
  get codecs() {
63
62
  return codecs
64
63
  }
65
64
 
66
65
  addProto(name, proto) {
67
- if (!this.protos[name]) this.protos[name] = proto
66
+ if (!globalThis.peernet.protos[name]) globalThis.peernet.protos[name] = proto
68
67
  }
69
68
 
70
69
  addCodec(name, codec) {
@@ -159,7 +158,9 @@ export default class Peernet {
159
158
  DataMessage,
160
159
  DataMessageResponse,
161
160
  PsMessage,
162
- ChatMessage
161
+ ChatMessage,
162
+ PeernetFile
163
+ // FolderMessageResponse
163
164
  } = await import(/* webpackChunkName: "messages" */ './messages.js')
164
165
 
165
166
  /**
@@ -184,6 +185,7 @@ export default class Peernet {
184
185
  'peernet-data-response': DataMessageResponse,
185
186
  'peernet-ps': PsMessage,
186
187
  'chat-message': ChatMessage,
188
+ 'peernet-file': PeernetFile
187
189
  }
188
190
 
189
191
  this._messageHandler = new MessageHandler(this.network)
@@ -294,7 +296,7 @@ export default class Peernet {
294
296
  if (store.private) has = false
295
297
  else has = await store.has(hash)
296
298
  }
297
- const data = await new this.protos['peernet-dht-response']({hash, has})
299
+ const data = await new globalThis.peernet.protos['peernet-dht-response']({hash, has})
298
300
  const node = await this.prepareMessage(from, data.encoded)
299
301
 
300
302
  this.sendMessage(peer, id, node.encoded)
@@ -310,7 +312,7 @@ export default class Peernet {
310
312
  data = await store.get(hash)
311
313
 
312
314
  if (data) {
313
- data = await new this.protos['peernet-data-response']({hash, data});
315
+ data = await new globalThis.peernet.protos['peernet-data-response']({hash, data});
314
316
 
315
317
  const node = await this.prepareMessage(from, data.encoded)
316
318
  this.sendMessage(peer, id, node.encoded)
@@ -339,7 +341,7 @@ export default class Peernet {
339
341
  */
340
342
  async walk(hash) {
341
343
  if (!hash) throw new Error('hash expected, received undefined')
342
- const data = await new this.protos['peernet-dht']({hash})
344
+ const data = await new globalThis.peernet.protos['peernet-dht']({hash})
343
345
  const clientId = this.client.id
344
346
  const walk = async peer => {
345
347
  const node = await this.prepareMessage(peer.peerId, data.encoded)
@@ -447,7 +449,7 @@ export default class Peernet {
447
449
  if (peer.peerId === id) return peer
448
450
  })
449
451
 
450
- let data = await new this.protos['peernet-data']({hash, store: store?.name ? store?.name : store});
452
+ let data = await new globalThis.peernet.protos['peernet-data']({hash, store: store?.name ? store?.name : store});
451
453
 
452
454
  const node = await this.prepareMessage(id, data.encoded)
453
455
  if (closest[0]) data = await closest[0].request(node.encoded)
@@ -525,6 +527,76 @@ export default class Peernet {
525
527
  }
526
528
  }
527
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
+
528
600
  /**
529
601
  * goes trough given stores and tries to find data for given hash
530
602
  * @param {Array} stores
@@ -593,7 +665,7 @@ export default class Peernet {
593
665
  if (topic instanceof Uint8Array === false) topic = new TextEncoder().encode(topic)
594
666
  if (data instanceof Uint8Array === false) data = new TextEncoder().encode(JSON.stringify(data))
595
667
  const id = Math.random().toString(36).slice(-12)
596
- data = await new this.protos['peernet-ps']({data, topic})
668
+ data = await new globalThis.peernet.protos['peernet-ps']({data, topic})
597
669
  for (const peer of this.connections) {
598
670
  if (peer.peerId !== this.peerId) {
599
671
  const node = await this.prepareMessage(peer.peerId, data.encoded)
@@ -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
+ `