Skip to content

Commit

Permalink
refactor
Browse files Browse the repository at this point in the history
  • Loading branch information
milesstoetzner committed Sep 3, 2023
1 parent ad25913 commit a55cd9f
Show file tree
Hide file tree
Showing 42 changed files with 588 additions and 589 deletions.
172 changes: 86 additions & 86 deletions src/core/actions.ts
Original file line number Diff line number Diff line change
@@ -1,44 +1,44 @@
import {Bridge} from '#/core/bridge'
import {VCAN, VCANOptions} from '#/core/vcan'
import {CanReceiver} from '#/receiver/can'
import {ConsoleReceiver} from '#/receiver/console'
import {HTTPReceiver} from '#/receiver/http'
import {MQTTReceiver} from '#/receiver/mqtt'
import {SocketIOReceiver} from '#/receiver/socket-io'
import {WSReceiver} from '#/receiver/ws'
import {CANSender} from '#/sender/can'
import {ConsoleSender} from '#/sender/console'
import {FileSender} from '#/sender/file'
import {HTTPSender} from '#/sender/http'
import {MQTTSender} from '#/sender/mqtt'
import {SocketIOSender} from '#/sender/socket-io'
import {WSSender} from '#/sender/ws'
import {CANSource} from '#/source/can'
import {ConsoleSource} from '#/source/console'
import {HTTPSource} from '#/source/http'
import {MQTTSource} from '#/source/mqtt'
import {SocketIOSource} from '#/source/socketio'
import {WSSource} from '#/source/ws'
import {CANTarget} from '#/target/can'
import {ConsoleTarget} from '#/target/console'
import {FileTargt} from '#/target/file'
import {HTTPTarget} from '#/target/http'
import {MQTTTarget} from '#/target/mqtt'
import {SocketIOTarget} from '#/target/socketio'
import {WSTarget} from '#/target/ws'
import * as assert from '#assert'
import std from '#std'

export type BridgeOptions = {
receiver?: string
receiverPort?: string
receiverHost?: string
receiverEvent?: string
receiverTopic?: string
receiverName?: string
receiverId?: string
receiverData?: string[]
sender?: string
senderEndpoint?: string
senderEvent?: string
senderTopic?: string
senderName?: string
senderFile?: string
source?: string
sourcePort?: string
sourceHost?: string
sourceEvent?: string
sourceTopic?: string
sourceName?: string
sourceId?: string
sourceData?: string[]
target?: string
targetEndpoint?: string
targetEvent?: string
targetTopic?: string
targetName?: string
targetFile?: string
}

export async function startBridge(options: BridgeOptions) {
std.log('can2x bridge', {options})

const receiver = createReceiver(options)
const sender = createSender(options)
const bridge = new Bridge(receiver, sender)
const source = createSource(options)
const target = createTarget(options)
const bridge = new Bridge(source, target)

std.log('starting bridge')
await bridge.start()
Expand All @@ -63,92 +63,92 @@ export async function stopVCAN(options: VCANOptions) {
return vcan
}

function createReceiver(options: BridgeOptions) {
if (options.receiver === 'can') return new CanReceiver({name: options.receiverName ?? 'can2x'})
function createSource(options: BridgeOptions) {
if (options.source === 'can') return new CANSource({name: options.sourceName ?? 'can2x'})

if (options.receiver === 'console') {
assert.isDefined(options.receiverId, '--receiver-id undefined')
assert.isDefined(options.receiverData, '--receiver-data undefined')
assert.isArray(options.receiverData, '--receiver-data must be an array')
return new ConsoleReceiver({
id: Number(options.receiverId),
data: options.receiverData.map(Number),
if (options.source === 'console') {
assert.isDefined(options.sourceId, '--source-id undefined')
assert.isDefined(options.sourceData, '--source-data undefined')
assert.isArray(options.sourceData, '--source-data must be an array')
return new ConsoleSource({
id: Number(options.sourceId),
data: options.sourceData.map(Number),
})
}

if (options.receiver === 'http')
return new HTTPReceiver({
port: options.receiverPort ? Number(options.receiverPort) : 3000,
host: options.receiverHost ?? 'localhost',
if (options.source === 'http')
return new HTTPSource({
port: options.sourcePort ? Number(options.sourcePort) : 3000,
host: options.sourceHost ?? 'localhost',
})

if (options.receiver === 'mqtt')
return new MQTTReceiver({
port: options.receiverPort ? Number(options.receiverPort) : 3000,
host: options.receiverHost ?? 'localhost',
topic: options.receiverTopic ?? 'can2x',
if (options.source === 'mqtt')
return new MQTTSource({
port: options.sourcePort ? Number(options.sourcePort) : 3000,
host: options.sourceHost ?? 'localhost',
topic: options.sourceTopic ?? 'can2x',
})

if (options.receiver === 'socket-io')
return new SocketIOReceiver({
port: options.receiverPort ? Number(options.receiverPort) : 3000,
host: options.receiverHost ?? 'localhost',
event: options.receiverEvent ?? 'can2x',
if (options.source === 'socketio')
return new SocketIOSource({
port: options.sourcePort ? Number(options.sourcePort) : 3000,
host: options.sourceHost ?? 'localhost',
event: options.sourceEvent ?? 'can2x',
})

if (options.receiver === 'ws')
return new WSReceiver({
port: options.receiverPort ? Number(options.receiverPort) : 3000,
host: options.receiverHost ?? 'localhost',
if (options.source === 'ws')
return new WSSource({
port: options.sourcePort ? Number(options.sourcePort) : 3000,
host: options.sourceHost ?? 'localhost',
})

throw new Error(`Receiver of type "${options.receiver}" unknown`)
throw new Error(`Source of type "${options.source}" unknown`)
}

function createSender(options: BridgeOptions) {
if (options.sender === 'can')
return new CANSender({
name: options.senderName ?? 'can2x',
function createTarget(options: BridgeOptions) {
if (options.target === 'can')
return new CANTarget({
name: options.targetName ?? 'can2x',
})

if (options.sender === 'console') return new ConsoleSender()
if (options.target === 'console') return new ConsoleTarget()

if (options.sender === 'file') {
assert.isString(options.senderFile)
return new FileSender({
file: options.senderFile,
if (options.target === 'file') {
assert.isString(options.targetFile)
return new FileTargt({
file: options.targetFile,
})
}

if (options.sender === 'http') {
assert.isString(options.senderEndpoint)
return new HTTPSender({
endpoint: options.senderEndpoint,
if (options.target === 'http') {
assert.isString(options.targetEndpoint)
return new HTTPTarget({
endpoint: options.targetEndpoint,
})
}

if (options.sender === 'mqtt') {
assert.isString(options.senderEndpoint)
return new MQTTSender({
endpoint: options.senderEndpoint,
topic: options.senderTopic ?? 'can2x',
if (options.target === 'mqtt') {
assert.isString(options.targetEndpoint)
return new MQTTTarget({
endpoint: options.targetEndpoint,
topic: options.targetTopic ?? 'can2x',
})
}

if (options.sender === 'socket-io') {
assert.isDefined(options.senderEndpoint, '--sender-endpoint must be defined')
return new SocketIOSender({
endpoint: options.senderEndpoint,
event: options.senderEvent ?? 'can2x',
if (options.target === 'socketio') {
assert.isDefined(options.targetEndpoint, '--target-endpoint must be defined')
return new SocketIOTarget({
endpoint: options.targetEndpoint,
event: options.targetEvent ?? 'can2x',
})
}

if (options.sender === 'ws') {
assert.isDefined(options.senderEndpoint, '--sender-endpoint must be defined')
return new WSSender({
endpoint: options.senderEndpoint,
if (options.target === 'ws') {
assert.isDefined(options.targetEndpoint, '--target-endpoint must be defined')
return new WSTarget({
endpoint: options.targetEndpoint,
})
}

throw new Error(`Sender of type "${options.sender}" unknown`)
throw new Error(`Target of type "${options.target}" unknown`)
}
40 changes: 20 additions & 20 deletions src/core/bridge.ts
Original file line number Diff line number Diff line change
@@ -1,50 +1,50 @@
import {Receiver} from '#/receiver/receiver'
import {Sender} from '#/sender/sender'
import {Source} from '#/source/source'
import {Target} from '#/target/target'
import * as assert from '#assert'
import std from '#std'
import hae from '#utils/hae'

export class Bridge {
receiver: Receiver
sender: Sender
source: Source
target: Target

constructor(receiver: Receiver, sender: Sender) {
this.receiver = receiver
this.sender = sender
constructor(source: Source, target: Target) {
this.source = source
this.target = target
}

async start() {
std.log('starting receiver')
await this.receiver.start()
std.log('starting source')
await this.source.start()

std.log('starting sender')
await this.sender.start()
std.log('starting target')
await this.target.start()

await this.receiver.ready()
std.log('receiver ready')
await this.source.ready()
std.log('source ready')

await this.sender.ready()
std.log('sender ready')
await this.target.ready()
std.log('target ready')

std.log('bridge started')
await this.receiver.receive(
await this.source.receive(
hae.log(async message => {
std.log('bridging', {message})

assert.isNumber(message.id)
assert.isArray(message.data)
message.data.forEach(assert.isNumber)

await this.sender.send(message)
if (!this.receiver.continuous) await this.stop()
await this.target.send(message)
if (!this.source.continuous) await this.stop()
})
)
}

async stop() {
std.log('stopping bridge')
await this.receiver.stop()
await this.sender.stop()
await this.source.stop()
await this.target.stop()
std.log('bridge stopped')
}
}
3 changes: 1 addition & 2 deletions src/core/vcan.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,10 @@
import std from '#std'
import * as execa from 'execa'

export type VCANOptions = {
name?: string
}

import * as execa from 'execa'

export class VCAN {
options: Required<VCANOptions>

Expand Down
32 changes: 16 additions & 16 deletions src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,27 +12,27 @@ bridge
.command('start')
.description('starts a can2x bridge')
.addOption(
new Option('--receiver [string]', '')
new Option('--source [string]', '')
.default('can')
.choices(['can', 'console', 'http', 'mqtt', 'socket-io', 'ws'])
.choices(['can', 'console', 'http', 'mqtt', 'socketio', 'ws'])
)
.option('--receiver-port [string]', '', '3000')
.option('--receiver-host [string]', '', 'localhost')
.option('--receiver-event [string]', '', 'can2x')
.option('--receiver-topic [string]', '', 'can2x')
.option('--receiver-name [string]', '', 'can2x')
.option('--receiver-id [number]', '')
.option('--receiver-data [numbers...]', '')
.option('--source-port [string]', '', '3000')
.option('--source-host [string]', '', 'localhost')
.option('--source-event [string]', '', 'can2x')
.option('--source-topic [string]', '', 'can2x')
.option('--source-name [string]', '', 'can2x')
.option('--source-id [number]', '')
.option('--source-data [numbers...]', '')
.addOption(
new Option('--sender [string]', '')
new Option('--target [string]', '')
.default('console')
.choices(['can', 'console', 'file', 'http', 'mqtt', 'socket-io', 'ws'])
.choices(['can', 'console', 'file', 'http', 'mqtt', 'socketio', 'ws'])
)
.option('--sender-endpoint [string]', '')
.option('--sender-event [string]', '', 'can2x')
.option('--sender-topic [string]', '', 'can2x')
.option('--sender-name [string]', '', 'can2x')
.option('--sender-file [string]', '')
.option('--target-endpoint [string]', '')
.option('--target-event [string]', '', 'can2x')
.option('--target-topic [string]', '', 'can2x')
.option('--target-name [string]', '', 'can2x')
.option('--target-file [string]', '')
.action(
hae.exit(async options => {
await actions.startBridge(options)
Expand Down
Loading

0 comments on commit a55cd9f

Please sign in to comment.