Skip to content
This repository was archived by the owner on Oct 3, 2023. It is now read-only.

Commit 123a3e9

Browse files
committed
fix!: remove @libp2p/components
`@libp2p/components` is a choke-point for our dependency graph as it depends on every interface, meaning when one interface revs a major `@libp2p/components` major has to change too which means every module depending on it also needs a major. Switch instead to constructor injection of simple objects that let modules declare their dependencies on interfaces directly instead of indirectly via `@libp2p/components` Refs libp2p/js-libp2p-components#6 BREAKING CHANGE: modules no longer implement `Initializable` instead switching to constructor injection
1 parent d141806 commit 123a3e9

File tree

4 files changed

+39
-37
lines changed

4 files changed

+39
-37
lines changed

package.json

+3-3
Original file line numberDiff line numberDiff line change
@@ -138,19 +138,19 @@
138138
"release": "aegir release"
139139
},
140140
"dependencies": {
141-
"@libp2p/components": "^3.0.0",
142141
"@libp2p/interface-peer-discovery": "^1.0.1",
143142
"@libp2p/interface-peer-info": "^1.0.3",
143+
"@libp2p/interface-peer-store": "^1.2.2",
144144
"@libp2p/interfaces": "^3.0.3",
145145
"@libp2p/logger": "^2.0.1",
146146
"@libp2p/peer-id": "^1.1.15",
147147
"@multiformats/mafmt": "^11.0.3",
148148
"@multiformats/multiaddr": "^11.0.0"
149149
},
150150
"devDependencies": {
151-
"@libp2p/interface-peer-discovery-compliance-tests": "^1.0.2",
151+
"@libp2p/interface-peer-discovery-compliance-tests": "^2.0.0",
152152
"@libp2p/interface-peer-id": "^1.0.4",
153-
"@libp2p/peer-store": "^4.0.0",
153+
"@libp2p/peer-store": "^5.0.0",
154154
"aegir": "^37.5.3",
155155
"datastore-core": "^8.0.1",
156156
"delay": "^5.0.0"

src/index.ts

+17-11
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,8 @@ import type { PeerDiscovery, PeerDiscoveryEvents } from '@libp2p/interface-peer-
66
import type { PeerInfo } from '@libp2p/interface-peer-info'
77
import { peerIdFromString } from '@libp2p/peer-id'
88
import { symbol } from '@libp2p/interface-peer-discovery'
9-
import { Components, Initializable } from '@libp2p/components'
9+
import type { Startable } from '@libp2p/interfaces/dist/src/startable'
10+
import type { PeerStore } from '@libp2p/interface-peer-store'
1011

1112
const log = logger('libp2p:bootstrap')
1213

@@ -15,7 +16,7 @@ const DEFAULT_BOOTSTRAP_TAG_VALUE = 50
1516
const DEFAULT_BOOTSTRAP_TAG_TTL = 120000
1617
const DEFAULT_BOOTSTRAP_DISCOVERY_TIMEOUT = 1000
1718

18-
export interface BootstrapOptions {
19+
export interface BootstrapInit {
1920
/**
2021
* The list of peer addresses in multi-address format
2122
*/
@@ -42,24 +43,29 @@ export interface BootstrapOptions {
4243
tagTTL?: number
4344
}
4445

46+
export interface BootstrapComponents {
47+
peerStore: PeerStore
48+
}
49+
4550
/**
4651
* Emits 'peer' events on a regular interval for each peer in the provided list.
4752
*/
48-
export class Bootstrap extends EventEmitter<PeerDiscoveryEvents> implements PeerDiscovery, Initializable {
53+
class Bootstrap extends EventEmitter<PeerDiscoveryEvents> implements PeerDiscovery, Startable {
4954
static tag = 'bootstrap'
5055

5156
private timer?: ReturnType<typeof setTimeout>
5257
private readonly list: PeerInfo[]
5358
private readonly timeout: number
54-
private components: Components = new Components()
55-
private readonly _init: BootstrapOptions
59+
private readonly components: BootstrapComponents
60+
private readonly _init: BootstrapInit
5661

57-
constructor (options: BootstrapOptions = { list: [] }) {
62+
constructor (components: BootstrapComponents, options: BootstrapInit = { list: [] }) {
5863
if (options.list == null || options.list.length === 0) {
5964
throw new Error('Bootstrap requires a list of peer addresses')
6065
}
6166
super()
6267

68+
this.components = components
6369
this.timeout = options.timeout ?? DEFAULT_BOOTSTRAP_DISCOVERY_TIMEOUT
6470
this.list = []
6571

@@ -89,10 +95,6 @@ export class Bootstrap extends EventEmitter<PeerDiscoveryEvents> implements Peer
8995
this._init = options
9096
}
9197

92-
init (components: Components) {
93-
this.components = components
94-
}
95-
9698
get [symbol] (): true {
9799
return true
98100
}
@@ -131,7 +133,7 @@ export class Bootstrap extends EventEmitter<PeerDiscoveryEvents> implements Peer
131133
}
132134

133135
for (const peerData of this.list) {
134-
await this.components.getPeerStore().tagPeer(peerData.id, this._init.tagName ?? DEFAULT_BOOTSTRAP_TAG_NAME, {
136+
await this.components.peerStore.tagPeer(peerData.id, this._init.tagName ?? DEFAULT_BOOTSTRAP_TAG_NAME, {
135137
value: this._init.tagValue ?? DEFAULT_BOOTSTRAP_TAG_VALUE,
136138
ttl: this._init.tagTTL ?? DEFAULT_BOOTSTRAP_TAG_TTL
137139
})
@@ -156,3 +158,7 @@ export class Bootstrap extends EventEmitter<PeerDiscoveryEvents> implements Peer
156158
this.timer = undefined
157159
}
158160
}
161+
162+
export function bootstrap (init: BootstrapInit): (components: BootstrapComponents) => PeerDiscovery {
163+
return (components: BootstrapComponents) => new Bootstrap(components, init)
164+
}

test/bootstrap.spec.ts

+16-17
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
import { expect } from 'aegir/chai'
44
import { IPFS } from '@multiformats/mafmt'
5-
import { Bootstrap } from '../src/index.js'
5+
import { bootstrap } from '../src/index.js'
66
import peerList from './fixtures/default-peers.js'
77
import partialValidPeerList from './fixtures/some-invalid-peers.js'
88
import { isPeerId } from '@libp2p/interface-peer-id'
@@ -12,6 +12,7 @@ import { MemoryDatastore } from 'datastore-core'
1212
import { multiaddr } from '@multiformats/multiaddr'
1313
import { peerIdFromString } from '@libp2p/peer-id'
1414
import delay from 'delay'
15+
import { start, stop } from '@libp2p/interfaces/startable'
1516

1617
describe('bootstrap', () => {
1718
let components: Components
@@ -29,25 +30,25 @@ describe('bootstrap', () => {
2930
})
3031

3132
it('should throw if no peer list is provided', () => {
32-
expect(() => new Bootstrap())
33+
// @ts-expect-error missing args
34+
expect(() => bootstrap()())
3335
.to.throw('Bootstrap requires a list of peer addresses')
3436
})
3537

3638
it('should discover bootstrap peers', async function () {
3739
this.timeout(5 * 1000)
38-
const r = new Bootstrap({
40+
const r = bootstrap({
3941
list: peerList,
4042
timeout: 100
41-
})
42-
r.init(components)
43+
})(components)
4344

4445
const p = new Promise((resolve) => r.addEventListener('peer', resolve, {
4546
once: true
4647
}))
47-
r.start()
48+
await start(r)
4849

4950
await p
50-
r.stop()
51+
await stop(r)
5152
})
5253

5354
it('should tag bootstrap peers', async function () {
@@ -57,19 +58,18 @@ describe('bootstrap', () => {
5758
const tagValue = 10
5859
const tagTTL = 50
5960

60-
const r = new Bootstrap({
61+
const r = bootstrap({
6162
list: peerList,
6263
timeout: 100,
6364
tagName,
6465
tagValue,
6566
tagTTL
66-
})
67-
r.init(components)
67+
})(components)
6868

6969
const p = new Promise((resolve) => r.addEventListener('peer', resolve, {
7070
once: true
7171
}))
72-
r.start()
72+
await start(r)
7373

7474
await p
7575

@@ -94,17 +94,16 @@ describe('bootstrap', () => {
9494

9595
expect(tags2).to.have.lengthOf(0, 'bootstrap tag did not expire')
9696

97-
r.stop()
97+
await stop(r)
9898
})
9999

100100
it('should not fail on malformed peers in peer list', async function () {
101101
this.timeout(5 * 1000)
102102

103-
const r = new Bootstrap({
103+
const r = bootstrap({
104104
list: partialValidPeerList,
105105
timeout: 100
106-
})
107-
r.init(components)
106+
})(components)
108107

109108
const p = new Promise<void>((resolve) => {
110109
r.addEventListener('peer', (evt) => {
@@ -118,9 +117,9 @@ describe('bootstrap', () => {
118117
})
119118
})
120119

121-
r.start()
120+
await start(r)
122121

123122
await p
124-
r.stop()
123+
await stop(r)
125124
})
126125
})

test/compliance.spec.ts

+3-6
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
/* eslint-env mocha */
22

33
import tests from '@libp2p/interface-peer-discovery-compliance-tests'
4-
import { Bootstrap } from '../src/index.js'
4+
import { bootstrap } from '../src/index.js'
55
import peerList from './fixtures/default-peers.js'
66
import { Components } from '@libp2p/components'
77
import { PersistentPeerStore } from '@libp2p/peer-store'
@@ -18,13 +18,10 @@ describe('compliance tests', () => {
1818
})
1919
peerStore.init(components)
2020

21-
const bootstrap = new Bootstrap({
21+
return bootstrap({
2222
list: peerList,
2323
timeout: 100
24-
})
25-
bootstrap.init(components)
26-
27-
return bootstrap
24+
})(components)
2825
},
2926
async teardown () {}
3027
})

0 commit comments

Comments
 (0)