@superblocksteam/shared 0.9607.3 → 0.9608.0

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 (294) hide show
  1. package/dist/database-lifecycle/appDatabaseCompatibility.d.ts +49 -0
  2. package/dist/database-lifecycle/appDatabaseCompatibility.d.ts.map +1 -0
  3. package/dist/database-lifecycle/appDatabaseCompatibility.js +32 -0
  4. package/dist/database-lifecycle/appDatabaseCompatibility.js.map +1 -0
  5. package/dist/database-lifecycle/appDatabaseCompatibility.test.d.ts +2 -0
  6. package/dist/database-lifecycle/appDatabaseCompatibility.test.d.ts.map +1 -0
  7. package/dist/database-lifecycle/appDatabaseCompatibility.test.js +47 -0
  8. package/dist/database-lifecycle/appDatabaseCompatibility.test.js.map +1 -0
  9. package/dist/database-lifecycle/destructiveMigrations.d.ts +12 -0
  10. package/dist/database-lifecycle/destructiveMigrations.d.ts.map +1 -1
  11. package/dist/database-lifecycle/destructiveMigrations.js +114 -0
  12. package/dist/database-lifecycle/destructiveMigrations.js.map +1 -1
  13. package/dist/database-lifecycle/destructiveMigrations.test.js +79 -0
  14. package/dist/database-lifecycle/destructiveMigrations.test.js.map +1 -1
  15. package/dist/database-lifecycle/index.d.ts +46 -2
  16. package/dist/database-lifecycle/index.d.ts.map +1 -1
  17. package/dist/database-lifecycle/index.js +127 -1
  18. package/dist/database-lifecycle/index.js.map +1 -1
  19. package/dist/database-lifecycle/providerDiagnostics.test.d.ts +2 -0
  20. package/dist/database-lifecycle/providerDiagnostics.test.d.ts.map +1 -0
  21. package/dist/database-lifecycle/providerDiagnostics.test.js +119 -0
  22. package/dist/database-lifecycle/providerDiagnostics.test.js.map +1 -0
  23. package/dist/environment-compatibility/appEnvironmentCompatibility.d.ts +65 -0
  24. package/dist/environment-compatibility/appEnvironmentCompatibility.d.ts.map +1 -0
  25. package/dist/environment-compatibility/appEnvironmentCompatibility.js +87 -0
  26. package/dist/environment-compatibility/appEnvironmentCompatibility.js.map +1 -0
  27. package/dist/environment-compatibility/appEnvironmentCompatibility.test.d.ts +2 -0
  28. package/dist/environment-compatibility/appEnvironmentCompatibility.test.d.ts.map +1 -0
  29. package/dist/environment-compatibility/appEnvironmentCompatibility.test.js +285 -0
  30. package/dist/environment-compatibility/appEnvironmentCompatibility.test.js.map +1 -0
  31. package/dist/errors/http.d.ts +15 -4
  32. package/dist/errors/http.d.ts.map +1 -1
  33. package/dist/errors/http.js +25 -7
  34. package/dist/errors/http.js.map +1 -1
  35. package/dist/errors/http.test.d.ts +2 -0
  36. package/dist/errors/http.test.d.ts.map +1 -0
  37. package/dist/errors/http.test.js +28 -0
  38. package/dist/errors/http.test.js.map +1 -0
  39. package/dist/index.d.ts +2 -0
  40. package/dist/index.d.ts.map +1 -1
  41. package/dist/index.js +2 -0
  42. package/dist/index.js.map +1 -1
  43. package/dist/plugins/templates/restApiIntegration.d.ts.map +1 -1
  44. package/dist/plugins/templates/restApiIntegration.js +2 -0
  45. package/dist/plugins/templates/restApiIntegration.js.map +1 -1
  46. package/dist/plugins/templates/shared/auth.d.ts +3 -1
  47. package/dist/plugins/templates/shared/auth.d.ts.map +1 -1
  48. package/dist/plugins/templates/shared/auth.js +129 -17
  49. package/dist/plugins/templates/shared/auth.js.map +1 -1
  50. package/dist/plugins/templates/shared/auth.test.d.ts +2 -0
  51. package/dist/plugins/templates/shared/auth.test.d.ts.map +1 -0
  52. package/dist/plugins/templates/shared/auth.test.js +116 -0
  53. package/dist/plugins/templates/shared/auth.test.js.map +1 -0
  54. package/dist/plugins/templates/shared/restapiintegration.d.ts +2 -0
  55. package/dist/plugins/templates/shared/restapiintegration.d.ts.map +1 -1
  56. package/dist/plugins/templates/shared/restapiintegration.js +3 -1
  57. package/dist/plugins/templates/shared/restapiintegration.js.map +1 -1
  58. package/dist/socket/dist-entry.test.d.ts +2 -0
  59. package/dist/socket/dist-entry.test.d.ts.map +1 -0
  60. package/dist/socket/dist-entry.test.js +34 -0
  61. package/dist/socket/dist-entry.test.js.map +1 -0
  62. package/dist/socket/heartbeat.d.ts +258 -0
  63. package/dist/socket/heartbeat.d.ts.map +1 -0
  64. package/dist/socket/heartbeat.js +307 -0
  65. package/dist/socket/heartbeat.js.map +1 -0
  66. package/dist/socket/heartbeat.test.d.ts +2 -0
  67. package/dist/socket/heartbeat.test.d.ts.map +1 -0
  68. package/dist/socket/heartbeat.test.js +431 -0
  69. package/dist/socket/heartbeat.test.js.map +1 -0
  70. package/dist/socket/index.d.ts +1 -0
  71. package/dist/socket/index.d.ts.map +1 -1
  72. package/dist/socket/index.js +1 -0
  73. package/dist/socket/index.js.map +1 -1
  74. package/dist/socket/util.d.ts.map +1 -1
  75. package/dist/socket/util.js +15 -1
  76. package/dist/socket/util.js.map +1 -1
  77. package/dist/socket/util.test.js +12 -2
  78. package/dist/socket/util.test.js.map +1 -1
  79. package/dist/types/ai/index.d.ts +3 -0
  80. package/dist/types/ai/index.d.ts.map +1 -1
  81. package/dist/types/ai/index.js +3 -0
  82. package/dist/types/ai/index.js.map +1 -1
  83. package/dist/types/application/index.d.ts +12 -0
  84. package/dist/types/application/index.d.ts.map +1 -1
  85. package/dist/types/application/index.js.map +1 -1
  86. package/dist/types/codeSecurity/index.d.ts +55 -1
  87. package/dist/types/codeSecurity/index.d.ts.map +1 -1
  88. package/dist/types/codeSecurity/index.js +21 -1
  89. package/dist/types/codeSecurity/index.js.map +1 -1
  90. package/dist/types/codeSecurity/index.test.d.ts +2 -0
  91. package/dist/types/codeSecurity/index.test.d.ts.map +1 -0
  92. package/dist/types/codeSecurity/index.test.js +19 -0
  93. package/dist/types/codeSecurity/index.test.js.map +1 -0
  94. package/dist/types/datasource/auth.d.ts +12 -1
  95. package/dist/types/datasource/auth.d.ts.map +1 -1
  96. package/dist/types/datasource/auth.js +20 -2
  97. package/dist/types/datasource/auth.js.map +1 -1
  98. package/dist/types/datasource/auth.test.js +3 -1
  99. package/dist/types/datasource/auth.test.js.map +1 -1
  100. package/dist/types/group/index.d.ts +1 -3
  101. package/dist/types/group/index.d.ts.map +1 -1
  102. package/dist/types/group/index.js +1 -3
  103. package/dist/types/group/index.js.map +1 -1
  104. package/dist/types/integration/index.d.ts +11 -1
  105. package/dist/types/integration/index.d.ts.map +1 -1
  106. package/dist/types/integration/index.js +11 -1
  107. package/dist/types/integration/index.js.map +1 -1
  108. package/dist/types/plugin/form.d.ts +32 -0
  109. package/dist/types/plugin/form.d.ts.map +1 -1
  110. package/dist/types/plugin/form.js +73 -1
  111. package/dist/types/plugin/form.js.map +1 -1
  112. package/dist/types/plugin/form.test.js +128 -0
  113. package/dist/types/plugin/form.test.js.map +1 -1
  114. package/dist/types/profile/index.d.ts +16 -1
  115. package/dist/types/profile/index.d.ts.map +1 -1
  116. package/dist/types/profile/index.js +7 -1
  117. package/dist/types/profile/index.js.map +1 -1
  118. package/dist/types/rbac/index.d.ts +2 -0
  119. package/dist/types/rbac/index.d.ts.map +1 -1
  120. package/dist/types/rbac/index.js +2 -0
  121. package/dist/types/rbac/index.js.map +1 -1
  122. package/dist/types/response/GetRecentApplicationsResponseBody.d.ts +4 -0
  123. package/dist/types/response/GetRecentApplicationsResponseBody.d.ts.map +1 -0
  124. package/dist/types/response/GetRecentApplicationsResponseBody.js +3 -0
  125. package/dist/types/response/GetRecentApplicationsResponseBody.js.map +1 -0
  126. package/dist/types/response/index.d.ts +1 -0
  127. package/dist/types/response/index.d.ts.map +1 -1
  128. package/dist/types/response/index.js +1 -0
  129. package/dist/types/response/index.js.map +1 -1
  130. package/dist-esm/database-lifecycle/appDatabaseCompatibility.d.ts +49 -0
  131. package/dist-esm/database-lifecycle/appDatabaseCompatibility.d.ts.map +1 -0
  132. package/dist-esm/database-lifecycle/appDatabaseCompatibility.js +28 -0
  133. package/dist-esm/database-lifecycle/appDatabaseCompatibility.js.map +1 -0
  134. package/dist-esm/database-lifecycle/appDatabaseCompatibility.test.d.ts +2 -0
  135. package/dist-esm/database-lifecycle/appDatabaseCompatibility.test.d.ts.map +1 -0
  136. package/dist-esm/database-lifecycle/appDatabaseCompatibility.test.js +45 -0
  137. package/dist-esm/database-lifecycle/appDatabaseCompatibility.test.js.map +1 -0
  138. package/dist-esm/database-lifecycle/destructiveMigrations.d.ts +12 -0
  139. package/dist-esm/database-lifecycle/destructiveMigrations.d.ts.map +1 -1
  140. package/dist-esm/database-lifecycle/destructiveMigrations.js +113 -0
  141. package/dist-esm/database-lifecycle/destructiveMigrations.js.map +1 -1
  142. package/dist-esm/database-lifecycle/destructiveMigrations.test.js +80 -1
  143. package/dist-esm/database-lifecycle/destructiveMigrations.test.js.map +1 -1
  144. package/dist-esm/database-lifecycle/index.d.ts +46 -2
  145. package/dist-esm/database-lifecycle/index.d.ts.map +1 -1
  146. package/dist-esm/database-lifecycle/index.js +123 -1
  147. package/dist-esm/database-lifecycle/index.js.map +1 -1
  148. package/dist-esm/database-lifecycle/providerDiagnostics.test.d.ts +2 -0
  149. package/dist-esm/database-lifecycle/providerDiagnostics.test.d.ts.map +1 -0
  150. package/dist-esm/database-lifecycle/providerDiagnostics.test.js +117 -0
  151. package/dist-esm/database-lifecycle/providerDiagnostics.test.js.map +1 -0
  152. package/dist-esm/environment-compatibility/appEnvironmentCompatibility.d.ts +65 -0
  153. package/dist-esm/environment-compatibility/appEnvironmentCompatibility.d.ts.map +1 -0
  154. package/dist-esm/environment-compatibility/appEnvironmentCompatibility.js +79 -0
  155. package/dist-esm/environment-compatibility/appEnvironmentCompatibility.js.map +1 -0
  156. package/dist-esm/environment-compatibility/appEnvironmentCompatibility.test.d.ts +2 -0
  157. package/dist-esm/environment-compatibility/appEnvironmentCompatibility.test.d.ts.map +1 -0
  158. package/dist-esm/environment-compatibility/appEnvironmentCompatibility.test.js +283 -0
  159. package/dist-esm/environment-compatibility/appEnvironmentCompatibility.test.js.map +1 -0
  160. package/dist-esm/errors/http.d.ts +15 -4
  161. package/dist-esm/errors/http.d.ts.map +1 -1
  162. package/dist-esm/errors/http.js +22 -6
  163. package/dist-esm/errors/http.js.map +1 -1
  164. package/dist-esm/errors/http.test.d.ts +2 -0
  165. package/dist-esm/errors/http.test.d.ts.map +1 -0
  166. package/dist-esm/errors/http.test.js +26 -0
  167. package/dist-esm/errors/http.test.js.map +1 -0
  168. package/dist-esm/index.d.ts +2 -0
  169. package/dist-esm/index.d.ts.map +1 -1
  170. package/dist-esm/index.js +2 -0
  171. package/dist-esm/index.js.map +1 -1
  172. package/dist-esm/plugins/templates/restApiIntegration.d.ts.map +1 -1
  173. package/dist-esm/plugins/templates/restApiIntegration.js +2 -0
  174. package/dist-esm/plugins/templates/restApiIntegration.js.map +1 -1
  175. package/dist-esm/plugins/templates/shared/auth.d.ts +3 -1
  176. package/dist-esm/plugins/templates/shared/auth.d.ts.map +1 -1
  177. package/dist-esm/plugins/templates/shared/auth.js +129 -17
  178. package/dist-esm/plugins/templates/shared/auth.js.map +1 -1
  179. package/dist-esm/plugins/templates/shared/auth.test.d.ts +2 -0
  180. package/dist-esm/plugins/templates/shared/auth.test.d.ts.map +1 -0
  181. package/dist-esm/plugins/templates/shared/auth.test.js +114 -0
  182. package/dist-esm/plugins/templates/shared/auth.test.js.map +1 -0
  183. package/dist-esm/plugins/templates/shared/restapiintegration.d.ts +2 -0
  184. package/dist-esm/plugins/templates/shared/restapiintegration.d.ts.map +1 -1
  185. package/dist-esm/plugins/templates/shared/restapiintegration.js +3 -1
  186. package/dist-esm/plugins/templates/shared/restapiintegration.js.map +1 -1
  187. package/dist-esm/socket/dist-entry.test.d.ts +2 -0
  188. package/dist-esm/socket/dist-entry.test.d.ts.map +1 -0
  189. package/dist-esm/socket/dist-entry.test.js +29 -0
  190. package/dist-esm/socket/dist-entry.test.js.map +1 -0
  191. package/dist-esm/socket/heartbeat.d.ts +258 -0
  192. package/dist-esm/socket/heartbeat.d.ts.map +1 -0
  193. package/dist-esm/socket/heartbeat.js +303 -0
  194. package/dist-esm/socket/heartbeat.js.map +1 -0
  195. package/dist-esm/socket/heartbeat.test.d.ts +2 -0
  196. package/dist-esm/socket/heartbeat.test.d.ts.map +1 -0
  197. package/dist-esm/socket/heartbeat.test.js +429 -0
  198. package/dist-esm/socket/heartbeat.test.js.map +1 -0
  199. package/dist-esm/socket/index.d.ts +1 -0
  200. package/dist-esm/socket/index.d.ts.map +1 -1
  201. package/dist-esm/socket/index.js +1 -0
  202. package/dist-esm/socket/index.js.map +1 -1
  203. package/dist-esm/socket/util.d.ts.map +1 -1
  204. package/dist-esm/socket/util.js +15 -1
  205. package/dist-esm/socket/util.js.map +1 -1
  206. package/dist-esm/socket/util.test.js +12 -2
  207. package/dist-esm/socket/util.test.js.map +1 -1
  208. package/dist-esm/types/ai/index.d.ts +3 -0
  209. package/dist-esm/types/ai/index.d.ts.map +1 -1
  210. package/dist-esm/types/ai/index.js +3 -0
  211. package/dist-esm/types/ai/index.js.map +1 -1
  212. package/dist-esm/types/application/index.d.ts +12 -0
  213. package/dist-esm/types/application/index.d.ts.map +1 -1
  214. package/dist-esm/types/application/index.js.map +1 -1
  215. package/dist-esm/types/codeSecurity/index.d.ts +55 -1
  216. package/dist-esm/types/codeSecurity/index.d.ts.map +1 -1
  217. package/dist-esm/types/codeSecurity/index.js +17 -1
  218. package/dist-esm/types/codeSecurity/index.js.map +1 -1
  219. package/dist-esm/types/codeSecurity/index.test.d.ts +2 -0
  220. package/dist-esm/types/codeSecurity/index.test.d.ts.map +1 -0
  221. package/dist-esm/types/codeSecurity/index.test.js +17 -0
  222. package/dist-esm/types/codeSecurity/index.test.js.map +1 -0
  223. package/dist-esm/types/datasource/auth.d.ts +12 -1
  224. package/dist-esm/types/datasource/auth.d.ts.map +1 -1
  225. package/dist-esm/types/datasource/auth.js +19 -2
  226. package/dist-esm/types/datasource/auth.js.map +1 -1
  227. package/dist-esm/types/datasource/auth.test.js +3 -1
  228. package/dist-esm/types/datasource/auth.test.js.map +1 -1
  229. package/dist-esm/types/group/index.d.ts +1 -3
  230. package/dist-esm/types/group/index.d.ts.map +1 -1
  231. package/dist-esm/types/group/index.js +1 -3
  232. package/dist-esm/types/group/index.js.map +1 -1
  233. package/dist-esm/types/integration/index.d.ts +11 -1
  234. package/dist-esm/types/integration/index.d.ts.map +1 -1
  235. package/dist-esm/types/integration/index.js +11 -1
  236. package/dist-esm/types/integration/index.js.map +1 -1
  237. package/dist-esm/types/plugin/form.d.ts +32 -0
  238. package/dist-esm/types/plugin/form.d.ts.map +1 -1
  239. package/dist-esm/types/plugin/form.js +68 -0
  240. package/dist-esm/types/plugin/form.js.map +1 -1
  241. package/dist-esm/types/plugin/form.test.js +129 -1
  242. package/dist-esm/types/plugin/form.test.js.map +1 -1
  243. package/dist-esm/types/profile/index.d.ts +16 -1
  244. package/dist-esm/types/profile/index.d.ts.map +1 -1
  245. package/dist-esm/types/profile/index.js +7 -1
  246. package/dist-esm/types/profile/index.js.map +1 -1
  247. package/dist-esm/types/rbac/index.d.ts +2 -0
  248. package/dist-esm/types/rbac/index.d.ts.map +1 -1
  249. package/dist-esm/types/rbac/index.js +2 -0
  250. package/dist-esm/types/rbac/index.js.map +1 -1
  251. package/dist-esm/types/response/GetRecentApplicationsResponseBody.d.ts +4 -0
  252. package/dist-esm/types/response/GetRecentApplicationsResponseBody.d.ts.map +1 -0
  253. package/dist-esm/types/response/GetRecentApplicationsResponseBody.js +2 -0
  254. package/dist-esm/types/response/GetRecentApplicationsResponseBody.js.map +1 -0
  255. package/dist-esm/types/response/index.d.ts +1 -0
  256. package/dist-esm/types/response/index.d.ts.map +1 -1
  257. package/dist-esm/types/response/index.js +1 -0
  258. package/dist-esm/types/response/index.js.map +1 -1
  259. package/package.json +1 -1
  260. package/src/database-lifecycle/appDatabaseCompatibility.test.ts +55 -0
  261. package/src/database-lifecycle/appDatabaseCompatibility.ts +62 -0
  262. package/src/database-lifecycle/destructiveMigrations.test.ts +108 -1
  263. package/src/database-lifecycle/destructiveMigrations.ts +129 -0
  264. package/src/database-lifecycle/index.ts +173 -0
  265. package/src/database-lifecycle/providerDiagnostics.test.ts +134 -0
  266. package/src/environment-compatibility/appEnvironmentCompatibility.test.ts +326 -0
  267. package/src/environment-compatibility/appEnvironmentCompatibility.ts +173 -0
  268. package/src/errors/http.test.ts +32 -0
  269. package/src/errors/http.ts +24 -6
  270. package/src/index.ts +2 -0
  271. package/src/plugins/templates/restApiIntegration.ts +2 -0
  272. package/src/plugins/templates/shared/auth.test.ts +162 -0
  273. package/src/plugins/templates/shared/auth.ts +135 -18
  274. package/src/plugins/templates/shared/restapiintegration.ts +3 -1
  275. package/src/socket/dist-entry.test.ts +29 -0
  276. package/src/socket/heartbeat.test.ts +538 -0
  277. package/src/socket/heartbeat.ts +469 -0
  278. package/src/socket/index.ts +1 -0
  279. package/src/socket/util.test.ts +14 -2
  280. package/src/socket/util.ts +15 -1
  281. package/src/types/ai/index.ts +3 -0
  282. package/src/types/application/index.ts +14 -0
  283. package/src/types/codeSecurity/index.test.ts +21 -0
  284. package/src/types/codeSecurity/index.ts +83 -1
  285. package/src/types/datasource/auth.test.ts +3 -1
  286. package/src/types/datasource/auth.ts +24 -3
  287. package/src/types/group/index.ts +1 -3
  288. package/src/types/integration/index.ts +14 -0
  289. package/src/types/plugin/form.test.ts +174 -1
  290. package/src/types/plugin/form.ts +100 -2
  291. package/src/types/profile/index.ts +19 -1
  292. package/src/types/rbac/index.ts +2 -0
  293. package/src/types/response/GetRecentApplicationsResponseBody.ts +4 -0
  294. package/src/types/response/index.ts +1 -0
@@ -0,0 +1,429 @@
1
+ import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest';
2
+ import { SocketHeartbeat } from './heartbeat.js';
3
+ const INTERVAL_MS = 100;
4
+ const TIMEOUT_MS = 50;
5
+ /** A beat whose answer the test decides, so the deadline is the only thing racing it. */
6
+ function controllableBeat() {
7
+ const pending = [];
8
+ const beat = vi.fn(() => new Promise((resolve, reject) => {
9
+ pending.push({ reject, resolve });
10
+ }));
11
+ return {
12
+ answerLast: () => pending[pending.length - 1]?.resolve(),
13
+ beat,
14
+ refuseLast: (error) => pending[pending.length - 1]?.reject(error),
15
+ pending
16
+ };
17
+ }
18
+ function heartbeat(overrides = {}) {
19
+ const onLost = vi.fn();
20
+ const onOutcome = vi.fn();
21
+ const { answerLast, beat, refuseLast } = controllableBeat();
22
+ const subject = new SocketHeartbeat({
23
+ beat,
24
+ intervalMs: INTERVAL_MS,
25
+ onLost,
26
+ onOutcome,
27
+ timeoutMs: TIMEOUT_MS,
28
+ ...overrides
29
+ });
30
+ return { answerLast, beat, onLost, onOutcome, refuseLast, subject };
31
+ }
32
+ /** Runs one full interval, then the beat deadline, letting each settle. */
33
+ async function elapse(ms) {
34
+ await vi.advanceTimersByTimeAsync(ms);
35
+ }
36
+ const outcomes = (onOutcome) => onOutcome.mock.calls.map((call) => call[0]);
37
+ describe('SocketHeartbeat', () => {
38
+ beforeEach(() => {
39
+ vi.useFakeTimers();
40
+ });
41
+ afterEach(() => {
42
+ vi.clearAllTimers();
43
+ vi.useRealTimers();
44
+ });
45
+ // The answer has to pace the beats, not the interval. Otherwise a channel that
46
+ // stopped answering collects a new pending request every interval, none of
47
+ // which can ever be reconciled.
48
+ it('keeps a single beat in flight however many intervals pass', async () => {
49
+ const { beat, subject } = heartbeat({ timeoutMs: 10_000 });
50
+ subject.start();
51
+ await elapse(INTERVAL_MS * 5);
52
+ expect(beat).toHaveBeenCalledTimes(1);
53
+ subject.stop();
54
+ });
55
+ // A request channel's own budget is the whole caller-facing operation, so a
56
+ // beat that borrows it cannot report a miss inside any window a caller waits in.
57
+ it('holds a beat to its own deadline rather than the request channel budget', async () => {
58
+ const { onOutcome, subject } = heartbeat();
59
+ subject.start();
60
+ await elapse(INTERVAL_MS + TIMEOUT_MS);
61
+ expect(outcomes(onOutcome)).toEqual(['grace']);
62
+ subject.stop();
63
+ });
64
+ // A refusal is a definite answer about the peer - it arrived, so the channel
65
+ // works - and counting it as a lapse would hide the very thing it reports.
66
+ it('records a refusal apart from a silence rather than excusing it as a lapse', async () => {
67
+ const { onOutcome, refuseLast, subject } = heartbeat();
68
+ subject.start();
69
+ subject.recordReceive();
70
+ await elapse(INTERVAL_MS);
71
+ refuseLast(new Error('peer is shutting down'));
72
+ await elapse(1);
73
+ expect(outcomes(onOutcome)).toEqual(['refused']);
74
+ expect(subject.account).toMatchObject({
75
+ failures: 0,
76
+ lapses: 0,
77
+ lastError: 'peer is shutting down',
78
+ refusals: 1,
79
+ unanswered: 0
80
+ });
81
+ subject.stop();
82
+ });
83
+ // A refusal is an answer: the peer is reachable and the request channel works,
84
+ // so whatever is wrong is not the connection. Spending the grace meant for a
85
+ // starved pong on one would tear a working socket down over an
86
+ // application-level problem.
87
+ it('does not let a refusal spend the grace meant for a silence', async () => {
88
+ const { onLost, onOutcome, refuseLast, subject } = heartbeat();
89
+ subject.start();
90
+ await elapse(INTERVAL_MS);
91
+ refuseLast(new Error('peer is shutting down'));
92
+ await elapse(1);
93
+ // One unanswered beat after the refusal is still only the first silence.
94
+ await elapse(INTERVAL_MS + TIMEOUT_MS);
95
+ expect(outcomes(onOutcome)).toEqual(['refused', 'grace']);
96
+ expect(onLost).not.toHaveBeenCalled();
97
+ subject.stop();
98
+ });
99
+ // ...but an answer to one beat says nothing about the beats that went
100
+ // missing, so a refusal must not clear a run of silences either. Otherwise a
101
+ // channel alternating between timing out and refusing never gives up.
102
+ it('does not let a refusal clear a run of silences', async () => {
103
+ const { onLost, onOutcome, refuseLast, subject } = heartbeat();
104
+ subject.start();
105
+ await elapse(INTERVAL_MS + TIMEOUT_MS);
106
+ await elapse(INTERVAL_MS - TIMEOUT_MS);
107
+ refuseLast(new Error('peer is shutting down'));
108
+ await elapse(1);
109
+ await elapse(INTERVAL_MS + TIMEOUT_MS);
110
+ expect(outcomes(onOutcome)).toEqual(['grace', 'refused', 'miss']);
111
+ expect(onLost).toHaveBeenCalledTimes(1);
112
+ subject.stop();
113
+ });
114
+ // Inbound traffic proves the connection is alive, so an unanswered beat on a
115
+ // socket that is still delivering data indicts the request channel, not the
116
+ // connection. Closing on that would kill a healthy-but-busy socket.
117
+ it('lapses an unanswered beat while the socket is provably receiving', async () => {
118
+ const { onLost, onOutcome, subject } = heartbeat();
119
+ subject.start();
120
+ await elapse(INTERVAL_MS);
121
+ subject.recordReceive();
122
+ await elapse(TIMEOUT_MS);
123
+ expect(outcomes(onOutcome)).toEqual(['lapse']);
124
+ expect(subject.account).toMatchObject({ failures: 0, lapses: 1, unanswered: 1 });
125
+ expect(onLost).not.toHaveBeenCalled();
126
+ subject.stop();
127
+ });
128
+ // Proof of life has to undo a suspicion the same way an answer does, or a
129
+ // single miss during a large transfer stays on the books until a pong lands.
130
+ it('resets the miss count when inbound traffic proves the connection alive', async () => {
131
+ const { onLost, subject } = heartbeat();
132
+ subject.start();
133
+ // First beat: nothing inbound, so a genuine miss held back by grace.
134
+ await elapse(INTERVAL_MS + TIMEOUT_MS);
135
+ expect(subject.account).toMatchObject({ failures: 1 });
136
+ // Second beat: unanswered, but the socket is provably carrying traffic.
137
+ await elapse(INTERVAL_MS - TIMEOUT_MS);
138
+ subject.recordReceive();
139
+ await elapse(TIMEOUT_MS);
140
+ expect(subject.account).toMatchObject({ failures: 0, lapses: 1, unanswered: 2 });
141
+ expect(onLost).not.toHaveBeenCalled();
142
+ subject.stop();
143
+ });
144
+ // Inbound data proves the receive path, not that the request channel answers.
145
+ // Without a bound, a wedged channel hides behind continuous pushes forever.
146
+ it('stops excusing a silent request channel once the silences are exhausted', async () => {
147
+ const maxConsecutiveUnanswered = 3;
148
+ const { onLost, onOutcome, subject } = heartbeat({ maxConsecutiveUnanswered });
149
+ subject.start();
150
+ // Traffic arrives during every beat's own wait, so each one is excused -
151
+ // until the allowance runs out and the next silence is believed anyway.
152
+ for (let beats = 0; beats < maxConsecutiveUnanswered; beats += 1) {
153
+ await elapse(INTERVAL_MS - (beats === 0 ? 0 : TIMEOUT_MS));
154
+ subject.recordReceive();
155
+ await elapse(TIMEOUT_MS);
156
+ }
157
+ expect(outcomes(onOutcome)).toEqual(['lapse', 'lapse', 'miss']);
158
+ expect(onLost).toHaveBeenCalledTimes(1);
159
+ // Both counts ride along on the close: how long the silence had run, and
160
+ // how much of it the socket was demonstrably carrying traffic through.
161
+ expect(onLost.mock.calls[0]?.[0]).toMatchObject({
162
+ failures: 1,
163
+ lapses: maxConsecutiveUnanswered - 1,
164
+ unanswered: maxConsecutiveUnanswered
165
+ });
166
+ subject.stop();
167
+ });
168
+ // The bound is on silence, not on the excuse. Two unanswered beats with
169
+ // nothing inbound must report the same run length as two that were excused,
170
+ // or telemetry cannot tell "died after two misses" from "wedged behind
171
+ // continuous pushes until the cap".
172
+ it('counts every unanswered beat toward the bound, excused or not', async () => {
173
+ const { onLost, subject } = heartbeat();
174
+ subject.start();
175
+ await elapse(INTERVAL_MS * 2 + TIMEOUT_MS);
176
+ expect(onLost).toHaveBeenCalledTimes(1);
177
+ expect(onLost.mock.calls[0]?.[0]).toMatchObject({ failures: 2, lapses: 0, unanswered: 2 });
178
+ subject.stop();
179
+ });
180
+ // The bound is what stops a wedged request channel hiding behind inbound
181
+ // pushes forever, and a refusal answers one beat - not the beats that already
182
+ // went missing. Clearing the run on a refusal hands that channel an unlimited
183
+ // deferral: every silence is excused by traffic, so `unanswered` is the only
184
+ // thing left that can ever end it.
185
+ it('does not let a refusal defer the bound on a silent request channel', async () => {
186
+ const maxConsecutiveUnanswered = 3;
187
+ const { onLost, onOutcome, refuseLast, subject } = heartbeat({ maxConsecutiveUnanswered });
188
+ subject.start();
189
+ // Traffic arrives during the beat's own wait, so this silence is excused.
190
+ await elapse(INTERVAL_MS);
191
+ subject.recordReceive();
192
+ await elapse(TIMEOUT_MS);
193
+ // A refusal interleaves: recorded as the answer it is, but it must not wipe
194
+ // the run of silence already on the books.
195
+ await elapse(INTERVAL_MS - TIMEOUT_MS);
196
+ refuseLast(new Error('peer is shutting down'));
197
+ await elapse(1);
198
+ await elapse(INTERVAL_MS - 1);
199
+ subject.recordReceive();
200
+ await elapse(TIMEOUT_MS);
201
+ await elapse(INTERVAL_MS - TIMEOUT_MS);
202
+ subject.recordReceive();
203
+ await elapse(TIMEOUT_MS);
204
+ expect(outcomes(onOutcome)).toEqual(['lapse', 'refused', 'lapse', 'miss']);
205
+ expect(onLost).toHaveBeenCalledTimes(1);
206
+ expect(onLost.mock.calls[0]?.[0]).toMatchObject({ refusals: 1, unanswered: maxConsecutiveUnanswered });
207
+ subject.stop();
208
+ });
209
+ // `unanswered` is what the caller reports as the length of the silence that
210
+ // killed the connection, and it is documented as bounded by the cap. Beats
211
+ // keep going out after the alarm has been raised - the caller still has to
212
+ // tear the socket down - so without saturating it the reported run climbs
213
+ // past the cap it is promised to respect.
214
+ it('never reports a longer silence than the bound allows', async () => {
215
+ const maxConsecutiveUnanswered = 3;
216
+ const { onOutcome, subject } = heartbeat({ maxConsecutiveUnanswered });
217
+ subject.start();
218
+ await elapse(INTERVAL_MS * 5 + TIMEOUT_MS);
219
+ expect(subject.account.unanswered).toBe(maxConsecutiveUnanswered);
220
+ const lastAccount = onOutcome.mock.calls[onOutcome.mock.calls.length - 1]?.[2];
221
+ expect(lastAccount.unanswered).toBe(maxConsecutiveUnanswered);
222
+ subject.stop();
223
+ });
224
+ // The alarm is edge-triggered so one run of misses causes one teardown, but
225
+ // that assumes the teardown happened. When the caller cannot act - the socket
226
+ // lookup throws, the close rejects - latching would mean nothing ever closes
227
+ // the connection and nothing ever says so again.
228
+ it('keeps the alarm armed when the caller could not act on the loss', async () => {
229
+ const onLost = vi.fn(() => {
230
+ throw new Error('the socket was already gone');
231
+ });
232
+ const { subject } = heartbeat({ maxConsecutiveMisses: 1, onLost });
233
+ subject.start();
234
+ await elapse(INTERVAL_MS + TIMEOUT_MS);
235
+ expect(onLost).toHaveBeenCalledTimes(1);
236
+ await elapse(INTERVAL_MS);
237
+ expect(onLost).toHaveBeenCalledTimes(2);
238
+ subject.stop();
239
+ });
240
+ // One missed beat is survivable: a bulk response is a single websocket message
241
+ // and no receive event fires until its last byte lands, so a transfer only has
242
+ // to finish inside one extra interval for the next answer to get through.
243
+ it('gives the first genuine miss grace and loses the beat on the second', async () => {
244
+ const { onLost, onOutcome, subject } = heartbeat();
245
+ subject.start();
246
+ await elapse(INTERVAL_MS + TIMEOUT_MS);
247
+ expect(onLost).not.toHaveBeenCalled();
248
+ await elapse(INTERVAL_MS);
249
+ expect(outcomes(onOutcome)).toEqual(['grace', 'miss']);
250
+ expect(onLost).toHaveBeenCalledTimes(1);
251
+ subject.stop();
252
+ });
253
+ it('resets both counters when a beat is answered', async () => {
254
+ const { answerLast, subject } = heartbeat();
255
+ subject.start();
256
+ await elapse(INTERVAL_MS + TIMEOUT_MS);
257
+ expect(subject.account).toMatchObject({ failures: 1 });
258
+ await elapse(INTERVAL_MS - TIMEOUT_MS);
259
+ answerLast();
260
+ await elapse(1);
261
+ expect(subject.account).toMatchObject({ failures: 0, lapses: 0, unanswered: 0 });
262
+ expect(subject.account.lastSuccessAt).toBeDefined();
263
+ subject.stop();
264
+ });
265
+ // A deadline armed for a previous connection fires after the restart. Letting
266
+ // it tick the new run's counters would close a healthy socket on the strength
267
+ // of a dead one's silence.
268
+ it('ignores a beat armed before the heartbeat was restarted', async () => {
269
+ const { onLost, onOutcome, subject } = heartbeat();
270
+ subject.start();
271
+ await elapse(INTERVAL_MS);
272
+ subject.stop();
273
+ subject.start();
274
+ await elapse(TIMEOUT_MS);
275
+ expect(onLost).not.toHaveBeenCalled();
276
+ expect(outcomes(onOutcome)).toEqual([]);
277
+ expect(subject.account).toMatchObject({ failures: 0, lapses: 0 });
278
+ subject.stop();
279
+ });
280
+ // A socket can die before any beat settles, and unanswered beats are the
281
+ // strongest evidence there is that the peer was gone - so the account cannot
282
+ // be built from settled outcomes alone.
283
+ it('counts every beat issued, including one still waiting', async () => {
284
+ const { subject } = heartbeat({ timeoutMs: 10_000 });
285
+ subject.start();
286
+ await elapse(INTERVAL_MS);
287
+ expect(subject.account).toMatchObject({ failures: 0, sent: 1 });
288
+ subject.stop();
289
+ });
290
+ // `sent` says a beat went out; it cannot say whether the last one came back.
291
+ // The caller reporting a death needs both, because a socket that answered a
292
+ // beat and then went quiet is otherwise indistinguishable from one answering
293
+ // right up to the close.
294
+ it('stamps the outstanding beat and clears the stamp when it settles', async () => {
295
+ const { answerLast, subject } = heartbeat({ timeoutMs: 10_000 });
296
+ subject.start();
297
+ await elapse(INTERVAL_MS);
298
+ const { pendingSince } = subject.account;
299
+ expect(pendingSince).toBeTypeOf('number');
300
+ answerLast();
301
+ await elapse(0);
302
+ expect(subject.account.pendingSince).toBeUndefined();
303
+ subject.stop();
304
+ });
305
+ // The account is read after the socket is gone, and stopping is the first
306
+ // thing a caller does with a dead connection. A stamp cleared on the way out
307
+ // would erase the one fact that names what the beat was doing when it died -
308
+ // and no settle is coming, because a retired beat's rejection is dropped.
309
+ it('keeps the outstanding beat stamped through a stop', async () => {
310
+ const { subject } = heartbeat({ timeoutMs: 10_000 });
311
+ subject.start();
312
+ await elapse(INTERVAL_MS);
313
+ subject.stop();
314
+ expect(subject.account.pendingSince).toBeTypeOf('number');
315
+ });
316
+ // A channel that cannot carry a beat yet has no turn to protect either, so a
317
+ // skipped beat is not a miss - and must not be booked as an answer, which is
318
+ // what returning early from the beat itself would amount to.
319
+ it('skips a beat while the channel is not ready to carry one', async () => {
320
+ const { beat, onOutcome, subject } = heartbeat({ shouldBeat: () => false, timeoutMs: 10_000 });
321
+ subject.start();
322
+ await elapse(INTERVAL_MS * 3);
323
+ expect(beat).not.toHaveBeenCalled();
324
+ expect(outcomes(onOutcome)).toEqual([]);
325
+ expect(subject.account).toMatchObject({ failures: 0, sent: 0 });
326
+ subject.stop();
327
+ });
328
+ // The alarm is edge-triggered: the counters are an account of what happened,
329
+ // read when a socket dies, and resetting them to re-arm would erase the very
330
+ // evidence the death report is built from.
331
+ it('raises the alarm once rather than on every beat after it', async () => {
332
+ const { onLost, onOutcome, subject } = heartbeat();
333
+ subject.start();
334
+ await elapse(INTERVAL_MS * 4 + TIMEOUT_MS);
335
+ expect(outcomes(onOutcome)).toEqual(['grace', 'miss', 'miss', 'miss']);
336
+ expect(onLost).toHaveBeenCalledTimes(1);
337
+ expect(subject.account).toMatchObject({ failures: 4 });
338
+ subject.stop();
339
+ });
340
+ it('re-arms the alarm once the peer answers again', async () => {
341
+ const { answerLast, onLost, subject } = heartbeat();
342
+ subject.start();
343
+ await elapse(INTERVAL_MS * 2 + TIMEOUT_MS);
344
+ expect(onLost).toHaveBeenCalledTimes(1);
345
+ await elapse(INTERVAL_MS - TIMEOUT_MS);
346
+ answerLast();
347
+ await elapse(1);
348
+ expect(subject.account).toMatchObject({ failures: 0 });
349
+ await elapse(INTERVAL_MS * 2 + TIMEOUT_MS);
350
+ expect(onLost).toHaveBeenCalledTimes(2);
351
+ subject.stop();
352
+ });
353
+ // Two callers drive the editor's beat: its own cadence, and the moment a
354
+ // user comes back to the keyboard. The second must not have to wait out an
355
+ // interval sized for idle connections.
356
+ it('beats on demand outside the interval', async () => {
357
+ const { beat, onOutcome, subject } = heartbeat({ timeoutMs: 10_000 });
358
+ // Not awaited: the beat is deliberately left in flight, which is what an
359
+ // on-demand caller sees when the peer is slow.
360
+ void subject.beatNow();
361
+ await elapse(1);
362
+ expect(beat).toHaveBeenCalledTimes(1);
363
+ expect(subject.account).toMatchObject({ sent: 1 });
364
+ expect(outcomes(onOutcome)).toEqual([]);
365
+ });
366
+ it('lets an on-demand beat and the interval share the in-flight guard', async () => {
367
+ const { beat, subject } = heartbeat({ timeoutMs: 10_000 });
368
+ subject.start();
369
+ await elapse(INTERVAL_MS);
370
+ await subject.beatNow();
371
+ expect(beat).toHaveBeenCalledTimes(1);
372
+ subject.stop();
373
+ });
374
+ // A caller can learn it has a new connection before it is ready to beat on
375
+ // one. The old socket's armed deadline has to stop counting at that moment,
376
+ // not whenever the first new beat happens to go out.
377
+ it('retires an armed beat on reset without touching the interval', async () => {
378
+ const { onLost, onOutcome, subject } = heartbeat();
379
+ subject.start();
380
+ await elapse(INTERVAL_MS);
381
+ subject.reset();
382
+ await elapse(TIMEOUT_MS);
383
+ expect(outcomes(onOutcome)).toEqual([]);
384
+ expect(onLost).not.toHaveBeenCalled();
385
+ expect(subject.account).toMatchObject({ failures: 0, sent: 0, unanswered: 0 });
386
+ // Still beating: reset is not a stop.
387
+ await elapse(INTERVAL_MS);
388
+ expect(subject.account).toMatchObject({ sent: 1 });
389
+ subject.stop();
390
+ });
391
+ // One heartbeat outlives the connections it beats for, and a superseded
392
+ // connection's teardown arrives late. If its stop were not bound to the
393
+ // cadence it started, it would take the live connection's beat down with it -
394
+ // silently, since nothing re-arms an interval that was never meant to stop.
395
+ it('ignores a stop belonging to a cadence that has been replaced', async () => {
396
+ const { beat, subject } = heartbeat({ timeoutMs: 10_000 });
397
+ const stopFirst = subject.start();
398
+ subject.start();
399
+ stopFirst();
400
+ await elapse(INTERVAL_MS);
401
+ expect(beat).toHaveBeenCalledTimes(1);
402
+ subject.stop();
403
+ });
404
+ it('stops the cadence it started when nothing has replaced it', async () => {
405
+ const { beat, subject } = heartbeat({ timeoutMs: 10_000 });
406
+ const stop = subject.start();
407
+ stop();
408
+ await elapse(INTERVAL_MS * 2);
409
+ expect(beat).not.toHaveBeenCalled();
410
+ });
411
+ it('replaces a running cadence rather than leaving two beating', async () => {
412
+ const { beat, subject } = heartbeat({ timeoutMs: 10_000 });
413
+ subject.start();
414
+ subject.start();
415
+ await elapse(INTERVAL_MS);
416
+ expect(beat).toHaveBeenCalledTimes(1);
417
+ subject.stop();
418
+ });
419
+ it('sends nothing before it is started or after it is stopped', async () => {
420
+ const { beat, subject } = heartbeat();
421
+ await elapse(INTERVAL_MS * 2);
422
+ expect(beat).not.toHaveBeenCalled();
423
+ subject.start();
424
+ subject.stop();
425
+ await elapse(INTERVAL_MS * 2);
426
+ expect(beat).not.toHaveBeenCalled();
427
+ });
428
+ });
429
+ //# sourceMappingURL=heartbeat.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"heartbeat.test.js","sourceRoot":"","sources":["../../src/socket/heartbeat.test.ts"],"names":[],"mappings":"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"}
@@ -1,3 +1,4 @@
1
+ export * from './heartbeat.js';
1
2
  export * from './socket.js';
2
3
  export * from './socketWithClientAuth.js';
3
4
  export * from './types.js';
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/socket/index.ts"],"names":[],"mappings":"AAEA,cAAc,aAAa,CAAC;AAC5B,cAAc,2BAA2B,CAAC;AAC1C,cAAc,YAAY,CAAC;AAC3B,cAAc,WAAW,CAAC;AAC1B,cAAc,mBAAmB,CAAC;AAGlC,cAAc,eAAe,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/socket/index.ts"],"names":[],"mappings":"AAEA,cAAc,gBAAgB,CAAC;AAC/B,cAAc,aAAa,CAAC;AAC5B,cAAc,2BAA2B,CAAC;AAC1C,cAAc,YAAY,CAAC;AAC3B,cAAc,WAAW,CAAC;AAC1B,cAAc,mBAAmB,CAAC;AAGlC,cAAc,eAAe,CAAC"}
@@ -1,5 +1,6 @@
1
1
  // the implementation of ISocket
2
2
  // this is protocol agnostic, it only handles the communication
3
+ export * from './heartbeat.js';
3
4
  export * from './socket.js';
4
5
  export * from './socketWithClientAuth.js';
5
6
  export * from './types.js';
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/socket/index.ts"],"names":[],"mappings":"AAAA,gCAAgC;AAChC,+DAA+D;AAC/D,cAAc,aAAa,CAAC;AAC5B,cAAc,2BAA2B,CAAC;AAC1C,cAAc,YAAY,CAAC;AAC3B,cAAc,WAAW,CAAC;AAC1B,cAAc,mBAAmB,CAAC;AAElC,0FAA0F;AAC1F,cAAc,eAAe,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/socket/index.ts"],"names":[],"mappings":"AAAA,gCAAgC;AAChC,+DAA+D;AAC/D,cAAc,gBAAgB,CAAC;AAC/B,cAAc,aAAa,CAAC;AAC5B,cAAc,2BAA2B,CAAC;AAC1C,cAAc,YAAY,CAAC;AAC3B,cAAc,WAAW,CAAC;AAC1B,cAAc,mBAAmB,CAAC;AAElC,0FAA0F;AAC1F,cAAc,eAAe,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"util.d.ts","sourceRoot":"","sources":["../../src/socket/util.ts"],"names":[],"mappings":"AAAA,OAAO,SAAS,MAAM,eAAe,CAAC;AAEtC;;;;;;;;;GASG;AACH,eAAO,MAAM,wBAAwB,QAAoB,CAAC;AAE1D;;;;;;;GAOG;AACH,eAAO,MAAM,4BAA4B,uBAAuB,CAAC;AAEjE;;;;GAIG;AACH,wBAAgB,oBAAoB,CAAC,SAAS,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,MAAM,GAAG,MAAM,CAEhF;AAED,MAAM,WAAW,uBAAuB;IACtC,QAAQ,CAAC,EAAE,MAAM,GAAG,MAAM,EAAE,CAAC;IAC7B,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,kGAAkG;IAClG,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CAClC;AAED;;;GAGG;AACH,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,GAAE,uBAA4B,GAAG,OAAO,CAAC,SAAS,CAAC,CA0BzG"}
1
+ {"version":3,"file":"util.d.ts","sourceRoot":"","sources":["../../src/socket/util.ts"],"names":[],"mappings":"AAAA,OAAO,SAAS,MAAM,eAAe,CAAC;AAEtC;;;;;;;;;GASG;AACH,eAAO,MAAM,wBAAwB,QAAoB,CAAC;AAE1D;;;;;;;GAOG;AACH,eAAO,MAAM,4BAA4B,uBAAuB,CAAC;AAEjE;;;;GAIG;AACH,wBAAgB,oBAAoB,CAAC,SAAS,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,MAAM,GAAG,MAAM,CAEhF;AAED,MAAM,WAAW,uBAAuB;IACtC,QAAQ,CAAC,EAAE,MAAM,GAAG,MAAM,EAAE,CAAC;IAC7B,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,kGAAkG;IAClG,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CAClC;AAED;;;GAGG;AACH,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,GAAE,uBAA4B,GAAG,OAAO,CAAC,SAAS,CAAC,CAwCzG"}
@@ -34,7 +34,21 @@ export function buildClientUserAgent(component, version) {
34
34
  export function connectWebSocket(wsUrl, options = {}) {
35
35
  const { protocol, timeout = 30_000, headers } = options;
36
36
  return new Promise((resolve, reject) => {
37
- const ws = new WebSocket(wsUrl, protocol, {
37
+ // `protocol ?? []` normalizes "no role asked for" to the empty list. It is
38
+ // defensive only: both runtimes this reaches already collapse an explicit
39
+ // `undefined` to the same thing, so neither offers a subprotocol that was
40
+ // never requested. A browser applies the WebIDL default (`protocols` is
41
+ // optional with default `[]`, and an explicit `undefined` selects it), and
42
+ // isomorphic-ws hands browsers the native WebSocket. Node takes `ws`, which
43
+ // maps `undefined` to `[]` before building the header (websocket.js: `if
44
+ // (protocols === undefined) protocols = []`).
45
+ //
46
+ // What does break a handshake is a *string* naming a role the server does
47
+ // not implement: it answers without echoing a subprotocol, the client fails
48
+ // the handshake, and it reads as a dead dev server rather than a bad offer.
49
+ // `??` cannot catch that - a string is not nullish - so a caller that
50
+ // stringifies its own value still offers the bogus role.
51
+ const ws = new WebSocket(wsUrl, protocol ?? [], {
38
52
  maxPayload: MAX_SOCKET_PAYLOAD_BYTES,
39
53
  headers: { 'User-Agent': DEFAULT_WEBSOCKET_USER_AGENT, ...headers }
40
54
  });
@@ -1 +1 @@
1
- {"version":3,"file":"util.js","sourceRoot":"","sources":["../../src/socket/util.ts"],"names":[],"mappings":"AAAA,OAAO,SAAS,MAAM,eAAe,CAAC;AAEtC;;;;;;;;;GASG;AACH,MAAM,CAAC,MAAM,wBAAwB,GAAG,GAAG,GAAG,IAAI,GAAG,IAAI,CAAC;AAE1D;;;;;;;GAOG;AACH,MAAM,CAAC,MAAM,4BAA4B,GAAG,oBAAoB,CAAC;AAEjE;;;;GAIG;AACH,MAAM,UAAU,oBAAoB,CAAC,SAAiB,EAAE,OAAgB;IACtE,OAAO,OAAO,CAAC,CAAC,CAAC,GAAG,SAAS,IAAI,OAAO,EAAE,CAAC,CAAC,CAAC,SAAS,CAAC;AACzD,CAAC;AASD;;;GAGG;AACH,MAAM,UAAU,gBAAgB,CAAC,KAAa,EAAE,UAAmC,EAAE;IACnF,MAAM,EAAE,QAAQ,EAAE,OAAO,GAAG,MAAM,EAAE,OAAO,EAAE,GAAG,OAAO,CAAC;IACxD,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;QACrC,MAAM,EAAE,GAAG,IAAI,SAAS,CAAC,KAAK,EAAE,QAAQ,EAAE;YACxC,UAAU,EAAE,wBAAwB;YACpC,OAAO,EAAE,EAAE,YAAY,EAAE,4BAA4B,EAAE,GAAG,OAAO,EAAE;SACpE,CAAC,CAAC;QAEH,MAAM,SAAS,GAAG,UAAU,CAAC,GAAG,EAAE;YAChC,MAAM,CAAC,IAAI,KAAK,CAAC,yCAAyC,CAAC,CAAC,CAAC;QAC/D,CAAC,EAAE,OAAO,CAAC,CAAC;QAEZ,EAAE,CAAC,gBAAgB,CAAC,MAAM,EAAE,GAAG,EAAE;YAC/B,YAAY,CAAC,SAAS,CAAC,CAAC;YACxB,8EAA8E;YAC9E,OAAO,CAAC,EAAE,CAAC,CAAC;QACd,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,gBAAgB,CAAC,OAAO,EAAE,CAAC,KAAK,EAAE,EAAE;YACrC,YAAY,CAAC,SAAS,CAAC,CAAC;YACxB,4EAA4E;YAC5E,2EAA2E;YAC3E,MAAM,OAAO,GAAG,SAAS,IAAI,KAAK,IAAI,OAAO,KAAK,CAAC,OAAO,KAAK,QAAQ,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,6BAA6B,CAAC;YACxH,MAAM,CAAC,IAAI,KAAK,CAAC,cAAc,OAAO,EAAE,CAAC,CAAC,CAAC;QAC7C,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;AACL,CAAC"}
1
+ {"version":3,"file":"util.js","sourceRoot":"","sources":["../../src/socket/util.ts"],"names":[],"mappings":"AAAA,OAAO,SAAS,MAAM,eAAe,CAAC;AAEtC;;;;;;;;;GASG;AACH,MAAM,CAAC,MAAM,wBAAwB,GAAG,GAAG,GAAG,IAAI,GAAG,IAAI,CAAC;AAE1D;;;;;;;GAOG;AACH,MAAM,CAAC,MAAM,4BAA4B,GAAG,oBAAoB,CAAC;AAEjE;;;;GAIG;AACH,MAAM,UAAU,oBAAoB,CAAC,SAAiB,EAAE,OAAgB;IACtE,OAAO,OAAO,CAAC,CAAC,CAAC,GAAG,SAAS,IAAI,OAAO,EAAE,CAAC,CAAC,CAAC,SAAS,CAAC;AACzD,CAAC;AASD;;;GAGG;AACH,MAAM,UAAU,gBAAgB,CAAC,KAAa,EAAE,UAAmC,EAAE;IACnF,MAAM,EAAE,QAAQ,EAAE,OAAO,GAAG,MAAM,EAAE,OAAO,EAAE,GAAG,OAAO,CAAC;IACxD,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;QACrC,2EAA2E;QAC3E,0EAA0E;QAC1E,0EAA0E;QAC1E,wEAAwE;QACxE,2EAA2E;QAC3E,4EAA4E;QAC5E,yEAAyE;QACzE,8CAA8C;QAC9C,EAAE;QACF,0EAA0E;QAC1E,4EAA4E;QAC5E,4EAA4E;QAC5E,sEAAsE;QACtE,yDAAyD;QACzD,MAAM,EAAE,GAAG,IAAI,SAAS,CAAC,KAAK,EAAE,QAAQ,IAAI,EAAE,EAAE;YAC9C,UAAU,EAAE,wBAAwB;YACpC,OAAO,EAAE,EAAE,YAAY,EAAE,4BAA4B,EAAE,GAAG,OAAO,EAAE;SACpE,CAAC,CAAC;QAEH,MAAM,SAAS,GAAG,UAAU,CAAC,GAAG,EAAE;YAChC,MAAM,CAAC,IAAI,KAAK,CAAC,yCAAyC,CAAC,CAAC,CAAC;QAC/D,CAAC,EAAE,OAAO,CAAC,CAAC;QAEZ,EAAE,CAAC,gBAAgB,CAAC,MAAM,EAAE,GAAG,EAAE;YAC/B,YAAY,CAAC,SAAS,CAAC,CAAC;YACxB,8EAA8E;YAC9E,OAAO,CAAC,EAAE,CAAC,CAAC;QACd,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,gBAAgB,CAAC,OAAO,EAAE,CAAC,KAAK,EAAE,EAAE;YACrC,YAAY,CAAC,SAAS,CAAC,CAAC;YACxB,4EAA4E;YAC5E,2EAA2E;YAC3E,MAAM,OAAO,GAAG,SAAS,IAAI,KAAK,IAAI,OAAO,KAAK,CAAC,OAAO,KAAK,QAAQ,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,6BAA6B,CAAC;YACxH,MAAM,CAAC,IAAI,KAAK,CAAC,cAAc,OAAO,EAAE,CAAC,CAAC,CAAC;QAC7C,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;AACL,CAAC"}
@@ -24,14 +24,14 @@ describe('connectWebSocket User-Agent', () => {
24
24
  });
25
25
  it('sends a default User-Agent and preserves maxPayload on the handshake', () => {
26
26
  void connectWebSocket('wss://example.com/api/v1/rpc-ws');
27
- expect(constructorSpy).toHaveBeenCalledWith('wss://example.com/api/v1/rpc-ws', undefined, expect.objectContaining({
27
+ expect(constructorSpy).toHaveBeenCalledWith('wss://example.com/api/v1/rpc-ws', [], expect.objectContaining({
28
28
  maxPayload: MAX_SOCKET_PAYLOAD_BYTES,
29
29
  headers: expect.objectContaining({ 'User-Agent': DEFAULT_WEBSOCKET_USER_AGENT })
30
30
  }));
31
31
  });
32
32
  it('lets callers override the User-Agent via options.headers', () => {
33
33
  void connectWebSocket('wss://example.com/api/v1/rpc-ws', { headers: { 'User-Agent': 'superblocks-cli/9.9.9' } });
34
- expect(constructorSpy).toHaveBeenCalledWith('wss://example.com/api/v1/rpc-ws', undefined, expect.objectContaining({
34
+ expect(constructorSpy).toHaveBeenCalledWith('wss://example.com/api/v1/rpc-ws', [], expect.objectContaining({
35
35
  headers: expect.objectContaining({ 'User-Agent': 'superblocks-cli/9.9.9' })
36
36
  }));
37
37
  });
@@ -39,6 +39,16 @@ describe('connectWebSocket User-Agent', () => {
39
39
  void connectWebSocket('wss://example.com/api/v1/rpc-ws', { protocol: 'editor' });
40
40
  expect(constructorSpy).toHaveBeenCalledWith('wss://example.com/api/v1/rpc-ws', 'editor', expect.anything());
41
41
  });
42
+ it('offers no subprotocol at all when the caller asked for none', () => {
43
+ // A browser turns an explicit `undefined` here into the literal string
44
+ // "undefined" on the wire, so a caller that wanted no role ends up offering
45
+ // one no server implements. An empty list is the only value that reaches the
46
+ // handshake as "no subprotocol offered".
47
+ void connectWebSocket('wss://example.com/api/v1/rpc-ws');
48
+ const [, protocol] = constructorSpy.mock.calls[0];
49
+ expect(protocol).toEqual([]);
50
+ expect(protocol).not.toBeUndefined();
51
+ });
42
52
  });
43
53
  describe('buildClientUserAgent', () => {
44
54
  it('joins component and version with a slash', () => {
@@ -1 +1 @@
1
- {"version":3,"file":"util.test.js","sourceRoot":"","sources":["../../src/socket/util.test.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,UAAU,EAAE,QAAQ,EAAE,MAAM,EAAE,EAAE,EAAE,EAAE,EAAE,MAAM,QAAQ,CAAC;AAEzE,OAAO,EAAE,oBAAoB,EAAE,gBAAgB,EAAE,4BAA4B,EAAE,wBAAwB,EAAE,MAAM,WAAW,CAAC;AAE3H,MAAM,cAAc,GAAG,EAAE,CAAC,EAAE,EAAE,CAAC;AAE/B,oFAAoF;AACpF,mFAAmF;AACnF,EAAE,CAAC,IAAI,CAAC,eAAe,EAAE,GAAG,EAAE,CAAC,CAAC;IAC9B,OAAO,EAAE,MAAM,aAAa;QAC1B,YAAY,GAAW,EAAE,QAAiB,EAAE,OAAgB;YAC1D,cAAc,CAAC,GAAG,EAAE,QAAQ,EAAE,OAAO,CAAC,CAAC;QACzC,CAAC;QACD,gBAAgB;YACd,+EAA+E;QACjF,CAAC;KACF;CACF,CAAC,CAAC,CAAC;AAEJ,QAAQ,CAAC,6BAA6B,EAAE,GAAG,EAAE;IAC3C,UAAU,CAAC,GAAG,EAAE;QACd,EAAE,CAAC,aAAa,EAAE,CAAC;QACnB,cAAc,CAAC,SAAS,EAAE,CAAC;IAC7B,CAAC,CAAC,CAAC;IAEH,SAAS,CAAC,GAAG,EAAE;QACb,EAAE,CAAC,cAAc,EAAE,CAAC;QACpB,EAAE,CAAC,aAAa,EAAE,CAAC;IACrB,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,sEAAsE,EAAE,GAAG,EAAE;QAC9E,KAAK,gBAAgB,CAAC,iCAAiC,CAAC,CAAC;QAEzD,MAAM,CAAC,cAAc,CAAC,CAAC,oBAAoB,CACzC,iCAAiC,EACjC,SAAS,EACT,MAAM,CAAC,gBAAgB,CAAC;YACtB,UAAU,EAAE,wBAAwB;YACpC,OAAO,EAAE,MAAM,CAAC,gBAAgB,CAAC,EAAE,YAAY,EAAE,4BAA4B,EAAE,CAAC;SACjF,CAAC,CACH,CAAC;IACJ,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,0DAA0D,EAAE,GAAG,EAAE;QAClE,KAAK,gBAAgB,CAAC,iCAAiC,EAAE,EAAE,OAAO,EAAE,EAAE,YAAY,EAAE,uBAAuB,EAAE,EAAE,CAAC,CAAC;QAEjH,MAAM,CAAC,cAAc,CAAC,CAAC,oBAAoB,CACzC,iCAAiC,EACjC,SAAS,EACT,MAAM,CAAC,gBAAgB,CAAC;YACtB,OAAO,EAAE,MAAM,CAAC,gBAAgB,CAAC,EAAE,YAAY,EAAE,uBAAuB,EAAE,CAAC;SAC5E,CAAC,CACH,CAAC;IACJ,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,wDAAwD,EAAE,GAAG,EAAE;QAChE,KAAK,gBAAgB,CAAC,iCAAiC,EAAE,EAAE,QAAQ,EAAE,QAAQ,EAAE,CAAC,CAAC;QAEjF,MAAM,CAAC,cAAc,CAAC,CAAC,oBAAoB,CAAC,iCAAiC,EAAE,QAAQ,EAAE,MAAM,CAAC,QAAQ,EAAE,CAAC,CAAC;IAC9G,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC;AAEH,QAAQ,CAAC,sBAAsB,EAAE,GAAG,EAAE;IACpC,EAAE,CAAC,0CAA0C,EAAE,GAAG,EAAE;QAClD,MAAM,CAAC,oBAAoB,CAAC,iBAAiB,EAAE,cAAc,CAAC,CAAC,CAAC,IAAI,CAAC,8BAA8B,CAAC,CAAC;IACvG,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,qDAAqD,EAAE,GAAG,EAAE;QAC7D,MAAM,CAAC,oBAAoB,CAAC,wBAAwB,CAAC,CAAC,CAAC,IAAI,CAAC,wBAAwB,CAAC,CAAC;IACxF,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC"}
1
+ {"version":3,"file":"util.test.js","sourceRoot":"","sources":["../../src/socket/util.test.ts"],"names":[],"mappings":"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"}
@@ -53,9 +53,12 @@ export interface AiResolveAttachmentLeasesResponse {
53
53
  * System event trigger types for AI operations without prompt_id
54
54
  */
55
55
  export declare enum AiSystemTriggerType {
56
+ API_USAGE_SUMMARY = "api_usage_summary",
56
57
  APP_NAME = "app_name",
58
+ ATTACHMENT_LABEL = "attachment_label",
57
59
  COMMIT_MESSAGE = "commit_message",
58
60
  DASHBOARD_CHAT = "dashboard_chat",
61
+ ERROR_SUMMARY = "error_summary",
59
62
  FACT_METADATA = "fact_metadata",
60
63
  PR_DESCRIPTION = "pr_description"
61
64
  }
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/types/ai/index.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/types/ai/index.ts"],"names":[],"mappings":"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"}
@@ -3,9 +3,12 @@
3
3
  */
4
4
  export var AiSystemTriggerType;
5
5
  (function (AiSystemTriggerType) {
6
+ AiSystemTriggerType["API_USAGE_SUMMARY"] = "api_usage_summary";
6
7
  AiSystemTriggerType["APP_NAME"] = "app_name";
8
+ AiSystemTriggerType["ATTACHMENT_LABEL"] = "attachment_label";
7
9
  AiSystemTriggerType["COMMIT_MESSAGE"] = "commit_message";
8
10
  AiSystemTriggerType["DASHBOARD_CHAT"] = "dashboard_chat";
11
+ AiSystemTriggerType["ERROR_SUMMARY"] = "error_summary";
9
12
  AiSystemTriggerType["FACT_METADATA"] = "fact_metadata";
10
13
  AiSystemTriggerType["PR_DESCRIPTION"] = "pr_description";
11
14
  })(AiSystemTriggerType || (AiSystemTriggerType = {}));
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/types/ai/index.ts"],"names":[],"mappings":"AA0DA;;GAEG;AACH,MAAM,CAAN,IAAY,mBAMX;AAND,WAAY,mBAAmB;IAC7B,4CAAqB,CAAA;IACrB,wDAAiC,CAAA;IACjC,wDAAiC,CAAA;IACjC,sDAA+B,CAAA;IAC/B,wDAAiC,CAAA;AACnC,CAAC,EANW,mBAAmB,KAAnB,mBAAmB,QAM9B;AA6DD,cAAc,0BAA0B,CAAC;AACzC,cAAc,oBAAoB,CAAC;AACnC,cAAc,4BAA4B,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/types/ai/index.ts"],"names":[],"mappings":"AA0DA;;GAEG;AACH,MAAM,CAAN,IAAY,mBASX;AATD,WAAY,mBAAmB;IAC7B,8DAAuC,CAAA;IACvC,4CAAqB,CAAA;IACrB,4DAAqC,CAAA;IACrC,wDAAiC,CAAA;IACjC,wDAAiC,CAAA;IACjC,sDAA+B,CAAA;IAC/B,sDAA+B,CAAA;IAC/B,wDAAiC,CAAA;AACnC,CAAC,EATW,mBAAmB,KAAnB,mBAAmB,QAS9B;AA6DD,cAAc,0BAA0B,CAAC;AACzC,cAAc,oBAAoB,CAAC;AACnC,cAAc,4BAA4B,CAAC"}