perf(relay): reduce encrypted binary traffic overhead (#2480)

Preserve application frame identity through encryption so negotiated binary traffic avoids base64 expansion while mixed-version peers remain compatible.
This commit is contained in:
Mohamed Boudra
2026-07-27 12:12:02 +02:00
committed by GitHub
parent 1a1ff8828f
commit 1d1132de9c
22 changed files with 397 additions and 113 deletions
@@ -8,15 +8,12 @@ import type {
DaemonTransportFactory,
TransportLogger,
} from "./daemon-client-transport-types.js";
import {
extractRelayMessageData,
normalizeTransportPayload,
} from "./daemon-client-transport-utils.js";
import { extractRelayMessage, normalizeTransportPayload } from "./daemon-client-transport-utils.js";
type OpenHandler = () => void;
type CloseHandler = (event?: unknown) => void;
type ErrorHandler = (event?: unknown) => void;
type MessageHandler = (data: unknown) => void;
type MessageHandler = (data: unknown, isBinary: boolean) => void;
export function createRelayE2eeTransportFactory(args: {
baseFactory: DaemonTransportFactory;
@@ -70,7 +67,7 @@ export function createEncryptedTransport(
if (closed) {
return;
}
emitHandlers(messageHandlers, data);
emitHandlers(messageHandlers, data, data instanceof ArrayBuffer);
};
const relayTransport: RelayTransport = {
@@ -115,8 +112,8 @@ export function createEncryptedTransport(
base.onOpen(() => {
void startHandshake();
});
base.onMessage((event) => {
relayTransport.onmessage?.(extractRelayMessageData(event));
base.onMessage((data, isBinary) => {
relayTransport.onmessage?.(extractRelayMessage(data, isBinary));
});
base.onClose((event) => {
const record = event as { code?: number; reason?: string } | undefined;
@@ -1,7 +1,7 @@
export interface DaemonTransport {
send: (data: string | Uint8Array | ArrayBuffer) => void;
close: (code?: number, reason?: string) => void;
onMessage: (handler: (data: unknown) => void) => () => void;
onMessage: (handler: (data: unknown, isBinary: boolean) => void) => () => void;
onOpen: (handler: () => void) => () => void;
onClose: (handler: (event?: unknown) => void) => () => void;
onError: (handler: (event?: unknown) => void) => () => void;
@@ -14,17 +14,25 @@ export function normalizeTransportPayload(
return copyArrayBufferViewToBuffer(data);
}
export function extractRelayMessageData(event: unknown): string | ArrayBuffer {
export interface RelayTransportMessage {
data: string | ArrayBuffer;
isBinary: boolean;
}
export function extractRelayMessage(event: unknown, nodeIsBinary?: boolean): RelayTransportMessage {
const raw =
event && typeof event === "object" && "data" in event
? (event as { data: unknown }).data
: event;
if (typeof raw === "string") return raw;
if (raw instanceof ArrayBuffer) return raw;
if (ArrayBuffer.isView(raw)) {
return copyArrayBufferViewToBuffer(raw);
const isBinary = nodeIsBinary ?? typeof raw !== "string";
if (!isBinary) {
return { data: decodeMessageData(raw) ?? String(raw ?? ""), isBinary: false };
}
return String(raw ?? "");
if (raw instanceof ArrayBuffer) return { data: raw, isBinary: true };
if (ArrayBuffer.isView(raw)) {
return { data: copyArrayBufferViewToBuffer(raw), isBinary: true };
}
return { data: String(raw ?? ""), isBinary: true };
}
export function describeTransportClose(event?: unknown): string {
@@ -7,7 +7,7 @@ import {
describeTransportClose,
describeTransportError,
encodeUtf8String,
extractRelayMessageData,
extractRelayMessage,
} from "./daemon-client-transport.js";
const createClientChannelMock = vi.hoisted(() => vi.fn());
@@ -130,7 +130,7 @@ describe("daemon-client transport helpers", () => {
const message = { data: "payload" };
listeners.get("message")?.(message);
expect(onMessage).toHaveBeenCalledWith(message);
expect(onMessage).toHaveBeenCalledWith("payload", false);
unsubscribe();
expect(ws.removeEventListener).toHaveBeenCalledWith("message", expect.any(Function));
@@ -165,13 +165,16 @@ describe("daemon-client transport helpers", () => {
expect(describeTransportError()).toBe("Transport error");
});
test("extractRelayMessageData returns strings and array buffers", () => {
expect(extractRelayMessageData({ data: "hello" })).toBe("hello");
test("extractRelayMessage preserves browser and Node WebSocket frame kind", () => {
expect(extractRelayMessage({ data: "hello" })).toEqual({ data: "hello", isBinary: false });
const view = new Uint8Array([1, 2, 3]);
const extracted = extractRelayMessageData({ data: view });
expect(extracted).toBeInstanceOf(ArrayBuffer);
expect(Array.from(new Uint8Array(extracted as ArrayBuffer))).toEqual([1, 2, 3]);
const binary = extractRelayMessage(view, true);
expect(binary.isBinary).toBe(true);
expect(Array.from(new Uint8Array(binary.data as ArrayBuffer))).toEqual([1, 2, 3]);
const text = extractRelayMessage(view, false);
expect(text).toEqual({ data: "\u0001\u0002\u0003", isBinary: false });
});
test("decodeMessageData decodes strings, array buffers, and typed arrays", () => {
@@ -10,7 +10,7 @@ export {
describeTransportClose,
describeTransportError,
encodeUtf8String,
extractRelayMessageData,
extractRelayMessage,
normalizeTransportPayload,
safeRandomId,
} from "./daemon-client-transport-utils.js";
@@ -3,6 +3,7 @@ import type {
WebSocketFactory,
WebSocketLike,
} from "./daemon-client-transport-types.js";
import { extractRelayMessage } from "./daemon-client-transport-utils.js";
export function defaultWebSocketFactory(
url: string,
@@ -52,11 +53,25 @@ export function createWebSocketTransportFactory(factory: WebSocketFactory): Daem
onOpen: (handler) => bindWsHandler(ws, "open", handler),
onClose: (handler) => bindWsHandler(ws, "close", handler),
onError: (handler) => bindWsHandler(ws, "error", handler),
onMessage: (handler) => bindWsHandler(ws, "message", handler),
onMessage: (handler) => bindWsMessageHandler(ws, handler),
};
};
}
function bindWsMessageHandler(
ws: WebSocketLike,
handler: (data: unknown, isBinary: boolean) => void,
): () => void {
const listener = (...args: unknown[]) => {
const message = extractRelayMessage(
args[0],
typeof args[1] === "boolean" ? args[1] : undefined,
);
handler(message.data, message.isBinary);
};
return bindWsHandler(ws, "message", listener);
}
function bindTemporaryEarlyCloseErrorHandler(ws: WebSocketLike): () => void {
const noop = () => {};
+1 -1
View File
@@ -34,7 +34,7 @@ class FakeWebSocket {
}
message(data: string): void {
this.onmessage?.(data);
this.onmessage?.({ data });
}
}