rwsdk
Version:
Build fast, server-driven webapps on Cloudflare with SSR, RSC, and realtime
70 lines (69 loc) • 2.4 kB
JavaScript
import { packMessage, unpackServerMessage, } from "../protocol.mjs";
import { startPendingRequestTimer } from "./timer.js";
export function makeMessageId(connection) {
return `${connection.nextId++}`;
}
export async function sendMessage(connection, message) {
const { isOpen, ws, pending } = connection;
if (isOpen) {
return new Promise((resolve, reject) => {
pending.set(message.id, { resolve, reject });
startPendingRequestTimer(connection);
ws.send(packMessage(message));
});
}
return new Promise((resolve, reject) => {
const onOpen = () => {
cleanup();
connection.pending.set(message.id, { resolve, reject });
startPendingRequestTimer(connection);
connection.ws.send(packMessage(message));
};
const onClose = () => {
cleanup();
reject(new Error("WebSocket closed before message could be sent"));
};
const cleanup = () => {
connection.ws.removeEventListener("open", onOpen);
connection.ws.removeEventListener("close", onClose);
};
connection.ws.addEventListener("open", onOpen);
connection.ws.addEventListener("close", onClose);
});
}
export function handleServerMessage(connection, message) {
if (message.kind === "update") {
const handlers = connection.messageHandlers.get(message.key);
if (handlers)
for (const handler of handlers)
handler(message.value);
return;
}
if (message.kind === "error") {
if (message.id !== undefined) {
const pending = connection.pending.get(message.id);
if (pending) {
connection.pending.delete(message.id);
pending.reject(new Error(message.message));
}
}
startPendingRequestTimer(connection);
return;
}
const pending = connection.pending.get(message.id);
if (!pending)
return;
connection.pending.delete(message.id);
pending.resolve(message.kind === "getState" ? message.value : undefined);
startPendingRequestTimer(connection);
}
export function unpackMessage(data) {
if (typeof data !== "string")
return undefined;
try {
return unpackServerMessage(data);
}
catch {
return undefined;
}
}