Skip to content

Commit

Permalink
feat: use typed eventemitter3
Browse files Browse the repository at this point in the history
  • Loading branch information
Julusian committed Oct 2, 2023
1 parent c0ad4e4 commit ff3551e
Show file tree
Hide file tree
Showing 9 changed files with 70 additions and 53 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ package-lock.json
yarn-error.log
/lib
/dist
/scratch

.pnp.*
.yarn/*
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,6 @@
"validate:dependencies": "yarn npm audit --environment production && run license-validate",
"validate:dev-dependencies": "yarn npm audit --environment development",
"license-validate": "sofie-licensecheck --allowPackages caniuse-lite@1.0.30001541",

"eslint": "./node_modules/.bin/eslint",
"prettier": "./node_modules/.bin/prettier",
"lint-staged": "./node_modules/.bin/lint-staged"
Expand All @@ -48,6 +47,7 @@
"dependencies": {
"asn1": "evs-broadcast/node-asn1",
"debug": "^4.3.4",
"eventemitter3": "^4.0.7",
"long": "^3.2.0",
"smart-buffer": "^3.0.3",
"tslib": "^2.6.2"
Expand Down
12 changes: 10 additions & 2 deletions src/Ember/Client/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ import { ConnectionOperation } from '../../model/Connection'
import { Root } from '../../types/types'
import { EmberNode } from '../../model/EmberNode'

import { EventEmitter } from 'events'
import { EventEmitter } from 'eventemitter3'
import { S101Client } from '../Socket'
import { getPath, assertQualifiedEmberNode, insertCommand, updateProps } from '../Lib/util'
import { berEncode } from '../..'
Expand Down Expand Up @@ -67,7 +67,15 @@ export enum ConnectionStatus {
Connected,
}

export class EmberClient extends EventEmitter {
export type EmberClientEvents = {
error: [Error]
warn: [Error]

connected: []
disconnected: []
}

export class EmberClient extends EventEmitter<EmberClientEvents> {
host: string
port: number
tree: Collection<NumberedTreeNode<EmberElement>> = []
Expand Down
39 changes: 20 additions & 19 deletions src/Ember/Server/index.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import { EventEmitter } from 'events'
import { EventEmitter } from 'eventemitter3'
import { S101Server } from '../Socket/S101Server'
import { S101Client } from '../Socket'
import {
EmberElement,
NumberedTreeNodeImpl,
Expand Down Expand Up @@ -28,12 +27,14 @@ import { berEncode } from '../../encodings/ber'
import { Command, CommandType, FieldFlags, GetDirectory, Invoke } from '../../model/Command'
import { Connection, ConnectionOperation, ConnectionImpl } from '../../model/Connection'
import { InvocationResultImpl } from '../../model/InvocationResult'
import S101Socket from '../Socket/S101Socket'

const ServerEvents = null

export { EmberServer, ServerEvents }
export type EmberServerEvents = {
error: [Error]
clientError: [client: S101Socket, error: Error]
}

class EmberServer extends EventEmitter {
export class EmberServer extends EventEmitter<EmberServerEvents> {
address: string | undefined
port: number
tree: Collection<NumberedTreeNode<EmberElement>> = {}
Expand All @@ -46,8 +47,8 @@ class EmberServer extends EventEmitter {
onMatrixOperation?: (Matrix: NumberedTreeNode<Matrix>, connection: Connections) => Promise<void>

private _server: S101Server
private _clients: Set<S101Client> = new Set()
private _subscriptions: { [path: string]: Array<S101Client> } = {}
private _clients: Set<S101Socket> = new Set()
private _subscriptions: { [path: string]: Array<S101Socket> } = {}

constructor(port: number, address?: string) {
super()
Expand All @@ -56,7 +57,7 @@ class EmberServer extends EventEmitter {
this.port = port
this._server = new S101Server(port, address)

this._server.on('connection', (client: S101Client) => {
this._server.on('connection', (client: S101Socket) => {
this._clients.add(client)

client.on('emberTree', (tree: DecodeResult<Collection<RootElement>>) => this._handleIncoming(tree, client))
Expand Down Expand Up @@ -123,7 +124,7 @@ class EmberServer extends EventEmitter {
elPath = elPath.slice(0, -2) // remove the last element number
}

for (const [path, clients] of Object.entries<S101Client[]>(this._subscriptions)) {
for (const [path, clients] of Object.entries<S101Socket[]>(this._subscriptions)) {
if (elPath === path) {
clients.forEach((client) => {
client.sendBER(data)
Expand Down Expand Up @@ -166,7 +167,7 @@ class EmberServer extends EventEmitter {
})
const data = berEncode([qualified], RootType.Elements)

for (const [path, clients] of Object.entries<S101Client[]>(this._subscriptions)) {
for (const [path, clients] of Object.entries<S101Socket[]>(this._subscriptions)) {
if (qualified.path === path) {
clients.forEach((client) => {
client.sendBER(data)
Expand All @@ -175,7 +176,7 @@ class EmberServer extends EventEmitter {
}
}

private _handleIncoming(incoming: DecodeResult<Collection<RootElement>>, client: S101Client) {
private _handleIncoming(incoming: DecodeResult<Collection<RootElement>>, client: S101Socket) {
for (const rootEl of Object.values<RootElement>(incoming.value)) {
if (rootEl.contents.type === ElementType.Command) {
// command on root
Expand All @@ -191,7 +192,7 @@ class EmberServer extends EventEmitter {
private _handleNode(
path: string,
el: QualifiedElement<EmberElement> | NumberedTreeNode<EmberElement>,
client: S101Client
client: S101Socket
) {
const children = Object.values<NumberedTreeNode<EmberElement>>(el.children || {})

Expand Down Expand Up @@ -229,7 +230,7 @@ class EmberServer extends EventEmitter {
private async _handleSetValue(
path: string,
el: QualifiedElement<Parameter> | NumberedTreeNode<Parameter>,
client: S101Client
client: S101Socket
) {
const tree = this.getElementByPath(path)
if (!tree || tree.contents.type !== ElementType.Parameter || el.contents.value === undefined) return
Expand All @@ -247,7 +248,7 @@ class EmberServer extends EventEmitter {
}
}

private async _handleCommand(path: string, el: NumberedTreeNode<Command>, client: S101Client) {
private async _handleCommand(path: string, el: NumberedTreeNode<Command>, client: S101Socket) {
const tree = path ? this.getElementByPath(path) : this.tree
if (!tree) return

Expand Down Expand Up @@ -303,10 +304,10 @@ class EmberServer extends EventEmitter {
return tree
}

private _subscribe(path: string, client: S101Client) {
private _subscribe(path: string, client: S101Socket) {
this._subscriptions[path] = [...(this._subscriptions[path] || []), client]
}
private _unsubscribe(path: string, client: S101Client) {
private _unsubscribe(path: string, client: S101Socket) {
if (!this._subscriptions[path]) return

this._subscriptions[path].forEach((c, i) => {
Expand All @@ -315,7 +316,7 @@ class EmberServer extends EventEmitter {
}
})
}
private _clearSubscription(client: S101Client) {
private _clearSubscription(client: S101Socket) {
for (const path of Object.keys(this._subscriptions)) {
this._unsubscribe(path, client)
}
Expand All @@ -324,7 +325,7 @@ class EmberServer extends EventEmitter {
private _handleGetDirectory(
tree: Collection<NumberedTreeNode<EmberElement>> | NumberedTreeNode<EmberElement>,
_dirFieldMasks: FieldFlags,
client: S101Client
client: S101Socket
) {
if (tree === this.tree) {
// getDir on root
Expand Down
9 changes: 7 additions & 2 deletions src/Ember/Socket/S101Server.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,13 @@
import { EventEmitter } from 'events'
import { EventEmitter } from 'eventemitter3'
import { Socket, createServer, Server } from 'net'
import S101Socket from './S101Socket'

export class S101Server extends EventEmitter {
export type S101ServerEvents = {
error: [Error]
listening: []
connection: [client: S101Socket]
}
export class S101Server extends EventEmitter<S101ServerEvents> {
port: number
address: string | undefined
server: Server | null
Expand Down
27 changes: 11 additions & 16 deletions src/Ember/Socket/S101Socket.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { EventEmitter } from 'events'
import { EventEmitter } from 'eventemitter3'
import { Socket } from 'net'

import { S101Codec } from '../../S101'
Expand All @@ -8,7 +8,16 @@ import { normalizeError } from '../Lib/util'

export type Request = any

export default class S101Socket extends EventEmitter {
export type S101SocketEvents = {
error: [Error]
emberPacket: [packet: Buffer]
emberTree: [root: any]
connecting: []
connected: []
disconnected: []
}

export default class S101Socket extends EventEmitter<S101SocketEvents> {
socket: Socket | undefined
keepaliveInterval = 10
keepaliveMaxResponseTime = 500
Expand Down Expand Up @@ -50,20 +59,6 @@ export default class S101Socket extends EventEmitter {
this._initSocket()
}

// Overide EventEmitter.on() for stronger typings:
on: ((event: 'emberPacket', listener: (packet: Buffer) => void) => this) &
((event: 'emberTree', listener: (root: any) => void) => this) &
((event: 'error', listener: (error: Error) => void) => this) &
((event: 'connecting', listener: () => void) => this) &
((event: 'connected', listener: () => void) => this) &
((event: 'disconnected', listener: () => void) => this) = super.on
emit: ((event: 'emberPacket', packet: Buffer) => boolean) &
((event: 'emberTree', root: any) => boolean) &
((event: 'error', error: Error) => boolean) &
((event: 'connecting') => boolean) &
((event: 'connected') => boolean) &
((event: 'disconnected') => boolean) = super.emit

_initSocket(): void {
if (this.socket != null) {
this.socket.on('data', (data) => {
Expand Down
18 changes: 8 additions & 10 deletions src/S101/S101Codec.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { EventEmitter } from 'events'
import { EventEmitter } from 'eventemitter3'
import { SmartBuffer } from 'smart-buffer'
import Debug from 'debug'
import { format } from 'util'
Expand Down Expand Up @@ -52,7 +52,13 @@ const CRC_TABLE = [
0x3de3, 0x2c6a, 0x1ef1, 0x0f78,
]

export default class S101Codec extends EventEmitter {
export type S101CodecEvents = {
emberPacket: [packet: Buffer]
keepaliveReq: []
keepaliveResp: []
}

export default class S101Codec extends EventEmitter<S101CodecEvents> {
inbuf = new SmartBuffer()
emberbuf = new SmartBuffer()
escaped = false
Expand Down Expand Up @@ -226,14 +232,6 @@ export default class S101Codec extends EventEmitter {
return this._finalizeBuffer(frame)
}

// Overide EventEmitter.on() for stronger typings:
on: ((event: 'emberPacket', listener: (packet: Buffer) => void) => this) &
((event: 'keepaliveReq', listener: () => void) => this) &
((event: 'keepaliveResp', listener: () => void) => this) = super.on
emit: ((event: 'emberPacket', packet: Buffer) => boolean) &
((event: 'keepaliveReq') => boolean) &
((event: 'keepaliveResp') => boolean) = super.emit

private _finalizeBuffer(smartbuf: SmartBuffer) {
const crc = ~this._calculateCRCCE(smartbuf.toBuffer().slice(1, smartbuf.length)) & 0xffff
const crcHi = crc >> 8
Expand Down
7 changes: 4 additions & 3 deletions src/index.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { EmberClient } from './Ember/Client/index'
import { EmberClient, EmberClientEvents } from './Ember/Client/index'
import { EmberLib } from './Ember/Lib/index'
import { EmberServer, ServerEvents } from './Ember/Server/index'
import { EmberServer, EmberServerEvents } from './Ember/Server/index'
import { S101Codec } from './S101/index'
import { S101Client } from './Ember/Socket/index'
// import { EmberTreeNode, TreeElement } from './types/types'
Expand Down Expand Up @@ -40,10 +40,11 @@ const Decoder = EmberLib.DecodeBuffer

export {
EmberClient,
EmberClientEvents,
Decoder,
EmberLib,
EmberServer,
ServerEvents,
EmberServerEvents,
S101Codec,
S101Client,
berEncode,
Expand Down
8 changes: 8 additions & 0 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -2028,6 +2028,7 @@ asn1@evs-broadcast/node-asn1:
"@types/long": ^4.0.1
asn1: evs-broadcast/node-asn1
debug: ^4.3.4
eventemitter3: ^5.0.1
jest: ^29.7.0
long: ^3.2.0
rimraf: ^5.0.5
Expand Down Expand Up @@ -2341,6 +2342,13 @@ asn1@evs-broadcast/node-asn1:
languageName: node
linkType: hard

"eventemitter3@npm:^5.0.1":
version: 5.0.1
resolution: "eventemitter3@npm:5.0.1"
checksum: 543d6c858ab699303c3c32e0f0f47fc64d360bf73c3daf0ac0b5079710e340d6fe9f15487f94e66c629f5f82cd1a8678d692f3dbb6f6fcd1190e1b97fcad36f8
languageName: node
linkType: hard

"execa@npm:^5.0.0":
version: 5.1.1
resolution: "execa@npm:5.1.1"
Expand Down

0 comments on commit ff3551e

Please sign in to comment.