@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/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, Initializable {
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: Components = new 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.store = new PersistentStore()
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.getPeerId())) {
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, writer, opts = {}) => {
23
+ _codec = message<Peer>((obj, w, opts = {}) => {
22
24
  if (opts.lengthDelimited !== false) {
23
- writer.fork()
25
+ w.fork()
24
26
  }
25
27
 
26
28
  if (obj.addresses != null) {
27
29
  for (const value of obj.addresses) {
28
- writer.uint32(10)
29
- Address.codec().encode(value, writer)
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
- writer.uint32(18)
38
- writer.string(value)
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
- writer.uint32(26)
47
- Metadata.codec().encode(value, writer)
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
- writer.uint32(34)
55
- writer.bytes(obj.pubKey)
54
+ w.uint32(34)
55
+ w.bytes(obj.pubKey)
56
56
  }
57
57
 
58
58
  if (obj.peerRecordEnvelope != null) {
59
- writer.uint32(42)
60
- writer.bytes(obj.peerRecordEnvelope)
59
+ w.uint32(42)
60
+ w.bytes(obj.peerRecordEnvelope)
61
61
  }
62
62
 
63
63
  if (opts.lengthDelimited !== false) {
64
- writer.ldelim()
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, writer, opts = {}) => {
126
+ _codec = message<Address>((obj, w, opts = {}) => {
127
127
  if (opts.lengthDelimited !== false) {
128
- writer.fork()
128
+ w.fork()
129
129
  }
130
130
 
131
- if (obj.multiaddr != null) {
132
- writer.uint32(10)
133
- writer.bytes(obj.multiaddr)
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
- writer.uint32(16)
140
- writer.bool(obj.isCertified)
137
+ w.uint32(16)
138
+ w.bool(obj.isCertified)
141
139
  }
142
140
 
143
141
  if (opts.lengthDelimited !== false) {
144
- writer.ldelim()
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, writer, opts = {}) => {
193
+ _codec = message<Metadata>((obj, w, opts = {}) => {
200
194
  if (opts.lengthDelimited !== false) {
201
- writer.fork()
195
+ w.fork()
202
196
  }
203
197
 
204
- if (obj.key != null) {
205
- writer.uint32(10)
206
- writer.string(obj.key)
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
- writer.uint32(18)
213
- writer.bytes(obj.value)
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
- writer.ldelim()
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, writer, opts = {}) => {
19
+ _codec = message<Tags>((obj, w, opts = {}) => {
18
20
  if (opts.lengthDelimited !== false) {
19
- writer.fork()
21
+ w.fork()
20
22
  }
21
23
 
22
24
  if (obj.tags != null) {
23
25
  for (const value of obj.tags) {
24
- writer.uint32(10)
25
- Tag.codec().encode(value, writer)
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
- writer.ldelim()
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, writer, opts = {}) => {
83
+ _codec = message<Tag>((obj, w, opts = {}) => {
82
84
  if (opts.lengthDelimited !== false) {
83
- writer.fork()
85
+ w.fork()
84
86
  }
85
87
 
86
- if (obj.name != null) {
87
- writer.uint32(10)
88
- writer.string(obj.name)
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
- writer.uint32(16)
95
- writer.uint32(obj.value)
94
+ w.uint32(16)
95
+ w.uint32(obj.value)
96
96
  }
97
97
 
98
98
  if (obj.expiry != null) {
99
- writer.uint32(24)
100
- writer.uint64(obj.expiry)
99
+ w.uint32(24)
100
+ w.uint64(obj.expiry)
101
101
  }
102
102
 
103
103
  if (opts.lengthDelimited !== false) {
104
- writer.ldelim()
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 { Components } from '@libp2p/components'
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: Components = new 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.getDatastore().has(this._peerIdToDatastoreKey(peerId))
59
+ return await this.components.datastore.has(this._peerIdToDatastoreKey(peerId))
63
60
  }
64
61
 
65
62
  async delete (peerId: PeerId) {
66
- await this.components.getDatastore().delete(this._peerIdToDatastoreKey(peerId))
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.getDatastore().get(this._peerIdToDatastoreKey(peerId))
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.getDatastore().put(this._peerIdToDatastoreKey(peer.id), buf.subarray())
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.getDatastore().queryKeys({
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}