import { SerialEventEmitter } from './SerialEventEmitter.js';
import { SerialDeviceOptions, SerialPolyfillOptions, SerialProvider } from '../types/index.js';
/**
 * Abstract base class for all serial devices.
 *
 * @typeParam T - Type of parsed data emitted by `"serial:data"` events.
 *   Use `string` with a delimiter parser, `Uint8Array` for raw/fixed-length,
 *   or any custom type with a custom parser.
 */
export declare abstract class AbstractSerialDevice<T> extends SerialEventEmitter<T> {
    /** The currently open serial port, or `null` when disconnected. */
    protected port: SerialPort | null;
    private reader;
    private writer;
    private queue;
    private options;
    private isConnecting;
    private abortController;
    private userInitiatedDisconnect;
    private reconnectTimerId;
    private isHandshaking;
    /**
     * Custom serial provider (e.g. a WebUSB polyfill).
     * Falls back to `navigator.serial` when not set.
     */
    private static customProvider;
    /**
     * Options forwarded to the polyfill provider on every
     * `requestPort()` / `getPorts()` call.
     */
    private static polyfillOptions;
    constructor(options: SerialDeviceOptions<T>);
    /**
     * Override this method in your subclass to perform a handshake
     * after the port is opened. Return `true` if the handshake
     * succeeds (correct device), or `false` to reject the port.
     *
     * The method receives the opened port and should write/read
     * directly to validate the device identity.
     *
     * If not overridden, all ports are accepted (no handshake).
     */
    protected handshake(): Promise<boolean>;
    connect(): Promise<void>;
    disconnect(): Promise<void>;
    /**
     * Returns `true` if the device is currently connected and the port
     * is open, readable, and writable. Note that a port can become
     * disconnected at any time (e.g. unplugged), so this is not a
     * guarantee that a subsequent read/write will succeed, but it is
     * a useful check before attempting communication.
     * @returns `true` if the device is connected and ready for communication, `false` otherwise.
     */
    isConnected(): boolean;
    /**
     * Returns `true` if the device is not connected or in the process of connecting.
     * This is a convenience method equivalent to `!isConnected()`, but may be more
     * semantically clear in certain contexts (e.g. when checking for disconnection
     * in a read loop catch block).
     * @returns `true` if the device is disconnected or not ready, `false` if it is currently connected.
     */
    isDisconnected(): boolean;
    /**
     * Internal cleanup: tears down the port, reader, writer without
     * marking it as user-initiated. This allows auto-reconnect to trigger.
     */
    private cleanupPort;
    forget(): Promise<void>;
    send(data: string | Uint8Array): Promise<void>;
    clearQueue(): void;
    private writeToPort;
    private readLoop;
    /**
     * Opens a port, locks it in the registry, starts reading, and runs the handshake.
     * If handshake fails, tears down reader/queue, closes and unlocks the port.
     */
    private openAndHandshake;
    /**
     * Cleans up after a failed handshake attempt and restores the queue.
     */
    private teardownHandshake;
    /**
     * Cancels and releases the current reader.
     */
    private stopReader;
    /**
     * Wraps the handshake() in a timeout race.
     */
    private runHandshakeWithTimeout;
    /**
     * Iterates ALL previously-authorized ports matching filters.
     * For each match, opens + handshake. Returns the first port that passes.
     * If a port fails handshake, it is closed and the next one is tried.
     */
    private findAndValidatePort;
    private startReconnecting;
    stopReconnecting(): void;
    private reconnect;
    static getInstances(): AbstractSerialDevice<unknown>[];
    static connectAll(): Promise<void>;
    /**
     * Sets a custom serial provider (e.g. a WebUSB polyfill for Android).
     * Call this once before any `connect()` if the native Web Serial API
     * is not available.
     *
     * @param provider  The provider object (`{ requestPort, getPorts }`).
     * @param options   Polyfill options forwarded on every `requestPort` /
     *                  `getPorts` call.  Use `usbControlInterfaceClass` to
     *                  support devices that don't use the standard CDC class
     *                  code (2). E.g. `{ usbControlInterfaceClass: 255 }`.
     *
     * @example
     * ```ts
     * import { serial as polyfill } from 'web-serial-polyfill';
     * AbstractSerialDevice.setProvider(polyfill, {
     *   usbControlInterfaceClass: 255,
     * });
     * ```
     */
    static setProvider(provider: SerialProvider, options?: SerialPolyfillOptions): void;
    /**
     * Returns the serial provider: instance provider > custom provider > navigator.serial > null.
     */
    private getSerial;
}
