From 5860dc0310a4111e034eda39c56d97acd048569e Mon Sep 17 00:00:00 2001 From: lody Date: Sun, 4 Jan 2026 04:02:20 +0000 Subject: [PATCH] feat(loro-websocket): add sendExternalUpdates method to LoroWebsocketClient Add a new public method sendExternalUpdates() that allows users to send additional updates to a specified room that are not from the local peer's document. This is useful for forwarding updates received from other sources or peers. The method: - Takes crdt type, roomId, and an array of update payloads - Validates that the room is active and WebSocket is open - Uses existing sendUpdateOrFragments() for proper fragmentation handling - Throws descriptive errors if preconditions are not met Co-authored-by: lody --- packages/loro-websocket/src/client/index.ts | 35 +++++++++++++++++++++ 1 file changed, 35 insertions(+) diff --git a/packages/loro-websocket/src/client/index.ts b/packages/loro-websocket/src/client/index.ts index 7747a4b..d93e032 100644 --- a/packages/loro-websocket/src/client/index.ts +++ b/packages/loro-websocket/src/client/index.ts @@ -1215,6 +1215,41 @@ export class LoroWebsocketClient { ); } + /** + * Send additional updates to a specified room. + * + * This method allows sending updates that are not from the local peer's document, + * such as updates received from other sources or peers. The updates will be + * broadcast to the room and other connected clients. + * + * @param crdt - The CRDT type of the room + * @param roomId - The room ID to send updates to + * @param updates - Array of update payloads to send + * @throws Error if not connected or room is not active + */ + sendExternalUpdates( + crdt: CrdtType, + roomId: string, + updates: Uint8Array[] + ): void { + const id = crdt + roomId; + const active = this.activeRooms.get(id); + if (!active) { + throw new Error( + `Cannot send updates: room ${roomId} (${crdt}) is not active` + ); + } + + if (!this.ws || this.ws.readyState !== WebSocket.OPEN) { + throw new Error("Cannot send updates: WebSocket is not open"); + } + + // Send each update individually, fragmenting when necessary + for (const update of updates) { + this.sendUpdateOrFragments(crdt, roomId, update); + } + } + consumeSentBatch(refId: HexString): { roomKey: string; updates: Uint8Array[] } | undefined { const entry = this.sentUpdateBatches.get(refId); if (entry) {