agentic-flow 3.4.3 → 3.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -51,8 +51,7 @@ export interface AgentMessage {
51
51
  * - One stream per task (`taskId` doubled as streamId)
52
52
  * - One stream per priority class (`'high'`, `'normal'`, `'low'`)
53
53
  *
54
- * Maps cleanly to native QUIC streams when AGENTIC_FLOW_QUIC_NATIVE=1
55
- * (each app-layer streamId becomes a QUIC stream id at that point).
54
+ * Would map to native QUIC stream ids if a native binding is ever added.
56
55
  */
57
56
  streamId?: string | number;
58
57
  }
@@ -240,24 +239,46 @@ declare class WebSocketFallbackTransport implements AgentTransport {
240
239
  close(): Promise<void>;
241
240
  }
242
241
  /**
243
- * Public API — load a working transport, preferring real QUIC when
244
- * available, falling back to WebSocket otherwise. The returned object
245
- * satisfies the AgentTransport interface in both cases.
242
+ * Why real QUIC is not available in npm builds of agentic-flow.
243
+ *
244
+ * - No native (N-API) QUIC binding exists. The quinn-based client/server in
245
+ * `crates/agentic-flow-quic` has no Node bindings and no build/publish
246
+ * pipeline, so nothing native ships in the tarball.
247
+ * - `wasm/quic/` is a browser build of that crate with quinn/tokio compiled
248
+ * out (browsers cannot open UDP sockets). It cannot move QUIC packets.
249
+ * - `agentic-flow/transport/quic` (QuicClient/QuicServer/QuicTransport) is a
250
+ * placeholder API that does not transmit bytes.
251
+ *
252
+ * The working transport is the WebSocket fallback returned by
253
+ * {@link loadQuicTransport}.
254
+ */
255
+ export declare const QUIC_UNAVAILABLE_REASON: string;
256
+ /** Honest status for the QUIC backend. */
257
+ export interface QuicStatus {
258
+ available: boolean;
259
+ /** Present when available is false. */
260
+ reason?: string;
261
+ /** The transport loadQuicTransport() actually returns. */
262
+ fallback: 'websocket';
263
+ }
264
+ /**
265
+ * Public API — load a working transport. Real QUIC is not available in npm
266
+ * builds (see {@link QUIC_UNAVAILABLE_REASON}), so this returns the WebSocket
267
+ * fallback, which satisfies the AgentTransport interface.
246
268
  *
247
269
  * Example:
248
270
  * const t = await loadQuicTransport({ serverName: 'ruvultra:9100' });
249
271
  * await t.send('ruvultra:9100', { id: '1', type: 'task', payload: {...} });
250
- *
251
- * Federation v1 ships on the WebSocket fallback (this is the actual
252
- * working transport today). When the native QUIC binding lands, set
253
- * the AGENTIC_FLOW_QUIC_NATIVE=1 environment variable and the same
254
- * code path picks up the upgrade with no API changes.
255
272
  */
256
273
  export declare function loadQuicTransport(config?: QuicTransportConfig): Promise<AgentTransport>;
257
274
  /** Quick capability probe for the doctor / health surface. */
258
275
  export declare function isQuicAvailable(): Promise<boolean>;
276
+ /** Availability plus the reason when QUIC is unavailable. */
277
+ export declare function getQuicStatus(): Promise<QuicStatus>;
259
278
  export interface TransportCapabilities {
260
279
  quicAvailable: boolean;
280
+ /** Why QUIC is unavailable; present when quicAvailable is false. */
281
+ quicUnavailableReason?: string;
261
282
  webSocketFallbackAvailable: true;
262
283
  selectedBackend: 'quic' | 'websocket';
263
284
  }
@@ -1 +1 @@
1
- {"version":3,"file":"quic-loader.d.ts","sourceRoot":"","sources":["../../src/transport/quic-loader.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"quic-loader.d.ts","sourceRoot":"","sources":["../../src/transport/quic-loader.ts"],"names":[],"mappings":"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"}
@@ -479,56 +479,44 @@ class WebSocketFallbackTransport {
479
479
  }
480
480
  }
481
481
  /**
482
- * Detect whether the WASM-backed QUIC transport is "real" (i.e. it
483
- * actually moves bytes on the wire) vs the current stub. The stub
484
- * returns 0ms for connect+send and never increments the server's
485
- * received-bytes counter. We probe by observing a documented marker
486
- * on the WASM module: when it's truly wired the loader function
487
- * `defaultConfig` returns an object whose round-trip through
488
- * `WasmQuicClient.new` actually opens a UDP socket — failing fast on
489
- * an OS that blocks UDP outbound (e.g. some sandboxed CI envs).
482
+ * Why real QUIC is not available in npm builds of agentic-flow.
490
483
  *
491
- * Until the native build lands this returns false; the loader picks
492
- * WebSocket. When the native binding is wired this returns true and
493
- * the loader picks real QUIC. Callers get the same API either way.
484
+ * - No native (N-API) QUIC binding exists. The quinn-based client/server in
485
+ * `crates/agentic-flow-quic` has no Node bindings and no build/publish
486
+ * pipeline, so nothing native ships in the tarball.
487
+ * - `wasm/quic/` is a browser build of that crate with quinn/tokio compiled
488
+ * out (browsers cannot open UDP sockets). It cannot move QUIC packets.
489
+ * - `agentic-flow/transport/quic` (QuicClient/QuicServer/QuicTransport) is a
490
+ * placeholder API that does not transmit bytes.
491
+ *
492
+ * The working transport is the WebSocket fallback returned by
493
+ * {@link loadQuicTransport}.
494
+ */
495
+ export const QUIC_UNAVAILABLE_REASON = 'No native QUIC binding is published for agentic-flow: the quinn-based ' +
496
+ 'crates/agentic-flow-quic has no N-API build, wasm/quic is a browser stub ' +
497
+ 'without UDP, and agentic-flow/transport/quic is a placeholder that sends ' +
498
+ 'no bytes. loadQuicTransport() uses the WebSocket fallback.';
499
+ /**
500
+ * Real QUIC is available only when a native binding has been loaded. None
501
+ * is published, so this is always false. Earlier releases returned true when
502
+ * AGENTIC_FLOW_QUIC_NATIVE=1 was set, even though the loader still returned
503
+ * the WebSocket transport. That variable is now ignored.
494
504
  */
495
505
  async function isRealQuicAvailable() {
496
- try {
497
- // The WASM file is published in `wasm/quic/` of this package. We
498
- // do NOT use it for federation today (per the wasm.rs note: it's a
499
- // stub since browsers can't do UDP). When a native binding is added
500
- // this probe should switch to detect that binding instead.
501
- const native = process.env.AGENTIC_FLOW_QUIC_NATIVE === '1';
502
- return native;
503
- }
504
- catch {
505
- return false;
506
- }
506
+ return false;
507
507
  }
508
508
  /**
509
- * Public API — load a working transport, preferring real QUIC when
510
- * available, falling back to WebSocket otherwise. The returned object
511
- * satisfies the AgentTransport interface in both cases.
509
+ * Public API — load a working transport. Real QUIC is not available in npm
510
+ * builds (see {@link QUIC_UNAVAILABLE_REASON}), so this returns the WebSocket
511
+ * fallback, which satisfies the AgentTransport interface.
512
512
  *
513
513
  * Example:
514
514
  * const t = await loadQuicTransport({ serverName: 'ruvultra:9100' });
515
515
  * await t.send('ruvultra:9100', { id: '1', type: 'task', payload: {...} });
516
- *
517
- * Federation v1 ships on the WebSocket fallback (this is the actual
518
- * working transport today). When the native QUIC binding lands, set
519
- * the AGENTIC_FLOW_QUIC_NATIVE=1 environment variable and the same
520
- * code path picks up the upgrade with no API changes.
521
516
  */
522
517
  export async function loadQuicTransport(config = {}) {
523
- if (await isRealQuicAvailable()) {
524
- // Future: wire to the native binding here.
525
- logger.info('QUIC transport: native binding selected');
526
- }
527
- else {
528
- if (process.env.NODE_ENV !== 'test') {
529
- logger.warn('QUIC native binding not available; using WebSocket fallback. ' +
530
- 'Set AGENTIC_FLOW_QUIC_NATIVE=1 once a native build is installed.');
531
- }
518
+ if (process.env.NODE_ENV !== 'test') {
519
+ logger.warn('QUIC unavailable; using WebSocket fallback. ' + QUIC_UNAVAILABLE_REASON);
532
520
  }
533
521
  return WebSocketFallbackTransport.create(config);
534
522
  }
@@ -536,10 +524,18 @@ export async function loadQuicTransport(config = {}) {
536
524
  export async function isQuicAvailable() {
537
525
  return isRealQuicAvailable();
538
526
  }
527
+ /** Availability plus the reason when QUIC is unavailable. */
528
+ export async function getQuicStatus() {
529
+ const available = await isRealQuicAvailable();
530
+ return available
531
+ ? { available, fallback: 'websocket' }
532
+ : { available, reason: QUIC_UNAVAILABLE_REASON, fallback: 'websocket' };
533
+ }
539
534
  export async function getTransportCapabilities() {
540
535
  const quic = await isRealQuicAvailable();
541
536
  return {
542
537
  quicAvailable: quic,
538
+ ...(quic ? {} : { quicUnavailableReason: QUIC_UNAVAILABLE_REASON }),
543
539
  webSocketFallbackAvailable: true,
544
540
  selectedBackend: quic ? 'quic' : 'websocket',
545
541
  };
@@ -1 +1 @@
1
- {"version":3,"file":"quic-loader.js","sourceRoot":"","sources":["../../src/transport/quic-loader.ts"],"names":[],"mappings":"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","sourcesContent":["// QUIC Transport Loader with WebSocket fallback\n//\n// Backported from outer repo loader pattern. Exposes a single\n// loadQuicTransport(config) entry point that:\n//\n// 1. Tries to load the WASM-backed QuicClient/QuicServer (real QUIC if a\n// native build is wired in the future).\n// 2. Falls back to WebSocketFallbackTransport when QUIC is unavailable\n// OR when the WASM stub is detected (current state — see\n// crates/agentic-flow-quic/src/wasm.rs comment: WASM build is a stub\n// because browsers can't do raw UDP/QUIC; production QUIC needs\n// native Node.js builds which haven't shipped yet).\n//\n// The fallback uses standard WebSocket (ws://) so it works on all Node\n// versions without complex native dependencies. Same async send/receive\n// API surface as QuicTransport.\n//\n// Federation use case (ruvnet/ruflo ADR-104): two peers on the same\n// tailnet can call loadQuicTransport({ serverName: 'peer.tailnet' }) and\n// exchange signed envelopes today, with zero code change required when\n// the native QUIC build lands later.\n\nimport { logger } from '../utils/logger.js';\nimport WebSocket, { WebSocketServer, type RawData } from 'ws';\nimport { createHash } from 'node:crypto';\nimport { createServer as createHttpsServer } from 'node:https';\nimport { readFileSync } from 'node:fs';\n\n/** TLS configuration for wss:// peers (ADR-107). */\nexport interface TlsConfig {\n /** Path to PEM cert file (server side — bind certs for the listener). */\n certPath?: string;\n /** Path to PEM key file (server side). */\n keyPath?: string;\n /**\n * Pinned `sha256/<base64>` fingerprints of acceptable peer certs\n * (client side — outbound connections).\n *\n * When set, ONLY these exact certs are accepted. CA validation is\n * skipped — the fingerprint IS the trust anchor. Fail-closed: if the\n * peer's cert rotates and the fingerprint doesn't match, the\n * connection is refused (operator must update config + restart).\n *\n * This prevents:\n * - Compromised public CAs issuing rogue certs for our domain\n * - TLS-MITM attacks where the attacker holds a valid cert chain\n */\n pinnedFingerprints?: string[];\n /**\n * Optional CA bundle path for non-pinned mode (e.g. private CA).\n * Used only when `pinnedFingerprints` is empty/unset.\n */\n caPath?: string;\n}\n\n/** Caller-facing config — minimal common surface across both backends. */\nexport interface QuicTransportConfig {\n serverName?: string;\n maxIdleTimeoutMs?: number;\n maxConcurrentStreams?: number;\n enable0Rtt?: boolean;\n /** TLS materials for wss:// listeners + clients (ADR-107). */\n tls?: TlsConfig;\n}\n\nexport interface AgentMessage {\n id: string;\n type: 'task' | 'result' | 'status' | 'coordination' | 'heartbeat' | string;\n payload: unknown;\n metadata?: Record<string, unknown>;\n /**\n * Stream multiplexing identifier. Messages with different streamIds\n * to the same peer are independent — receive queues and onMessage\n * handlers can scope per-stream, eliminating head-of-line blocking\n * for sequential `await` patterns on a single peer connection.\n *\n * Defaults to `'default'` if omitted (backward compat). Common\n * patterns:\n * - One stream per logical request type (`'rpc'`, `'event'`,\n * `'control'`)\n * - One stream per task (`taskId` doubled as streamId)\n * - One stream per priority class (`'high'`, `'normal'`, `'low'`)\n *\n * Maps cleanly to native QUIC streams when AGENTIC_FLOW_QUIC_NATIVE=1\n * (each app-layer streamId becomes a QUIC stream id at that point).\n */\n streamId?: string | number;\n}\n\n/** Default streamId when caller omits it. Backward-compat sentinel. */\nexport const DEFAULT_STREAM_ID = 'default';\n\n/** Largest WebSocket frame accepted from a peer (federation envelopes are ~100B-10KB). */\nexport const MAX_WS_PAYLOAD_BYTES = 1024 * 1024;\n/** Unconsumed messages kept per (peer, stream) for receive(); oldest dropped beyond this. */\nexport const MAX_QUEUED_PER_STREAM = 1000;\n/** Distinct (peer, stream) queues kept; messages for further new streams are dropped. */\nexport const MAX_QUEUE_STREAMS = 1024;\n\nexport interface PoolStatistics {\n active: number;\n idle: number;\n created: number;\n closed: number;\n}\n\n/** Inbound message handler — called for every received message. */\nexport type InboundMessageHandler = (\n address: string,\n message: AgentMessage,\n) => void | Promise<void>;\n\n/**\n * Per-stream subscription options. Pass to `onMessage` to scope a\n * handler to a specific streamId (only fires for messages with that\n * exact streamId). Omit to receive all streams.\n */\nexport interface OnMessageOptions {\n readonly streamId?: string | number;\n}\n\n/** Common interface both real-QUIC and fallback transports satisfy. */\nexport interface AgentTransport {\n send(address: string, message: AgentMessage): Promise<void>;\n /**\n * Receive the next message from a peer. Optional `streamId` scopes\n * to that stream's queue (independent of other streams to the same\n * peer). Omit to use the default stream — backward-compat behavior.\n */\n receive(address: string, streamId?: string | number): Promise<AgentMessage>;\n request(address: string, message: AgentMessage): Promise<AgentMessage>;\n sendBatch(address: string, messages: AgentMessage[]): Promise<void>;\n getStats(): Promise<PoolStatistics>;\n close(): Promise<void>;\n /**\n * Subscribe to inbound messages. The handler fires for every received\n * message that matches `options.streamId` (if provided) or for every\n * message regardless of streamId (if options omitted).\n *\n * Multiple handlers may be registered (per-stream OR all-streams or\n * a mix). Errors thrown by a handler are logged but do not stop\n * delivery to other handlers.\n *\n * Optional method — implementations that don't support push-style\n * delivery may omit it. Callers should use `transport.onMessage?.(h)`\n * to gracefully degrade.\n */\n onMessage?(handler: InboundMessageHandler, options?: OnMessageOptions): void;\n}\n\n/**\n * WebSocket fallback transport.\n *\n * Spec compliance: implements the AgentTransport interface using\n * `ws://` (or `wss://` if address starts with `wss://`). Each call to\n * `send` lazily opens (or reuses) a connection to `address`. The\n * `receive(address)` call drains the next queued message for that\n * address; if none is queued it polls every 100ms until one arrives.\n *\n * Limits vs real QUIC: no 0-RTT resumption, no multiplexed streams\n * (one TCP connection per peer), TLS handled by the WS layer (use\n * `wss://` for encryption). Performance is \"good enough\" for federation\n * messages at human/agent rates (≤ 100 RPS per peer).\n */\nclass WebSocketFallbackTransport implements AgentTransport {\n private connections = new Map<string, WebSocket>();\n /**\n * Per-(address, streamId) message queue. Composite key shape\n * `${address}#${streamId}` — see {@link queueKey}. Each stream gets\n * its own FIFO so receive(addr, streamA) is independent of\n * receive(addr, streamB) — eliminates head-of-line blocking on a\n * single peer connection.\n */\n private messageQueue = new Map<string, AgentMessage[]>();\n private connectionsCreated = 0;\n private connectionsClosed = 0;\n private servers = new Map<number, WebSocketServer>();\n /**\n * Inbound handlers. Each entry is { handler, streamId? }. When\n * streamId is undefined the handler receives ALL messages\n * regardless of stream; otherwise only messages with the matching\n * streamId. Lets callers register both per-stream + catch-all.\n */\n private inboundHandlers = new Set<{\n handler: InboundMessageHandler;\n streamId?: string | number;\n }>();\n /**\n * Server-accepted (inbound) sockets indexed by peer host (#162). A\n * peer that already dialed us has a live, full-duplex socket here;\n * {@link getOrCreateConnection} reuses it for replies instead of\n * opening a fresh outbound connection — which, on a direct\n * point-to-point link, can hit a per-process stale scoped route\n * (`EHOSTUNREACH`) even while the inbound direction is healthy.\n */\n private inboundByHost = new Map<string, WebSocket>();\n /** Active liveness-probe intervals, cleared on close (#162). */\n private heartbeats = new Set<ReturnType<typeof setInterval>>();\n\n /**\n * Liveness ping cadence, derived from `maxIdleTimeoutMs` (#162 — this\n * config was previously accepted but never used). Pings at 1/6 of the\n * idle timeout so a dead socket is caught within ~1/3 of it. Default\n * 30000ms → 5000ms.\n */\n private get pingIntervalMs(): number {\n return Math.max(1000, Math.floor(this.config.maxIdleTimeoutMs / 6));\n }\n\n /**\n * Normalize an address or socket `remoteAddress` to a bare host key\n * for {@link inboundByHost} lookups. Strips `ws(s)://` scheme, an\n * IPv6-mapped IPv4 prefix (`::ffff:`), bracketed IPv6 (`[::1]:port`),\n * and a trailing `:port` on plain `host:port` forms. Bare IPv6\n * (multiple colons, no brackets) is returned unchanged.\n */\n private hostOf(addr: string): string {\n let s = addr.replace(/^wss?:\\/\\//i, '');\n const bracket = s.match(/^\\[([^\\]]+)\\](?::\\d+)?$/);\n if (bracket) s = bracket[1];\n else if (/^[^:]+:\\d+$/.test(s)) s = s.slice(0, s.lastIndexOf(':'));\n return s.replace(/^::ffff:/i, '');\n }\n\n /**\n * Liveness probe for a socket (#162). Pings on {@link pingIntervalMs};\n * a socket that misses a ping/pong window is terminated so a stale\n * connection can't silently black-hole sends. The interval is unref'd\n * (never keeps the process alive on its own) and cleared on close/error.\n */\n private startHeartbeat(ws: WebSocket): void {\n let alive = true;\n ws.on('pong', () => { alive = true; });\n const interval = setInterval(() => {\n if (!alive) {\n try { ws.terminate(); } catch { /* already gone */ }\n return; // 'close' fires → stop() clears this interval\n }\n alive = false;\n try { ws.ping(); } catch { /* socket is closing */ }\n }, this.pingIntervalMs);\n (interval as { unref?: () => void }).unref?.();\n this.heartbeats.add(interval);\n const stop = () => {\n clearInterval(interval);\n this.heartbeats.delete(interval);\n };\n ws.on('close', stop);\n ws.on('error', stop);\n }\n\n /** Compose the per-(address, streamId) queue key. */\n private queueKey(address: string, streamId: string | number): string {\n return `${address}#${streamId}`;\n }\n\n /** Resolve the streamId for a message — defaults to DEFAULT_STREAM_ID. */\n private streamOf(message: AgentMessage): string | number {\n return message.streamId ?? DEFAULT_STREAM_ID;\n }\n\n constructor(private readonly config: Required<QuicTransportConfig>) {}\n\n static async create(config: QuicTransportConfig = {}): Promise<WebSocketFallbackTransport> {\n const fullConfig: Required<QuicTransportConfig> = {\n serverName: config.serverName ?? 'localhost',\n maxIdleTimeoutMs: config.maxIdleTimeoutMs ?? 30000,\n maxConcurrentStreams: config.maxConcurrentStreams ?? 100,\n // Not applicable for WebSocket — record but ignore\n enable0Rtt: config.enable0Rtt ?? false,\n tls: config.tls ?? {},\n };\n return new WebSocketFallbackTransport(fullConfig);\n }\n\n /**\n * Bind a server-side listener so this transport instance can RECEIVE\n * messages from a remote peer (in addition to sending). Federation\n * peers run BOTH a listener and a client — calling listen(9100) plus\n * send('peer:9100', ...) gives bidirectional connectivity.\n *\n * Enables `permessage-deflate` compression with thresholds chosen\n * for federation envelopes (typically JSON, 100B-10KB):\n * - threshold: 256B — don't waste CPU compressing tiny pings\n * - level: 3 — balanced compression vs CPU (zlib's BEST_SPEED→6 range)\n * - serverNoContextTakeover: true — bound per-conn memory growth\n */\n async listen(port: number, host = '127.0.0.1'): Promise<void> {\n if (this.servers.has(port)) return;\n return new Promise((resolve, reject) => {\n const tls = this.config.tls;\n const wssOpts: ConstructorParameters<typeof WebSocketServer>[0] = {\n maxPayload: MAX_WS_PAYLOAD_BYTES,\n perMessageDeflate: {\n threshold: 256,\n zlibDeflateOptions: { level: 3 },\n serverNoContextTakeover: true,\n clientNoContextTakeover: true,\n },\n };\n // ADR-107: if cert+key paths are configured, bind via https.Server\n // (wss://). Otherwise bind plain ws:// directly.\n if (tls?.certPath && tls?.keyPath) {\n const cert = readFileSync(tls.certPath);\n const key = readFileSync(tls.keyPath);\n const httpsServer = createHttpsServer({ cert, key });\n httpsServer.listen(port, host, () => {\n const wss = new WebSocketServer({ ...wssOpts, server: httpsServer });\n this.attachServerHandlers(wss);\n this.servers.set(port, wss);\n resolve();\n });\n httpsServer.on('error', reject);\n return;\n }\n const wss = new WebSocketServer({ ...wssOpts, port, host });\n wss.on('listening', () => {\n this.servers.set(port, wss);\n resolve();\n });\n wss.on('error', reject);\n this.attachServerHandlers(wss);\n });\n }\n\n /**\n * Wire the server's `connection` and per-socket `message` handlers.\n * Extracted so the wss:// path (where the WebSocketServer is attached\n * to a pre-created https.Server) can share the same logic.\n */\n private attachServerHandlers(wss: WebSocketServer): void {\n wss.on('connection', (ws, req) => {\n const remoteAddr = `${req.socket.remoteAddress}:${req.socket.remotePort}`;\n // #162: register this accepted socket for outbound reuse, and probe\n // it for liveness. Reusing it for replies avoids a fresh (stale-route\n // prone) outbound dial back to the same peer.\n const host = this.hostOf(req.socket.remoteAddress ?? remoteAddr);\n this.inboundByHost.set(host, ws);\n this.startHeartbeat(ws);\n const dropInbound = () => {\n if (this.inboundByHost.get(host) === ws) this.inboundByHost.delete(host);\n };\n ws.on('close', dropInbound);\n ws.on('error', dropInbound);\n\n ws.on('message', (raw: RawData) => {\n try {\n const message = JSON.parse(raw.toString()) as AgentMessage;\n this.deliverInbound(remoteAddr, message);\n } catch (err) {\n logger.warn('Dropped malformed inbound WS message', { remoteAddr, err });\n }\n });\n });\n }\n\n private async getOrCreateConnection(address: string): Promise<WebSocket> {\n return new Promise((resolve, reject) => {\n const existing = this.connections.get(address);\n if (existing && existing.readyState === WebSocket.OPEN) {\n resolve(existing);\n return;\n }\n\n // #162: prefer an already-open INBOUND socket from the same peer host\n // before dialing. WebSocket is full-duplex, so the server-accepted\n // socket can carry our replies — and the inbound direction stays\n // healthy when a fresh outbound dial would hit a stale scoped route.\n const inbound = this.inboundByHost.get(this.hostOf(address));\n if (inbound && inbound.readyState === WebSocket.OPEN) {\n resolve(inbound);\n return;\n }\n\n const url = address.startsWith('ws://') || address.startsWith('wss://')\n ? address\n : `ws://${address}`;\n\n // ADR-107: cert pinning for wss:// peers. Build the WS options\n // with both compression (perf) and TLS hooks (security).\n const tls = this.config.tls;\n const isWss = url.startsWith('wss://');\n const wsOpts: WebSocket.ClientOptions = {\n maxPayload: MAX_WS_PAYLOAD_BYTES,\n perMessageDeflate: {\n threshold: 256,\n zlibDeflateOptions: { level: 3 },\n serverNoContextTakeover: true,\n clientNoContextTakeover: true,\n },\n };\n\n if (isWss && tls?.pinnedFingerprints && tls.pinnedFingerprints.length > 0) {\n // Fail-closed pinning: ONLY accept the listed cert fingerprints.\n // CA path validation is irrelevant — the fingerprint IS the trust\n // anchor. If the cert rotates, the operator must update config.\n const pinned = new Set(tls.pinnedFingerprints);\n // Cast: ws's `checkServerIdentity` is typed as returning boolean\n // but the underlying `tls.checkServerIdentity` (which it\n // forwards to) accepts `Error | undefined`. The runtime\n // semantics are: throw OR return Error → reject; otherwise accept.\n // The boolean type signature is overly restrictive.\n (wsOpts as unknown as { checkServerIdentity: unknown }).checkServerIdentity = (\n _host: string,\n cert: { raw: Buffer },\n ): Error | undefined => {\n // cert.raw is the DER-encoded cert bytes; sha256/<base64> matches\n // common pinning notation (and what `openssl x509 -fingerprint\n // -sha256` outputs after base64-encoding).\n const fp = `sha256/${createHash('sha256').update(cert.raw).digest('base64')}`;\n if (!pinned.has(fp)) {\n return new Error(\n `Federation TLS: peer cert fingerprint ${fp} not in pinned set ` +\n `(${pinned.size} fingerprint(s) configured)`,\n );\n }\n return undefined; // accept\n };\n // When pinning is on, we explicitly DON'T want CA validation\n // (the fingerprint check above is the real auth). But we also\n // DON'T want to silently accept ANY cert — the checkServerIdentity\n // above is still called.\n wsOpts.rejectUnauthorized = false;\n } else if (isWss && tls?.caPath) {\n // Non-pinned mode: validate against the configured CA bundle.\n wsOpts.ca = readFileSync(tls.caPath);\n wsOpts.rejectUnauthorized = true;\n }\n // (no tls config + ws:// → plain unencrypted; ADR-104 documents\n // tailnet-as-TLS as the recommended path)\n\n const ws = new WebSocket(url, wsOpts);\n\n ws.on('open', () => {\n this.connections.set(address, ws);\n this.connectionsCreated++;\n this.startHeartbeat(ws); // #162: keep the outbound link probed\n resolve(ws);\n });\n\n ws.on('error', (error: Error) => {\n reject(new Error(`WebSocket connection to ${url} failed: ${error.message}`));\n });\n\n ws.on('close', () => {\n this.connectionsClosed++;\n this.connections.delete(address);\n });\n\n ws.on('message', (raw: RawData) => {\n try {\n const message = JSON.parse(raw.toString()) as AgentMessage;\n this.deliverInbound(address, message);\n } catch (err) {\n logger.warn('Dropped malformed WebSocket message', { address, err });\n }\n });\n });\n }\n\n async send(address: string, message: AgentMessage): Promise<void> {\n const ws = await this.getOrCreateConnection(address);\n ws.send(JSON.stringify(message));\n }\n\n /**\n * Register an inbound handler. Optional `options.streamId` scopes\n * the handler to a specific stream (only fires for messages with\n * matching streamId). Omit to subscribe to ALL streams.\n *\n * Patterns:\n * onMessage(h) — receives all\n * onMessage(h, { streamId: 'rpc' }) — receives only rpc\n * onMessage(h, { streamId: 'event' }) — receives only event\n * (both registered) — both fire on\n * their respective streams\n */\n onMessage(handler: InboundMessageHandler, options: OnMessageOptions = {}): void {\n this.inboundHandlers.add({ handler, streamId: options.streamId });\n }\n\n /**\n * Fire all matching handlers for a received message. Stream-scoped\n * handlers only fire when the message's streamId matches; all-stream\n * handlers always fire. Errors thrown sync OR async-rejected by one\n * handler don't stop delivery to others.\n */\n private dispatchInbound(address: string, message: AgentMessage): boolean {\n if (this.inboundHandlers.size === 0) return false;\n const msgStream = this.streamOf(message);\n let delivered = false;\n for (const entry of this.inboundHandlers) {\n // Stream filter: scoped handler only fires on matching streamId\n if (entry.streamId !== undefined && entry.streamId !== msgStream) continue;\n delivered = true;\n try {\n const r = entry.handler(address, message);\n if (r && typeof (r as Promise<void>).catch === 'function') {\n (r as Promise<void>).catch((err) => {\n logger.warn('Inbound handler rejected', { address, err });\n });\n }\n } catch (err) {\n logger.warn('Inbound handler threw', { address, err });\n }\n }\n return delivered;\n }\n\n /**\n * Hand an inbound message to the matching onMessage handlers. Only a\n * message no handler consumed is queued for receive(), and the queues are\n * bounded so a peer cannot grow memory without limit.\n */\n private deliverInbound(address: string, message: AgentMessage): void {\n if (this.dispatchInbound(address, message)) return;\n // Per-stream queue (default stream when message.streamId omitted)\n const key = this.queueKey(address, this.streamOf(message));\n let queue = this.messageQueue.get(key);\n if (!queue) {\n if (this.messageQueue.size >= MAX_QUEUE_STREAMS) {\n logger.warn('Dropped inbound message: too many queued streams', { address, key });\n return;\n }\n queue = [];\n this.messageQueue.set(key, queue);\n }\n queue.push(message);\n if (queue.length > MAX_QUEUED_PER_STREAM) {\n queue.shift();\n logger.warn('Inbound queue full; dropped oldest message', { address, key });\n }\n }\n\n /** Shift the head of a queue, dropping the queue once empty so stream keys don't accumulate. */\n private takeFrom(key: string, queue: AgentMessage[]): AgentMessage {\n const message = queue.shift()!;\n if (queue.length === 0) this.messageQueue.delete(key);\n return message;\n }\n\n /** Messages waiting for receive(), across all peers and streams. */\n queuedMessageCount(): number {\n let total = 0;\n for (const queue of this.messageQueue.values()) total += queue.length;\n return total;\n }\n\n async receive(address: string, streamId: string | number = DEFAULT_STREAM_ID): Promise<AgentMessage> {\n const key = this.queueKey(address, streamId);\n // Fast path\n const queue = this.messageQueue.get(key) ?? [];\n if (queue.length > 0) return this.takeFrom(key, queue);\n\n // Poll (caller must time out externally if they don't want to wait)\n return new Promise((resolve) => {\n const interval = setInterval(() => {\n const q = this.messageQueue.get(key) ?? [];\n if (q.length > 0) {\n clearInterval(interval);\n resolve(this.takeFrom(key, q));\n }\n }, 100);\n });\n }\n\n async request(address: string, message: AgentMessage): Promise<AgentMessage> {\n await this.send(address, message);\n return this.receive(address);\n }\n\n async sendBatch(address: string, messages: AgentMessage[]): Promise<void> {\n await Promise.all(messages.map((m) => this.send(address, m)));\n }\n\n async getStats(): Promise<PoolStatistics> {\n return {\n active: this.connections.size,\n idle: 0,\n created: this.connectionsCreated,\n closed: this.connectionsClosed,\n };\n }\n\n async close(): Promise<void> {\n // Outbound clients first.\n for (const ws of this.connections.values()) {\n ws.terminate();\n }\n this.connections.clear();\n this.messageQueue.clear();\n\n // Stop all liveness probes and drop the inbound index (#162).\n for (const interval of this.heartbeats) clearInterval(interval);\n this.heartbeats.clear();\n this.inboundByHost.clear();\n\n // Inbound: WebSocketServer.close() blocks until every accepted\n // socket disconnects. Forcibly terminate them so the close\n // callback fires within the test/CI timeout window.\n for (const wss of this.servers.values()) {\n for (const client of wss.clients) {\n try {\n client.terminate();\n } catch {\n /* socket already gone */\n }\n }\n await new Promise<void>((resolve) => wss.close(() => resolve()));\n }\n this.servers.clear();\n }\n}\n\n/**\n * Detect whether the WASM-backed QUIC transport is \"real\" (i.e. it\n * actually moves bytes on the wire) vs the current stub. The stub\n * returns 0ms for connect+send and never increments the server's\n * received-bytes counter. We probe by observing a documented marker\n * on the WASM module: when it's truly wired the loader function\n * `defaultConfig` returns an object whose round-trip through\n * `WasmQuicClient.new` actually opens a UDP socket — failing fast on\n * an OS that blocks UDP outbound (e.g. some sandboxed CI envs).\n *\n * Until the native build lands this returns false; the loader picks\n * WebSocket. When the native binding is wired this returns true and\n * the loader picks real QUIC. Callers get the same API either way.\n */\nasync function isRealQuicAvailable(): Promise<boolean> {\n try {\n // The WASM file is published in `wasm/quic/` of this package. We\n // do NOT use it for federation today (per the wasm.rs note: it's a\n // stub since browsers can't do UDP). When a native binding is added\n // this probe should switch to detect that binding instead.\n const native = process.env.AGENTIC_FLOW_QUIC_NATIVE === '1';\n return native;\n } catch {\n return false;\n }\n}\n\n/**\n * Public API — load a working transport, preferring real QUIC when\n * available, falling back to WebSocket otherwise. The returned object\n * satisfies the AgentTransport interface in both cases.\n *\n * Example:\n * const t = await loadQuicTransport({ serverName: 'ruvultra:9100' });\n * await t.send('ruvultra:9100', { id: '1', type: 'task', payload: {...} });\n *\n * Federation v1 ships on the WebSocket fallback (this is the actual\n * working transport today). When the native QUIC binding lands, set\n * the AGENTIC_FLOW_QUIC_NATIVE=1 environment variable and the same\n * code path picks up the upgrade with no API changes.\n */\nexport async function loadQuicTransport(\n config: QuicTransportConfig = {},\n): Promise<AgentTransport> {\n if (await isRealQuicAvailable()) {\n // Future: wire to the native binding here.\n logger.info('QUIC transport: native binding selected');\n } else {\n if (process.env.NODE_ENV !== 'test') {\n logger.warn(\n 'QUIC native binding not available; using WebSocket fallback. ' +\n 'Set AGENTIC_FLOW_QUIC_NATIVE=1 once a native build is installed.',\n );\n }\n }\n return WebSocketFallbackTransport.create(config);\n}\n\n/** Quick capability probe for the doctor / health surface. */\nexport async function isQuicAvailable(): Promise<boolean> {\n return isRealQuicAvailable();\n}\n\nexport interface TransportCapabilities {\n quicAvailable: boolean;\n webSocketFallbackAvailable: true;\n selectedBackend: 'quic' | 'websocket';\n}\n\nexport async function getTransportCapabilities(): Promise<TransportCapabilities> {\n const quic = await isRealQuicAvailable();\n return {\n quicAvailable: quic,\n webSocketFallbackAvailable: true,\n selectedBackend: quic ? 'quic' : 'websocket',\n };\n}\n\nexport { WebSocketFallbackTransport };\n"]}
1
+ {"version":3,"file":"quic-loader.js","sourceRoot":"","sources":["../../src/transport/quic-loader.ts"],"names":[],"mappings":"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","sourcesContent":["// QUIC Transport Loader with WebSocket fallback\n//\n// Backported from outer repo loader pattern. Exposes a single\n// loadQuicTransport(config) entry point that:\n//\n// 1. Tries to load the WASM-backed QuicClient/QuicServer (real QUIC if a\n// native build is wired in the future).\n// 2. Falls back to WebSocketFallbackTransport when QUIC is unavailable\n// OR when the WASM stub is detected (current state — see\n// crates/agentic-flow-quic/src/wasm.rs comment: WASM build is a stub\n// because browsers can't do raw UDP/QUIC; production QUIC needs\n// native Node.js builds which haven't shipped yet).\n//\n// The fallback uses standard WebSocket (ws://) so it works on all Node\n// versions without complex native dependencies. Same async send/receive\n// API surface as QuicTransport.\n//\n// Federation use case (ruvnet/ruflo ADR-104): two peers on the same\n// tailnet can call loadQuicTransport({ serverName: 'peer.tailnet' }) and\n// exchange signed envelopes today, with zero code change required when\n// the native QUIC build lands later.\n\nimport { logger } from '../utils/logger.js';\nimport WebSocket, { WebSocketServer, type RawData } from 'ws';\nimport { createHash } from 'node:crypto';\nimport { createServer as createHttpsServer } from 'node:https';\nimport { readFileSync } from 'node:fs';\n\n/** TLS configuration for wss:// peers (ADR-107). */\nexport interface TlsConfig {\n /** Path to PEM cert file (server side — bind certs for the listener). */\n certPath?: string;\n /** Path to PEM key file (server side). */\n keyPath?: string;\n /**\n * Pinned `sha256/<base64>` fingerprints of acceptable peer certs\n * (client side — outbound connections).\n *\n * When set, ONLY these exact certs are accepted. CA validation is\n * skipped — the fingerprint IS the trust anchor. Fail-closed: if the\n * peer's cert rotates and the fingerprint doesn't match, the\n * connection is refused (operator must update config + restart).\n *\n * This prevents:\n * - Compromised public CAs issuing rogue certs for our domain\n * - TLS-MITM attacks where the attacker holds a valid cert chain\n */\n pinnedFingerprints?: string[];\n /**\n * Optional CA bundle path for non-pinned mode (e.g. private CA).\n * Used only when `pinnedFingerprints` is empty/unset.\n */\n caPath?: string;\n}\n\n/** Caller-facing config — minimal common surface across both backends. */\nexport interface QuicTransportConfig {\n serverName?: string;\n maxIdleTimeoutMs?: number;\n maxConcurrentStreams?: number;\n enable0Rtt?: boolean;\n /** TLS materials for wss:// listeners + clients (ADR-107). */\n tls?: TlsConfig;\n}\n\nexport interface AgentMessage {\n id: string;\n type: 'task' | 'result' | 'status' | 'coordination' | 'heartbeat' | string;\n payload: unknown;\n metadata?: Record<string, unknown>;\n /**\n * Stream multiplexing identifier. Messages with different streamIds\n * to the same peer are independent — receive queues and onMessage\n * handlers can scope per-stream, eliminating head-of-line blocking\n * for sequential `await` patterns on a single peer connection.\n *\n * Defaults to `'default'` if omitted (backward compat). Common\n * patterns:\n * - One stream per logical request type (`'rpc'`, `'event'`,\n * `'control'`)\n * - One stream per task (`taskId` doubled as streamId)\n * - One stream per priority class (`'high'`, `'normal'`, `'low'`)\n *\n * Would map to native QUIC stream ids if a native binding is ever added.\n */\n streamId?: string | number;\n}\n\n/** Default streamId when caller omits it. Backward-compat sentinel. */\nexport const DEFAULT_STREAM_ID = 'default';\n\n/** Largest WebSocket frame accepted from a peer (federation envelopes are ~100B-10KB). */\nexport const MAX_WS_PAYLOAD_BYTES = 1024 * 1024;\n/** Unconsumed messages kept per (peer, stream) for receive(); oldest dropped beyond this. */\nexport const MAX_QUEUED_PER_STREAM = 1000;\n/** Distinct (peer, stream) queues kept; messages for further new streams are dropped. */\nexport const MAX_QUEUE_STREAMS = 1024;\n\nexport interface PoolStatistics {\n active: number;\n idle: number;\n created: number;\n closed: number;\n}\n\n/** Inbound message handler — called for every received message. */\nexport type InboundMessageHandler = (\n address: string,\n message: AgentMessage,\n) => void | Promise<void>;\n\n/**\n * Per-stream subscription options. Pass to `onMessage` to scope a\n * handler to a specific streamId (only fires for messages with that\n * exact streamId). Omit to receive all streams.\n */\nexport interface OnMessageOptions {\n readonly streamId?: string | number;\n}\n\n/** Common interface both real-QUIC and fallback transports satisfy. */\nexport interface AgentTransport {\n send(address: string, message: AgentMessage): Promise<void>;\n /**\n * Receive the next message from a peer. Optional `streamId` scopes\n * to that stream's queue (independent of other streams to the same\n * peer). Omit to use the default stream — backward-compat behavior.\n */\n receive(address: string, streamId?: string | number): Promise<AgentMessage>;\n request(address: string, message: AgentMessage): Promise<AgentMessage>;\n sendBatch(address: string, messages: AgentMessage[]): Promise<void>;\n getStats(): Promise<PoolStatistics>;\n close(): Promise<void>;\n /**\n * Subscribe to inbound messages. The handler fires for every received\n * message that matches `options.streamId` (if provided) or for every\n * message regardless of streamId (if options omitted).\n *\n * Multiple handlers may be registered (per-stream OR all-streams or\n * a mix). Errors thrown by a handler are logged but do not stop\n * delivery to other handlers.\n *\n * Optional method — implementations that don't support push-style\n * delivery may omit it. Callers should use `transport.onMessage?.(h)`\n * to gracefully degrade.\n */\n onMessage?(handler: InboundMessageHandler, options?: OnMessageOptions): void;\n}\n\n/**\n * WebSocket fallback transport.\n *\n * Spec compliance: implements the AgentTransport interface using\n * `ws://` (or `wss://` if address starts with `wss://`). Each call to\n * `send` lazily opens (or reuses) a connection to `address`. The\n * `receive(address)` call drains the next queued message for that\n * address; if none is queued it polls every 100ms until one arrives.\n *\n * Limits vs real QUIC: no 0-RTT resumption, no multiplexed streams\n * (one TCP connection per peer), TLS handled by the WS layer (use\n * `wss://` for encryption). Performance is \"good enough\" for federation\n * messages at human/agent rates (≤ 100 RPS per peer).\n */\nclass WebSocketFallbackTransport implements AgentTransport {\n private connections = new Map<string, WebSocket>();\n /**\n * Per-(address, streamId) message queue. Composite key shape\n * `${address}#${streamId}` — see {@link queueKey}. Each stream gets\n * its own FIFO so receive(addr, streamA) is independent of\n * receive(addr, streamB) — eliminates head-of-line blocking on a\n * single peer connection.\n */\n private messageQueue = new Map<string, AgentMessage[]>();\n private connectionsCreated = 0;\n private connectionsClosed = 0;\n private servers = new Map<number, WebSocketServer>();\n /**\n * Inbound handlers. Each entry is { handler, streamId? }. When\n * streamId is undefined the handler receives ALL messages\n * regardless of stream; otherwise only messages with the matching\n * streamId. Lets callers register both per-stream + catch-all.\n */\n private inboundHandlers = new Set<{\n handler: InboundMessageHandler;\n streamId?: string | number;\n }>();\n /**\n * Server-accepted (inbound) sockets indexed by peer host (#162). A\n * peer that already dialed us has a live, full-duplex socket here;\n * {@link getOrCreateConnection} reuses it for replies instead of\n * opening a fresh outbound connection — which, on a direct\n * point-to-point link, can hit a per-process stale scoped route\n * (`EHOSTUNREACH`) even while the inbound direction is healthy.\n */\n private inboundByHost = new Map<string, WebSocket>();\n /** Active liveness-probe intervals, cleared on close (#162). */\n private heartbeats = new Set<ReturnType<typeof setInterval>>();\n\n /**\n * Liveness ping cadence, derived from `maxIdleTimeoutMs` (#162 — this\n * config was previously accepted but never used). Pings at 1/6 of the\n * idle timeout so a dead socket is caught within ~1/3 of it. Default\n * 30000ms → 5000ms.\n */\n private get pingIntervalMs(): number {\n return Math.max(1000, Math.floor(this.config.maxIdleTimeoutMs / 6));\n }\n\n /**\n * Normalize an address or socket `remoteAddress` to a bare host key\n * for {@link inboundByHost} lookups. Strips `ws(s)://` scheme, an\n * IPv6-mapped IPv4 prefix (`::ffff:`), bracketed IPv6 (`[::1]:port`),\n * and a trailing `:port` on plain `host:port` forms. Bare IPv6\n * (multiple colons, no brackets) is returned unchanged.\n */\n private hostOf(addr: string): string {\n let s = addr.replace(/^wss?:\\/\\//i, '');\n const bracket = s.match(/^\\[([^\\]]+)\\](?::\\d+)?$/);\n if (bracket) s = bracket[1];\n else if (/^[^:]+:\\d+$/.test(s)) s = s.slice(0, s.lastIndexOf(':'));\n return s.replace(/^::ffff:/i, '');\n }\n\n /**\n * Liveness probe for a socket (#162). Pings on {@link pingIntervalMs};\n * a socket that misses a ping/pong window is terminated so a stale\n * connection can't silently black-hole sends. The interval is unref'd\n * (never keeps the process alive on its own) and cleared on close/error.\n */\n private startHeartbeat(ws: WebSocket): void {\n let alive = true;\n ws.on('pong', () => { alive = true; });\n const interval = setInterval(() => {\n if (!alive) {\n try { ws.terminate(); } catch { /* already gone */ }\n return; // 'close' fires → stop() clears this interval\n }\n alive = false;\n try { ws.ping(); } catch { /* socket is closing */ }\n }, this.pingIntervalMs);\n (interval as { unref?: () => void }).unref?.();\n this.heartbeats.add(interval);\n const stop = () => {\n clearInterval(interval);\n this.heartbeats.delete(interval);\n };\n ws.on('close', stop);\n ws.on('error', stop);\n }\n\n /** Compose the per-(address, streamId) queue key. */\n private queueKey(address: string, streamId: string | number): string {\n return `${address}#${streamId}`;\n }\n\n /** Resolve the streamId for a message — defaults to DEFAULT_STREAM_ID. */\n private streamOf(message: AgentMessage): string | number {\n return message.streamId ?? DEFAULT_STREAM_ID;\n }\n\n constructor(private readonly config: Required<QuicTransportConfig>) {}\n\n static async create(config: QuicTransportConfig = {}): Promise<WebSocketFallbackTransport> {\n const fullConfig: Required<QuicTransportConfig> = {\n serverName: config.serverName ?? 'localhost',\n maxIdleTimeoutMs: config.maxIdleTimeoutMs ?? 30000,\n maxConcurrentStreams: config.maxConcurrentStreams ?? 100,\n // Not applicable for WebSocket — record but ignore\n enable0Rtt: config.enable0Rtt ?? false,\n tls: config.tls ?? {},\n };\n return new WebSocketFallbackTransport(fullConfig);\n }\n\n /**\n * Bind a server-side listener so this transport instance can RECEIVE\n * messages from a remote peer (in addition to sending). Federation\n * peers run BOTH a listener and a client — calling listen(9100) plus\n * send('peer:9100', ...) gives bidirectional connectivity.\n *\n * Enables `permessage-deflate` compression with thresholds chosen\n * for federation envelopes (typically JSON, 100B-10KB):\n * - threshold: 256B — don't waste CPU compressing tiny pings\n * - level: 3 — balanced compression vs CPU (zlib's BEST_SPEED→6 range)\n * - serverNoContextTakeover: true — bound per-conn memory growth\n */\n async listen(port: number, host = '127.0.0.1'): Promise<void> {\n if (this.servers.has(port)) return;\n return new Promise((resolve, reject) => {\n const tls = this.config.tls;\n const wssOpts: ConstructorParameters<typeof WebSocketServer>[0] = {\n maxPayload: MAX_WS_PAYLOAD_BYTES,\n perMessageDeflate: {\n threshold: 256,\n zlibDeflateOptions: { level: 3 },\n serverNoContextTakeover: true,\n clientNoContextTakeover: true,\n },\n };\n // ADR-107: if cert+key paths are configured, bind via https.Server\n // (wss://). Otherwise bind plain ws:// directly.\n if (tls?.certPath && tls?.keyPath) {\n const cert = readFileSync(tls.certPath);\n const key = readFileSync(tls.keyPath);\n const httpsServer = createHttpsServer({ cert, key });\n httpsServer.listen(port, host, () => {\n const wss = new WebSocketServer({ ...wssOpts, server: httpsServer });\n this.attachServerHandlers(wss);\n this.servers.set(port, wss);\n resolve();\n });\n httpsServer.on('error', reject);\n return;\n }\n const wss = new WebSocketServer({ ...wssOpts, port, host });\n wss.on('listening', () => {\n this.servers.set(port, wss);\n resolve();\n });\n wss.on('error', reject);\n this.attachServerHandlers(wss);\n });\n }\n\n /**\n * Wire the server's `connection` and per-socket `message` handlers.\n * Extracted so the wss:// path (where the WebSocketServer is attached\n * to a pre-created https.Server) can share the same logic.\n */\n private attachServerHandlers(wss: WebSocketServer): void {\n wss.on('connection', (ws, req) => {\n const remoteAddr = `${req.socket.remoteAddress}:${req.socket.remotePort}`;\n // #162: register this accepted socket for outbound reuse, and probe\n // it for liveness. Reusing it for replies avoids a fresh (stale-route\n // prone) outbound dial back to the same peer.\n const host = this.hostOf(req.socket.remoteAddress ?? remoteAddr);\n this.inboundByHost.set(host, ws);\n this.startHeartbeat(ws);\n const dropInbound = () => {\n if (this.inboundByHost.get(host) === ws) this.inboundByHost.delete(host);\n };\n ws.on('close', dropInbound);\n ws.on('error', dropInbound);\n\n ws.on('message', (raw: RawData) => {\n try {\n const message = JSON.parse(raw.toString()) as AgentMessage;\n this.deliverInbound(remoteAddr, message);\n } catch (err) {\n logger.warn('Dropped malformed inbound WS message', { remoteAddr, err });\n }\n });\n });\n }\n\n private async getOrCreateConnection(address: string): Promise<WebSocket> {\n return new Promise((resolve, reject) => {\n const existing = this.connections.get(address);\n if (existing && existing.readyState === WebSocket.OPEN) {\n resolve(existing);\n return;\n }\n\n // #162: prefer an already-open INBOUND socket from the same peer host\n // before dialing. WebSocket is full-duplex, so the server-accepted\n // socket can carry our replies — and the inbound direction stays\n // healthy when a fresh outbound dial would hit a stale scoped route.\n const inbound = this.inboundByHost.get(this.hostOf(address));\n if (inbound && inbound.readyState === WebSocket.OPEN) {\n resolve(inbound);\n return;\n }\n\n const url = address.startsWith('ws://') || address.startsWith('wss://')\n ? address\n : `ws://${address}`;\n\n // ADR-107: cert pinning for wss:// peers. Build the WS options\n // with both compression (perf) and TLS hooks (security).\n const tls = this.config.tls;\n const isWss = url.startsWith('wss://');\n const wsOpts: WebSocket.ClientOptions = {\n maxPayload: MAX_WS_PAYLOAD_BYTES,\n perMessageDeflate: {\n threshold: 256,\n zlibDeflateOptions: { level: 3 },\n serverNoContextTakeover: true,\n clientNoContextTakeover: true,\n },\n };\n\n if (isWss && tls?.pinnedFingerprints && tls.pinnedFingerprints.length > 0) {\n // Fail-closed pinning: ONLY accept the listed cert fingerprints.\n // CA path validation is irrelevant — the fingerprint IS the trust\n // anchor. If the cert rotates, the operator must update config.\n const pinned = new Set(tls.pinnedFingerprints);\n // Cast: ws's `checkServerIdentity` is typed as returning boolean\n // but the underlying `tls.checkServerIdentity` (which it\n // forwards to) accepts `Error | undefined`. The runtime\n // semantics are: throw OR return Error → reject; otherwise accept.\n // The boolean type signature is overly restrictive.\n (wsOpts as unknown as { checkServerIdentity: unknown }).checkServerIdentity = (\n _host: string,\n cert: { raw: Buffer },\n ): Error | undefined => {\n // cert.raw is the DER-encoded cert bytes; sha256/<base64> matches\n // common pinning notation (and what `openssl x509 -fingerprint\n // -sha256` outputs after base64-encoding).\n const fp = `sha256/${createHash('sha256').update(cert.raw).digest('base64')}`;\n if (!pinned.has(fp)) {\n return new Error(\n `Federation TLS: peer cert fingerprint ${fp} not in pinned set ` +\n `(${pinned.size} fingerprint(s) configured)`,\n );\n }\n return undefined; // accept\n };\n // When pinning is on, we explicitly DON'T want CA validation\n // (the fingerprint check above is the real auth). But we also\n // DON'T want to silently accept ANY cert — the checkServerIdentity\n // above is still called.\n wsOpts.rejectUnauthorized = false;\n } else if (isWss && tls?.caPath) {\n // Non-pinned mode: validate against the configured CA bundle.\n wsOpts.ca = readFileSync(tls.caPath);\n wsOpts.rejectUnauthorized = true;\n }\n // (no tls config + ws:// → plain unencrypted; ADR-104 documents\n // tailnet-as-TLS as the recommended path)\n\n const ws = new WebSocket(url, wsOpts);\n\n ws.on('open', () => {\n this.connections.set(address, ws);\n this.connectionsCreated++;\n this.startHeartbeat(ws); // #162: keep the outbound link probed\n resolve(ws);\n });\n\n ws.on('error', (error: Error) => {\n reject(new Error(`WebSocket connection to ${url} failed: ${error.message}`));\n });\n\n ws.on('close', () => {\n this.connectionsClosed++;\n this.connections.delete(address);\n });\n\n ws.on('message', (raw: RawData) => {\n try {\n const message = JSON.parse(raw.toString()) as AgentMessage;\n this.deliverInbound(address, message);\n } catch (err) {\n logger.warn('Dropped malformed WebSocket message', { address, err });\n }\n });\n });\n }\n\n async send(address: string, message: AgentMessage): Promise<void> {\n const ws = await this.getOrCreateConnection(address);\n ws.send(JSON.stringify(message));\n }\n\n /**\n * Register an inbound handler. Optional `options.streamId` scopes\n * the handler to a specific stream (only fires for messages with\n * matching streamId). Omit to subscribe to ALL streams.\n *\n * Patterns:\n * onMessage(h) — receives all\n * onMessage(h, { streamId: 'rpc' }) — receives only rpc\n * onMessage(h, { streamId: 'event' }) — receives only event\n * (both registered) — both fire on\n * their respective streams\n */\n onMessage(handler: InboundMessageHandler, options: OnMessageOptions = {}): void {\n this.inboundHandlers.add({ handler, streamId: options.streamId });\n }\n\n /**\n * Fire all matching handlers for a received message. Stream-scoped\n * handlers only fire when the message's streamId matches; all-stream\n * handlers always fire. Errors thrown sync OR async-rejected by one\n * handler don't stop delivery to others.\n */\n private dispatchInbound(address: string, message: AgentMessage): boolean {\n if (this.inboundHandlers.size === 0) return false;\n const msgStream = this.streamOf(message);\n let delivered = false;\n for (const entry of this.inboundHandlers) {\n // Stream filter: scoped handler only fires on matching streamId\n if (entry.streamId !== undefined && entry.streamId !== msgStream) continue;\n delivered = true;\n try {\n const r = entry.handler(address, message);\n if (r && typeof (r as Promise<void>).catch === 'function') {\n (r as Promise<void>).catch((err) => {\n logger.warn('Inbound handler rejected', { address, err });\n });\n }\n } catch (err) {\n logger.warn('Inbound handler threw', { address, err });\n }\n }\n return delivered;\n }\n\n /**\n * Hand an inbound message to the matching onMessage handlers. Only a\n * message no handler consumed is queued for receive(), and the queues are\n * bounded so a peer cannot grow memory without limit.\n */\n private deliverInbound(address: string, message: AgentMessage): void {\n if (this.dispatchInbound(address, message)) return;\n // Per-stream queue (default stream when message.streamId omitted)\n const key = this.queueKey(address, this.streamOf(message));\n let queue = this.messageQueue.get(key);\n if (!queue) {\n if (this.messageQueue.size >= MAX_QUEUE_STREAMS) {\n logger.warn('Dropped inbound message: too many queued streams', { address, key });\n return;\n }\n queue = [];\n this.messageQueue.set(key, queue);\n }\n queue.push(message);\n if (queue.length > MAX_QUEUED_PER_STREAM) {\n queue.shift();\n logger.warn('Inbound queue full; dropped oldest message', { address, key });\n }\n }\n\n /** Shift the head of a queue, dropping the queue once empty so stream keys don't accumulate. */\n private takeFrom(key: string, queue: AgentMessage[]): AgentMessage {\n const message = queue.shift()!;\n if (queue.length === 0) this.messageQueue.delete(key);\n return message;\n }\n\n /** Messages waiting for receive(), across all peers and streams. */\n queuedMessageCount(): number {\n let total = 0;\n for (const queue of this.messageQueue.values()) total += queue.length;\n return total;\n }\n\n async receive(address: string, streamId: string | number = DEFAULT_STREAM_ID): Promise<AgentMessage> {\n const key = this.queueKey(address, streamId);\n // Fast path\n const queue = this.messageQueue.get(key) ?? [];\n if (queue.length > 0) return this.takeFrom(key, queue);\n\n // Poll (caller must time out externally if they don't want to wait)\n return new Promise((resolve) => {\n const interval = setInterval(() => {\n const q = this.messageQueue.get(key) ?? [];\n if (q.length > 0) {\n clearInterval(interval);\n resolve(this.takeFrom(key, q));\n }\n }, 100);\n });\n }\n\n async request(address: string, message: AgentMessage): Promise<AgentMessage> {\n await this.send(address, message);\n return this.receive(address);\n }\n\n async sendBatch(address: string, messages: AgentMessage[]): Promise<void> {\n await Promise.all(messages.map((m) => this.send(address, m)));\n }\n\n async getStats(): Promise<PoolStatistics> {\n return {\n active: this.connections.size,\n idle: 0,\n created: this.connectionsCreated,\n closed: this.connectionsClosed,\n };\n }\n\n async close(): Promise<void> {\n // Outbound clients first.\n for (const ws of this.connections.values()) {\n ws.terminate();\n }\n this.connections.clear();\n this.messageQueue.clear();\n\n // Stop all liveness probes and drop the inbound index (#162).\n for (const interval of this.heartbeats) clearInterval(interval);\n this.heartbeats.clear();\n this.inboundByHost.clear();\n\n // Inbound: WebSocketServer.close() blocks until every accepted\n // socket disconnects. Forcibly terminate them so the close\n // callback fires within the test/CI timeout window.\n for (const wss of this.servers.values()) {\n for (const client of wss.clients) {\n try {\n client.terminate();\n } catch {\n /* socket already gone */\n }\n }\n await new Promise<void>((resolve) => wss.close(() => resolve()));\n }\n this.servers.clear();\n }\n}\n\n/**\n * Why real QUIC is not available in npm builds of agentic-flow.\n *\n * - No native (N-API) QUIC binding exists. The quinn-based client/server in\n * `crates/agentic-flow-quic` has no Node bindings and no build/publish\n * pipeline, so nothing native ships in the tarball.\n * - `wasm/quic/` is a browser build of that crate with quinn/tokio compiled\n * out (browsers cannot open UDP sockets). It cannot move QUIC packets.\n * - `agentic-flow/transport/quic` (QuicClient/QuicServer/QuicTransport) is a\n * placeholder API that does not transmit bytes.\n *\n * The working transport is the WebSocket fallback returned by\n * {@link loadQuicTransport}.\n */\nexport const QUIC_UNAVAILABLE_REASON =\n 'No native QUIC binding is published for agentic-flow: the quinn-based ' +\n 'crates/agentic-flow-quic has no N-API build, wasm/quic is a browser stub ' +\n 'without UDP, and agentic-flow/transport/quic is a placeholder that sends ' +\n 'no bytes. loadQuicTransport() uses the WebSocket fallback.';\n\n/** Honest status for the QUIC backend. */\nexport interface QuicStatus {\n available: boolean;\n /** Present when available is false. */\n reason?: string;\n /** The transport loadQuicTransport() actually returns. */\n fallback: 'websocket';\n}\n\n/**\n * Real QUIC is available only when a native binding has been loaded. None\n * is published, so this is always false. Earlier releases returned true when\n * AGENTIC_FLOW_QUIC_NATIVE=1 was set, even though the loader still returned\n * the WebSocket transport. That variable is now ignored.\n */\nasync function isRealQuicAvailable(): Promise<boolean> {\n return false;\n}\n\n/**\n * Public API — load a working transport. Real QUIC is not available in npm\n * builds (see {@link QUIC_UNAVAILABLE_REASON}), so this returns the WebSocket\n * fallback, which satisfies the AgentTransport interface.\n *\n * Example:\n * const t = await loadQuicTransport({ serverName: 'ruvultra:9100' });\n * await t.send('ruvultra:9100', { id: '1', type: 'task', payload: {...} });\n */\nexport async function loadQuicTransport(\n config: QuicTransportConfig = {},\n): Promise<AgentTransport> {\n if (process.env.NODE_ENV !== 'test') {\n logger.warn('QUIC unavailable; using WebSocket fallback. ' + QUIC_UNAVAILABLE_REASON);\n }\n return WebSocketFallbackTransport.create(config);\n}\n\n/** Quick capability probe for the doctor / health surface. */\nexport async function isQuicAvailable(): Promise<boolean> {\n return isRealQuicAvailable();\n}\n\n/** Availability plus the reason when QUIC is unavailable. */\nexport async function getQuicStatus(): Promise<QuicStatus> {\n const available = await isRealQuicAvailable();\n return available\n ? { available, fallback: 'websocket' }\n : { available, reason: QUIC_UNAVAILABLE_REASON, fallback: 'websocket' };\n}\n\nexport interface TransportCapabilities {\n quicAvailable: boolean;\n /** Why QUIC is unavailable; present when quicAvailable is false. */\n quicUnavailableReason?: string;\n webSocketFallbackAvailable: true;\n selectedBackend: 'quic' | 'websocket';\n}\n\nexport async function getTransportCapabilities(): Promise<TransportCapabilities> {\n const quic = await isRealQuicAvailable();\n return {\n quicAvailable: quic,\n ...(quic ? {} : { quicUnavailableReason: QUIC_UNAVAILABLE_REASON }),\n webSocketFallbackAvailable: true,\n selectedBackend: quic ? 'quic' : 'websocket',\n };\n}\n\nexport { WebSocketFallbackTransport };\n"]}
@@ -1,3 +1,4 @@
1
+ export { isQuicAvailable, getQuicStatus, QUIC_UNAVAILABLE_REASON, type QuicStatus, } from './quic-loader.js';
1
2
  export interface QuicConfig {
2
3
  host?: string;
3
4
  port?: number;
@@ -1 +1 @@
1
- {"version":3,"file":"quic.d.ts","sourceRoot":"","sources":["../../src/transport/quic.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"quic.d.ts","sourceRoot":"","sources":["../../src/transport/quic.ts"],"names":[],"mappings":"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"}
@@ -1,6 +1,13 @@
1
1
  // QUIC Transport Layer for Agentic Flow
2
- // WebAssembly-based QUIC client/server with connection pooling and stream multiplexing
2
+ //
3
+ // PLACEHOLDER API: QuicClient, QuicServer and QuicTransport do not open UDP
4
+ // sockets or transmit bytes. No native QUIC binding is published for
5
+ // agentic-flow, and wasm/quic is a browser stub without UDP. Probe with
6
+ // isQuicAvailable() / getQuicStatus() (re-exported below); for a transport
7
+ // that moves bytes use loadQuicTransport() from 'agentic-flow/transport/loader'.
3
8
  import { logger } from '../utils/logger.js';
9
+ import { QUIC_UNAVAILABLE_REASON } from './quic-loader.js';
10
+ export { isQuicAvailable, getQuicStatus, QUIC_UNAVAILABLE_REASON, } from './quic-loader.js';
4
11
  /**
5
12
  * QUIC Client - Manages outbound QUIC connections and stream multiplexing
6
13
  */
@@ -46,6 +53,7 @@ export class QuicClient {
46
53
  });
47
54
  // Load WASM module (implementation depends on WASM binding)
48
55
  // For now, this is a placeholder for the actual WASM loading
56
+ logger.warn('agentic-flow/transport/quic is a placeholder; no QUIC packets are sent. ' + QUIC_UNAVAILABLE_REASON);
49
57
  this.wasmModule = await this.loadWasmModule();
50
58
  this.initialized = true;
51
59
  logger.info('QUIC client initialized successfully');
@@ -265,6 +273,7 @@ export class QuicServer {
265
273
  certPath: this.config.certPath
266
274
  });
267
275
  // Load WASM module
276
+ logger.warn('agentic-flow/transport/quic is a placeholder; no QUIC packets are sent. ' + QUIC_UNAVAILABLE_REASON);
268
277
  this.wasmModule = await this.loadWasmModule();
269
278
  this.initialized = true;
270
279
  logger.info('QUIC server initialized successfully');
@@ -1 +1 @@
1
- {"version":3,"file":"quic.js","sourceRoot":"","sources":["../../src/transport/quic.ts"],"names":[],"mappings":"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","sourcesContent":["// QUIC Transport Layer for Agentic Flow\n// WebAssembly-based QUIC client/server with connection pooling and stream multiplexing\n\nimport { logger } from '../utils/logger.js';\n\nexport interface QuicConfig {\n // Server configuration\n host?: string;\n port?: number;\n certPath?: string;\n keyPath?: string;\n\n // Client configuration\n serverHost?: string;\n serverPort?: number;\n verifyPeer?: boolean;\n\n // Connection pool\n maxConnections?: number;\n connectionTimeout?: number;\n idleTimeout?: number;\n\n // Stream configuration\n maxConcurrentStreams?: number;\n streamTimeout?: number;\n\n // Performance tuning\n initialCongestionWindow?: number;\n maxDatagramSize?: number;\n enableEarlyData?: boolean;\n}\n\nexport interface QuicConnection {\n id: string;\n remoteAddr: string;\n streamCount: number;\n createdAt: Date;\n lastActivity: Date;\n}\n\nexport interface QuicStream {\n id: number;\n connectionId: string;\n send(data: Uint8Array): Promise<void>;\n receive(): Promise<Uint8Array>;\n close(): Promise<void>;\n}\n\nexport interface QuicStats {\n totalConnections: number;\n activeConnections: number;\n totalStreams: number;\n activeStreams: number;\n bytesReceived: number;\n bytesSent: number;\n packetsLost: number;\n rttMs: number;\n}\n\n/**\n * QUIC Client - Manages outbound QUIC connections and stream multiplexing\n */\nexport class QuicClient {\n private config: Required<QuicConfig>;\n private connections: Map<string, QuicConnection>;\n private wasmModule: any; // WASM module reference\n private initialized: boolean;\n\n constructor(config: QuicConfig = {}) {\n this.config = {\n host: config.host || '127.0.0.1',\n port: config.port || 4433,\n certPath: config.certPath || './certs/cert.pem',\n keyPath: config.keyPath || './certs/key.pem',\n serverHost: config.serverHost || 'localhost',\n serverPort: config.serverPort || 4433,\n verifyPeer: config.verifyPeer ?? true,\n maxConnections: config.maxConnections || 100,\n connectionTimeout: config.connectionTimeout || 30000,\n idleTimeout: config.idleTimeout || 60000,\n maxConcurrentStreams: config.maxConcurrentStreams || 100,\n streamTimeout: config.streamTimeout || 30000,\n initialCongestionWindow: config.initialCongestionWindow || 10,\n maxDatagramSize: config.maxDatagramSize || 1200,\n enableEarlyData: config.enableEarlyData ?? true\n };\n this.connections = new Map();\n this.initialized = false;\n }\n\n /**\n * Initialize QUIC client with WASM module\n */\n async initialize(): Promise<void> {\n if (this.initialized) {\n logger.warn('QUIC client already initialized');\n return;\n }\n\n try {\n logger.info('Initializing QUIC client...', {\n serverHost: this.config.serverHost,\n serverPort: this.config.serverPort,\n verifyPeer: this.config.verifyPeer\n });\n\n // Load WASM module (implementation depends on WASM binding)\n // For now, this is a placeholder for the actual WASM loading\n this.wasmModule = await this.loadWasmModule();\n\n this.initialized = true;\n logger.info('QUIC client initialized successfully');\n } catch (error) {\n logger.error('Failed to initialize QUIC client', { error });\n throw error;\n }\n }\n\n /**\n * Connect to QUIC server\n */\n async connect(host?: string, port?: number): Promise<QuicConnection> {\n if (!this.initialized) {\n throw new Error('QUIC client not initialized. Call initialize() first.');\n }\n\n const targetHost = host || this.config.serverHost;\n const targetPort = port || this.config.serverPort;\n const connectionId = `${targetHost}:${targetPort}`;\n\n // Check if connection already exists\n if (this.connections.has(connectionId)) {\n const conn = this.connections.get(connectionId)!;\n conn.lastActivity = new Date();\n logger.debug('Reusing existing QUIC connection', { connectionId });\n return conn;\n }\n\n // Check connection pool limit\n if (this.connections.size >= this.config.maxConnections) {\n throw new Error(`Maximum connections (${this.config.maxConnections}) reached`);\n }\n\n try {\n logger.info('Establishing QUIC connection', { host: targetHost, port: targetPort });\n\n // Establish QUIC connection via WASM\n // This is a placeholder - actual implementation will use WASM bindings\n const connection: QuicConnection = {\n id: connectionId,\n remoteAddr: `${targetHost}:${targetPort}`,\n streamCount: 0,\n createdAt: new Date(),\n lastActivity: new Date()\n };\n\n this.connections.set(connectionId, connection);\n logger.info('QUIC connection established', { connectionId });\n\n return connection;\n } catch (error) {\n logger.error('Failed to establish QUIC connection', { error, host: targetHost, port: targetPort });\n throw error;\n }\n }\n\n /**\n * Create bidirectional stream on connection\n */\n async createStream(connectionId: string): Promise<QuicStream> {\n const connection = this.connections.get(connectionId);\n if (!connection) {\n throw new Error(`Connection ${connectionId} not found`);\n }\n\n if (connection.streamCount >= this.config.maxConcurrentStreams) {\n throw new Error(`Maximum concurrent streams (${this.config.maxConcurrentStreams}) reached`);\n }\n\n const streamId = connection.streamCount++;\n connection.lastActivity = new Date();\n\n logger.debug('Creating QUIC stream', { connectionId, streamId });\n\n // Create stream via WASM\n const stream: QuicStream = {\n id: streamId,\n connectionId,\n send: async (data: Uint8Array) => {\n logger.debug('Sending data on stream', { connectionId, streamId, bytes: data.length });\n // WASM call to send data\n connection.lastActivity = new Date();\n },\n receive: async (): Promise<Uint8Array> => {\n logger.debug('Receiving data on stream', { connectionId, streamId });\n // WASM call to receive data\n connection.lastActivity = new Date();\n return new Uint8Array(); // Placeholder\n },\n close: async () => {\n logger.debug('Closing stream', { connectionId, streamId });\n connection.streamCount--;\n connection.lastActivity = new Date();\n }\n };\n\n return stream;\n }\n\n /**\n * Send HTTP/3 request over QUIC\n */\n async sendRequest(\n connectionId: string,\n method: string,\n path: string,\n headers: Record<string, string>,\n body?: Uint8Array\n ): Promise<{ status: number; headers: Record<string, string>; body: Uint8Array }> {\n const stream = await this.createStream(connectionId);\n\n try {\n // Encode HTTP/3 request\n const request = this.encodeHttp3Request(method, path, headers, body);\n await stream.send(request);\n\n // Receive HTTP/3 response\n const responseData = await stream.receive();\n const response = this.decodeHttp3Response(responseData);\n\n return response;\n } finally {\n await stream.close();\n }\n }\n\n /**\n * Close connection\n */\n async closeConnection(connectionId: string): Promise<void> {\n const connection = this.connections.get(connectionId);\n if (!connection) {\n logger.warn('Connection not found', { connectionId });\n return;\n }\n\n logger.info('Closing QUIC connection', { connectionId });\n // WASM call to close connection\n this.connections.delete(connectionId);\n }\n\n /**\n * Close all connections and cleanup\n */\n async shutdown(): Promise<void> {\n logger.info('Shutting down QUIC client', { activeConnections: this.connections.size });\n\n for (const connectionId of this.connections.keys()) {\n await this.closeConnection(connectionId);\n }\n\n this.initialized = false;\n }\n\n /**\n * Get connection statistics\n */\n getStats(): QuicStats {\n return {\n totalConnections: this.connections.size,\n activeConnections: this.connections.size,\n totalStreams: Array.from(this.connections.values()).reduce((sum, c) => sum + c.streamCount, 0),\n activeStreams: Array.from(this.connections.values()).reduce((sum, c) => sum + c.streamCount, 0),\n bytesReceived: 0, // From WASM\n bytesSent: 0, // From WASM\n packetsLost: 0, // From WASM\n rttMs: 0 // From WASM\n };\n }\n\n /**\n * Load WASM module (placeholder)\n */\n private async loadWasmModule(): Promise<any> {\n // This will be implemented to load the actual WASM module\n // For now, return a mock object\n logger.debug('Loading QUIC WASM module...');\n return {};\n }\n\n /**\n * Encode HTTP/3 request (placeholder)\n */\n private encodeHttp3Request(\n method: string,\n path: string,\n headers: Record<string, string>,\n body?: Uint8Array\n ): Uint8Array {\n // HTTP/3 QPACK encoding will be implemented\n logger.debug('Encoding HTTP/3 request', { method, path, headers });\n return new Uint8Array();\n }\n\n /**\n * Decode HTTP/3 response (placeholder)\n */\n private decodeHttp3Response(data: Uint8Array): {\n status: number;\n headers: Record<string, string>;\n body: Uint8Array;\n } {\n // HTTP/3 QPACK decoding will be implemented\n logger.debug('Decoding HTTP/3 response', { bytes: data.length });\n return {\n status: 200,\n headers: {},\n body: new Uint8Array()\n };\n }\n}\n\n/**\n * QUIC Server - Listens for inbound QUIC connections\n */\nexport class QuicServer {\n private config: Required<QuicConfig>;\n private connections: Map<string, QuicConnection>;\n private wasmModule: any;\n private initialized: boolean;\n private listening: boolean;\n\n constructor(config: QuicConfig = {}) {\n this.config = {\n host: config.host || '127.0.0.1',\n port: config.port || 4433,\n certPath: config.certPath || './certs/cert.pem',\n keyPath: config.keyPath || './certs/key.pem',\n serverHost: config.serverHost || 'localhost',\n serverPort: config.serverPort || 4433,\n verifyPeer: config.verifyPeer ?? false,\n maxConnections: config.maxConnections || 1000,\n connectionTimeout: config.connectionTimeout || 30000,\n idleTimeout: config.idleTimeout || 120000,\n maxConcurrentStreams: config.maxConcurrentStreams || 100,\n streamTimeout: config.streamTimeout || 30000,\n initialCongestionWindow: config.initialCongestionWindow || 10,\n maxDatagramSize: config.maxDatagramSize || 1200,\n enableEarlyData: config.enableEarlyData ?? false\n };\n this.connections = new Map();\n this.initialized = false;\n this.listening = false;\n }\n\n /**\n * Initialize QUIC server\n */\n async initialize(): Promise<void> {\n if (this.initialized) {\n logger.warn('QUIC server already initialized');\n return;\n }\n\n try {\n logger.info('Initializing QUIC server...', {\n host: this.config.host,\n port: this.config.port,\n certPath: this.config.certPath\n });\n\n // Load WASM module\n this.wasmModule = await this.loadWasmModule();\n\n this.initialized = true;\n logger.info('QUIC server initialized successfully');\n } catch (error) {\n logger.error('Failed to initialize QUIC server', { error });\n throw error;\n }\n }\n\n /**\n * Start listening for connections\n */\n async listen(): Promise<void> {\n if (!this.initialized) {\n throw new Error('QUIC server not initialized. Call initialize() first.');\n }\n\n if (this.listening) {\n logger.warn('QUIC server already listening');\n return;\n }\n\n try {\n logger.info('Starting QUIC server', { host: this.config.host, port: this.config.port });\n\n // Start QUIC server via WASM\n // This will be implemented with actual WASM bindings\n\n this.listening = true;\n logger.info(`QUIC server listening on ${this.config.host}:${this.config.port}`);\n } catch (error) {\n logger.error('Failed to start QUIC server', { error });\n throw error;\n }\n }\n\n /**\n * Stop server and close all connections\n */\n async stop(): Promise<void> {\n if (!this.listening) {\n logger.warn('QUIC server not listening');\n return;\n }\n\n logger.info('Stopping QUIC server', { activeConnections: this.connections.size });\n\n // Close all connections\n for (const connectionId of this.connections.keys()) {\n await this.closeConnection(connectionId);\n }\n\n // Stop listening via WASM\n this.listening = false;\n logger.info('QUIC server stopped');\n }\n\n /**\n * Close connection\n */\n async closeConnection(connectionId: string): Promise<void> {\n const connection = this.connections.get(connectionId);\n if (!connection) {\n logger.warn('Connection not found', { connectionId });\n return;\n }\n\n logger.info('Closing connection', { connectionId });\n this.connections.delete(connectionId);\n }\n\n /**\n * Get server statistics\n */\n getStats(): QuicStats {\n return {\n totalConnections: this.connections.size,\n activeConnections: this.connections.size,\n totalStreams: Array.from(this.connections.values()).reduce((sum, c) => sum + c.streamCount, 0),\n activeStreams: Array.from(this.connections.values()).reduce((sum, c) => sum + c.streamCount, 0),\n bytesReceived: 0,\n bytesSent: 0,\n packetsLost: 0,\n rttMs: 0\n };\n }\n\n /**\n * Load WASM module (placeholder)\n */\n private async loadWasmModule(): Promise<any> {\n logger.debug('Loading QUIC server WASM module...');\n return {};\n }\n}\n\n/**\n * Connection pool manager for QUIC connections\n */\nexport class QuicConnectionPool {\n private client: QuicClient;\n private connections: Map<string, QuicConnection>;\n private maxPoolSize: number;\n\n constructor(client: QuicClient, maxPoolSize: number = 10) {\n this.client = client;\n this.connections = new Map();\n this.maxPoolSize = maxPoolSize;\n }\n\n /**\n * Get or create connection from pool\n */\n async getConnection(host: string, port: number): Promise<QuicConnection> {\n const key = `${host}:${port}`;\n\n if (this.connections.has(key)) {\n const conn = this.connections.get(key)!;\n conn.lastActivity = new Date();\n return conn;\n }\n\n if (this.connections.size >= this.maxPoolSize) {\n // Remove oldest idle connection\n this.removeOldestConnection();\n }\n\n const connection = await this.client.connect(host, port);\n this.connections.set(key, connection);\n return connection;\n }\n\n /**\n * Remove oldest idle connection\n */\n private removeOldestConnection(): void {\n let oldestKey: string | null = null;\n let oldestTime = Date.now();\n\n for (const [key, conn] of this.connections.entries()) {\n const lastActivity = conn.lastActivity.getTime();\n if (lastActivity < oldestTime) {\n oldestTime = lastActivity;\n oldestKey = key;\n }\n }\n\n if (oldestKey) {\n this.client.closeConnection(oldestKey);\n this.connections.delete(oldestKey);\n logger.debug('Removed idle connection from pool', { connectionId: oldestKey });\n }\n }\n\n /**\n * Clear all connections in pool\n */\n async clear(): Promise<void> {\n for (const connectionId of this.connections.keys()) {\n await this.client.closeConnection(connectionId);\n }\n this.connections.clear();\n }\n}\n\n/**\n * QuicTransport - High-level QUIC transport interface\n * Simplified API for common use cases (backwards compatible)\n */\nexport interface QuicTransportConfig {\n host?: string;\n port?: number;\n maxConcurrentStreams?: number;\n certPath?: string;\n keyPath?: string;\n}\n\nexport class QuicTransport {\n private client: QuicClient;\n private config: QuicTransportConfig;\n\n constructor(config: QuicTransportConfig = {}) {\n this.config = config;\n this.client = new QuicClient({\n serverHost: config.host || 'localhost',\n serverPort: config.port || 4433,\n maxConcurrentStreams: config.maxConcurrentStreams || 100,\n certPath: config.certPath,\n keyPath: config.keyPath\n });\n }\n\n /**\n * Connect to QUIC server\n */\n async connect(): Promise<void> {\n await this.client.initialize();\n await this.client.connect();\n }\n\n /**\n * Send data over QUIC\n */\n async send(data: any): Promise<void> {\n // Convert data to bytes and send\n const jsonStr = JSON.stringify(data);\n const bytes = new TextEncoder().encode(jsonStr);\n // Implementation will use QUIC client to send\n logger.debug('Sending data via QUIC', { bytes: bytes.length });\n }\n\n /**\n * Close connection\n */\n async close(): Promise<void> {\n await this.client.shutdown();\n }\n\n /**\n * Get connection statistics\n */\n getStats(): QuicStats {\n return this.client.getStats();\n }\n}\n"]}
1
+ {"version":3,"file":"quic.js","sourceRoot":"","sources":["../../src/transport/quic.ts"],"names":[],"mappings":"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","sourcesContent":["// QUIC Transport Layer for Agentic Flow\n//\n// PLACEHOLDER API: QuicClient, QuicServer and QuicTransport do not open UDP\n// sockets or transmit bytes. No native QUIC binding is published for\n// agentic-flow, and wasm/quic is a browser stub without UDP. Probe with\n// isQuicAvailable() / getQuicStatus() (re-exported below); for a transport\n// that moves bytes use loadQuicTransport() from 'agentic-flow/transport/loader'.\n\nimport { logger } from '../utils/logger.js';\nimport { QUIC_UNAVAILABLE_REASON } from './quic-loader.js';\n\nexport {\n isQuicAvailable,\n getQuicStatus,\n QUIC_UNAVAILABLE_REASON,\n type QuicStatus,\n} from './quic-loader.js';\n\nexport interface QuicConfig {\n // Server configuration\n host?: string;\n port?: number;\n certPath?: string;\n keyPath?: string;\n\n // Client configuration\n serverHost?: string;\n serverPort?: number;\n verifyPeer?: boolean;\n\n // Connection pool\n maxConnections?: number;\n connectionTimeout?: number;\n idleTimeout?: number;\n\n // Stream configuration\n maxConcurrentStreams?: number;\n streamTimeout?: number;\n\n // Performance tuning\n initialCongestionWindow?: number;\n maxDatagramSize?: number;\n enableEarlyData?: boolean;\n}\n\nexport interface QuicConnection {\n id: string;\n remoteAddr: string;\n streamCount: number;\n createdAt: Date;\n lastActivity: Date;\n}\n\nexport interface QuicStream {\n id: number;\n connectionId: string;\n send(data: Uint8Array): Promise<void>;\n receive(): Promise<Uint8Array>;\n close(): Promise<void>;\n}\n\nexport interface QuicStats {\n totalConnections: number;\n activeConnections: number;\n totalStreams: number;\n activeStreams: number;\n bytesReceived: number;\n bytesSent: number;\n packetsLost: number;\n rttMs: number;\n}\n\n/**\n * QUIC Client - Manages outbound QUIC connections and stream multiplexing\n */\nexport class QuicClient {\n private config: Required<QuicConfig>;\n private connections: Map<string, QuicConnection>;\n private wasmModule: any; // WASM module reference\n private initialized: boolean;\n\n constructor(config: QuicConfig = {}) {\n this.config = {\n host: config.host || '127.0.0.1',\n port: config.port || 4433,\n certPath: config.certPath || './certs/cert.pem',\n keyPath: config.keyPath || './certs/key.pem',\n serverHost: config.serverHost || 'localhost',\n serverPort: config.serverPort || 4433,\n verifyPeer: config.verifyPeer ?? true,\n maxConnections: config.maxConnections || 100,\n connectionTimeout: config.connectionTimeout || 30000,\n idleTimeout: config.idleTimeout || 60000,\n maxConcurrentStreams: config.maxConcurrentStreams || 100,\n streamTimeout: config.streamTimeout || 30000,\n initialCongestionWindow: config.initialCongestionWindow || 10,\n maxDatagramSize: config.maxDatagramSize || 1200,\n enableEarlyData: config.enableEarlyData ?? true\n };\n this.connections = new Map();\n this.initialized = false;\n }\n\n /**\n * Initialize QUIC client with WASM module\n */\n async initialize(): Promise<void> {\n if (this.initialized) {\n logger.warn('QUIC client already initialized');\n return;\n }\n\n try {\n logger.info('Initializing QUIC client...', {\n serverHost: this.config.serverHost,\n serverPort: this.config.serverPort,\n verifyPeer: this.config.verifyPeer\n });\n\n // Load WASM module (implementation depends on WASM binding)\n // For now, this is a placeholder for the actual WASM loading\n logger.warn('agentic-flow/transport/quic is a placeholder; no QUIC packets are sent. ' + QUIC_UNAVAILABLE_REASON);\n this.wasmModule = await this.loadWasmModule();\n\n this.initialized = true;\n logger.info('QUIC client initialized successfully');\n } catch (error) {\n logger.error('Failed to initialize QUIC client', { error });\n throw error;\n }\n }\n\n /**\n * Connect to QUIC server\n */\n async connect(host?: string, port?: number): Promise<QuicConnection> {\n if (!this.initialized) {\n throw new Error('QUIC client not initialized. Call initialize() first.');\n }\n\n const targetHost = host || this.config.serverHost;\n const targetPort = port || this.config.serverPort;\n const connectionId = `${targetHost}:${targetPort}`;\n\n // Check if connection already exists\n if (this.connections.has(connectionId)) {\n const conn = this.connections.get(connectionId)!;\n conn.lastActivity = new Date();\n logger.debug('Reusing existing QUIC connection', { connectionId });\n return conn;\n }\n\n // Check connection pool limit\n if (this.connections.size >= this.config.maxConnections) {\n throw new Error(`Maximum connections (${this.config.maxConnections}) reached`);\n }\n\n try {\n logger.info('Establishing QUIC connection', { host: targetHost, port: targetPort });\n\n // Establish QUIC connection via WASM\n // This is a placeholder - actual implementation will use WASM bindings\n const connection: QuicConnection = {\n id: connectionId,\n remoteAddr: `${targetHost}:${targetPort}`,\n streamCount: 0,\n createdAt: new Date(),\n lastActivity: new Date()\n };\n\n this.connections.set(connectionId, connection);\n logger.info('QUIC connection established', { connectionId });\n\n return connection;\n } catch (error) {\n logger.error('Failed to establish QUIC connection', { error, host: targetHost, port: targetPort });\n throw error;\n }\n }\n\n /**\n * Create bidirectional stream on connection\n */\n async createStream(connectionId: string): Promise<QuicStream> {\n const connection = this.connections.get(connectionId);\n if (!connection) {\n throw new Error(`Connection ${connectionId} not found`);\n }\n\n if (connection.streamCount >= this.config.maxConcurrentStreams) {\n throw new Error(`Maximum concurrent streams (${this.config.maxConcurrentStreams}) reached`);\n }\n\n const streamId = connection.streamCount++;\n connection.lastActivity = new Date();\n\n logger.debug('Creating QUIC stream', { connectionId, streamId });\n\n // Create stream via WASM\n const stream: QuicStream = {\n id: streamId,\n connectionId,\n send: async (data: Uint8Array) => {\n logger.debug('Sending data on stream', { connectionId, streamId, bytes: data.length });\n // WASM call to send data\n connection.lastActivity = new Date();\n },\n receive: async (): Promise<Uint8Array> => {\n logger.debug('Receiving data on stream', { connectionId, streamId });\n // WASM call to receive data\n connection.lastActivity = new Date();\n return new Uint8Array(); // Placeholder\n },\n close: async () => {\n logger.debug('Closing stream', { connectionId, streamId });\n connection.streamCount--;\n connection.lastActivity = new Date();\n }\n };\n\n return stream;\n }\n\n /**\n * Send HTTP/3 request over QUIC\n */\n async sendRequest(\n connectionId: string,\n method: string,\n path: string,\n headers: Record<string, string>,\n body?: Uint8Array\n ): Promise<{ status: number; headers: Record<string, string>; body: Uint8Array }> {\n const stream = await this.createStream(connectionId);\n\n try {\n // Encode HTTP/3 request\n const request = this.encodeHttp3Request(method, path, headers, body);\n await stream.send(request);\n\n // Receive HTTP/3 response\n const responseData = await stream.receive();\n const response = this.decodeHttp3Response(responseData);\n\n return response;\n } finally {\n await stream.close();\n }\n }\n\n /**\n * Close connection\n */\n async closeConnection(connectionId: string): Promise<void> {\n const connection = this.connections.get(connectionId);\n if (!connection) {\n logger.warn('Connection not found', { connectionId });\n return;\n }\n\n logger.info('Closing QUIC connection', { connectionId });\n // WASM call to close connection\n this.connections.delete(connectionId);\n }\n\n /**\n * Close all connections and cleanup\n */\n async shutdown(): Promise<void> {\n logger.info('Shutting down QUIC client', { activeConnections: this.connections.size });\n\n for (const connectionId of this.connections.keys()) {\n await this.closeConnection(connectionId);\n }\n\n this.initialized = false;\n }\n\n /**\n * Get connection statistics\n */\n getStats(): QuicStats {\n return {\n totalConnections: this.connections.size,\n activeConnections: this.connections.size,\n totalStreams: Array.from(this.connections.values()).reduce((sum, c) => sum + c.streamCount, 0),\n activeStreams: Array.from(this.connections.values()).reduce((sum, c) => sum + c.streamCount, 0),\n bytesReceived: 0, // From WASM\n bytesSent: 0, // From WASM\n packetsLost: 0, // From WASM\n rttMs: 0 // From WASM\n };\n }\n\n /**\n * Load WASM module (placeholder)\n */\n private async loadWasmModule(): Promise<any> {\n // This will be implemented to load the actual WASM module\n // For now, return a mock object\n logger.debug('Loading QUIC WASM module...');\n return {};\n }\n\n /**\n * Encode HTTP/3 request (placeholder)\n */\n private encodeHttp3Request(\n method: string,\n path: string,\n headers: Record<string, string>,\n body?: Uint8Array\n ): Uint8Array {\n // HTTP/3 QPACK encoding will be implemented\n logger.debug('Encoding HTTP/3 request', { method, path, headers });\n return new Uint8Array();\n }\n\n /**\n * Decode HTTP/3 response (placeholder)\n */\n private decodeHttp3Response(data: Uint8Array): {\n status: number;\n headers: Record<string, string>;\n body: Uint8Array;\n } {\n // HTTP/3 QPACK decoding will be implemented\n logger.debug('Decoding HTTP/3 response', { bytes: data.length });\n return {\n status: 200,\n headers: {},\n body: new Uint8Array()\n };\n }\n}\n\n/**\n * QUIC Server - Listens for inbound QUIC connections\n */\nexport class QuicServer {\n private config: Required<QuicConfig>;\n private connections: Map<string, QuicConnection>;\n private wasmModule: any;\n private initialized: boolean;\n private listening: boolean;\n\n constructor(config: QuicConfig = {}) {\n this.config = {\n host: config.host || '127.0.0.1',\n port: config.port || 4433,\n certPath: config.certPath || './certs/cert.pem',\n keyPath: config.keyPath || './certs/key.pem',\n serverHost: config.serverHost || 'localhost',\n serverPort: config.serverPort || 4433,\n verifyPeer: config.verifyPeer ?? false,\n maxConnections: config.maxConnections || 1000,\n connectionTimeout: config.connectionTimeout || 30000,\n idleTimeout: config.idleTimeout || 120000,\n maxConcurrentStreams: config.maxConcurrentStreams || 100,\n streamTimeout: config.streamTimeout || 30000,\n initialCongestionWindow: config.initialCongestionWindow || 10,\n maxDatagramSize: config.maxDatagramSize || 1200,\n enableEarlyData: config.enableEarlyData ?? false\n };\n this.connections = new Map();\n this.initialized = false;\n this.listening = false;\n }\n\n /**\n * Initialize QUIC server\n */\n async initialize(): Promise<void> {\n if (this.initialized) {\n logger.warn('QUIC server already initialized');\n return;\n }\n\n try {\n logger.info('Initializing QUIC server...', {\n host: this.config.host,\n port: this.config.port,\n certPath: this.config.certPath\n });\n\n // Load WASM module\n logger.warn('agentic-flow/transport/quic is a placeholder; no QUIC packets are sent. ' + QUIC_UNAVAILABLE_REASON);\n this.wasmModule = await this.loadWasmModule();\n\n this.initialized = true;\n logger.info('QUIC server initialized successfully');\n } catch (error) {\n logger.error('Failed to initialize QUIC server', { error });\n throw error;\n }\n }\n\n /**\n * Start listening for connections\n */\n async listen(): Promise<void> {\n if (!this.initialized) {\n throw new Error('QUIC server not initialized. Call initialize() first.');\n }\n\n if (this.listening) {\n logger.warn('QUIC server already listening');\n return;\n }\n\n try {\n logger.info('Starting QUIC server', { host: this.config.host, port: this.config.port });\n\n // Start QUIC server via WASM\n // This will be implemented with actual WASM bindings\n\n this.listening = true;\n logger.info(`QUIC server listening on ${this.config.host}:${this.config.port}`);\n } catch (error) {\n logger.error('Failed to start QUIC server', { error });\n throw error;\n }\n }\n\n /**\n * Stop server and close all connections\n */\n async stop(): Promise<void> {\n if (!this.listening) {\n logger.warn('QUIC server not listening');\n return;\n }\n\n logger.info('Stopping QUIC server', { activeConnections: this.connections.size });\n\n // Close all connections\n for (const connectionId of this.connections.keys()) {\n await this.closeConnection(connectionId);\n }\n\n // Stop listening via WASM\n this.listening = false;\n logger.info('QUIC server stopped');\n }\n\n /**\n * Close connection\n */\n async closeConnection(connectionId: string): Promise<void> {\n const connection = this.connections.get(connectionId);\n if (!connection) {\n logger.warn('Connection not found', { connectionId });\n return;\n }\n\n logger.info('Closing connection', { connectionId });\n this.connections.delete(connectionId);\n }\n\n /**\n * Get server statistics\n */\n getStats(): QuicStats {\n return {\n totalConnections: this.connections.size,\n activeConnections: this.connections.size,\n totalStreams: Array.from(this.connections.values()).reduce((sum, c) => sum + c.streamCount, 0),\n activeStreams: Array.from(this.connections.values()).reduce((sum, c) => sum + c.streamCount, 0),\n bytesReceived: 0,\n bytesSent: 0,\n packetsLost: 0,\n rttMs: 0\n };\n }\n\n /**\n * Load WASM module (placeholder)\n */\n private async loadWasmModule(): Promise<any> {\n logger.debug('Loading QUIC server WASM module...');\n return {};\n }\n}\n\n/**\n * Connection pool manager for QUIC connections\n */\nexport class QuicConnectionPool {\n private client: QuicClient;\n private connections: Map<string, QuicConnection>;\n private maxPoolSize: number;\n\n constructor(client: QuicClient, maxPoolSize: number = 10) {\n this.client = client;\n this.connections = new Map();\n this.maxPoolSize = maxPoolSize;\n }\n\n /**\n * Get or create connection from pool\n */\n async getConnection(host: string, port: number): Promise<QuicConnection> {\n const key = `${host}:${port}`;\n\n if (this.connections.has(key)) {\n const conn = this.connections.get(key)!;\n conn.lastActivity = new Date();\n return conn;\n }\n\n if (this.connections.size >= this.maxPoolSize) {\n // Remove oldest idle connection\n this.removeOldestConnection();\n }\n\n const connection = await this.client.connect(host, port);\n this.connections.set(key, connection);\n return connection;\n }\n\n /**\n * Remove oldest idle connection\n */\n private removeOldestConnection(): void {\n let oldestKey: string | null = null;\n let oldestTime = Date.now();\n\n for (const [key, conn] of this.connections.entries()) {\n const lastActivity = conn.lastActivity.getTime();\n if (lastActivity < oldestTime) {\n oldestTime = lastActivity;\n oldestKey = key;\n }\n }\n\n if (oldestKey) {\n this.client.closeConnection(oldestKey);\n this.connections.delete(oldestKey);\n logger.debug('Removed idle connection from pool', { connectionId: oldestKey });\n }\n }\n\n /**\n * Clear all connections in pool\n */\n async clear(): Promise<void> {\n for (const connectionId of this.connections.keys()) {\n await this.client.closeConnection(connectionId);\n }\n this.connections.clear();\n }\n}\n\n/**\n * QuicTransport - High-level QUIC transport interface\n * Simplified API for common use cases (backwards compatible)\n */\nexport interface QuicTransportConfig {\n host?: string;\n port?: number;\n maxConcurrentStreams?: number;\n certPath?: string;\n keyPath?: string;\n}\n\nexport class QuicTransport {\n private client: QuicClient;\n private config: QuicTransportConfig;\n\n constructor(config: QuicTransportConfig = {}) {\n this.config = config;\n this.client = new QuicClient({\n serverHost: config.host || 'localhost',\n serverPort: config.port || 4433,\n maxConcurrentStreams: config.maxConcurrentStreams || 100,\n certPath: config.certPath,\n keyPath: config.keyPath\n });\n }\n\n /**\n * Connect to QUIC server\n */\n async connect(): Promise<void> {\n await this.client.initialize();\n await this.client.connect();\n }\n\n /**\n * Send data over QUIC\n */\n async send(data: any): Promise<void> {\n // Convert data to bytes and send\n const jsonStr = JSON.stringify(data);\n const bytes = new TextEncoder().encode(jsonStr);\n // Implementation will use QUIC client to send\n logger.debug('Sending data via QUIC', { bytes: bytes.length });\n }\n\n /**\n * Close connection\n */\n async close(): Promise<void> {\n await this.client.shutdown();\n }\n\n /**\n * Get connection statistics\n */\n getStats(): QuicStats {\n return this.client.getStats();\n }\n}\n"]}