rwsdk
Version:
Build fast, server-driven webapps on Cloudflare with SSR, RSC, and realtime
59 lines (58 loc) • 1.92 kB
JavaScript
// Version marker for the state-sync protocol. Bumped whenever the
// envelope or message shape changes incompatibly.
export const PROTOCOL_VERSION = 1;
export function packMessage(message) {
return JSON.stringify({ v: PROTOCOL_VERSION, ...message });
}
function parseEnvelope(data) {
const parsed = JSON.parse(data);
if (parsed.v !== PROTOCOL_VERSION) {
throw new Error(`Unsupported protocol version: ${parsed.v ?? "missing"}`);
}
return parsed;
}
function isClientMessage(message) {
switch (message.kind) {
case "getState":
case "subscribe":
case "unsubscribe":
return "id" in message && typeof message.id === "string";
case "setState":
return "id" in message && typeof message.id === "string" && "value" in message;
default:
return false;
}
}
function isServerMessage(message) {
switch (message.kind) {
case "getState":
return ("id" in message &&
typeof message.id === "string" &&
"key" in message &&
typeof message.key === "string");
case "setState":
case "subscribe":
case "unsubscribe":
return "id" in message && typeof message.id === "string";
case "update":
return "key" in message && typeof message.key === "string";
case "error":
return "message" in message && typeof message.message === "string";
default:
return false;
}
}
export function unpackClientMessage(data) {
const message = parseEnvelope(data);
if (!isClientMessage(message)) {
throw new Error("Invalid client message");
}
return message;
}
export function unpackServerMessage(data) {
const message = parseEnvelope(data);
if (!isServerMessage(message)) {
throw new Error("Invalid server message");
}
return message;
}