import Gio from '@girs/gio-2.0'; import { Duplex } from 'node:stream'; import type { DuplexOptions } from 'node:stream'; export interface SocketConnectOptions { port: number; host?: string; localAddress?: string; localPort?: number; family?: 4 | 6 | 0; keepAlive?: boolean; keepAliveInitialDelay?: number; noDelay?: boolean; timeout?: number; } export interface SocketOptions extends DuplexOptions { allowHalfOpen?: boolean; } export declare class Socket extends Duplex { remoteAddress?: string; remotePort?: number; remoteFamily?: string; localAddress?: string; localPort?: number; bytesRead: number; bytesWritten: number; connecting: boolean; destroyed: boolean; pending: boolean; readyState: 'opening' | 'open' | 'readOnly' | 'writeOnly' | 'closed'; allowHalfOpen: boolean; private _connection; private _ioStream; private _inputStream; private _outputStream; private _cancellable; private _reading; private _timeout; private _timeoutId; constructor(options?: SocketOptions); /** @internal Set the connection from an accepted server socket. */ _setConnection(connection: Gio.SocketConnection): void; /** * @internal Set up this socket from a raw Gio.IOStream (e.g., stolen from Soup.Server * during an HTTP upgrade). Extracts I/O streams, attempts to read address info * if the underlying stream is a SocketConnection, and starts reading. */ _setupFromIOStream(ioStream: Gio.IOStream): void; /** * @internal For HTTP upgrade handoff: configures write capability and address * info from the IOStream but does NOT start the async read loop. Used by * http.Server._handleRequest so handleUpgrade() can write the 101 response and * then hand the IOStream to Soup.WebsocketConnection without a read-loop race. */ _attachOutputOnly(ioStream: Gio.IOStream): void; /** Release IOStream ownership to the caller (Soup.WebsocketConnection handoff). * Nullifies the socket's stream references so they are not closed when the * socket itself is later destroyed. */ _releaseIOStream(): Gio.IOStream | null; /** * Initiate a TCP connection. */ connect(options: SocketConnectOptions | number, host?: string | (() => void), connectionListener?: () => void): this; /** @internal Set up streams and emit connect after connection is established. */ _setupConnection(opts: SocketConnectOptions | Record): void; private _startReading; private _readLoop; _read(_size: number): void; _write(chunk: unknown, encoding: string, callback: (error?: Error | null) => void): void; _final(callback: (error?: Error | null) => void): void; _destroy(err: Error | null, callback: (error?: Error | null) => void): void; /** Set the socket timeout in milliseconds. 0 disables. */ setTimeout(timeout: number, callback?: () => void): this; private _resetTimeout; private _clearTimeout; /** Enable/disable TCP keep-alive. */ setKeepAlive(enable?: boolean, _initialDelay?: number): this; /** Enable/disable TCP_NODELAY (disable Nagle algorithm). */ setNoDelay(noDelay?: boolean): this; /** Half-close then destroy: end() if writable, destroy() once finished. */ destroySoon(): void; /** Get the underlying socket address info. */ address(): { port: number; family: string; address: string; } | {}; /** Reference this socket (keep event loop alive). No-op in GJS. */ ref(): this; /** Unreference this socket. No-op in GJS. */ unref(): this; }