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

Commit

Permalink
fix: move startable and events interfaces (#209)
Browse files Browse the repository at this point in the history
The index file is a dumping ground for interfaces, move them into their own files to keep things manageable.

Also fixes pubsub test to actually shut the nodes down.
  • Loading branch information
achingbrain committed May 4, 2022
1 parent 9ca1d2e commit 8ce8a08
Show file tree
Hide file tree
Showing 31 changed files with 294 additions and 278 deletions.
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@
"test:firefox-webworker": "lerna run --concurrency 1 test:firefox-webworker -- --",
"test:electron-main": "lerna run --concurrency 1 test:electron-main -- --",
"test:electron-renderer": "lerna run --concurrency 1 test:electron-renderer -- --",
"clean": "lerna run clean",
"build": "lerna run build",
"lint": "lerna run lint",
"dep-check": "lerna run dep-check",
Expand Down
65 changes: 0 additions & 65 deletions packages/libp2p-interface-compliance-tests/src/index.ts
Original file line number Diff line number Diff line change
@@ -1,70 +1,5 @@
import { isStartable, Startable } from '@libp2p/interfaces'

export interface TestSetup<T, SetupArgs = {}> {
setup: (args?: SetupArgs) => Promise<T>
teardown: () => Promise<void>
}

export async function start (...objs: any[]) {
const startables: Startable[] = []

for (const obj of objs) {
if (isStartable(obj)) {
startables.push(obj)
}
}

await Promise.all(
startables.map(async s => {
if (s.beforeStart != null) {
await s.beforeStart()
}
})
)

await Promise.all(
startables.map(async s => {
await s.start()
})
)

await Promise.all(
startables.map(async s => {
if (s.afterStart != null) {
await s.afterStart()
}
})
)
}

export async function stop (...objs: any[]) {
const startables: Startable[] = []

for (const obj of objs) {
if (isStartable(obj)) {
startables.push(obj)
}
}

await Promise.all(
startables.map(async s => {
if (s.beforeStop != null) {
await s.beforeStop()
}
})
)

await Promise.all(
startables.map(async s => {
await s.stop()
})
)

await Promise.all(
startables.map(async s => {
if (s.afterStop != null) {
await s.afterStop()
}
})
)
}
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { CustomEvent, EventEmitter, Startable } from '@libp2p/interfaces'
import { CustomEvent, EventEmitter } from '@libp2p/interfaces/events'
import type { Startable } from '@libp2p/interfaces/startable'
import type { Connection } from '@libp2p/interfaces/connection'
import type { PeerId } from '@libp2p/interfaces/peer-id'
import type { ConnectionManager, ConnectionManagerEvents } from '@libp2p/interfaces/connection-manager'
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import { expect } from 'aegir/chai'
import { mockConnection } from './connection.js'
import type { Upgrader, MultiaddrConnection, UpgraderEvents } from '@libp2p/interfaces/transport'
import type { Registrar } from '@libp2p/interfaces/registrar'
import { EventEmitter } from '@libp2p/interfaces'
import { EventEmitter } from '@libp2p/interfaces/events'

export interface MockUpgraderInit {
registrar?: Registrar
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,10 @@ import { expect } from 'aegir/chai'
import { Multiaddr } from '@multiformats/multiaddr'
import delay from 'delay'
import pDefer from 'p-defer'
import { start, stop } from '../index.js'
import { start, stop } from '@libp2p/interfaces/startable'
import type { TestSetup } from '../index.js'
import type { PeerDiscovery } from '@libp2p/interfaces/peer-discovery'
import type { Startable } from '@libp2p/interfaces'
import type { Startable } from '@libp2p/interfaces/startable'

export default (common: TestSetup<PeerDiscovery & Startable>) => {
describe('interface-peer-discovery compliance tests', () => {
Expand Down
5 changes: 2 additions & 3 deletions packages/libp2p-interface-compliance-tests/src/pubsub/api.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,7 @@ import type { PubSub } from '@libp2p/interfaces/pubsub'
import type { PubSubArgs } from './index.js'
import type { Components } from '@libp2p/interfaces/components'
import { createComponents } from './utils.js'
import { start, stop } from '../index.js'
import { isStartable } from '@libp2p/interfaces'
import { isStartable, start, stop } from '@libp2p/interfaces/startable'
import { mockNetwork } from '../mocks/connection-manager.js'

const topic = 'foo'
Expand All @@ -36,7 +35,7 @@ export default (common: TestSetup<PubSub, PubSubArgs>) => {

afterEach(async () => {
sinon.restore()
await stop(common)
await stop(components)
await common.teardown()
mockNetwork.reset()
})
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import type { TestSetup } from '../index.js'
import type { Message, PubSub } from '@libp2p/interfaces/pubsub'
import type { PubSubArgs } from './index.js'
import type { Components } from '@libp2p/interfaces/components'
import { start, stop } from '../index.js'
import { start, stop } from '@libp2p/interfaces/startable'
import { createComponents } from './utils.js'
import { pEvent } from 'p-event'
import { mockNetwork } from '../mocks/connection-manager.js'
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import { mockRegistrar } from '../mocks/registrar.js'
import type { TestSetup } from '../index.js'
import type { PubSubArgs } from './index.js'
import { Components } from '@libp2p/interfaces/components'
import { start, stop } from '../index.js'
import { start, stop } from '@libp2p/interfaces/startable'
import type { PubSub } from '@libp2p/interfaces/pubsub'
import { createComponents } from './utils.js'
import { mockNetwork } from '../mocks/connection-manager.js'
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import type { TestSetup } from '../index.js'
import type { Message, PubSub } from '@libp2p/interfaces/pubsub'
import type { PubSubArgs } from './index.js'
import type { Components } from '@libp2p/interfaces/components'
import { start, stop } from '../index.js'
import { start, stop } from '@libp2p/interfaces/startable'
import { pEvent } from 'p-event'
import { createComponents } from './utils.js'
import { mockNetwork } from '../mocks/connection-manager.js'
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import type { TestSetup } from '../index.js'
import type { Message, PubSub } from '@libp2p/interfaces/pubsub'
import type { PubSubArgs } from './index.js'
import type { Components } from '@libp2p/interfaces/components'
import { start, stop } from '../index.js'
import { start, stop } from '@libp2p/interfaces/startable'
import delay from 'delay'
import { mockNetwork } from '../mocks/connection-manager.js'

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import type { TestSetup } from '../index.js'
import type { Message, PubSub } from '@libp2p/interfaces/pubsub'
import type { PubSubArgs } from './index.js'
import type { Components } from '@libp2p/interfaces/components'
import { start, stop } from '../index.js'
import { start, stop } from '@libp2p/interfaces/startable'
import { mockNetwork } from '../mocks/connection-manager.js'

const topic = 'foo'
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import { mockUpgrader } from '../mocks/upgrader.js'
import defer from 'p-defer'
import { mockRegistrar } from '../mocks/registrar.js'
import drain from 'it-drain'
import { CustomEvent } from '@libp2p/interfaces'
import { CustomEvent } from '@libp2p/interfaces/events'
import type { TestSetup } from '../index.js'
import type { Transport, Upgrader } from '@libp2p/interfaces/transport'
import type { TransportTestFixtures } from './index.js'
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { Multiaddr } from '@multiformats/multiaddr'
import * as PeerIdFactory from '@libp2p/peer-id-factory'
import { EventEmitter, CustomEvent } from '@libp2p/interfaces'
import { EventEmitter, CustomEvent } from '@libp2p/interfaces/events'
import type { PeerDiscovery, PeerDiscoveryEvents } from '@libp2p/interfaces/peer-discovery'
import type { PeerInfo } from '@libp2p/interfaces/peer-info'

Expand Down
12 changes: 12 additions & 0 deletions packages/libp2p-interfaces/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,10 @@
"import": "./dist/src/index.js",
"types": "./dist/src/index.d.ts"
},
"./address-manager": {
"import": "./dist/src/address-manager.js",
"types": "./dist/src/address-manager.d.ts"
},
"./components": {
"import": "./dist/src/components.js",
"types": "./dist/src/components.d.ts"
Expand Down Expand Up @@ -84,6 +88,10 @@
"import": "./dist/src/errors.js",
"types": "./dist/src/errors.d.ts"
},
"./events": {
"import": "./dist/src/events.js",
"types": "./dist/src/events.d.ts"
},
"./keys": {
"import": "./dist/src/keys/index.js",
"types": "./dist/src/keys/index.d.ts"
Expand Down Expand Up @@ -124,6 +132,10 @@
"import": "./dist/src/registrar/index.js",
"types": "./dist/src/registrar/index.d.ts"
},
"./startable": {
"import": "./dist/src/startable.js",
"types": "./dist/src/startable.d.ts"
},
"./stream-muxer": {
"import": "./dist/src/stream-muxer/index.js",
"types": "./dist/src/stream-muxer/index.d.ts"
Expand Down
36 changes: 36 additions & 0 deletions packages/libp2p-interfaces/src/address-manager/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
import type { Multiaddr } from '@multiformats/multiaddr'
import type { EventEmitter } from '../events.js'

export interface AddressManagerEvents {
/**
* Emitted when the current node's addresses change
*/
'change:addresses': CustomEvent
}

export interface AddressManager extends EventEmitter<AddressManagerEvents> {
/**
* Get peer listen multiaddrs
*/
getListenAddrs: () => Multiaddr[]

/**
* Get peer announcing multiaddrs
*/
getAnnounceAddrs: () => Multiaddr[]

/**
* Get observed multiaddrs
*/
getObservedAddrs: () => Multiaddr[]

/**
* Add peer observed addresses
*/
addObservedAddr: (addr: Multiaddr) => void

/**
* Get the current node's addresses
*/
getAddresses: () => Multiaddr[]
}
3 changes: 2 additions & 1 deletion packages/libp2p-interfaces/src/components.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
import errCode from 'err-code'
import type { ConnectionGater, ConnectionProtector } from './connection/index.js'
import type { ContentRouting } from './content-routing/index.js'
import { AddressManager, isStartable, Startable } from './index.js'
import type { AddressManager } from './address-manager/index.js'
import { isStartable, Startable } from './startable.js'
import type { Metrics } from './metrics/index.js'
import type { PeerId } from './peer-id/index.js'
import type { PeerRouting } from './peer-routing/index.js'
Expand Down
3 changes: 2 additions & 1 deletion packages/libp2p-interfaces/src/connection-manager/index.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import type { AbortOptions, EventEmitter } from '../index.js'
import type { AbortOptions } from '../index.js'
import type { EventEmitter } from '../events.js'
import type { Connection } from '../connection/index.js'
import type { PeerId } from '../peer-id/index.js'

Expand Down
98 changes: 98 additions & 0 deletions packages/libp2p-interfaces/src/events.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@

export interface EventCallback<EventType> { (evt: EventType): void }
export type EventHandler<EventType> = EventCallback<EventType> | ({ handleEvent: EventCallback<EventType> }) | null

interface Listener {
once: boolean
callback: any
}

/**
* Adds types to the EventTarget class. Hopefully this won't be necessary forever.
*
* https://github.com/microsoft/TypeScript/issues/28357
* https://github.com/microsoft/TypeScript/issues/43477
* https://github.com/microsoft/TypeScript/issues/299
* etc
*/
export class EventEmitter<EventMap> extends EventTarget {
#listeners: Map<any, Listener[]> = new Map()

listenerCount (type: string) {
const listeners = this.#listeners.get(type)

if (listeners == null) {
return 0
}

return listeners.length
}

// @ts-expect-error EventTarget is not typed
addEventListener<U extends keyof EventMap> (type: U, callback: EventHandler<EventMap[U]>, options?: AddEventListenerOptions | boolean) {
// @ts-expect-error EventTarget is not typed
super.addEventListener(type, callback, options)

let list = this.#listeners.get(type)

if (list == null) {
list = []
this.#listeners.set(type, list)
}

list.push({
callback,
once: (options !== true && options !== false && options?.once) ?? false
})
}

// @ts-expect-error EventTarget is not typed
removeEventListener<U extends keyof EventMap> (type: U, callback?: EventHandler<EventMap[U]> | undefined, options?: EventListenerOptions | boolean) {
// @ts-expect-error EventTarget is not typed
super.removeEventListener(type, callback, options)

let list = this.#listeners.get(type)

if (list == null) {
return
}

list = list.filter(({ callback: cb }) => cb !== callback)
this.#listeners.set(type, list)
}

dispatchEvent (event: Event): boolean {
const result = super.dispatchEvent(event)

let list = this.#listeners.get(event.type)

if (list == null) {
return result
}

list = list.filter(({ once }) => !once)
this.#listeners.set(event.type, list)

return result
}
}

/**
* CustomEvent is a standard event but it's not supported by node.
*
* Remove this when https://github.com/nodejs/node/issues/40678 is closed.
*
* Ref: https://developer.mozilla.org/en-US/docs/Web/API/CustomEvent
*/
class CustomEventPolyfill<T = any> extends Event {
/** Returns any custom data event was created with. Typically used for synthetic events. */
public detail: T

constructor (message: string, data?: EventInit & { detail: T }) {
super(message, data)
// @ts-expect-error could be undefined
this.detail = data?.detail
}
}

export const CustomEvent = globalThis.CustomEvent ?? CustomEventPolyfill
Loading

0 comments on commit 8ce8a08

Please sign in to comment.