tci-client-node 0.2.0 → 0.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +17 -0
- package/README.md +50 -6
- package/dist/audio/index.cjs +11 -0
- package/dist/audio/index.cjs.map +1 -1
- package/dist/audio/index.d.cts +4 -2
- package/dist/audio/index.d.ts +4 -2
- package/dist/audio/index.js +10 -0
- package/dist/audio/index.js.map +1 -1
- package/dist/dialect/index.cjs +193 -12
- package/dist/dialect/index.cjs.map +1 -1
- package/dist/dialect/index.d.cts +3 -2
- package/dist/dialect/index.d.ts +3 -2
- package/dist/dialect/index.js +193 -12
- package/dist/dialect/index.js.map +1 -1
- package/dist/errors-CT3b8LLw.d.cts +9 -0
- package/dist/errors-CT3b8LLw.d.ts +9 -0
- package/dist/index.cjs +606 -6
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +68 -6
- package/dist/index.d.ts +68 -6
- package/dist/index.js +599 -6
- package/dist/index.js.map +1 -1
- package/dist/meter/index.cjs +348 -0
- package/dist/meter/index.cjs.map +1 -0
- package/dist/meter/index.d.cts +78 -0
- package/dist/meter/index.d.ts +78 -0
- package/dist/meter/index.js +317 -0
- package/dist/meter/index.js.map +1 -0
- package/dist/protocol/index.d.cts +36 -2
- package/dist/protocol/index.d.ts +36 -2
- package/dist/testing/index.cjs +58 -0
- package/dist/testing/index.cjs.map +1 -1
- package/dist/testing/index.d.cts +23 -1
- package/dist/testing/index.d.ts +23 -1
- package/dist/testing/index.js +58 -0
- package/dist/testing/index.js.map +1 -1
- package/dist/types-C0qVJVSO.d.ts +74 -0
- package/dist/types-C4MtLKoy.d.cts +74 -0
- package/dist/{types-xRotf9gW.d.cts → types-CYK_NOTz.d.cts} +5 -1
- package/dist/{types-9seY9Th-.d.ts → types-DVIPU-VR.d.ts} +5 -1
- package/package.json +11 -2
- package/dist/index-lbK6NGY4.d.cts +0 -42
- package/dist/index-paj1AOJY.d.ts +0 -42
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/errors.ts","../src/client/TciClient.ts","../src/audio/streamFrame.ts","../src/protocol/text.ts","../src/protocol/commandQueue.ts","../src/dialect/builtins.ts","../src/dialect/registry.ts","../src/dialect/handshake.ts","../src/transport/WebSocketTransport.ts"],"sourcesContent":["export type TciErrorCode =\n | 'connect-timeout'\n | 'handshake-timeout'\n | 'invalid-handshake'\n | 'unknown-dialect'\n | 'command-timeout'\n | 'not-connected'\n | 'disconnected'\n | 'protocol-error'\n | 'invalid-frame'\n | 'cancelled';\n\nexport class TciError extends Error {\n readonly code: TciErrorCode;\n readonly details?: unknown;\n\n constructor(code: TciErrorCode, message: string, details?: unknown) {\n super(message);\n this.name = 'TciError';\n this.code = code;\n this.details = details;\n }\n}\n\nexport function toTciError(error: unknown, fallbackCode: TciErrorCode = 'protocol-error'): TciError {\n if (error instanceof TciError) {\n return error;\n }\n if (error instanceof Error) {\n return new TciError(fallbackCode, error.message, error);\n }\n return new TciError(fallbackCode, String(error), error);\n}\n","import { EventEmitter } from 'eventemitter3';\nimport WebSocket from 'ws';\nimport { TciError, toTciError } from '../errors.js';\nimport {\n buildTxAudioFrame,\n normalizeSampleType,\n parseStreamFrame,\n sampleTypeName,\n TciSampleType,\n TciStreamType,\n type BuildTxAudioFrameOptions,\n type TciSampleTypeName,\n type TciStreamFrame,\n} from '../audio/streamFrame.js';\nimport {\n formatTciCommand,\n parseTciText,\n TciCommandQueue,\n type QueueCommandOptions,\n type TciCommand,\n} from '../protocol/index.js';\nimport {\n assertValidTciHandshake,\n defaultTciDialectRegistry,\n parseProtocolIdentity,\n type TciDialect,\n type TciDialectId,\n type TciDialectRegistry,\n type TciDialectSelection,\n type TciHandshakeResult,\n type TciWriteResult,\n} from '../dialect/index.js';\nimport {\n WebSocketTciTransport,\n type TciTransport,\n type TciTransportFactory,\n} from '../transport/index.js';\n\nexport interface TciClientOptions {\n url: string;\n receiver?: number;\n trx?: number;\n vfo?: number;\n connectTimeoutMs?: number;\n handshakeTimeoutMs?: number;\n commandTimeoutMs?: number;\n writeAckMode?: TciWriteAckMode;\n writeTimeoutMs?: number;\n writeSettleMs?: number;\n frequencyWriteSettleMs?: number;\n dialect?: TciDialectSelection;\n dialectRegistry?: TciDialectRegistry;\n WebSocketImpl?: typeof WebSocket;\n transportFactory?: TciTransportFactory;\n}\n\nexport interface TciAudioConfig {\n sampleRate: 8_000 | 12_000 | 24_000 | 48_000 | number;\n sampleType?: TciSampleType | TciSampleTypeName;\n channels?: 1 | 2 | number;\n samplesPerFrame?: number;\n txBufferingMs?: number;\n}\n\nexport interface TciPttOptions {\n source?: 'tci' | 'mic1' | 'mic2' | 'micpc' | 'ecoder2' | string;\n trx?: number;\n ackMode?: TciWriteAckMode;\n timeoutMs?: number;\n settleMs?: number;\n}\n\nexport type TciWriteAckMode = 'state' | 'reply' | 'optimistic';\n\nexport interface TciWriteOptions {\n ackMode?: TciWriteAckMode;\n timeoutMs?: number;\n settleMs?: number;\n}\n\nexport interface TciTxChronoRequest {\n frame: TciStreamFrame;\n receiver: number;\n sampleRate: number;\n channels: number;\n sampleType: TciSampleType;\n sampleCount: number;\n frameCount: number;\n}\n\nexport interface TciClientState {\n connected: boolean;\n ready: boolean;\n protocol?: string;\n protocolName?: string;\n protocolVersion?: string;\n dialectId?: TciDialectId;\n dialectConfidence?: TciHandshakeResult['dialect']['confidence'];\n dialectWarnings: string[];\n device?: string;\n receiveOnly?: boolean;\n trxCount?: number;\n channelCount?: number;\n vfoLimits?: [number, number];\n ifLimits?: [number, number];\n modulations: string[];\n frequencies: Record<string, number>;\n modes: Record<string, string>;\n ptt: Record<string, boolean>;\n pttSource: Record<string, string | undefined>;\n tune: Record<string, boolean>;\n drive: Record<string, number>;\n tuneDrive: Record<string, number>;\n split: Record<string, boolean>;\n rxSensors: Record<string, Record<string, number | string | boolean>>;\n txSensors: Record<string, Record<string, number | string | boolean>>;\n audio?: Required<Pick<TciAudioConfig, 'sampleRate' | 'channels' | 'sampleType' | 'samplesPerFrame'>> & {\n txBufferingMs?: number;\n running: boolean;\n };\n}\n\nexport interface TciClientEvents {\n connected: () => void;\n disconnected: (reason?: unknown) => void;\n ready: (state: TciClientState) => void;\n handshake: (result: TciHandshakeResult) => void;\n state: (state: TciClientState) => void;\n command: (command: TciCommand) => void;\n binary: (frame: TciStreamFrame) => void;\n 'tci:tx': (raw: string) => void;\n 'tci:rx': (raw: string, commands: TciCommand[]) => void;\n 'tci:binary': (frame: TciStreamFrame) => void;\n rxAudioFrame: (frame: TciStreamFrame) => void;\n lineoutAudioFrame: (frame: TciStreamFrame) => void;\n txChrono: (request: TciTxChronoRequest) => void;\n error: (error: TciError) => void;\n}\n\nexport interface SendCommandOptions extends QueueCommandOptions {\n waitForReply?: boolean;\n}\n\nexport class TciClient extends EventEmitter<TciClientEvents> {\n readonly options: Required<Pick<\n TciClientOptions,\n | 'receiver'\n | 'trx'\n | 'vfo'\n | 'connectTimeoutMs'\n | 'handshakeTimeoutMs'\n | 'commandTimeoutMs'\n | 'writeAckMode'\n | 'writeTimeoutMs'\n | 'writeSettleMs'\n | 'frequencyWriteSettleMs'\n >> &\n Pick<TciClientOptions, 'url'> & { dialect: TciDialectSelection };\n\n private readonly WebSocketImpl: typeof WebSocket;\n private readonly transportFactory: TciTransportFactory;\n private transport?: TciTransport;\n private readonly queue: TciCommandQueue;\n private readonly state: TciClientState;\n private readonly stateReducers: Map<string, (args: string[]) => void>;\n private readonly dialectRegistry: TciDialectRegistry;\n private activeDialect?: TciDialect;\n private handshakeResult?: TciHandshakeResult;\n private handshakeError?: TciError;\n private initializationCommands: TciCommand[] = [];\n private handshakeWaiter?: {\n resolve: (result: TciHandshakeResult) => void;\n reject: (error: TciError) => void;\n timer: NodeJS.Timeout;\n };\n\n constructor(options: TciClientOptions) {\n super();\n this.options = {\n url: options.url,\n receiver: options.receiver ?? 0,\n trx: options.trx ?? 0,\n vfo: options.vfo ?? 0,\n connectTimeoutMs: options.connectTimeoutMs ?? 5_000,\n handshakeTimeoutMs: options.handshakeTimeoutMs ?? 10_000,\n commandTimeoutMs: options.commandTimeoutMs ?? 1_000,\n writeAckMode: options.writeAckMode ?? 'state',\n writeTimeoutMs: options.writeTimeoutMs ?? 3_000,\n writeSettleMs: options.writeSettleMs ?? 0,\n frequencyWriteSettleMs: options.frequencyWriteSettleMs ?? 250,\n dialect: options.dialect ?? 'auto',\n };\n this.dialectRegistry = options.dialectRegistry ?? defaultTciDialectRegistry;\n this.WebSocketImpl = options.WebSocketImpl ?? WebSocket;\n this.transportFactory = options.transportFactory\n ?? ((url) => new WebSocketTciTransport(url, this.WebSocketImpl));\n this.queue = new TciCommandQueue({\n timeoutMs: this.options.commandTimeoutMs,\n send: (raw) => this.sendRaw(raw),\n });\n this.queue.setConnected(false);\n this.state = {\n connected: false,\n ready: false,\n modulations: [],\n frequencies: {},\n modes: {},\n ptt: {},\n pttSource: {},\n tune: {},\n drive: {},\n tuneDrive: {},\n split: {},\n dialectWarnings: [],\n rxSensors: {},\n txSensors: {},\n };\n this.stateReducers = this.createStateReducers();\n }\n\n async connect(): Promise<TciHandshakeResult> {\n if (this.transport?.isConnected()) {\n return this.handshakeResult ?? this.waitForHandshake();\n }\n this.resetHandshake();\n const transport = this.transportFactory(this.options.url);\n this.transport = transport;\n this.attachTransport(transport);\n await transport.connect(this.options.connectTimeoutMs);\n this.state.connected = true;\n this.queue.setConnected(true);\n this.emit('connected');\n this.emitState();\n try {\n return await this.waitForHandshake();\n } catch (error) {\n transport.terminate();\n throw error;\n }\n }\n\n async disconnect(code = 1000, reason = 'client disconnect'): Promise<void> {\n const transport = this.transport;\n if (!transport) return;\n await transport.disconnect(code, reason);\n this.handleClose();\n }\n\n isConnected(): boolean {\n return this.transport?.isConnected() ?? false;\n }\n\n getState(): TciClientState {\n return cloneState(this.state);\n }\n\n getHandshakeResult(): TciHandshakeResult | undefined {\n return this.handshakeResult ? cloneHandshake(this.handshakeResult) : undefined;\n }\n\n async sendCommand(name: string, args: readonly unknown[] = [], options: SendCommandOptions = {}): Promise<TciCommand | undefined> {\n const raw = formatTciCommand(name, args);\n if (options.waitForReply === false) {\n await this.sendRaw(raw);\n return undefined;\n }\n const result = await this.queue.enqueue(raw, options);\n return result.reply;\n }\n\n async request(name: string, args: readonly unknown[] = [], options: QueueCommandOptions = {}): Promise<TciCommand> {\n const reply = await this.sendCommand(name, args, { ...options, waitForReply: true });\n if (!reply) {\n throw new TciError('protocol-error', `No reply for ${name}`);\n }\n return reply;\n }\n\n async sendStateWrite(\n name: string,\n args: readonly unknown[],\n isApplied: (state: TciClientState) => boolean,\n description = formatTciCommand(name, args).replace(/;$/, ''),\n options: TciWriteOptions = {},\n ): Promise<void> {\n const ackMode = options.ackMode ?? this.options.writeAckMode;\n if (ackMode === 'reply') {\n await this.sendCommand(name, args, { timeoutMs: options.timeoutMs });\n return;\n }\n\n if (isApplied(this.getState())) {\n return;\n }\n\n if (ackMode === 'optimistic') {\n await this.sendCommand(name, args, { waitForReply: false });\n return;\n }\n\n const timeoutMs = options.timeoutMs ?? this.options.writeTimeoutMs;\n const settleMs = options.settleMs ?? this.options.writeSettleMs;\n const waiter = this.waitForState(isApplied, timeoutMs, settleMs, description);\n try {\n await this.sendCommand(name, args, { waitForReply: false });\n await waiter.promise;\n } catch (error) {\n waiter.cancel();\n throw error;\n }\n }\n\n async setFrequency(\n frequencyHz: number,\n receiver = this.options.receiver,\n vfo = this.options.vfo,\n options: TciWriteOptions = {},\n ): Promise<void> {\n const frequency = Math.round(frequencyHz);\n const key = rxVfoKey(receiver, vfo);\n await this.sendStateWrite(\n 'VFO',\n [receiver, vfo, frequency],\n (state) => state.frequencies[key] === frequency,\n `VFO:${receiver},${vfo},${frequency}`,\n { settleMs: this.options.frequencyWriteSettleMs, ...options },\n );\n }\n\n async getFrequency(receiver = this.options.receiver, vfo = this.options.vfo): Promise<number | undefined> {\n const reply = await this.request('VFO', [receiver, vfo]);\n return parseNumber(reply.args[2]) ?? this.state.frequencies[rxVfoKey(receiver, vfo)];\n }\n\n async setMode(mode: string, receiver = this.options.receiver, options: TciWriteOptions = {}): Promise<void> {\n const normalizedMode = mode.toUpperCase();\n const key = rxVfoKey(receiver, this.options.vfo);\n await this.sendStateWrite(\n 'MODULATION',\n [receiver, normalizedMode],\n (state) => state.modes[key]?.toLowerCase() === normalizedMode.toLowerCase(),\n `MODULATION:${receiver},${normalizedMode}`,\n options,\n );\n }\n\n async getMode(receiver = this.options.receiver): Promise<string | undefined> {\n const reply = await this.request('MODULATION', [receiver]);\n const mode = reply.args.length >= 3 ? reply.args[2] : reply.args[1];\n return (mode ?? this.state.modes[rxVfoKey(receiver, this.options.vfo)])?.toLowerCase();\n }\n\n async setPtt(enabled: boolean, options: TciPttOptions = {}): Promise<void> {\n const trx = options.trx ?? this.options.trx;\n if (options.source && !this.requireDialect().supportsTxAudioSource) {\n throw new TciError('protocol-error', `TCI dialect ${this.requireDialect().id} does not support a TRX audio source argument`);\n }\n const args = options.source ? [trx, enabled, options.source] : [trx, enabled];\n await this.sendStateWrite(\n 'TRX',\n args,\n (state) => state.ptt[String(trx)] === enabled,\n `TRX:${trx},${enabled}`,\n options,\n );\n }\n\n async getPtt(trx = this.options.trx): Promise<boolean | undefined> {\n const reply = await this.request('TRX', [trx]);\n return parseBoolean(reply.args[1]) ?? this.state.ptt[String(trx)];\n }\n\n async setTune(enabled: boolean, trx = this.options.trx, options: TciWriteOptions = {}): Promise<void> {\n try {\n await this.sendStateWrite(\n 'TUNE',\n [trx, enabled],\n (state) => state.tune[String(trx)] === enabled,\n `TUNE:${trx},${enabled}`,\n options,\n );\n } catch (error) {\n if (!(error instanceof TciError) || error.code !== 'command-timeout') throw error;\n await this.request('TUNE', [trx], { timeoutMs: options.timeoutMs });\n if (this.state.tune[String(trx)] !== enabled) throw error;\n }\n }\n\n async setDrive(value: number, trx = this.options.trx): Promise<void> {\n await this.setDriveWithResult(value, trx);\n }\n\n async setDriveWithResult(value: number, trx = this.options.trx, options: TciWriteOptions = {}): Promise<TciWriteResult<number>> {\n const requested = normalizePercent(value);\n const dialect = this.requireDialect();\n if (this.state.drive[String(trx)] === requested) {\n return writeResult(requested, requested, 'state');\n }\n\n const timeoutMs = options.timeoutMs ?? this.options.writeTimeoutMs;\n const waiter = this.waitForCommand(\n (command) => command.name === 'drive' && dialect.parseDrive(command.args, trx)?.trx === trx,\n Math.min(500, timeoutMs),\n `DRIVE state for TRX ${trx}`,\n );\n await this.sendCommand('DRIVE', dialect.buildDriveSetArgs(trx, requested), { waitForReply: false });\n try {\n const command = await waiter.promise;\n const applied = dialect.parseDrive(command.args, trx)?.value;\n if (applied !== undefined) return writeResult(requested, applied, 'state');\n } catch (error) {\n if (!(error instanceof TciError) || error.code !== 'command-timeout') throw error;\n } finally {\n waiter.cancel();\n }\n\n const reply = await this.request('DRIVE', dialect.buildDriveReadArgs(trx), {\n timeoutMs: Math.max(1, timeoutMs - Math.min(500, timeoutMs)),\n });\n const applied = dialect.parseDrive(reply.args, trx)?.value;\n if (applied === undefined) throw new TciError('protocol-error', `Invalid DRIVE readback: ${reply.raw}`);\n return writeResult(requested, applied, 'readback');\n }\n\n async getDrive(trx = this.options.trx): Promise<number | undefined> {\n const dialect = this.requireDialect();\n const reply = await this.request('DRIVE', dialect.buildDriveReadArgs(trx));\n return dialect.parseDrive(reply.args, trx)?.value ?? this.state.drive[String(trx)];\n }\n\n async setTuneDrive(value: number, trx = this.options.trx, options: TciWriteOptions = {}): Promise<TciWriteResult<number>> {\n const requested = normalizePercent(value);\n const dialect = this.requireDialect();\n if (this.state.tuneDrive[String(trx)] === requested) return writeResult(requested, requested, 'state');\n const timeoutMs = options.timeoutMs ?? this.options.writeTimeoutMs;\n const waiter = this.waitForCommand(\n (command) => command.name === 'tune_drive' && dialect.parseTuneDrive(command.args, trx)?.trx === trx,\n Math.min(500, timeoutMs),\n `TUNE_DRIVE state for TRX ${trx}`,\n );\n await this.sendCommand('TUNE_DRIVE', dialect.buildTuneDriveSetArgs(trx, requested), { waitForReply: false });\n try {\n const command = await waiter.promise;\n const applied = dialect.parseTuneDrive(command.args, trx)?.value;\n if (applied !== undefined) return writeResult(requested, applied, 'state');\n } catch (error) {\n if (!(error instanceof TciError) || error.code !== 'command-timeout') throw error;\n } finally {\n waiter.cancel();\n }\n const reply = await this.request('TUNE_DRIVE', dialect.buildTuneDriveReadArgs(trx), {\n timeoutMs: Math.max(1, timeoutMs - Math.min(500, timeoutMs)),\n });\n const applied = dialect.parseTuneDrive(reply.args, trx)?.value;\n if (applied === undefined) throw new TciError('protocol-error', `Invalid TUNE_DRIVE readback: ${reply.raw}`);\n return writeResult(requested, applied, 'readback');\n }\n\n async getTuneDrive(trx = this.options.trx): Promise<number | undefined> {\n const dialect = this.requireDialect();\n const reply = await this.request('TUNE_DRIVE', dialect.buildTuneDriveReadArgs(trx));\n return dialect.parseTuneDrive(reply.args, trx)?.value ?? this.state.tuneDrive[String(trx)];\n }\n\n async setSplit(enabled: boolean, trx = this.options.trx, options: TciWriteOptions = {}): Promise<void> {\n try {\n await this.sendStateWrite(\n 'SPLIT_ENABLE',\n [trx, enabled],\n (state) => state.split[String(trx)] === enabled,\n `SPLIT_ENABLE:${trx},${enabled}`,\n options,\n );\n } catch (error) {\n if (!(error instanceof TciError) || error.code !== 'command-timeout') throw error;\n await this.request('SPLIT_ENABLE', [trx], { timeoutMs: options.timeoutMs });\n if (this.state.split[String(trx)] !== enabled) throw error;\n }\n }\n\n async configureAudio(config: TciAudioConfig): Promise<void> {\n const dialect = this.requireDialect();\n const audio = {\n sampleRate: config.sampleRate,\n sampleType: normalizeSampleType(config.sampleType ?? TciSampleType.FLOAT32),\n channels: config.channels ?? 1,\n samplesPerFrame: config.samplesPerFrame ?? 512,\n txBufferingMs: config.txBufferingMs,\n running: this.state.audio?.running ?? false,\n };\n this.state.audio = audio;\n\n await this.sendCommand('AUDIO_SAMPLERATE', [audio.sampleRate], { waitForReply: false });\n if (dialect.supportsStreamChannels) {\n await this.sendCommand('AUDIO_STREAM_SAMPLE_TYPE', [sampleTypeName(audio.sampleType)], { waitForReply: false });\n await this.sendCommand('AUDIO_STREAM_CHANNELS', [audio.channels], { waitForReply: false });\n await this.sendCommand('AUDIO_STREAM_SAMPLES', [audio.samplesPerFrame], { waitForReply: false });\n if (audio.txBufferingMs !== undefined) {\n await this.sendCommand('TX_STREAM_AUDIO_BUFFERING', [audio.txBufferingMs], { waitForReply: false });\n }\n }\n this.emitState();\n }\n\n async startAudio(receiver = this.options.receiver): Promise<void> {\n await this.sendCommand('AUDIO_START', [receiver], { waitForReply: false });\n if (this.state.audio) {\n this.state.audio.running = true;\n this.emitState();\n }\n }\n\n async stopAudio(receiver = this.options.receiver): Promise<void> {\n await this.sendCommand('AUDIO_STOP', [receiver], { waitForReply: false });\n if (this.state.audio) {\n this.state.audio.running = false;\n this.emitState();\n }\n }\n\n sendTxAudio(options: BuildTxAudioFrameOptions): void {\n const frame = buildTxAudioFrame({\n receiver: this.options.receiver,\n lengthSemantics: this.requireDialect().streamLengthSemantics,\n ...options,\n });\n this.sendRawBinary(frame);\n }\n\n sendTxAudioForChrono(request: TciTxChronoRequest, samples: Float32Array | readonly number[]): void {\n const channels = Math.max(1, Math.floor(request.channels || 1));\n const targetSampleLength = Math.max(0, Math.floor(request.sampleCount));\n const output = new Float32Array(targetSampleLength);\n const source = samples instanceof Float32Array ? samples : Float32Array.from(samples);\n output.set(source.subarray(0, output.length));\n this.sendTxAudio({\n receiver: request.receiver,\n sampleRate: request.sampleRate,\n sampleType: request.sampleType,\n channels,\n samples: output,\n });\n }\n\n async setRxSensorsEnabled(enabled: boolean, intervalMs?: number): Promise<void> {\n const args = intervalMs === undefined ? [enabled] : [enabled, intervalMs];\n await this.sendCommand('RX_SENSORS_ENABLE', args, { waitForReply: false });\n }\n\n async setTxSensorsEnabled(enabled: boolean, intervalMs?: number): Promise<void> {\n const args = intervalMs === undefined ? [enabled] : [enabled, intervalMs];\n await this.sendCommand('TX_SENSORS_ENABLE', args, { waitForReply: false });\n }\n\n async sendCwMacro(index: number): Promise<void> {\n await this.sendCommand('CW_MACROS', [index]);\n }\n\n async sendCwMessage(message: string): Promise<void> {\n await this.sendCommand('CW_MSG', [message]);\n }\n\n async stopCw(): Promise<void> {\n await this.sendCommand('CW_MACROS_STOP');\n }\n\n private waitForState(\n predicate: (state: TciClientState) => boolean,\n timeoutMs: number,\n settleMs: number,\n description: string,\n ): { promise: Promise<void>; cancel: () => void } {\n let timeout: NodeJS.Timeout | undefined;\n let settleTimeout: NodeJS.Timeout | undefined;\n let resolved = false;\n let resolvePromise!: () => void;\n let rejectPromise!: (error: TciError) => void;\n\n const cleanup = () => {\n if (timeout) {\n clearTimeout(timeout);\n timeout = undefined;\n }\n if (settleTimeout) {\n clearTimeout(settleTimeout);\n settleTimeout = undefined;\n }\n this.off('state', onState);\n this.off('disconnected', onDisconnected);\n };\n\n const resolveNow = () => {\n resolved = true;\n cleanup();\n resolvePromise();\n };\n\n const check = () => {\n if (!predicate(this.getState())) {\n if (settleTimeout) {\n clearTimeout(settleTimeout);\n settleTimeout = undefined;\n }\n return;\n }\n\n if (settleMs <= 0) {\n resolveNow();\n return;\n }\n\n if (settleTimeout) {\n return;\n }\n\n settleTimeout = setTimeout(() => {\n settleTimeout = undefined;\n if (predicate(this.getState())) {\n resolveNow();\n }\n }, settleMs);\n };\n\n const onState = () => check();\n const onDisconnected = () => {\n if (resolved) {\n return;\n }\n cleanup();\n rejectPromise(new TciError('disconnected', `Disconnected while waiting for TCI state ${description}`));\n };\n\n const promise = new Promise<void>((resolve, reject) => {\n resolvePromise = resolve;\n rejectPromise = reject;\n timeout = setTimeout(() => {\n cleanup();\n reject(new TciError('command-timeout', `Timed out waiting for TCI state ${description}`));\n }, timeoutMs);\n this.on('state', onState);\n this.on('disconnected', onDisconnected);\n check();\n });\n\n return {\n promise,\n cancel: cleanup,\n };\n }\n\n private waitForCommand(\n predicate: (command: TciCommand) => boolean,\n timeoutMs: number,\n description: string,\n ): { promise: Promise<TciCommand>; cancel: () => void } {\n let timer: NodeJS.Timeout | undefined;\n let resolvePromise!: (command: TciCommand) => void;\n let rejectPromise!: (error: TciError) => void;\n const cleanup = () => {\n if (timer) clearTimeout(timer);\n timer = undefined;\n this.off('command', onCommand);\n this.off('disconnected', onDisconnected);\n };\n const onCommand = (command: TciCommand) => {\n if (!predicate(command)) return;\n cleanup();\n resolvePromise(command);\n };\n const onDisconnected = () => {\n cleanup();\n rejectPromise(new TciError('disconnected', `Disconnected while waiting for ${description}`));\n };\n const promise = new Promise<TciCommand>((resolve, reject) => {\n resolvePromise = resolve;\n rejectPromise = reject;\n timer = setTimeout(() => {\n cleanup();\n reject(new TciError('command-timeout', `Timed out waiting for ${description}`));\n }, timeoutMs);\n this.on('command', onCommand);\n this.on('disconnected', onDisconnected);\n });\n return { promise, cancel: cleanup };\n }\n\n private resetHandshake(): void {\n this.rejectHandshake(new TciError('cancelled', 'TCI handshake replaced by a new connection'));\n this.handshakeResult = undefined;\n this.handshakeError = undefined;\n this.activeDialect = undefined;\n this.initializationCommands = [];\n this.state.ready = false;\n this.state.protocol = undefined;\n this.state.protocolName = undefined;\n this.state.protocolVersion = undefined;\n this.state.dialectId = undefined;\n this.state.dialectConfidence = undefined;\n this.state.dialectWarnings = [];\n }\n\n private waitForHandshake(): Promise<TciHandshakeResult> {\n if (this.handshakeResult) return Promise.resolve(cloneHandshake(this.handshakeResult));\n if (this.handshakeError) return Promise.reject(this.handshakeError);\n if (this.handshakeWaiter) {\n return new Promise((resolve, reject) => {\n const onHandshake = (result: TciHandshakeResult) => { cleanup(); resolve(result); };\n const onError = (error: TciError) => { cleanup(); reject(error); };\n const cleanup = () => { this.off('handshake', onHandshake); this.off('error', onError); };\n this.once('handshake', onHandshake);\n this.once('error', onError);\n });\n }\n return new Promise<TciHandshakeResult>((resolve, reject) => {\n const timer = setTimeout(() => {\n const error = new TciError('handshake-timeout', `Timed out waiting for TCI READY from ${this.options.url}`);\n this.handshakeWaiter = undefined;\n reject(error);\n }, this.options.handshakeTimeoutMs);\n this.handshakeWaiter = { resolve, reject, timer };\n });\n }\n\n private finalizeHandshake(): TciHandshakeResult {\n if (this.handshakeResult) return this.handshakeResult;\n assertValidTciHandshake(this.initializationCommands);\n const identity = parseProtocolIdentity(this.initializationCommands);\n const commandNames = [...new Set(this.initializationCommands.map((command) => command.name))];\n const dialect = this.dialectRegistry.select(\n { identity, commands: this.initializationCommands, commandNames: new Set(commandNames) },\n this.options.dialect,\n );\n const result: TciHandshakeResult = { identity, dialect, ready: true, commandNames };\n this.handshakeResult = result;\n this.activeDialect = dialect.dialect;\n this.state.protocolName = identity.programName;\n this.state.protocolVersion = identity.protocolVersion;\n this.state.protocol = identity.protocolVersion ?? identity.programName;\n this.state.device = identity.device ?? this.state.device;\n this.state.dialectId = dialect.dialect.id;\n this.state.dialectConfidence = dialect.confidence;\n this.state.dialectWarnings = [...dialect.warnings];\n const waiter = this.handshakeWaiter;\n this.handshakeWaiter = undefined;\n if (waiter) {\n clearTimeout(waiter.timer);\n waiter.resolve(cloneHandshake(result));\n }\n this.emit('handshake', cloneHandshake(result));\n return result;\n }\n\n private rejectHandshake(error: TciError): void {\n const waiter = this.handshakeWaiter;\n this.handshakeWaiter = undefined;\n if (!waiter) return;\n clearTimeout(waiter.timer);\n waiter.reject(error);\n }\n\n private requireDialect(): TciDialect {\n if (!this.activeDialect) throw new TciError('invalid-handshake', 'TCI dialect is not available before READY');\n return this.activeDialect;\n }\n\n private attachTransport(transport: TciTransport): void {\n transport.on('text', (raw) => this.handleText(raw));\n transport.on('binary', (raw) => this.handleBinary(raw));\n transport.on('disconnected', (reason) => this.handleClose(reason));\n transport.on('error', (error) => this.handleError(error));\n }\n\n private async sendRaw(raw: string): Promise<void> {\n const transport = this.transport;\n if (!transport?.isConnected()) {\n throw new TciError('not-connected', 'TCI socket is not connected');\n }\n this.emit('tci:tx', raw);\n await transport.sendText(raw);\n }\n\n private sendRawBinary(raw: Buffer): void {\n const transport = this.transport;\n if (!transport?.isConnected()) {\n throw new TciError('not-connected', 'TCI socket is not connected');\n }\n void transport.sendBinary(raw).catch((error) => this.handleError(error));\n }\n\n private handleText(raw: string): void {\n try {\n const commands = parseTciText(raw);\n this.emit('tci:rx', raw, commands);\n for (const command of commands) {\n if (!this.handshakeResult) this.initializationCommands.push(command);\n this.queue.handleCommand(command);\n this.applyCommand(command);\n this.emit('command', command);\n }\n } catch (error) {\n this.handleError(error);\n }\n }\n\n private handleBinary(data: Buffer): void {\n const frame = parseStreamFrame(data, {\n lengthSemantics: this.requireDialect().streamLengthSemantics,\n negotiatedChannels: this.state.audio?.channels,\n });\n this.emit('tci:binary', frame);\n this.emit('binary', frame);\n switch (frame.streamType) {\n case TciStreamType.RX_AUDIO_STREAM:\n this.emit('rxAudioFrame', frame);\n break;\n case TciStreamType.TX_CHRONO:\n this.emit('txChrono', {\n frame,\n receiver: frame.receiver,\n sampleRate: frame.sampleRate,\n channels: frame.channels,\n sampleType: frame.sampleType,\n sampleCount: frame.sampleCount,\n frameCount: frame.frameCount,\n });\n break;\n case TciStreamType.LINEOUT_STREAM:\n this.emit('lineoutAudioFrame', frame);\n break;\n default:\n break;\n }\n }\n\n private applyCommand(command: TciCommand): void {\n const readyBefore = this.state.ready;\n this.stateReducers.get(command.name)?.(command.args);\n\n if (!readyBefore && this.state.ready) {\n try {\n this.finalizeHandshake();\n this.emit('ready', this.getState());\n } catch (error) {\n const tciError = toTciError(error, 'invalid-handshake');\n this.handshakeError = tciError;\n this.state.ready = false;\n this.rejectHandshake(tciError);\n this.handleError(tciError);\n }\n }\n this.emitState();\n }\n\n private createStateReducers(): Map<string, (args: string[]) => void> {\n const reducers = new Map<string, (args: string[]) => void>();\n reducers.set('ready', (args) => {\n this.state.ready = args.length === 0 ? true : (parseBoolean(args[0]) ?? true);\n });\n reducers.set('protocol', (args) => {\n if (/^\\d+(?:\\.\\d+){0,2}/.test(args[0] ?? '')) {\n this.state.protocol = args[0];\n this.state.protocolVersion = args[0];\n } else {\n this.state.protocolName = args[0];\n this.state.protocolVersion = args[1];\n this.state.protocol = args[1] ?? args[0];\n }\n });\n reducers.set('device', (args) => { this.state.device = args.join(','); });\n reducers.set('receive_only', (args) => { this.state.receiveOnly = parseBoolean(args[0]); });\n reducers.set('trx_count', (args) => { this.state.trxCount = parseNumber(args[0]); });\n const channelCount = (args: string[]) => { this.state.channelCount = parseNumber(args[0]); };\n reducers.set('channels_count', channelCount);\n reducers.set('channel_count', channelCount);\n reducers.set('vfo_limits', (args) => { this.state.vfoLimits = parseNumberPair(args); });\n reducers.set('if_limits', (args) => { this.state.ifLimits = parseNumberPair(args); });\n reducers.set('modulations_list', (args) => { this.state.modulations = args.map((mode) => mode.toLowerCase()); });\n reducers.set('vfo', (args) => this.applyVfo(args));\n reducers.set('modulation', (args) => this.applyModulation(args));\n reducers.set('trx', (args) => this.applyTrx(args));\n reducers.set('tune', (args) => this.applyBooleanByFirstArg(this.state.tune, args));\n reducers.set('drive', (args) => this.applyDrive(args));\n reducers.set('tune_drive', (args) => this.applyTuneDrive(args));\n reducers.set('split_enable', (args) => this.applyBooleanByFirstArg(this.state.split, args));\n reducers.set('rx_channel_sensors', (args) => this.applyRxChannelSensors(args));\n reducers.set('rx_sensors', (args) => this.applyRxSensors(args));\n reducers.set('tx_sensors', (args) => this.applyTxSensors(args));\n reducers.set('audio_samplerate', (args) => this.updateAudioState({ sampleRate: parseNumber(args[0]) }));\n reducers.set('audio_stream_sample_type', (args) => this.updateAudioState({ sampleType: parseSampleType(args[0]) }));\n reducers.set('audio_stream_channels', (args) => this.updateAudioState({ channels: parseNumber(args[0]) }));\n reducers.set('audio_stream_samples', (args) => this.updateAudioState({ samplesPerFrame: parseNumber(args[0]) }));\n reducers.set('tx_stream_audio_buffering', (args) => this.updateAudioState({ txBufferingMs: parseNumber(args[0]) }));\n reducers.set('audio_start', () => this.updateAudioState({ running: true }));\n reducers.set('audio_stop', () => this.updateAudioState({ running: false }));\n return reducers;\n }\n\n private applyVfo(args: string[]): void {\n if (args.length < 3) {\n return;\n }\n const receiver = parseNumber(args[0]);\n const vfo = parseNumber(args[1]);\n const frequency = parseNumber(args[2]);\n if (receiver === undefined || vfo === undefined || frequency === undefined || frequency < 0) {\n return;\n }\n this.state.frequencies[rxVfoKey(receiver, vfo)] = frequency;\n }\n\n private applyModulation(args: string[]): void {\n if (args.length < 2) {\n return;\n }\n const receiver = parseNumber(args[0]);\n if (receiver === undefined) {\n return;\n }\n const vfo = args.length >= 3 ? parseNumber(args[1]) ?? this.options.vfo : this.options.vfo;\n const mode = args.length >= 3 ? args[2] : args[1];\n if (!mode) {\n return;\n }\n this.state.modes[rxVfoKey(receiver, vfo)] = mode.toLowerCase();\n }\n\n private applyTrx(args: string[]): void {\n if (args.length < 2) {\n return;\n }\n const trx = args[0] ?? String(this.options.trx);\n this.state.ptt[trx] = parseBoolean(args[1]) ?? false;\n this.state.pttSource[trx] = args[2]?.toLowerCase();\n }\n\n private applyBooleanByFirstArg(target: Record<string, boolean>, args: string[]): void {\n if (args.length < 2) {\n return;\n }\n const key = args[0] ?? '0';\n const value = parseBoolean(args[1]);\n if (value !== undefined) {\n target[key] = value;\n }\n }\n\n private applyDrive(args: string[]): void {\n const parsed = this.activeDialect?.parseDrive(args, this.options.trx)\n ?? parseObservedDrive(args, this.options.trx);\n if (parsed) this.state.drive[String(parsed.trx)] = parsed.value;\n }\n\n private applyTuneDrive(args: string[]): void {\n const parsed = this.activeDialect?.parseTuneDrive(args, this.options.trx)\n ?? parseObservedDrive(args, this.options.trx);\n if (parsed) this.state.tuneDrive[String(parsed.trx)] = parsed.value;\n }\n\n private updateAudioState(update: Partial<NonNullable<TciClientState['audio']>>): void {\n this.state.audio = {\n sampleRate: update.sampleRate ?? this.state.audio?.sampleRate ?? 12_000,\n sampleType: update.sampleType ?? this.state.audio?.sampleType ?? TciSampleType.FLOAT32,\n channels: update.channels ?? this.state.audio?.channels ?? 1,\n samplesPerFrame: update.samplesPerFrame ?? this.state.audio?.samplesPerFrame ?? 512,\n txBufferingMs: update.txBufferingMs ?? this.state.audio?.txBufferingMs,\n running: update.running ?? this.state.audio?.running ?? false,\n };\n }\n\n private applyRxChannelSensors(args: string[]): void {\n if (args.length < 3) {\n return;\n }\n const key = rxVfoKey(args[0], args[1]);\n this.state.rxSensors[key] = {\n receiver: args[0],\n channel: args[1],\n levelDbm: parseNumber(args[2]) ?? args[2],\n };\n }\n\n private applyRxSensors(args: string[]): void {\n if (args.length < 2) {\n return;\n }\n this.state.rxSensors[String(args[0])] = {\n receiver: args[0],\n levelDbm: parseNumber(args[1]) ?? args[1],\n deprecated: true,\n };\n }\n\n private applyTxSensors(args: string[]): void {\n if (args.length < 2) {\n return;\n }\n this.state.txSensors[String(args[0])] = {\n trx: args[0],\n micDbm: parseNumber(args[1]) ?? args[1],\n rmsPowerW: parseNumber(args[2]) ?? args[2],\n peakPowerW: parseNumber(args[3]) ?? args[3],\n swr: parseNumber(args[4]) ?? args[4],\n };\n }\n\n private handleClose(reason?: unknown): void {\n const transport = this.transport;\n this.transport = undefined;\n transport?.removeAllListeners();\n const wasConnected = this.state.connected;\n this.state.connected = false;\n this.state.ready = false;\n this.queue.setConnected(false);\n this.rejectHandshake(new TciError('disconnected', 'TCI connection closed during handshake', reason));\n if (wasConnected) {\n this.emit('disconnected', reason);\n this.emitState();\n }\n }\n\n private handleError(error: unknown): void {\n const tciError = toTciError(error);\n this.emit('error', tciError);\n }\n\n private emitState(): void {\n this.emit('state', this.getState());\n }\n}\n\nexport function createTciClient(options: TciClientOptions): TciClient {\n return new TciClient(options);\n}\n\nfunction rxVfoKey(receiver: string | number, vfo: string | number): string {\n return `${receiver}:${vfo}`;\n}\n\nfunction parseNumber(value: string | undefined): number | undefined {\n if (value === undefined || value === '') {\n return undefined;\n }\n const number = Number(value);\n return Number.isFinite(number) ? number : undefined;\n}\n\nfunction parseBoolean(value: string | undefined): boolean | undefined {\n if (value === undefined) {\n return undefined;\n }\n const normalized = value.toLowerCase();\n if (normalized === 'true' || normalized === '1' || normalized === 'on') {\n return true;\n }\n if (normalized === 'false' || normalized === '0' || normalized === 'off') {\n return false;\n }\n return undefined;\n}\n\nfunction parseSampleType(value: string | undefined): TciSampleType | undefined {\n if (!value) return undefined;\n try { return normalizeSampleType(value.toLowerCase() as TciSampleTypeName); } catch { return undefined; }\n}\n\nfunction parseObservedDrive(args: readonly string[], defaultTrx: number): { trx: number; value: number } | undefined {\n const hasTrx = args.length >= 2;\n const trx = hasTrx ? parseNumber(args[0]) : defaultTrx;\n const value = parseNumber(args[hasTrx ? 1 : 0]);\n return trx === undefined || value === undefined ? undefined : { trx, value };\n}\n\nfunction normalizePercent(value: number): number {\n if (!Number.isFinite(value)) throw new TciError('protocol-error', `Invalid TCI percentage: ${value}`);\n return Math.round(Math.max(0, Math.min(100, value)));\n}\n\nfunction writeResult(\n requested: number,\n applied: number,\n acknowledgement: TciWriteResult<number>['acknowledgement'],\n): TciWriteResult<number> {\n return { requested, applied, outcome: requested === applied ? 'applied' : 'clamped', acknowledgement };\n}\n\nfunction parseNumberPair(args: string[]): [number, number] | undefined {\n const first = parseNumber(args[0]);\n const second = parseNumber(args[1]);\n return first === undefined || second === undefined ? undefined : [first, second];\n}\n\nfunction cloneState(state: TciClientState): TciClientState {\n return {\n ...state,\n modulations: [...state.modulations],\n frequencies: { ...state.frequencies },\n modes: { ...state.modes },\n ptt: { ...state.ptt },\n pttSource: { ...state.pttSource },\n tune: { ...state.tune },\n drive: { ...state.drive },\n tuneDrive: { ...state.tuneDrive },\n split: { ...state.split },\n dialectWarnings: [...state.dialectWarnings],\n rxSensors: cloneNested(state.rxSensors),\n txSensors: cloneNested(state.txSensors),\n audio: state.audio ? { ...state.audio } : undefined,\n };\n}\n\nfunction cloneHandshake(result: TciHandshakeResult): TciHandshakeResult {\n return {\n identity: { ...result.identity, rawProtocolArgs: [...result.identity.rawProtocolArgs] },\n dialect: {\n ...result.dialect,\n evidence: [...result.dialect.evidence],\n warnings: [...result.dialect.warnings],\n },\n ready: true,\n commandNames: [...result.commandNames],\n };\n}\n\nfunction cloneNested<T>(value: Record<string, T>): Record<string, T> {\n return Object.fromEntries(Object.entries(value).map(([key, item]) => [key, { ...(item as Record<string, unknown>) } as T]));\n}\n","import { TciError } from '../errors.js';\nimport type { TciStreamLengthSemantics } from '../dialect/types.js';\n\nexport const TCI_STREAM_HEADER_BYTES = 16 * 4;\n\nexport enum TciStreamType {\n IQ_STREAM = 0,\n RX_AUDIO_STREAM = 1,\n TX_AUDIO_STREAM = 2,\n TX_CHRONO = 3,\n LINEOUT_STREAM = 4,\n}\n\nexport enum TciSampleType {\n INT16 = 0,\n INT24 = 1,\n INT32 = 2,\n FLOAT32 = 3,\n}\n\nexport type TciSampleTypeName = 'int16' | 'int24' | 'int32' | 'float32';\n\nexport interface TciStreamFrame {\n receiver: number;\n sampleRate: number;\n sampleType: TciSampleType;\n codec: number;\n crc: number;\n /** Byte length of the payload following the 64-byte TCI stream header. */\n payloadLength: number;\n streamType: TciStreamType;\n channels: number;\n reserved: number[];\n payload: Buffer;\n /** Raw Stream.length value from the wire header. */\n headerSampleCount: number;\n /** Canonical number of scalar sample values across all channels. */\n sampleCount: number;\n /** Number of sample frames, each containing `channels` scalar values. */\n frameCount: number;\n lengthSemantics: Exclude<TciStreamLengthSemantics, 'auto'>;\n}\n\nexport interface ParseStreamFrameOptions {\n lengthSemantics?: TciStreamLengthSemantics;\n negotiatedChannels?: number;\n}\n\nexport interface BuildStreamFrameOptions {\n receiver?: number;\n sampleRate: number;\n sampleType: TciSampleType | TciSampleTypeName;\n streamType: TciStreamType;\n channels: number;\n payload?: Buffer | Uint8Array | ArrayBuffer | ArrayBufferView;\n samples?: Float32Array | readonly number[];\n /** Explicit Stream.length value, used for header-only frames such as TX_CHRONO. */\n sampleCount?: number;\n lengthSemantics?: TciStreamLengthSemantics;\n codec?: number;\n crc?: number;\n reserved?: readonly number[];\n}\n\nexport interface BuildTxAudioFrameOptions extends Omit<BuildStreamFrameOptions, 'streamType'> {\n receiver?: number;\n}\n\nexport function parseStreamFrame(input: Buffer | ArrayBuffer | ArrayBufferView, options: ParseStreamFrameOptions = {}): TciStreamFrame {\n const buffer = toBuffer(input);\n if (buffer.byteLength < TCI_STREAM_HEADER_BYTES) {\n throw new TciError('invalid-frame', `TCI stream frame is shorter than ${TCI_STREAM_HEADER_BYTES} bytes`);\n }\n\n const view = new DataView(buffer.buffer, buffer.byteOffset, buffer.byteLength);\n const header = Array.from({ length: 16 }, (_, index) => view.getUint32(index * 4, true));\n const sampleType = normalizeSampleType(header[2]);\n const streamType = normalizeStreamType(header[6]);\n let channels = header[7] || options.negotiatedChannels || 0;\n const bytesPerSample = sampleTypeBytes(sampleType);\n const headerSampleCount = header[5];\n const actualPayloadLength = buffer.byteLength - TCI_STREAM_HEADER_BYTES;\n if (channels <= 0) {\n if (streamType === TciStreamType.TX_CHRONO && actualPayloadLength === 0) {\n channels = 1;\n } else {\n const inferredChannels = headerSampleCount > 0 ? actualPayloadLength / headerSampleCount / bytesPerSample : 1;\n if (!Number.isInteger(inferredChannels) || inferredChannels <= 0) {\n throw new TciError('invalid-frame', `Invalid TCI channel count: ${channels}`);\n }\n channels = inferredChannels;\n }\n }\n const payloadLength = actualPayloadLength;\n const alignedFrameBytes = bytesPerSample * channels;\n if (payloadLength % alignedFrameBytes !== 0) {\n throw new TciError('invalid-frame', 'TCI payload length is not aligned to sample type and channel count');\n }\n\n const actualScalarCount = payloadLength / bytesPerSample;\n const requestedSemantics = options.lengthSemantics ?? 'auto';\n const lengthSemantics = resolveLengthSemantics(\n requestedSemantics,\n streamType,\n headerSampleCount,\n actualScalarCount,\n channels,\n );\n const sampleCount = lengthSemantics === 'per-channel' ? headerSampleCount * channels : headerSampleCount;\n\n if (streamType !== TciStreamType.TX_CHRONO) {\n const expectedPayloadLength = sampleCount * bytesPerSample;\n if (payloadLength !== expectedPayloadLength) {\n throw new TciError(\n 'invalid-frame',\n `TCI stream frame length mismatch: header says ${headerSampleCount} samples using ${lengthSemantics} semantics (${expectedPayloadLength} payload bytes), got ${payloadLength}`,\n );\n }\n }\n\n if (sampleCount % channels !== 0) {\n throw new TciError('invalid-frame', `TCI scalar sample count ${sampleCount} is not divisible by ${channels} channels`);\n }\n\n return {\n receiver: header[0],\n sampleRate: header[1],\n sampleType,\n codec: header[3],\n crc: header[4],\n payloadLength,\n streamType,\n channels,\n reserved: header.slice(8),\n payload: buffer.subarray(TCI_STREAM_HEADER_BYTES),\n headerSampleCount,\n sampleCount,\n frameCount: sampleCount / channels,\n lengthSemantics,\n };\n}\n\nexport function buildStreamFrame(options: BuildStreamFrameOptions): Buffer {\n const sampleType = normalizeSampleType(options.sampleType);\n const payload = options.payload ? toBuffer(options.payload) : samplesToPayload(options.samples ?? [], sampleType);\n const channels = options.channels;\n if (channels <= 0) {\n throw new TciError('invalid-frame', `Invalid TCI channel count: ${channels}`);\n }\n const bytesPerSample = sampleTypeBytes(sampleType);\n if (payload.byteLength % (bytesPerSample * channels) !== 0) {\n throw new TciError('invalid-frame', 'TCI payload length is not aligned to sample type and channel count');\n }\n const derivedSampleCount = payload.byteLength / bytesPerSample;\n const sampleCount = options.sampleCount ?? derivedSampleCount;\n if (!Number.isInteger(sampleCount) || sampleCount < 0) {\n throw new TciError('invalid-frame', `Invalid TCI sample count: ${sampleCount}`);\n }\n if (payload.byteLength > 0 && sampleCount !== derivedSampleCount) {\n throw new TciError('invalid-frame', `Explicit scalar sample count ${sampleCount} does not match payload count ${derivedSampleCount}`);\n }\n if (sampleCount % channels !== 0) {\n throw new TciError('invalid-frame', `TCI scalar sample count ${sampleCount} is not divisible by ${channels} channels`);\n }\n const lengthSemantics = options.lengthSemantics === 'per-channel' ? 'per-channel' : 'scalar';\n const headerSampleCount = lengthSemantics === 'per-channel' ? sampleCount / channels : sampleCount;\n\n const frame = Buffer.alloc(TCI_STREAM_HEADER_BYTES + payload.byteLength);\n const view = new DataView(frame.buffer, frame.byteOffset, frame.byteLength);\n const reserved = options.reserved ?? [];\n const header = [\n options.receiver ?? 0,\n options.sampleRate,\n sampleType,\n options.codec ?? 0,\n options.crc ?? 0,\n headerSampleCount,\n options.streamType,\n channels,\n ...Array.from({ length: 8 }, (_, index) => reserved[index] ?? 0),\n ];\n header.forEach((value, index) => view.setUint32(index * 4, value >>> 0, true));\n payload.copy(frame, TCI_STREAM_HEADER_BYTES);\n return frame;\n}\n\nfunction resolveLengthSemantics(\n requested: TciStreamLengthSemantics,\n streamType: TciStreamType,\n headerSampleCount: number,\n actualScalarCount: number,\n channels: number,\n): Exclude<TciStreamLengthSemantics, 'auto'> {\n if (requested !== 'auto') return requested;\n if (streamType === TciStreamType.TX_CHRONO && actualScalarCount === 0) return 'scalar';\n if (actualScalarCount === headerSampleCount) return 'scalar';\n if (actualScalarCount === headerSampleCount * channels) return 'per-channel';\n return 'scalar';\n}\n\nexport function buildTxAudioFrame(options: BuildTxAudioFrameOptions): Buffer {\n return buildStreamFrame({ ...options, streamType: TciStreamType.TX_AUDIO_STREAM });\n}\n\nexport function sampleTypeBytes(sampleType: TciSampleType | TciSampleTypeName): number {\n switch (normalizeSampleType(sampleType)) {\n case TciSampleType.INT16:\n return 2;\n case TciSampleType.INT24:\n return 3;\n case TciSampleType.INT32:\n case TciSampleType.FLOAT32:\n return 4;\n default:\n throw new TciError('invalid-frame', `Unsupported TCI sample type: ${sampleType}`);\n }\n}\n\nexport function sampleTypeName(sampleType: TciSampleType): TciSampleTypeName {\n switch (sampleType) {\n case TciSampleType.INT16:\n return 'int16';\n case TciSampleType.INT24:\n return 'int24';\n case TciSampleType.INT32:\n return 'int32';\n case TciSampleType.FLOAT32:\n return 'float32';\n default:\n throw new TciError('invalid-frame', `Unsupported TCI sample type: ${sampleType}`);\n }\n}\n\nexport function normalizeSampleType(sampleType: TciSampleType | TciSampleTypeName | number): TciSampleType {\n if (typeof sampleType === 'string') {\n switch (sampleType.toLowerCase()) {\n case 'int16':\n return TciSampleType.INT16;\n case 'int24':\n return TciSampleType.INT24;\n case 'int32':\n return TciSampleType.INT32;\n case 'float32':\n return TciSampleType.FLOAT32;\n default:\n throw new TciError('invalid-frame', `Unsupported TCI sample type: ${sampleType}`);\n }\n }\n if (sampleType >= TciSampleType.INT16 && sampleType <= TciSampleType.FLOAT32) {\n return sampleType as TciSampleType;\n }\n throw new TciError('invalid-frame', `Unsupported TCI sample type: ${sampleType}`);\n}\n\nexport function normalizeStreamType(streamType: TciStreamType | number): TciStreamType {\n if (streamType >= TciStreamType.IQ_STREAM && streamType <= TciStreamType.LINEOUT_STREAM) {\n return streamType as TciStreamType;\n }\n throw new TciError('invalid-frame', `Unsupported TCI stream type: ${streamType}`);\n}\n\nexport function payloadToFloat32(frameOrPayload: TciStreamFrame | Buffer | Uint8Array, sampleType?: TciSampleType | TciSampleTypeName): Float32Array {\n const payload = isFrame(frameOrPayload) ? frameOrPayload.payload : toBuffer(frameOrPayload);\n const type = isFrame(frameOrPayload) ? frameOrPayload.sampleType : normalizeSampleType(sampleType ?? TciSampleType.FLOAT32);\n const bytes = sampleTypeBytes(type);\n if (payload.byteLength % bytes !== 0) {\n throw new TciError('invalid-frame', 'Payload length is not aligned to sample type');\n }\n\n const output = new Float32Array(payload.byteLength / bytes);\n const view = new DataView(payload.buffer, payload.byteOffset, payload.byteLength);\n for (let i = 0; i < output.length; i += 1) {\n const offset = i * bytes;\n switch (type) {\n case TciSampleType.INT16:\n output[i] = view.getInt16(offset, true) / 32768;\n break;\n case TciSampleType.INT24:\n output[i] = readInt24(view, offset) / 8388608;\n break;\n case TciSampleType.INT32:\n output[i] = view.getInt32(offset, true) / 2147483648;\n break;\n case TciSampleType.FLOAT32:\n output[i] = view.getFloat32(offset, true);\n break;\n }\n }\n return output;\n}\n\nexport function samplesToPayload(samples: Float32Array | readonly number[], sampleType: TciSampleType | TciSampleTypeName): Buffer {\n const type = normalizeSampleType(sampleType);\n const bytes = sampleTypeBytes(type);\n const payload = Buffer.alloc(samples.length * bytes);\n const view = new DataView(payload.buffer, payload.byteOffset, payload.byteLength);\n for (let i = 0; i < samples.length; i += 1) {\n const value = clampSample(samples[i] ?? 0);\n const offset = i * bytes;\n switch (type) {\n case TciSampleType.INT16:\n view.setInt16(offset, Math.round(value * 32767), true);\n break;\n case TciSampleType.INT24:\n writeInt24(view, offset, Math.round(value * 8388607));\n break;\n case TciSampleType.INT32:\n view.setInt32(offset, Math.round(value * 2147483647), true);\n break;\n case TciSampleType.FLOAT32:\n view.setFloat32(offset, value, true);\n break;\n }\n }\n return payload;\n}\n\nexport function pcm16ToFloat32(input: Buffer | Uint8Array | Int16Array): Float32Array {\n if (input instanceof Int16Array) {\n const output = new Float32Array(input.length);\n for (let i = 0; i < input.length; i += 1) {\n output[i] = input[i] / 32768;\n }\n return output;\n }\n return payloadToFloat32(toBuffer(input), TciSampleType.INT16);\n}\n\nexport function float32ToPcm16(samples: Float32Array | readonly number[]): Buffer {\n return samplesToPayload(samples, TciSampleType.INT16);\n}\n\nexport function deinterleaveChannels(samples: Float32Array, channels: number): Float32Array[] {\n if (channels <= 0 || samples.length % channels !== 0) {\n throw new TciError('invalid-frame', 'Cannot deinterleave samples with invalid channel count');\n }\n const frames = samples.length / channels;\n const outputs = Array.from({ length: channels }, () => new Float32Array(frames));\n for (let frame = 0; frame < frames; frame += 1) {\n for (let channel = 0; channel < channels; channel += 1) {\n outputs[channel][frame] = samples[frame * channels + channel];\n }\n }\n return outputs;\n}\n\nexport function mixToMono(samples: Float32Array, channels: number): Float32Array {\n if (channels === 1) {\n return samples;\n }\n const separated = deinterleaveChannels(samples, channels);\n const mono = new Float32Array(separated[0]?.length ?? 0);\n for (const channel of separated) {\n for (let i = 0; i < mono.length; i += 1) {\n mono[i] += channel[i] / channels;\n }\n }\n return mono;\n}\n\nfunction toBuffer(input: Buffer | Uint8Array | ArrayBuffer | ArrayBufferView): Buffer {\n if (Buffer.isBuffer(input)) {\n return input;\n }\n if (input instanceof ArrayBuffer) {\n return Buffer.from(input);\n }\n if (ArrayBuffer.isView(input)) {\n return Buffer.from(input.buffer, input.byteOffset, input.byteLength);\n }\n return Buffer.from(input);\n}\n\nfunction isFrame(value: unknown): value is TciStreamFrame {\n return Boolean(value && typeof value === 'object' && 'payload' in value && 'sampleType' in value);\n}\n\nfunction clampSample(value: number): number {\n if (!Number.isFinite(value)) {\n return 0;\n }\n return Math.max(-1, Math.min(1, value));\n}\n\nfunction readInt24(view: DataView, offset: number): number {\n const value = view.getUint8(offset) | (view.getUint8(offset + 1) << 8) | (view.getUint8(offset + 2) << 16);\n return value & 0x800000 ? value | 0xff000000 : value;\n}\n\nfunction writeInt24(view: DataView, offset: number, value: number): void {\n const clamped = Math.max(-8388608, Math.min(8388607, value));\n view.setUint8(offset, clamped & 0xff);\n view.setUint8(offset + 1, (clamped >> 8) & 0xff);\n view.setUint8(offset + 2, (clamped >> 16) & 0xff);\n}\n","export interface TciCommand {\n /** Lower-case command name for case-insensitive matching. */\n name: string;\n /** Original command name as received, without surrounding whitespace. */\n originalName: string;\n /** Unescaped argument list. Empty commands have an empty array. */\n args: string[];\n /** Raw command fragment without the trailing semicolon. */\n raw: string;\n}\n\nexport type TciCommandInput = string | TciCommand;\n\nconst ESCAPE_TO_CHAR: Record<string, string> = {\n '^': ':',\n '~': ',',\n '*': ';',\n};\n\nconst CHAR_TO_ESCAPE: Record<string, string> = {\n ':': '^',\n ',': '~',\n ';': '*',\n};\n\nexport function escapeTciText(value: unknown): string {\n return String(value).replace(/[:;,]/g, (char) => CHAR_TO_ESCAPE[char] ?? char);\n}\n\nexport function unescapeTciText(value: string): string {\n return value.replace(/[\\^~*]/g, (char) => ESCAPE_TO_CHAR[char] ?? char);\n}\n\nexport function parseTciText(text: string | Buffer | ArrayBuffer | ArrayBufferView): TciCommand[] {\n const source = normalizeTextInput(text);\n const commands: TciCommand[] = [];\n\n for (const fragment of source.split(';')) {\n const raw = fragment.trim();\n if (!raw) {\n continue;\n }\n\n const colonIndex = raw.indexOf(':');\n const originalName = (colonIndex >= 0 ? raw.slice(0, colonIndex) : raw).trim();\n if (!originalName) {\n continue;\n }\n\n const argsText = colonIndex >= 0 ? raw.slice(colonIndex + 1) : undefined;\n commands.push({\n name: originalName.toLowerCase(),\n originalName,\n args: argsText === undefined ? [] : splitArgs(argsText),\n raw,\n });\n }\n\n return commands;\n}\n\nexport function parseTciCommand(input: TciCommandInput): TciCommand {\n if (typeof input !== 'string') {\n return input;\n }\n const [command] = parseTciText(input);\n if (!command) {\n throw new Error(`Invalid TCI command: ${input}`);\n }\n return command;\n}\n\nexport function formatTciCommand(name: string, args: readonly unknown[] = []): string {\n const commandName = name.trim().toUpperCase();\n if (!commandName) {\n throw new Error('TCI command name cannot be empty');\n }\n if (args.length === 0) {\n return `${commandName};`;\n }\n return `${commandName}:${args.map(escapeTciText).join(',')};`;\n}\n\nexport function normalizeCommandName(name: string): string {\n return name.trim().toLowerCase();\n}\n\nexport function isCommandReplyTo(replyInput: TciCommandInput, requestInput: TciCommandInput): boolean {\n const reply = parseTciCommand(replyInput);\n const request = parseTciCommand(requestInput);\n if (reply.name !== request.name) {\n return false;\n }\n\n if (request.args.length === 0) {\n return true;\n }\n\n if (argsHavePrefix(reply.args, request.args)) {\n return true;\n }\n\n return isKnownVariantReply(reply, request);\n}\n\nexport function commandKey(command: TciCommandInput): string {\n const parsed = parseTciCommand(command);\n return `${parsed.name}:${parsed.args.join(',')}`;\n}\n\nfunction normalizeTextInput(text: string | Buffer | ArrayBuffer | ArrayBufferView): string {\n if (typeof text === 'string') {\n return text;\n }\n if (Buffer.isBuffer(text)) {\n return text.toString('utf8');\n }\n if (text instanceof ArrayBuffer) {\n return Buffer.from(text).toString('utf8');\n }\n return Buffer.from(text.buffer, text.byteOffset, text.byteLength).toString('utf8');\n}\n\nfunction splitArgs(argsText: string): string[] {\n return argsText.split(',').map((arg) => unescapeTciText(arg.trim()));\n}\n\nfunction argsHavePrefix(args: readonly string[], prefix: readonly string[]): boolean {\n if (args.length < prefix.length) {\n return false;\n }\n return prefix.every((arg, index) => args[index]?.toLowerCase() === arg.toLowerCase());\n}\n\nfunction isKnownVariantReply(reply: TciCommand, request: TciCommand): boolean {\n if (reply.name === 'modulation') {\n // ExpertSDR/WSJT-X variants can use MODULATION:rx,mode and MODULATION:rx,vfo,mode.\n if (request.args.length === 2 && reply.args.length >= 3) {\n return reply.args[0] === request.args[0] && reply.args[2]?.toLowerCase() === request.args[1]?.toLowerCase();\n }\n if (request.args.length === 3 && reply.args.length === 2) {\n return reply.args[0] === request.args[0] && reply.args[1]?.toLowerCase() === request.args[2]?.toLowerCase();\n }\n }\n\n if (reply.name === 'protocol') {\n return request.args.length <= 1;\n }\n\n if (reply.name === 'trx' && request.args.length >= 3 && reply.args.length >= 2) {\n // Official TRX writes may include an audio source as arg3, while replies only echo trx+state.\n return reply.args[0] === request.args[0] && reply.args[1]?.toLowerCase() === request.args[1]?.toLowerCase();\n }\n\n return false;\n}\n","import { TciError } from '../errors.js';\nimport {\n formatTciCommand,\n isCommandReplyTo,\n parseTciCommand,\n type TciCommand,\n type TciCommandInput,\n} from './text.js';\n\nexport type TciCommandMatcher = (reply: TciCommand, request: TciCommand) => boolean;\n\nexport interface QueueCommandOptions {\n timeoutMs?: number;\n matcher?: TciCommandMatcher;\n signal?: AbortSignal;\n}\n\nexport interface QueuedCommandResult {\n request: TciCommand;\n reply: TciCommand;\n}\n\ninterface PendingCommand {\n raw: string;\n request: TciCommand;\n timeoutMs: number;\n matcher: TciCommandMatcher;\n resolve: (result: QueuedCommandResult) => void;\n reject: (error: TciError) => void;\n timer?: NodeJS.Timeout;\n abortCleanup?: () => void;\n}\n\nexport interface TciCommandQueueOptions {\n send: (raw: string) => void | Promise<void>;\n timeoutMs?: number;\n}\n\nexport class TciCommandQueue {\n private readonly send: (raw: string) => void | Promise<void>;\n private readonly defaultTimeoutMs: number;\n private queue: PendingCommand[] = [];\n private active?: PendingCommand;\n private connected = true;\n\n constructor(options: TciCommandQueueOptions) {\n this.send = options.send;\n this.defaultTimeoutMs = options.timeoutMs ?? 1_000;\n }\n\n setConnected(connected: boolean): void {\n this.connected = connected;\n if (!connected) {\n this.cancelAll(new TciError('disconnected', 'TCI connection closed'));\n }\n }\n\n enqueue(command: TciCommandInput, options: QueueCommandOptions = {}): Promise<QueuedCommandResult> {\n const request = parseTciCommand(command);\n const raw = typeof command === 'string' ? ensureSemicolon(command) : formatTciCommand(command.originalName, command.args);\n\n if (!this.connected) {\n return Promise.reject(new TciError('not-connected', 'TCI socket is not connected'));\n }\n\n return new Promise<QueuedCommandResult>((resolve, reject) => {\n const pending: PendingCommand = {\n raw,\n request,\n timeoutMs: options.timeoutMs ?? this.defaultTimeoutMs,\n matcher: options.matcher ?? ((reply, req) => isCommandReplyTo(reply, req)),\n resolve,\n reject,\n };\n\n if (options.signal) {\n if (options.signal.aborted) {\n reject(new TciError('cancelled', 'TCI command was cancelled'));\n return;\n }\n const onAbort = () => this.rejectPending(pending, new TciError('cancelled', 'TCI command was cancelled'));\n options.signal.addEventListener('abort', onAbort, { once: true });\n pending.abortCleanup = () => options.signal?.removeEventListener('abort', onAbort);\n }\n\n this.queue.push(pending);\n void this.pump();\n });\n }\n\n handleCommand(commandInput: TciCommandInput): boolean {\n const active = this.active;\n if (!active) {\n return false;\n }\n const reply = parseTciCommand(commandInput);\n if (!active.matcher(reply, active.request)) {\n return false;\n }\n this.finishActive(reply);\n return true;\n }\n\n cancelAll(error = new TciError('cancelled', 'TCI command queue cancelled')): void {\n const pending = [...this.queue];\n this.queue = [];\n if (this.active) {\n pending.unshift(this.active);\n this.active = undefined;\n }\n for (const item of pending) {\n this.rejectPending(item, error);\n }\n }\n\n get size(): number {\n return this.queue.length + (this.active ? 1 : 0);\n }\n\n private async pump(): Promise<void> {\n if (this.active || !this.connected) {\n return;\n }\n const next = this.queue.shift();\n if (!next) {\n return;\n }\n\n this.active = next;\n next.timer = setTimeout(() => {\n this.rejectPending(next, new TciError('command-timeout', `Timed out waiting for TCI reply to ${next.raw}`));\n if (this.active === next) {\n this.active = undefined;\n }\n void this.pump();\n }, next.timeoutMs);\n\n try {\n await this.send(next.raw);\n } catch (error) {\n this.rejectPending(next, new TciError('disconnected', error instanceof Error ? error.message : String(error), error));\n if (this.active === next) {\n this.active = undefined;\n }\n void this.pump();\n }\n }\n\n private finishActive(reply: TciCommand): void {\n const active = this.active;\n if (!active) {\n return;\n }\n this.active = undefined;\n if (active.timer) {\n clearTimeout(active.timer);\n }\n active.abortCleanup?.();\n active.resolve({ request: active.request, reply });\n void this.pump();\n }\n\n private rejectPending(pending: PendingCommand, error: TciError): void {\n if (pending.timer) {\n clearTimeout(pending.timer);\n }\n pending.abortCleanup?.();\n const wasActive = this.active === pending;\n if (wasActive) {\n this.active = undefined;\n } else {\n this.queue = this.queue.filter((item) => item !== pending);\n }\n pending.reject(error);\n if (wasActive && this.connected) {\n void this.pump();\n }\n }\n}\n\nfunction ensureSemicolon(command: string): string {\n return command.trim().endsWith(';') ? command.trim() : `${command.trim()};`;\n}\n","import type {\n TciDialect,\n TciDialectDetectionContext,\n TciDialectScore,\n TciDriveState,\n TciStreamLengthSemantics,\n} from './types.js';\n\ntype VersionTuple = readonly number[];\n\ninterface StandardDialectOptions {\n id: TciDialect['id'];\n label: string;\n streamLengthSemantics: TciStreamLengthSemantics;\n supportsStreamChannels: boolean;\n supportsTxAudioSource: boolean;\n driveHasTrx: boolean;\n detect: (context: TciDialectDetectionContext) => TciDialectScore;\n resolve?: (context: TciDialectDetectionContext) => TciDialect;\n}\n\nclass StandardTciDialect implements TciDialect {\n readonly id: TciDialect['id'];\n readonly label: string;\n readonly streamLengthSemantics: TciStreamLengthSemantics;\n readonly supportsStreamChannels: boolean;\n readonly supportsTxAudioSource: boolean;\n private readonly driveHasTrx: boolean;\n private readonly detector: StandardDialectOptions['detect'];\n private readonly resolver?: StandardDialectOptions['resolve'];\n\n constructor(options: StandardDialectOptions) {\n this.id = options.id;\n this.label = options.label;\n this.streamLengthSemantics = options.streamLengthSemantics;\n this.supportsStreamChannels = options.supportsStreamChannels;\n this.supportsTxAudioSource = options.supportsTxAudioSource;\n this.driveHasTrx = options.driveHasTrx;\n this.detector = options.detect;\n this.resolver = options.resolve;\n }\n\n detect(context: TciDialectDetectionContext): TciDialectScore {\n return this.detector(context);\n }\n\n resolve(context: TciDialectDetectionContext): TciDialect {\n return this.resolver?.(context) ?? this;\n }\n\n buildDriveSetArgs(trx: number, value: number): readonly unknown[] {\n return this.driveHasTrx ? [trx, value] : [value];\n }\n\n buildDriveReadArgs(trx: number): readonly unknown[] {\n return this.driveHasTrx ? [trx] : [];\n }\n\n parseDrive(args: readonly string[], defaultTrx: number): TciDriveState | undefined {\n return parseDriveState(args, defaultTrx, this.driveHasTrx);\n }\n\n buildTuneDriveSetArgs(trx: number, value: number): readonly unknown[] {\n return this.driveHasTrx ? [trx, value] : [value];\n }\n\n buildTuneDriveReadArgs(trx: number): readonly unknown[] {\n return this.driveHasTrx ? [trx] : [];\n }\n\n parseTuneDrive(args: readonly string[], defaultTrx: number): TciDriveState | undefined {\n return parseDriveState(args, defaultTrx, this.driveHasTrx);\n }\n}\n\nfunction parseDriveState(args: readonly string[], defaultTrx: number, hasTrx: boolean): TciDriveState | undefined {\n const trx = hasTrx ? Number(args[0]) : defaultTrx;\n const value = Number(args[hasTrx ? 1 : 0]);\n if (!Number.isInteger(trx) || !Number.isFinite(value)) return undefined;\n return { trx, value };\n}\n\nfunction version(context: TciDialectDetectionContext): VersionTuple | undefined {\n return parseTciVersion(context.identity.protocolVersion);\n}\n\nfunction programIncludes(context: TciDialectDetectionContext, value: string): boolean {\n return context.identity.programName?.toLowerCase().includes(value) ?? false;\n}\n\nexport const expertSdr14Dialect: TciDialect = new StandardTciDialect({\n id: 'expertsdr-1.4', label: 'ExpertSDR / TCI 1.4', streamLengthSemantics: 'per-channel',\n supportsStreamChannels: false, supportsTxAudioSource: false, driveHasTrx: false,\n detect: (context) => {\n const parsed = version(context);\n if (!parsed || compareTciVersion(parsed, [1, 4]) > 0) return { score: 0, evidence: [] };\n return { score: 80 + (programIncludes(context, 'expert') ? 10 : 0), evidence: [`protocol ${formatVersion(parsed)} <= 1.4`] };\n },\n});\n\nexport const expertSdrLegacyDialect: TciDialect = new StandardTciDialect({\n id: 'expertsdr-1.5-1.8', label: 'ExpertSDR / TCI 1.5-1.8', streamLengthSemantics: 'per-channel',\n supportsStreamChannels: false, supportsTxAudioSource: false, driveHasTrx: true,\n detect: (context) => {\n const parsed = version(context);\n if (!parsed || compareTciVersion(parsed, [1, 5]) < 0 || compareTciVersion(parsed, [1, 9]) >= 0) return { score: 0, evidence: [] };\n return { score: 80 + (programIncludes(context, 'expert') ? 10 : 0), evidence: [`protocol ${formatVersion(parsed)} is in 1.5-1.8`] };\n },\n});\n\nexport const expertSdrModernDialect: TciDialect = new StandardTciDialect({\n id: 'expertsdr-1.9-2.0', label: 'ExpertSDR / TCI 1.9-2.0', streamLengthSemantics: 'scalar',\n supportsStreamChannels: true, supportsTxAudioSource: true, driveHasTrx: true,\n detect: (context) => {\n const parsed = version(context);\n if (!parsed || compareTciVersion(parsed, [1, 9]) < 0) return { score: 0, evidence: [] };\n const future = compareTciVersion(parsed, [2, 0]) > 0;\n return {\n score: 70 + (programIncludes(context, 'expert') ? 15 : 0),\n evidence: [`protocol ${formatVersion(parsed)} uses modern stream negotiation`],\n warnings: future ? [`Unknown future TCI version ${formatVersion(parsed)}; using the modern dialect`] : [],\n };\n },\n});\n\nexport const thetisDialect: TciDialect = new StandardTciDialect({\n id: 'thetis-2.0', label: 'Thetis / TCI 2.0', streamLengthSemantics: 'scalar',\n supportsStreamChannels: true, supportsTxAudioSource: true, driveHasTrx: true,\n detect: (context) => {\n const evidence: string[] = [];\n let score = 0;\n if (programIncludes(context, 'thetis')) { score += 120; evidence.push('PROTOCOL program is Thetis'); }\n const observed = ['tx_frequency_ex', 'tx_profiles_ex', 'tx_profile_ex', 'calibration_ex']\n .filter((name) => context.commandNames.has(name));\n if (observed.length > 0) { score += 100; evidence.push(`Thetis extension commands: ${observed.join(', ')}`); }\n if (/anan|hermes|orion|saturn/i.test(context.identity.device ?? '')) {\n score += 30;\n evidence.push(`Thetis-family device: ${context.identity.device}`);\n }\n return { score, evidence };\n },\n});\n\nexport const aetherSdrDialect: TciDialect = new StandardTciDialect({\n id: 'aethersdr-1.5', label: 'AetherSDR / TCI 1.5 hybrid', streamLengthSemantics: 'scalar',\n supportsStreamChannels: true, supportsTxAudioSource: true, driveHasTrx: true,\n detect: (context) => {\n if (!/^aethersdr$/i.test(context.identity.device ?? '')) return { score: 0, evidence: [] };\n const evidence = [`AetherSDR device identity: ${context.identity.device}`];\n const modernAudioCommands = ['audio_stream_sample_type', 'audio_stream_channels', 'audio_stream_samples']\n .filter((name) => context.commandNames.has(name));\n if (modernAudioCommands.length > 0) evidence.push(`Modern audio negotiation: ${modernAudioCommands.join(', ')}`);\n return {\n score: 150,\n evidence,\n warnings: context.identity.protocolVersion === '1.5'\n ? ['AetherSDR reports TCI 1.5 but uses modern scalar audio stream semantics']\n : [],\n };\n },\n});\n\nexport const genericObservedDialect: TciDialect = new StandardTciDialect({\n id: 'generic-observed', label: 'Generic observed TCI', streamLengthSemantics: 'auto',\n supportsStreamChannels: true, supportsTxAudioSource: true, driveHasTrx: true,\n detect: (context) => ({\n score: context.commandNames.has('ready') ? 10 : 0,\n evidence: ['No vendor-specific match; using observed command shapes'],\n warnings: ['Dialect identity is uncertain'],\n }),\n resolve: (context) => {\n const drive = [...context.commands].reverse().find((command) => command.name === 'drive');\n const driveHasTrx = (drive?.args.length ?? 0) >= 2;\n return new StandardTciDialect({\n id: 'generic-observed',\n label: 'Generic observed TCI',\n streamLengthSemantics: 'auto',\n supportsStreamChannels: context.commandNames.has('audio_stream_channels'),\n supportsTxAudioSource: compareTciVersion(version(context) ?? [0], [2, 0]) >= 0,\n driveHasTrx,\n detect: genericObservedDialect.detect.bind(genericObservedDialect),\n });\n },\n});\n\nexport const builtInDialects: readonly TciDialect[] = [\n aetherSdrDialect, thetisDialect, expertSdr14Dialect, expertSdrLegacyDialect, expertSdrModernDialect, genericObservedDialect,\n];\n\nexport function parseTciVersion(value: string | undefined): VersionTuple | undefined {\n if (!value) return undefined;\n const match = value.trim().match(/^(\\d+)(?:\\.(\\d+))?(?:\\.(\\d+))?/);\n if (!match) return undefined;\n return match.slice(1).filter((part): part is string => part !== undefined).map(Number);\n}\n\nexport function compareTciVersion(left: VersionTuple, right: VersionTuple): number {\n const length = Math.max(left.length, right.length);\n for (let index = 0; index < length; index += 1) {\n const difference = (left[index] ?? 0) - (right[index] ?? 0);\n if (difference !== 0) return difference;\n }\n return 0;\n}\n\nfunction formatVersion(value: VersionTuple): string { return value.join('.'); }\n","import { TciError } from '../errors.js';\nimport { builtInDialects } from './builtins.js';\nimport type {\n TciDialect,\n TciDialectDetection,\n TciDialectDetectionContext,\n TciDialectId,\n TciDialectSelection,\n} from './types.js';\n\nexport class TciDialectRegistry {\n private readonly dialects = new Map<TciDialectId, TciDialect>();\n\n constructor(dialects: readonly TciDialect[] = builtInDialects) {\n for (const dialect of dialects) this.register(dialect);\n }\n\n register(dialect: TciDialect): void { this.dialects.set(dialect.id, dialect); }\n get(id: TciDialectId): TciDialect | undefined { return this.dialects.get(id); }\n list(): TciDialect[] { return [...this.dialects.values()]; }\n\n select(context: TciDialectDetectionContext, selection: TciDialectSelection = 'auto'): TciDialectDetection {\n if (typeof selection === 'object') {\n return { dialect: selection, confidence: 'manual', evidence: ['Custom dialect supplied by caller'], warnings: [] };\n }\n if (selection !== 'auto') {\n const dialect = this.get(selection);\n if (!dialect) throw new TciError('unknown-dialect', `Unknown TCI dialect: ${selection}`);\n return { dialect: dialect.resolve?.(context) ?? dialect, confidence: 'manual', evidence: [`Dialect ${selection} selected by caller`], warnings: [] };\n }\n\n const candidates = this.list()\n .map((dialect) => ({ dialect, result: dialect.detect(context) }))\n .sort((left, right) => right.result.score - left.result.score);\n const selected = candidates[0];\n if (!selected || selected.result.score <= 0) {\n throw new TciError('unknown-dialect', 'Unable to identify the TCI server dialect');\n }\n return {\n dialect: selected.dialect.resolve?.(context) ?? selected.dialect,\n confidence: selected.result.score >= 100 ? 'high' : selected.result.score >= 70 ? 'medium' : 'low',\n evidence: selected.result.evidence,\n warnings: selected.result.warnings ?? [],\n };\n }\n}\n\nexport const defaultTciDialectRegistry = new TciDialectRegistry();\n","import { TciError } from '../errors.js';\nimport type { TciCommand } from '../protocol/text.js';\nimport type { TciProtocolIdentity } from './types.js';\n\nconst IDENTITY_COMMANDS = new Set(['protocol', 'device', 'trx_count', 'channels_count', 'channel_count']);\nconst STATE_COMMANDS = new Set(['vfo', 'modulation', 'modulations_list', 'trx', 'drive']);\n\nexport function parseProtocolIdentity(commands: readonly TciCommand[]): TciProtocolIdentity {\n const protocol = [...commands].reverse().find((command) => command.name === 'protocol');\n const device = [...commands].reverse().find((command) => command.name === 'device');\n const rawProtocolArgs = protocol?.args ?? [];\n const firstLooksLikeVersion = /^\\d+(?:\\.\\d+){0,2}/.test(rawProtocolArgs[0] ?? '');\n return {\n programName: firstLooksLikeVersion ? undefined : rawProtocolArgs[0],\n protocolVersion: firstLooksLikeVersion ? rawProtocolArgs[0] : rawProtocolArgs[1],\n rawProtocolArgs: [...rawProtocolArgs],\n device: device?.args.join(','),\n };\n}\n\nexport function assertValidTciHandshake(commands: readonly TciCommand[]): void {\n const names = new Set(commands.map((command) => command.name));\n if (!names.has('ready')) throw new TciError('handshake-timeout', 'TCI READY was not received');\n const categories = [\n [...IDENTITY_COMMANDS].some((name) => names.has(name)),\n [...STATE_COMMANDS].some((name) => names.has(name)),\n ].filter(Boolean).length;\n const identitySignals = [...IDENTITY_COMMANDS].filter((name) => names.has(name)).length;\n if (categories < 2 && identitySignals < 2) {\n throw new TciError('invalid-handshake', 'WebSocket opened but did not provide enough TCI initialization evidence');\n }\n}\n","import { EventEmitter } from 'eventemitter3';\nimport WebSocket from 'ws';\nimport { TciError, toTciError } from '../errors.js';\nimport type { TciTransport, TciTransportEvents } from './types.js';\n\nexport class WebSocketTciTransport extends EventEmitter<TciTransportEvents> implements TciTransport {\n private socket?: WebSocket;\n\n constructor(readonly url: string, private readonly WebSocketImpl: typeof WebSocket = WebSocket) {\n super();\n }\n\n async connect(timeoutMs: number): Promise<void> {\n if (this.socket?.readyState === WebSocket.OPEN) return;\n const socket = new this.WebSocketImpl(this.url);\n this.socket = socket;\n await new Promise<void>((resolve, reject) => {\n const timer = setTimeout(() => {\n cleanup();\n this.terminate();\n reject(new TciError('connect-timeout', `Timed out connecting to ${this.url}`));\n }, timeoutMs);\n const cleanup = () => {\n clearTimeout(timer);\n socket.off('open', onOpen);\n socket.off('close', onCloseBeforeOpen);\n socket.off('error', onErrorBeforeOpen);\n };\n const onOpen = () => {\n cleanup();\n this.attach(socket);\n this.emit('connected');\n resolve();\n };\n const onCloseBeforeOpen = () => {\n cleanup();\n reject(new TciError('disconnected', `Disconnected while connecting to ${this.url}`));\n };\n const onErrorBeforeOpen = (error: Error) => {\n cleanup();\n reject(toTciError(error, 'disconnected'));\n };\n socket.once('open', onOpen);\n socket.once('close', onCloseBeforeOpen);\n socket.once('error', onErrorBeforeOpen);\n });\n }\n\n async disconnect(code = 1000, reason = 'client disconnect'): Promise<void> {\n const socket = this.socket;\n if (!socket || socket.readyState === WebSocket.CLOSED) return;\n await new Promise<void>((resolve) => {\n const timer = setTimeout(resolve, 1_000);\n timer.unref?.();\n socket.once('close', () => { clearTimeout(timer); resolve(); });\n socket.once('error', () => { clearTimeout(timer); resolve(); });\n socket.close(code, reason);\n });\n }\n\n isConnected(): boolean { return this.socket?.readyState === WebSocket.OPEN; }\n\n async sendText(raw: string): Promise<void> { await this.send(raw); }\n async sendBinary(raw: Buffer): Promise<void> { await this.send(raw, true); }\n\n terminate(): void {\n try { this.socket?.terminate(); } catch { /* ignore termination races */ }\n }\n\n private attach(socket: WebSocket): void {\n socket.on('message', (data, isBinary) => {\n try {\n const buffer = dataToBuffer(data);\n if (isBinary) this.emit('binary', buffer);\n else this.emit('text', buffer.toString('utf8'));\n } catch (error) {\n this.emit('error', error instanceof Error ? error : new Error(String(error)));\n }\n });\n socket.on('close', (code, reason) => {\n if (this.socket === socket) this.socket = undefined;\n this.emit('disconnected', { code, reason: reason.toString('utf8') });\n });\n socket.on('error', (error) => this.emit('error', error));\n }\n\n private async send(data: string | Buffer, binary = false): Promise<void> {\n const socket = this.socket;\n if (!socket || socket.readyState !== WebSocket.OPEN) {\n throw new TciError('not-connected', 'TCI socket is not connected');\n }\n await new Promise<void>((resolve, reject) => {\n socket.send(data, { binary }, (error) => error ? reject(error) : resolve());\n });\n }\n}\n\nfunction dataToBuffer(data: WebSocket.RawData): Buffer {\n if (Buffer.isBuffer(data)) return data;\n if (data instanceof ArrayBuffer) return Buffer.from(data);\n if (Array.isArray(data)) return Buffer.concat(data.map((item) => dataToBuffer(item)));\n throw new TciError('protocol-error', 'Unsupported WebSocket data type');\n}\n"],"mappings":"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","names":["EventEmitter","WebSocket","TciStreamType","TciSampleType","EventEmitter","WebSocket","applied"]}
|
|
1
|
+
{"version":3,"sources":["../src/errors.ts","../src/client/TciClient.ts","../src/audio/streamFrame.ts","../src/protocol/text.ts","../src/protocol/commandQueue.ts","../src/meter/types.ts","../src/meter/adapters.ts","../src/meter/TciMeterStreamSession.ts","../src/dialect/builtins.ts","../src/dialect/registry.ts","../src/dialect/handshake.ts","../src/transport/WebSocketTransport.ts"],"sourcesContent":["export type TciErrorCode =\n | 'connect-timeout'\n | 'handshake-timeout'\n | 'invalid-handshake'\n | 'unknown-dialect'\n | 'command-timeout'\n | 'not-connected'\n | 'disconnected'\n | 'protocol-error'\n | 'invalid-frame'\n | 'cancelled';\n\nexport class TciError extends Error {\n readonly code: TciErrorCode;\n readonly details?: unknown;\n\n constructor(code: TciErrorCode, message: string, details?: unknown) {\n super(message);\n this.name = 'TciError';\n this.code = code;\n this.details = details;\n }\n}\n\nexport function toTciError(error: unknown, fallbackCode: TciErrorCode = 'protocol-error'): TciError {\n if (error instanceof TciError) {\n return error;\n }\n if (error instanceof Error) {\n return new TciError(fallbackCode, error.message, error);\n }\n return new TciError(fallbackCode, String(error), error);\n}\n","import { EventEmitter } from 'eventemitter3';\nimport WebSocket from 'ws';\nimport { TciError, toTciError } from '../errors.js';\nimport {\n buildTxAudioFrame,\n normalizeSampleType,\n parseStreamFrame,\n sampleTypeName,\n TciSampleType,\n TciStreamType,\n type BuildTxAudioFrameOptions,\n type TciSampleTypeName,\n type TciStreamFrame,\n} from '../audio/streamFrame.js';\nimport {\n formatTciCommand,\n parseTciText,\n TciCommandQueue,\n type QueueCommandOptions,\n type TciCommand,\n} from '../protocol/index.js';\nimport {\n assertValidTciHandshake,\n defaultTciDialectRegistry,\n parseProtocolIdentity,\n type TciDialect,\n type TciDialectId,\n type TciDialectRegistry,\n type TciDialectSelection,\n type TciHandshakeResult,\n type TciWriteResult,\n} from '../dialect/index.js';\nimport {\n WebSocketTciTransport,\n type TciTransport,\n type TciTransportFactory,\n} from '../transport/index.js';\nimport {\n TciMeterStreamSession,\n UNKNOWN_TCI_METER_CAPABILITIES,\n cloneMeterCapabilities,\n createUnknownTciMeterAdapter,\n type TciMeterCapabilities,\n type TciMeterStreamOptions,\n} from '../meter/index.js';\n\nexport interface TciClientOptions {\n url: string;\n receiver?: number;\n trx?: number;\n vfo?: number;\n connectTimeoutMs?: number;\n handshakeTimeoutMs?: number;\n commandTimeoutMs?: number;\n writeAckMode?: TciWriteAckMode;\n writeTimeoutMs?: number;\n writeSettleMs?: number;\n frequencyWriteSettleMs?: number;\n dialect?: TciDialectSelection;\n dialectRegistry?: TciDialectRegistry;\n WebSocketImpl?: typeof WebSocket;\n transportFactory?: TciTransportFactory;\n}\n\nexport interface TciAudioConfig {\n sampleRate: 8_000 | 12_000 | 24_000 | 48_000 | number;\n sampleType?: TciSampleType | TciSampleTypeName;\n channels?: 1 | 2 | number;\n samplesPerFrame?: number;\n txBufferingMs?: number;\n}\n\nexport interface TciPttOptions {\n source?: 'tci' | 'mic1' | 'mic2' | 'micpc' | 'ecoder2' | string;\n trx?: number;\n ackMode?: TciWriteAckMode;\n timeoutMs?: number;\n settleMs?: number;\n}\n\nexport type TciWriteAckMode = 'state' | 'reply' | 'optimistic';\n\nexport interface TciWriteOptions {\n ackMode?: TciWriteAckMode;\n timeoutMs?: number;\n settleMs?: number;\n}\n\nexport interface TciTxChronoRequest {\n frame: TciStreamFrame;\n receiver: number;\n sampleRate: number;\n channels: number;\n sampleType: TciSampleType;\n sampleCount: number;\n frameCount: number;\n}\n\nexport interface TciIqCapabilities {\n supported: boolean;\n currentSampleRate?: number;\n supportedSampleRates: readonly number[];\n}\n\nexport interface TciIqFrame {\n frame: TciStreamFrame;\n receiver: number;\n sampleRate: number;\n centerFrequency?: number;\n complexSampleCount: number;\n}\n\nexport interface TciIqStreamOptions {\n receiver?: number;\n sampleRate?: number;\n firstFrameTimeoutMs?: number;\n}\n\nexport interface IqSampleRateResult extends TciWriteResult<number> {}\n\nexport interface TciIqStreamEvents {\n frame: (frame: TciIqFrame) => void;\n error: (error: TciError) => void;\n closed: () => void;\n}\n\ninterface TciIqStreamCallbacks {\n setSampleRate: (sampleRate: number) => Promise<IqSampleRateResult>;\n close: () => Promise<void>;\n}\n\nexport class TciIqStreamSession extends EventEmitter<TciIqStreamEvents> {\n readonly receiver: number;\n private _appliedSampleRate: number;\n private readonly callbacks: TciIqStreamCallbacks;\n private closed = false;\n private firstFrame?: {\n promise: Promise<TciIqFrame>;\n resolve: (frame: TciIqFrame) => void;\n reject: (error: TciError) => void;\n timer: NodeJS.Timeout;\n };\n\n constructor(receiver: number, appliedSampleRate: number, callbacks: TciIqStreamCallbacks) {\n super();\n this.receiver = receiver;\n this._appliedSampleRate = appliedSampleRate;\n this.callbacks = callbacks;\n }\n\n get appliedSampleRate(): number { return this._appliedSampleRate; }\n\n async setSampleRate(sampleRate: number): Promise<IqSampleRateResult> {\n if (this.closed) throw new TciError('cancelled', 'TCI IQ stream is closed');\n const result = await this.callbacks.setSampleRate(sampleRate);\n this._appliedSampleRate = result.applied;\n return result;\n }\n\n async close(): Promise<void> {\n if (this.closed) return;\n this.closed = true;\n this.rejectFirstFrame(new TciError('cancelled', 'TCI IQ stream closed before its first frame'));\n try {\n await this.callbacks.close();\n } finally {\n this.emit('closed');\n this.removeAllListeners();\n }\n }\n\n waitForFirstFrame(timeoutMs: number): Promise<TciIqFrame> {\n if (this.firstFrame) return this.firstFrame.promise;\n let resolvePromise!: (frame: TciIqFrame) => void;\n let rejectPromise!: (error: TciError) => void;\n const promise = new Promise<TciIqFrame>((resolve, reject) => {\n resolvePromise = resolve;\n rejectPromise = reject;\n });\n const timer = setTimeout(() => {\n this.firstFrame = undefined;\n rejectPromise(new TciError('command-timeout', `Timed out waiting for TCI IQ frame for receiver ${this.receiver}`));\n }, timeoutMs);\n this.firstFrame = { promise, resolve: resolvePromise, reject: rejectPromise, timer };\n return promise;\n }\n\n _acceptFrame(frame: TciIqFrame): void {\n if (this.closed || frame.receiver !== this.receiver) return;\n this._appliedSampleRate = frame.sampleRate;\n const firstFrame = this.firstFrame;\n if (firstFrame) {\n clearTimeout(firstFrame.timer);\n this.firstFrame = undefined;\n firstFrame.resolve(frame);\n }\n this.emit('frame', frame);\n }\n\n _fail(error: TciError): void {\n if (this.closed) return;\n this.rejectFirstFrame(error);\n this.emit('error', error);\n }\n\n private rejectFirstFrame(error: TciError): void {\n const firstFrame = this.firstFrame;\n if (!firstFrame) return;\n clearTimeout(firstFrame.timer);\n this.firstFrame = undefined;\n firstFrame.reject(error);\n }\n}\n\nexport interface TciClientState {\n connected: boolean;\n ready: boolean;\n protocol?: string;\n protocolName?: string;\n protocolVersion?: string;\n dialectId?: TciDialectId;\n dialectConfidence?: TciHandshakeResult['dialect']['confidence'];\n dialectWarnings: string[];\n device?: string;\n receiveOnly?: boolean;\n trxCount?: number;\n channelCount?: number;\n vfoLimits?: [number, number];\n ifLimits?: [number, number];\n modulations: string[];\n frequencies: Record<string, number>;\n modes: Record<string, string>;\n ptt: Record<string, boolean>;\n pttSource: Record<string, string | undefined>;\n tune: Record<string, boolean>;\n drive: Record<string, number>;\n tuneDrive: Record<string, number>;\n split: Record<string, boolean>;\n rxSensors: Record<string, Record<string, number | string | boolean>>;\n txSensors: Record<string, Record<string, number | string | boolean>>;\n audio?: Required<Pick<TciAudioConfig, 'sampleRate' | 'channels' | 'sampleType' | 'samplesPerFrame'>> & {\n txBufferingMs?: number;\n running: boolean;\n };\n iq: {\n sampleRate?: number;\n activeReceivers: Record<string, boolean>;\n };\n dds: Record<string, number>;\n}\n\nexport interface TciClientEvents {\n connected: () => void;\n disconnected: (reason?: unknown) => void;\n ready: (state: TciClientState) => void;\n handshake: (result: TciHandshakeResult) => void;\n state: (state: TciClientState) => void;\n command: (command: TciCommand) => void;\n binary: (frame: TciStreamFrame) => void;\n 'tci:tx': (raw: string) => void;\n 'tci:rx': (raw: string, commands: TciCommand[]) => void;\n 'tci:binary': (frame: TciStreamFrame) => void;\n rxAudioFrame: (frame: TciStreamFrame) => void;\n iqFrame: (frame: TciIqFrame) => void;\n lineoutAudioFrame: (frame: TciStreamFrame) => void;\n txChrono: (request: TciTxChronoRequest) => void;\n error: (error: TciError) => void;\n}\n\nexport interface SendCommandOptions extends QueueCommandOptions {\n waitForReply?: boolean;\n}\n\nexport class TciClient extends EventEmitter<TciClientEvents> {\n readonly options: Required<Pick<\n TciClientOptions,\n | 'receiver'\n | 'trx'\n | 'vfo'\n | 'connectTimeoutMs'\n | 'handshakeTimeoutMs'\n | 'commandTimeoutMs'\n | 'writeAckMode'\n | 'writeTimeoutMs'\n | 'writeSettleMs'\n | 'frequencyWriteSettleMs'\n >> &\n Pick<TciClientOptions, 'url'> & { dialect: TciDialectSelection };\n\n private readonly WebSocketImpl: typeof WebSocket;\n private readonly transportFactory: TciTransportFactory;\n private transport?: TciTransport;\n private readonly queue: TciCommandQueue;\n private readonly state: TciClientState;\n private readonly stateReducers: Map<string, (args: string[]) => void>;\n private readonly dialectRegistry: TciDialectRegistry;\n private activeDialect?: TciDialect;\n private handshakeResult?: TciHandshakeResult;\n private handshakeError?: TciError;\n private initializationCommands: TciCommand[] = [];\n private handshakeWaiter?: {\n resolve: (result: TciHandshakeResult) => void;\n reject: (error: TciError) => void;\n timer: NodeJS.Timeout;\n };\n private activeIqSession?: TciIqStreamSession;\n private activeMeterSession?: TciMeterStreamSession;\n\n constructor(options: TciClientOptions) {\n super();\n this.options = {\n url: options.url,\n receiver: options.receiver ?? 0,\n trx: options.trx ?? 0,\n vfo: options.vfo ?? 0,\n connectTimeoutMs: options.connectTimeoutMs ?? 5_000,\n handshakeTimeoutMs: options.handshakeTimeoutMs ?? 10_000,\n commandTimeoutMs: options.commandTimeoutMs ?? 1_000,\n writeAckMode: options.writeAckMode ?? 'state',\n writeTimeoutMs: options.writeTimeoutMs ?? 3_000,\n writeSettleMs: options.writeSettleMs ?? 0,\n frequencyWriteSettleMs: options.frequencyWriteSettleMs ?? 250,\n dialect: options.dialect ?? 'auto',\n };\n this.dialectRegistry = options.dialectRegistry ?? defaultTciDialectRegistry;\n this.WebSocketImpl = options.WebSocketImpl ?? WebSocket;\n this.transportFactory = options.transportFactory\n ?? ((url) => new WebSocketTciTransport(url, this.WebSocketImpl));\n this.queue = new TciCommandQueue({\n timeoutMs: this.options.commandTimeoutMs,\n send: (raw) => this.sendRaw(raw),\n });\n this.queue.setConnected(false);\n this.state = {\n connected: false,\n ready: false,\n modulations: [],\n frequencies: {},\n modes: {},\n ptt: {},\n pttSource: {},\n tune: {},\n drive: {},\n tuneDrive: {},\n split: {},\n dialectWarnings: [],\n rxSensors: {},\n txSensors: {},\n iq: { activeReceivers: {} },\n dds: {},\n };\n this.stateReducers = this.createStateReducers();\n }\n\n async connect(): Promise<TciHandshakeResult> {\n if (this.transport?.isConnected()) {\n return this.handshakeResult ?? this.waitForHandshake();\n }\n this.resetHandshake();\n const transport = this.transportFactory(this.options.url);\n this.transport = transport;\n this.attachTransport(transport);\n await transport.connect(this.options.connectTimeoutMs);\n this.state.connected = true;\n this.queue.setConnected(true);\n this.emit('connected');\n this.emitState();\n try {\n return await this.waitForHandshake();\n } catch (error) {\n transport.terminate();\n throw error;\n }\n }\n\n async disconnect(code = 1000, reason = 'client disconnect'): Promise<void> {\n await this.activeMeterSession?.close().catch(() => undefined);\n const transport = this.transport;\n if (!transport) return;\n await transport.disconnect(code, reason);\n this.handleClose();\n }\n\n isConnected(): boolean {\n return this.transport?.isConnected() ?? false;\n }\n\n getState(): TciClientState {\n return cloneState(this.state);\n }\n\n getHandshakeResult(): TciHandshakeResult | undefined {\n return this.handshakeResult ? cloneHandshake(this.handshakeResult) : undefined;\n }\n\n getIqCapabilities(): TciIqCapabilities {\n const dialect = this.requireDialect();\n return {\n supported: dialect.supportsIqStream,\n currentSampleRate: this.state.iq.sampleRate,\n supportedSampleRates: [...dialect.iqSampleRates],\n };\n }\n\n getMeterCapabilities(): TciMeterCapabilities {\n if (this.activeMeterSession) return this.activeMeterSession.getCapabilities();\n const adapter = this.activeDialect?.meterAdapter;\n return adapter\n ? cloneMeterCapabilities(adapter.declaredCapabilities)\n : cloneMeterCapabilities(UNKNOWN_TCI_METER_CAPABILITIES);\n }\n\n async openMeterStream(options: TciMeterStreamOptions = {}): Promise<TciMeterStreamSession> {\n if (this.activeMeterSession) throw new TciError('protocol-error', 'This TCI client already has an active meter stream session');\n this.requireDialect();\n const receiver = normalizeNonNegativeInteger(options.receiver ?? this.options.receiver, 'meter receiver');\n const channel = normalizeNonNegativeInteger(options.channel ?? this.options.vfo, 'meter channel');\n const trx = normalizeNonNegativeInteger(options.trx ?? this.options.trx, 'meter transmitter');\n const rxEnabled = options.rx ?? true;\n const txEnabled = options.tx ?? true;\n if (!rxEnabled && !txEnabled) throw new TciError('protocol-error', 'TCI meter stream must enable RX, TX, or both');\n const requestedIntervalMs = Math.round(options.intervalMs ?? 300);\n if (!Number.isFinite(requestedIntervalMs) || requestedIntervalMs <= 0) {\n throw new TciError('protocol-error', `Invalid TCI meter interval: ${options.intervalMs}`);\n }\n\n const adapter = this.activeDialect?.meterAdapter ?? createUnknownTciMeterAdapter();\n const interval = adapter.normalizeInterval(requestedIntervalMs);\n let session!: TciMeterStreamSession;\n session = new TciMeterStreamSession({\n receiver,\n channel,\n trx,\n requestedIntervalMs: interval.requestedMs,\n appliedIntervalMs: interval.appliedMs,\n rxEnabled,\n txEnabled,\n adapter,\n callbacks: {\n close: async () => {\n try {\n if (this.isConnected()) {\n if (rxEnabled) {\n const command = adapter.buildEnableCommand('rx', false, interval.appliedMs ?? interval.requestedMs);\n await this.sendCommand(command.name, command.args, { waitForReply: false }).catch(() => undefined);\n }\n if (txEnabled) {\n const command = adapter.buildEnableCommand('tx', false, interval.appliedMs ?? interval.requestedMs);\n await this.sendCommand(command.name, command.args, { waitForReply: false }).catch(() => undefined);\n }\n }\n } finally {\n if (this.activeMeterSession === session) this.activeMeterSession = undefined;\n }\n },\n },\n });\n this.activeMeterSession = session;\n try {\n if (rxEnabled) {\n const command = adapter.buildEnableCommand('rx', true, interval.appliedMs ?? interval.requestedMs);\n await this.sendCommand(command.name, command.args, { waitForReply: false });\n }\n if (txEnabled) {\n const command = adapter.buildEnableCommand('tx', true, interval.appliedMs ?? interval.requestedMs);\n await this.sendCommand(command.name, command.args, { waitForReply: false });\n }\n return session;\n } catch (error) {\n await session.close().catch(() => undefined);\n throw error;\n }\n }\n\n async setIqSampleRate(sampleRate: number, timeoutMs = this.options.commandTimeoutMs): Promise<IqSampleRateResult> {\n const capabilities = this.getIqCapabilities();\n const requested = Math.round(sampleRate);\n if (!capabilities.supported) throw new TciError('protocol-error', `TCI dialect ${this.requireDialect().id} does not support IQ streaming`);\n if (!Number.isFinite(requested) || requested <= 0) throw new TciError('protocol-error', `Invalid TCI IQ sample rate: ${sampleRate}`);\n if (capabilities.supportedSampleRates.length > 0 && !capabilities.supportedSampleRates.includes(requested)) {\n throw new TciError('protocol-error', `TCI IQ sample rate ${requested} is not supported by dialect ${this.requireDialect().id}`);\n }\n if (this.state.iq.sampleRate === requested) return writeResult(requested, requested, 'state');\n const waiter = this.waitForCommand((command) => command.name === 'iq_samplerate', timeoutMs, 'IQ_SAMPLERATE readback');\n try {\n await this.sendCommand('IQ_SAMPLERATE', [requested], { waitForReply: false });\n const reply = await waiter.promise;\n const applied = parseNumber(reply.args[0]);\n if (applied === undefined || applied <= 0) throw new TciError('protocol-error', `Invalid IQ_SAMPLERATE readback: ${reply.raw}`);\n return writeResult(requested, applied, 'reply');\n } finally {\n waiter.cancel();\n }\n }\n\n async openIqStream(options: TciIqStreamOptions = {}): Promise<TciIqStreamSession> {\n if (this.activeIqSession) throw new TciError('protocol-error', 'This TCI client already has an active IQ stream session');\n const capabilities = this.getIqCapabilities();\n if (!capabilities.supported) throw new TciError('protocol-error', `TCI dialect ${this.requireDialect().id} does not support IQ streaming`);\n const receiver = Math.floor(options.receiver ?? this.options.receiver);\n if (!Number.isInteger(receiver) || receiver < 0) throw new TciError('protocol-error', `Invalid TCI IQ receiver: ${receiver}`);\n const requestedRate = options.sampleRate ?? capabilities.currentSampleRate ?? capabilities.supportedSampleRates[0] ?? 48_000;\n const rateResult = await this.setIqSampleRate(requestedRate);\n let session!: TciIqStreamSession;\n session = new TciIqStreamSession(receiver, rateResult.applied, {\n setSampleRate: (rate) => this.setIqSampleRate(rate),\n close: async () => {\n try {\n if (this.isConnected()) await this.sendCommand('IQ_STOP', [receiver], { waitForReply: false });\n } finally {\n this.state.iq.activeReceivers[String(receiver)] = false;\n if (this.activeIqSession === session) this.activeIqSession = undefined;\n this.emitState();\n }\n },\n });\n this.activeIqSession = session;\n const firstFrame = session.waitForFirstFrame(options.firstFrameTimeoutMs ?? 5_000);\n try {\n await this.sendCommand('IQ_START', [receiver], { waitForReply: false });\n this.state.iq.activeReceivers[String(receiver)] = true;\n this.emitState();\n await firstFrame;\n return session;\n } catch (error) {\n await session.close().catch(() => undefined);\n throw error;\n }\n }\n\n async sendCommand(name: string, args: readonly unknown[] = [], options: SendCommandOptions = {}): Promise<TciCommand | undefined> {\n const raw = formatTciCommand(name, args);\n if (options.waitForReply === false) {\n await this.sendRaw(raw);\n return undefined;\n }\n const result = await this.queue.enqueue(raw, options);\n return result.reply;\n }\n\n async request(name: string, args: readonly unknown[] = [], options: QueueCommandOptions = {}): Promise<TciCommand> {\n const reply = await this.sendCommand(name, args, { ...options, waitForReply: true });\n if (!reply) {\n throw new TciError('protocol-error', `No reply for ${name}`);\n }\n return reply;\n }\n\n async sendStateWrite(\n name: string,\n args: readonly unknown[],\n isApplied: (state: TciClientState) => boolean,\n description = formatTciCommand(name, args).replace(/;$/, ''),\n options: TciWriteOptions = {},\n ): Promise<void> {\n const ackMode = options.ackMode ?? this.options.writeAckMode;\n if (ackMode === 'reply') {\n await this.sendCommand(name, args, { timeoutMs: options.timeoutMs });\n return;\n }\n\n if (isApplied(this.getState())) {\n return;\n }\n\n if (ackMode === 'optimistic') {\n await this.sendCommand(name, args, { waitForReply: false });\n return;\n }\n\n const timeoutMs = options.timeoutMs ?? this.options.writeTimeoutMs;\n const settleMs = options.settleMs ?? this.options.writeSettleMs;\n const waiter = this.waitForState(isApplied, timeoutMs, settleMs, description);\n try {\n await this.sendCommand(name, args, { waitForReply: false });\n await waiter.promise;\n } catch (error) {\n waiter.cancel();\n throw error;\n }\n }\n\n async setFrequency(\n frequencyHz: number,\n receiver = this.options.receiver,\n vfo = this.options.vfo,\n options: TciWriteOptions = {},\n ): Promise<void> {\n const frequency = Math.round(frequencyHz);\n const key = rxVfoKey(receiver, vfo);\n await this.sendStateWrite(\n 'VFO',\n [receiver, vfo, frequency],\n (state) => state.frequencies[key] === frequency,\n `VFO:${receiver},${vfo},${frequency}`,\n { settleMs: this.options.frequencyWriteSettleMs, ...options },\n );\n }\n\n async getFrequency(receiver = this.options.receiver, vfo = this.options.vfo): Promise<number | undefined> {\n const reply = await this.request('VFO', [receiver, vfo]);\n return parseNumber(reply.args[2]) ?? this.state.frequencies[rxVfoKey(receiver, vfo)];\n }\n\n async setMode(mode: string, receiver = this.options.receiver, options: TciWriteOptions = {}): Promise<void> {\n const normalizedMode = mode.toUpperCase();\n const key = rxVfoKey(receiver, this.options.vfo);\n await this.sendStateWrite(\n 'MODULATION',\n [receiver, normalizedMode],\n (state) => state.modes[key]?.toLowerCase() === normalizedMode.toLowerCase(),\n `MODULATION:${receiver},${normalizedMode}`,\n options,\n );\n }\n\n async getMode(receiver = this.options.receiver): Promise<string | undefined> {\n const reply = await this.request('MODULATION', [receiver]);\n const mode = reply.args.length >= 3 ? reply.args[2] : reply.args[1];\n return (mode ?? this.state.modes[rxVfoKey(receiver, this.options.vfo)])?.toLowerCase();\n }\n\n async setPtt(enabled: boolean, options: TciPttOptions = {}): Promise<void> {\n const trx = options.trx ?? this.options.trx;\n if (options.source && !this.requireDialect().supportsTxAudioSource) {\n throw new TciError('protocol-error', `TCI dialect ${this.requireDialect().id} does not support a TRX audio source argument`);\n }\n const args = options.source ? [trx, enabled, options.source] : [trx, enabled];\n await this.sendStateWrite(\n 'TRX',\n args,\n (state) => state.ptt[String(trx)] === enabled,\n `TRX:${trx},${enabled}`,\n options,\n );\n }\n\n async getPtt(trx = this.options.trx): Promise<boolean | undefined> {\n const reply = await this.request('TRX', [trx]);\n return parseBoolean(reply.args[1]) ?? this.state.ptt[String(trx)];\n }\n\n async setTune(enabled: boolean, trx = this.options.trx, options: TciWriteOptions = {}): Promise<void> {\n try {\n await this.sendStateWrite(\n 'TUNE',\n [trx, enabled],\n (state) => state.tune[String(trx)] === enabled,\n `TUNE:${trx},${enabled}`,\n options,\n );\n } catch (error) {\n if (!(error instanceof TciError) || error.code !== 'command-timeout') throw error;\n await this.request('TUNE', [trx], { timeoutMs: options.timeoutMs });\n if (this.state.tune[String(trx)] !== enabled) throw error;\n }\n }\n\n async setDrive(value: number, trx = this.options.trx): Promise<void> {\n await this.setDriveWithResult(value, trx);\n }\n\n async setDriveWithResult(value: number, trx = this.options.trx, options: TciWriteOptions = {}): Promise<TciWriteResult<number>> {\n const requested = normalizePercent(value);\n const dialect = this.requireDialect();\n if (this.state.drive[String(trx)] === requested) {\n return writeResult(requested, requested, 'state');\n }\n\n const timeoutMs = options.timeoutMs ?? this.options.writeTimeoutMs;\n const waiter = this.waitForCommand(\n (command) => command.name === 'drive' && dialect.parseDrive(command.args, trx)?.trx === trx,\n Math.min(500, timeoutMs),\n `DRIVE state for TRX ${trx}`,\n );\n await this.sendCommand('DRIVE', dialect.buildDriveSetArgs(trx, requested), { waitForReply: false });\n try {\n const command = await waiter.promise;\n const applied = dialect.parseDrive(command.args, trx)?.value;\n if (applied !== undefined) return writeResult(requested, applied, 'state');\n } catch (error) {\n if (!(error instanceof TciError) || error.code !== 'command-timeout') throw error;\n } finally {\n waiter.cancel();\n }\n\n const reply = await this.request('DRIVE', dialect.buildDriveReadArgs(trx), {\n timeoutMs: Math.max(1, timeoutMs - Math.min(500, timeoutMs)),\n });\n const applied = dialect.parseDrive(reply.args, trx)?.value;\n if (applied === undefined) throw new TciError('protocol-error', `Invalid DRIVE readback: ${reply.raw}`);\n return writeResult(requested, applied, 'readback');\n }\n\n async getDrive(trx = this.options.trx): Promise<number | undefined> {\n const dialect = this.requireDialect();\n const reply = await this.request('DRIVE', dialect.buildDriveReadArgs(trx));\n return dialect.parseDrive(reply.args, trx)?.value ?? this.state.drive[String(trx)];\n }\n\n async setTuneDrive(value: number, trx = this.options.trx, options: TciWriteOptions = {}): Promise<TciWriteResult<number>> {\n const requested = normalizePercent(value);\n const dialect = this.requireDialect();\n if (this.state.tuneDrive[String(trx)] === requested) return writeResult(requested, requested, 'state');\n const timeoutMs = options.timeoutMs ?? this.options.writeTimeoutMs;\n const waiter = this.waitForCommand(\n (command) => command.name === 'tune_drive' && dialect.parseTuneDrive(command.args, trx)?.trx === trx,\n Math.min(500, timeoutMs),\n `TUNE_DRIVE state for TRX ${trx}`,\n );\n await this.sendCommand('TUNE_DRIVE', dialect.buildTuneDriveSetArgs(trx, requested), { waitForReply: false });\n try {\n const command = await waiter.promise;\n const applied = dialect.parseTuneDrive(command.args, trx)?.value;\n if (applied !== undefined) return writeResult(requested, applied, 'state');\n } catch (error) {\n if (!(error instanceof TciError) || error.code !== 'command-timeout') throw error;\n } finally {\n waiter.cancel();\n }\n const reply = await this.request('TUNE_DRIVE', dialect.buildTuneDriveReadArgs(trx), {\n timeoutMs: Math.max(1, timeoutMs - Math.min(500, timeoutMs)),\n });\n const applied = dialect.parseTuneDrive(reply.args, trx)?.value;\n if (applied === undefined) throw new TciError('protocol-error', `Invalid TUNE_DRIVE readback: ${reply.raw}`);\n return writeResult(requested, applied, 'readback');\n }\n\n async getTuneDrive(trx = this.options.trx): Promise<number | undefined> {\n const dialect = this.requireDialect();\n const reply = await this.request('TUNE_DRIVE', dialect.buildTuneDriveReadArgs(trx));\n return dialect.parseTuneDrive(reply.args, trx)?.value ?? this.state.tuneDrive[String(trx)];\n }\n\n async setSplit(enabled: boolean, trx = this.options.trx, options: TciWriteOptions = {}): Promise<void> {\n try {\n await this.sendStateWrite(\n 'SPLIT_ENABLE',\n [trx, enabled],\n (state) => state.split[String(trx)] === enabled,\n `SPLIT_ENABLE:${trx},${enabled}`,\n options,\n );\n } catch (error) {\n if (!(error instanceof TciError) || error.code !== 'command-timeout') throw error;\n await this.request('SPLIT_ENABLE', [trx], { timeoutMs: options.timeoutMs });\n if (this.state.split[String(trx)] !== enabled) throw error;\n }\n }\n\n async configureAudio(config: TciAudioConfig): Promise<void> {\n const dialect = this.requireDialect();\n const audio = {\n sampleRate: config.sampleRate,\n sampleType: normalizeSampleType(config.sampleType ?? TciSampleType.FLOAT32),\n channels: config.channels ?? 1,\n samplesPerFrame: config.samplesPerFrame ?? 512,\n txBufferingMs: config.txBufferingMs,\n running: this.state.audio?.running ?? false,\n };\n this.state.audio = audio;\n\n await this.sendCommand('AUDIO_SAMPLERATE', [audio.sampleRate], { waitForReply: false });\n if (dialect.supportsStreamChannels) {\n await this.sendCommand('AUDIO_STREAM_SAMPLE_TYPE', [sampleTypeName(audio.sampleType)], { waitForReply: false });\n await this.sendCommand('AUDIO_STREAM_CHANNELS', [audio.channels], { waitForReply: false });\n await this.sendCommand('AUDIO_STREAM_SAMPLES', [audio.samplesPerFrame], { waitForReply: false });\n if (audio.txBufferingMs !== undefined) {\n await this.sendCommand('TX_STREAM_AUDIO_BUFFERING', [audio.txBufferingMs], { waitForReply: false });\n }\n }\n this.emitState();\n }\n\n async startAudio(receiver = this.options.receiver): Promise<void> {\n await this.sendCommand('AUDIO_START', [receiver], { waitForReply: false });\n if (this.state.audio) {\n this.state.audio.running = true;\n this.emitState();\n }\n }\n\n async stopAudio(receiver = this.options.receiver): Promise<void> {\n await this.sendCommand('AUDIO_STOP', [receiver], { waitForReply: false });\n if (this.state.audio) {\n this.state.audio.running = false;\n this.emitState();\n }\n }\n\n sendTxAudio(options: BuildTxAudioFrameOptions): void {\n const frame = buildTxAudioFrame({\n receiver: this.options.receiver,\n lengthSemantics: this.requireDialect().streamLengthSemantics,\n ...options,\n });\n this.sendRawBinary(frame);\n }\n\n sendTxAudioForChrono(request: TciTxChronoRequest, samples: Float32Array | readonly number[]): void {\n const channels = Math.max(1, Math.floor(request.channels || 1));\n const targetSampleLength = Math.max(0, Math.floor(request.sampleCount));\n const output = new Float32Array(targetSampleLength);\n const source = samples instanceof Float32Array ? samples : Float32Array.from(samples);\n output.set(source.subarray(0, output.length));\n this.sendTxAudio({\n receiver: request.receiver,\n sampleRate: request.sampleRate,\n sampleType: request.sampleType,\n channels,\n samples: output,\n });\n }\n\n async setRxSensorsEnabled(enabled: boolean, intervalMs?: number): Promise<void> {\n const args = intervalMs === undefined ? [enabled] : [enabled, intervalMs];\n await this.sendCommand('RX_SENSORS_ENABLE', args, { waitForReply: false });\n }\n\n async setTxSensorsEnabled(enabled: boolean, intervalMs?: number): Promise<void> {\n const args = intervalMs === undefined ? [enabled] : [enabled, intervalMs];\n await this.sendCommand('TX_SENSORS_ENABLE', args, { waitForReply: false });\n }\n\n async sendCwMacro(index: number): Promise<void> {\n await this.sendCommand('CW_MACROS', [index]);\n }\n\n async sendCwMessage(message: string): Promise<void> {\n await this.sendCommand('CW_MSG', [message]);\n }\n\n async stopCw(): Promise<void> {\n await this.sendCommand('CW_MACROS_STOP');\n }\n\n private waitForState(\n predicate: (state: TciClientState) => boolean,\n timeoutMs: number,\n settleMs: number,\n description: string,\n ): { promise: Promise<void>; cancel: () => void } {\n let timeout: NodeJS.Timeout | undefined;\n let settleTimeout: NodeJS.Timeout | undefined;\n let resolved = false;\n let resolvePromise!: () => void;\n let rejectPromise!: (error: TciError) => void;\n\n const cleanup = () => {\n if (timeout) {\n clearTimeout(timeout);\n timeout = undefined;\n }\n if (settleTimeout) {\n clearTimeout(settleTimeout);\n settleTimeout = undefined;\n }\n this.off('state', onState);\n this.off('disconnected', onDisconnected);\n };\n\n const resolveNow = () => {\n resolved = true;\n cleanup();\n resolvePromise();\n };\n\n const check = () => {\n if (!predicate(this.getState())) {\n if (settleTimeout) {\n clearTimeout(settleTimeout);\n settleTimeout = undefined;\n }\n return;\n }\n\n if (settleMs <= 0) {\n resolveNow();\n return;\n }\n\n if (settleTimeout) {\n return;\n }\n\n settleTimeout = setTimeout(() => {\n settleTimeout = undefined;\n if (predicate(this.getState())) {\n resolveNow();\n }\n }, settleMs);\n };\n\n const onState = () => check();\n const onDisconnected = () => {\n if (resolved) {\n return;\n }\n cleanup();\n rejectPromise(new TciError('disconnected', `Disconnected while waiting for TCI state ${description}`));\n };\n\n const promise = new Promise<void>((resolve, reject) => {\n resolvePromise = resolve;\n rejectPromise = reject;\n timeout = setTimeout(() => {\n cleanup();\n reject(new TciError('command-timeout', `Timed out waiting for TCI state ${description}`));\n }, timeoutMs);\n this.on('state', onState);\n this.on('disconnected', onDisconnected);\n check();\n });\n\n return {\n promise,\n cancel: cleanup,\n };\n }\n\n private waitForCommand(\n predicate: (command: TciCommand) => boolean,\n timeoutMs: number,\n description: string,\n ): { promise: Promise<TciCommand>; cancel: () => void } {\n let timer: NodeJS.Timeout | undefined;\n let resolvePromise!: (command: TciCommand) => void;\n let rejectPromise!: (error: TciError) => void;\n const cleanup = () => {\n if (timer) clearTimeout(timer);\n timer = undefined;\n this.off('command', onCommand);\n this.off('disconnected', onDisconnected);\n };\n const onCommand = (command: TciCommand) => {\n if (!predicate(command)) return;\n cleanup();\n resolvePromise(command);\n };\n const onDisconnected = () => {\n cleanup();\n rejectPromise(new TciError('disconnected', `Disconnected while waiting for ${description}`));\n };\n const promise = new Promise<TciCommand>((resolve, reject) => {\n resolvePromise = resolve;\n rejectPromise = reject;\n timer = setTimeout(() => {\n cleanup();\n reject(new TciError('command-timeout', `Timed out waiting for ${description}`));\n }, timeoutMs);\n this.on('command', onCommand);\n this.on('disconnected', onDisconnected);\n });\n return { promise, cancel: cleanup };\n }\n\n private resetHandshake(): void {\n this.rejectHandshake(new TciError('cancelled', 'TCI handshake replaced by a new connection'));\n this.handshakeResult = undefined;\n this.handshakeError = undefined;\n this.activeDialect = undefined;\n this.initializationCommands = [];\n this.state.ready = false;\n this.state.protocol = undefined;\n this.state.protocolName = undefined;\n this.state.protocolVersion = undefined;\n this.state.dialectId = undefined;\n this.state.dialectConfidence = undefined;\n this.state.dialectWarnings = [];\n }\n\n private waitForHandshake(): Promise<TciHandshakeResult> {\n if (this.handshakeResult) return Promise.resolve(cloneHandshake(this.handshakeResult));\n if (this.handshakeError) return Promise.reject(this.handshakeError);\n if (this.handshakeWaiter) {\n return new Promise((resolve, reject) => {\n const onHandshake = (result: TciHandshakeResult) => { cleanup(); resolve(result); };\n const onError = (error: TciError) => { cleanup(); reject(error); };\n const cleanup = () => { this.off('handshake', onHandshake); this.off('error', onError); };\n this.once('handshake', onHandshake);\n this.once('error', onError);\n });\n }\n return new Promise<TciHandshakeResult>((resolve, reject) => {\n const timer = setTimeout(() => {\n const error = new TciError('handshake-timeout', `Timed out waiting for TCI READY from ${this.options.url}`);\n this.handshakeWaiter = undefined;\n reject(error);\n }, this.options.handshakeTimeoutMs);\n this.handshakeWaiter = { resolve, reject, timer };\n });\n }\n\n private finalizeHandshake(): TciHandshakeResult {\n if (this.handshakeResult) return this.handshakeResult;\n assertValidTciHandshake(this.initializationCommands);\n const identity = parseProtocolIdentity(this.initializationCommands);\n const commandNames = [...new Set(this.initializationCommands.map((command) => command.name))];\n const dialect = this.dialectRegistry.select(\n { identity, commands: this.initializationCommands, commandNames: new Set(commandNames) },\n this.options.dialect,\n );\n const result: TciHandshakeResult = { identity, dialect, ready: true, commandNames };\n this.handshakeResult = result;\n this.activeDialect = dialect.dialect;\n this.state.protocolName = identity.programName;\n this.state.protocolVersion = identity.protocolVersion;\n this.state.protocol = identity.protocolVersion ?? identity.programName;\n this.state.device = identity.device ?? this.state.device;\n this.state.dialectId = dialect.dialect.id;\n this.state.dialectConfidence = dialect.confidence;\n this.state.dialectWarnings = [...dialect.warnings];\n const waiter = this.handshakeWaiter;\n this.handshakeWaiter = undefined;\n if (waiter) {\n clearTimeout(waiter.timer);\n waiter.resolve(cloneHandshake(result));\n }\n this.emit('handshake', cloneHandshake(result));\n return result;\n }\n\n private rejectHandshake(error: TciError): void {\n const waiter = this.handshakeWaiter;\n this.handshakeWaiter = undefined;\n if (!waiter) return;\n clearTimeout(waiter.timer);\n waiter.reject(error);\n }\n\n private requireDialect(): TciDialect {\n if (!this.activeDialect) throw new TciError('invalid-handshake', 'TCI dialect is not available before READY');\n return this.activeDialect;\n }\n\n private attachTransport(transport: TciTransport): void {\n transport.on('text', (raw) => this.handleText(raw));\n transport.on('binary', (raw) => this.handleBinary(raw));\n transport.on('disconnected', (reason) => this.handleClose(reason));\n transport.on('error', (error) => this.handleError(error));\n }\n\n private async sendRaw(raw: string): Promise<void> {\n const transport = this.transport;\n if (!transport?.isConnected()) {\n throw new TciError('not-connected', 'TCI socket is not connected');\n }\n this.emit('tci:tx', raw);\n await transport.sendText(raw);\n }\n\n private sendRawBinary(raw: Buffer): void {\n const transport = this.transport;\n if (!transport?.isConnected()) {\n throw new TciError('not-connected', 'TCI socket is not connected');\n }\n void transport.sendBinary(raw).catch((error) => this.handleError(error));\n }\n\n private handleText(raw: string): void {\n try {\n const commands = parseTciText(raw);\n const receivedAtMs = Date.now();\n this.emit('tci:rx', raw, commands);\n for (const command of commands) {\n if (!this.handshakeResult) this.initializationCommands.push(command);\n this.queue.handleCommand(command);\n this.applyCommand(command);\n this.activeMeterSession?._acceptCommand(command, receivedAtMs);\n this.emit('command', command);\n }\n } catch (error) {\n this.handleError(error);\n }\n }\n\n private handleBinary(data: Buffer): void {\n const frame = parseStreamFrame(data, {\n lengthSemantics: this.requireDialect().streamLengthSemantics,\n negotiatedChannels: this.state.audio?.channels,\n });\n this.emit('tci:binary', frame);\n this.emit('binary', frame);\n switch (frame.streamType) {\n case TciStreamType.IQ_STREAM: {\n if (frame.channels !== 2 || frame.sampleCount % 2 !== 0) {\n throw new TciError('invalid-frame', 'TCI IQ stream frame must contain interleaved I/Q pairs');\n }\n this.state.iq.sampleRate = frame.sampleRate;\n const iqFrame: TciIqFrame = {\n frame,\n receiver: frame.receiver,\n sampleRate: frame.sampleRate,\n centerFrequency: this.state.dds[String(frame.receiver)],\n complexSampleCount: frame.frameCount,\n };\n this.emit('iqFrame', iqFrame);\n this.activeIqSession?._acceptFrame(iqFrame);\n break;\n }\n case TciStreamType.RX_AUDIO_STREAM:\n this.emit('rxAudioFrame', frame);\n break;\n case TciStreamType.TX_CHRONO:\n this.emit('txChrono', {\n frame,\n receiver: frame.receiver,\n sampleRate: frame.sampleRate,\n channels: frame.channels,\n sampleType: frame.sampleType,\n sampleCount: frame.sampleCount,\n frameCount: frame.frameCount,\n });\n break;\n case TciStreamType.LINEOUT_STREAM:\n this.emit('lineoutAudioFrame', frame);\n break;\n default:\n break;\n }\n }\n\n private applyCommand(command: TciCommand): void {\n const readyBefore = this.state.ready;\n this.stateReducers.get(command.name)?.(command.args);\n\n if (!readyBefore && this.state.ready) {\n try {\n this.finalizeHandshake();\n this.emit('ready', this.getState());\n } catch (error) {\n const tciError = toTciError(error, 'invalid-handshake');\n this.handshakeError = tciError;\n this.state.ready = false;\n this.rejectHandshake(tciError);\n this.handleError(tciError);\n }\n }\n this.emitState();\n }\n\n private createStateReducers(): Map<string, (args: string[]) => void> {\n const reducers = new Map<string, (args: string[]) => void>();\n reducers.set('ready', (args) => {\n this.state.ready = args.length === 0 ? true : (parseBoolean(args[0]) ?? true);\n });\n reducers.set('protocol', (args) => {\n if (/^\\d+(?:\\.\\d+){0,2}/.test(args[0] ?? '')) {\n this.state.protocol = args[0];\n this.state.protocolVersion = args[0];\n } else {\n this.state.protocolName = args[0];\n this.state.protocolVersion = args[1];\n this.state.protocol = args[1] ?? args[0];\n }\n });\n reducers.set('device', (args) => { this.state.device = args.join(','); });\n reducers.set('receive_only', (args) => { this.state.receiveOnly = parseBoolean(args[0]); });\n reducers.set('trx_count', (args) => { this.state.trxCount = parseNumber(args[0]); });\n const channelCount = (args: string[]) => { this.state.channelCount = parseNumber(args[0]); };\n reducers.set('channels_count', channelCount);\n reducers.set('channel_count', channelCount);\n reducers.set('vfo_limits', (args) => { this.state.vfoLimits = parseNumberPair(args); });\n reducers.set('if_limits', (args) => { this.state.ifLimits = parseNumberPair(args); });\n reducers.set('modulations_list', (args) => { this.state.modulations = args.map((mode) => mode.toLowerCase()); });\n reducers.set('vfo', (args) => this.applyVfo(args));\n reducers.set('dds', (args) => {\n const receiver = parseNumber(args[0]);\n const frequency = parseNumber(args[1]);\n if (receiver !== undefined && frequency !== undefined && frequency >= 0) this.state.dds[String(receiver)] = frequency;\n });\n reducers.set('modulation', (args) => this.applyModulation(args));\n reducers.set('trx', (args) => this.applyTrx(args));\n reducers.set('tune', (args) => this.applyBooleanByFirstArg(this.state.tune, args));\n reducers.set('drive', (args) => this.applyDrive(args));\n reducers.set('tune_drive', (args) => this.applyTuneDrive(args));\n reducers.set('split_enable', (args) => this.applyBooleanByFirstArg(this.state.split, args));\n reducers.set('rx_channel_sensors', (args) => this.applyRxChannelSensors(args));\n reducers.set('rx_channel_sensors_ex', (args) => this.applyRxChannelSensors(args));\n reducers.set('rx_sensors', (args) => this.applyRxSensors(args));\n reducers.set('tx_sensors', (args) => this.applyTxSensors(args));\n reducers.set('audio_samplerate', (args) => this.updateAudioState({ sampleRate: parseNumber(args[0]) }));\n reducers.set('audio_stream_sample_type', (args) => this.updateAudioState({ sampleType: parseSampleType(args[0]) }));\n reducers.set('audio_stream_channels', (args) => this.updateAudioState({ channels: parseNumber(args[0]) }));\n reducers.set('audio_stream_samples', (args) => this.updateAudioState({ samplesPerFrame: parseNumber(args[0]) }));\n reducers.set('tx_stream_audio_buffering', (args) => this.updateAudioState({ txBufferingMs: parseNumber(args[0]) }));\n reducers.set('audio_start', () => this.updateAudioState({ running: true }));\n reducers.set('audio_stop', () => this.updateAudioState({ running: false }));\n reducers.set('iq_samplerate', (args) => { this.state.iq.sampleRate = parseNumber(args[0]); });\n reducers.set('iq_start', (args) => { this.state.iq.activeReceivers[String(args[0] ?? this.options.receiver)] = true; });\n reducers.set('iq_stop', (args) => { this.state.iq.activeReceivers[String(args[0] ?? this.options.receiver)] = false; });\n return reducers;\n }\n\n private applyVfo(args: string[]): void {\n if (args.length < 3) {\n return;\n }\n const receiver = parseNumber(args[0]);\n const vfo = parseNumber(args[1]);\n const frequency = parseNumber(args[2]);\n if (receiver === undefined || vfo === undefined || frequency === undefined || frequency < 0) {\n return;\n }\n this.state.frequencies[rxVfoKey(receiver, vfo)] = frequency;\n }\n\n private applyModulation(args: string[]): void {\n if (args.length < 2) {\n return;\n }\n const receiver = parseNumber(args[0]);\n if (receiver === undefined) {\n return;\n }\n const vfo = args.length >= 3 ? parseNumber(args[1]) ?? this.options.vfo : this.options.vfo;\n const mode = args.length >= 3 ? args[2] : args[1];\n if (!mode) {\n return;\n }\n this.state.modes[rxVfoKey(receiver, vfo)] = mode.toLowerCase();\n }\n\n private applyTrx(args: string[]): void {\n if (args.length < 2) {\n return;\n }\n const trx = args[0] ?? String(this.options.trx);\n this.state.ptt[trx] = parseBoolean(args[1]) ?? false;\n this.state.pttSource[trx] = args[2]?.toLowerCase();\n }\n\n private applyBooleanByFirstArg(target: Record<string, boolean>, args: string[]): void {\n if (args.length < 2) {\n return;\n }\n const key = args[0] ?? '0';\n const value = parseBoolean(args[1]);\n if (value !== undefined) {\n target[key] = value;\n }\n }\n\n private applyDrive(args: string[]): void {\n const parsed = this.activeDialect?.parseDrive(args, this.options.trx)\n ?? parseObservedDrive(args, this.options.trx);\n if (parsed) this.state.drive[String(parsed.trx)] = parsed.value;\n }\n\n private applyTuneDrive(args: string[]): void {\n const parsed = this.activeDialect?.parseTuneDrive(args, this.options.trx)\n ?? parseObservedDrive(args, this.options.trx);\n if (parsed) this.state.tuneDrive[String(parsed.trx)] = parsed.value;\n }\n\n private updateAudioState(update: Partial<NonNullable<TciClientState['audio']>>): void {\n this.state.audio = {\n sampleRate: update.sampleRate ?? this.state.audio?.sampleRate ?? 12_000,\n sampleType: update.sampleType ?? this.state.audio?.sampleType ?? TciSampleType.FLOAT32,\n channels: update.channels ?? this.state.audio?.channels ?? 1,\n samplesPerFrame: update.samplesPerFrame ?? this.state.audio?.samplesPerFrame ?? 512,\n txBufferingMs: update.txBufferingMs ?? this.state.audio?.txBufferingMs,\n running: update.running ?? this.state.audio?.running ?? false,\n };\n }\n\n private applyRxChannelSensors(args: string[]): void {\n if (args.length < 3) {\n return;\n }\n const key = rxVfoKey(args[0], args[1]);\n this.state.rxSensors[key] = {\n receiver: args[0],\n channel: args[1],\n levelDbm: parseNumber(args[2]) ?? args[2],\n };\n }\n\n private applyRxSensors(args: string[]): void {\n if (args.length < 2) {\n return;\n }\n this.state.rxSensors[String(args[0])] = {\n receiver: args[0],\n levelDbm: parseNumber(args[1]) ?? args[1],\n deprecated: true,\n };\n }\n\n private applyTxSensors(args: string[]): void {\n if (args.length < 2) {\n return;\n }\n this.state.txSensors[String(args[0])] = {\n trx: args[0],\n micDbm: parseNumber(args[1]) ?? args[1],\n rmsPowerW: parseNumber(args[2]) ?? args[2],\n peakPowerW: parseNumber(args[3]) ?? args[3],\n swr: parseNumber(args[4]) ?? args[4],\n };\n }\n\n private handleClose(reason?: unknown): void {\n const transport = this.transport;\n this.transport = undefined;\n transport?.removeAllListeners();\n const wasConnected = this.state.connected;\n this.state.connected = false;\n this.state.ready = false;\n this.queue.setConnected(false);\n this.rejectHandshake(new TciError('disconnected', 'TCI connection closed during handshake', reason));\n this.activeIqSession?._fail(new TciError('disconnected', 'TCI connection closed while IQ stream was active', reason));\n this.activeIqSession = undefined;\n this.activeMeterSession?._fail(new TciError('disconnected', 'TCI connection closed while meter stream was active', reason));\n this.activeMeterSession = undefined;\n if (wasConnected) {\n this.emit('disconnected', reason);\n this.emitState();\n }\n }\n\n private handleError(error: unknown): void {\n const tciError = toTciError(error);\n this.emit('error', tciError);\n }\n\n private emitState(): void {\n this.emit('state', this.getState());\n }\n}\n\nexport function createTciClient(options: TciClientOptions): TciClient {\n return new TciClient(options);\n}\n\nfunction rxVfoKey(receiver: string | number, vfo: string | number): string {\n return `${receiver}:${vfo}`;\n}\n\nfunction parseNumber(value: string | undefined): number | undefined {\n if (value === undefined || value === '') {\n return undefined;\n }\n const number = Number(value);\n return Number.isFinite(number) ? number : undefined;\n}\n\nfunction normalizeNonNegativeInteger(value: number, description: string): number {\n if (!Number.isInteger(value) || value < 0) {\n throw new TciError('protocol-error', `Invalid TCI ${description}: ${value}`);\n }\n return value;\n}\n\nfunction parseBoolean(value: string | undefined): boolean | undefined {\n if (value === undefined) {\n return undefined;\n }\n const normalized = value.toLowerCase();\n if (normalized === 'true' || normalized === '1' || normalized === 'on') {\n return true;\n }\n if (normalized === 'false' || normalized === '0' || normalized === 'off') {\n return false;\n }\n return undefined;\n}\n\nfunction parseSampleType(value: string | undefined): TciSampleType | undefined {\n if (!value) return undefined;\n try { return normalizeSampleType(value.toLowerCase() as TciSampleTypeName); } catch { return undefined; }\n}\n\nfunction parseObservedDrive(args: readonly string[], defaultTrx: number): { trx: number; value: number } | undefined {\n const hasTrx = args.length >= 2;\n const trx = hasTrx ? parseNumber(args[0]) : defaultTrx;\n const value = parseNumber(args[hasTrx ? 1 : 0]);\n return trx === undefined || value === undefined ? undefined : { trx, value };\n}\n\nfunction normalizePercent(value: number): number {\n if (!Number.isFinite(value)) throw new TciError('protocol-error', `Invalid TCI percentage: ${value}`);\n return Math.round(Math.max(0, Math.min(100, value)));\n}\n\nfunction writeResult(\n requested: number,\n applied: number,\n acknowledgement: TciWriteResult<number>['acknowledgement'],\n): TciWriteResult<number> {\n return { requested, applied, outcome: requested === applied ? 'applied' : 'clamped', acknowledgement };\n}\n\nfunction parseNumberPair(args: string[]): [number, number] | undefined {\n const first = parseNumber(args[0]);\n const second = parseNumber(args[1]);\n return first === undefined || second === undefined ? undefined : [first, second];\n}\n\nfunction cloneState(state: TciClientState): TciClientState {\n return {\n ...state,\n modulations: [...state.modulations],\n frequencies: { ...state.frequencies },\n modes: { ...state.modes },\n ptt: { ...state.ptt },\n pttSource: { ...state.pttSource },\n tune: { ...state.tune },\n drive: { ...state.drive },\n tuneDrive: { ...state.tuneDrive },\n split: { ...state.split },\n dialectWarnings: [...state.dialectWarnings],\n rxSensors: cloneNested(state.rxSensors),\n txSensors: cloneNested(state.txSensors),\n audio: state.audio ? { ...state.audio } : undefined,\n iq: { ...state.iq, activeReceivers: { ...state.iq.activeReceivers } },\n dds: { ...state.dds },\n };\n}\n\nfunction cloneHandshake(result: TciHandshakeResult): TciHandshakeResult {\n return {\n identity: { ...result.identity, rawProtocolArgs: [...result.identity.rawProtocolArgs] },\n dialect: {\n ...result.dialect,\n evidence: [...result.dialect.evidence],\n warnings: [...result.dialect.warnings],\n },\n ready: true,\n commandNames: [...result.commandNames],\n };\n}\n\nfunction cloneNested<T>(value: Record<string, T>): Record<string, T> {\n return Object.fromEntries(Object.entries(value).map(([key, item]) => [key, { ...(item as Record<string, unknown>) } as T]));\n}\n","import { TciError } from '../errors.js';\nimport type { TciStreamLengthSemantics } from '../dialect/types.js';\n\nexport const TCI_STREAM_HEADER_BYTES = 16 * 4;\n\nexport enum TciStreamType {\n IQ_STREAM = 0,\n RX_AUDIO_STREAM = 1,\n TX_AUDIO_STREAM = 2,\n TX_CHRONO = 3,\n LINEOUT_STREAM = 4,\n}\n\nexport enum TciSampleType {\n INT16 = 0,\n INT24 = 1,\n INT32 = 2,\n FLOAT32 = 3,\n}\n\nexport type TciSampleTypeName = 'int16' | 'int24' | 'int32' | 'float32';\n\nexport interface TciStreamFrame {\n receiver: number;\n sampleRate: number;\n sampleType: TciSampleType;\n codec: number;\n crc: number;\n /** Byte length of the payload following the 64-byte TCI stream header. */\n payloadLength: number;\n streamType: TciStreamType;\n channels: number;\n reserved: number[];\n payload: Buffer;\n /** Raw Stream.length value from the wire header. */\n headerSampleCount: number;\n /** Canonical number of scalar sample values across all channels. */\n sampleCount: number;\n /** Number of sample frames, each containing `channels` scalar values. */\n frameCount: number;\n lengthSemantics: Exclude<TciStreamLengthSemantics, 'auto'>;\n}\n\nexport interface ParseStreamFrameOptions {\n lengthSemantics?: TciStreamLengthSemantics;\n negotiatedChannels?: number;\n}\n\nexport interface BuildStreamFrameOptions {\n receiver?: number;\n sampleRate: number;\n sampleType: TciSampleType | TciSampleTypeName;\n streamType: TciStreamType;\n channels: number;\n payload?: Buffer | Uint8Array | ArrayBuffer | ArrayBufferView;\n samples?: Float32Array | readonly number[];\n /** Explicit Stream.length value, used for header-only frames such as TX_CHRONO. */\n sampleCount?: number;\n lengthSemantics?: TciStreamLengthSemantics;\n codec?: number;\n crc?: number;\n reserved?: readonly number[];\n}\n\nexport interface BuildTxAudioFrameOptions extends Omit<BuildStreamFrameOptions, 'streamType'> {\n receiver?: number;\n}\n\nexport function parseStreamFrame(input: Buffer | ArrayBuffer | ArrayBufferView, options: ParseStreamFrameOptions = {}): TciStreamFrame {\n const buffer = toBuffer(input);\n if (buffer.byteLength < TCI_STREAM_HEADER_BYTES) {\n throw new TciError('invalid-frame', `TCI stream frame is shorter than ${TCI_STREAM_HEADER_BYTES} bytes`);\n }\n\n const view = new DataView(buffer.buffer, buffer.byteOffset, buffer.byteLength);\n const header = Array.from({ length: 16 }, (_, index) => view.getUint32(index * 4, true));\n const sampleType = normalizeSampleType(header[2]);\n const streamType = normalizeStreamType(header[6]);\n let channels = header[7] || options.negotiatedChannels || 0;\n const bytesPerSample = sampleTypeBytes(sampleType);\n const headerSampleCount = header[5];\n const actualPayloadLength = buffer.byteLength - TCI_STREAM_HEADER_BYTES;\n if (channels <= 0) {\n if (streamType === TciStreamType.TX_CHRONO && actualPayloadLength === 0) {\n channels = 1;\n } else {\n const inferredChannels = headerSampleCount > 0 ? actualPayloadLength / headerSampleCount / bytesPerSample : 1;\n if (!Number.isInteger(inferredChannels) || inferredChannels <= 0) {\n throw new TciError('invalid-frame', `Invalid TCI channel count: ${channels}`);\n }\n channels = inferredChannels;\n }\n }\n const payloadLength = actualPayloadLength;\n const alignedFrameBytes = bytesPerSample * channels;\n if (payloadLength % alignedFrameBytes !== 0) {\n throw new TciError('invalid-frame', 'TCI payload length is not aligned to sample type and channel count');\n }\n\n const actualScalarCount = payloadLength / bytesPerSample;\n const requestedSemantics = options.lengthSemantics ?? 'auto';\n const lengthSemantics = resolveLengthSemantics(\n requestedSemantics,\n streamType,\n headerSampleCount,\n actualScalarCount,\n channels,\n );\n const sampleCount = lengthSemantics === 'per-channel' ? headerSampleCount * channels : headerSampleCount;\n\n if (streamType !== TciStreamType.TX_CHRONO) {\n const expectedPayloadLength = sampleCount * bytesPerSample;\n if (payloadLength !== expectedPayloadLength) {\n throw new TciError(\n 'invalid-frame',\n `TCI stream frame length mismatch: header says ${headerSampleCount} samples using ${lengthSemantics} semantics (${expectedPayloadLength} payload bytes), got ${payloadLength}`,\n );\n }\n }\n\n if (sampleCount % channels !== 0) {\n throw new TciError('invalid-frame', `TCI scalar sample count ${sampleCount} is not divisible by ${channels} channels`);\n }\n\n return {\n receiver: header[0],\n sampleRate: header[1],\n sampleType,\n codec: header[3],\n crc: header[4],\n payloadLength,\n streamType,\n channels,\n reserved: header.slice(8),\n payload: buffer.subarray(TCI_STREAM_HEADER_BYTES),\n headerSampleCount,\n sampleCount,\n frameCount: sampleCount / channels,\n lengthSemantics,\n };\n}\n\nexport function buildStreamFrame(options: BuildStreamFrameOptions): Buffer {\n const sampleType = normalizeSampleType(options.sampleType);\n const payload = options.payload ? toBuffer(options.payload) : samplesToPayload(options.samples ?? [], sampleType);\n const channels = options.channels;\n if (channels <= 0) {\n throw new TciError('invalid-frame', `Invalid TCI channel count: ${channels}`);\n }\n const bytesPerSample = sampleTypeBytes(sampleType);\n if (payload.byteLength % (bytesPerSample * channels) !== 0) {\n throw new TciError('invalid-frame', 'TCI payload length is not aligned to sample type and channel count');\n }\n const derivedSampleCount = payload.byteLength / bytesPerSample;\n const sampleCount = options.sampleCount ?? derivedSampleCount;\n if (!Number.isInteger(sampleCount) || sampleCount < 0) {\n throw new TciError('invalid-frame', `Invalid TCI sample count: ${sampleCount}`);\n }\n if (payload.byteLength > 0 && sampleCount !== derivedSampleCount) {\n throw new TciError('invalid-frame', `Explicit scalar sample count ${sampleCount} does not match payload count ${derivedSampleCount}`);\n }\n if (sampleCount % channels !== 0) {\n throw new TciError('invalid-frame', `TCI scalar sample count ${sampleCount} is not divisible by ${channels} channels`);\n }\n const lengthSemantics = options.lengthSemantics === 'per-channel' ? 'per-channel' : 'scalar';\n const headerSampleCount = lengthSemantics === 'per-channel' ? sampleCount / channels : sampleCount;\n\n const frame = Buffer.alloc(TCI_STREAM_HEADER_BYTES + payload.byteLength);\n const view = new DataView(frame.buffer, frame.byteOffset, frame.byteLength);\n const reserved = options.reserved ?? [];\n const header = [\n options.receiver ?? 0,\n options.sampleRate,\n sampleType,\n options.codec ?? 0,\n options.crc ?? 0,\n headerSampleCount,\n options.streamType,\n channels,\n ...Array.from({ length: 8 }, (_, index) => reserved[index] ?? 0),\n ];\n header.forEach((value, index) => view.setUint32(index * 4, value >>> 0, true));\n payload.copy(frame, TCI_STREAM_HEADER_BYTES);\n return frame;\n}\n\nfunction resolveLengthSemantics(\n requested: TciStreamLengthSemantics,\n streamType: TciStreamType,\n headerSampleCount: number,\n actualScalarCount: number,\n channels: number,\n): Exclude<TciStreamLengthSemantics, 'auto'> {\n if (requested !== 'auto') return requested;\n if (streamType === TciStreamType.TX_CHRONO && actualScalarCount === 0) return 'scalar';\n if (actualScalarCount === headerSampleCount) return 'scalar';\n if (actualScalarCount === headerSampleCount * channels) return 'per-channel';\n return 'scalar';\n}\n\nexport function buildTxAudioFrame(options: BuildTxAudioFrameOptions): Buffer {\n return buildStreamFrame({ ...options, streamType: TciStreamType.TX_AUDIO_STREAM });\n}\n\nexport function sampleTypeBytes(sampleType: TciSampleType | TciSampleTypeName): number {\n switch (normalizeSampleType(sampleType)) {\n case TciSampleType.INT16:\n return 2;\n case TciSampleType.INT24:\n return 3;\n case TciSampleType.INT32:\n case TciSampleType.FLOAT32:\n return 4;\n default:\n throw new TciError('invalid-frame', `Unsupported TCI sample type: ${sampleType}`);\n }\n}\n\nexport function sampleTypeName(sampleType: TciSampleType): TciSampleTypeName {\n switch (sampleType) {\n case TciSampleType.INT16:\n return 'int16';\n case TciSampleType.INT24:\n return 'int24';\n case TciSampleType.INT32:\n return 'int32';\n case TciSampleType.FLOAT32:\n return 'float32';\n default:\n throw new TciError('invalid-frame', `Unsupported TCI sample type: ${sampleType}`);\n }\n}\n\nexport function normalizeSampleType(sampleType: TciSampleType | TciSampleTypeName | number): TciSampleType {\n if (typeof sampleType === 'string') {\n switch (sampleType.toLowerCase()) {\n case 'int16':\n return TciSampleType.INT16;\n case 'int24':\n return TciSampleType.INT24;\n case 'int32':\n return TciSampleType.INT32;\n case 'float32':\n return TciSampleType.FLOAT32;\n default:\n throw new TciError('invalid-frame', `Unsupported TCI sample type: ${sampleType}`);\n }\n }\n if (sampleType >= TciSampleType.INT16 && sampleType <= TciSampleType.FLOAT32) {\n return sampleType as TciSampleType;\n }\n throw new TciError('invalid-frame', `Unsupported TCI sample type: ${sampleType}`);\n}\n\nexport function normalizeStreamType(streamType: TciStreamType | number): TciStreamType {\n if (streamType >= TciStreamType.IQ_STREAM && streamType <= TciStreamType.LINEOUT_STREAM) {\n return streamType as TciStreamType;\n }\n throw new TciError('invalid-frame', `Unsupported TCI stream type: ${streamType}`);\n}\n\nexport function payloadToFloat32(frameOrPayload: TciStreamFrame | Buffer | Uint8Array, sampleType?: TciSampleType | TciSampleTypeName): Float32Array {\n const payload = isFrame(frameOrPayload) ? frameOrPayload.payload : toBuffer(frameOrPayload);\n const type = isFrame(frameOrPayload) ? frameOrPayload.sampleType : normalizeSampleType(sampleType ?? TciSampleType.FLOAT32);\n const bytes = sampleTypeBytes(type);\n if (payload.byteLength % bytes !== 0) {\n throw new TciError('invalid-frame', 'Payload length is not aligned to sample type');\n }\n\n const output = new Float32Array(payload.byteLength / bytes);\n const view = new DataView(payload.buffer, payload.byteOffset, payload.byteLength);\n for (let i = 0; i < output.length; i += 1) {\n const offset = i * bytes;\n switch (type) {\n case TciSampleType.INT16:\n output[i] = view.getInt16(offset, true) / 32768;\n break;\n case TciSampleType.INT24:\n output[i] = readInt24(view, offset) / 8388608;\n break;\n case TciSampleType.INT32:\n output[i] = view.getInt32(offset, true) / 2147483648;\n break;\n case TciSampleType.FLOAT32:\n output[i] = view.getFloat32(offset, true);\n break;\n }\n }\n return output;\n}\n\nexport function decodeInterleavedIq(frame: TciStreamFrame): Float32Array {\n if (frame.streamType !== TciStreamType.IQ_STREAM) {\n throw new TciError('invalid-frame', 'Expected a TCI IQ stream frame');\n }\n if (frame.channels !== 2 || frame.sampleCount % 2 !== 0) {\n throw new TciError('invalid-frame', `TCI IQ frame must contain interleaved I/Q pairs, got ${frame.channels} channels`);\n }\n return payloadToFloat32(frame);\n}\n\nexport function samplesToPayload(samples: Float32Array | readonly number[], sampleType: TciSampleType | TciSampleTypeName): Buffer {\n const type = normalizeSampleType(sampleType);\n const bytes = sampleTypeBytes(type);\n const payload = Buffer.alloc(samples.length * bytes);\n const view = new DataView(payload.buffer, payload.byteOffset, payload.byteLength);\n for (let i = 0; i < samples.length; i += 1) {\n const value = clampSample(samples[i] ?? 0);\n const offset = i * bytes;\n switch (type) {\n case TciSampleType.INT16:\n view.setInt16(offset, Math.round(value * 32767), true);\n break;\n case TciSampleType.INT24:\n writeInt24(view, offset, Math.round(value * 8388607));\n break;\n case TciSampleType.INT32:\n view.setInt32(offset, Math.round(value * 2147483647), true);\n break;\n case TciSampleType.FLOAT32:\n view.setFloat32(offset, value, true);\n break;\n }\n }\n return payload;\n}\n\nexport function pcm16ToFloat32(input: Buffer | Uint8Array | Int16Array): Float32Array {\n if (input instanceof Int16Array) {\n const output = new Float32Array(input.length);\n for (let i = 0; i < input.length; i += 1) {\n output[i] = input[i] / 32768;\n }\n return output;\n }\n return payloadToFloat32(toBuffer(input), TciSampleType.INT16);\n}\n\nexport function float32ToPcm16(samples: Float32Array | readonly number[]): Buffer {\n return samplesToPayload(samples, TciSampleType.INT16);\n}\n\nexport function deinterleaveChannels(samples: Float32Array, channels: number): Float32Array[] {\n if (channels <= 0 || samples.length % channels !== 0) {\n throw new TciError('invalid-frame', 'Cannot deinterleave samples with invalid channel count');\n }\n const frames = samples.length / channels;\n const outputs = Array.from({ length: channels }, () => new Float32Array(frames));\n for (let frame = 0; frame < frames; frame += 1) {\n for (let channel = 0; channel < channels; channel += 1) {\n outputs[channel][frame] = samples[frame * channels + channel];\n }\n }\n return outputs;\n}\n\nexport function mixToMono(samples: Float32Array, channels: number): Float32Array {\n if (channels === 1) {\n return samples;\n }\n const separated = deinterleaveChannels(samples, channels);\n const mono = new Float32Array(separated[0]?.length ?? 0);\n for (const channel of separated) {\n for (let i = 0; i < mono.length; i += 1) {\n mono[i] += channel[i] / channels;\n }\n }\n return mono;\n}\n\nfunction toBuffer(input: Buffer | Uint8Array | ArrayBuffer | ArrayBufferView): Buffer {\n if (Buffer.isBuffer(input)) {\n return input;\n }\n if (input instanceof ArrayBuffer) {\n return Buffer.from(input);\n }\n if (ArrayBuffer.isView(input)) {\n return Buffer.from(input.buffer, input.byteOffset, input.byteLength);\n }\n return Buffer.from(input);\n}\n\nfunction isFrame(value: unknown): value is TciStreamFrame {\n return Boolean(value && typeof value === 'object' && 'payload' in value && 'sampleType' in value);\n}\n\nfunction clampSample(value: number): number {\n if (!Number.isFinite(value)) {\n return 0;\n }\n return Math.max(-1, Math.min(1, value));\n}\n\nfunction readInt24(view: DataView, offset: number): number {\n const value = view.getUint8(offset) | (view.getUint8(offset + 1) << 8) | (view.getUint8(offset + 2) << 16);\n return value & 0x800000 ? value | 0xff000000 : value;\n}\n\nfunction writeInt24(view: DataView, offset: number, value: number): void {\n const clamped = Math.max(-8388608, Math.min(8388607, value));\n view.setUint8(offset, clamped & 0xff);\n view.setUint8(offset + 1, (clamped >> 8) & 0xff);\n view.setUint8(offset + 2, (clamped >> 16) & 0xff);\n}\n","export interface TciCommand {\n /** Lower-case command name for case-insensitive matching. */\n name: string;\n /** Original command name as received, without surrounding whitespace. */\n originalName: string;\n /** Unescaped argument list. Empty commands have an empty array. */\n args: string[];\n /** Raw command fragment without the trailing semicolon. */\n raw: string;\n}\n\nexport type TciCommandInput = string | TciCommand;\n\nconst ESCAPE_TO_CHAR: Record<string, string> = {\n '^': ':',\n '~': ',',\n '*': ';',\n};\n\nconst CHAR_TO_ESCAPE: Record<string, string> = {\n ':': '^',\n ',': '~',\n ';': '*',\n};\n\nexport function escapeTciText(value: unknown): string {\n return String(value).replace(/[:;,]/g, (char) => CHAR_TO_ESCAPE[char] ?? char);\n}\n\nexport function unescapeTciText(value: string): string {\n return value.replace(/[\\^~*]/g, (char) => ESCAPE_TO_CHAR[char] ?? char);\n}\n\nexport function parseTciText(text: string | Buffer | ArrayBuffer | ArrayBufferView): TciCommand[] {\n const source = normalizeTextInput(text);\n const commands: TciCommand[] = [];\n\n for (const fragment of source.split(';')) {\n const raw = fragment.trim();\n if (!raw) {\n continue;\n }\n\n const colonIndex = raw.indexOf(':');\n const originalName = (colonIndex >= 0 ? raw.slice(0, colonIndex) : raw).trim();\n if (!originalName) {\n continue;\n }\n\n const argsText = colonIndex >= 0 ? raw.slice(colonIndex + 1) : undefined;\n commands.push({\n name: originalName.toLowerCase(),\n originalName,\n args: argsText === undefined ? [] : splitArgs(argsText),\n raw,\n });\n }\n\n return commands;\n}\n\nexport function parseTciCommand(input: TciCommandInput): TciCommand {\n if (typeof input !== 'string') {\n return input;\n }\n const [command] = parseTciText(input);\n if (!command) {\n throw new Error(`Invalid TCI command: ${input}`);\n }\n return command;\n}\n\nexport function formatTciCommand(name: string, args: readonly unknown[] = []): string {\n const commandName = name.trim().toUpperCase();\n if (!commandName) {\n throw new Error('TCI command name cannot be empty');\n }\n if (args.length === 0) {\n return `${commandName};`;\n }\n return `${commandName}:${args.map(escapeTciText).join(',')};`;\n}\n\nexport function normalizeCommandName(name: string): string {\n return name.trim().toLowerCase();\n}\n\nexport function isCommandReplyTo(replyInput: TciCommandInput, requestInput: TciCommandInput): boolean {\n const reply = parseTciCommand(replyInput);\n const request = parseTciCommand(requestInput);\n if (reply.name !== request.name) {\n return false;\n }\n\n if (request.args.length === 0) {\n return true;\n }\n\n if (argsHavePrefix(reply.args, request.args)) {\n return true;\n }\n\n return isKnownVariantReply(reply, request);\n}\n\nexport function commandKey(command: TciCommandInput): string {\n const parsed = parseTciCommand(command);\n return `${parsed.name}:${parsed.args.join(',')}`;\n}\n\nfunction normalizeTextInput(text: string | Buffer | ArrayBuffer | ArrayBufferView): string {\n if (typeof text === 'string') {\n return text;\n }\n if (Buffer.isBuffer(text)) {\n return text.toString('utf8');\n }\n if (text instanceof ArrayBuffer) {\n return Buffer.from(text).toString('utf8');\n }\n return Buffer.from(text.buffer, text.byteOffset, text.byteLength).toString('utf8');\n}\n\nfunction splitArgs(argsText: string): string[] {\n return argsText.split(',').map((arg) => unescapeTciText(arg.trim()));\n}\n\nfunction argsHavePrefix(args: readonly string[], prefix: readonly string[]): boolean {\n if (args.length < prefix.length) {\n return false;\n }\n return prefix.every((arg, index) => args[index]?.toLowerCase() === arg.toLowerCase());\n}\n\nfunction isKnownVariantReply(reply: TciCommand, request: TciCommand): boolean {\n if (reply.name === 'modulation') {\n // ExpertSDR/WSJT-X variants can use MODULATION:rx,mode and MODULATION:rx,vfo,mode.\n if (request.args.length === 2 && reply.args.length >= 3) {\n return reply.args[0] === request.args[0] && reply.args[2]?.toLowerCase() === request.args[1]?.toLowerCase();\n }\n if (request.args.length === 3 && reply.args.length === 2) {\n return reply.args[0] === request.args[0] && reply.args[1]?.toLowerCase() === request.args[2]?.toLowerCase();\n }\n }\n\n if (reply.name === 'protocol') {\n return request.args.length <= 1;\n }\n\n if (reply.name === 'trx' && request.args.length >= 3 && reply.args.length >= 2) {\n // Official TRX writes may include an audio source as arg3, while replies only echo trx+state.\n return reply.args[0] === request.args[0] && reply.args[1]?.toLowerCase() === request.args[1]?.toLowerCase();\n }\n\n return false;\n}\n","import { TciError } from '../errors.js';\nimport {\n formatTciCommand,\n isCommandReplyTo,\n parseTciCommand,\n type TciCommand,\n type TciCommandInput,\n} from './text.js';\n\nexport type TciCommandMatcher = (reply: TciCommand, request: TciCommand) => boolean;\n\nexport interface QueueCommandOptions {\n timeoutMs?: number;\n matcher?: TciCommandMatcher;\n signal?: AbortSignal;\n}\n\nexport interface QueuedCommandResult {\n request: TciCommand;\n reply: TciCommand;\n}\n\ninterface PendingCommand {\n raw: string;\n request: TciCommand;\n timeoutMs: number;\n matcher: TciCommandMatcher;\n resolve: (result: QueuedCommandResult) => void;\n reject: (error: TciError) => void;\n timer?: NodeJS.Timeout;\n abortCleanup?: () => void;\n}\n\nexport interface TciCommandQueueOptions {\n send: (raw: string) => void | Promise<void>;\n timeoutMs?: number;\n}\n\nexport class TciCommandQueue {\n private readonly send: (raw: string) => void | Promise<void>;\n private readonly defaultTimeoutMs: number;\n private queue: PendingCommand[] = [];\n private active?: PendingCommand;\n private connected = true;\n\n constructor(options: TciCommandQueueOptions) {\n this.send = options.send;\n this.defaultTimeoutMs = options.timeoutMs ?? 1_000;\n }\n\n setConnected(connected: boolean): void {\n this.connected = connected;\n if (!connected) {\n this.cancelAll(new TciError('disconnected', 'TCI connection closed'));\n }\n }\n\n enqueue(command: TciCommandInput, options: QueueCommandOptions = {}): Promise<QueuedCommandResult> {\n const request = parseTciCommand(command);\n const raw = typeof command === 'string' ? ensureSemicolon(command) : formatTciCommand(command.originalName, command.args);\n\n if (!this.connected) {\n return Promise.reject(new TciError('not-connected', 'TCI socket is not connected'));\n }\n\n return new Promise<QueuedCommandResult>((resolve, reject) => {\n const pending: PendingCommand = {\n raw,\n request,\n timeoutMs: options.timeoutMs ?? this.defaultTimeoutMs,\n matcher: options.matcher ?? ((reply, req) => isCommandReplyTo(reply, req)),\n resolve,\n reject,\n };\n\n if (options.signal) {\n if (options.signal.aborted) {\n reject(new TciError('cancelled', 'TCI command was cancelled'));\n return;\n }\n const onAbort = () => this.rejectPending(pending, new TciError('cancelled', 'TCI command was cancelled'));\n options.signal.addEventListener('abort', onAbort, { once: true });\n pending.abortCleanup = () => options.signal?.removeEventListener('abort', onAbort);\n }\n\n this.queue.push(pending);\n void this.pump();\n });\n }\n\n handleCommand(commandInput: TciCommandInput): boolean {\n const active = this.active;\n if (!active) {\n return false;\n }\n const reply = parseTciCommand(commandInput);\n if (!active.matcher(reply, active.request)) {\n return false;\n }\n this.finishActive(reply);\n return true;\n }\n\n cancelAll(error = new TciError('cancelled', 'TCI command queue cancelled')): void {\n const pending = [...this.queue];\n this.queue = [];\n if (this.active) {\n pending.unshift(this.active);\n this.active = undefined;\n }\n for (const item of pending) {\n this.rejectPending(item, error);\n }\n }\n\n get size(): number {\n return this.queue.length + (this.active ? 1 : 0);\n }\n\n private async pump(): Promise<void> {\n if (this.active || !this.connected) {\n return;\n }\n const next = this.queue.shift();\n if (!next) {\n return;\n }\n\n this.active = next;\n next.timer = setTimeout(() => {\n this.rejectPending(next, new TciError('command-timeout', `Timed out waiting for TCI reply to ${next.raw}`));\n if (this.active === next) {\n this.active = undefined;\n }\n void this.pump();\n }, next.timeoutMs);\n\n try {\n await this.send(next.raw);\n } catch (error) {\n this.rejectPending(next, new TciError('disconnected', error instanceof Error ? error.message : String(error), error));\n if (this.active === next) {\n this.active = undefined;\n }\n void this.pump();\n }\n }\n\n private finishActive(reply: TciCommand): void {\n const active = this.active;\n if (!active) {\n return;\n }\n this.active = undefined;\n if (active.timer) {\n clearTimeout(active.timer);\n }\n active.abortCleanup?.();\n active.resolve({ request: active.request, reply });\n void this.pump();\n }\n\n private rejectPending(pending: PendingCommand, error: TciError): void {\n if (pending.timer) {\n clearTimeout(pending.timer);\n }\n pending.abortCleanup?.();\n const wasActive = this.active === pending;\n if (wasActive) {\n this.active = undefined;\n } else {\n this.queue = this.queue.filter((item) => item !== pending);\n }\n pending.reject(error);\n if (wasActive && this.connected) {\n void this.pump();\n }\n }\n}\n\nfunction ensureSemicolon(command: string): string {\n return command.trim().endsWith(';') ? command.trim() : `${command.trim()};`;\n}\n","import type { TciCommand } from '../protocol/index.js';\n\nexport type TciMeterSupport =\n | 'unknown'\n | 'declared'\n | 'acknowledged'\n | 'observed'\n | 'unsupported';\n\nexport interface TciMeterCapabilities {\n rxLevel: TciMeterSupport;\n rxAverageLevel: TciMeterSupport;\n rxPeakBin: TciMeterSupport;\n txMicLevel: TciMeterSupport;\n txRmsPower: TciMeterSupport;\n txPeakPower: TciMeterSupport;\n txSwr: TciMeterSupport;\n txAlcDbfs: TciMeterSupport;\n}\n\nexport type TciRxMeterSource = 'rx_sensors' | 'rx_channel_sensors' | 'rx_channel_sensors_ex';\n\nexport interface TciRxMeterFrame {\n receiver: number;\n channel: number;\n levelDbm: number;\n averageLevelDbm?: number;\n peakBinDbm?: number;\n source: TciRxMeterSource;\n receivedAtMs: number;\n extraArgs?: readonly string[];\n}\n\nexport interface TciTxMeterFrame {\n trx: number;\n micLevelDbm?: number;\n rmsPowerWatts?: number;\n peakPowerWatts?: number;\n swr?: number;\n alc?: { value: number; unit: 'dbfs' | 'percent' };\n receivedAtMs: number;\n extraArgs?: readonly string[];\n}\n\nexport interface TciMeterStreamOptions {\n receiver?: number;\n channel?: number;\n trx?: number;\n rx?: boolean;\n tx?: boolean;\n intervalMs?: number;\n}\n\nexport interface TciMeterInterval {\n requestedMs: number;\n appliedMs?: number;\n}\n\nexport interface TciMeterCommand {\n name: string;\n args: readonly unknown[];\n}\n\nexport type TciMeterDecodedFrame =\n | { kind: 'rx'; frame: TciRxMeterFrame }\n | { kind: 'tx'; frame: TciTxMeterFrame };\n\nexport interface TciMeterDecodeResult {\n decoded?: TciMeterDecodedFrame;\n issue?: string;\n}\n\nexport interface TciMeterAdapter {\n readonly declaredCapabilities: TciMeterCapabilities;\n normalizeInterval(intervalMs: number): TciMeterInterval;\n buildEnableCommand(kind: 'rx' | 'tx', enabled: boolean, intervalMs: number): TciMeterCommand;\n decode(command: TciCommand, receivedAtMs: number): TciMeterDecodeResult | undefined;\n}\n\nexport const UNKNOWN_TCI_METER_CAPABILITIES: TciMeterCapabilities = {\n rxLevel: 'unknown',\n rxAverageLevel: 'unknown',\n rxPeakBin: 'unknown',\n txMicLevel: 'unknown',\n txRmsPower: 'unknown',\n txPeakPower: 'unknown',\n txSwr: 'unknown',\n txAlcDbfs: 'unknown',\n};\n\nexport function cloneMeterCapabilities(capabilities: TciMeterCapabilities): TciMeterCapabilities {\n return { ...capabilities };\n}\n","import type { TciCommand } from '../protocol/index.js';\nimport {\n cloneMeterCapabilities,\n UNKNOWN_TCI_METER_CAPABILITIES,\n type TciMeterAdapter,\n type TciMeterCapabilities,\n type TciMeterDecodeResult,\n type TciMeterInterval,\n type TciRxMeterFrame,\n type TciTxMeterFrame,\n} from './types.js';\n\ninterface StandardTciMeterAdapterOptions {\n capabilities?: Partial<TciMeterCapabilities>;\n interval?: { minMs?: number; maxMs?: number; fixedMs?: number; reportsApplied?: boolean };\n supportsRxExtended?: boolean;\n txAlcUnit?: 'dbfs' | 'percent';\n}\n\nexport class StandardTciMeterAdapter implements TciMeterAdapter {\n readonly declaredCapabilities: TciMeterCapabilities;\n private readonly options: StandardTciMeterAdapterOptions;\n\n constructor(options: StandardTciMeterAdapterOptions = {}) {\n this.options = options;\n this.declaredCapabilities = {\n ...UNKNOWN_TCI_METER_CAPABILITIES,\n rxLevel: 'declared',\n txMicLevel: 'declared',\n txRmsPower: 'declared',\n txPeakPower: 'declared',\n txSwr: 'declared',\n rxAverageLevel: options.supportsRxExtended ? 'declared' : 'unknown',\n rxPeakBin: options.supportsRxExtended ? 'declared' : 'unknown',\n txAlcDbfs: options.txAlcUnit === 'dbfs' ? 'declared' : 'unknown',\n ...options.capabilities,\n };\n }\n\n normalizeInterval(intervalMs: number): TciMeterInterval {\n const requestedMs = Math.round(intervalMs);\n if (this.options.interval?.fixedMs !== undefined) {\n return { requestedMs, appliedMs: this.options.interval.fixedMs };\n }\n const minMs = this.options.interval?.minMs ?? requestedMs;\n const maxMs = this.options.interval?.maxMs ?? requestedMs;\n const normalized = Math.max(minMs, Math.min(maxMs, requestedMs));\n return {\n requestedMs,\n appliedMs: this.options.interval?.reportsApplied === false ? undefined : normalized,\n };\n }\n\n buildEnableCommand(kind: 'rx' | 'tx', enabled: boolean, intervalMs: number) {\n return {\n name: kind === 'rx' ? 'RX_SENSORS_ENABLE' : 'TX_SENSORS_ENABLE',\n args: enabled ? [true, intervalMs] : [false],\n };\n }\n\n decode(command: TciCommand, receivedAtMs: number): TciMeterDecodeResult | undefined {\n switch (command.name) {\n case 'rx_sensors':\n return decodeRx(command, receivedAtMs, 'rx_sensors');\n case 'rx_channel_sensors':\n return decodeRx(command, receivedAtMs, 'rx_channel_sensors');\n case 'rx_channel_sensors_ex':\n return decodeRx(command, receivedAtMs, 'rx_channel_sensors_ex');\n case 'tx_sensors':\n return decodeTx(command, receivedAtMs, this.options.txAlcUnit);\n default:\n return undefined;\n }\n }\n}\n\nexport function createUnknownTciMeterAdapter(): TciMeterAdapter {\n return new StandardTciMeterAdapter({\n capabilities: cloneMeterCapabilities(UNKNOWN_TCI_METER_CAPABILITIES),\n interval: { reportsApplied: false },\n });\n}\n\nfunction decodeRx(\n command: TciCommand,\n receivedAtMs: number,\n source: TciRxMeterFrame['source'],\n): TciMeterDecodeResult {\n const receiver = integer(command.args[0]);\n const hasChannel = source !== 'rx_sensors';\n const channel = hasChannel ? integer(command.args[1]) : 0;\n const levelIndex = hasChannel ? 2 : 1;\n const levelDbm = finite(command.args[levelIndex]);\n if (receiver === undefined || receiver < 0 || channel === undefined || channel < 0 || levelDbm === undefined) {\n return { issue: `Invalid ${command.originalName} meter frame: ${command.raw}` };\n }\n\n const frame: TciRxMeterFrame = { receiver, channel, levelDbm, source, receivedAtMs };\n if (source === 'rx_channel_sensors_ex') {\n const averageLevelDbm = finite(command.args[3]);\n const peakBinDbm = finite(command.args[4]);\n if (averageLevelDbm === undefined || peakBinDbm === undefined) {\n return { issue: `Invalid ${command.originalName} extended meter frame: ${command.raw}` };\n }\n frame.averageLevelDbm = averageLevelDbm;\n frame.peakBinDbm = peakBinDbm;\n if (command.args.length > 5) frame.extraArgs = command.args.slice(5);\n } else if (command.args.length > levelIndex + 1) {\n frame.extraArgs = command.args.slice(levelIndex + 1);\n }\n return { decoded: { kind: 'rx', frame } };\n}\n\nfunction decodeTx(\n command: TciCommand,\n receivedAtMs: number,\n alcUnit?: 'dbfs' | 'percent',\n): TciMeterDecodeResult {\n const trx = integer(command.args[0]);\n if (trx === undefined || trx < 0) {\n return { issue: `Invalid ${command.originalName} transmitter index: ${command.raw}` };\n }\n\n const micLevelDbm = optionalFinite(command.args[1]);\n const rmsPowerWatts = optionalFinite(command.args[2]);\n const peakPowerWatts = optionalFinite(command.args[3]);\n const swr = optionalFinite(command.args[4]);\n const alcValue = alcUnit ? optionalFinite(command.args[5]) : undefined;\n if (micLevelDbm.invalid || rmsPowerWatts.invalid || peakPowerWatts.invalid || swr.invalid || alcValue?.invalid) {\n return { issue: `Invalid ${command.originalName} numeric meter frame: ${command.raw}` };\n }\n if ((rmsPowerWatts.value !== undefined && rmsPowerWatts.value < 0)\n || (peakPowerWatts.value !== undefined && peakPowerWatts.value < 0)\n || (swr.value !== undefined && swr.value < 1)) {\n return { issue: `Out-of-range ${command.originalName} meter frame: ${command.raw}` };\n }\n if (micLevelDbm.value === undefined && rmsPowerWatts.value === undefined\n && peakPowerWatts.value === undefined && swr.value === undefined && alcValue?.value === undefined) {\n return { issue: `Empty ${command.originalName} meter frame: ${command.raw}` };\n }\n\n const frame: TciTxMeterFrame = {\n trx,\n micLevelDbm: micLevelDbm.value,\n rmsPowerWatts: rmsPowerWatts.value,\n peakPowerWatts: peakPowerWatts.value,\n swr: swr.value,\n receivedAtMs,\n };\n if (alcUnit && alcValue?.value !== undefined) frame.alc = { value: alcValue.value, unit: alcUnit };\n const knownArgs = alcUnit ? 6 : 5;\n if (command.args.length > knownArgs) frame.extraArgs = command.args.slice(knownArgs);\n return { decoded: { kind: 'tx', frame } };\n}\n\nfunction finite(value: string | undefined): number | undefined {\n if (value === undefined || value === '') return undefined;\n const parsed = Number(value);\n return Number.isFinite(parsed) ? parsed : undefined;\n}\n\nfunction integer(value: string | undefined): number | undefined {\n const parsed = finite(value);\n return parsed !== undefined && Number.isInteger(parsed) ? parsed : undefined;\n}\n\nfunction optionalFinite(value: string | undefined): { value?: number; invalid: boolean } {\n if (value === undefined || value === '') return { invalid: false };\n const parsed = Number(value);\n return Number.isFinite(parsed) ? { value: parsed, invalid: false } : { invalid: true };\n}\n","import { EventEmitter } from 'eventemitter3';\nimport { TciError } from '../errors.js';\nimport type { TciCommand } from '../protocol/index.js';\nimport {\n cloneMeterCapabilities,\n type TciMeterAdapter,\n type TciMeterCapabilities,\n type TciMeterSupport,\n type TciRxMeterFrame,\n type TciTxMeterFrame,\n} from './types.js';\n\nconst RX_COALESCE_MS = 20;\n\nexport interface TciMeterStreamEvents {\n rxFrame: (frame: TciRxMeterFrame) => void;\n txFrame: (frame: TciTxMeterFrame) => void;\n capabilitiesChanged: (capabilities: TciMeterCapabilities) => void;\n error: (error: TciError) => void;\n closed: () => void;\n}\n\ninterface TciMeterStreamCallbacks {\n close: () => Promise<void>;\n}\n\ninterface PendingRxFrame {\n frame: TciRxMeterFrame;\n timer: NodeJS.Timeout;\n}\n\nexport class TciMeterStreamSession extends EventEmitter<TciMeterStreamEvents> {\n readonly receiver: number;\n readonly channel: number;\n readonly trx: number;\n readonly requestedIntervalMs: number;\n readonly appliedIntervalMs?: number;\n readonly rxEnabled: boolean;\n readonly txEnabled: boolean;\n\n private readonly adapter: TciMeterAdapter;\n private readonly callbacks: TciMeterStreamCallbacks;\n private capabilities: TciMeterCapabilities;\n private readonly pendingRx = new Map<string, PendingRxFrame>();\n private closed = false;\n\n constructor(options: {\n receiver: number;\n channel: number;\n trx: number;\n requestedIntervalMs: number;\n appliedIntervalMs?: number;\n rxEnabled: boolean;\n txEnabled: boolean;\n adapter: TciMeterAdapter;\n callbacks: TciMeterStreamCallbacks;\n }) {\n super();\n this.receiver = options.receiver;\n this.channel = options.channel;\n this.trx = options.trx;\n this.requestedIntervalMs = options.requestedIntervalMs;\n this.appliedIntervalMs = options.appliedIntervalMs;\n this.rxEnabled = options.rxEnabled;\n this.txEnabled = options.txEnabled;\n this.adapter = options.adapter;\n this.callbacks = options.callbacks;\n this.capabilities = cloneMeterCapabilities(options.adapter.declaredCapabilities);\n }\n\n getCapabilities(): TciMeterCapabilities {\n return cloneMeterCapabilities(this.capabilities);\n }\n\n async close(): Promise<void> {\n if (this.closed) return;\n this.closed = true;\n this.clearPendingRx();\n try {\n await this.callbacks.close();\n } finally {\n this.emit('closed');\n this.removeAllListeners();\n }\n }\n\n _acceptCommand(command: TciCommand, receivedAtMs: number): void {\n if (this.closed) return;\n this.acceptEnableAcknowledgement(command);\n const result = this.adapter.decode(command, receivedAtMs);\n if (!result) return;\n if (result.issue) {\n this.emit('error', new TciError('protocol-error', result.issue));\n return;\n }\n if (result.decoded?.kind === 'rx') this.acceptRxFrame(result.decoded.frame);\n if (result.decoded?.kind === 'tx') this.acceptTxFrame(result.decoded.frame);\n }\n\n _fail(error: TciError): void {\n if (this.closed) return;\n this.closed = true;\n this.clearPendingRx();\n this.emit('error', error);\n this.emit('closed');\n this.removeAllListeners();\n }\n\n private acceptRxFrame(frame: TciRxMeterFrame): void {\n if (!this.rxEnabled || frame.receiver !== this.receiver || frame.channel !== this.channel) return;\n this.observe('rxLevel');\n if (frame.averageLevelDbm !== undefined) this.observe('rxAverageLevel');\n if (frame.peakBinDbm !== undefined) this.observe('rxPeakBin');\n\n const key = `${frame.receiver}:${frame.channel}`;\n const pending = this.pendingRx.get(key);\n if (pending) {\n const sameReading = Math.abs(pending.frame.levelDbm - frame.levelDbm) < 0.05;\n if (sameReading && rxPriority(frame) >= rxPriority(pending.frame)) {\n clearTimeout(pending.timer);\n this.pendingRx.delete(key);\n } else if (sameReading) {\n return;\n } else {\n this.flushRx(key, pending);\n }\n }\n const timer = setTimeout(() => {\n const current = this.pendingRx.get(key);\n if (current?.frame === frame) this.flushRx(key, current);\n }, RX_COALESCE_MS);\n this.pendingRx.set(key, { frame, timer });\n }\n\n private acceptTxFrame(frame: TciTxMeterFrame): void {\n if (!this.txEnabled || frame.trx !== this.trx) return;\n if (frame.micLevelDbm !== undefined) this.observe('txMicLevel');\n if (frame.rmsPowerWatts !== undefined) this.observe('txRmsPower');\n if (frame.peakPowerWatts !== undefined) this.observe('txPeakPower');\n if (frame.swr !== undefined) this.observe('txSwr');\n if (frame.alc?.unit === 'dbfs') this.observe('txAlcDbfs');\n this.emit('txFrame', frame);\n }\n\n private acceptEnableAcknowledgement(command: TciCommand): void {\n const enabled = command.args[0]?.toLowerCase();\n if (enabled !== 'true' && enabled !== '1' && enabled !== 'on') return;\n if (command.name === 'rx_sensors_enable' && this.rxEnabled) {\n this.acknowledge(['rxLevel']);\n }\n if (command.name === 'tx_sensors_enable' && this.txEnabled) {\n this.acknowledge(['txMicLevel', 'txRmsPower', 'txPeakPower', 'txSwr']);\n }\n }\n\n private acknowledge(keys: Array<keyof TciMeterCapabilities>): void {\n let changed = false;\n for (const key of keys) {\n if (supportRank(this.capabilities[key]) < supportRank('acknowledged')) {\n this.capabilities[key] = 'acknowledged';\n changed = true;\n }\n }\n if (changed) this.emit('capabilitiesChanged', this.getCapabilities());\n }\n\n private observe(key: keyof TciMeterCapabilities): void {\n if (this.capabilities[key] === 'observed') return;\n this.capabilities[key] = 'observed';\n this.emit('capabilitiesChanged', this.getCapabilities());\n }\n\n private flushRx(key: string, pending: PendingRxFrame): void {\n clearTimeout(pending.timer);\n if (this.pendingRx.get(key) === pending) this.pendingRx.delete(key);\n this.emit('rxFrame', pending.frame);\n }\n\n private clearPendingRx(): void {\n for (const pending of this.pendingRx.values()) clearTimeout(pending.timer);\n this.pendingRx.clear();\n }\n}\n\nfunction rxPriority(frame: TciRxMeterFrame): number {\n if (frame.source === 'rx_channel_sensors_ex') return 3;\n if (frame.source === 'rx_channel_sensors') return 2;\n return 1;\n}\n\nfunction supportRank(value: TciMeterSupport): number {\n switch (value) {\n case 'unsupported': return -1;\n case 'unknown': return 0;\n case 'declared': return 1;\n case 'acknowledged': return 2;\n case 'observed': return 3;\n }\n}\n","import type {\n TciDialect,\n TciDialectDetectionContext,\n TciDialectScore,\n TciDriveState,\n TciStreamLengthSemantics,\n} from './types.js';\nimport { StandardTciMeterAdapter, createUnknownTciMeterAdapter } from '../meter/index.js';\n\ntype VersionTuple = readonly number[];\n\ninterface StandardDialectOptions {\n id: TciDialect['id'];\n label: string;\n streamLengthSemantics: TciStreamLengthSemantics;\n supportsStreamChannels: boolean;\n supportsTxAudioSource: boolean;\n supportsIqStream: boolean;\n iqSampleRates: readonly number[];\n driveHasTrx: boolean;\n meterAdapter?: TciDialect['meterAdapter'];\n detect: (context: TciDialectDetectionContext) => TciDialectScore;\n resolve?: (context: TciDialectDetectionContext) => TciDialect;\n}\n\nclass StandardTciDialect implements TciDialect {\n readonly id: TciDialect['id'];\n readonly label: string;\n readonly streamLengthSemantics: TciStreamLengthSemantics;\n readonly supportsStreamChannels: boolean;\n readonly supportsTxAudioSource: boolean;\n readonly supportsIqStream: boolean;\n readonly iqSampleRates: readonly number[];\n readonly meterAdapter?: TciDialect['meterAdapter'];\n private readonly driveHasTrx: boolean;\n private readonly detector: StandardDialectOptions['detect'];\n private readonly resolver?: StandardDialectOptions['resolve'];\n\n constructor(options: StandardDialectOptions) {\n this.id = options.id;\n this.label = options.label;\n this.streamLengthSemantics = options.streamLengthSemantics;\n this.supportsStreamChannels = options.supportsStreamChannels;\n this.supportsTxAudioSource = options.supportsTxAudioSource;\n this.supportsIqStream = options.supportsIqStream;\n this.iqSampleRates = [...options.iqSampleRates];\n this.meterAdapter = options.meterAdapter;\n this.driveHasTrx = options.driveHasTrx;\n this.detector = options.detect;\n this.resolver = options.resolve;\n }\n\n detect(context: TciDialectDetectionContext): TciDialectScore {\n return this.detector(context);\n }\n\n resolve(context: TciDialectDetectionContext): TciDialect {\n return this.resolver?.(context) ?? this;\n }\n\n buildDriveSetArgs(trx: number, value: number): readonly unknown[] {\n return this.driveHasTrx ? [trx, value] : [value];\n }\n\n buildDriveReadArgs(trx: number): readonly unknown[] {\n return this.driveHasTrx ? [trx] : [];\n }\n\n parseDrive(args: readonly string[], defaultTrx: number): TciDriveState | undefined {\n return parseDriveState(args, defaultTrx, this.driveHasTrx);\n }\n\n buildTuneDriveSetArgs(trx: number, value: number): readonly unknown[] {\n return this.driveHasTrx ? [trx, value] : [value];\n }\n\n buildTuneDriveReadArgs(trx: number): readonly unknown[] {\n return this.driveHasTrx ? [trx] : [];\n }\n\n parseTuneDrive(args: readonly string[], defaultTrx: number): TciDriveState | undefined {\n return parseDriveState(args, defaultTrx, this.driveHasTrx);\n }\n}\n\nfunction parseDriveState(args: readonly string[], defaultTrx: number, hasTrx: boolean): TciDriveState | undefined {\n const trx = hasTrx ? Number(args[0]) : defaultTrx;\n const value = Number(args[hasTrx ? 1 : 0]);\n if (!Number.isInteger(trx) || !Number.isFinite(value)) return undefined;\n return { trx, value };\n}\n\nfunction version(context: TciDialectDetectionContext): VersionTuple | undefined {\n return parseTciVersion(context.identity.protocolVersion);\n}\n\nfunction programIncludes(context: TciDialectDetectionContext, value: string): boolean {\n return context.identity.programName?.toLowerCase().includes(value) ?? false;\n}\n\nexport const expertSdr14Dialect: TciDialect = new StandardTciDialect({\n id: 'expertsdr-1.4', label: 'ExpertSDR / TCI 1.4', streamLengthSemantics: 'per-channel',\n supportsStreamChannels: false, supportsTxAudioSource: false, supportsIqStream: true,\n iqSampleRates: [48_000, 96_000, 192_000, 384_000], driveHasTrx: false,\n meterAdapter: new StandardTciMeterAdapter({ interval: { reportsApplied: false } }),\n detect: (context) => {\n const parsed = version(context);\n if (!parsed || compareTciVersion(parsed, [1, 4]) > 0) return { score: 0, evidence: [] };\n return { score: 80 + (programIncludes(context, 'expert') ? 10 : 0), evidence: [`protocol ${formatVersion(parsed)} <= 1.4`] };\n },\n});\n\nexport const expertSdrLegacyDialect: TciDialect = new StandardTciDialect({\n id: 'expertsdr-1.5-1.8', label: 'ExpertSDR / TCI 1.5-1.8', streamLengthSemantics: 'per-channel',\n supportsStreamChannels: false, supportsTxAudioSource: false, supportsIqStream: true,\n iqSampleRates: [48_000, 96_000, 192_000, 384_000], driveHasTrx: true,\n meterAdapter: new StandardTciMeterAdapter({ interval: { reportsApplied: false } }),\n detect: (context) => {\n const parsed = version(context);\n if (!parsed || compareTciVersion(parsed, [1, 5]) < 0 || compareTciVersion(parsed, [1, 9]) >= 0) return { score: 0, evidence: [] };\n return { score: 80 + (programIncludes(context, 'expert') ? 10 : 0), evidence: [`protocol ${formatVersion(parsed)} is in 1.5-1.8`] };\n },\n});\n\nexport const expertSdrModernDialect: TciDialect = new StandardTciDialect({\n id: 'expertsdr-1.9-2.0', label: 'ExpertSDR / TCI 1.9-2.0', streamLengthSemantics: 'scalar',\n supportsStreamChannels: true, supportsTxAudioSource: true, supportsIqStream: true,\n iqSampleRates: [48_000, 96_000, 192_000, 384_000], driveHasTrx: true,\n meterAdapter: new StandardTciMeterAdapter({ interval: { reportsApplied: false } }),\n detect: (context) => {\n const parsed = version(context);\n if (!parsed || compareTciVersion(parsed, [1, 9]) < 0) return { score: 0, evidence: [] };\n const future = compareTciVersion(parsed, [2, 0]) > 0;\n return {\n score: 70 + (programIncludes(context, 'expert') ? 15 : 0),\n evidence: [`protocol ${formatVersion(parsed)} uses modern stream negotiation`],\n warnings: future ? [`Unknown future TCI version ${formatVersion(parsed)}; using the modern dialect`] : [],\n };\n },\n});\n\nexport const thetisDialect: TciDialect = new StandardTciDialect({\n id: 'thetis-2.0', label: 'Thetis / TCI 2.0', streamLengthSemantics: 'scalar',\n supportsStreamChannels: true, supportsTxAudioSource: true, supportsIqStream: true,\n iqSampleRates: [48_000, 96_000, 192_000, 384_000], driveHasTrx: true,\n meterAdapter: new StandardTciMeterAdapter({\n interval: { minMs: 30, maxMs: 1_000 },\n supportsRxExtended: true,\n }),\n detect: (context) => {\n const evidence: string[] = [];\n let score = 0;\n if (programIncludes(context, 'thetis')) { score += 120; evidence.push('PROTOCOL program is Thetis'); }\n const observed = ['tx_frequency_ex', 'tx_profiles_ex', 'tx_profile_ex', 'calibration_ex']\n .filter((name) => context.commandNames.has(name));\n if (observed.length > 0) { score += 100; evidence.push(`Thetis extension commands: ${observed.join(', ')}`); }\n if (/anan|hermes|orion|saturn/i.test(context.identity.device ?? '')) {\n score += 30;\n evidence.push(`Thetis-family device: ${context.identity.device}`);\n }\n return { score, evidence };\n },\n});\n\nexport const aetherSdrDialect: TciDialect = new StandardTciDialect({\n id: 'aethersdr-1.5', label: 'AetherSDR / TCI 1.5 hybrid', streamLengthSemantics: 'scalar',\n supportsStreamChannels: true, supportsTxAudioSource: true, supportsIqStream: true,\n iqSampleRates: [24_000, 48_000, 96_000, 192_000], driveHasTrx: true,\n meterAdapter: new StandardTciMeterAdapter({\n interval: { fixedMs: 200 },\n txAlcUnit: 'dbfs',\n }),\n detect: (context) => {\n if (!/^aethersdr$/i.test(context.identity.device ?? '')) return { score: 0, evidence: [] };\n const evidence = [`AetherSDR device identity: ${context.identity.device}`];\n const modernAudioCommands = ['audio_stream_sample_type', 'audio_stream_channels', 'audio_stream_samples']\n .filter((name) => context.commandNames.has(name));\n if (modernAudioCommands.length > 0) evidence.push(`Modern audio negotiation: ${modernAudioCommands.join(', ')}`);\n return {\n score: 150,\n evidence,\n warnings: context.identity.protocolVersion === '1.5'\n ? ['AetherSDR reports TCI 1.5 but uses modern scalar audio stream semantics']\n : [],\n };\n },\n});\n\nexport const genericObservedDialect: TciDialect = new StandardTciDialect({\n id: 'generic-observed', label: 'Generic observed TCI', streamLengthSemantics: 'auto',\n supportsStreamChannels: true, supportsTxAudioSource: true, supportsIqStream: false,\n iqSampleRates: [], driveHasTrx: true,\n meterAdapter: createUnknownTciMeterAdapter(),\n detect: (context) => ({\n score: context.commandNames.has('ready') ? 10 : 0,\n evidence: ['No vendor-specific match; using observed command shapes'],\n warnings: ['Dialect identity is uncertain'],\n }),\n resolve: (context) => {\n const drive = [...context.commands].reverse().find((command) => command.name === 'drive');\n const driveHasTrx = (drive?.args.length ?? 0) >= 2;\n return new StandardTciDialect({\n id: 'generic-observed',\n label: 'Generic observed TCI',\n streamLengthSemantics: 'auto',\n supportsStreamChannels: context.commandNames.has('audio_stream_channels'),\n supportsTxAudioSource: compareTciVersion(version(context) ?? [0], [2, 0]) >= 0,\n supportsIqStream: context.commandNames.has('iq_samplerate'),\n iqSampleRates: context.commandNames.has('iq_samplerate') ? [48_000] : [],\n driveHasTrx,\n meterAdapter: createUnknownTciMeterAdapter(),\n detect: genericObservedDialect.detect.bind(genericObservedDialect),\n });\n },\n});\n\nexport const builtInDialects: readonly TciDialect[] = [\n aetherSdrDialect, thetisDialect, expertSdr14Dialect, expertSdrLegacyDialect, expertSdrModernDialect, genericObservedDialect,\n];\n\nexport function parseTciVersion(value: string | undefined): VersionTuple | undefined {\n if (!value) return undefined;\n const match = value.trim().match(/^(\\d+)(?:\\.(\\d+))?(?:\\.(\\d+))?/);\n if (!match) return undefined;\n return match.slice(1).filter((part): part is string => part !== undefined).map(Number);\n}\n\nexport function compareTciVersion(left: VersionTuple, right: VersionTuple): number {\n const length = Math.max(left.length, right.length);\n for (let index = 0; index < length; index += 1) {\n const difference = (left[index] ?? 0) - (right[index] ?? 0);\n if (difference !== 0) return difference;\n }\n return 0;\n}\n\nfunction formatVersion(value: VersionTuple): string { return value.join('.'); }\n","import { TciError } from '../errors.js';\nimport { builtInDialects } from './builtins.js';\nimport type {\n TciDialect,\n TciDialectDetection,\n TciDialectDetectionContext,\n TciDialectId,\n TciDialectSelection,\n} from './types.js';\n\nexport class TciDialectRegistry {\n private readonly dialects = new Map<TciDialectId, TciDialect>();\n\n constructor(dialects: readonly TciDialect[] = builtInDialects) {\n for (const dialect of dialects) this.register(dialect);\n }\n\n register(dialect: TciDialect): void { this.dialects.set(dialect.id, dialect); }\n get(id: TciDialectId): TciDialect | undefined { return this.dialects.get(id); }\n list(): TciDialect[] { return [...this.dialects.values()]; }\n\n select(context: TciDialectDetectionContext, selection: TciDialectSelection = 'auto'): TciDialectDetection {\n if (typeof selection === 'object') {\n return { dialect: selection, confidence: 'manual', evidence: ['Custom dialect supplied by caller'], warnings: [] };\n }\n if (selection !== 'auto') {\n const dialect = this.get(selection);\n if (!dialect) throw new TciError('unknown-dialect', `Unknown TCI dialect: ${selection}`);\n return { dialect: dialect.resolve?.(context) ?? dialect, confidence: 'manual', evidence: [`Dialect ${selection} selected by caller`], warnings: [] };\n }\n\n const candidates = this.list()\n .map((dialect) => ({ dialect, result: dialect.detect(context) }))\n .sort((left, right) => right.result.score - left.result.score);\n const selected = candidates[0];\n if (!selected || selected.result.score <= 0) {\n throw new TciError('unknown-dialect', 'Unable to identify the TCI server dialect');\n }\n return {\n dialect: selected.dialect.resolve?.(context) ?? selected.dialect,\n confidence: selected.result.score >= 100 ? 'high' : selected.result.score >= 70 ? 'medium' : 'low',\n evidence: selected.result.evidence,\n warnings: selected.result.warnings ?? [],\n };\n }\n}\n\nexport const defaultTciDialectRegistry = new TciDialectRegistry();\n","import { TciError } from '../errors.js';\nimport type { TciCommand } from '../protocol/text.js';\nimport type { TciProtocolIdentity } from './types.js';\n\nconst IDENTITY_COMMANDS = new Set(['protocol', 'device', 'trx_count', 'channels_count', 'channel_count']);\nconst STATE_COMMANDS = new Set(['vfo', 'modulation', 'modulations_list', 'trx', 'drive']);\n\nexport function parseProtocolIdentity(commands: readonly TciCommand[]): TciProtocolIdentity {\n const protocol = [...commands].reverse().find((command) => command.name === 'protocol');\n const device = [...commands].reverse().find((command) => command.name === 'device');\n const rawProtocolArgs = protocol?.args ?? [];\n const firstLooksLikeVersion = /^\\d+(?:\\.\\d+){0,2}/.test(rawProtocolArgs[0] ?? '');\n return {\n programName: firstLooksLikeVersion ? undefined : rawProtocolArgs[0],\n protocolVersion: firstLooksLikeVersion ? rawProtocolArgs[0] : rawProtocolArgs[1],\n rawProtocolArgs: [...rawProtocolArgs],\n device: device?.args.join(','),\n };\n}\n\nexport function assertValidTciHandshake(commands: readonly TciCommand[]): void {\n const names = new Set(commands.map((command) => command.name));\n if (!names.has('ready')) throw new TciError('handshake-timeout', 'TCI READY was not received');\n const categories = [\n [...IDENTITY_COMMANDS].some((name) => names.has(name)),\n [...STATE_COMMANDS].some((name) => names.has(name)),\n ].filter(Boolean).length;\n const identitySignals = [...IDENTITY_COMMANDS].filter((name) => names.has(name)).length;\n if (categories < 2 && identitySignals < 2) {\n throw new TciError('invalid-handshake', 'WebSocket opened but did not provide enough TCI initialization evidence');\n }\n}\n","import { EventEmitter } from 'eventemitter3';\nimport WebSocket from 'ws';\nimport { TciError, toTciError } from '../errors.js';\nimport type { TciTransport, TciTransportEvents } from './types.js';\n\nexport class WebSocketTciTransport extends EventEmitter<TciTransportEvents> implements TciTransport {\n private socket?: WebSocket;\n\n constructor(readonly url: string, private readonly WebSocketImpl: typeof WebSocket = WebSocket) {\n super();\n }\n\n async connect(timeoutMs: number): Promise<void> {\n if (this.socket?.readyState === WebSocket.OPEN) return;\n const socket = new this.WebSocketImpl(this.url);\n this.socket = socket;\n await new Promise<void>((resolve, reject) => {\n const timer = setTimeout(() => {\n cleanup();\n this.terminate();\n reject(new TciError('connect-timeout', `Timed out connecting to ${this.url}`));\n }, timeoutMs);\n const cleanup = () => {\n clearTimeout(timer);\n socket.off('open', onOpen);\n socket.off('close', onCloseBeforeOpen);\n socket.off('error', onErrorBeforeOpen);\n };\n const onOpen = () => {\n cleanup();\n this.attach(socket);\n this.emit('connected');\n resolve();\n };\n const onCloseBeforeOpen = () => {\n cleanup();\n reject(new TciError('disconnected', `Disconnected while connecting to ${this.url}`));\n };\n const onErrorBeforeOpen = (error: Error) => {\n cleanup();\n reject(toTciError(error, 'disconnected'));\n };\n socket.once('open', onOpen);\n socket.once('close', onCloseBeforeOpen);\n socket.once('error', onErrorBeforeOpen);\n });\n }\n\n async disconnect(code = 1000, reason = 'client disconnect'): Promise<void> {\n const socket = this.socket;\n if (!socket || socket.readyState === WebSocket.CLOSED) return;\n await new Promise<void>((resolve) => {\n const timer = setTimeout(resolve, 1_000);\n timer.unref?.();\n socket.once('close', () => { clearTimeout(timer); resolve(); });\n socket.once('error', () => { clearTimeout(timer); resolve(); });\n socket.close(code, reason);\n });\n }\n\n isConnected(): boolean { return this.socket?.readyState === WebSocket.OPEN; }\n\n async sendText(raw: string): Promise<void> { await this.send(raw); }\n async sendBinary(raw: Buffer): Promise<void> { await this.send(raw, true); }\n\n terminate(): void {\n try { this.socket?.terminate(); } catch { /* ignore termination races */ }\n }\n\n private attach(socket: WebSocket): void {\n socket.on('message', (data, isBinary) => {\n try {\n const buffer = dataToBuffer(data);\n if (isBinary) this.emit('binary', buffer);\n else this.emit('text', buffer.toString('utf8'));\n } catch (error) {\n this.emit('error', error instanceof Error ? error : new Error(String(error)));\n }\n });\n socket.on('close', (code, reason) => {\n if (this.socket === socket) this.socket = undefined;\n this.emit('disconnected', { code, reason: reason.toString('utf8') });\n });\n socket.on('error', (error) => this.emit('error', error));\n }\n\n private async send(data: string | Buffer, binary = false): Promise<void> {\n const socket = this.socket;\n if (!socket || socket.readyState !== WebSocket.OPEN) {\n throw new TciError('not-connected', 'TCI socket is not connected');\n }\n await new Promise<void>((resolve, reject) => {\n socket.send(data, { binary }, (error) => error ? reject(error) : resolve());\n });\n }\n}\n\nfunction dataToBuffer(data: WebSocket.RawData): Buffer {\n if (Buffer.isBuffer(data)) return data;\n if (data instanceof ArrayBuffer) return Buffer.from(data);\n if (Array.isArray(data)) return Buffer.concat(data.map((item) => dataToBuffer(item)));\n throw new TciError('protocol-error', 'Unsupported WebSocket data type');\n}\n"],"mappings":"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","names":["EventEmitter","WebSocket","TciStreamType","TciSampleType","EventEmitter","EventEmitter","EventEmitter","WebSocket","applied"]}
|