import * as decoding from "lib0/decoding";
import * as encoding from "lib0/encoding";
import { MESSAGE_AWARENESS } from "~/lib/editor-protocol";
/**
* y-protocols awareness updates, framed without a server-side Awareness instance. The room only relays
* and caches them, because Awareness keeps a timer running that would stop the Durable Object hibernating.
*/
export type AwarenessEntry = { clientId: number; clock: number; state: unknown };
export function decodeAwareness(update: Uint8Array): AwarenessEntry[] {
const decoder = decoding.createDecoder(update);
const count = decoding.readVarUint(decoder);
const entries: AwarenessEntry[] = [];
for (let index = 0; index < count; index++) {
const clientId = decoding.readVarUint(decoder);
const clock = decoding.readVarUint(decoder);
entries.push({ clientId, clock, state: JSON.parse(decoding.readVarString(decoder)) });
}
return entries;
}
export function encodeAwareness(entries: AwarenessEntry[]): Uint8Array {
const encoder = encoding.createEncoder();
encoding.writeVarUint(encoder, entries.length);
for (const entry of entries) {
encoding.writeVarUint(encoder, entry.clientId);
encoding.writeVarUint(encoder, entry.clock);
encoding.writeVarString(encoder, JSON.stringify(entry.state));
}
return encoding.toUint8Array(encoder);
}
/** Wraps an awareness update in the room's binary frame. */
export function awarenessFrame(update: Uint8Array): Uint8Array {
const encoder = encoding.createEncoder();
encoding.writeVarUint(encoder, MESSAGE_AWARENESS);
encoding.writeVarUint8Array(encoder, update);
return encoding.toUint8Array(encoder);
}