From 7b7d6d01cf94ecad1dcaaa4b87670d50fe15790a Mon Sep 17 00:00:00 2001 From: Adam Malczewski Date: Wed, 21 Oct 2026 19:39:47 +0900 Subject: fix(chat): bound live subscriptions and preserve unconfirmed input --- src/app/surface-protocol.test.ts | 31 +++++++++++++++++++++++++++++++ 1 file changed, 31 insertions(+) (limited to 'src/app/surface-protocol.test.ts') diff --git a/src/app/surface-protocol.test.ts b/src/app/surface-protocol.test.ts index 5ac4f70..405e561 100644 --- a/src/app/surface-protocol.test.ts +++ b/src/app/surface-protocol.test.ts @@ -63,3 +63,34 @@ describe("conversation-scoped surface lookup", () => { expect(surfaces.surfaceSpecOp("s1", "c1")).toBeNull(); }); }); + +describe("surface subscription budget", () => { + it("bounds a large catalog and releases old slots before subscribing a replacement catalog", () => { + const live = new Set(); + let peak = 0; + const surfaces = createSurfaceProtocol({ + focusedConversationId: () => "chat", + send(message) { + if (message.type === "subscribe") live.add(message.surfaceId); + if (message.type === "unsubscribe") live.delete(message.surfaceId); + peak = Math.max(peak, live.size); + }, + }); + for (const prefix of ["old", "new"]) { + surfaces.handleServerMessage({ + type: "catalog", + catalog: Array.from({ length: 339 }, (_, i) => ({ + id: `${prefix}-${i}`, + region: "inline", + title: "Surface", + scope: "global" as const, + })), + }); + expect(live.size).toBe(128); + expect([...live].every((id) => id.startsWith(prefix))).toBe(true); + } + surfaces.subscribeSurfaceOp("overflow"); + expect(live.has("overflow")).toBe(false); + expect(peak).toBe(128); + }); +}); -- cgit v1.2.3