@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.
- package/dist/browser/messages.js +54 -89
- package/dist/browser/peernet.js +701 -53
- package/dist/browser/protons.js +54 -11
- package/dist/browser/storage.js +1 -1
- package/dist/commonjs/dht-response.js +23 -3
- package/dist/commonjs/dht.js +34 -3
- package/dist/commonjs/{messages-bcb02ee9.js → messages-f46a3ca1.js} +63 -58
- package/dist/commonjs/peernet.js +85 -13
- package/dist/commonjs/peernet2.js +25 -3
- package/dist/commonjs/request.js +22 -3
- package/dist/commonjs/response.js +22 -3
- package/dist/module/{messages-421f88db.js → messages-bce1b91d.js} +56 -77
- package/dist/module/peernet.js +83 -12
- package/package.json +2 -2
- package/src/messages/file.js +21 -0
- package/src/messages.js +13 -11
- package/src/peernet.js +83 -11
- package/src/proto/file.proto.js +14 -0
- package/test.js +43 -31
- package/dist/commonjs/dht-6a1b6246.js +0 -45
- package/dist/commonjs/dht-response-e4a603ea.js +0 -34
- package/dist/commonjs/peernet-6eef77d5.js +0 -36
- package/dist/commonjs/request-95ed03ec.js +0 -33
- package/dist/commonjs/response-bae4e2a2.js +0 -33
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { FormatInterface } from '@leofcoin/codec-format-interface';
|
|
2
2
|
|
|
3
|
-
var proto$
|
|
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$
|
|
24
|
+
super(buffer, proto$b, {name});
|
|
25
25
|
}
|
|
26
26
|
}
|
|
27
27
|
|
|
28
|
-
var
|
|
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$
|
|
58
|
+
super(data, proto$a, {name});
|
|
64
59
|
}
|
|
65
60
|
}
|
|
66
61
|
|
|
67
|
-
var
|
|
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$
|
|
81
|
+
super(data, proto$9, {name});
|
|
92
82
|
}
|
|
93
83
|
}
|
|
94
84
|
|
|
95
|
-
var
|
|
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$
|
|
108
|
+
super(data, proto$8, {name: 'peernet-data'});
|
|
124
109
|
}
|
|
125
110
|
}
|
|
126
111
|
|
|
127
|
-
var
|
|
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$
|
|
130
|
+
super(buffer, proto$7, {name});
|
|
151
131
|
}
|
|
152
132
|
}
|
|
153
133
|
|
|
154
|
-
var
|
|
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$
|
|
152
|
+
super(data, proto$6, {name});
|
|
178
153
|
}
|
|
179
154
|
}
|
|
180
155
|
|
|
181
|
-
var
|
|
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$
|
|
174
|
+
super(data, proto$5, {name});
|
|
205
175
|
}
|
|
206
176
|
}
|
|
207
177
|
|
|
208
|
-
var
|
|
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$
|
|
196
|
+
super(data, proto$4, {name});
|
|
232
197
|
}
|
|
233
198
|
}
|
|
234
199
|
|
|
235
|
-
var
|
|
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$
|
|
218
|
+
super(data, proto$3, {name});
|
|
259
219
|
}
|
|
260
220
|
}
|
|
261
221
|
|
|
262
|
-
var
|
|
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$
|
|
241
|
+
super(data, proto$2, {name});
|
|
287
242
|
}
|
|
288
243
|
}
|
|
289
244
|
|
|
290
|
-
var
|
|
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
|
|
319
|
-
|
|
320
|
-
|
|
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 {
|
|
302
|
+
export { ChatMessage, DHTMessage, DHTMessageResponse, DataMessage, DataMessageResponse, PeerMessage, PeerMessageResponse, PeernetFile, PeernetMessage, PsMessage, RequestMessage, ResponseMessage };
|
package/dist/module/peernet.js
CHANGED
|
@@ -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 (!
|
|
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
|
-
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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.
|
|
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.
|
|
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
|
|
2
|
-
export
|
|
3
|
-
export
|
|
4
|
-
export
|
|
5
|
-
export
|
|
6
|
-
export
|
|
7
|
-
export
|
|
8
|
-
export
|
|
9
|
-
export
|
|
10
|
-
export
|
|
11
|
-
export
|
|
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 (!
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
+
`
|