{"version":3,"sources":["../src/wire-schemas.ts","../src/protocol.ts","../src/ros.ts","../src/topic.ts","../src/service.ts","../src/action-client.ts","../src/param.ts","../src/types.ts","../src/tf-client.ts"],"names":["z","parseRosMsgDefinition","bytes","MessageReader","MessageWriter","direct"],"mappings":"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","file":"index.cjs","sourcesContent":["/**\n * Zod schemas for the Foxglove WebSocket server→client text message ops.\n *\n * The WebSocket delivers each server-originated control message as JSON; we\n * validate the shape at the transport edge so the rest of the adapter can\n * work with properly typed values and never needs a type assertion to move\n * from `unknown` to a domain shape.\n *\n * Protocol spec: https://github.com/foxglove/ws-protocol/blob/main/docs/spec.md\n */\n\nimport { z } from \"zod\";\n\nconst channelSchema = z.object({\n  id: z.number(),\n  topic: z.string(),\n  encoding: z.string(),\n  schemaName: z.string(),\n  schema: z.string(),\n  schemaEncoding: z.string().optional()\n});\n\nconst serviceSchemaSide = z.object({\n  encoding: z.string().optional(),\n  schemaName: z.string().optional(),\n  schemaEncoding: z.string().optional(),\n  schema: z.string()\n});\n\nconst serviceSchema = z.object({\n  id: z.number(),\n  name: z.string(),\n  type: z.string(),\n  // Legacy flat form (foxglove.websocket.v1 bridges).\n  requestSchema: z.string().optional(),\n  responseSchema: z.string().optional(),\n  // foxglove.sdk.v1 nested form.\n  request: serviceSchemaSide.optional(),\n  response: serviceSchemaSide.optional()\n});\n\nconst parameterValueSchema = z.object({\n  name: z.string(),\n  value: z.unknown(),\n  type: z.string().optional()\n});\n\nconst serverInfoMessageSchema = z.object({\n  op: z.literal(\"serverInfo\"),\n  name: z.string(),\n  capabilities: z.array(z.string()),\n  supportedEncodings: z.array(z.string()).optional(),\n  metadata: z.record(z.string(), z.string()).optional(),\n  sessionId: z.string().optional()\n});\n\nconst advertiseMessageSchema = z.object({\n  op: z.literal(\"advertise\"),\n  channels: z.array(channelSchema)\n});\n\nconst unadvertiseMessageSchema = z.object({\n  op: z.literal(\"unadvertise\"),\n  channelIds: z.array(z.number())\n});\n\nconst advertiseServicesMessageSchema = z.object({\n  op: z.literal(\"advertiseServices\"),\n  services: z.array(serviceSchema)\n});\n\nconst unadvertiseServicesMessageSchema = z.object({\n  op: z.literal(\"unadvertiseServices\"),\n  serviceIds: z.array(z.number())\n});\n\nconst parameterValuesMessageSchema = z.object({\n  op: z.literal(\"parameterValues\"),\n  id: z.string().optional(),\n  parameters: z.array(parameterValueSchema)\n});\n\nconst statusMessageSchema = z.object({\n  op: z.literal(\"status\"),\n  level: z.number(),\n  message: z.string().optional(),\n  msg: z.string().optional()\n});\n\n// foxglove_bridge emits this when a service handler raises, when the service\n// has been unadvertised mid-call, or when the request payload is rejected.\n// Without it the pending call would hang forever.\nconst serviceCallFailureMessageSchema = z.object({\n  op: z.literal(\"serviceCallFailure\"),\n  serviceId: z.number(),\n  callId: z.number(),\n  message: z.string().optional()\n});\n\n/**\n * Discriminated union of every server→client text message we handle. Any\n * other `op` the server sends is tolerated silently (parsed as the `ignored`\n * variant) rather than erroring — future protocol additions shouldn't break\n * the session.\n */\nexport const serverMessageSchema = z.discriminatedUnion(\"op\", [\n  serverInfoMessageSchema,\n  advertiseMessageSchema,\n  unadvertiseMessageSchema,\n  advertiseServicesMessageSchema,\n  unadvertiseServicesMessageSchema,\n  parameterValuesMessageSchema,\n  statusMessageSchema,\n  serviceCallFailureMessageSchema\n]);\n","/**\n * Foxglove WebSocket protocol client.\n *\n * Implements the Foxglove WebSocket protocol for communicating with\n * foxglove_bridge. Handles channel advertisements, subscriptions, service\n * calls, and parameter operations.\n *\n * Two subprotocol negotiation strings exist in the wild with the same wire\n * format: `foxglove.websocket.v1` (legacy websocket_server-based builds) and\n * `foxglove.sdk.v1` (newer foxglove-sdk-cpp-based builds, including the\n * ros-humble-foxglove-bridge 3.2.x apt package). We advertise both so either\n * server accepts the handshake.\n *\n * Control-plane JSON messages (the server→client traffic handled here) are\n * validated via the zod schemas in `./wire-schemas` at the transport edge\n * so the rest of the adapter can work with properly typed values without\n * resorting to `as` casts. The authoritative wire format still lives in the\n * (archived) foxglove/ws-protocol spec, which is what ros-foxglove-bridge\n * 3.2.x continues to implement.\n */\n\nimport type { FoxgloveChannel, FoxgloveServerInfo, FoxgloveService } from \"./types\";\nimport { serverMessageSchema } from \"./wire-schemas\";\n\n// ─── Binary opcodes (server → client) ────────────────────────────────────────\nconst OP_MESSAGE_DATA = 0x01;\nconst OP_SERVICE_CALL_RESPONSE = 0x03;\n\n// ─── Binary opcodes (client → server) ────────────────────────────────────────\nconst OP_CLIENT_MESSAGE_DATA = 0x01;\nconst OP_CLIENT_SERVICE_CALL_REQUEST = 0x02;\nconst WEB_SOCKET_OPEN = 1;\n\n/** Creates the WebSocket used for a Foxglove connection. */\nexport type WebSocketFactory = (url: string, protocols: string[]) => WebSocket;\n\nexport interface ProtocolEvents {\n  serverInfo: (info: FoxgloveServerInfo) => void;\n  advertise: (channels: FoxgloveChannel[]) => void;\n  unadvertise: (channelIds: number[]) => void;\n  advertiseServices: (services: FoxgloveService[]) => void;\n  unadvertiseServices: (serviceIds: number[]) => void;\n  message: (subscriptionId: number, timestamp: bigint, data: Uint8Array) => void;\n  serviceResponse: (response: ServiceCallResponse) => void;\n  serviceCallFailure: (failure: ServiceCallFailure) => void;\n  parameterValues: (id: string, params: ParameterValue[]) => void;\n  open: () => void;\n  close: (event: CloseEvent) => void;\n  error: (error: Event) => void;\n}\n\nexport interface ParameterValue {\n  name: string;\n  value: unknown;\n  type?: string;\n}\n\nexport interface ServiceCallResponse {\n  serviceId: number;\n  callId: number;\n  encoding: string;\n  data: Uint8Array;\n}\n\nexport interface ServiceCallFailure {\n  serviceId: number;\n  callId: number;\n  message: string;\n}\n\n/**\n * One Set of handlers per event name. Keying the storage with a mapped type\n * over `ProtocolEvents` lets `add` / `delete` / iteration stay fully typed,\n * which is how we dispatch handlers in `emit` without a type assertion.\n */\ntype ProtocolEventHandlers = {\n  [K in keyof ProtocolEvents]: Set<ProtocolEvents[K]>;\n};\n\nexport class FoxgloveProtocolClient {\n  private ws: WebSocket | null = null;\n  private readonly handlers: ProtocolEventHandlers = {\n    serverInfo: new Set(),\n    advertise: new Set(),\n    unadvertise: new Set(),\n    advertiseServices: new Set(),\n    unadvertiseServices: new Set(),\n    message: new Set(),\n    serviceResponse: new Set(),\n    serviceCallFailure: new Set(),\n    parameterValues: new Set(),\n    open: new Set(),\n    close: new Set(),\n    error: new Set()\n  };\n  private nextSubscriptionId = 1;\n  private nextCallId = 1;\n  private nextClientChannelId = 1;\n\n  constructor(\n    private readonly webSocketFactory: WebSocketFactory = (url, protocols) =>\n      new WebSocket(url, protocols)\n  ) {}\n\n  connect(url: string): void {\n    this.close();\n    // Convert http/https URLs to ws/wss\n    const wsUrl = url.replace(/^http/, \"ws\");\n    this.ws = this.webSocketFactory(wsUrl, [\n      \"foxglove.sdk.v1\",\n      \"foxglove.websocket.v1\"\n    ]);\n    this.ws.binaryType = \"arraybuffer\";\n\n    this.ws.onopen = () => this.dispatch(this.handlers.open, (h) => h(), \"open\");\n    this.ws.onclose = (event) =>\n      this.dispatch(this.handlers.close, (h) => h(event), \"close\");\n    this.ws.onerror = (event) =>\n      this.dispatch(this.handlers.error, (h) => h(event), \"error\");\n    this.ws.onmessage = (event) => this.handleMessage(event);\n  }\n\n  close(): void {\n    const ws = this.ws;\n    if (!ws) return;\n    // Null the reference first so re-entry from a close handler is idempotent.\n    this.ws = null;\n    // Fire close synchronously before suppressing the socket's onclose, so\n    // reconnect doesn't silently drop the prior session's close event.\n    const closeEvent =\n      typeof CloseEvent === \"function\"\n        ? new CloseEvent(\"close\")\n        : ({\n            code: 1000,\n            reason: \"\",\n            wasClean: true\n          } as CloseEvent);\n    this.dispatch(this.handlers.close, (h) => h(closeEvent), \"close\");\n\n    ws.onopen = null;\n    ws.onclose = null;\n    ws.onerror = null;\n    ws.onmessage = null;\n    ws.close();\n  }\n\n  get isConnected(): boolean {\n    return this.ws?.readyState === WEB_SOCKET_OPEN;\n  }\n\n  // ─── Subscriptions ──────────────────────────────────────────────────────\n\n  subscribe(channelId: number): number {\n    const id = this.nextSubscriptionId++;\n    this.sendJson({\n      op: \"subscribe\",\n      subscriptions: [{ id, channelId }]\n    });\n    return id;\n  }\n\n  unsubscribe(subscriptionId: number): void {\n    this.sendJson({\n      op: \"unsubscribe\",\n      subscriptionIds: [subscriptionId]\n    });\n  }\n\n  // ─── Publishing ─────────────────────────────────────────────────────────\n\n  /**\n   * Advertise a channel this client will publish on, or return null while the\n   * socket is down. Caching an ID for an advertise frame that was never sent\n   * would strand every later publish on that topic until reconnect.\n   */\n  advertiseClientChannel(\n    topic: string,\n    encoding: string,\n    schemaName: string\n  ): number | null {\n    if (!this.isConnected) return null;\n    const id = this.nextClientChannelId++;\n    this.sendJson({\n      op: \"advertise\",\n      channels: [{ id, topic, encoding, schemaName }]\n    });\n    return id;\n  }\n\n  unadvertiseClientChannel(channelId: number): void {\n    this.sendJson({\n      op: \"unadvertise\",\n      channelIds: [channelId]\n    });\n  }\n\n  publishMessage(channelId: number, data: Uint8Array): void {\n    if (this.ws?.readyState !== WEB_SOCKET_OPEN) return;\n    // Binary format: [opcode:1][channelId:4][data:variable]\n    const msg = new Uint8Array(1 + 4 + data.byteLength);\n    const view = new DataView(msg.buffer);\n    view.setUint8(0, OP_CLIENT_MESSAGE_DATA);\n    view.setUint32(1, channelId, true);\n    msg.set(data, 5);\n    this.ws.send(msg);\n  }\n\n  // ─── Services ───────────────────────────────────────────────────────────\n\n  callService(serviceId: number, encoding: string, requestData: Uint8Array): number {\n    const callId = this.nextCallId++;\n    if (this.ws?.readyState !== WEB_SOCKET_OPEN) return callId;\n\n    const encodingBytes = new TextEncoder().encode(encoding);\n    // Binary format: [opcode:1][serviceId:4][callId:4][encodingLength:4][encoding:var][requestData:var]\n    const msg = new Uint8Array(\n      1 + 4 + 4 + 4 + encodingBytes.byteLength + requestData.byteLength\n    );\n    const view = new DataView(msg.buffer);\n    let offset = 0;\n    view.setUint8(offset, OP_CLIENT_SERVICE_CALL_REQUEST);\n    offset += 1;\n    view.setUint32(offset, serviceId, true);\n    offset += 4;\n    view.setUint32(offset, callId, true);\n    offset += 4;\n    view.setUint32(offset, encodingBytes.byteLength, true);\n    offset += 4;\n    msg.set(encodingBytes, offset);\n    offset += encodingBytes.byteLength;\n    msg.set(requestData, offset);\n\n    this.ws.send(msg);\n    return callId;\n  }\n\n  // ─── Parameters ─────────────────────────────────────────────────────────\n\n  getParameters(names: string[], requestId?: string): void {\n    this.sendJson({\n      op: \"getParameters\",\n      parameterNames: names,\n      id: requestId\n    });\n  }\n\n  setParameters(parameters: ParameterValue[], requestId?: string): void {\n    this.sendJson({\n      op: \"setParameters\",\n      parameters,\n      id: requestId\n    });\n  }\n\n  // ─── Event system ───────────────────────────────────────────────────────\n\n  on<K extends keyof ProtocolEvents>(event: K, callback: ProtocolEvents[K]): void {\n    this.handlers[event].add(callback);\n  }\n\n  off<K extends keyof ProtocolEvents>(event: K, callback: ProtocolEvents[K]): void {\n    this.handlers[event].delete(callback);\n  }\n\n  /**\n   * Dispatch helper that stays outside TypeScript's distributed-generic\n   * limitation. Each caller passes the concrete Set for one event plus a\n   * function that invokes a single handler with the right argument shape,\n   * so the spread is in a non-generic context and the types line up.\n   */\n  private dispatch<F>(\n    handlers: Set<F>,\n    invoke: (handler: F) => void,\n    event: string\n  ): void {\n    for (const handler of handlers) {\n      try {\n        invoke(handler);\n      } catch (e) {\n        console.warn(`Error in ${event} handler:`, e);\n      }\n    }\n  }\n\n  // ─── Message handling ───────────────────────────────────────────────────\n\n  private handleMessage(event: MessageEvent): void {\n    if (typeof event.data === \"string\") {\n      this.handleTextMessage(event.data);\n    } else if (event.data instanceof ArrayBuffer) {\n      this.handleBinaryMessage(event.data);\n    }\n  }\n\n  private handleTextMessage(text: string): void {\n    let parsed: unknown;\n    try {\n      parsed = JSON.parse(text);\n    } catch {\n      console.warn(\"Failed to parse foxglove text message:\", text.slice(0, 100));\n      return;\n    }\n\n    const result = serverMessageSchema.safeParse(parsed);\n    if (!result.success) {\n      // Unknown / newer op, or malformed shape. Ignore silently rather than\n      // crashing — the protocol evolves and the server may send messages\n      // this client does not implement yet.\n      return;\n    }\n    const msg = result.data;\n\n    switch (msg.op) {\n      case \"serverInfo\":\n        this.dispatch(this.handlers.serverInfo, (h) => h(msg), \"serverInfo\");\n        break;\n      case \"advertise\":\n        this.dispatch(this.handlers.advertise, (h) => h(msg.channels), \"advertise\");\n        break;\n      case \"unadvertise\":\n        this.dispatch(this.handlers.unadvertise, (h) => h(msg.channelIds), \"unadvertise\");\n        break;\n      case \"advertiseServices\":\n        this.dispatch(\n          this.handlers.advertiseServices,\n          (h) => h(msg.services),\n          \"advertiseServices\"\n        );\n        break;\n      case \"unadvertiseServices\":\n        this.dispatch(\n          this.handlers.unadvertiseServices,\n          (h) => h(msg.serviceIds),\n          \"unadvertiseServices\"\n        );\n        break;\n      case \"parameterValues\":\n        this.dispatch(\n          this.handlers.parameterValues,\n          (h) => h(msg.id ?? \"\", msg.parameters),\n          \"parameterValues\"\n        );\n        break;\n      case \"status\": {\n        const message = msg.message ?? msg.msg;\n        if (msg.level === 0) console.info(\"[foxglove]\", message);\n        else console.warn(\"[foxglove]\", message);\n        break;\n      }\n      case \"serviceCallFailure\":\n        this.dispatch(\n          this.handlers.serviceCallFailure,\n          (h) =>\n            h({\n              serviceId: msg.serviceId,\n              callId: msg.callId,\n              message: msg.message ?? \"service call failed\"\n            }),\n          \"serviceCallFailure\"\n        );\n        break;\n    }\n  }\n\n  private handleBinaryMessage(data: ArrayBuffer): void {\n    const bytes = new Uint8Array(data);\n    if (bytes.length < 1) return;\n\n    const opcode = bytes[0];\n    if (opcode === undefined) return;\n    const view = new DataView(data);\n\n    switch (opcode) {\n      case OP_MESSAGE_DATA: {\n        // [opcode:1][subscriptionId:4][timestamp:8][data:variable]\n        if (bytes.length < 13) return;\n        const subscriptionId = view.getUint32(1, true);\n        const timestamp = view.getBigUint64(5, true);\n        const msgData = bytes.slice(13);\n        this.dispatch(\n          this.handlers.message,\n          (h) => h(subscriptionId, timestamp, msgData),\n          \"message\"\n        );\n        break;\n      }\n      case OP_SERVICE_CALL_RESPONSE: {\n        // [opcode:1][serviceId:4][callId:4][encodingLength:4][encoding:var][data:var]\n        if (bytes.length < 13) return;\n        const serviceId = view.getUint32(1, true);\n        const callId = view.getUint32(5, true);\n        const encodingLength = view.getUint32(9, true);\n        const encoding = new TextDecoder().decode(bytes.slice(13, 13 + encodingLength));\n        const responseData = bytes.slice(13 + encodingLength);\n        this.dispatch(\n          this.handlers.serviceResponse,\n          (h) => h({ serviceId, callId, encoding, data: responseData }),\n          \"serviceResponse\"\n        );\n        break;\n      }\n      default:\n        console.warn(\n          `[foxglove] unhandled binary opcode 0x${opcode.toString(16)} (len=${bytes.length})`\n        );\n    }\n  }\n\n  private sendJson(msg: Record<string, unknown>): void {\n    if (this.ws?.readyState === WEB_SOCKET_OPEN) {\n      this.ws.send(JSON.stringify(msg));\n    }\n  }\n}\n","/**\n * Ros class — drop-in replacement for roslib's ROSLIB.Ros.\n *\n * Manages the WebSocket connection to foxglove_bridge and maintains\n * a registry of available channels (topics) and services. Higher-level\n * classes (Topic, Service, Action) use this to subscribe, publish, and call.\n */\n\nimport { parse as parseRosMsgDefinition } from \"@foxglove/rosmsg\";\nimport { MessageReader, MessageWriter } from \"@foxglove/rosmsg2-serialization\";\n\nimport {\n  FoxgloveProtocolClient,\n  type ServiceCallResponse,\n  type ServiceCallFailure,\n  type ParameterValue,\n  type WebSocketFactory\n} from \"./protocol\";\nimport type { ActionFeedback, ActionResult, FoxgloveChannel, FoxgloveService } from \"./types\";\n\ntype RosEventName =\n  | \"connection\"\n  | \"error\"\n  | \"close\"\n  | \"channelsChanged\"\n  | \"servicesChanged\";\n// roslib emits \"connection\" / \"close\" with no args and \"error\" with an Error.\n// Split callback types so each `on()` overload type-checks at the call site\n// without the caller having to widen `e` to `unknown` and narrow back.\ntype RosLifecycleCallback = () => void;\ntype RosErrorCallback = (error: Error) => void;\n\nexport interface RosOptions {\n  url?: string;\n  /**\n   * Creates the connection socket. Node.js callers can use this to supply\n   * authentication headers or custom TLS trust without replacing globals.\n   */\n  webSocketFactory?: WebSocketFactory;\n}\n\n/** Callback for incoming topic messages (deserialized to JS objects). */\nexport type MessageCallback<T = unknown> = {\n  bivarianceHack(message: T): void;\n}[\"bivarianceHack\"];\n\n/**\n * Normalize a ROS message/service type string to canonical `pkg/msg/Name` or\n * `pkg/srv/Name` form. Accepts and corrects:\n *   - leading slash (`/std_msgs/msg/String` → `std_msgs/msg/String`)\n *   - ROS 1 style (`std_msgs/String` → `std_msgs/msg/String`)\n *   - already-canonical forms (left untouched)\n */\nfunction normalizeRosType(\n  type: string,\n  kind: \"msg\" | \"srv\" | \"action\" = \"msg\"\n): string {\n  const trimmed = type.replace(/^\\/+/, \"\");\n  if (/\\/(?:msg|srv|action)\\//.test(trimmed)) {\n    return trimmed;\n  }\n  const slash = trimmed.indexOf(\"/\");\n  if (slash === -1) {\n    return trimmed;\n  }\n  return `${trimmed.slice(0, slash)}/${kind}/${trimmed.slice(slash + 1)}`;\n}\n\n/**\n * Translate roslib-style parameter names (`/node:param`) to the `/node.param`\n * form foxglove_bridge expects so callers written against rosbridge keep working.\n */\nfunction toFoxgloveParamName(name: string): string {\n  return name.replaceAll(\":\", \".\");\n}\n\nfunction actionEndpoint(actionName: string, leaf: string): string {\n  return `${requireActionName(actionName).replace(/\\/+$/, \"\")}/_action/${leaf}`;\n}\n\nfunction requireActionName(actionName: string): string {\n  const trimmed = actionName.trim();\n  if (!trimmed) {\n    throw new Error(\"Action name must be a non-empty ROS action name\");\n  }\n  return trimmed;\n}\n\nfunction serviceRequestSchema(svc: FoxgloveService): string {\n  return svc.request?.schema ?? svc.requestSchema ?? \"\";\n}\n\nfunction serviceResponseSchema(svc: FoxgloveService): string {\n  return svc.response?.schema ?? svc.responseSchema ?? \"\";\n}\n\nfunction firstSchemaFieldNames(schema: string): Set<string> {\n  if (!schema) return new Set();\n  return new Set(\n    parseRosMsgDefinition(schema, { ros2: true })[0]?.definitions\n      .filter((field) => !field.isConstant)\n      .flatMap((field) => (field.name ? [field.name] : []))\n  );\n}\n\nfunction goalIdToUuidBytes(goalId: string): number[] {\n  const hex = goalId.replace(/-/g, \"\");\n  if (/^[0-9a-fA-F]{32}$/.test(hex)) {\n    const bytes: number[] = [];\n    for (let i = 0; i < 32; i += 2) {\n      bytes.push(Number.parseInt(hex.slice(i, i + 2), 16));\n    }\n    return bytes;\n  }\n\n  // Deterministic fallback for roslib-style textual goal IDs. ROS only needs a\n  // stable 16-byte action UUID; generated ActionClient IDs are canonical UUIDs.\n  const bytes = new Uint8Array(16);\n  let h1 = 0x811c9dc5;\n  let h2 = 0x9e3779b9;\n  for (let i = 0; i < goalId.length; i += 1) {\n    const c = goalId.charCodeAt(i);\n    h1 ^= c;\n    h1 = Math.imul(h1, 0x01000193);\n    h2 ^= c + i;\n    h2 = Math.imul(h2, 0x85ebca6b);\n  }\n  const view = new DataView(bytes.buffer);\n  view.setUint32(0, h1, false);\n  view.setUint32(4, h2, false);\n  view.setUint32(8, Math.imul(h1 ^ h2, 0xc2b2ae35), false);\n  view.setUint32(12, Math.imul(h1 + h2, 0x27d4eb2d), false);\n  return Array.from(bytes);\n}\n\nfunction newGoalId(): string {\n  const cryptoLike = globalThis.crypto as Crypto | undefined;\n  if (cryptoLike?.randomUUID) return cryptoLike.randomUUID();\n\n  const bytes = new Uint8Array(16);\n  if (cryptoLike?.getRandomValues) {\n    cryptoLike.getRandomValues(bytes);\n  } else {\n    for (let i = 0; i < bytes.length; i += 1) {\n      bytes[i] = Math.floor(Math.random() * 256);\n    }\n  }\n  bytes[6] = (bytes[6]! & 0x0f) | 0x40;\n  bytes[8] = (bytes[8]! & 0x3f) | 0x80;\n  const hex = Array.from(bytes, (b) => b.toString(16).padStart(2, \"0\")).join(\"\");\n  return `${hex.slice(0, 8)}-${hex.slice(8, 12)}-${hex.slice(12, 16)}-${hex.slice(\n    16,\n    20\n  )}-${hex.slice(20)}`;\n}\n\nfunction sameUuid(a: unknown, b: number[]): boolean {\n  const candidate =\n    typeof a === \"object\" && a !== null && \"uuid\" in a\n      ? (a as { uuid?: unknown }).uuid\n      : a;\n  const bytes =\n    Array.isArray(candidate) || candidate instanceof Uint8Array\n      ? Array.from(candidate)\n      : null;\n  return bytes?.length === 16 && bytes.every((value, index) => value === b[index]);\n}\n\n/** Pending service call awaiting a response. */\ninterface PendingServiceCall {\n  resolve: (response: Record<string, unknown>) => void;\n  reject: (error: Error) => void;\n  responseReader: MessageReader | null;\n}\n\n/** Active topic subscription. */\ninterface ActiveSubscription {\n  subscriptionId: number;\n  channelId: number;\n  callbacks: Set<MessageCallback>;\n  reader: MessageReader;\n}\n\n/** Pending subscriber waiting for a channel to be advertised. */\ninterface PendingSubscriber {\n  topic: string;\n  messageType: string;\n  callback: MessageCallback;\n}\n\n/** Client-advertised channel for publishing. */\ninterface ClientChannel {\n  clientChannelId: number;\n  topic: string;\n  schemaName: string;\n  // Wire encoding agreed with the server at client-advertise time. CDR is the\n  // hot path (matches the binary encoding used for subscribe traffic); JSON is\n  // the fallback when we can't build a CDR writer because the schema isn't on\n  // any server-advertised channel (e.g. startup race, or a type the ROS\n  // interface registry hasn't surfaced yet).\n  encoding: \"cdr\" | \"json\";\n  // Non-null only when encoding === \"cdr\".\n  writer: MessageWriter | null;\n}\n\nexport class Ros {\n  private readonly protocol: FoxgloveProtocolClient;\n  private readonly connectionListeners = new Set<RosLifecycleCallback>();\n  private readonly closeListeners = new Set<RosLifecycleCallback>();\n  private readonly channelsChangedListeners = new Set<RosLifecycleCallback>();\n  private readonly servicesChangedListeners = new Set<RosLifecycleCallback>();\n  private readonly errorListeners = new Set<RosErrorCallback>();\n\n  // Channel/service registries populated by foxglove_bridge advertisements\n  private readonly channels = new Map<number, FoxgloveChannel>(); // channelId → channel\n  private readonly channelsByTopic = new Map<string, FoxgloveChannel>(); // topicName → channel\n  private readonly services = new Map<number, FoxgloveService>(); // serviceId → service\n  private readonly servicesByName = new Map<string, FoxgloveService>(); // serviceName → service\n\n  // Subscription state\n  private readonly subscriptions = new Map<number, ActiveSubscription>(); // subscriptionId → sub\n  private readonly subscriptionsByTopic = new Map<string, ActiveSubscription>(); // topic → sub\n  private readonly pendingSubscribers: PendingSubscriber[] = [];\n\n  // Publishing state\n  private readonly clientChannels = new Map<string, ClientChannel>(); // topic → client channel\n\n  // Service call correlation\n  private readonly pendingServiceCalls = new Map<number, PendingServiceCall>(); // callId → pending\n\n  // Splitting onValues/onClose lets callers distinguish \"param missing\"\n  // (resolve null) from \"WebSocket closed before reply\" (reject).\n  private readonly pendingParamRequests = new Map<\n    string,\n    {\n      onValues: (params: ParameterValue[]) => void;\n      onClose: () => void;\n    }\n  >();\n  private nextParamRequestId = 1;\n\n  // Compiled reader/writer caches keyed by the canonical schema name plus the\n  // full schema text. The full text is the only collision-free identity:\n  // schema.length alone collides for equal-length schemas, and schemaName alone\n  // collides across distros that share a type name but evolve its fields.\n  // MessageReader / MessageWriter internally pre-compile per-type decode paths\n  // from a MessageDefinition list, so we reuse them across messages instead of\n  // re-parsing the schema on every topic/service hit.\n  private readonly readerCache = new Map<string, MessageReader>();\n  private readonly writerCache = new Map<string, MessageWriter>();\n\n  isConnected = false;\n\n  constructor(options: RosOptions = {}) {\n    this.protocol = new FoxgloveProtocolClient(options.webSocketFactory);\n    this.setupProtocolHandlers();\n    if (options.url) {\n      this.connect(options.url);\n    }\n  }\n\n  connect(url: string): void {\n    this.protocol.connect(url);\n  }\n\n  close(): void {\n    this.protocol.close();\n    this.isConnected = false;\n  }\n\n  on(event: \"error\", callback: RosErrorCallback): void;\n  on(\n    event: \"connection\" | \"close\" | \"channelsChanged\" | \"servicesChanged\",\n    callback: RosLifecycleCallback\n  ): void;\n  on(\n    ...args:\n      | [event: \"error\", callback: RosErrorCallback]\n      | [\n          event: \"connection\" | \"close\" | \"channelsChanged\" | \"servicesChanged\",\n          callback: RosLifecycleCallback\n        ]\n  ): void {\n    const [event, callback] = args;\n    switch (event) {\n      case \"connection\":\n        this.connectionListeners.add(callback);\n        break;\n      case \"close\":\n        this.closeListeners.add(callback);\n        break;\n      case \"channelsChanged\":\n        this.channelsChangedListeners.add(callback);\n        break;\n      case \"servicesChanged\":\n        this.servicesChangedListeners.add(callback);\n        break;\n      case \"error\":\n        this.errorListeners.add(callback);\n        break;\n    }\n  }\n\n  off(event: \"error\", callback: RosErrorCallback): void;\n  off(\n    event: \"connection\" | \"close\" | \"channelsChanged\" | \"servicesChanged\",\n    callback: RosLifecycleCallback\n  ): void;\n  off(\n    ...args:\n      | [event: \"error\", callback: RosErrorCallback]\n      | [\n          event: \"connection\" | \"close\" | \"channelsChanged\" | \"servicesChanged\",\n          callback: RosLifecycleCallback\n        ]\n  ): void {\n    const [event, callback] = args;\n    switch (event) {\n      case \"connection\":\n        this.connectionListeners.delete(callback);\n        break;\n      case \"close\":\n        this.closeListeners.delete(callback);\n        break;\n      case \"channelsChanged\":\n        this.channelsChangedListeners.delete(callback);\n        break;\n      case \"servicesChanged\":\n        this.servicesChangedListeners.delete(callback);\n        break;\n      case \"error\":\n        this.errorListeners.delete(callback);\n        break;\n    }\n  }\n\n  /**\n   * roslib-compatible bulk listener removal. Tests use this to reset the\n   * module-level mock Ros between cases; production code does not call it.\n   */\n  removeAllListeners(event?: RosEventName): void {\n    if (event === undefined) {\n      this.connectionListeners.clear();\n      this.closeListeners.clear();\n      this.channelsChangedListeners.clear();\n      this.servicesChangedListeners.clear();\n      this.errorListeners.clear();\n      return;\n    }\n\n    switch (event) {\n      case \"connection\":\n        this.connectionListeners.clear();\n        break;\n      case \"close\":\n        this.closeListeners.clear();\n        break;\n      case \"channelsChanged\":\n        this.channelsChangedListeners.clear();\n        break;\n      case \"servicesChanged\":\n        this.servicesChangedListeners.clear();\n        break;\n      case \"error\":\n        this.errorListeners.clear();\n        break;\n    }\n  }\n\n  emit(event: \"error\", error: Error): void;\n  emit(event: \"connection\" | \"close\" | \"channelsChanged\" | \"servicesChanged\"): void;\n  emit(event: RosEventName, error?: Error): void {\n    switch (event) {\n      case \"connection\":\n        this.emitLifecycle(\"connection\", this.connectionListeners);\n        break;\n      case \"close\":\n        this.emitLifecycle(\"close\", this.closeListeners);\n        break;\n      case \"channelsChanged\":\n        this.emitLifecycle(\"channelsChanged\", this.channelsChangedListeners);\n        break;\n      case \"servicesChanged\":\n        this.emitLifecycle(\"servicesChanged\", this.servicesChangedListeners);\n        break;\n      case \"error\":\n        this.emitError(error ?? new Error(\"ros emit('error') called without an error\"));\n        break;\n    }\n  }\n\n  private emitLifecycle(\n    event: \"connection\" | \"close\" | \"channelsChanged\" | \"servicesChanged\",\n    listeners: Set<RosLifecycleCallback>\n  ): void {\n    for (const cb of listeners) {\n      try {\n        cb();\n      } catch (e) {\n        console.warn(`Error in Ros \"${event}\" handler:`, e);\n      }\n    }\n  }\n\n  private emitError(error: Error): void {\n    for (const cb of this.errorListeners) {\n      try {\n        cb(error);\n      } catch (e) {\n        console.warn('Error in Ros \"error\" handler:', e);\n      }\n    }\n  }\n\n  // ─── Channel/Service Lookups ────────────────────────────────────────────\n\n  getChannel(topic: string): FoxgloveChannel | undefined {\n    return this.channelsByTopic.get(topic);\n  }\n\n  getServiceByName(name: string): FoxgloveService | undefined {\n    return this.servicesByName.get(name);\n  }\n\n  getActionServers(onSuccess: (actions: string[]) => void): void {\n    const suffix = \"/_action/send_goal\";\n    const actions = Array.from(this.servicesByName.keys())\n      .filter((name) => name.endsWith(suffix))\n      .map((name) => name.slice(0, -suffix.length))\n      .sort();\n    onSuccess(actions);\n  }\n\n  isServiceAdvertised(serviceName: string): boolean {\n    return this.servicesByName.has(serviceName);\n  }\n\n  getMissingActionEndpoints(\n    actionName: string,\n    options?: { requireFeedback?: boolean; requireCancel?: boolean }\n  ): string[] {\n    const missing: string[] = [];\n    for (const leaf of [\"send_goal\", \"get_result\"]) {\n      const service = actionEndpoint(actionName, leaf);\n      if (!this.servicesByName.has(service)) missing.push(service);\n    }\n\n    if (options?.requireCancel) {\n      const cancel = actionEndpoint(actionName, \"cancel_goal\");\n      if (!this.servicesByName.has(cancel)) missing.push(cancel);\n    }\n\n    if (options?.requireFeedback) {\n      const feedback = actionEndpoint(actionName, \"feedback\");\n      if (!this.channelsByTopic.has(feedback)) missing.push(feedback);\n    }\n\n    return missing;\n  }\n\n  isActionAdvertised(\n    actionName: string,\n    options?: { requireFeedback?: boolean; requireCancel?: boolean }\n  ): boolean {\n    return this.getMissingActionEndpoints(actionName, options).length === 0;\n  }\n\n  waitForService(serviceName: string, timeoutMs = 5000): Promise<boolean> {\n    if (this.isServiceAdvertised(serviceName)) return Promise.resolve(true);\n    return new Promise((resolve) => {\n      const check = () => {\n        if (this.isServiceAdvertised(serviceName)) done(true);\n      };\n      const done = (value: boolean) => {\n        clearTimeout(timeout);\n        this.off(\"servicesChanged\", check);\n        resolve(value);\n      };\n      const timeout = setTimeout(done, timeoutMs, false);\n      this.on(\"servicesChanged\", check);\n      check();\n    });\n  }\n\n  waitForAction(\n    actionName: string,\n    timeoutMs = 5000,\n    options?: { requireFeedback?: boolean; requireCancel?: boolean }\n  ): Promise<boolean> {\n    if (this.isActionAdvertised(actionName, options)) return Promise.resolve(true);\n    return new Promise((resolve) => {\n      const check = () => {\n        if (this.isActionAdvertised(actionName, options)) done(true);\n      };\n      const done = (value: boolean) => {\n        clearTimeout(timeout);\n        this.off(\"servicesChanged\", check);\n        this.off(\"channelsChanged\", check);\n        resolve(value);\n      };\n      const timeout = setTimeout(done, timeoutMs, false);\n      this.on(\"servicesChanged\", check);\n      this.on(\"channelsChanged\", check);\n      check();\n    });\n  }\n\n  /**\n   * Return every advertised topic whose schema matches `messageType`. Matches\n   * roslib's `Ros#getTopicsForType(type, success, fail)` callback API so\n   * existing callers (e.g. `useImageTopics`) can use this adapter unchanged.\n   */\n  /**\n   * The roslib signature also accepts an `onError` callback. Foxglove resolves\n   * synchronously from the in-memory channel registry, so the failure path is\n   * unreachable; we drop the parameter to keep lint clean. Callers that pass\n   * one are unaffected — extra arguments to a JS function are ignored.\n   */\n  getTopicsForType(messageType: string, onSuccess: (topics: string[]) => void): void {\n    const canonical = normalizeRosType(messageType, \"msg\");\n    const topics: string[] = [];\n    for (const ch of this.channels.values()) {\n      if (normalizeRosType(ch.schemaName, \"msg\") === canonical) {\n        topics.push(ch.topic);\n      }\n    }\n    onSuccess(topics);\n  }\n\n  // ─── Topic Subscription ─────────────────────────────────────────────────\n\n  subscribeTopic(topic: string, messageType: string, callback: MessageCallback): void {\n    // If we already have an active subscription for this topic, add the callback\n    const existing = this.subscriptionsByTopic.get(topic);\n    if (existing) {\n      existing.callbacks.add(callback);\n      return;\n    }\n\n    // If the channel is advertised, subscribe now\n    const channel = this.channelsByTopic.get(topic);\n    if (channel) {\n      this.createSubscription(channel, callback);\n    } else {\n      // Queue for when the channel becomes available\n      this.pendingSubscribers.push({ topic, messageType, callback });\n    }\n  }\n\n  unsubscribeTopic(topic: string, callback?: MessageCallback): void {\n    // A caller may unsubscribe before the channel has been advertised, in\n    // which case the callback lives in `pendingSubscribers` and there is no\n    // active subscription yet. Drop the matching queued entry/entries first\n    // so processPendingSubscribers cannot later wire the dead callback to a\n    // fresh subscription once the server's advertise arrives.\n    const keep = this.pendingSubscribers.filter(\n      (p) => p.topic !== topic || (callback !== undefined && p.callback !== callback)\n    );\n    if (keep.length !== this.pendingSubscribers.length) {\n      this.pendingSubscribers.length = 0;\n      this.pendingSubscribers.push(...keep);\n    }\n\n    const sub = this.subscriptionsByTopic.get(topic);\n    if (!sub) return;\n\n    if (callback) {\n      sub.callbacks.delete(callback);\n      if (sub.callbacks.size > 0) return; // Other subscribers remain\n    }\n\n    // Fully unsubscribe\n    this.protocol.unsubscribe(sub.subscriptionId);\n    this.subscriptions.delete(sub.subscriptionId);\n    this.subscriptionsByTopic.delete(topic);\n  }\n\n  private createSubscription(channel: FoxgloveChannel, callback: MessageCallback): void {\n    const reader = this.getReader(channel.schemaName, channel.schema);\n    const subscriptionId = this.protocol.subscribe(channel.id);\n    const sub: ActiveSubscription = {\n      subscriptionId,\n      channelId: channel.id,\n      callbacks: new Set([callback]),\n      reader\n    };\n    this.subscriptions.set(subscriptionId, sub);\n    this.subscriptionsByTopic.set(channel.topic, sub);\n  }\n\n  // ─── Topic Publishing ───────────────────────────────────────────────────\n\n  publishTopic(topic: string, messageType: string, message: unknown): void {\n    let clientCh = this.clientChannels.get(topic);\n\n    if (!clientCh) {\n      const schemaName = normalizeRosType(messageType, \"msg\");\n      const writer = this.findWriterForSchema(schemaName);\n      // Encoding is fixed at advertise time. Prefer CDR (smaller, faster) when\n      // we can find a matching schema; otherwise advertise JSON so\n      // foxglove_bridge converts our payload to the ROS message using its own\n      // type-registry. JSON keeps subscriber-only / unknown-schema topics\n      // working at the cost of a few extra bytes per publish.\n      const encoding: \"cdr\" | \"json\" = writer ? \"cdr\" : \"json\";\n      const clientChannelId = this.protocol.advertiseClientChannel(\n        topic,\n        encoding,\n        schemaName\n      );\n      // Drop this sample while disconnected. The next publish will advertise\n      // afresh instead of reusing an ID the server never received.\n      if (clientChannelId === null) return;\n      clientCh = { clientChannelId, topic, schemaName, encoding, writer };\n      this.clientChannels.set(topic, clientCh);\n    }\n\n    if (clientCh.encoding === \"cdr\") {\n      // The CDR writer is built from a schema on a server-advertised channel.\n      // If the schema only became available after this channel was advertised,\n      // pick it up lazily here.\n      if (!clientCh.writer) {\n        clientCh.writer = this.findWriterForSchema(clientCh.schemaName);\n      }\n      if (!clientCh.writer) {\n        // Schema still unknown — should not happen because the encoding was\n        // chosen at advertise time, but guard so a serialization failure is\n        // loud rather than silent.\n        throw new Error(\n          `Cannot publish CDR to \"${topic}\": schema \"${clientCh.schemaName}\" disappeared from advertised channels.`\n        );\n      }\n      const cdrData = clientCh.writer.writeMessage(message);\n      this.protocol.publishMessage(clientCh.clientChannelId, cdrData);\n      return;\n    }\n\n    // JSON fallback: serialize as UTF-8 JSON; the bridge converts to the ROS\n    // message via its type registry on the receiving side.\n    const jsonData = new TextEncoder().encode(JSON.stringify(message));\n    this.protocol.publishMessage(clientCh.clientChannelId, jsonData);\n  }\n\n  private findWriterForSchema(schemaName: string): MessageWriter | null {\n    const canonical = normalizeRosType(schemaName, \"msg\");\n    for (const channel of this.channels.values()) {\n      if (normalizeRosType(channel.schemaName, \"msg\") === canonical) {\n        return this.getWriter(channel.schemaName, channel.schema);\n      }\n    }\n    return null;\n  }\n\n  unpublishTopic(topic: string): void {\n    const clientCh = this.clientChannels.get(topic);\n    if (clientCh) {\n      this.protocol.unadvertiseClientChannel(clientCh.clientChannelId);\n      this.clientChannels.delete(topic);\n    }\n  }\n\n  // ─── Service Calls ──────────────────────────────────────────────────────\n\n  callService(\n    serviceName: string,\n    serviceType: string,\n    request: unknown\n  ): Promise<Record<string, unknown>> {\n    return new Promise((resolve, reject) => {\n      const svc = this.servicesByName.get(serviceName);\n      if (!svc) {\n        reject(new Error(`Service ${serviceName} not available`));\n        return;\n      }\n\n      // Normalize so mixed caller formats (e.g. `pkg/Foo` vs `pkg/srv/Foo`)\n      // produce the same cache keys. Prefer the sdk.v1 nested schema fields\n      // and fall back to the legacy flat form for older bridges.\n      const advertisedType = normalizeRosType(svc.type || serviceType, \"srv\");\n      const requestSchema = serviceRequestSchema(svc);\n      const responseSchema = serviceResponseSchema(svc);\n      if (!requestSchema) {\n        reject(new Error(`No request definition for service ${serviceName}`));\n        return;\n      }\n\n      const requestWriter = this.getWriter(advertisedType + \"_Request\", requestSchema);\n      const responseReader = responseSchema\n        ? this.getReader(advertisedType + \"_Response\", responseSchema)\n        : null;\n\n      const requestData = requestWriter.writeMessage(request);\n      const callId = this.protocol.callService(svc.id, \"cdr\", requestData);\n\n      this.pendingServiceCalls.set(callId, { resolve, reject, responseReader });\n    });\n  }\n\n  sendActionGoal<TGoal = Record<string, unknown>, TResult = unknown, TFeedback = unknown>(\n    actionName: string,\n    actionType: string,\n    goal: TGoal,\n    onResult?: (result: ActionResult<TResult>) => void,\n    onFeedback?: (feedback: ActionFeedback<TFeedback>) => void,\n    onError?: (error: Error) => void,\n    goalId = newGoalId()\n  ): string {\n    const canonicalActionType = normalizeRosType(actionType, \"action\");\n    const uuid = goalIdToUuidBytes(goalId);\n    const missing = this.getMissingActionEndpoints(actionName, {\n      requireFeedback: onFeedback !== undefined\n    });\n    if (missing.length > 0) {\n      const error = new Error(\n        `Action ${actionName} is not fully advertised by foxglove_bridge; missing ${missing.join(\n          \", \"\n        )}. ROS 2 action endpoints are hidden topics/services in Foxglove, so launch foxglove_bridge with include_hidden:=true when using ActionClient.`\n      );\n      if (onError) {\n        onError(error);\n        return goalId;\n      }\n      throw error;\n    }\n\n    let feedbackCallback: MessageCallback | undefined;\n    const feedbackTopic = actionEndpoint(actionName, \"feedback\");\n    if (onFeedback) {\n      feedbackCallback = (message: Record<string, unknown>) => {\n        if (\"goal_id\" in message && !sameUuid(message.goal_id, uuid)) return;\n        const values = (message.feedback ?? message) as TFeedback;\n        onFeedback({ action: actionName, id: goalId, values, feedback: values });\n      };\n      this.subscribeTopic(\n        feedbackTopic,\n        `${canonicalActionType}_FeedbackMessage`,\n        feedbackCallback\n      );\n    }\n\n    const cleanupFeedback = () => {\n      if (feedbackCallback) this.unsubscribeTopic(feedbackTopic, feedbackCallback);\n    };\n\n    const sendGoalService = actionEndpoint(actionName, \"send_goal\");\n    const getResultService = actionEndpoint(actionName, \"get_result\");\n    const sendGoalRequest = this.actionSendGoalRequest(sendGoalService, uuid, goal);\n\n    this.callService(sendGoalService, `${canonicalActionType}_SendGoal`, sendGoalRequest)\n      .then((response) => {\n        if (response.accepted === false) {\n          cleanupFeedback();\n          onResult?.({\n            action: actionName,\n            id: goalId,\n            status: 0,\n            result: false,\n            accepted: false,\n            values: response as TResult,\n            response\n          });\n          return undefined;\n        }\n        return this.callService(getResultService, `${canonicalActionType}_GetResult`, {\n          goal_id: { uuid }\n        });\n      })\n      .then((response) => {\n        if (!response) return;\n        cleanupFeedback();\n        const values = (response.result ?? response) as TResult;\n        onResult?.({\n          action: actionName,\n          id: goalId,\n          status: Number(response.status ?? 0),\n          result: true,\n          accepted: true,\n          values,\n          response\n        });\n      })\n      .catch((err: unknown) => {\n        cleanupFeedback();\n        const error = err instanceof Error ? err : new Error(String(err));\n        if (onError) onError(error);\n        else this.emit(\"error\", error);\n      });\n\n    return goalId;\n  }\n\n  cancelActionGoal(actionName: string, goalId: string): Promise<Record<string, unknown>> {\n    return this.callService(actionEndpoint(actionName, \"cancel_goal\"), \"action_msgs/srv/CancelGoal\", {\n      goal_info: {\n        goal_id: { uuid: goalIdToUuidBytes(goalId) },\n        stamp: { sec: 0, nanosec: 0 }\n      }\n    });\n  }\n\n  private actionSendGoalRequest<TGoal>(\n    serviceName: string,\n    uuid: number[],\n    goal: TGoal\n  ): Record<string, unknown> {\n    const svc = this.servicesByName.get(serviceName);\n    const fields = svc ? firstSchemaFieldNames(serviceRequestSchema(svc)) : new Set();\n    if (fields.size === 0 || fields.has(\"goal\")) {\n      return { goal_id: { uuid }, goal };\n    }\n    return { goal_id: { uuid }, ...(goal as Record<string, unknown>) };\n  }\n\n  // ─── Parameters ─────────────────────────────────────────────────────────\n\n  getParam(name: string): Promise<unknown> {\n    return new Promise((resolve, reject) => {\n      const wireName = toFoxgloveParamName(name);\n      const requestId = `param_get_${this.nextParamRequestId++}`;\n      this.pendingParamRequests.set(requestId, {\n        onValues: (params) => {\n          const param = params.find((p) => toFoxgloveParamName(p.name) === wireName);\n          resolve(param?.value ?? null);\n        },\n        onClose: () =>\n          reject(new Error(`getParam(${name}): WebSocket closed before response`))\n      });\n      this.protocol.getParameters([wireName], requestId);\n    });\n  }\n\n  setParam(name: string, value: unknown): Promise<void> {\n    return new Promise((resolve, reject) => {\n      const wireName = toFoxgloveParamName(name);\n      const requestId = `param_set_${this.nextParamRequestId++}`;\n      this.pendingParamRequests.set(requestId, {\n        onValues: () => resolve(),\n        onClose: () =>\n          reject(new Error(`setParam(${name}): WebSocket closed before response`))\n      });\n      this.protocol.setParameters([{ name: wireName, value }], requestId);\n    });\n  }\n\n  // ─── Internal: Protocol Event Handlers ──────────────────────────────────\n\n  private setupProtocolHandlers(): void {\n    this.protocol.on(\"open\", () => {\n      this.isConnected = true;\n      this.emit(\"connection\");\n    });\n\n    this.protocol.on(\"close\", () => {\n      this.isConnected = false;\n      this.channels.clear();\n      this.channelsByTopic.clear();\n      this.services.clear();\n      this.servicesByName.clear();\n      this.subscriptions.clear();\n      this.subscriptionsByTopic.clear();\n      this.clientChannels.clear();\n      // Bound long-session growth and avoid decoding against a stale schema\n      // if the server's definition changes across a reconnect.\n      this.readerCache.clear();\n      this.writerCache.clear();\n\n      // Reject any in-flight service calls and parameter requests so their\n      // promises don't hang forever across a disconnect.\n      const closeError = new Error(\"WebSocket closed before response received\");\n      for (const pending of this.pendingServiceCalls.values()) {\n        try {\n          pending.reject(closeError);\n        } catch (e) {\n          console.warn(\"Error rejecting pending service call on close:\", e);\n        }\n      }\n      this.pendingServiceCalls.clear();\n\n      for (const pending of this.pendingParamRequests.values()) {\n        try {\n          pending.onClose();\n        } catch (e) {\n          console.warn(\"Error completing pending param request on close:\", e);\n        }\n      }\n      this.pendingParamRequests.clear();\n\n      this.pendingSubscribers.length = 0;\n\n      this.emit(\"channelsChanged\");\n      this.emit(\"servicesChanged\");\n      this.emit(\"close\");\n    });\n\n    this.protocol.on(\"error\", () => {\n      // Browser WebSocket error events carry no detail; reason codes come\n      // from the close event that follows.\n      this.emit(\"error\", new Error(\"Foxglove WebSocket error\"));\n    });\n\n    this.protocol.on(\"advertise\", (channels: FoxgloveChannel[]) => {\n      for (const ch of channels) {\n        this.channels.set(ch.id, ch);\n        this.channelsByTopic.set(ch.topic, ch);\n      }\n      // Process pending subscribers that were waiting for these channels\n      this.processPendingSubscribers();\n      this.emit(\"channelsChanged\");\n    });\n\n    this.protocol.on(\"unadvertise\", (channelIds: number[]) => {\n      for (const id of channelIds) {\n        const ch = this.channels.get(id);\n        if (ch) {\n          this.channelsByTopic.delete(ch.topic);\n          this.channels.delete(id);\n        }\n      }\n      this.emit(\"channelsChanged\");\n    });\n\n    this.protocol.on(\"advertiseServices\", (svcs: FoxgloveService[]) => {\n      for (const svc of svcs) {\n        this.services.set(svc.id, svc);\n        this.servicesByName.set(svc.name, svc);\n      }\n      this.emit(\"servicesChanged\");\n    });\n\n    this.protocol.on(\"unadvertiseServices\", (serviceIds: number[]) => {\n      for (const id of serviceIds) {\n        const svc = this.services.get(id);\n        if (svc) {\n          this.servicesByName.delete(svc.name);\n          this.services.delete(id);\n        }\n      }\n      this.emit(\"servicesChanged\");\n    });\n\n    this.protocol.on(\n      \"message\",\n      (subscriptionId: number, _timestamp: bigint, data: Uint8Array) => {\n        const sub = this.subscriptions.get(subscriptionId);\n        if (!sub) return;\n\n        try {\n          const msg = sub.reader.readMessage<Record<string, unknown>>(data);\n          for (const cb of sub.callbacks) {\n            cb(msg);\n          }\n        } catch (e) {\n          console.warn(\"CDR deserialization error:\", e);\n        }\n      }\n    );\n\n    this.protocol.on(\"serviceResponse\", (response: ServiceCallResponse) => {\n      const pending = this.pendingServiceCalls.get(response.callId);\n      if (!pending) return;\n      this.pendingServiceCalls.delete(response.callId);\n\n      try {\n        if (pending.responseReader) {\n          const result = pending.responseReader.readMessage<Record<string, unknown>>(\n            response.data\n          );\n          pending.resolve(result);\n          return;\n        }\n        pending.resolve({});\n      } catch (e) {\n        pending.reject(e instanceof Error ? e : new Error(String(e)));\n      }\n    });\n\n    // foxglove_bridge emits this when a service handler raises, the service\n    // gets unadvertised mid-call, or the request payload is rejected. Without\n    // this branch the corresponding pending Promise would hang forever — the\n    // legacy roslib path raised an explicit error callback in the same shape.\n    this.protocol.on(\"serviceCallFailure\", (failure: ServiceCallFailure) => {\n      const pending = this.pendingServiceCalls.get(failure.callId);\n      if (!pending) return;\n      this.pendingServiceCalls.delete(failure.callId);\n      pending.reject(new Error(failure.message));\n    });\n\n    this.protocol.on(\"parameterValues\", (id: string, params: ParameterValue[]) => {\n      const pending = this.pendingParamRequests.get(id);\n      if (pending) {\n        this.pendingParamRequests.delete(id);\n        pending.onValues(params);\n      }\n    });\n  }\n\n  private processPendingSubscribers(): void {\n    const remaining: PendingSubscriber[] = [];\n    for (const pending of this.pendingSubscribers) {\n      const channel = this.channelsByTopic.get(pending.topic);\n      if (channel) {\n        const existing = this.subscriptionsByTopic.get(pending.topic);\n        if (existing) {\n          existing.callbacks.add(pending.callback);\n        } else {\n          this.createSubscription(channel, pending.callback);\n        }\n      } else {\n        remaining.push(pending);\n      }\n    }\n    this.pendingSubscribers.length = 0;\n    this.pendingSubscribers.push(...remaining);\n  }\n\n  private getReader(schemaName: string, schema: string): MessageReader {\n    const key = `${normalizeRosType(schemaName, \"msg\")} ${schema}`;\n    let reader = this.readerCache.get(key);\n    if (!reader) {\n      reader = new MessageReader(parseRosMsgDefinition(schema, { ros2: true }));\n      this.readerCache.set(key, reader);\n    }\n    return reader;\n  }\n\n  private getWriter(schemaName: string, schema: string): MessageWriter {\n    const key = `${normalizeRosType(schemaName, \"msg\")} ${schema}`;\n    let writer = this.writerCache.get(key);\n    if (!writer) {\n      writer = new MessageWriter(parseRosMsgDefinition(schema, { ros2: true }));\n      this.writerCache.set(key, writer);\n    }\n    return writer;\n  }\n}\n","/**\n * Topic class — drop-in replacement for roslib's ROSLIB.Topic.\n *\n * Provides subscribe/unsubscribe/publish matching the roslib API.\n * Internally delegates to the Ros class which manages foxglove subscriptions.\n */\n\nimport type { z } from \"zod\";\n\nimport { Ros, type MessageCallback } from \"./ros\";\n\nexport interface TopicOptions<T = unknown> {\n  ros: Ros;\n  name: string;\n  messageType: string;\n  /**\n   * Optional runtime validator for decoded messages. When supplied, subscribed\n   * callbacks receive only values that have passed this schema.\n   */\n  messageSchema?: z.ZodType<T>;\n  /**\n   * Minimum milliseconds between delivered messages. Matches rosbridge's\n   * `throttle_rate`: leading-edge fire, no trailing catch-up. Enforced client-side\n   * because foxglove_bridge does not expose a per-subscription rate limiter —\n   * rosbridge delivered the rate cap on the server, foxglove_bridge delivers every\n   * message published.\n   *\n   * `0` / `undefined` → no throttle; the hot path takes zero extra work.\n   */\n  throttle_rate?: number;\n  // roslib compatibility fields. foxglove_bridge negotiates transport-level\n  // concerns on its own, so the adapter accepts and ignores these to keep the\n  // public API stable.\n  compression?: string;\n  queue_size?: number;\n  queue_length?: number;\n  latch?: boolean;\n  reconnect_on_close?: boolean;\n}\n\nexport class Topic<T = Record<string, unknown>> {\n  ros: Ros;\n  name: string;\n  messageType: string;\n  private readonly messageSchema: z.ZodType<T> | undefined;\n\n  /**\n   * Throttle window in ms. `0` disables throttling — in that case `subscribe`\n   * skips the throttling code path entirely and registers an unwrapped callback\n   * so the per-message hot path has no throttle-related work.\n   */\n  private readonly throttleMs: number;\n\n  /**\n   * Original user callback → wrapped MessageCallback registered with Ros.\n   * Keyed as `object` (all JS functions are objects) so `Topic<T>` stays\n   * variance-friendly for callers that pass a `Topic<Foo>` into a slot typed\n   * as `Topic<unknown>` — otherwise T ends up invariant through this field\n   * and blocks assignments that are safe at runtime.\n   */\n  private readonly wrappedCallbacks = new Map<object, MessageCallback>();\n\n  constructor(options: TopicOptions<T>) {\n    this.ros = options.ros;\n    this.name = options.name;\n    this.messageType = options.messageType;\n    this.messageSchema = options.messageSchema;\n    // Non-finite / negative / zero → no throttling.\n    const rate = options.throttle_rate ?? 0;\n    this.throttleMs = Number.isFinite(rate) && rate > 0 ? rate : 0;\n  }\n\n  /**\n   * advertise() is a no-op: the foxglove adapter advertises a client channel\n   * lazily on the first publish() and reuses it afterwards, so explicit\n   * registration has no effect on the wire.\n   */\n  advertise(): void {\n    // Intentional no-op — the foxglove adapter advertises lazily on first publish().\n  }\n\n  /**\n   * Release the client channel allocated by the lazy advertise on first publish().\n   * Callers that publish once then tear down (e.g. joint-control-spinners' StoreJointState\n   * burst) rely on this to drop the channel registration rather than leaking it for the\n   * life of the Ros connection.\n   */\n  unadvertise(): void {\n    this.ros.unpublishTopic(this.name);\n  }\n\n  subscribe(callback: MessageCallback<T>): void {\n    if (this.wrappedCallbacks.has(callback)) {\n      // Idempotent: subscribing the same callback twice is a no-op rather\n      // than a silent leak of the prior wrapped registration.\n      return;\n    }\n\n    const messageSchema = this.messageSchema;\n    const deliver: MessageCallback = messageSchema\n      ? (msg) => callback(messageSchema.parse(msg))\n      : callback;\n\n    let wrappedCb: MessageCallback;\n    if (this.throttleMs === 0) {\n      // Fast path: no throttle requested. Register the user callback directly so\n      // the hot path costs nothing beyond the existing Ros-level fan-out.\n      wrappedCb = deliver;\n    } else {\n      // Leading-edge throttle. `lastFiredAt` lives in the closure (one slot per\n      // subscription) so there is no Map lookup, Set access, or object\n      // allocation on the hot path — just a clock read, a subtract, and a\n      // compare. `performance.now()` is monotonic and immune to wall-clock\n      // changes, which matters for long-running UIs.\n      const windowMs = this.throttleMs;\n      let lastFiredAt = -Infinity;\n      wrappedCb = (msg) => {\n        const now = performance.now();\n        if (now - lastFiredAt < windowMs) return;\n        lastFiredAt = now;\n        deliver(msg);\n      };\n    }\n\n    this.wrappedCallbacks.set(callback, wrappedCb);\n    this.ros.subscribeTopic(this.name, this.messageType, wrappedCb);\n  }\n\n  unsubscribe(callback?: MessageCallback<T>): void {\n    if (callback) {\n      const wrapped = this.wrappedCallbacks.get(callback);\n      if (wrapped) {\n        this.ros.unsubscribeTopic(this.name, wrapped);\n        this.wrappedCallbacks.delete(callback);\n      }\n      return;\n    }\n    // No callback given — unsubscribe every wrapped callback we registered.\n    for (const wrapped of this.wrappedCallbacks.values()) {\n      this.ros.unsubscribeTopic(this.name, wrapped);\n    }\n    this.wrappedCallbacks.clear();\n  }\n\n  publish(message: T): void {\n    this.ros.publishTopic(this.name, this.messageType, message);\n  }\n}\n","/**\n * Service class — drop-in replacement for roslib's ROSLIB.Service.\n *\n * Provides callService matching the roslib API. Service calls go through the\n * foxglove WebSocket protocol. Client-side service advertisement is not\n * supported by foxglove_bridge, and the corresponding no-op shims have been\n * removed now that no caller depends on them.\n */\n\nimport type { z } from \"zod\";\n\nimport { Ros } from \"./ros\";\n\ntype ServiceResponseCallback<T = unknown> = {\n  bivarianceHack(response: T): void;\n}[\"bivarianceHack\"];\n\nexport interface ServiceOptions<TResp = unknown> {\n  ros: Ros;\n  name: string;\n  serviceType: string;\n  /**\n   * Optional runtime validator for decoded responses. When supplied, success\n   * callbacks receive only values that have passed this schema.\n   */\n  responseSchema?: z.ZodType<TResp>;\n}\n\nexport class Service<TReq = unknown, TResp = unknown> {\n  ros: Ros;\n  name: string;\n  serviceType: string;\n  private readonly responseSchema: z.ZodType<TResp> | undefined;\n\n  constructor(options: ServiceOptions<TResp>) {\n    this.ros = options.ros;\n    this.name = options.name;\n    this.serviceType = options.serviceType;\n    this.responseSchema = options.responseSchema;\n  }\n\n  /**\n   * Call the service (roslib-compatible callback API).\n   */\n  callService(\n    request: TReq,\n    onSuccess?: ServiceResponseCallback<TResp>,\n    onError?: (error: string) => void\n  ): void {\n    const responseSchema = this.responseSchema;\n    const deliver: ServiceResponseCallback | undefined =\n      onSuccess && responseSchema\n        ? (response) => onSuccess(responseSchema.parse(response))\n        : onSuccess;\n\n    this.ros\n      .callService(this.name, this.serviceType, request)\n      .then((response) => deliver?.(response))\n      .catch((err) => {\n        const msg = err instanceof Error ? err.message : String(err);\n        onError?.(msg);\n      });\n  }\n}\n","import { Ros } from \"./ros\";\nimport type { ActionFeedback, ActionResult } from \"./types\";\n\nfunction newActionGoalId(): string {\n  const cryptoLike = globalThis.crypto as Crypto | undefined;\n  if (cryptoLike?.randomUUID) return cryptoLike.randomUUID();\n\n  const bytes = new Uint8Array(16);\n  if (cryptoLike?.getRandomValues) {\n    cryptoLike.getRandomValues(bytes);\n  } else {\n    for (let i = 0; i < bytes.length; i += 1) {\n      bytes[i] = Math.floor(Math.random() * 256);\n    }\n  }\n  bytes[6] = (bytes[6]! & 0x0f) | 0x40;\n  bytes[8] = (bytes[8]! & 0x3f) | 0x80;\n  const hex = Array.from(bytes, (b) => b.toString(16).padStart(2, \"0\")).join(\"\");\n  return `${hex.slice(0, 8)}-${hex.slice(8, 12)}-${hex.slice(12, 16)}-${hex.slice(\n    16,\n    20\n  )}-${hex.slice(20)}`;\n}\n\nexport interface ActionClientOptions {\n  ros: Ros;\n  /** ROS action name, e.g. `/fibonacci` or `/do_objective`. */\n  name: string;\n  /** ROS action type, e.g. `example_interfaces/action/Fibonacci`. */\n  actionType: string;\n  /** Accepted for roslib compatibility; reconnect behavior is owned by Ros. */\n  reconnectOnClose?: boolean;\n}\n\nexport class ActionClient<\n  TGoal = Record<string, unknown>,\n  TResult = unknown,\n  TFeedback = unknown\n> {\n  ros: Ros;\n  name: string;\n  actionType: string;\n  reconnectOnClose: boolean;\n\n  private readonly waiters = new Map<\n    string,\n    {\n      resolve: () => void;\n      reject: (error: Error) => void;\n      timeout?: ReturnType<typeof setTimeout>;\n    }\n  >();\n  private readonly completedGoals = new Set<string>();\n  private readonly failedGoals = new Map<string, Error>();\n\n  constructor(options: ActionClientOptions) {\n    this.ros = options.ros;\n    this.name = options.name;\n    this.actionType = options.actionType;\n    this.reconnectOnClose = options.reconnectOnClose ?? true;\n  }\n\n  sendGoal(\n    goal: TGoal,\n    onResult?: (result: ActionResult<TResult>) => void,\n    onFeedback?: (feedback: ActionFeedback<TFeedback>) => void,\n    onError?: (error: Error) => void\n  ): string {\n    const goalId = newActionGoalId();\n    return this.ros.sendActionGoal<TGoal, TResult, TFeedback>(\n      this.name,\n      this.actionType,\n      goal,\n      (result) => {\n        this.resolveWaiter(goalId);\n        onResult?.(result);\n      },\n      onFeedback,\n      (error) => {\n        this.rejectWaiter(goalId, error);\n        onError?.(error);\n      },\n      goalId\n    );\n  }\n\n  cancelGoal(goalId: string): Promise<Record<string, unknown>> {\n    this.resolveWaiter(goalId);\n    return this.ros.cancelActionGoal(this.name, goalId);\n  }\n\n  waitGoal(goalId: string, timeoutMs?: number): Promise<void> {\n    if (this.completedGoals.has(goalId)) return Promise.resolve();\n    const priorError = this.failedGoals.get(goalId);\n    if (priorError) return Promise.reject(priorError);\n\n    if (this.waiters.has(goalId)) {\n      return Promise.reject(new Error(`Already waiting for goal ${goalId}`));\n    }\n\n    return new Promise((resolve, reject) => {\n      const waiter = {\n        resolve,\n        reject,\n        timeout: undefined as ReturnType<typeof setTimeout> | undefined\n      };\n      if (timeoutMs !== undefined) {\n        waiter.timeout = setTimeout(() => {\n          this.waiters.delete(goalId);\n          reject(new Error(`Timed out waiting for action goal ${goalId}`));\n        }, timeoutMs);\n      }\n      this.waiters.set(goalId, waiter);\n    });\n  }\n\n  private resolveWaiter(goalId: string): void {\n    this.completedGoals.add(goalId);\n    this.failedGoals.delete(goalId);\n    const waiter = this.waiters.get(goalId);\n    if (!waiter) return;\n    if (waiter.timeout) clearTimeout(waiter.timeout);\n    this.waiters.delete(goalId);\n    waiter.resolve();\n  }\n\n  private rejectWaiter(goalId: string, error: Error): void {\n    this.failedGoals.set(goalId, error);\n    this.completedGoals.delete(goalId);\n    const waiter = this.waiters.get(goalId);\n    if (!waiter) return;\n    if (waiter.timeout) clearTimeout(waiter.timeout);\n    this.waiters.delete(goalId);\n    waiter.reject(error);\n  }\n}\n","/**\n * Param class — drop-in replacement for roslib's ROSLIB.Param.\n *\n * Provides get/set matching the roslib API.\n * Uses foxglove_bridge's parameter operations.\n */\n\nimport { Ros } from \"./ros\";\n\nexport interface ParamOptions {\n  ros: Ros;\n  name: string;\n}\n\nexport class Param {\n  readonly ros: Ros;\n  readonly name: string;\n\n  constructor(options: ParamOptions) {\n    this.ros = options.ros;\n    this.name = options.name;\n  }\n\n  /**\n   * Overload: callers often pass a typed callback\n   * (e.g. `(v: string) => setState(v)`) where our actual runtime value is\n   * `unknown`. TypeScript matches the generic overload at call sites while\n   * the implementation handles `unknown` — runtime validation is the\n   * caller's job, same convention as `roslib`'s original `Param.get` typing.\n   */\n  get<T>(callback: (value: T) => void): void;\n  get(callback: (value: unknown) => void): void;\n  get(callback: (value: unknown) => void): void {\n    this.ros\n      .getParam(this.name)\n      .then(callback)\n      .catch((err) => {\n        console.warn(`Param.get(\"${this.name}\") failed:`, err);\n        callback(null);\n      });\n  }\n\n  set(\n    value: unknown,\n    onSuccess?: (value?: unknown) => void,\n    onError?: (error: string) => void\n  ): void {\n    this.ros\n      .setParam(this.name, value)\n      .then(() => onSuccess?.())\n      .catch((err) => {\n        const msg = err instanceof Error ? err.message : String(err);\n        onError?.(msg);\n      });\n  }\n}\n","/**\n * Data types matching roslib's Vector3, Quaternion, and Transform classes.\n * These are simple data containers used by the TF system.\n */\n\nexport class Vector3 {\n  x: number;\n  y: number;\n  z: number;\n\n  constructor(options?: { x?: number; y?: number; z?: number }) {\n    this.x = options?.x ?? 0;\n    this.y = options?.y ?? 0;\n    this.z = options?.z ?? 0;\n  }\n}\n\nexport class Quaternion {\n  x: number;\n  y: number;\n  z: number;\n  w: number;\n\n  constructor(options?: { x?: number; y?: number; z?: number; w?: number }) {\n    this.x = options?.x ?? 0;\n    this.y = options?.y ?? 0;\n    this.z = options?.z ?? 0;\n    this.w = options?.w ?? 1;\n  }\n}\n\nexport class Transform {\n  translation: Vector3;\n  rotation: Quaternion;\n\n  constructor(options?: { translation?: Vector3; rotation?: Quaternion }) {\n    this.translation = options?.translation ?? new Vector3();\n    this.rotation = options?.rotation ?? new Quaternion();\n  }\n\n  static identity(): Transform {\n    return new Transform();\n  }\n\n  /**\n   * Invert a rigid transform: if `this` is a→b, the result is b→a. For a unit\n   * quaternion the inverse rotation is its conjugate, and the inverse\n   * translation is that conjugate applied to the negated translation.\n   */\n  inverse(): Transform {\n    const r = this.rotation;\n    const invRotation = new Quaternion({ x: -r.x, y: -r.y, z: -r.z, w: r.w });\n    const rotated = rotateVectorByQuaternion(this.translation, invRotation);\n    return new Transform({\n      translation: new Vector3({ x: -rotated.x, y: -rotated.y, z: -rotated.z }),\n      rotation: invRotation\n    });\n  }\n\n  /**\n   * Compose two rigid transforms: `this` (a→b) composed with `other` (b→c)\n   * yields the transform from a→c.\n   */\n  multiply(other: Transform): Transform {\n    // Rotate other.translation by this.rotation, then add this.translation.\n    const rotated = rotateVectorByQuaternion(other.translation, this.rotation);\n    const translation = new Vector3({\n      x: this.translation.x + rotated.x,\n      y: this.translation.y + rotated.y,\n      z: this.translation.z + rotated.z\n    });\n    const rotation = multiplyQuaternions(this.rotation, other.rotation);\n    return new Transform({ translation, rotation });\n  }\n}\n\nfunction multiplyQuaternions(a: Quaternion, b: Quaternion): Quaternion {\n  return new Quaternion({\n    x: a.w * b.x + a.x * b.w + a.y * b.z - a.z * b.y,\n    y: a.w * b.y - a.x * b.z + a.y * b.w + a.z * b.x,\n    z: a.w * b.z + a.x * b.y - a.y * b.x + a.z * b.w,\n    w: a.w * b.w - a.x * b.x - a.y * b.y - a.z * b.z\n  });\n}\n\nfunction rotateVectorByQuaternion(v: Vector3, q: Quaternion): Vector3 {\n  // Standard formula: v' = q * v * q⁻¹, expanded for efficiency.\n  const { x, y, z } = v;\n  const qx = q.x;\n  const qy = q.y;\n  const qz = q.z;\n  const qw = q.w;\n  // t = 2 * (q_vec × v)\n  const tx = 2 * (qy * z - qz * y);\n  const ty = 2 * (qz * x - qx * z);\n  const tz = 2 * (qx * y - qy * x);\n  // v' = v + qw * t + q_vec × t\n  return new Vector3({\n    x: x + qw * tx + (qy * tz - qz * ty),\n    y: y + qw * ty + (qz * tx - qx * tz),\n    z: z + qw * tz + (qx * ty - qy * tx)\n  });\n}\n\n/** Channel info advertised by foxglove_bridge. */\nexport interface FoxgloveChannel {\n  id: number;\n  topic: string;\n  encoding: string;\n  schemaName: string;\n  schema: string;\n  schemaEncoding?: string;\n}\n\n/**\n * Service schema side (request or response) as advertised by `foxglove.sdk.v1`.\n * The legacy `foxglove.websocket.v1` protocol used flat `requestSchema`/\n * `responseSchema` fields; the sdk.v1 protocol nests the encoding metadata\n * alongside the schema.\n */\nexport interface FoxgloveServiceSchemaSide {\n  encoding?: string;\n  schemaName?: string;\n  schemaEncoding?: string;\n  schema: string;\n}\n\n/** Service info advertised by foxglove_bridge. Accepts both wire shapes. */\nexport interface FoxgloveService {\n  id: number;\n  name: string;\n  type: string;\n  // Legacy flat form.\n  requestSchema?: string;\n  responseSchema?: string;\n  // sdk.v1 nested form.\n  request?: FoxgloveServiceSchemaSide;\n  response?: FoxgloveServiceSchemaSide;\n}\n\n/** Server info sent on connection. */\nexport interface FoxgloveServerInfo {\n  name: string;\n  capabilities: string[];\n  supportedEncodings?: string[];\n  metadata?: Record<string, string>;\n  sessionId?: string;\n}\n\nexport interface ActionFeedback<TFeedback = unknown> {\n  action: string;\n  id: string;\n  values: TFeedback;\n  feedback: TFeedback;\n}\n\nexport interface ActionResult<TResult = unknown> {\n  action: string;\n  id: string;\n  status: number;\n  result: boolean;\n  accepted: boolean;\n  values: TResult;\n  response: Record<string, unknown>;\n}\n\nexport const GoalStatus = {\n  STATUS_UNKNOWN: 0,\n  STATUS_ACCEPTED: 1,\n  STATUS_EXECUTING: 2,\n  STATUS_CANCELING: 3,\n  STATUS_SUCCEEDED: 4,\n  STATUS_CANCELED: 5,\n  STATUS_ABORTED: 6\n} as const;\n","/**\n * ROS2TFClient — drop-in replacement for roslib's ROSLIB.ROS2TFClient.\n *\n * Subscribes to /tf and /tf_static topics, builds a parent→child transform\n * graph, and resolves transforms from `fixedFrame` to any requested frame by\n * chaining through intermediate frames.\n */\n\nimport { z } from \"zod\";\n\nimport { Ros, type MessageCallback } from \"./ros\";\nimport { Transform, Vector3, Quaternion } from \"./types\";\n\nexport interface TFClientOptions {\n  ros: Ros;\n  fixedFrame?: string;\n  angularThres?: number;\n  transThres?: number;\n  /**\n   * Max /tf processing rate in Hz (roslib semantics). Throttled client-side to\n   * a `1000 / rate` ms leading-edge window; 0 / undefined / non-finite disables\n   * throttling. /tf_static is never throttled (see subscribeTF).\n   */\n  rate?: number;\n  serverName?: string;\n}\n\n/**\n * Runtime shape of a `tf2_msgs/TFMessage` as deserialized from CDR by the\n * Ros class. Validated with zod at the subscription edge so downstream\n * code works with properly typed values instead of casting the generic\n * `Record<string, unknown>` coming off the wire.\n */\nconst tfMessageSchema = z.object({\n  transforms: z.array(\n    z.object({\n      header: z.object({\n        stamp: z.object({ sec: z.number(), nanosec: z.number() }),\n        frame_id: z.string()\n      }),\n      child_frame_id: z.string(),\n      transform: z.object({\n        translation: z.object({ x: z.number(), y: z.number(), z: z.number() }),\n        rotation: z.object({\n          x: z.number(),\n          y: z.number(),\n          z: z.number(),\n          w: z.number()\n        })\n      })\n    })\n  )\n});\ntype TFMessage = z.infer<typeof tfMessageSchema>;\n\ntype TFCallback = (transform: Transform) => void;\n\n/**\n * Notified whenever the set of frames known to the client grows. Receives the\n * full sorted frame list. Used by the TF visualization layer to populate the\n * frame-selection UI; not part of roslib's ROS2TFClient API.\n */\ntype FramesCallback = (frames: string[]) => void;\n\n/**\n * Stored direct transform: parent → child, keyed by child frame id. One entry\n * per child — `resolveTransform` relies on each frame having a single parent, so\n * a frame published by multiple authorities is reduced to last-writer-wins (with\n * a one-time warning; see `handleTFMessage`).\n */\ninterface ParentedTransform {\n  parentFrame: string;\n  transform: Transform;\n}\n\n/** Strip any leading slash so keys compare consistently. */\nfunction normalizeFrameId(frame: string): string {\n  return frame.replace(/^\\/+/, \"\");\n}\n\n/**\n * Return a unit quaternion. TF rotations enter straight off the wire and zod\n * only checks the four fields are numbers, not that ‖q‖≈1; `Transform.inverse`\n * and composition assume unit quaternions, so a drifted or hand-edited rotation\n * would otherwise skew every descendant frame. Falls back to identity for a\n * degenerate (zero-norm) quaternion.\n */\nfunction normalizeQuaternion(q: {\n  x: number;\n  y: number;\n  z: number;\n  w: number;\n}): Quaternion {\n  const norm = Math.hypot(q.x, q.y, q.z, q.w);\n  if (norm === 0) {\n    return new Quaternion({ x: 0, y: 0, z: 0, w: 1 });\n  }\n  return new Quaternion({ x: q.x / norm, y: q.y / norm, z: q.z / norm, w: q.w / norm });\n}\n\n/**\n * Leading-edge throttle: fire immediately, then drop calls until `windowMs`\n * elapses (no trailing catch-up). Uses the monotonic `performance.now()` clock\n * so a long-running UI is immune to wall-clock changes. foxglove_bridge delivers\n * every published message (no server-side rate cap, see topic.ts), so /tf is\n * capped here. Mirrors the throttle in `Topic`.\n */\nfunction throttleLeadingEdge(fn: MessageCallback, windowMs: number): MessageCallback {\n  let lastFiredAt = -Infinity;\n  return (msg) => {\n    const now = performance.now();\n    if (now - lastFiredAt < windowMs) return;\n    lastFiredAt = now;\n    fn(msg);\n  };\n}\n\nexport class ROS2TFClient {\n  private readonly ros: Ros;\n  private readonly fixedFrame: string;\n  private readonly frameCallbacks = new Map<string, Set<TFCallback>>();\n  /** child_frame_id → {parent, local transform}. One entry per child. */\n  private readonly directTransforms = new Map<string, ParentedTransform>();\n  // Every frame id ever seen as a parent or child, for enumeration. Grows\n  // monotonically for the life of the client (only dispose() clears it), which\n  // assumes frame ids are stable for a connection — true for a fixed robot, but\n  // a source that mints transient frame ids would accumulate stale entries.\n  private readonly knownFrames = new Set<string>();\n  private readonly framesListeners = new Set<FramesCallback>();\n  // Children for which a conflicting parent has already been reported, so the\n  // multi-authority warning fires once per child rather than every tick.\n  private readonly multiParentWarned = new Set<string>();\n  private tfSub: MessageCallback | null = null;\n  private tfStaticSub: MessageCallback | null = null;\n  private readonly onReconnect: () => void;\n  private readonly throttleMs: number;\n  private parseWarned = false;\n  private disposed = false;\n\n  constructor(options: TFClientOptions) {\n    this.ros = options.ros;\n    this.fixedFrame = normalizeFrameId(options.fixedFrame ?? \"world\");\n    // rate is in Hz; convert to a ms throttle window. 0 / non-finite disables it.\n    const rate = options.rate ?? 0;\n    this.throttleMs = Number.isFinite(rate) && rate > 0 ? 1000 / rate : 0;\n    // The foxglove Ros reuses the same instance across reconnects and clears all\n    // subscription state on close, so a one-time constructor subscription is\n    // silently dropped on the first WebSocket drop. Re-subscribe on reconnect —\n    // the same invariant `useTopicSubscription` maintains for ordinary topics.\n    this.onReconnect = () => this.subscribeTF();\n    this.ros.on(\"connection\", this.onReconnect);\n    this.subscribeTF();\n  }\n\n  subscribe(frameId: string, callback: TFCallback): void {\n    if (this.warnIfDisposed(\"subscribe\")) return;\n    const key = normalizeFrameId(frameId);\n    let callbacks = this.frameCallbacks.get(key);\n    if (!callbacks) {\n      callbacks = new Set();\n      this.frameCallbacks.set(key, callbacks);\n    }\n    callbacks.add(callback);\n\n    // If we can already resolve the chain, deliver the current transform.\n    const resolved = this.resolveTransform(key);\n    if (resolved) {\n      callback(resolved);\n    }\n  }\n\n  unsubscribe(frameId: string, callback?: TFCallback): void {\n    const key = normalizeFrameId(frameId);\n    if (callback) {\n      const callbacks = this.frameCallbacks.get(key);\n      callbacks?.delete(callback);\n      // Drop the now-empty Set so a session that toggles many frames on and off\n      // doesn't accumulate empty entries keyed by every frame ever subscribed.\n      if (callbacks?.size === 0) {\n        this.frameCallbacks.delete(key);\n      }\n    } else {\n      this.frameCallbacks.delete(key);\n    }\n  }\n\n  /**\n   * Sorted list of every frame seen so far on /tf or /tf_static (as a parent or\n   * child). MoveIt Pro extension used to drive the TF visualization frame list.\n   */\n  getFrameIds(): string[] {\n    return [...this.knownFrames].sort((a, b) => a.localeCompare(b));\n  }\n\n  /**\n   * Register a listener fired whenever new frames appear. Invoked immediately\n   * with the current frame list so callers don't miss frames seen before they\n   * subscribed. MoveIt Pro extension, not part of roslib's ROS2TFClient.\n   */\n  addFramesListener(callback: FramesCallback): void {\n    if (this.warnIfDisposed(\"addFramesListener\")) return;\n    this.framesListeners.add(callback);\n    callback(this.getFrameIds());\n  }\n\n  removeFramesListener(callback: FramesCallback): void {\n    this.framesListeners.delete(callback);\n  }\n\n  dispose(): void {\n    this.disposed = true;\n    this.ros.off(\"connection\", this.onReconnect);\n    if (this.tfSub) {\n      this.ros.unsubscribeTopic(\"/tf\", this.tfSub);\n      this.tfSub = null;\n    }\n    if (this.tfStaticSub) {\n      this.ros.unsubscribeTopic(\"/tf_static\", this.tfStaticSub);\n      this.tfStaticSub = null;\n    }\n    this.frameCallbacks.clear();\n    this.directTransforms.clear();\n    this.knownFrames.clear();\n    this.framesListeners.clear();\n    this.multiParentWarned.clear();\n  }\n\n  /** Warn once if a mutating method is called on a disposed client. */\n  private warnIfDisposed(method: string): boolean {\n    if (this.disposed) {\n      console.warn(`ROS2TFClient.${method}() called after dispose(); ignoring.`);\n    }\n    return this.disposed;\n  }\n\n  private subscribeTF(): void {\n    // Idempotent: drop any existing handles before re-subscribing. The\n    // constructor calls this once, and the \"connection\" handler calls it again\n    // on every (re)connect — including the first connect when the client was\n    // built before the socket opened. Without tearing down first, that race\n    // would double-subscribe and orphan the previous callbacks (dispose only\n    // tracks the latest). On a real reconnect the foxglove Ros has already\n    // cleared its side, so these unsubscribes are harmless no-ops.\n    if (this.tfSub) this.ros.unsubscribeTopic(\"/tf\", this.tfSub);\n    if (this.tfStaticSub) this.ros.unsubscribeTopic(\"/tf_static\", this.tfStaticSub);\n\n    // Distinct callback identities — Topic.unsubscribe keys by reference, so\n    // sharing one arrow makes dispose()'s second unsubscribe a no-op.\n    const dispatch: MessageCallback = (msg) => this.dispatchTFMessage(msg);\n\n    // /tf can arrive far faster than we redraw, so throttle it client-side when\n    // a rate was requested. /tf_static is latched and low-volume, and a dropped\n    // static transform is lost permanently (never re-published), so it is never\n    // throttled. When throttleMs is 0 the dispatch callback is registered\n    // directly, so the hot path takes no wrapper overhead (same as Topic).\n    this.tfSub =\n      this.throttleMs > 0 ? throttleLeadingEdge(dispatch, this.throttleMs) : dispatch;\n    this.ros.subscribeTopic(\"/tf\", \"tf2_msgs/msg/TFMessage\", this.tfSub);\n\n    this.tfStaticSub = (msg) => this.dispatchTFMessage(msg);\n    this.ros.subscribeTopic(\"/tf_static\", \"tf2_msgs/msg/TFMessage\", this.tfStaticSub);\n  }\n\n  private dispatchTFMessage(msg: unknown): void {\n    const parsed = tfMessageSchema.safeParse(msg);\n    if (parsed.success) {\n      this.handleTFMessage(parsed.data);\n    } else if (!this.parseWarned) {\n      // Warn once rather than every tick so a wire-shape drift (e.g. a tf2_msgs\n      // field rename across distros) is visible instead of silently empty.\n      this.parseWarned = true;\n      console.warn(\"ROS2TFClient: ignoring /tf message that failed schema validation.\");\n    }\n  }\n\n  /**\n   * Warn once per child when it is published with a parent different from the\n   * one already stored. A frame with two live parents is a malformed tree (tf2\n   * surfaces this as a multiple-authority warning). We keep last-writer-wins so\n   * resolution still works, but a silent pick can resolve through a different\n   * parent than tf2/RViz would, so make the misconfiguration visible.\n   */\n  private warnIfReparented(childFrame: string, parentFrame: string): void {\n    const existing = this.directTransforms.get(childFrame);\n    if (\n      !existing ||\n      existing.parentFrame === parentFrame ||\n      this.multiParentWarned.has(childFrame)\n    ) {\n      return;\n    }\n    this.multiParentWarned.add(childFrame);\n    console.warn(\n      `TF: frame \"${childFrame}\" is published with multiple parents ` +\n        `(\"${existing.parentFrame}\" and \"${parentFrame}\"); using the most ` +\n        `recent. This is a malformed TF tree and may render differently from RViz.`\n    );\n  }\n\n  private handleTFMessage(msg: TFMessage): void {\n    // Whether any edge was updated this tick. The re-resolution pass below\n    // ignores *which* edges changed (it re-resolves every subscribed frame), so\n    // a boolean is enough — no need to allocate a Set per tick.\n    let anyChanged = false;\n    const framesBefore = this.knownFrames.size;\n\n    for (const tfStamped of msg.transforms) {\n      const childFrame = normalizeFrameId(tfStamped.child_frame_id);\n      const parentFrame = normalizeFrameId(tfStamped.header.frame_id);\n      const t = tfStamped.transform;\n\n      this.knownFrames.add(childFrame);\n      this.knownFrames.add(parentFrame);\n\n      const transform = new Transform({\n        translation: new Vector3({\n          x: t.translation.x,\n          y: t.translation.y,\n          z: t.translation.z\n        }),\n        // Normalize at the ingest boundary so downstream inverse/compose can\n        // assume unit quaternions (see normalizeQuaternion).\n        rotation: normalizeQuaternion(t.rotation)\n      });\n\n      this.warnIfReparented(childFrame, parentFrame);\n      this.directTransforms.set(childFrame, { parentFrame, transform });\n      anyChanged = true;\n    }\n\n    // Notify frame-list listeners only when the known set actually grew, so\n    // the steady state (same frames re-published every tick) costs nothing.\n    if (this.knownFrames.size !== framesBefore) {\n      const frames = this.getFrameIds();\n      for (const listener of this.framesListeners) {\n        listener(frames);\n      }\n    }\n\n    if (!anyChanged) return;\n\n    // A change to frame X's direct transform can affect any subscriber whose\n    // resolved chain passes through X. Cheaper than computing exact impact:\n    // re-resolve every subscribed frame and deliver if resolution succeeds.\n    for (const [frameId, callbacks] of this.frameCallbacks) {\n      if (callbacks.size === 0) continue;\n      const resolved = this.resolveTransform(frameId);\n      if (resolved) {\n        for (const cb of callbacks) {\n          cb(resolved);\n        }\n      }\n    }\n  }\n\n  /**\n   * Resolve the transform from `fixedFrame` to `frameId`, i.e. the pose of\n   * `frameId` expressed in `fixedFrame`.\n   *\n   * tf2 (and RViz) can relate any two connected frames, not just a frame and\n   * its descendant: it walks both frames up to their lowest common ancestor and\n   * inverts one side. We do the same. Walking only child→parent from `frameId`\n   * to `fixedFrame` (the previous approach) silently failed for any frame that\n   * is an ancestor of — or in a sibling branch to — `fixedFrame`, which is the\n   * common case for mobile-base trees where the reference frame sits below\n   * `map`/`odom`.\n   *\n   * Returns null if the two frames are not connected (yet) or the tree is\n   * malformed (cycle).\n   *\n   * Time semantics: this composes each edge's most recent value. Unlike tf2 it\n   * does not interpolate edges to a common timestamp, so during fast motion with\n   * edges published at different rates the result can briefly lead or lag tf2's.\n   * For a visualization layer this is an accepted simplification.\n   */\n  private resolveTransform(frameId: string): Transform | null {\n    if (frameId === this.fixedFrame) {\n      return Transform.identity();\n    }\n\n    // Fast path for a direct child of the fixed frame — by far the most common\n    // case (markers, tip frames) — avoids allocating the ancestor map every tick.\n    const direct = this.directTransforms.get(frameId);\n    if (direct !== undefined) {\n      if (direct.parentFrame === this.fixedFrame) {\n        return direct.transform;\n      }\n    }\n\n    // Map each ancestor A of frameId (including frameId itself) to T_A_frameId.\n    const targetAncestors = this.ancestorTransforms(frameId);\n    if (!targetAncestors) return null;\n\n    // Walk up from fixedFrame until we reach a frame that is also an ancestor\n    // of frameId — the lowest common ancestor (LCA). `tFixed` accumulates\n    // T_current_fixedFrame as we climb.\n    let current = this.fixedFrame;\n    let tFixed = Transform.identity();\n    const visited = new Set<string>();\n    for (;;) {\n      const tToTarget = targetAncestors.get(current);\n      if (tToTarget) {\n        // current is the LCA: T_LCA_fixedFrame = tFixed, T_LCA_frameId = tToTarget.\n        // T_fixedFrame_frameId = inverse(T_LCA_fixedFrame) ∘ T_LCA_frameId.\n        return tFixed.inverse().multiply(tToTarget);\n      }\n      if (visited.has(current)) return null;\n      visited.add(current);\n      const direct = this.directTransforms.get(current);\n      if (!direct) return null; // reached a root with no common ancestor — disconnected.\n      tFixed = direct.transform.multiply(tFixed);\n      current = direct.parentFrame;\n    }\n  }\n\n  /**\n   * Walk from `frameId` up to its tree root, returning a map from every\n   * ancestor frame (including `frameId`) to the transform expressing `frameId`\n   * in that ancestor's frame. Returns null on a cycle.\n   */\n  private ancestorTransforms(frameId: string): Map<string, Transform> | null {\n    const ancestors = new Map<string, Transform>();\n    let current = frameId;\n    let accumulated = Transform.identity(); // T_current_frameId\n    ancestors.set(current, accumulated);\n\n    const visited = new Set<string>();\n    for (;;) {\n      if (visited.has(current)) return null;\n      visited.add(current);\n      const direct = this.directTransforms.get(current);\n      if (!direct) return ancestors; // reached the root.\n      accumulated = direct.transform.multiply(accumulated);\n      current = direct.parentFrame;\n      ancestors.set(current, accumulated);\n    }\n  }\n}\n"]}