{"version":3,"file":"index.cjs","names":[],"sources":["../src/index.ts"],"sourcesContent":["import {existsSync} from \"node:fs\";\nimport {createConnection as createNetConnection, Socket} from \"node:net\";\nimport {EventEmitter} from \"node:events\";\nimport {Duplex} from \"node:stream\";\nimport {connect as connectTls, TLSSocket} from \"node:tls\";\nimport type {ConnectionOptions as TlsConnectionOptions} from \"node:tls\";\n\nimport type {\n    AbortOperation,\n    AssertOperation,\n    CommentOperation,\n    CommitOperation,\n    DatabaseOperation,\n    DatabaseSchema,\n    DatabaseTableMap,\n    DeleteOperation,\n    InsertOperation,\n    JsonObject,\n    JsonValue,\n    ListDbsResult,\n    LockedNotification,\n    MutateOperation,\n    MonitorCondRequest,\n    MonitorCondSinceResult,\n    MonitorRequest,\n    OperationResult,\n    OperationResults,\n    OvsdbError,\n    OvsdbNotification,\n    OvsdbResponse,\n    OvsdbValue,\n    SelectOperation,\n    StolenNotification,\n    TableUpdates,\n    TableUpdates2,\n    Update2Notification,\n    Update3Notification,\n    UpdateNotification,\n    UpdateOperation,\n    WaitOperation\n} from \"./types\";\n\n/**\n * A socket-compatible stream used by the client transport.\n */\nexport type OvsdbStream = Duplex | Socket | TLSSocket;\n\n/**\n * Supported connection modes for the OVSDB transport.\n */\nexport type OvsdbTransportKind = \"unix\" | \"tcp\" | \"tls\";\n\n/**\n * Resolved Unix socket transport settings.\n */\nexport interface OvsdbUnixConnectionOptions {\n    transport: \"unix\";\n    socketPath: string;\n}\n\n/**\n * Resolved TCP transport settings.\n */\nexport interface OvsdbTcpConnectionOptions {\n    transport: \"tcp\";\n    host: string;\n    port: number;\n}\n\n/**\n * Resolved TLS transport settings.\n */\nexport interface OvsdbTlsTransportOptions {\n    transport: \"tls\";\n    host: string;\n    port: number;\n    tlsOptions: TlsConnectionOptions;\n}\n\n/**\n * Fully resolved transport settings used by the client.\n */\nexport type OvsdbResolvedConnectionOptions =\n    | OvsdbUnixConnectionOptions\n    | OvsdbTcpConnectionOptions\n    | OvsdbTlsTransportOptions;\n\n/**\n * Typed events emitted by {@link OVSDBClient}.\n */\nexport interface OvsdbClientEvents<TDatabase extends DatabaseTableMap = DatabaseTableMap> {\n    connect: [];\n    close: [];\n    notification: [OvsdbNotification<TDatabase>];\n    update: [UpdateNotification<TDatabase>];\n    update2: [Update2Notification<TDatabase>];\n    update3: [Update3Notification<TDatabase>];\n    locked: [LockedNotification];\n    stolen: [StolenNotification];\n    protocolError: [Error, unknown];\n    transportError: [Error];\n}\n\n/**\n * Options for configuring an {@link OVSDBClient}.\n */\nexport interface OvsdbClientOptions {\n    /**\n     * Path to the OVSDB Unix domain socket.\n     *\n     * @defaultValue `\"/var/run/openvswitch/db.sock\"`\n     */\n    socketPath?: string;\n\n    /**\n     * Hostname for TCP or TLS connections.\n     *\n     * When set, the client uses a network socket instead of a Unix socket.\n     */\n    host?: string;\n\n    /**\n     * Port for TCP or TLS connections.\n     *\n     * @defaultValue `6640`\n     */\n    port?: number;\n\n    /**\n     * Enables TLS for network connections.\n     *\n     * @defaultValue `false`\n     */\n    tls?: boolean;\n\n    /**\n     * Extra TLS connection options forwarded to `node:tls`.\n     *\n     * These options are only used when `tls` is enabled.\n     */\n    tlsOptions?: TlsConnectionOptions;\n\n    /**\n     * Request and connection timeout in milliseconds.\n     *\n     * @defaultValue `5000`\n     */\n    timeout?: number;\n\n    /**\n     * Optional stream factory used for testing or custom transports.\n     * When set, the client skips the socket path existence check.\n     */\n    connectionFactory?: (options: OvsdbResolvedConnectionOptions) => OvsdbStream;\n}\n\n/**\n * JSON-RPC transport error returned by the OVSDB server.\n */\nexport class OvsdbRpcError extends Error {\n    /**\n     * The error payload returned by the server.\n     */\n    public readonly response: OvsdbError;\n\n    /**\n     * Creates a new RPC error wrapper.\n     */\n    constructor(response: OvsdbError) {\n        super(response.details ? `${response.error}: ${response.details}` : response.error);\n        this.name = \"OvsdbRpcError\";\n        this.response = response;\n    }\n}\n\n/**\n * Raised when a message does not match the expected JSON-RPC envelope.\n */\nexport class OvsdbProtocolError extends Error {\n    /**\n     * The raw payload that failed validation.\n     */\n    public readonly payload: unknown;\n\n    /**\n     * Creates a new protocol error wrapper.\n     */\n    constructor(message: string, payload: unknown) {\n        super(message);\n        this.name = \"OvsdbProtocolError\";\n        this.payload = payload;\n    }\n}\n\n/**\n * Raised when an OVSDB transaction response contains an operation-level error.\n */\nexport class OvsdbTransactionError<\n    TDatabase extends DatabaseTableMap = DatabaseTableMap\n> extends Error {\n    /**\n     * Zero-based index of the failed operation in the submitted transaction.\n     */\n    public readonly operationIndex: number;\n\n    /**\n     * Operation that produced the error.\n     */\n    public readonly operation: DatabaseOperation<TDatabase>;\n\n    /**\n     * OVSDB error payload returned for the failed operation.\n     */\n    public readonly result: OvsdbError;\n\n    /**\n     * Raw transaction results returned by the server.\n     */\n    public readonly results: Array<OperationResult<TDatabase, DatabaseOperation<TDatabase>> | OvsdbError>;\n\n    /**\n     * Creates a new transaction error wrapper.\n     */\n    constructor(options: {\n        operationIndex: number;\n        operation: DatabaseOperation<TDatabase>;\n        result: OvsdbError;\n        results: Array<OperationResult<TDatabase, DatabaseOperation<TDatabase>> | OvsdbError>;\n    }) {\n        super(`Transaction operation ${options.operationIndex} failed: ${options.result.error}`);\n        this.name = \"OvsdbTransactionError\";\n        this.operationIndex = options.operationIndex;\n        this.operation = options.operation;\n        this.result = options.result;\n        this.results = options.results;\n    }\n}\n\ninterface PendingRequest {\n    resolve: (value: unknown) => void;\n    reject: (reason?: unknown) => void;\n    timeoutId: NodeJS.Timeout;\n}\n\n/**\n * Result payload returned by a staged transaction helper.\n */\nexport interface OvsdbTransactionOutcome<\n    TDatabase extends DatabaseTableMap = DatabaseTableMap,\n    TValue = void\n> {\n    /**\n     * Value returned by the transaction callback.\n     */\n    value: TValue;\n\n    /**\n     * Operations that were submitted to OVSDB.\n     */\n    operations: readonly DatabaseOperation<TDatabase>[];\n\n    /**\n     * Per-operation OVSDB results in submission order.\n     */\n    results: Array<OperationResult<TDatabase, DatabaseOperation<TDatabase>>>;\n}\n\n/**\n * Options for the staged transaction helper.\n */\nexport interface OvsdbTransactionOptions {\n    /**\n     * Appends a trailing `commit` operation when the callback succeeds and the\n     * staged operations do not already include `commit` or `abort`.\n     *\n     * @defaultValue `true`\n     */\n    autoCommit?: boolean;\n\n    /**\n     * Durable flag used by the auto-generated `commit` operation.\n     *\n     * @defaultValue `false`\n     */\n    durable?: boolean;\n}\n\n/**\n * Stages OVSDB operations before sending them as a single `transact` request.\n */\nexport class OvsdbTransaction<TDatabase extends DatabaseTableMap = DatabaseTableMap> {\n    private readonly stagedOperations: DatabaseOperation<TDatabase>[] = [];\n\n    /**\n     * Returns the currently staged operations.\n     */\n    public get operations(): readonly DatabaseOperation<TDatabase>[] {\n        return this.stagedOperations;\n    }\n\n    /**\n     * Adds an operation to the transaction.\n     */\n    public add<TOperation extends DatabaseOperation<TDatabase>>(operation: TOperation): TOperation {\n        this.stagedOperations.push(operation);\n        return operation;\n    }\n\n    /**\n     * Stages an insert operation.\n     */\n    public insert<TOperation extends InsertOperation<TDatabase>>(operation: TOperation): TOperation {\n        return this.add(operation);\n    }\n\n    /**\n     * Stages a select operation.\n     */\n    public select<TOperation extends SelectOperation<TDatabase>>(operation: TOperation): TOperation {\n        return this.add(operation);\n    }\n\n    /**\n     * Stages an update operation.\n     */\n    public update<TOperation extends UpdateOperation<TDatabase>>(operation: TOperation): TOperation {\n        return this.add(operation);\n    }\n\n    /**\n     * Stages a mutate operation.\n     */\n    public mutate<TOperation extends MutateOperation<TDatabase>>(operation: TOperation): TOperation {\n        return this.add(operation);\n    }\n\n    /**\n     * Stages a delete operation.\n     */\n    public delete<TOperation extends DeleteOperation<TDatabase>>(operation: TOperation): TOperation {\n        return this.add(operation);\n    }\n\n    /**\n     * Stages a wait operation.\n     */\n    public wait<TOperation extends WaitOperation<TDatabase>>(operation: TOperation): TOperation {\n        return this.add(operation);\n    }\n\n    /**\n     * Stages a comment operation.\n     */\n    public comment(comment: string): CommentOperation {\n        return this.add({\n            op: \"comment\",\n            comment\n        });\n    }\n\n    /**\n     * Stages an assert operation.\n     */\n    public assert(lock: string): AssertOperation {\n        return this.add({\n            op: \"assert\",\n            lock\n        });\n    }\n\n    /**\n     * Stages a commit operation.\n     */\n    public commit(durable = false): CommitOperation {\n        return this.add({\n            op: \"commit\",\n            durable\n        });\n    }\n\n    /**\n     * Stages an abort operation.\n     */\n    public abort(): AbortOperation {\n        return this.add({\n            op: \"abort\"\n        });\n    }\n}\n\n/**\n * A low-level, event-driven OVSDB client for Unix sockets, TCP, or TLS.\n *\n * The client exposes the RFC 7047 primitives together with common\n * Open vSwitch protocol extensions while keeping the API small and predictable.\n */\nexport class OVSDBClient<\n    TDatabase extends DatabaseTableMap = DatabaseTableMap\n> extends EventEmitter<OvsdbClientEvents<TDatabase>> implements AsyncDisposable {\n    private readonly timeout: number;\n    private readonly connectionOptions: OvsdbResolvedConnectionOptions;\n    private readonly connectionFactory?: (options: OvsdbResolvedConnectionOptions) => OvsdbStream;\n\n    private socket: OvsdbStream | null = null;\n    private requestId = 1;\n    private receiveBuffer = \"\";\n    private pendingRequests = new Map<JsonValue, PendingRequest>();\n    private connected = false;\n    private closeEmitted = false;\n\n    /**\n     * Creates a new OVSDB client instance.\n     */\n    constructor(options: OvsdbClientOptions = {}) {\n        super();\n        this.timeout = options.timeout ?? 5000;\n        this.connectionOptions = resolveConnectionOptions(options);\n        this.connectionFactory = options.connectionFactory;\n    }\n\n    /**\n     * Returns `true` when the underlying socket is currently connected.\n     */\n    public get isConnected(): boolean {\n        return this.connected;\n    }\n\n    /**\n     * Opens the transport connection.\n     *\n     * @returns The connected client instance for chaining.\n     */\n    public async connect(): Promise<this> {\n        if (this.connected) {\n            return this;\n        }\n\n        if (\n            !this.connectionFactory &&\n            this.connectionOptions.transport === \"unix\" &&\n            !existsSync(this.connectionOptions.socketPath)\n        ) {\n            throw new Error(`OVSDB socket not found: ${this.connectionOptions.socketPath}`);\n        }\n\n        const socket = this.connectionFactory\n            ? this.connectionFactory(this.connectionOptions)\n            : createTransport(this.connectionOptions);\n        this.attachSocket(socket);\n        const connectEvent = this.connectionOptions.transport === \"tls\" ? \"secureConnect\" : \"connect\";\n\n        await new Promise<void>((resolve, reject) => {\n            const timeoutId = setTimeout(() => {\n                cleanup();\n                this.disposeTransport(new Error(`Connection timeout after ${this.timeout}ms`));\n                reject(new Error(`Connection timeout after ${this.timeout}ms`));\n            }, this.timeout);\n\n            const onConnect = () => {\n                cleanup();\n                this.connected = true;\n                this.closeEmitted = false;\n                this.emit(\"connect\");\n                resolve();\n            };\n\n            const onError = (error: Error) => {\n                cleanup();\n                reject(error);\n            };\n\n            const cleanup = () => {\n                clearTimeout(timeoutId);\n                socket.off(connectEvent, onConnect);\n                socket.off(\"error\", onError);\n            };\n\n            socket.once(connectEvent, onConnect);\n            socket.once(\"error\", onError);\n        });\n\n        return this;\n    }\n\n    /**\n     * Sends a raw JSON-RPC request and resolves with its `result` payload.\n     *\n     * @param method RPC method name.\n     * @param params RPC parameters.\n     */\n    public async request<TResult>(method: string, params: JsonValue[] = []): Promise<TResult> {\n        this.assertConnected();\n\n        const id = this.requestId++;\n        const payload = {\n            method,\n            params,\n            id\n        };\n\n        return await new Promise<TResult>((resolve, reject) => {\n            const timeoutId = setTimeout(() => {\n                this.pendingRequests.delete(id);\n                reject(new Error(`Request timeout for method: ${method}`));\n            }, this.timeout);\n\n            this.pendingRequests.set(id, {\n                resolve: (value) => resolve(value as TResult),\n                reject,\n                timeoutId\n            });\n\n            this.writeMessage(payload).catch((error) => {\n                clearTimeout(timeoutId);\n                this.pendingRequests.delete(id);\n                reject(error);\n            });\n        });\n    }\n\n    /**\n     * Sends a JSON-RPC notification without waiting for a response.\n     *\n     * @param method RPC method name.\n     * @param params RPC parameters.\n     */\n    public async notify(method: string, params: JsonValue[] = []): Promise<void> {\n        this.assertConnected();\n        await this.writeMessage({method, params});\n    }\n\n    /**\n     * Returns the database names exposed by the connected OVSDB server.\n     */\n    public async listDbs(): Promise<ListDbsResult> {\n        return await this.request<ListDbsResult>(\"list_dbs\", []);\n    }\n\n    /**\n     * Returns the schema definition for a database.\n     *\n     * @param dbName Database name.\n     */\n    public async getSchema(dbName = \"Open_vSwitch\"): Promise<DatabaseSchema> {\n        return await this.request<DatabaseSchema>(\"get_schema\", [dbName]);\n    }\n\n    /**\n     * Executes a single transaction.\n     *\n     * The response preserves operation ordering, so tuple inputs infer tuple outputs.\n     *\n     * @param dbName Database name.\n     * @param operations Transaction operations.\n     */\n    public async transact<TOperations extends readonly DatabaseOperation<TDatabase>[]>(\n        dbName: string,\n        operations: [...TOperations]\n    ): Promise<OperationResults<TDatabase, TOperations>> {\n        return await this.request<OperationResults<TDatabase, TOperations>>(\n            \"transact\",\n            [dbName, ...operations] as JsonValue[]\n        );\n    }\n\n    /**\n     * Stages a transaction in a callback and submits it only if the callback\n     * completes successfully.\n     *\n     * This helper is convenient when you want a scoped, imperative API while\n     * still sending exactly one OVSDB `transact` request.\n     *\n     * @param dbName Database name.\n     * @param callback Callback that stages operations on the transaction object.\n     * @param options Auto-commit behavior for the staged transaction.\n     */\n    public async transaction<TValue>(\n        dbName: string,\n        callback: (transaction: OvsdbTransaction<TDatabase>) => Promise<TValue> | TValue,\n        options: OvsdbTransactionOptions = {}\n    ): Promise<OvsdbTransactionOutcome<TDatabase, TValue>> {\n        const transaction = new OvsdbTransaction<TDatabase>();\n        const value = await callback(transaction);\n\n        const operations = [...transaction.operations];\n        const autoCommit = options.autoCommit ?? true;\n        const hasFinalizer = operations.some((operation) => operation.op === \"commit\" || operation.op === \"abort\");\n        if (autoCommit && !hasFinalizer) {\n            operations.push({\n                op: \"commit\",\n                durable: options.durable ?? false\n            });\n        }\n\n        if (operations.length === 0) {\n            return {\n                value,\n                operations,\n                results: []\n            };\n        }\n\n        const results = await this.request<Array<OperationResult<TDatabase, DatabaseOperation<TDatabase>> | OvsdbError>>(\n            \"transact\",\n            [dbName, ...operations] as JsonValue[]\n        );\n\n        for (const [index, result] of results.entries()) {\n            if (isOvsdbError(result)) {\n                throw new OvsdbTransactionError<TDatabase>({\n                    operationIndex: index,\n                    operation: operations[index] as DatabaseOperation<TDatabase>,\n                    result,\n                    results\n                });\n            }\n        }\n\n        return {\n            value,\n            operations,\n            results: results as Array<OperationResult<TDatabase, DatabaseOperation<TDatabase>>>\n        };\n    }\n\n    /**\n     * Cancels a previously issued request by id.\n     *\n     * @param requestId JSON-RPC request id to cancel.\n     */\n    public async cancel(requestId: JsonValue): Promise<null | JsonObject> {\n        return await this.request<null | JsonObject>(\"cancel\", [requestId]);\n    }\n\n    /**\n     * Starts a standard RFC 7047 monitor.\n     *\n     * @param dbName Database name.\n     * @param monitorId Application-defined monitor id.\n     * @param monitorRequests Per-table monitor definitions.\n     */\n    public async monitor(\n        dbName: string,\n        monitorId: JsonValue,\n        monitorRequests: Record<string, MonitorRequest<TDatabase>>\n    ): Promise<TableUpdates<TDatabase>> {\n        return await this.request<TableUpdates<TDatabase>>(\"monitor\", [\n            dbName,\n            monitorId,\n            monitorRequests as JsonValue\n        ]);\n    }\n\n    /**\n     * Starts an Open vSwitch conditional monitor.\n     *\n     * @param dbName Database name.\n     * @param monitorId Application-defined monitor id.\n     * @param monitorRequests Per-table conditional monitor definitions.\n     */\n    public async monitorCond(\n        dbName: string,\n        monitorId: JsonValue,\n        monitorRequests: Record<string, MonitorCondRequest<TDatabase>>\n    ): Promise<TableUpdates2<TDatabase>> {\n        return await this.request<TableUpdates2<TDatabase>>(\"monitor_cond\", [\n            dbName,\n            monitorId,\n            monitorRequests as JsonValue\n        ]);\n    }\n\n    /**\n     * Starts an Open vSwitch conditional monitor from a known transaction id.\n     *\n     * @param dbName Database name.\n     * @param monitorId Application-defined monitor id.\n     * @param monitorRequests Per-table conditional monitor definitions.\n     * @param lastTransactionId Last seen transaction id, or `null` for a fresh snapshot.\n     */\n    public async monitorCondSince(\n        dbName: string,\n        monitorId: JsonValue,\n        monitorRequests: Record<string, MonitorCondRequest<TDatabase>>,\n        lastTransactionId: string | null = null\n    ): Promise<MonitorCondSinceResult<TDatabase>> {\n        return await this.request<MonitorCondSinceResult<TDatabase>>(\"monitor_cond_since\", [\n            dbName,\n            monitorId,\n            monitorRequests as JsonValue,\n            lastTransactionId\n        ]);\n    }\n\n    /**\n     * Cancels a monitor by its monitor id.\n     *\n     * @param monitorId Monitor id used when the monitor was created.\n     */\n    public async monitorCancel(monitorId: JsonValue): Promise<null | JsonObject> {\n        return await this.request<null | JsonObject>(\"monitor_cancel\", [monitorId]);\n    }\n\n    /**\n     * Acquires a named database lock.\n     *\n     * @param lockId Lock identifier.\n     */\n    public async lock(lockId: string): Promise<null | JsonObject> {\n        return await this.request<null | JsonObject>(\"lock\", [lockId]);\n    }\n\n    /**\n     * Forces ownership of a named database lock.\n     *\n     * @param lockId Lock identifier.\n     */\n    public async steal(lockId: string): Promise<null | JsonObject> {\n        return await this.request<null | JsonObject>(\"steal\", [lockId]);\n    }\n\n    /**\n     * Releases a previously acquired named database lock.\n     *\n     * @param lockId Lock identifier.\n     */\n    public async unlock(lockId: string): Promise<null | JsonObject> {\n        return await this.request<null | JsonObject>(\"unlock\", [lockId]);\n    }\n\n    /**\n     * Sends an echo request to validate transport liveness.\n     *\n     * @param payload Values to be echoed back by the server.\n     */\n    public async echo<TPayload extends OvsdbValue[]>(...payload: TPayload): Promise<TPayload> {\n        return await this.request<TPayload>(\"echo\", payload as JsonValue[]);\n    }\n\n    /**\n     * Enables or disables Open vSwitch database change awareness.\n     *\n     * @param enabled Whether the server should report change awareness metadata.\n     */\n    public async setDbChangeAware(enabled = true): Promise<boolean | null> {\n        return await this.request<boolean | null>(\"set_db_change_aware\", [enabled]);\n    }\n\n    /**\n     * Closes the connection and rejects all pending requests.\n     */\n    public async close(): Promise<void> {\n        this.disposeTransport();\n    }\n\n    /**\n     * Implements `AsyncDisposable`.\n     */\n    public async [Symbol.asyncDispose](): Promise<void> {\n        await this.close();\n    }\n\n    private attachSocket(socket: OvsdbStream): void {\n        this.socket = socket;\n        this.receiveBuffer = \"\";\n\n        socket.on(\"data\", this.handleData);\n        socket.on(\"error\", this.handleSocketError);\n        socket.on(\"close\", this.handleSocketClose);\n    }\n\n    private readonly handleData = (chunk: Buffer | string): void => {\n        this.receiveBuffer += typeof chunk === \"string\" ? chunk : chunk.toString(\"utf8\");\n\n        let frame = extractJsonFrame(this.receiveBuffer);\n        while (frame) {\n            this.receiveBuffer = frame.rest;\n            this.parseFrame(frame.frame);\n            frame = extractJsonFrame(this.receiveBuffer);\n        }\n\n        const trimmed = this.receiveBuffer.trimStart();\n        if (trimmed && trimmed[0] !== \"{\" && trimmed[0] !== \"[\") {\n            this.emitProtocolError(\"Received non-JSON data on the transport\", this.receiveBuffer);\n            this.receiveBuffer = \"\";\n        }\n    };\n\n    private readonly handleSocketError = (error: Error): void => {\n        this.emit(\"transportError\", error);\n        this.disposeTransport(error);\n    };\n\n    private readonly handleSocketClose = (): void => {\n        this.disposeTransport();\n    };\n\n    private parseFrame(frame: string): void {\n        try {\n            const payload = JSON.parse(frame) as unknown;\n            this.handleMessage(payload);\n        } catch (error) {\n            const protocolError = new OvsdbProtocolError(\"Failed to parse JSON message\", frame);\n            this.emit(\"protocolError\", protocolError, frame);\n            if (error instanceof Error) {\n                void error;\n            }\n        }\n    }\n\n    private handleMessage(payload: unknown): void {\n        if (!payload || typeof payload !== \"object\") {\n            this.emitProtocolError(\"Expected a JSON object message\", payload);\n            return;\n        }\n\n        if (\"method\" in payload && typeof payload.method === \"string\") {\n            const message = payload as {method: string; params?: JsonValue[]; id?: JsonValue | null};\n\n            if (message.id !== undefined && message.id !== null) {\n                void this.handleIncomingRequest(message.method, message.params ?? [], message.id);\n                return;\n            }\n\n            this.handleNotification(payload as OvsdbNotification<TDatabase>);\n            return;\n        }\n\n        if (\"id\" in payload) {\n            this.handleResponse(payload as OvsdbResponse<unknown>);\n            return;\n        }\n\n        this.emitProtocolError(\"Received message without method or id\", payload);\n    }\n\n    private handleResponse(response: OvsdbResponse<unknown>): void {\n        const pendingRequest = this.pendingRequests.get(response.id);\n        if (!pendingRequest) {\n            this.emitProtocolError(\"Received response for an unknown request id\", response);\n            return;\n        }\n\n        this.pendingRequests.delete(response.id);\n        clearTimeout(pendingRequest.timeoutId);\n\n        if (response.error) {\n            pendingRequest.reject(new OvsdbRpcError(response.error));\n            return;\n        }\n\n        pendingRequest.resolve(response.result);\n    }\n\n    private async handleIncomingRequest(method: string, params: JsonValue[], id: JsonValue): Promise<void> {\n        if (method === \"echo\") {\n            await this.writeMessage({\n                id,\n                result: params,\n                error: null\n            });\n            return;\n        }\n\n        await this.writeMessage({\n            id,\n            result: null,\n            error: {\n                error: \"not supported\",\n                details: `Unsupported server request: ${method}`\n            }\n        });\n    }\n\n    private handleNotification(notification: OvsdbNotification<TDatabase>): void {\n        this.emit(\"notification\", notification);\n\n        switch (notification.method) {\n            case \"update\":\n                this.emit(\"update\", notification);\n                break;\n            case \"update2\":\n                this.emit(\"update2\", notification);\n                break;\n            case \"update3\":\n                this.emit(\"update3\", notification);\n                break;\n            case \"locked\":\n                this.emit(\"locked\", notification);\n                break;\n            case \"stolen\":\n                this.emit(\"stolen\", notification);\n                break;\n            default:\n                this.emitProtocolError(\"Received an unknown notification method\", notification);\n                break;\n        }\n    }\n\n    private emitProtocolError(message: string, payload: unknown): void {\n        const error = new OvsdbProtocolError(message, payload);\n        this.emit(\"protocolError\", error, payload);\n    }\n\n    private async writeMessage(payload: JsonObject): Promise<void> {\n        this.assertConnected();\n\n        await new Promise<void>((resolve, reject) => {\n            this.socket?.write(`${JSON.stringify(payload)}\\n`, (error) => {\n                if (error) {\n                    reject(error);\n                    return;\n                }\n                resolve();\n            });\n        });\n    }\n\n    private assertConnected(): void {\n        if (!this.connected || !this.socket) {\n            throw new Error(\"Not connected to OVSDB\");\n        }\n    }\n\n    private disposeTransport(reason?: Error): void {\n        const socket = this.socket;\n        this.socket = null;\n        this.connected = false;\n        this.receiveBuffer = \"\";\n\n        if (socket) {\n            socket.off(\"data\", this.handleData);\n            socket.off(\"error\", this.handleSocketError);\n            socket.off(\"close\", this.handleSocketClose);\n            if (!socket.destroyed) {\n                socket.destroy();\n            }\n        }\n\n        const closeError = reason ?? new Error(\"Connection closed\");\n        for (const pendingRequest of this.pendingRequests.values()) {\n            clearTimeout(pendingRequest.timeoutId);\n            pendingRequest.reject(closeError);\n        }\n        this.pendingRequests.clear();\n\n        if (!this.closeEmitted) {\n            this.closeEmitted = true;\n            this.emit(\"close\");\n        }\n    }\n}\n\nexport * from \"./types\";\n\n/**\n * Resolves the user-supplied transport options into an explicit connection mode.\n */\nexport function resolveConnectionOptions(options: OvsdbClientOptions = {}): OvsdbResolvedConnectionOptions {\n    if (options.host) {\n        const port = options.port ?? 6640;\n        if (options.tls) {\n            return {\n                transport: \"tls\",\n                host: options.host,\n                port,\n                tlsOptions: {\n                    host: options.host,\n                    port,\n                    ...options.tlsOptions\n                }\n            };\n        }\n\n        return {\n            transport: \"tcp\",\n            host: options.host,\n            port\n        };\n    }\n\n    return {\n        transport: \"unix\",\n        socketPath: options.socketPath ?? \"/var/run/openvswitch/db.sock\"\n    };\n}\n\nfunction createTransport(options: OvsdbResolvedConnectionOptions): OvsdbStream {\n    switch (options.transport) {\n        case \"unix\":\n            return createNetConnection(options.socketPath);\n        case \"tcp\":\n            return createNetConnection(options.port, options.host);\n        case \"tls\":\n            return connectTls(options.tlsOptions);\n    }\n}\n\nfunction isOvsdbError(value: unknown): value is OvsdbError {\n    return typeof value === \"object\" && value !== null && \"error\" in value && typeof value.error === \"string\";\n}\n\nfunction extractJsonFrame(buffer: string): {frame: string; rest: string} | null {\n    let startIndex = 0;\n    while (startIndex < buffer.length && /\\s/u.test(buffer[startIndex])) {\n        startIndex += 1;\n    }\n\n    if (startIndex >= buffer.length) {\n        return null;\n    }\n\n    const opening = buffer[startIndex];\n    const closing = opening === \"{\" ? \"}\" : opening === \"[\" ? \"]\" : null;\n    if (!closing) {\n        return null;\n    }\n\n    let depth = 0;\n    let inString = false;\n    let escaping = false;\n\n    for (let index = startIndex; index < buffer.length; index += 1) {\n        const char = buffer[index];\n\n        if (inString) {\n            if (escaping) {\n                escaping = false;\n                continue;\n            }\n\n            if (char === \"\\\\\") {\n                escaping = true;\n                continue;\n            }\n\n            if (char === \"\\\"\") {\n                inString = false;\n            }\n            continue;\n        }\n\n        if (char === \"\\\"\") {\n            inString = true;\n            continue;\n        }\n\n        if (char === \"{\" || char === \"[\") {\n            depth += 1;\n            continue;\n        }\n\n        if (char === \"}\" || char === \"]\") {\n            depth -= 1;\n            if (depth === 0) {\n                return {\n                    frame: buffer.slice(startIndex, index + 1),\n                    rest: buffer.slice(index + 1)\n                };\n            }\n        }\n    }\n\n    return null;\n}\n"],"mappings":"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"}