/** * @license * Copyright 2022-2026 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ import { Environment } from "#environment/Environment.js"; import { Environmental } from "#environment/Environmental.js"; import { Bytes } from "#util/Bytes.js"; import { BasicSet } from "#util/Set.js"; import { Channel, ChannelType } from "./Channel.js"; import { ServerAddress } from "./ServerAddress.js"; /** * A local network endpoint for message transport. */ export interface Transport { onData(listener: (socket: Channel, data: Bytes) => void): Transport.Listener; close(): Promise; supports(type: ChannelType, address?: string): boolean; openChannel(address: ServerAddress, options?: Transport.OpenChannelOptions): Promise>; } export namespace Transport { export interface Listener { close(): Promise; } /** * Options accepted by {@link Transport.openChannel}. Connectionless transports (UDP) ignore * fields that only apply to connect-oriented setup. */ export interface OpenChannelOptions { /** Aborts an in-flight channel open; the transport tears down any partial state on signal. */ abort?: AbortSignal; } export interface Provider { /** * Obtain an interface capable of routing an address. */ interfaceFor(type: ChannelType, address?: string): T | undefined; /** * Obtain an interface of specific type. */ hasInterfaceFor(type: ChannelType, address?: string): boolean; } } /** * Extension of {@link Transport} for connection-oriented protocols (TCP). * Adds lifecycle hooks for connection/disconnection events. * Methods are optional — a transport may only implement one direction. */ export interface ConnectionOrientedTransport extends Transport { /** Fires when a remote peer connects (server role). */ onConnect?(listener: (channel: Channel) => void): Transport.Listener; /** Fires when a connection drops. */ onDisconnect?(listener: (channel: Channel) => void): Transport.Listener; } /** Type guard for connection-oriented transports. */ export function isConnectionOrientedTransport(transport: Transport): transport is ConnectionOrientedTransport { return typeof (transport as ConnectionOrientedTransport).onDisconnect === "function"; } /** * A collection of {@link Transport}s managed as a unit. */ export class TransportSet extends BasicSet implements Transport.Provider { constructor(...initialInterfaces: T[]) { super(...initialInterfaces); } static [Environmental.create](env: Environment) { const instance = new TransportSet(); env.set(TransportSet, instance); return instance; } /** * Closes all interfaces. */ async close() { for (const transportInterface of this) { await transportInterface.close(); } this.clear(); } /** * Obtain an interface capable of routing an address. */ interfaceFor(type: ChannelType, address?: string) { return this.find(transportInterface => transportInterface.supports(type, address)); } /** * Obtain an interface of specific type. */ hasInterfaceFor(type: ChannelType, address?: string) { return this.interfaceFor(type, address) !== undefined; } }