voice-over-translation/src/extension/shared/transport.ts
Toil 2ec15a71cf
Some checks failed
Build / node (22.x) (push) Has been cancelled
Build / extension (22.x) (push) Has been cancelled
Build / bun (push) Has been cancelled
refactor: cleanup duplicates and dead code with fallow suggests
2026-09-23 01:20:28 +03:00

72 lines
2.3 KiB
TypeScript

import { type AnyObject, MARK, TYPE_XHR_EVENT } from "./constants";
type BridgeMarkedMessage = AnyObject & { [MARK]: true };
function isArrayBuffer(value: unknown): value is ArrayBuffer {
return typeof ArrayBuffer !== "undefined" && value instanceof ArrayBuffer;
}
function getTransferables(payload: AnyObject): Transferable[] {
if (payload.type !== TYPE_XHR_EVENT) return [];
const eventPayload = payload.payload as AnyObject | undefined;
const progressChunk = eventPayload?.progress?.chunk;
const responseBody = eventPayload?.response?.response;
if (!isArrayBuffer(progressChunk)) {
return isArrayBuffer(responseBody) ? [responseBody] : [];
}
if (!isArrayBuffer(responseBody) || responseBody === progressChunk) {
return [progressChunk];
}
return [progressChunk, responseBody];
}
export function toBridgeMessage(payload: AnyObject): BridgeMarkedMessage {
// Always force the marker at the final write position.
return { ...payload, [MARK]: true };
}
export function getSameWindowPostMessageTargetOrigin(): string {
const origin = globalThis.location?.origin;
// Opaque origins (about:blank, about:srcdoc, sandboxed frames) expose
// location.origin as "null". That string is not a valid postMessage
// target origin, so the only valid target is "*". The bridge still
// verifies event.source and the private marker before accepting messages.
return !origin || origin === "null" ? "*" : origin;
}
export function isSameWindowBridgeEvent(event: MessageEvent): boolean {
if (event.source !== globalThis.window) return false;
const origin = globalThis.location?.origin;
if (!origin || origin === "null") {
return event.origin === "null" || event.origin === origin;
}
return event.origin === origin;
}
export function toPageMessage(payload: AnyObject): {
message: BridgeMarkedMessage;
transfer: Transferable[];
} {
const message = toBridgeMessage(payload);
return {
message,
transfer: getTransferables(payload),
};
}
export function postToPage(payload: AnyObject): void {
const { message, transfer } = toPageMessage(payload);
const targetOrigin = getSameWindowPostMessageTargetOrigin();
if (transfer.length) {
globalThis.postMessage(message, targetOrigin, transfer);
return;
}
globalThis.postMessage(message, targetOrigin);
}