mirror of
https://github.com/HKUDS/nanobot.git
synced 2026-08-31 08:13:11 +03:00
fix(webui): snapshot mutation replay frames
This commit is contained in:
@@ -109,10 +109,8 @@ interface PendingRequest<T> {
|
||||
timer: ReturnType<typeof setTimeout>;
|
||||
}
|
||||
|
||||
type WebUIRequestFrame = Extract<Outbound, { type: "webui_request" }>;
|
||||
|
||||
interface PendingWebUIRequest extends PendingRequest<unknown> {
|
||||
frame: WebUIRequestFrame;
|
||||
serializedFrame: string;
|
||||
}
|
||||
|
||||
export class WebUIMutationError extends Error {
|
||||
@@ -868,6 +866,13 @@ export class NanobotClient {
|
||||
}
|
||||
|
||||
return new Promise<T>((resolve, reject) => {
|
||||
let serializedFrame: string;
|
||||
try {
|
||||
serializedFrame = JSON.stringify(frame);
|
||||
} catch {
|
||||
reject(new WebUIMutationError(503, "Could not encode WebUI request"));
|
||||
return;
|
||||
}
|
||||
const timer = setTimeout(() => {
|
||||
this.pendingWebUIRequests.delete(requestId);
|
||||
reject(
|
||||
@@ -881,10 +886,10 @@ export class NanobotClient {
|
||||
resolve: (value) => resolve(value as T),
|
||||
reject,
|
||||
timer,
|
||||
frame,
|
||||
serializedFrame,
|
||||
});
|
||||
try {
|
||||
socket.send(JSON.stringify(frame));
|
||||
socket.send(serializedFrame);
|
||||
} catch {
|
||||
clearTimeout(timer);
|
||||
this.pendingWebUIRequests.delete(requestId);
|
||||
@@ -1028,7 +1033,7 @@ export class NanobotClient {
|
||||
this.rawSend({ type: "attach", chat_id: chatId });
|
||||
}
|
||||
for (const pending of this.pendingWebUIRequests.values()) {
|
||||
this.rawSend(pending.frame);
|
||||
this.rawSendSerialized(pending.serializedFrame);
|
||||
}
|
||||
// Flush anything queued during reconnect.
|
||||
const queued = this.sendQueue.splice(0);
|
||||
@@ -1476,4 +1481,13 @@ export class NanobotClient {
|
||||
this.sendQueue.push(frame);
|
||||
}
|
||||
}
|
||||
|
||||
private rawSendSerialized(serializedFrame: string): void {
|
||||
if (!this.socket) return;
|
||||
try {
|
||||
this.socket.send(serializedFrame);
|
||||
} catch {
|
||||
// The pending request remains available for the next successful reconnect.
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -183,12 +183,12 @@ describe("NanobotClient", () => {
|
||||
const firstSocket = lastSocket();
|
||||
firstSocket.fakeOpen();
|
||||
|
||||
const pending = client.requestMutation<{ ran: boolean }>(
|
||||
"automation.run",
|
||||
{ id: "daily-summary" },
|
||||
);
|
||||
const payload = { id: "daily-summary", options: { force: false } };
|
||||
const pending = client.requestMutation<{ ran: boolean }>("automation.run", payload);
|
||||
const frame = firstSocket.sent.at(-1) as string;
|
||||
const requestId = JSON.parse(frame).request_id;
|
||||
payload.id = "weekly-summary";
|
||||
payload.options.force = true;
|
||||
const settled = expect(pending).resolves.toEqual({ ran: true });
|
||||
firstSocket.fakeCloseWithCode(1006);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user