import { Transport, Interceptor } from '@connectrpc/connect'; import { Server, ServiceDefinition, ProtocolRegistration } from '@connectum/core'; import { a as InMemorySpanCollector, I as InMemoryMetricCollector, b as NormalizedSpan, N as NormalizedMetric } from './otel-collectors-uZ4OWw4a.js'; import '@opentelemetry/sdk-metrics'; import '@opentelemetry/sdk-trace-base'; /** * Cross-transport parity test driver. * * Registers a `node:test` test that runs the given scenario *twice* — once * against an HTTP/2 server (via `createGrpcTransport`) and once against the * in-process router transport (`createLocalTransport`). Both servers are * created with identical configuration: same services, same server-side * interceptors, same protocols. * * After both runs complete, the driver performs a structural diff over the * scenario's reported `ParityScenarioResult` and fails the test if any * non-transport-specific field differs. * * @module transportParityTest */ /** * Identifies which transport a scenario invocation is running against. */ type TransportKind = "http" | "local"; /** * Per-invocation context passed to the scenario function. */ interface ParityScenarioContext { /** Active client transport for this run. */ transport: Transport; /** Which transport this run uses. */ transportKind: TransportKind; /** The server instance — useful for inspection (e.g. `server.address`). */ server: Server; /** Base URL for the HTTP server, only defined when `transportKind === "http"`. */ baseUrl: string | undefined; /** Fresh span collector for this run (no cross-contamination between runs). */ spans: InMemorySpanCollector; /** Fresh metric collector for this run. */ metrics: InMemoryMetricCollector; } /** * Result reported by a scenario for a single transport. * * Every field is optional; the parity driver compares only fields that are * present in *both* runs (asymmetric presence is a parity failure). */ interface ParityScenarioResult { /** Successful response payload (must be JSON-serializable for diff). */ response?: unknown; /** Response headers reported by the client. */ responseHeaders?: Record; /** Response trailers reported by the client. */ trailers?: Record; /** Error captured during the scenario. */ error?: { code: number | string; message: string; details?: unknown; metadata?: Record; }; /** Spans observed during the scenario (already normalized — pass `await ctx.spans.flush()`). */ spans?: NormalizedSpan[]; /** Metrics observed during the scenario. */ metrics?: NormalizedMetric[]; } /** * Options for {@link transportParityTest}. */ interface TransportParityTestOptions { /** Service definitions registered on both servers. */ services: readonly ServiceDefinition[]; /** Server-side interceptors applied identically on both servers. */ interceptors?: Interceptor[]; /** * Client-side interceptors applied identically on both client transports * (e.g. an OTel client interceptor that must be the same instance for * both runs so they share a single `tracer` / `meter`). On HTTP they * are passed to `createGrpcTransport({ interceptors })`; on the local * path they are passed to `createLocalTransport(server, { interceptors })`. */ clientInterceptors?: Interceptor[]; /** Protocol extensions applied identically on both servers. */ protocols?: ProtocolRegistration[]; /** * The scenario under test. Invoked once per transport with a fresh * server, transport, and OTEL collector pair. */ scenario: (ctx: ParityScenarioContext) => Promise; /** * Optional custom comparison. Receives both results and should `throw` * (e.g. via `assert.deepStrictEqual`) when parity is violated. * * If omitted, {@link defaultCompare} is used, which performs structural * deep equality with normalization of trace/span identifiers. */ compare?: (http: ParityScenarioResult, local: ParityScenarioResult) => void; } /** * Default structural diff for two scenario results. */ declare function defaultCompare(http: ParityScenarioResult, local: ParityScenarioResult): void; /** * Register a `node:test` parity test that runs the same scenario over both * HTTP and in-process transports and asserts structural equivalence. * * @example * ```typescript * transportParityTest("Greeter.sayHello is identical across transports", { * services: [greeterRoutes], * scenario: async ({ transport }) => { * const client = createClient(GreeterService, transport); * const response = await client.sayHello({ name: "world" }); * return { response }; * }, * }); * ``` */ declare function transportParityTest(name: string, opts: TransportParityTestOptions): void; export { type ParityScenarioContext, type ParityScenarioResult, type TransportKind, type TransportParityTestOptions, defaultCompare, transportParityTest };