| 145 | } |
| 146 | } |
| 147 | |
| 148 | // ─── Packet encoding ───────────────────────────────────────────────────────── |
| 149 | |
| 150 | const MAGIC = Buffer.from([0x33, 0xc6, 0x00, 0x01]); |
| 151 | const HEADER_SIZE = 8; // 4 magic + 4 uint32LE length |
| 152 | // Heap dumps and element snapshots legitimately exceed trace-sized payloads. Keep generic |
| 153 | // framing bounded while applying the tighter trace limit once the inner request is identified. |
| 154 | export const MAX_DAEMON_INNER_PAYLOAD_BYTES = 64 * 1024 * 1024; |
| 155 | export const MAX_DAEMON_PACKET_PAYLOAD_BYTES = 128 * 1024 * 1024; |
| 156 | export const MAX_DAEMON_TRACE_PAYLOAD_BYTES = 4 * 1024 * 1024; |
| 157 | const MAX_DAEMON_BUFFERED_BYTES = HEADER_SIZE + MAX_DAEMON_PACKET_PAYLOAD_BYTES; |
| 158 | |
| 159 | function encodePacket(json: object): Buffer { |
| 160 | const serialized = JSON.stringify(json); |
| 161 | const payloadLength = Buffer.byteLength(serialized, 'utf8'); |
| 162 | if (payloadLength > MAX_DAEMON_PACKET_PAYLOAD_BYTES) { |
| 163 | throw new Error(`ValdiPacket payload exceeds the ${MAX_DAEMON_PACKET_PAYLOAD_BYTES}-byte limit.`); |
| 164 | } |
| 165 | const payload = Buffer.from(serialized, 'utf8'); |
| 166 | const header = Buffer.alloc(8); |
| 167 | MAGIC.copy(header, 0); |
| 168 | header.writeUInt32LE(payload.length, 4); |
| 169 | return Buffer.concat([header, payload]); |
| 170 | } |
| 171 | |
| 172 | // ─── DaemonConnection ──────────────────────────────────────────────────────── |
| 173 | |
| 174 | // In the direct-to-device protocol we are "client 1" (non-zero required by device JS check). |
| 175 | const DIRECT_CLIENT_ID = 1; |
| 176 | const ADB_FORWARD_REFRESH_INTERVAL_MS = 5000; |
| 177 | const adbForwardedAtByEndpoint = new Map<string, number>(); |
| 178 | const adbForwardRefreshByEndpoint = new Map<string, Promise<void>>(); |
| 179 | |
| 180 | interface PendingRequest { |
| 181 | resolve: (value: Record<string, unknown>) => void; |
| 182 | reject: (err: Error) => void; |
| 183 | } |
| 184 | |
| 185 | interface PendingPayloadRequest extends PendingRequest { |