import type { ProfileType } from './debugSession/Events'; /** * Configuration interface for Perfetto tracing */ interface PerfettoConfig { host: string; enabled?: boolean; dir?: string; filename?: string; rootDir?: string; remotePort?: number; /** Channel ID to trace. Defaults to 'dev'. */ channelId?: string; } export declare class PerfettoManager { /** * How long the trace stream must be silent before we consider the device finished and close the socket. * Must comfortably exceed the device's counter cadence (~250ms) so a normal gap between samples isn't mistaken for "done". */ private static readonly stopQuietWindowMs; /** * Hard ceiling on how long we'll wait for the stream to go quiet after initiating close, in case a device never stops streaming. */ private static readonly stopCeilingMs; constructor(config?: PerfettoConfig); private config; private socket; private writeStream; private pingTimer; private emitter; /** * Timestamp (ms) of the most recent trace message written to disk. Used when stopping to detect when the * device has gone quiet so we can close without waiting on the WebSocket closing handshake. */ private lastMessageTime; /** * When tracing is active, this is the file we're currently writing to. Cleaned up whenever tracing stops or errors. */ private filePath?; private logger; /** * Are we actively tracing right now */ private get isTracing(); /** * Subscribe to PerfettoManager events */ on(eventName: 'enable', handler: (data: { types: ProfileType[]; }) => void): () => void; on(eventName: 'start', handler: (data: { type: ProfileType; }) => void): () => void; on(eventName: 'stop', handler: (data: { type: ProfileType; result?: string; }) => void): () => void; on(eventName: 'error', handler: (data: { type: ProfileType; error: { message: string; stack?: string; }; }) => void): () => void; private emit; /** * Get app title from manifest file in cwd */ private getAppTitle; private createWebSocket; /** * Start Perfetto tracing * @param includeResultOnStop whether to include the file path when the 'stop' event fires. This should be false if the caller is going to emit their own 'stop' event (like when heapSnapshot is the activator of tracing. */ startTracing(options?: { excludeResultOnStop: boolean; }): Promise; private getFilename; /** * Get the next sequence number by scanning existing files in the directory */ private getNextSequenceNumber; /** * Stop Perfetto tracing gracefully. */ stopTracing(): Promise; /** * Enable tracing on the Roku device. This returns true if we were successful, and throws if we we failed to enable */ enableTracing(): Promise; /** * Create a write stream for the given file path, wrapped in a promise to handle async stream readiness and errors. * This ensures we don't start writing until the stream is ready, and that any errors are properly caught and emitted. * @param filePath * @returns */ private createWriteStream; private startPingTimer; /** * Close the trace socket without hanging on the WebSocket closing handshake. * * The Roku `/perfetto-session` server stops streaming the instant it receives our close frame, but it never sends * a close frame back, so a plain `socket.close()` would block for the full `ws` close timeout (~30s) before the * socket is force-destroyed. Instead we send the close frame, wait for the trace stream to go quiet (capturing any * final flush from the device), then terminate the socket so the 'close' event fires immediately. A hard ceiling * guards against a device that never stops streaming. */ private closeSocket; /** * Clean up all resources. Safe to call multiple times. * When isCrash is true, destroys the write stream immediately instead of flushing it. */ private cleanup; /** * Get the file path if it exists on disk, otherwise undefined. Empty trace files are still reported; the * client (VS Code) renders a dedicated empty-state for zero-byte traces. */ private getResult; /** * Dispose of all resources. Safe to call multiple times. * Closes all sockets, file handles, and timers. */ dispose(): Promise; /** * Capture a heap graph snapshot. Can only be called when tracing is active and WebSocket is connected. */ captureHeapSnapshot(): Promise; /** * Helper to emit an error and also return it for throwing. This ensures all errors go through the same handling and are emitted to any listeners. */ private emitError; } export {};