@libp2p/peer-store 4.0.0 → 5.0.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/README.md +17 -4
- package/dist/index.min.js +16 -0
- package/dist/src/index.d.ts +8 -5
- package/dist/src/index.d.ts.map +1 -1
- package/dist/src/index.js +4 -9
- package/dist/src/index.js.map +1 -1
- package/dist/src/pb/peer.d.ts.map +1 -1
- package/dist/src/pb/peer.js +36 -57
- package/dist/src/pb/peer.js.map +1 -1
- package/dist/src/pb/tags.d.ts.map +1 -1
- package/dist/src/pb/tags.js +19 -24
- package/dist/src/pb/tags.js.map +1 -1
- package/dist/src/store.d.ts +3 -4
- package/dist/src/store.d.ts.map +1 -1
- package/dist/src/store.js +7 -11
- package/dist/src/store.js.map +1 -1
- package/dist/typedoc-urls.json +4 -0
- package/package.json +13 -13
- package/src/index.ts +12 -11
- package/src/pb/peer.ts +36 -54
- package/src/pb/tags.ts +19 -23
- package/src/store.ts +9 -12
package/src/index.ts
CHANGED
|
@@ -7,39 +7,40 @@ import { PeerStoreProtoBook } from './proto-book.js'
|
|
|
7
7
|
import { PersistentStore, Store } from './store.js'
|
|
8
8
|
import type { PeerStore, AddressBook, KeyBook, MetadataBook, ProtoBook, PeerStoreEvents, PeerStoreInit, Peer, TagOptions } from '@libp2p/interface-peer-store'
|
|
9
9
|
import type { PeerId } from '@libp2p/interface-peer-id'
|
|
10
|
-
import { Components, Initializable } from '@libp2p/components'
|
|
11
10
|
import errCode from 'err-code'
|
|
12
11
|
import { Tag, Tags } from './pb/tags.js'
|
|
12
|
+
import type { Datastore } from 'interface-datastore'
|
|
13
13
|
|
|
14
14
|
const log = logger('libp2p:peer-store')
|
|
15
15
|
|
|
16
|
+
export interface PersistentPeerStoreComponents {
|
|
17
|
+
peerId: PeerId
|
|
18
|
+
datastore: Datastore
|
|
19
|
+
}
|
|
20
|
+
|
|
16
21
|
/**
|
|
17
22
|
* An implementation of PeerStore that stores data in a Datastore
|
|
18
23
|
*/
|
|
19
|
-
export class PersistentPeerStore extends EventEmitter<PeerStoreEvents> implements PeerStore
|
|
24
|
+
export class PersistentPeerStore extends EventEmitter<PeerStoreEvents> implements PeerStore {
|
|
20
25
|
public addressBook: AddressBook
|
|
21
26
|
public keyBook: KeyBook
|
|
22
27
|
public metadataBook: MetadataBook
|
|
23
28
|
public protoBook: ProtoBook
|
|
24
29
|
|
|
25
|
-
private components:
|
|
30
|
+
private readonly components: PersistentPeerStoreComponents
|
|
26
31
|
private readonly store: Store
|
|
27
32
|
|
|
28
|
-
constructor (init: PeerStoreInit = {}) {
|
|
33
|
+
constructor (components: PersistentPeerStoreComponents, init: PeerStoreInit = {}) {
|
|
29
34
|
super()
|
|
30
35
|
|
|
31
|
-
this.
|
|
36
|
+
this.components = components
|
|
37
|
+
this.store = new PersistentStore(components)
|
|
32
38
|
this.addressBook = new PeerStoreAddressBook(this.dispatchEvent.bind(this), this.store, init.addressFilter)
|
|
33
39
|
this.keyBook = new PeerStoreKeyBook(this.dispatchEvent.bind(this), this.store)
|
|
34
40
|
this.metadataBook = new PeerStoreMetadataBook(this.dispatchEvent.bind(this), this.store)
|
|
35
41
|
this.protoBook = new PeerStoreProtoBook(this.dispatchEvent.bind(this), this.store)
|
|
36
42
|
}
|
|
37
43
|
|
|
38
|
-
init (components: Components) {
|
|
39
|
-
this.components = components
|
|
40
|
-
;(this.store as PersistentStore).init(components)
|
|
41
|
-
}
|
|
42
|
-
|
|
43
44
|
async forEach (fn: (peer: Peer) => void) {
|
|
44
45
|
log.trace('getPeers await read lock')
|
|
45
46
|
const release = await this.store.lock.readLock()
|
|
@@ -47,7 +48,7 @@ export class PersistentPeerStore extends EventEmitter<PeerStoreEvents> implement
|
|
|
47
48
|
|
|
48
49
|
try {
|
|
49
50
|
for await (const peer of this.store.all()) {
|
|
50
|
-
if (peer.id.equals(this.components.
|
|
51
|
+
if (peer.id.equals(this.components.peerId)) {
|
|
51
52
|
// Skip self peer if present
|
|
52
53
|
continue
|
|
53
54
|
}
|
package/src/pb/peer.ts
CHANGED
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
/* eslint-disable import/export */
|
|
2
|
+
/* eslint-disable complexity */
|
|
2
3
|
/* eslint-disable @typescript-eslint/no-namespace */
|
|
4
|
+
/* eslint-disable @typescript-eslint/no-unnecessary-boolean-literal-compare */
|
|
3
5
|
|
|
4
6
|
import { encodeMessage, decodeMessage, message } from 'protons-runtime'
|
|
5
7
|
import type { Uint8ArrayList } from 'uint8arraylist'
|
|
@@ -18,50 +20,48 @@ export namespace Peer {
|
|
|
18
20
|
|
|
19
21
|
export const codec = (): Codec<Peer> => {
|
|
20
22
|
if (_codec == null) {
|
|
21
|
-
_codec = message<Peer>((obj,
|
|
23
|
+
_codec = message<Peer>((obj, w, opts = {}) => {
|
|
22
24
|
if (opts.lengthDelimited !== false) {
|
|
23
|
-
|
|
25
|
+
w.fork()
|
|
24
26
|
}
|
|
25
27
|
|
|
26
28
|
if (obj.addresses != null) {
|
|
27
29
|
for (const value of obj.addresses) {
|
|
28
|
-
|
|
29
|
-
Address.codec().encode(value,
|
|
30
|
+
w.uint32(10)
|
|
31
|
+
Address.codec().encode(value, w, {
|
|
32
|
+
writeDefaults: true
|
|
33
|
+
})
|
|
30
34
|
}
|
|
31
|
-
} else {
|
|
32
|
-
throw new Error('Protocol error: required field "addresses" was not found in object')
|
|
33
35
|
}
|
|
34
36
|
|
|
35
37
|
if (obj.protocols != null) {
|
|
36
38
|
for (const value of obj.protocols) {
|
|
37
|
-
|
|
38
|
-
|
|
39
|
+
w.uint32(18)
|
|
40
|
+
w.string(value)
|
|
39
41
|
}
|
|
40
|
-
} else {
|
|
41
|
-
throw new Error('Protocol error: required field "protocols" was not found in object')
|
|
42
42
|
}
|
|
43
43
|
|
|
44
44
|
if (obj.metadata != null) {
|
|
45
45
|
for (const value of obj.metadata) {
|
|
46
|
-
|
|
47
|
-
Metadata.codec().encode(value,
|
|
46
|
+
w.uint32(26)
|
|
47
|
+
Metadata.codec().encode(value, w, {
|
|
48
|
+
writeDefaults: true
|
|
49
|
+
})
|
|
48
50
|
}
|
|
49
|
-
} else {
|
|
50
|
-
throw new Error('Protocol error: required field "metadata" was not found in object')
|
|
51
51
|
}
|
|
52
52
|
|
|
53
53
|
if (obj.pubKey != null) {
|
|
54
|
-
|
|
55
|
-
|
|
54
|
+
w.uint32(34)
|
|
55
|
+
w.bytes(obj.pubKey)
|
|
56
56
|
}
|
|
57
57
|
|
|
58
58
|
if (obj.peerRecordEnvelope != null) {
|
|
59
|
-
|
|
60
|
-
|
|
59
|
+
w.uint32(42)
|
|
60
|
+
w.bytes(obj.peerRecordEnvelope)
|
|
61
61
|
}
|
|
62
62
|
|
|
63
63
|
if (opts.lengthDelimited !== false) {
|
|
64
|
-
|
|
64
|
+
w.ldelim()
|
|
65
65
|
}
|
|
66
66
|
}, (reader, length) => {
|
|
67
67
|
const obj: any = {
|
|
@@ -123,25 +123,23 @@ export namespace Address {
|
|
|
123
123
|
|
|
124
124
|
export const codec = (): Codec<Address> => {
|
|
125
125
|
if (_codec == null) {
|
|
126
|
-
_codec = message<Address>((obj,
|
|
126
|
+
_codec = message<Address>((obj, w, opts = {}) => {
|
|
127
127
|
if (opts.lengthDelimited !== false) {
|
|
128
|
-
|
|
128
|
+
w.fork()
|
|
129
129
|
}
|
|
130
130
|
|
|
131
|
-
if (obj.multiaddr != null) {
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
} else {
|
|
135
|
-
throw new Error('Protocol error: required field "multiaddr" was not found in object')
|
|
131
|
+
if (opts.writeDefaults === true || (obj.multiaddr != null && obj.multiaddr.byteLength > 0)) {
|
|
132
|
+
w.uint32(10)
|
|
133
|
+
w.bytes(obj.multiaddr)
|
|
136
134
|
}
|
|
137
135
|
|
|
138
136
|
if (obj.isCertified != null) {
|
|
139
|
-
|
|
140
|
-
|
|
137
|
+
w.uint32(16)
|
|
138
|
+
w.bool(obj.isCertified)
|
|
141
139
|
}
|
|
142
140
|
|
|
143
141
|
if (opts.lengthDelimited !== false) {
|
|
144
|
-
|
|
142
|
+
w.ldelim()
|
|
145
143
|
}
|
|
146
144
|
}, (reader, length) => {
|
|
147
145
|
const obj: any = {
|
|
@@ -166,10 +164,6 @@ export namespace Address {
|
|
|
166
164
|
}
|
|
167
165
|
}
|
|
168
166
|
|
|
169
|
-
if (obj.multiaddr == null) {
|
|
170
|
-
throw new Error('Protocol error: value for required field "multiaddr" was not found in protobuf')
|
|
171
|
-
}
|
|
172
|
-
|
|
173
167
|
return obj
|
|
174
168
|
})
|
|
175
169
|
}
|
|
@@ -196,27 +190,23 @@ export namespace Metadata {
|
|
|
196
190
|
|
|
197
191
|
export const codec = (): Codec<Metadata> => {
|
|
198
192
|
if (_codec == null) {
|
|
199
|
-
_codec = message<Metadata>((obj,
|
|
193
|
+
_codec = message<Metadata>((obj, w, opts = {}) => {
|
|
200
194
|
if (opts.lengthDelimited !== false) {
|
|
201
|
-
|
|
195
|
+
w.fork()
|
|
202
196
|
}
|
|
203
197
|
|
|
204
|
-
if (obj.key
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
} else {
|
|
208
|
-
throw new Error('Protocol error: required field "key" was not found in object')
|
|
198
|
+
if (opts.writeDefaults === true || obj.key !== '') {
|
|
199
|
+
w.uint32(10)
|
|
200
|
+
w.string(obj.key)
|
|
209
201
|
}
|
|
210
202
|
|
|
211
|
-
if (obj.value != null) {
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
} else {
|
|
215
|
-
throw new Error('Protocol error: required field "value" was not found in object')
|
|
203
|
+
if (opts.writeDefaults === true || (obj.value != null && obj.value.byteLength > 0)) {
|
|
204
|
+
w.uint32(18)
|
|
205
|
+
w.bytes(obj.value)
|
|
216
206
|
}
|
|
217
207
|
|
|
218
208
|
if (opts.lengthDelimited !== false) {
|
|
219
|
-
|
|
209
|
+
w.ldelim()
|
|
220
210
|
}
|
|
221
211
|
}, (reader, length) => {
|
|
222
212
|
const obj: any = {
|
|
@@ -242,14 +232,6 @@ export namespace Metadata {
|
|
|
242
232
|
}
|
|
243
233
|
}
|
|
244
234
|
|
|
245
|
-
if (obj.key == null) {
|
|
246
|
-
throw new Error('Protocol error: value for required field "key" was not found in protobuf')
|
|
247
|
-
}
|
|
248
|
-
|
|
249
|
-
if (obj.value == null) {
|
|
250
|
-
throw new Error('Protocol error: value for required field "value" was not found in protobuf')
|
|
251
|
-
}
|
|
252
|
-
|
|
253
235
|
return obj
|
|
254
236
|
})
|
|
255
237
|
}
|
package/src/pb/tags.ts
CHANGED
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
/* eslint-disable import/export */
|
|
2
|
+
/* eslint-disable complexity */
|
|
2
3
|
/* eslint-disable @typescript-eslint/no-namespace */
|
|
4
|
+
/* eslint-disable @typescript-eslint/no-unnecessary-boolean-literal-compare */
|
|
3
5
|
|
|
4
6
|
import { encodeMessage, decodeMessage, message } from 'protons-runtime'
|
|
5
7
|
import type { Uint8ArrayList } from 'uint8arraylist'
|
|
@@ -14,22 +16,22 @@ export namespace Tags {
|
|
|
14
16
|
|
|
15
17
|
export const codec = (): Codec<Tags> => {
|
|
16
18
|
if (_codec == null) {
|
|
17
|
-
_codec = message<Tags>((obj,
|
|
19
|
+
_codec = message<Tags>((obj, w, opts = {}) => {
|
|
18
20
|
if (opts.lengthDelimited !== false) {
|
|
19
|
-
|
|
21
|
+
w.fork()
|
|
20
22
|
}
|
|
21
23
|
|
|
22
24
|
if (obj.tags != null) {
|
|
23
25
|
for (const value of obj.tags) {
|
|
24
|
-
|
|
25
|
-
Tag.codec().encode(value,
|
|
26
|
+
w.uint32(10)
|
|
27
|
+
Tag.codec().encode(value, w, {
|
|
28
|
+
writeDefaults: true
|
|
29
|
+
})
|
|
26
30
|
}
|
|
27
|
-
} else {
|
|
28
|
-
throw new Error('Protocol error: required field "tags" was not found in object')
|
|
29
31
|
}
|
|
30
32
|
|
|
31
33
|
if (opts.lengthDelimited !== false) {
|
|
32
|
-
|
|
34
|
+
w.ldelim()
|
|
33
35
|
}
|
|
34
36
|
}, (reader, length) => {
|
|
35
37
|
const obj: any = {
|
|
@@ -78,30 +80,28 @@ export namespace Tag {
|
|
|
78
80
|
|
|
79
81
|
export const codec = (): Codec<Tag> => {
|
|
80
82
|
if (_codec == null) {
|
|
81
|
-
_codec = message<Tag>((obj,
|
|
83
|
+
_codec = message<Tag>((obj, w, opts = {}) => {
|
|
82
84
|
if (opts.lengthDelimited !== false) {
|
|
83
|
-
|
|
85
|
+
w.fork()
|
|
84
86
|
}
|
|
85
87
|
|
|
86
|
-
if (obj.name
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
} else {
|
|
90
|
-
throw new Error('Protocol error: required field "name" was not found in object')
|
|
88
|
+
if (opts.writeDefaults === true || obj.name !== '') {
|
|
89
|
+
w.uint32(10)
|
|
90
|
+
w.string(obj.name)
|
|
91
91
|
}
|
|
92
92
|
|
|
93
93
|
if (obj.value != null) {
|
|
94
|
-
|
|
95
|
-
|
|
94
|
+
w.uint32(16)
|
|
95
|
+
w.uint32(obj.value)
|
|
96
96
|
}
|
|
97
97
|
|
|
98
98
|
if (obj.expiry != null) {
|
|
99
|
-
|
|
100
|
-
|
|
99
|
+
w.uint32(24)
|
|
100
|
+
w.uint64(obj.expiry)
|
|
101
101
|
}
|
|
102
102
|
|
|
103
103
|
if (opts.lengthDelimited !== false) {
|
|
104
|
-
|
|
104
|
+
w.ldelim()
|
|
105
105
|
}
|
|
106
106
|
}, (reader, length) => {
|
|
107
107
|
const obj: any = {
|
|
@@ -129,10 +129,6 @@ export namespace Tag {
|
|
|
129
129
|
}
|
|
130
130
|
}
|
|
131
131
|
|
|
132
|
-
if (obj.name == null) {
|
|
133
|
-
throw new Error('Protocol error: value for required field "name" was not found in protobuf')
|
|
134
|
-
}
|
|
135
|
-
|
|
136
132
|
return obj
|
|
137
133
|
})
|
|
138
134
|
}
|
package/src/store.ts
CHANGED
|
@@ -10,7 +10,7 @@ import mortice from 'mortice'
|
|
|
10
10
|
import { equals as uint8arrayEquals } from 'uint8arrays/equals'
|
|
11
11
|
import type { Peer } from '@libp2p/interface-peer-store'
|
|
12
12
|
import type { PeerId } from '@libp2p/interface-peer-id'
|
|
13
|
-
import {
|
|
13
|
+
import type { PersistentPeerStoreComponents } from './index.js'
|
|
14
14
|
|
|
15
15
|
const log = logger('libp2p:peer-store:store')
|
|
16
16
|
|
|
@@ -34,20 +34,17 @@ export interface Store {
|
|
|
34
34
|
}
|
|
35
35
|
|
|
36
36
|
export class PersistentStore {
|
|
37
|
-
private components:
|
|
37
|
+
private readonly components: PersistentPeerStoreComponents
|
|
38
38
|
public lock: any
|
|
39
39
|
|
|
40
|
-
constructor () {
|
|
40
|
+
constructor (components: PersistentPeerStoreComponents) {
|
|
41
|
+
this.components = components
|
|
41
42
|
this.lock = mortice({
|
|
42
43
|
name: 'peer-store',
|
|
43
44
|
singleProcess: true
|
|
44
45
|
})
|
|
45
46
|
}
|
|
46
47
|
|
|
47
|
-
init (components: Components) {
|
|
48
|
-
this.components = components
|
|
49
|
-
}
|
|
50
|
-
|
|
51
48
|
_peerIdToDatastoreKey (peerId: PeerId) {
|
|
52
49
|
if (peerId.type == null) {
|
|
53
50
|
log.error('peerId must be an instance of peer-id to store data')
|
|
@@ -59,15 +56,15 @@ export class PersistentStore {
|
|
|
59
56
|
}
|
|
60
57
|
|
|
61
58
|
async has (peerId: PeerId) {
|
|
62
|
-
return await this.components.
|
|
59
|
+
return await this.components.datastore.has(this._peerIdToDatastoreKey(peerId))
|
|
63
60
|
}
|
|
64
61
|
|
|
65
62
|
async delete (peerId: PeerId) {
|
|
66
|
-
await this.components.
|
|
63
|
+
await this.components.datastore.delete(this._peerIdToDatastoreKey(peerId))
|
|
67
64
|
}
|
|
68
65
|
|
|
69
66
|
async load (peerId: PeerId): Promise<Peer> {
|
|
70
|
-
const buf = await this.components.
|
|
67
|
+
const buf = await this.components.datastore.get(this._peerIdToDatastoreKey(peerId))
|
|
71
68
|
const peer = PeerPB.decode(buf)
|
|
72
69
|
const metadata = new Map()
|
|
73
70
|
|
|
@@ -133,7 +130,7 @@ export class PersistentStore {
|
|
|
133
130
|
peerRecordEnvelope: peer.peerRecordEnvelope
|
|
134
131
|
})
|
|
135
132
|
|
|
136
|
-
await this.components.
|
|
133
|
+
await this.components.datastore.put(this._peerIdToDatastoreKey(peer.id), buf.subarray())
|
|
137
134
|
|
|
138
135
|
return await this.load(peer.id)
|
|
139
136
|
}
|
|
@@ -231,7 +228,7 @@ export class PersistentStore {
|
|
|
231
228
|
}
|
|
232
229
|
|
|
233
230
|
async * all () {
|
|
234
|
-
for await (const key of this.components.
|
|
231
|
+
for await (const key of this.components.datastore.queryKeys({
|
|
235
232
|
prefix: NAMESPACE_COMMON
|
|
236
233
|
})) {
|
|
237
234
|
// /peers/${peer-id-as-libp2p-key-cid-string-in-base-32}
|