import { EventEmitter } from 'node:events'; import { type EnvConfig } from '../config/env.js'; import { type BridgeHello } from './protocol.js'; export type BridgeState = 'disconnected' | 'connecting' | 'connected' | 'error'; export declare class BridgeManager extends EventEmitter { state: BridgeState; hello: BridgeHello | null; private wss; private ws; private heartbeatTimer; private reconnectTimer; private staleSweepTimer; private _activePort; private _connectedAtMs; private requestMap; private requestIdCounter; private config; private _lastHeartbeatMs; private reconnectAttempts; private reconnectStartMs; private pairingChallenges; private _methodRegistryHash; private _extensionVersion; private _extensionMethodListHash; private _loaderVersion; constructor(config: EnvConfig); get lastHeartbeatMs(): number; get activePort(): number; get uptimeMs(): number; get connected(): boolean; /** * Wait until the bridge is in the 'connected' state. * Resolves immediately if already connected. Rejects after timeoutMs. */ waitForConnection(timeoutMs: number): Promise; get methodRegistryHash(): string; /** EasyEDA Pro application version reported at the last successful handshake. */ get easyedaVersion(): string | undefined; /** Bridge extension version reported at the last successful handshake. */ get extensionVersion(): string | undefined; /** Whether the connected extension's version differs from this server's version. */ get extensionVersionMismatch(): boolean; /** Method-list hash reported by the extension's active dispatcher at handshake. */ get extensionMethodListHash(): string | undefined; /** Extension loader version reported at handshake (tracks the .eext import). */ get loaderVersion(): string | undefined; /** * True when the extension reported a dispatcher method-list hash that does * not match this server's method registry — i.e. the extension is serving * stale (or newer) dispatch logic. Undefined-hash extensions (older builds) * report false here; extension_version_mismatch covers those. */ get registryMismatch(): boolean; private isLoopbackHost; private computeMethodRegistryHash; connect(): Promise; private tryListen; private handleConnection; /** * Validate and accept a handshake message. Sets up the bridge session * and replies with a hello containing the server's capabilities. */ private handleHandshake; /** * Validate and handle an incoming request from the extension. * The server does not currently accept arbitrary extension requests, * so unknown methods are rejected with a structured error response. */ private handleIncomingRequest; call(method: string, params?: TParams, opts?: { timeoutMs?: number; traceparent?: string; }): Promise; disconnect(reason?: string): void; private handleResponse; private rejectPending; private startHeartbeat; private stopHeartbeat; /** * Schedule a reconnect attempt with tiered backoff. Never stops retrying. * Tiers (elapsed since first disconnect): * 0–30 s → 1 s interval * 30–120 s → 3 s interval * >120 s → 10 s interval * Each delay has ±10 % jitter. */ private scheduleReconnect; private clearReconnectTimer; /** * Periodically sweep the pending-request map for entries whose * timeout has elapsed but whose `setTimeout` may have been leaked * (defence-in-depth). Runs every 30 s while connected. */ private startStaleSweep; private stopStaleSweep; } /** * Parse a port scan specification string into an ordered array of ports. * Supports comma-separated values and dash ranges: * "18601" → [18601] * "18601,49620" → [18601, 49620] * "49620-49629" → [49620, 49621, ..., 49629] * "18601,49620-49629" → [18601, 49620, 49621, ..., 49629] */ export declare function parsePortScanSpec(spec: string): number[];