import * as fs from 'fs'; import WebSocket from 'ws'; import type { OpenFileStreamFrame } from './protocol.js'; /** * Sending a file the OTHER way: the server wants the bytes of a file that lives on THIS device * (`send_file device=…`). It reuses the reverse channel the port forward already proved — the * server asks over the control socket, we dial a new outbound WebSocket back and push the file * into it as binary frames. * * Why not answer on the control socket like every other command: a command result is one JSON * message, so a file would have to be base64'd whole into memory on both ends and would block * every other command for the device while it is in flight. A dedicated socket streams, costs no * base64, and a failure takes down only that transfer. * * The server always validates the path with a `file.stat` command FIRST, so by the time this runs * the file is known to exist and to be within the size cap. Anything that still goes wrong is * reported by closing the socket with a 4010 code and the reason text — never by a partial file * that looks complete, because the server also checks the byte count against the stat'd size. */ export declare function isOpenFileStream(msg: unknown): msg is OpenFileStreamFrame; /** Close code carrying a read-side failure; the reason text is the message the server surfaces. */ export declare const FILE_STREAM_ERROR_CODE = 4010; export interface FileStreamDeps { controlUrl: string; headers?: Record; /** Applied to the requested path (Windows drive-letter rewriting on the client). */ normalizePath?: (p: string) => string; connectWs?: (url: string, headers?: Record) => WebSocket; openRead?: (filePath: string) => fs.ReadStream; } /** * Serve one open-file-stream request. Like `openReverseStream`, every failure is contained: the * sockets are closed and the control connection — which carries the whole device — is untouched. */ export declare function openFileStream(msg: OpenFileStreamFrame, deps: FileStreamDeps): void;