/** * @license * Copyright 2022-2026 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ import { Logger } from "#log/Logger.js"; import { Bytes } from "#util/Bytes.js"; const logger = Logger.get("MockRouter"); export interface MockRouter extends MockRouter.Route { intercept(route: MockRouter.Interceptor): void; add(route: MockRouter.Route): void; delete(route: MockRouter.Route): void; } export function MockRouter(): MockRouter { const routes = new Set(); let route = (packet: MockRouter.Packet) => { for (const route of routes) { Promise.resolve() .then(() => route(packet)) .catch(e => logger.error("Unhandled error in network listener", e)); } }; const router = function router(packet: MockRouter.Packet) { route(packet); } as MockRouter; router.intercept = intercept => { const next = route; route = packet => { intercept(packet, next); }; }; router.add = routes.add.bind(routes); router.delete = routes.delete.bind(routes); return router; } export namespace MockRouter { /** * A mock network packet. */ export type Packet = UdpPacket | TcpPacket; export interface UdpPacket { kind: "udp"; sourceAddress: string; sourcePort: number; destAddress: string; destPort: number; payload: Bytes; } export interface TcpPacket { kind: "tcp"; sourceAddress: string; sourcePort: number; destAddress: string; destPort: number; payload: Bytes; } /** * A route. * * Takes a packet and does something with it. */ export interface Route { (packet: Packet): void; } /** * A route wrapper. * * Takes a packet and a route. Does something with {@link packet}, optionally passing along to {@link route} to * allow normal routing to proceed. */ export interface Interceptor { (packet: Packet, route: Route): void; } }