UNPKG

@hangtime/grip-connect-cli

Version:
111 lines (99 loc) 3.49 kB
/** * `grip-connect watch [device]` -- streams force data indefinitely until * the user presses Esc. * * On exit, prints a summary of peak, mean, sample count, and elapsed time. */ import type { Command } from "commander" import pc from "picocolors" import type { ForceMeasurement, ForceUnit } from "../types.js" import { resolveDeviceKey, createDevice, resolveContext, outputJson, formatMeasurement, printHeader, setupSignalHandlers, waitForKeyToStop, fail, } from "../utils.js" import ora from "ora" /** * Registers the `watch` command on the Commander program. * * @param program - The root Commander program. */ export function registerWatch(program: Command): void { program .command("watch [device]") .description("Stream force data indefinitely (Esc to stop, then show summary)") .action(async (deviceKey: string | undefined) => { const ctx = resolveContext(program) const key = await resolveDeviceKey(deviceKey) const { device, name } = createDevice(key) let sampleCount = 0 let peak = 0 let sum = 0 let unit: ForceUnit = ctx.unit const startTime = Date.now() /** Print the session summary to stdout. */ const printSummary = () => { if (ctx.json) { outputJson({ summary: { samples: sampleCount, peak: +peak.toFixed(2), mean: sampleCount > 0 ? +(sum / sampleCount).toFixed(2) : 0, elapsed: Date.now() - startTime, unit, }, }) } else { const elapsed = ((Date.now() - startTime) / 1000).toFixed(1) const mean = sampleCount > 0 ? (sum / sampleCount).toFixed(2) : "0.00" console.log(`\n${pc.bold("Session summary")}`) console.log(pc.dim("─".repeat(40))) console.log(` ${pc.cyan("Samples:".padEnd(18))}${sampleCount}`) console.log(` ${pc.cyan("Peak:".padEnd(18))}${peak.toFixed(2)} ${unit}`) console.log(` ${pc.cyan("Mean:".padEnd(18))}${mean} ${unit}`) console.log(` ${pc.cyan("Elapsed:".padEnd(18))}${elapsed}s`) console.log(pc.dim("─".repeat(40))) } } device.notify((data: ForceMeasurement) => { sampleCount++ if (data.current > peak) peak = data.current sum += data.current unit = data.unit if (ctx.json) { outputJson(data) } else { console.log(formatMeasurement(data)) } }, ctx.unit) const spinner = ctx.json ? null : ora(`Connecting to ${pc.bold(name)}...`).start() try { await device.connect(async () => { spinner?.succeed(`Connected to ${pc.bold(name)}`) setupSignalHandlers(device, printSummary) const streamFn = device.stream if (typeof streamFn !== "function") { device.disconnect() fail("Stream not supported on this device.") } if (!ctx.json) { printHeader(`Watching ${name}`) } await streamFn(0) await waitForKeyToStop(ctx.json ? undefined : "Press Esc to stop and see summary") await device.stop?.() printSummary() }) } catch (error: unknown) { const message = error instanceof Error ? error.message : String(error) spinner?.fail(`Connection failed: ${message}`) fail(`Connection to ${name} failed: ${message}`) } }) }