@openchambery/web 1.18.4-beta.15 → 1.18.4-beta.16

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (44) hide show
  1. package/dist/assets/{AssistantView-8uU58vy0.js → AssistantView-2oaKAdLl.js} +1 -1
  2. package/dist/assets/{ChatContainer-CimpaKcn.js → ChatContainer-C3okCjTT.js} +4 -4
  3. package/dist/assets/{DiagramView-euzFXO_O.js → DiagramView-BdWjzN9Y.js} +1 -1
  4. package/dist/assets/{MarkdownRendererImpl-Dit2Ib5h.js → MarkdownRendererImpl-DXzGhggv.js} +1 -1
  5. package/dist/assets/{MobileDetailNavigation-BUj1ICFS.js → MobileDetailNavigation-BxzzbVuo.js} +1 -1
  6. package/dist/assets/{MobileShareBridge-DFHvcf7Q.js → MobileShareBridge-CO5oEylO.js} +1 -1
  7. package/dist/assets/{MobileSurface-CDowKkJL.js → MobileSurface-DS_tuMUX.js} +1 -1
  8. package/dist/assets/{MultiRunWindow-CvUMhyyj.js → MultiRunWindow-D_z9Yrj0.js} +1 -1
  9. package/dist/assets/{SettingsView-By3I3xXH.js → SettingsView-Dq4d1azT.js} +1 -1
  10. package/dist/assets/{SettingsWindow-5n2DvzeP.js → SettingsWindow-B-2mGlsr.js} +1 -1
  11. package/dist/assets/{TerminalView-BmycLxLS.js → TerminalView-BGg8vpYk.js} +1 -1
  12. package/dist/assets/{ToolOutputDialog-BdhiH4i4.js → ToolOutputDialog-TUgfUyPX.js} +1 -1
  13. package/dist/assets/{appThemeRegistry-NoIEZNtX.js → appThemeRegistry-DYl9pc39.js} +2 -2
  14. package/dist/assets/{context-menu-BOlxzatH.js → context-menu-CHKr-Ai0.js} +1 -1
  15. package/dist/assets/{gitApi-q_WNtocg.js → gitApi-CBvO-0tn.js} +1 -1
  16. package/dist/assets/{insertionBoundaries-tokUZ60O.js → insertionBoundaries-DOABfwfW.js} +1 -1
  17. package/dist/assets/{main-D08xX-l9.js → main-CfHT5-XW.js} +2 -2
  18. package/dist/assets/{main-B5n5utaj.js → main-DmE2qI1o.js} +4 -4
  19. package/dist/assets/{miniChat-S0KGzmRO.js → miniChat-2PBRWMPo.js} +2 -2
  20. package/dist/assets/{mobile-BBGkZDcd.js → mobile-BllXjQxK.js} +2 -2
  21. package/dist/assets/{multirun-CWuU0fcO.js → multirun-CFX1tCht.js} +1 -1
  22. package/dist/assets/{projectMeta-BKC7h4Rl.js → projectMeta-BqjXxia6.js} +1 -1
  23. package/dist/assets/{radio-BNOD9XTZ.js → radio-DpGoPQGD.js} +1 -1
  24. package/dist/assets/{renderElectronMiniChatApp-CNL8yc53.js → renderElectronMiniChatApp-DtSye_u8.js} +2 -2
  25. package/dist/assets/{renderMobileApp-DabtxHdO.js → renderMobileApp-BDpsb0XZ.js} +4 -4
  26. package/dist/assets/{runtimeConfig-Cfrfl4hH.js → runtimeConfig-qlXnVd3m.js} +1 -1
  27. package/dist/assets/{runtimeEndpointReset-C1vjUBL_.js → runtimeEndpointReset-CBslSisj.js} +1 -1
  28. package/dist/assets/{useAppFontEffects-CkLk4g06.js → useAppFontEffects-D6a67KZ8.js} +2 -2
  29. package/dist/assets/{useDesktopWindowControlsLayout-BSeMY94L.js → useDesktopWindowControlsLayout-B-P1qfXu.js} +1 -1
  30. package/dist/assets/{useEffectiveDirectory-CA1iNlkc.js → useEffectiveDirectory-DLsYww1j.js} +1 -1
  31. package/dist/assets/useMobileNavigationStore-wm9JzfV_.js +475 -0
  32. package/dist/assets/{useSessionAutoCleanup-LLUYctRd.js → useSessionAutoCleanup-IpHMdVbd.js} +1 -1
  33. package/dist/assets/{useWorkerHighlightedLines-dTnogsPN.js → useWorkerHighlightedLines-B2PxEV54.js} +1 -1
  34. package/dist/index.html +2 -2
  35. package/dist/mini-chat.html +2 -2
  36. package/dist/mobile.html +2 -2
  37. package/package.json +1 -1
  38. package/server/lib/notifications/DOCUMENTATION.md +2 -1
  39. package/server/lib/notifications/emitter-runtime.js +78 -1
  40. package/server/lib/notifications/emitter-runtime.test.js +94 -1
  41. package/server/lib/scheduled-tasks/DOCUMENTATION.md +4 -1
  42. package/server/lib/scheduled-tasks/routes.js +51 -8
  43. package/server/sse-routes.test.js +64 -1
  44. package/dist/assets/useMobileNavigationStore-DyYYlEY1.js +0 -475
@@ -52,8 +52,10 @@ const createMockResponse = () => {
52
52
  let body = '';
53
53
  let flushed = false;
54
54
  let bodyFlushCount = 0;
55
+ let destroyed = false;
56
+ let writableEnded = false;
55
57
 
56
- return {
58
+ const res = {
57
59
  on(event, handler) {
58
60
  listeners.set(event, handler);
59
61
  return this;
@@ -80,6 +82,9 @@ const createMockResponse = () => {
80
82
  body += String(chunk);
81
83
  return true;
82
84
  },
85
+ destroy() {
86
+ destroyed = true;
87
+ },
83
88
  status(code) {
84
89
  statusCode = code;
85
90
  return this;
@@ -100,7 +105,21 @@ const createMockResponse = () => {
100
105
  get bodyFlushCount() {
101
106
  return bodyFlushCount;
102
107
  },
108
+ get destroyed() {
109
+ return destroyed;
110
+ },
111
+ set destroyed(value) {
112
+ destroyed = Boolean(value);
113
+ },
114
+ get writableEnded() {
115
+ return writableEnded;
116
+ },
117
+ set writableEnded(value) {
118
+ writableEnded = Boolean(value);
119
+ },
103
120
  };
121
+
122
+ return res;
104
123
  };
105
124
 
106
125
  describe('local SSE routes', () => {
@@ -162,6 +181,7 @@ describe('local SSE routes', () => {
162
181
  getOpenChamberEventClients: () => clients,
163
182
  writeSseEvent(res, payload) {
164
183
  res.write(`data: ${JSON.stringify(payload)}\n\n`);
184
+ return true;
165
185
  },
166
186
  });
167
187
 
@@ -183,4 +203,47 @@ describe('local SSE routes', () => {
183
203
  req.emit('close');
184
204
  expect(clients.has(res)).toBe(false);
185
205
  });
206
+
207
+ it('evicts half-open OpenChamber SSE clients after consecutive paused heartbeats', () => {
208
+ vi.useFakeTimers();
209
+ const { app, getRoute } = createRouteRegistry();
210
+ const clients = new Set();
211
+ let destroyCount = 0;
212
+
213
+ try {
214
+ registerScheduledTaskRoutes(app, {
215
+ getOpenChamberEventClients: () => clients,
216
+ writeSseEvent(res) {
217
+ res.__ssePaused = true;
218
+ return false;
219
+ },
220
+ });
221
+
222
+ const handler = getRoute('GET', '/api/openchamber/events');
223
+ const req = createMockRequest();
224
+ const res = createMockResponse();
225
+ res.destroy = () => {
226
+ destroyCount += 1;
227
+ res.destroyed = true;
228
+ };
229
+
230
+ handler(req, res);
231
+ expect(clients.has(res)).toBe(true);
232
+
233
+ vi.advanceTimersByTime(25_000);
234
+ expect(clients.has(res)).toBe(true);
235
+ expect(destroyCount).toBe(0);
236
+
237
+ vi.advanceTimersByTime(25_000);
238
+ expect(clients.has(res)).toBe(false);
239
+ expect(destroyCount).toBe(1);
240
+ expect(vi.getTimerCount()).toBe(0);
241
+
242
+ // Idempotent cleanup: a late close must not throw or re-destroy.
243
+ req.emit('close');
244
+ expect(destroyCount).toBe(1);
245
+ } finally {
246
+ vi.useRealTimers();
247
+ }
248
+ });
186
249
  });