Skip to content

Commit

Permalink
feat: Initial working connection
Browse files Browse the repository at this point in the history
  • Loading branch information
Julusian committed Oct 11, 2018
1 parent 5c5524b commit e5e264c
Show file tree
Hide file tree
Showing 10 changed files with 1,280 additions and 4 deletions.
47 changes: 47 additions & 0 deletions src/codes.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@

export type ResponseCode = ErrorCode | SynchronousCode | AsynchronousCode

export enum ErrorCode {
SyntaxError = 100,
UnsupportedParameter = 101,
InvalidValue = 102,
Unsupported = 103,
DiskFull = 104,
NoDisk = 105,
DiskError = 106,
TimelineEmpty = 107,
InternalError = 108,
OutOfRange = 109,
NoInput = 110,
RemoteControlDisabled = 111,
ConnectionRejected = 120,
InvalidState = 150,
InvalidCodec = 151,
InvalidFormat = 160,
InvalidToken = 161,
FormatNotPrepared = 162,
}

export enum SynchronousCode {
OK = 200,
Notify = 209,
}

export enum AsynchronousCode {
ConnectionInfo = 500,
}

export enum ResponseCodeType {
Unknown,
Error,
Synchronous,
Asynchronous,
}

export function GetResponseCodeType (val: ResponseCode): ResponseCodeType {
if (val >= 100 && val <= 199) return ResponseCodeType.Error
if (val >= 200 && val <= 299) return ResponseCodeType.Synchronous
if (val >= 500 && val <= 599) return ResponseCodeType.Asynchronous

return ResponseCodeType.Unknown
}
61 changes: 61 additions & 0 deletions src/commands/abstractCommand.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
import { ResponseCode } from '../codes'
import { ResponseMessage, NamedMessage } from '../message'

export interface ErrorResponse extends ResponseMessage {
}

export interface AbstractCommand {
expectedResponseCode: ResponseCode | null

deserialize(msg: ResponseMessage)
serialize(): NamedMessage | null

markSent()
}

export abstract class AbstractCommandBase<T> implements Promise<T>, AbstractCommand {
abstract expectedResponseCode: ResponseCode | null

abstract deserialize(msg: ResponseMessage)
abstract serialize(): NamedMessage | null

private _promise: Promise<T>
protected resolve: (res: T) => void
protected reject: (res: ErrorResponse) => void

constructor() {
// TODO - can this be done any cleaner?
this._promise = new Promise<T>((resolve, reject) => {
this.resolve = resolve
this.reject = reject
})
}

then<TResult1 = T, TResult2 = never>(onfulfilled?: ((value: T) => TResult1 | PromiseLike<TResult1>) | undefined | null, onrejected?: ((reason: any) => TResult2 | PromiseLike<TResult2>) | undefined | null): Promise<TResult1 | TResult2> {
return this._promise.then(onfulfilled, onrejected)
}

catch<TResult = never>(onrejected?: ((reason: any) => TResult | PromiseLike<TResult>) | undefined | null): Promise<T | TResult> {
return this._promise.catch(onrejected)
}

[Symbol.toStringTag] // TODO what is this??

markSent() {
// TODO - track time sent
}
}

// export abstract class AbstractCommandBaseNoResponse extends AbstractCommandBase<boolean>{ // TODO - is this type actually needed??
// expectedResponseCode = null

// markSent() {
// super.markSent()
// // No response will be received, so resolve the promise now
// this.resolve(true)
// }

// deserialize(msg: ResponseMessage){
// msg.Name
// }
// }
28 changes: 28 additions & 0 deletions src/commands/connect.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
import { AsynchronousCode } from '../codes'
import { ResponseMessage } from '../message'
import { AbstractCommandBase } from './abstractCommand'

export interface ConnectionInfoResponse {
ProtocolVersion: number
Model: string
}

// Purpose of this is to emit the connect event with the connectionInfo
export class DummyConnectCommand extends AbstractCommandBase<ConnectionInfoResponse> {
expectedResponseCode = AsynchronousCode.ConnectionInfo

deserialize (msg: ResponseMessage) {
if (msg.Code === this.expectedResponseCode) {
this.resolve({
ProtocolVersion: parseFloat(msg.Params['protocol version']),
Model: msg.Params['model'],
})
} else {
this.reject(msg)
}
}
serialize () {
// Nothing to send
return null
}
}
4 changes: 4 additions & 0 deletions src/commands/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
export { AbstractCommand, ErrorResponse } from './abstractCommand'

export * from './notify'
export { ConnectionInfoResponse } from './connect'
66 changes: 66 additions & 0 deletions src/commands/notify.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
import { SynchronousCode } from '../codes'
import { ResponseMessage, NamedMessage } from '../message'
import { AbstractCommandBase } from './abstractCommand'
import { SetBoolIfDefined } from './util'

export interface NotifyCommandResponse {
Remote: boolean
Transport: boolean
Slot: boolean
Configuration: boolean
}

export class NotifyGetCommand extends AbstractCommandBase<NotifyCommandResponse> {
expectedResponseCode = SynchronousCode.Notify

deserialize (msg: ResponseMessage) {
if (msg.Code === this.expectedResponseCode) {
this.resolve({
Remote: msg.Params['remote'] === 'true',
Transport: msg.Params['transport'] === 'true',
Slot: msg.Params['slot'] === 'true',
Configuration: msg.Params['configuration'] === 'true',
})
} else {
this.reject(msg)
}
}
serialize () {
const res: NamedMessage = {
Name: 'notify',
Params: {}
}

return res
}
}

export class NotifySetCommand extends AbstractCommandBase<boolean> {
expectedResponseCode = SynchronousCode.OK

Remote: boolean | undefined
Transport: boolean | undefined
Slot: boolean | undefined
Configuration: boolean | undefined

deserialize (msg: ResponseMessage) {
if (msg.Code === this.expectedResponseCode) {
this.resolve(true)
} else {
this.reject(msg)
}
}
serialize () {
const res: NamedMessage = {
Name: 'notify',
Params: {}
}

SetBoolIfDefined(res, 'remote', this.Remote)
SetBoolIfDefined(res, 'transport', this.Transport)
SetBoolIfDefined(res, 'slot', this.Slot)
SetBoolIfDefined(res, 'configuration', this.Configuration)

return res
}
}
9 changes: 9 additions & 0 deletions src/commands/util.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import { NamedMessage } from '../message'

export function SetBoolIfDefined(msg: NamedMessage, name: string, val: boolean | undefined) {
if (val !== undefined) {
msg.Params[name] = val ? 'true' : 'false'
}
}

export function literal<T> (o: T) { return o }
Loading

0 comments on commit e5e264c

Please sign in to comment.