import type { Envelope } from './protocol'; export type PacketChannelMode = 'loopback' | 'websocket' | 'webrtc' | 'relay' | 'colyseus'; export interface PacketChannel { readonly peerId: string; readonly mode: PacketChannelMode; send(envelope: Envelope): void; onEnvelope(handler: (envelope: Envelope) => void): () => void; onClose(handler: (reason?: string) => void): () => void; close(reason?: string): void; /** * Optional: fires when the underlying transport receives a frame it can't * interpret as this package's JSON `Envelope` protocol (e.g. a binary * WebSocket frame) — a live signal that the peer likely does not speak the * compat wire protocol at all (for example, a real Colyseus server, which * frames its own binary schema-diff protocol). Channels that can only ever * carry already-parsed envelopes (loopback, WebRTC data channel, Cloudflare * relay) have no such failure mode and may omit this. `CompatRoom.join()` * uses this — scoped to the pending-join window only — to reject a join * against a wire-incompatible peer instead of hanging forever. */ onProtocolError?(handler: (reason: string) => void): () => void; /** * Optional: send this envelope over an UNRELIABLE (unordered, no-retransmit) * sub-transport when the channel has one — the delivery `sendUnreliable` * asks for. Only the WebRTC channel has a second `RTCDataChannel` * (`{ordered: false, maxRetransmits: 0}`) to carry it; ordered transports * (loopback, websocket, relay, real Colyseus) have no unreliable mode and * omit this, so `CompatRoom.sendUnreliable` correctly degrades to the * reliable `send` path on them. The envelope shape is identical to `send`'s * — same JSON `Envelope` protocol, different channel. */ sendUnreliable?(envelope: Envelope): void; }