Skip to content
This repository has been archived by the owner on Jun 26, 2023. It is now read-only.

Commit

Permalink
fix: remove node event emitters (#161)
Browse files Browse the repository at this point in the history
Replaces the node `EventEmitter` with the pure-js `EventTarget` class.

All events are now instances of [Event](https://developer.mozilla.org/en-US/docs/Web/API/Event).

For typing [CustomEvent](https://developer.mozilla.org/en-US/docs/Web/API/CustomEvent) can be used which gives us a typed `.detail` field.

Tediously `EventTarget` itself [doesn't support typed events](microsoft/TypeScript#28357) (yet?) and node.js [doesn't support](nodejs/node#40678) `CustomEvent` globally so bit of trickery was required but hopefully this can be removed in future:

```js
import { EventEmitter, CustomEvent } from '@libp2p/interfaces'

interface EventMap {
  'foo': CustomEvent<number>
}

class MyEmitter extends EventEmitter<EventMap> {
  // ... other code here
} 

const emitter = new MyEmitter()

emitter.addEventListener('foo', (evt) => {
  const n = evt.detail // n is a 'number'
})
```
  • Loading branch information
achingbrain committed Feb 10, 2022
1 parent b952052 commit 221fb6a
Show file tree
Hide file tree
Showing 48 changed files with 645 additions and 365 deletions.
7 changes: 4 additions & 3 deletions packages/libp2p-connection/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -142,10 +142,10 @@
},
"scripts": {
"lint": "aegir lint",
"dep-check": "aegir dep-check dist/src/**/*.js",
"dep-check": "aegir dep-check dist/src/**/*.js dist/test/**/*.js",
"build": "tsc",
"pretest": "npm run build",
"test": "aegir test -f ./dist/test/**/*.js",
"test": "aegir test -f ./dist/test/*.js -f ./dist/test/**/*.js",
"test:chrome": "npm run test -- -t browser",
"test:chrome-webworker": "npm run test -- -t webworker",
"test:firefox": "npm run test -- -t browser -- --browser firefox",
Expand All @@ -161,6 +161,7 @@
"devDependencies": {
"@libp2p/interface-compliance-tests": "^1.0.0",
"@libp2p/peer-id-factory": "^1.0.0",
"aegir": "^36.1.3"
"aegir": "^36.1.3",
"it-pair": "^2.0.2"
}
}
12 changes: 10 additions & 2 deletions packages/libp2p-interface-compliance-tests/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,10 @@
"import": "./dist/src/utils/mock-connection-gater.js",
"types": "./dist/src/utils/mock-connection-gater.d.ts"
},
"./utils/mock-connection-manager": {
"import": "./dist/src/utils/mock-connection-manager.js",
"types": "./dist/src/utils/mock-connection-manager.d.ts"
},
"./utils/mock-multiaddr-connection": {
"import": "./dist/src/utils/mock-multiaddr-connection.js",
"types": "./dist/src/utils/mock-multiaddr-connection.d.ts"
Expand All @@ -108,6 +112,10 @@
"import": "./dist/src/utils/mock-peer-store.js",
"types": "./dist/src/utils/mock-peer-store.d.ts"
},
"./utils/mock-registrar": {
"import": "./dist/src/utils/mock-registrar.js",
"types": "./dist/src/utils/mock-registrar.d.ts"
},
"./utils/mock-upgrader": {
"import": "./dist/src/utils/mock-upgrader.js",
"types": "./dist/src/utils/mock-upgrader.d.ts"
Expand Down Expand Up @@ -206,10 +214,10 @@
},
"scripts": {
"lint": "aegir lint",
"dep-check": "aegir dep-check dist/src/**/*.js",
"dep-check": "aegir dep-check dist/src/**/*.js dist/test/**/*.js",
"build": "tsc",
"pretest": "npm run build",
"test": "aegir test -f ./dist/test/**/*.js",
"test": "aegir test -f ./dist/test/*.js -f ./dist/test/**/*.js",
"test:chrome": "npm run test -- -t browser",
"test:chrome-webworker": "npm run test -- -t webworker",
"test:firefox": "npm run test -- -t browser -- --browser firefox",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,6 @@ export default (common: TestSetup<PeerDiscovery & Startable>) => {

afterEach('ensure discovery was stopped', async () => {
await discovery.stop()

discovery.removeAllListeners()

await common.teardown()
})

Expand All @@ -44,7 +41,8 @@ export default (common: TestSetup<PeerDiscovery & Startable>) => {
const defer = pDefer()
await discovery.start()

discovery.on('peer', ({ id, multiaddrs }) => {
discovery.addEventListener('peer', (evt) => {
const { id, multiaddrs } = evt.detail
expect(id).to.exist()
expect(id).to.have.property('type').that.is.oneOf(['RSA', 'Ed25519', 'secp256k1'])
expect(multiaddrs).to.exist()
Expand All @@ -58,7 +56,7 @@ export default (common: TestSetup<PeerDiscovery & Startable>) => {
})

it('should not receive a peer event before start', async () => {
discovery.on('peer', () => {
discovery.addEventListener('peer', () => {
throw new Error('should not receive a peer event before start')
})

Expand All @@ -70,14 +68,14 @@ export default (common: TestSetup<PeerDiscovery & Startable>) => {

await discovery.start()

discovery.on('peer', () => {
discovery.addEventListener('peer', () => {
deferStart.resolve()
})

await deferStart.promise
await discovery.stop()

discovery.on('peer', () => {
discovery.addEventListener('peer', () => {
throw new Error('should not receive a peer event after stop')
})

Expand Down
21 changes: 10 additions & 11 deletions packages/libp2p-interface-compliance-tests/src/pubsub/api.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,15 +4,15 @@ import pDefer from 'p-defer'
import pWaitFor from 'p-wait-for'
import { fromString as uint8ArrayFromString } from 'uint8arrays/from-string'
import type { TestSetup } from '../index.js'
import type { PubSub, Message } from '@libp2p/interfaces/pubsub'
import type { Startable } from '@libp2p/interfaces'
import type { PubSub } from '@libp2p/interfaces/pubsub'
import type { EventMap } from './index.js'

const topic = 'foo'
const data = uint8ArrayFromString('bar')

export default (common: TestSetup<PubSub & Startable>) => {
export default (common: TestSetup<PubSub<EventMap>>) => {
describe('pubsub api', () => {
let pubsub: PubSub & Startable
let pubsub: PubSub<EventMap>

// Create pubsub router
beforeEach(async () => {
Expand Down Expand Up @@ -51,7 +51,7 @@ export default (common: TestSetup<PubSub & Startable>) => {

await pubsub.start()
pubsub.subscribe(topic)
pubsub.on('topic', handler)
pubsub.addEventListener('topic', handler)

await pWaitFor(() => {
const topics = pubsub.getTopics()
Expand All @@ -71,15 +71,14 @@ export default (common: TestSetup<PubSub & Startable>) => {
it('can subscribe and publish correctly', async () => {
const defer = pDefer()

const handler = (msg: Message) => {
expect(msg).to.not.eql(undefined)
defer.resolve()
}

await pubsub.start()

pubsub.subscribe(topic)
pubsub.on(topic, handler)
pubsub.addEventListener(topic, (evt) => {
const msg = evt.detail
expect(msg).to.not.eql(undefined)
defer.resolve()
})
await pubsub.publish(topic, data)
await defer.promise

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,12 @@ import { fromString as uint8ArrayFromString } from 'uint8arrays/from-string'
import { expectSet } from './utils.js'
import type { TestSetup } from '../index.js'
import type { PubSub, Message } from '@libp2p/interfaces/pubsub'
import type { Startable } from '@libp2p/interfaces'
import type { EventMap } from './index.js'

export default (common: TestSetup<PubSub & Startable>) => {
export default (common: TestSetup<PubSub<EventMap>>) => {
describe('pubsub connection handlers', () => {
let psA: PubSub & Startable
let psB: PubSub & Startable
let psA: PubSub<EventMap>
let psB: PubSub<EventMap>

describe('nodes send state on connection', () => {
// Create pubsub nodes and connect them
Expand Down Expand Up @@ -48,8 +48,12 @@ export default (common: TestSetup<PubSub & Startable>) => {
await Promise.all([
// @ts-expect-error protected fields
psA._libp2p.dial(psB.peerId),
new Promise((resolve) => psA.once('pubsub:subscription-change', resolve)),
new Promise((resolve) => psB.once('pubsub:subscription-change', resolve))
new Promise((resolve) => psA.addEventListener('pubsub:subscription-change', resolve, {
once: true
})),
new Promise((resolve) => psB.addEventListener('pubsub:subscription-change', resolve, {
once: true
}))
])

expect(psA.peers.size).to.equal(1)
Expand Down Expand Up @@ -103,7 +107,8 @@ export default (common: TestSetup<PubSub & Startable>) => {
let subscribedTopics = psA.getTopics()
expect(subscribedTopics).to.not.include(topic)

psA.on(topic, (msg) => {
psA.addEventListener(topic, (evt) => {
const msg = evt.detail
expect(msg.data).to.equalBytes(data)
defer.resolve()
})
Expand Down Expand Up @@ -174,7 +179,8 @@ export default (common: TestSetup<PubSub & Startable>) => {
let subscribedTopics = psA.getTopics()
expect(subscribedTopics).to.not.include(topic)

psA.on(topic, (msg) => {
psA.addEventListener(topic, (evt) => {
const msg = evt.detail
expect(msg.data).to.equalBytes(data)
defer.resolve()
})
Expand Down Expand Up @@ -228,7 +234,8 @@ export default (common: TestSetup<PubSub & Startable>) => {
let subscribedTopics = psA.getTopics()
expect(subscribedTopics).to.not.include(topic)

psA.on(topic, (msg) => {
psA.addEventListener(topic, (evt) => {
const msg = evt.detail
expect(msg.data).to.equalBytes(data)
counter++
counter === 1 ? defer1.resolve() : defer2.resolve()
Expand Down Expand Up @@ -285,7 +292,8 @@ export default (common: TestSetup<PubSub & Startable>) => {
let bReceivedFirstMessageFromA = false
let bReceivedSecondMessageFromA = false

const handlerSpyA = (message: Message) => {
const handlerSpyA = (evt: CustomEvent<Message>) => {
const message = evt.detail
const data = uint8ArrayToString(message.data)

if (data === 'message-from-b-1') {
Expand All @@ -296,7 +304,8 @@ export default (common: TestSetup<PubSub & Startable>) => {
aReceivedSecondMessageFromB = true
}
}
const handlerSpyB = (message: Message) => {
const handlerSpyB = (evt: CustomEvent<Message>) => {
const message = evt.detail
const data = uint8ArrayToString(message.data)

if (data === 'message-from-a-1') {
Expand All @@ -310,8 +319,8 @@ export default (common: TestSetup<PubSub & Startable>) => {

const topic = 'reconnect-channel'

psA.on(topic, handlerSpyA)
psB.on(topic, handlerSpyB)
psA.addEventListener(topic, handlerSpyA)
psB.addEventListener(topic, handlerSpyB)
psA.subscribe(topic)
psB.subscribe(topic)

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,15 +3,15 @@ import sinon from 'sinon'
import { fromString as uint8ArrayFromString } from 'uint8arrays/from-string'
import type { TestSetup } from '../index.js'
import type { PubSub, PubsubOptions } from '@libp2p/interfaces/pubsub'
import type { Startable } from '@libp2p/interfaces'
import type { EventMap } from './index.js'

const topic = 'foo'
const data = uint8ArrayFromString('bar')
const shouldNotHappen = () => expect.fail()

export default (common: TestSetup<PubSub & Startable, Partial<PubsubOptions>>) => {
export default (common: TestSetup<PubSub<EventMap>, Partial<PubsubOptions>>) => {
describe('emit self', () => {
let pubsub: PubSub & Startable
let pubsub: PubSub<EventMap>

describe('enabled', () => {
before(async () => {
Expand All @@ -30,7 +30,9 @@ export default (common: TestSetup<PubSub & Startable, Partial<PubsubOptions>>) =
})

it('should emit to self on publish', async () => {
const promise = new Promise((resolve) => pubsub.once(topic, resolve))
const promise = new Promise((resolve) => pubsub.addEventListener(topic, resolve, {
once: true
}))

void pubsub.publish(topic, data)

Expand All @@ -55,7 +57,9 @@ export default (common: TestSetup<PubSub & Startable, Partial<PubsubOptions>>) =
})

it('should not emit to self on publish', async () => {
pubsub.once(topic, () => shouldNotHappen)
pubsub.addEventListener(topic, () => shouldNotHappen, {
once: true
})

void pubsub.publish(topic, data)

Expand Down
13 changes: 10 additions & 3 deletions packages/libp2p-interface-compliance-tests/src/pubsub/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,17 @@ import connectionHandlersTest from './connection-handlers.js'
import twoNodesTest from './two-nodes.js'
import multipleNodesTest from './multiple-nodes.js'
import type { TestSetup } from '../index.js'
import type { PubSub } from '@libp2p/interfaces/pubsub'
import type { Startable } from '@libp2p/interfaces'
import type { PubSub, Message, PubsubEvents } from '@libp2p/interfaces/pubsub'

export default (common: TestSetup<PubSub & Startable>) => {
export interface EventMap extends PubsubEvents {
'topic': CustomEvent<Message>
'foo': CustomEvent<Message>
'test-topic': CustomEvent<Message>
'reconnect-channel': CustomEvent<Message>
'Z': CustomEvent<Message>
}

export default (common: TestSetup<PubSub<EventMap>>) => {
describe('interface-pubsub compliance tests', () => {
apiTest(common)
emitSelfTest(common)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,14 +6,14 @@ import * as utils from '@libp2p/pubsub/utils'
import { PeerStreams } from '@libp2p/pubsub/peer-streams'
import type { TestSetup } from '../index.js'
import type { PubSub } from '@libp2p/interfaces/pubsub'
import type { Startable } from '@libp2p/interfaces'
import type { EventMap } from './index.js'

const topic = 'foo'
const data = uint8ArrayFromString('bar')

export default (common: TestSetup<PubSub & Startable>) => {
export default (common: TestSetup<PubSub<EventMap>>) => {
describe('messages', () => {
let pubsub: PubSub & Startable
let pubsub: PubSub<EventMap>

// Create pubsub router
beforeEach(async () => {
Expand Down
Loading

0 comments on commit 221fb6a

Please sign in to comment.