@hydranium/protocol 1.0.0-next.10

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 (254) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +81 -0
  3. package/lib/abstract-logger.d.ts +66 -0
  4. package/lib/abstract-logger.d.ts.map +1 -0
  5. package/lib/abstract-logger.js +110 -0
  6. package/lib/abstract-logger.js.map +1 -0
  7. package/lib/browser-runtime.d.ts +124 -0
  8. package/lib/browser-runtime.d.ts.map +1 -0
  9. package/lib/browser-runtime.js +11 -0
  10. package/lib/browser-runtime.js.map +1 -0
  11. package/lib/client/data-events.d.ts +49 -0
  12. package/lib/client/data-events.d.ts.map +1 -0
  13. package/lib/client/data-events.js +60 -0
  14. package/lib/client/data-events.js.map +1 -0
  15. package/lib/client/data-port.d.ts +95 -0
  16. package/lib/client/data-port.d.ts.map +1 -0
  17. package/lib/client/data-port.js +11 -0
  18. package/lib/client/data-port.js.map +1 -0
  19. package/lib/client/data-session.d.ts +129 -0
  20. package/lib/client/data-session.d.ts.map +1 -0
  21. package/lib/client/data-session.js +179 -0
  22. package/lib/client/data-session.js.map +1 -0
  23. package/lib/client/index.d.ts +39 -0
  24. package/lib/client/index.d.ts.map +1 -0
  25. package/lib/client/index.js +55 -0
  26. package/lib/client/index.js.map +1 -0
  27. package/lib/client/message-relay.d.ts +111 -0
  28. package/lib/client/message-relay.d.ts.map +1 -0
  29. package/lib/client/message-relay.js +139 -0
  30. package/lib/client/message-relay.js.map +1 -0
  31. package/lib/client/post-message-transport.d.ts +77 -0
  32. package/lib/client/post-message-transport.d.ts.map +1 -0
  33. package/lib/client/post-message-transport.js +95 -0
  34. package/lib/client/post-message-transport.js.map +1 -0
  35. package/lib/clock.d.ts +111 -0
  36. package/lib/clock.d.ts.map +1 -0
  37. package/lib/clock.js +74 -0
  38. package/lib/clock.js.map +1 -0
  39. package/lib/data/data-protocol-methods.d.ts +39 -0
  40. package/lib/data/data-protocol-methods.d.ts.map +1 -0
  41. package/lib/data/data-protocol-methods.js +61 -0
  42. package/lib/data/data-protocol-methods.js.map +1 -0
  43. package/lib/data/data-server-protocol.d.ts +264 -0
  44. package/lib/data/data-server-protocol.d.ts.map +1 -0
  45. package/lib/data/data-server-protocol.js +11 -0
  46. package/lib/data/data-server-protocol.js.map +1 -0
  47. package/lib/data/diagnostics.d.ts +97 -0
  48. package/lib/data/diagnostics.d.ts.map +1 -0
  49. package/lib/data/diagnostics.js +25 -0
  50. package/lib/data/diagnostics.js.map +1 -0
  51. package/lib/data/events.d.ts +107 -0
  52. package/lib/data/events.d.ts.map +1 -0
  53. package/lib/data/events.js +11 -0
  54. package/lib/data/events.js.map +1 -0
  55. package/lib/data/index.d.ts +15 -0
  56. package/lib/data/index.d.ts.map +1 -0
  57. package/lib/data/index.js +38 -0
  58. package/lib/data/index.js.map +1 -0
  59. package/lib/data/methods.d.ts +57 -0
  60. package/lib/data/methods.d.ts.map +1 -0
  61. package/lib/data/methods.js +60 -0
  62. package/lib/data/methods.js.map +1 -0
  63. package/lib/data/requests.d.ts +65 -0
  64. package/lib/data/requests.d.ts.map +1 -0
  65. package/lib/data/requests.js +11 -0
  66. package/lib/data/requests.js.map +1 -0
  67. package/lib/debouncer.d.ts +75 -0
  68. package/lib/debouncer.d.ts.map +1 -0
  69. package/lib/debouncer.js +91 -0
  70. package/lib/debouncer.js.map +1 -0
  71. package/lib/errors.d.ts +84 -0
  72. package/lib/errors.d.ts.map +1 -0
  73. package/lib/errors.js +113 -0
  74. package/lib/errors.js.map +1 -0
  75. package/lib/host-diagnostics.d.ts +58 -0
  76. package/lib/host-diagnostics.d.ts.map +1 -0
  77. package/lib/host-diagnostics.js +18 -0
  78. package/lib/host-diagnostics.js.map +1 -0
  79. package/lib/index.d.ts +34 -0
  80. package/lib/index.d.ts.map +1 -0
  81. package/lib/index.js +56 -0
  82. package/lib/index.js.map +1 -0
  83. package/lib/latency-collector.d.ts +126 -0
  84. package/lib/latency-collector.d.ts.map +1 -0
  85. package/lib/latency-collector.js +137 -0
  86. package/lib/latency-collector.js.map +1 -0
  87. package/lib/logger.d.ts +119 -0
  88. package/lib/logger.d.ts.map +1 -0
  89. package/lib/logger.js +126 -0
  90. package/lib/logger.js.map +1 -0
  91. package/lib/model-server.d.ts +352 -0
  92. package/lib/model-server.d.ts.map +1 -0
  93. package/lib/model-server.js +160 -0
  94. package/lib/model-server.js.map +1 -0
  95. package/lib/model-service/args.d.ts +64 -0
  96. package/lib/model-service/args.d.ts.map +1 -0
  97. package/lib/model-service/args.js +11 -0
  98. package/lib/model-service/args.js.map +1 -0
  99. package/lib/model-service/index.d.ts +11 -0
  100. package/lib/model-service/index.d.ts.map +1 -0
  101. package/lib/model-service/index.js +31 -0
  102. package/lib/model-service/index.js.map +1 -0
  103. package/lib/model-service/reference-candidate.d.ts +56 -0
  104. package/lib/model-service/reference-candidate.d.ts.map +1 -0
  105. package/lib/model-service/reference-candidate.js +11 -0
  106. package/lib/model-service/reference-candidate.js.map +1 -0
  107. package/lib/noop-logger.d.ts +25 -0
  108. package/lib/noop-logger.d.ts.map +1 -0
  109. package/lib/noop-logger.js +36 -0
  110. package/lib/noop-logger.js.map +1 -0
  111. package/lib/observable-value.d.ts +72 -0
  112. package/lib/observable-value.d.ts.map +1 -0
  113. package/lib/observable-value.js +52 -0
  114. package/lib/observable-value.js.map +1 -0
  115. package/lib/patch-merge.d.ts +123 -0
  116. package/lib/patch-merge.d.ts.map +1 -0
  117. package/lib/patch-merge.js +104 -0
  118. package/lib/patch-merge.js.map +1 -0
  119. package/lib/profile-session.d.ts +87 -0
  120. package/lib/profile-session.d.ts.map +1 -0
  121. package/lib/profile-session.js +98 -0
  122. package/lib/profile-session.js.map +1 -0
  123. package/lib/profiling.d.ts +83 -0
  124. package/lib/profiling.d.ts.map +1 -0
  125. package/lib/profiling.js +20 -0
  126. package/lib/profiling.js.map +1 -0
  127. package/lib/project.d.ts +121 -0
  128. package/lib/project.d.ts.map +1 -0
  129. package/lib/project.js +34 -0
  130. package/lib/project.js.map +1 -0
  131. package/lib/rpc/bind-rpc-methods.d.ts +100 -0
  132. package/lib/rpc/bind-rpc-methods.d.ts.map +1 -0
  133. package/lib/rpc/bind-rpc-methods.js +110 -0
  134. package/lib/rpc/bind-rpc-methods.js.map +1 -0
  135. package/lib/rpc/create-rpc-proxy.d.ts +188 -0
  136. package/lib/rpc/create-rpc-proxy.d.ts.map +1 -0
  137. package/lib/rpc/create-rpc-proxy.js +158 -0
  138. package/lib/rpc/create-rpc-proxy.js.map +1 -0
  139. package/lib/rpc/index.d.ts +12 -0
  140. package/lib/rpc/index.d.ts.map +1 -0
  141. package/lib/rpc/index.js +31 -0
  142. package/lib/rpc/index.js.map +1 -0
  143. package/lib/rpc/wire-prefix.d.ts +37 -0
  144. package/lib/rpc/wire-prefix.d.ts.map +1 -0
  145. package/lib/rpc/wire-prefix.js +49 -0
  146. package/lib/rpc/wire-prefix.js.map +1 -0
  147. package/lib/testing/data-doubles.d.ts +121 -0
  148. package/lib/testing/data-doubles.d.ts.map +1 -0
  149. package/lib/testing/data-doubles.js +102 -0
  150. package/lib/testing/data-doubles.js.map +1 -0
  151. package/lib/testing/fake-clock.d.ts +35 -0
  152. package/lib/testing/fake-clock.d.ts.map +1 -0
  153. package/lib/testing/fake-clock.js +86 -0
  154. package/lib/testing/fake-clock.js.map +1 -0
  155. package/lib/testing/harness.d.ts +24 -0
  156. package/lib/testing/harness.d.ts.map +1 -0
  157. package/lib/testing/harness.js +11 -0
  158. package/lib/testing/harness.js.map +1 -0
  159. package/lib/testing/index.d.ts +13 -0
  160. package/lib/testing/index.d.ts.map +1 -0
  161. package/lib/testing/index.js +41 -0
  162. package/lib/testing/index.js.map +1 -0
  163. package/lib/testing/node/duplex-connection.d.ts +25 -0
  164. package/lib/testing/node/duplex-connection.d.ts.map +1 -0
  165. package/lib/testing/node/duplex-connection.js +34 -0
  166. package/lib/testing/node/duplex-connection.js.map +1 -0
  167. package/lib/testing/node/duplex-stream.d.ts +32 -0
  168. package/lib/testing/node/duplex-stream.d.ts.map +1 -0
  169. package/lib/testing/node/duplex-stream.js +35 -0
  170. package/lib/testing/node/duplex-stream.js.map +1 -0
  171. package/lib/testing/node/index.d.ts +11 -0
  172. package/lib/testing/node/index.d.ts.map +1 -0
  173. package/lib/testing/node/index.js +37 -0
  174. package/lib/testing/node/index.js.map +1 -0
  175. package/lib/testing/wait-for.d.ts +69 -0
  176. package/lib/testing/wait-for.d.ts.map +1 -0
  177. package/lib/testing/wait-for.js +67 -0
  178. package/lib/testing/wait-for.js.map +1 -0
  179. package/lib/tracer.d.ts +115 -0
  180. package/lib/tracer.d.ts.map +1 -0
  181. package/lib/tracer.js +205 -0
  182. package/lib/tracer.js.map +1 -0
  183. package/lib/transfer-diagnostic.d.ts +73 -0
  184. package/lib/transfer-diagnostic.d.ts.map +1 -0
  185. package/lib/transfer-diagnostic.js +45 -0
  186. package/lib/transfer-diagnostic.js.map +1 -0
  187. package/lib/transfer-document.d.ts +73 -0
  188. package/lib/transfer-document.d.ts.map +1 -0
  189. package/lib/transfer-document.js +46 -0
  190. package/lib/transfer-document.js.map +1 -0
  191. package/lib/transfer-element.d.ts +39 -0
  192. package/lib/transfer-element.d.ts.map +1 -0
  193. package/lib/transfer-element.js +11 -0
  194. package/lib/transfer-element.js.map +1 -0
  195. package/lib/uri.d.ts +62 -0
  196. package/lib/uri.d.ts.map +1 -0
  197. package/lib/uri.js +28 -0
  198. package/lib/uri.js.map +1 -0
  199. package/lib/util.d.ts +147 -0
  200. package/lib/util.d.ts.map +1 -0
  201. package/lib/util.js +211 -0
  202. package/lib/util.js.map +1 -0
  203. package/package.json +100 -0
  204. package/src/abstract-logger.ts +120 -0
  205. package/src/browser-runtime.ts +135 -0
  206. package/src/client/data-events.ts +71 -0
  207. package/src/client/data-port.ts +99 -0
  208. package/src/client/data-session.ts +209 -0
  209. package/src/client/index.ts +40 -0
  210. package/src/client/message-relay.ts +216 -0
  211. package/src/client/post-message-transport.ts +167 -0
  212. package/src/clock.ts +173 -0
  213. package/src/data/data-protocol-methods.ts +79 -0
  214. package/src/data/data-server-protocol.ts +296 -0
  215. package/src/data/diagnostics.ts +116 -0
  216. package/src/data/events.ts +127 -0
  217. package/src/data/index.ts +23 -0
  218. package/src/data/methods.ts +59 -0
  219. package/src/data/requests.ts +70 -0
  220. package/src/debouncer.ts +118 -0
  221. package/src/errors.ts +127 -0
  222. package/src/host-diagnostics.ts +63 -0
  223. package/src/index.ts +41 -0
  224. package/src/latency-collector.ts +231 -0
  225. package/src/logger.ts +172 -0
  226. package/src/model-server.ts +479 -0
  227. package/src/model-service/args.ts +67 -0
  228. package/src/model-service/index.ts +16 -0
  229. package/src/model-service/reference-candidate.ts +58 -0
  230. package/src/noop-logger.ts +36 -0
  231. package/src/observable-value.ts +92 -0
  232. package/src/patch-merge.ts +165 -0
  233. package/src/profile-session.ts +164 -0
  234. package/src/profiling.ts +113 -0
  235. package/src/project.ts +125 -0
  236. package/src/rpc/README.md +163 -0
  237. package/src/rpc/bind-rpc-methods.ts +180 -0
  238. package/src/rpc/create-rpc-proxy.ts +292 -0
  239. package/src/rpc/index.ts +16 -0
  240. package/src/rpc/wire-prefix.ts +48 -0
  241. package/src/testing/data-doubles.ts +178 -0
  242. package/src/testing/fake-clock.ts +106 -0
  243. package/src/testing/harness.ts +24 -0
  244. package/src/testing/index.ts +26 -0
  245. package/src/testing/node/duplex-connection.ts +50 -0
  246. package/src/testing/node/duplex-stream.ts +51 -0
  247. package/src/testing/node/index.ts +22 -0
  248. package/src/testing/wait-for.ts +94 -0
  249. package/src/tracer.ts +277 -0
  250. package/src/transfer-diagnostic.ts +92 -0
  251. package/src/transfer-document.ts +99 -0
  252. package/src/transfer-element.ts +43 -0
  253. package/src/uri.ts +61 -0
  254. package/src/util.ts +250 -0
@@ -0,0 +1,102 @@
1
+ "use strict";
2
+ /********************************************************************************
3
+ * Copyright (c) 2026 CrossBreeze, EclipseSource and others.
4
+ *
5
+ * This program and the accompanying materials are made available under the
6
+ * terms of the MIT License which is available in the project root.
7
+ *
8
+ * SPDX-License-Identifier: MIT
9
+ ********************************************************************************/
10
+ Object.defineProperty(exports, "__esModule", { value: true });
11
+ exports.makeFakeDataPort = makeFakeDataPort;
12
+ exports.makeCapturingDataClient = makeCapturingDataClient;
13
+ /**
14
+ * The two CLIENT-side doubles of the data head: a {@link DataPort} whose
15
+ * transport the test supplies, and a {@link DataClientProtocol} that records
16
+ * what arrived.
17
+ *
18
+ * # Why standalone, when a harness already builds one
19
+ *
20
+ * `makeDataServerHarness` builds a capturing client too, but fused into a
21
+ * server-bearing harness: taking it means taking a duplex pair, a `DataServer`
22
+ * and a proxy. That is the right shape for testing the server. It is the wrong
23
+ * shape — and not available at all — for testing the CLIENT half: a
24
+ * `DataSession`, a widget model, a host's port adapter. Those need to stand a
25
+ * double on one side of the boundary and something else entirely on the other,
26
+ * which is why both halves get hand-rolled per suite instead.
27
+ *
28
+ * # Runner-agnostic, deliberately
29
+ *
30
+ * No `jest.fn`, no `vi.fn`, no `expect`. The recorded arrays ARE the assertion
31
+ * surface, so the same double works under vitest, jest and a bare script. A
32
+ * mock-framework double would also make "was it called" the observable, when
33
+ * what a data-head test actually asserts is the CONTENT of what arrived —
34
+ * which `sourceClientId`, which version, which reason.
35
+ */
36
+ const vscode_jsonrpc_1 = require("vscode-jsonrpc");
37
+ /**
38
+ * A {@link DataPort} over a transport the caller supplies.
39
+ *
40
+ * It deliberately does not create the transport itself. What varies between the
41
+ * cases worth testing is exactly that: an in-process duplex pair, a socket, a
42
+ * connection with no server behind it, a different one per generation.
43
+ */
44
+ function makeFakeDataPort(options) {
45
+ const connections = [];
46
+ const reported = [];
47
+ const disposeEmitter = new vscode_jsonrpc_1.Emitter();
48
+ return {
49
+ clientId: options.clientId ?? 'fake-data-port',
50
+ connections,
51
+ reported,
52
+ onDispose: disposeEmitter.event,
53
+ async connect() {
54
+ const connection = await options.connect();
55
+ connections.push(connection);
56
+ return connection;
57
+ },
58
+ reportError(error, context) {
59
+ reported.push({ error, context });
60
+ },
61
+ fireDispose() {
62
+ disposeEmitter.fire(undefined);
63
+ },
64
+ dispose() {
65
+ disposeEmitter.dispose();
66
+ }
67
+ };
68
+ }
69
+ /**
70
+ * A {@link DataClientProtocol} that records every notification it receives.
71
+ *
72
+ * Recording ALL THREE channels even when a suite reads one is deliberate: an
73
+ * event delivered on the wrong channel is a real defect of the data head, and a
74
+ * double that drops the other two turns it into silence on the one being
75
+ * watched.
76
+ *
77
+ * An override replaces a channel's recording rather than supplementing it, so
78
+ * the corresponding array stays empty — that is what makes an override usable
79
+ * as a barrier (rejecting, counting differently, throwing) rather than only as
80
+ * a spy.
81
+ */
82
+ function makeCapturingDataClient(overrides = {}) {
83
+ const updates = [];
84
+ const saves = [];
85
+ const projectsChanges = [];
86
+ const client = {
87
+ onDocumentUpdated: overrides.onDocumentUpdated ??
88
+ (event => {
89
+ updates.push(event);
90
+ }),
91
+ onDocumentSaved: overrides.onDocumentSaved ??
92
+ (event => {
93
+ saves.push(event);
94
+ }),
95
+ onProjectsChanged: overrides.onProjectsChanged ??
96
+ (event => {
97
+ projectsChanges.push(event);
98
+ })
99
+ };
100
+ return { client, updates, saves, projectsChanges };
101
+ }
102
+ //# sourceMappingURL=data-doubles.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"data-doubles.js","sourceRoot":"","sources":["../../src/testing/data-doubles.ts"],"names":[],"mappings":";AAAA;;;;;;;kFAOkF;;AAyFlF,4CAwBC;AA+BD,0DA0BC;AAxKD;;;;;;;;;;;;;;;;;;;;;;GAsBG;AAEH,mDAAiE;AAwDjE;;;;;;GAMG;AACH,SAAgB,gBAAgB,CAAC,OAA4B;IAC1D,MAAM,WAAW,GAAwB,EAAE,CAAC;IAC5C,MAAM,QAAQ,GAA0C,EAAE,CAAC;IAC3D,MAAM,cAAc,GAAG,IAAI,wBAAO,EAAQ,CAAC;IAC3C,OAAO;QACJ,QAAQ,EAAE,OAAO,CAAC,QAAQ,IAAI,gBAAgB;QAC9C,WAAW;QACX,QAAQ;QACR,SAAS,EAAE,cAAc,CAAC,KAAK;QAC/B,KAAK,CAAC,OAAO;YACV,MAAM,UAAU,GAAG,MAAM,OAAO,CAAC,OAAO,EAAE,CAAC;YAC3C,WAAW,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;YAC7B,OAAO,UAAU,CAAC;QACrB,CAAC;QACD,WAAW,CAAC,KAAc,EAAE,OAAe;YACxC,QAAQ,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,OAAO,EAAE,CAAC,CAAC;QACrC,CAAC;QACD,WAAW;YACR,cAAc,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;QAClC,CAAC;QACD,OAAO;YACJ,cAAc,CAAC,OAAO,EAAE,CAAC;QAC5B,CAAC;KACH,CAAC;AACL,CAAC;AAkBD;;;;;;;;;;;;GAYG;AACH,SAAgB,uBAAuB,CAIrC,YAA2E,EAAE;IAC5E,MAAM,OAAO,GAA2D,EAAE,CAAC;IAC3E,MAAM,KAAK,GAAyD,EAAE,CAAC;IACvE,MAAM,eAAe,GAAqC,EAAE,CAAC;IAC7D,MAAM,MAAM,GAAyD;QAClE,iBAAiB,EACd,SAAS,CAAC,iBAAiB;YAC3B,CAAC,KAAK,CAAC,EAAE;gBACN,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;YACvB,CAAC,CAAC;QACL,eAAe,EACZ,SAAS,CAAC,eAAe;YACzB,CAAC,KAAK,CAAC,EAAE;gBACN,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;YACrB,CAAC,CAAC;QACL,iBAAiB,EACd,SAAS,CAAC,iBAAiB;YAC3B,CAAC,KAAK,CAAC,EAAE;gBACN,eAAe,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;YAC/B,CAAC,CAAC;KACP,CAAC;IACF,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,KAAK,EAAE,eAAe,EAAE,CAAC;AACtD,CAAC"}
@@ -0,0 +1,35 @@
1
+ /********************************************************************************
2
+ * Copyright (c) 2026 CrossBreeze, EclipseSource and others.
3
+ *
4
+ * This program and the accompanying materials are made available under the
5
+ * terms of the MIT License which is available in the project root.
6
+ *
7
+ * SPDX-License-Identifier: MIT
8
+ ********************************************************************************/
9
+ import { type Clock } from '../clock';
10
+ /** A {@link Clock} whose time only moves when the test calls {@link FakeClock.advance}. */
11
+ export interface FakeClock extends Clock {
12
+ /**
13
+ * Move virtual time forward by `ms`, firing every {@link Clock.setTimer}
14
+ * whose deadline falls within the window — in chronological order, each at
15
+ * its own deadline (so `now()` inside a callback reads the fire instant, not
16
+ * the advance target). Timers scheduled by a callback fire too if they fall
17
+ * within the same window.
18
+ */
19
+ advance(ms: number): void;
20
+ }
21
+ /**
22
+ * In-process {@link Clock} double for deterministic time. The real
23
+ * `SystemClock` has two underlying sources
24
+ * (`Date.now` for `now()`, `performance.now()` for the stopwatch); the fake
25
+ * collapses them onto ONE virtual time axis, so a single
26
+ * {@link FakeClock.advance} drives `now()`, every live stopwatch's elapsed, and
27
+ * any due timer together.
28
+ *
29
+ * Server-free and DI-free — lives in `@hydranium/protocol/testing` so every
30
+ * head can bind it without pulling in a server package.
31
+ */
32
+ export declare function makeFakeClock(options?: {
33
+ now?: number;
34
+ }): FakeClock;
35
+ //# sourceMappingURL=fake-clock.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"fake-clock.d.ts","sourceRoot":"","sources":["../../src/testing/fake-clock.ts"],"names":[],"mappings":"AAAA;;;;;;;kFAOkF;AAElF,OAAO,EAAE,KAAK,KAAK,EAA8B,MAAM,UAAU,CAAC;AAGlE,2FAA2F;AAC3F,MAAM,WAAW,SAAU,SAAQ,KAAK;IACrC;;;;;;OAMG;IACH,OAAO,CAAC,EAAE,EAAE,MAAM,GAAG,IAAI,CAAC;CAC5B;AASD;;;;;;;;;;GAUG;AACH,wBAAgB,aAAa,CAAC,OAAO,GAAE;IAAE,GAAG,CAAC,EAAE,MAAM,CAAA;CAAO,GAAG,SAAS,CA+DvE"}
@@ -0,0 +1,86 @@
1
+ "use strict";
2
+ /********************************************************************************
3
+ * Copyright (c) 2026 CrossBreeze, EclipseSource and others.
4
+ *
5
+ * This program and the accompanying materials are made available under the
6
+ * terms of the MIT License which is available in the project root.
7
+ *
8
+ * SPDX-License-Identifier: MIT
9
+ ********************************************************************************/
10
+ Object.defineProperty(exports, "__esModule", { value: true });
11
+ exports.makeFakeClock = makeFakeClock;
12
+ const util_1 = require("../util");
13
+ /**
14
+ * In-process {@link Clock} double for deterministic time. The real
15
+ * `SystemClock` has two underlying sources
16
+ * (`Date.now` for `now()`, `performance.now()` for the stopwatch); the fake
17
+ * collapses them onto ONE virtual time axis, so a single
18
+ * {@link FakeClock.advance} drives `now()`, every live stopwatch's elapsed, and
19
+ * any due timer together.
20
+ *
21
+ * Server-free and DI-free — lives in `@hydranium/protocol/testing` so every
22
+ * head can bind it without pulling in a server package.
23
+ */
24
+ function makeFakeClock(options = {}) {
25
+ let current = options.now ?? 0;
26
+ const timers = [];
27
+ const makeStopwatch = () => {
28
+ const start = current;
29
+ let lastLap = current;
30
+ let stopped;
31
+ return {
32
+ get elapsedMs() {
33
+ return (stopped ?? current) - start;
34
+ },
35
+ lap() {
36
+ const at = stopped ?? current;
37
+ const split = at - lastLap;
38
+ lastLap = at;
39
+ return split;
40
+ },
41
+ stop() {
42
+ if (stopped === undefined) {
43
+ stopped = current;
44
+ }
45
+ return stopped - start;
46
+ }
47
+ };
48
+ };
49
+ return {
50
+ now: () => current,
51
+ setTimer(callback, ms) {
52
+ const timer = { at: current + ms, callback, disposed: false, fired: false };
53
+ timers.push(timer);
54
+ return util_1.Disposable.create(() => {
55
+ timer.disposed = true;
56
+ });
57
+ },
58
+ stopwatch: makeStopwatch,
59
+ measure: ((callback) => {
60
+ const stopwatch = makeStopwatch();
61
+ const result = callback();
62
+ if (result instanceof Promise) {
63
+ return result.then(value => ({ result: value, elapsedMs: stopwatch.elapsedMs }));
64
+ }
65
+ return { result: result, elapsedMs: stopwatch.elapsedMs };
66
+ }),
67
+ advance(ms) {
68
+ const target = current + ms;
69
+ // Fire due timers one at a time, re-scanning after each so a callback
70
+ // that schedules a nearer timer still fires within this window.
71
+ for (;;) {
72
+ const next = timers
73
+ .filter(timer => !timer.disposed && !timer.fired && timer.at <= target)
74
+ .sort((left, right) => left.at - right.at)[0];
75
+ if (!next) {
76
+ break;
77
+ }
78
+ current = next.at;
79
+ next.fired = true;
80
+ next.callback();
81
+ }
82
+ current = target;
83
+ }
84
+ };
85
+ }
86
+ //# sourceMappingURL=fake-clock.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"fake-clock.js","sourceRoot":"","sources":["../../src/testing/fake-clock.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,24 @@
1
+ /********************************************************************************
2
+ * Copyright (c) 2026 CrossBreeze, EclipseSource and others.
3
+ *
4
+ * This program and the accompanying materials are made available under the
5
+ * terms of the MIT License which is available in the project root.
6
+ *
7
+ * SPDX-License-Identifier: MIT
8
+ ********************************************************************************/
9
+ /**
10
+ * The uniform contract every framework test harness satisfies. A harness is
11
+ * a wired bundle around a system-under-test, driven through a seam; its full
12
+ * shape is `{ <subject>, <seam>, …captureArrays, dispose() }`. This marker
13
+ * pins the one member that is identical across every harness — `dispose()` —
14
+ * so teardown is always `harness.dispose()` regardless of which harness, and
15
+ * a `Harness` reference can release any of them without knowing its concrete
16
+ * type. Each concrete harness interface — per head, and per conformance driver
17
+ * port — `extends Harness` and adds its subject / seam / capture members on
18
+ * top.
19
+ */
20
+ export interface Harness {
21
+ /** Release every resource the harness holds. Idempotent; the uniform teardown hook. */
22
+ dispose(): void;
23
+ }
24
+ //# sourceMappingURL=harness.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"harness.d.ts","sourceRoot":"","sources":["../../src/testing/harness.ts"],"names":[],"mappings":"AAAA;;;;;;;kFAOkF;AAElF;;;;;;;;;;GAUG;AACH,MAAM,WAAW,OAAO;IACrB,uFAAuF;IACvF,OAAO,IAAI,IAAI,CAAC;CAClB"}
@@ -0,0 +1,11 @@
1
+ "use strict";
2
+ /********************************************************************************
3
+ * Copyright (c) 2026 CrossBreeze, EclipseSource and others.
4
+ *
5
+ * This program and the accompanying materials are made available under the
6
+ * terms of the MIT License which is available in the project root.
7
+ *
8
+ * SPDX-License-Identifier: MIT
9
+ ********************************************************************************/
10
+ Object.defineProperty(exports, "__esModule", { value: true });
11
+ //# sourceMappingURL=harness.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"harness.js","sourceRoot":"","sources":["../../src/testing/harness.ts"],"names":[],"mappings":";AAAA;;;;;;;kFAOkF"}
@@ -0,0 +1,13 @@
1
+ /********************************************************************************
2
+ * Copyright (c) 2026 CrossBreeze, EclipseSource and others.
3
+ *
4
+ * This program and the accompanying materials are made available under the
5
+ * terms of the MIT License which is available in the project root.
6
+ *
7
+ * SPDX-License-Identifier: MIT
8
+ ********************************************************************************/
9
+ export * from './data-doubles';
10
+ export * from './fake-clock';
11
+ export * from './harness';
12
+ export * from './wait-for';
13
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/testing/index.ts"],"names":[],"mappings":"AAAA;;;;;;;kFAOkF;AAelF,cAAc,gBAAgB,CAAC;AAC/B,cAAc,cAAc,CAAC;AAC7B,cAAc,WAAW,CAAC;AAC1B,cAAc,YAAY,CAAC"}
@@ -0,0 +1,41 @@
1
+ "use strict";
2
+ /********************************************************************************
3
+ * Copyright (c) 2026 CrossBreeze, EclipseSource and others.
4
+ *
5
+ * This program and the accompanying materials are made available under the
6
+ * terms of the MIT License which is available in the project root.
7
+ *
8
+ * SPDX-License-Identifier: MIT
9
+ ********************************************************************************/
10
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
11
+ if (k2 === undefined) k2 = k;
12
+ var desc = Object.getOwnPropertyDescriptor(m, k);
13
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
14
+ desc = { enumerable: true, get: function() { return m[k]; } };
15
+ }
16
+ Object.defineProperty(o, k2, desc);
17
+ }) : (function(o, m, k, k2) {
18
+ if (k2 === undefined) k2 = k;
19
+ o[k2] = m[k];
20
+ }));
21
+ var __exportStar = (this && this.__exportStar) || function(m, exports) {
22
+ for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
23
+ };
24
+ Object.defineProperty(exports, "__esModule", { value: true });
25
+ // Subpath barrel for `@hydranium/protocol/testing` — the BROWSER-NEUTRAL shared
26
+ // primitives: `makeFakeClock` (deterministic `Clock` double on one virtual time
27
+ // axis), `waitFor` / `tick`, the client-side data-head doubles
28
+ // (`makeFakeDataPort` / `makeCapturingDataClient`), and the `Harness` marker
29
+ // interface every framework harness extends. Kept out of the main barrel so production bundles don't pull
30
+ // the test scaffolding in by default; adopters opt in by importing from
31
+ // `@hydranium/protocol/testing`.
32
+ //
33
+ // Neutrality is gated (`scripts/check-neutral-bundles.mjs`), which is why the
34
+ // duplex transports are NOT here: a `PassThrough` pair is in their exported
35
+ // type, so they cannot be made portable and live at `./testing/node` instead.
36
+ // The same rule the package surface uses — the portable name is the short one.
37
+ __exportStar(require("./data-doubles"), exports);
38
+ __exportStar(require("./fake-clock"), exports);
39
+ __exportStar(require("./harness"), exports);
40
+ __exportStar(require("./wait-for"), exports);
41
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/testing/index.ts"],"names":[],"mappings":";AAAA;;;;;;;kFAOkF;;;;;;;;;;;;;;;;AAElF,gFAAgF;AAChF,gFAAgF;AAChF,+DAA+D;AAC/D,6EAA6E;AAC7E,0GAA0G;AAC1G,wEAAwE;AACxE,iCAAiC;AACjC,EAAE;AACF,8EAA8E;AAC9E,4EAA4E;AAC5E,8EAA8E;AAC9E,+EAA+E;AAE/E,iDAA+B;AAC/B,+CAA6B;AAC7B,4CAA0B;AAC1B,6CAA2B"}
@@ -0,0 +1,25 @@
1
+ /********************************************************************************
2
+ * Copyright (c) 2026 CrossBreeze, EclipseSource and others.
3
+ *
4
+ * This program and the accompanying materials are made available under the
5
+ * terms of the MIT License which is available in the project root.
6
+ *
7
+ * SPDX-License-Identifier: MIT
8
+ ********************************************************************************/
9
+ import { type MessageConnection } from 'vscode-jsonrpc/node';
10
+ /**
11
+ * Bidirectional in-process vscode-jsonrpc bridge — two MessageConnections
12
+ * crossed over a PassThrough pair, both already listening. The framework's
13
+ * standard in-process test transport.
14
+ *
15
+ * Typical use: wire a `DataServer` to `pair.left` and exercise it from a
16
+ * client proxy on `pair.right` (or vice versa). Call `dispose` at test
17
+ * teardown to release the underlying streams.
18
+ */
19
+ export interface DuplexConnectionPair {
20
+ readonly left: MessageConnection;
21
+ readonly right: MessageConnection;
22
+ dispose(): void;
23
+ }
24
+ export declare function makeDuplexConnectionPair(): DuplexConnectionPair;
25
+ //# sourceMappingURL=duplex-connection.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"duplex-connection.d.ts","sourceRoot":"","sources":["../../../src/testing/node/duplex-connection.ts"],"names":[],"mappings":"AAAA;;;;;;;kFAOkF;AAElF,OAAO,EAAqE,KAAK,iBAAiB,EAAE,MAAM,qBAAqB,CAAC;AAGhI;;;;;;;;GAQG;AACH,MAAM,WAAW,oBAAoB;IAClC,QAAQ,CAAC,IAAI,EAAE,iBAAiB,CAAC;IACjC,QAAQ,CAAC,KAAK,EAAE,iBAAiB,CAAC;IAClC,OAAO,IAAI,IAAI,CAAC;CAClB;AAED,wBAAgB,wBAAwB,IAAI,oBAAoB,CAsB/D"}
@@ -0,0 +1,34 @@
1
+ "use strict";
2
+ /********************************************************************************
3
+ * Copyright (c) 2026 CrossBreeze, EclipseSource and others.
4
+ *
5
+ * This program and the accompanying materials are made available under the
6
+ * terms of the MIT License which is available in the project root.
7
+ *
8
+ * SPDX-License-Identifier: MIT
9
+ ********************************************************************************/
10
+ Object.defineProperty(exports, "__esModule", { value: true });
11
+ exports.makeDuplexConnectionPair = makeDuplexConnectionPair;
12
+ const node_1 = require("vscode-jsonrpc/node");
13
+ const duplex_stream_1 = require("./duplex-stream");
14
+ function makeDuplexConnectionPair() {
15
+ // `left` is the client side, `right` the server side: `clientToServer` is
16
+ // what `left` writes and `right` reads; `serverToClient` is what `right`
17
+ // writes and `left` reads.
18
+ const pair = (0, duplex_stream_1.makeDuplexStreamPair)();
19
+ const { clientToServer, serverToClient } = pair;
20
+ const left = (0, node_1.createMessageConnection)(new node_1.StreamMessageReader(serverToClient), new node_1.StreamMessageWriter(clientToServer));
21
+ const right = (0, node_1.createMessageConnection)(new node_1.StreamMessageReader(clientToServer), new node_1.StreamMessageWriter(serverToClient));
22
+ left.listen();
23
+ right.listen();
24
+ return {
25
+ left,
26
+ right,
27
+ dispose() {
28
+ left.dispose();
29
+ right.dispose();
30
+ pair.dispose();
31
+ }
32
+ };
33
+ }
34
+ //# sourceMappingURL=duplex-connection.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"duplex-connection.js","sourceRoot":"","sources":["../../../src/testing/node/duplex-connection.ts"],"names":[],"mappings":";AAAA;;;;;;;kFAOkF;;AAoBlF,4DAsBC;AAxCD,8CAAgI;AAChI,mDAAuD;AAiBvD,SAAgB,wBAAwB;IACrC,0EAA0E;IAC1E,yEAAyE;IACzE,2BAA2B;IAC3B,MAAM,IAAI,GAAG,IAAA,oCAAoB,GAAE,CAAC;IACpC,MAAM,EAAE,cAAc,EAAE,cAAc,EAAE,GAAG,IAAI,CAAC;IAEhD,MAAM,IAAI,GAAG,IAAA,8BAAuB,EAAC,IAAI,0BAAmB,CAAC,cAAc,CAAC,EAAE,IAAI,0BAAmB,CAAC,cAAc,CAAC,CAAC,CAAC;IACvH,MAAM,KAAK,GAAG,IAAA,8BAAuB,EAAC,IAAI,0BAAmB,CAAC,cAAc,CAAC,EAAE,IAAI,0BAAmB,CAAC,cAAc,CAAC,CAAC,CAAC;IAExH,IAAI,CAAC,MAAM,EAAE,CAAC;IACd,KAAK,CAAC,MAAM,EAAE,CAAC;IAEf,OAAO;QACJ,IAAI;QACJ,KAAK;QACL,OAAO;YACJ,IAAI,CAAC,OAAO,EAAE,CAAC;YACf,KAAK,CAAC,OAAO,EAAE,CAAC;YAChB,IAAI,CAAC,OAAO,EAAE,CAAC;QAClB,CAAC;KACH,CAAC;AACL,CAAC"}
@@ -0,0 +1,32 @@
1
+ /********************************************************************************
2
+ * Copyright (c) 2026 CrossBreeze, EclipseSource and others.
3
+ *
4
+ * This program and the accompanying materials are made available under the
5
+ * terms of the MIT License which is available in the project root.
6
+ *
7
+ * SPDX-License-Identifier: MIT
8
+ ********************************************************************************/
9
+ import { PassThrough } from 'node:stream';
10
+ /**
11
+ * A crossed pair of in-process `PassThrough` streams modelling one
12
+ * bidirectional client/server transport. Each `PassThrough` is itself both
13
+ * readable and writable: the side named first writes, the side named second
14
+ * reads off the same object. The shared substrate under the framework's
15
+ * in-process test transports — `makeDuplexConnectionPair` layers a
16
+ * `MessageConnection` pair on top.
17
+ */
18
+ export interface DuplexStreamPair {
19
+ /** Client writes here; server reads here. */
20
+ readonly clientToServer: PassThrough;
21
+ /** Server writes here; client reads here. */
22
+ readonly serverToClient: PassThrough;
23
+ /** Destroy both streams. Idempotent. */
24
+ dispose(): void;
25
+ }
26
+ /**
27
+ * Build a fresh {@link DuplexStreamPair}. The two streams are independent;
28
+ * data written to one never appears on the other. Call `dispose` at test
29
+ * teardown to release them.
30
+ */
31
+ export declare function makeDuplexStreamPair(): DuplexStreamPair;
32
+ //# sourceMappingURL=duplex-stream.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"duplex-stream.d.ts","sourceRoot":"","sources":["../../../src/testing/node/duplex-stream.ts"],"names":[],"mappings":"AAAA;;;;;;;kFAOkF;AAElF,OAAO,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAE1C;;;;;;;GAOG;AACH,MAAM,WAAW,gBAAgB;IAC9B,6CAA6C;IAC7C,QAAQ,CAAC,cAAc,EAAE,WAAW,CAAC;IACrC,6CAA6C;IAC7C,QAAQ,CAAC,cAAc,EAAE,WAAW,CAAC;IACrC,wCAAwC;IACxC,OAAO,IAAI,IAAI,CAAC;CAClB;AAED;;;;GAIG;AACH,wBAAgB,oBAAoB,IAAI,gBAAgB,CAiBvD"}
@@ -0,0 +1,35 @@
1
+ "use strict";
2
+ /********************************************************************************
3
+ * Copyright (c) 2026 CrossBreeze, EclipseSource and others.
4
+ *
5
+ * This program and the accompanying materials are made available under the
6
+ * terms of the MIT License which is available in the project root.
7
+ *
8
+ * SPDX-License-Identifier: MIT
9
+ ********************************************************************************/
10
+ Object.defineProperty(exports, "__esModule", { value: true });
11
+ exports.makeDuplexStreamPair = makeDuplexStreamPair;
12
+ const node_stream_1 = require("node:stream");
13
+ /**
14
+ * Build a fresh {@link DuplexStreamPair}. The two streams are independent;
15
+ * data written to one never appears on the other. Call `dispose` at test
16
+ * teardown to release them.
17
+ */
18
+ function makeDuplexStreamPair() {
19
+ const clientToServer = new node_stream_1.PassThrough();
20
+ const serverToClient = new node_stream_1.PassThrough();
21
+ let disposed = false;
22
+ return {
23
+ clientToServer,
24
+ serverToClient,
25
+ dispose() {
26
+ if (disposed) {
27
+ return;
28
+ }
29
+ disposed = true;
30
+ clientToServer.destroy();
31
+ serverToClient.destroy();
32
+ }
33
+ };
34
+ }
35
+ //# sourceMappingURL=duplex-stream.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"duplex-stream.js","sourceRoot":"","sources":["../../../src/testing/node/duplex-stream.ts"],"names":[],"mappings":";AAAA;;;;;;;kFAOkF;;AA0BlF,oDAiBC;AAzCD,6CAA0C;AAmB1C;;;;GAIG;AACH,SAAgB,oBAAoB;IACjC,MAAM,cAAc,GAAG,IAAI,yBAAW,EAAE,CAAC;IACzC,MAAM,cAAc,GAAG,IAAI,yBAAW,EAAE,CAAC;IAEzC,IAAI,QAAQ,GAAG,KAAK,CAAC;IACrB,OAAO;QACJ,cAAc;QACd,cAAc;QACd,OAAO;YACJ,IAAI,QAAQ,EAAE,CAAC;gBACZ,OAAO;YACV,CAAC;YACD,QAAQ,GAAG,IAAI,CAAC;YAChB,cAAc,CAAC,OAAO,EAAE,CAAC;YACzB,cAAc,CAAC,OAAO,EAAE,CAAC;QAC5B,CAAC;KACH,CAAC;AACL,CAAC"}
@@ -0,0 +1,11 @@
1
+ /********************************************************************************
2
+ * Copyright (c) 2026 CrossBreeze, EclipseSource and others.
3
+ *
4
+ * This program and the accompanying materials are made available under the
5
+ * terms of the MIT License which is available in the project root.
6
+ *
7
+ * SPDX-License-Identifier: MIT
8
+ ********************************************************************************/
9
+ export * from './duplex-connection';
10
+ export * from './duplex-stream';
11
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/testing/node/index.ts"],"names":[],"mappings":"AAAA;;;;;;;kFAOkF;AAalF,cAAc,qBAAqB,CAAC;AACpC,cAAc,iBAAiB,CAAC"}
@@ -0,0 +1,37 @@
1
+ "use strict";
2
+ /********************************************************************************
3
+ * Copyright (c) 2026 CrossBreeze, EclipseSource and others.
4
+ *
5
+ * This program and the accompanying materials are made available under the
6
+ * terms of the MIT License which is available in the project root.
7
+ *
8
+ * SPDX-License-Identifier: MIT
9
+ ********************************************************************************/
10
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
11
+ if (k2 === undefined) k2 = k;
12
+ var desc = Object.getOwnPropertyDescriptor(m, k);
13
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
14
+ desc = { enumerable: true, get: function() { return m[k]; } };
15
+ }
16
+ Object.defineProperty(o, k2, desc);
17
+ }) : (function(o, m, k, k2) {
18
+ if (k2 === undefined) k2 = k;
19
+ o[k2] = m[k];
20
+ }));
21
+ var __exportStar = (this && this.__exportStar) || function(m, exports) {
22
+ for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
23
+ };
24
+ Object.defineProperty(exports, "__esModule", { value: true });
25
+ // Subpath barrel for `@hydranium/protocol/testing/node` — the test transports
26
+ // that need a Node runtime: a crossed `PassThrough` pair and the in-process
27
+ // `MessageConnection` bridge over it.
28
+ //
29
+ // Separate from `./testing` because a `PassThrough` is in `DuplexStreamPair`'s
30
+ // exported type and `StreamMessageReader` comes from `vscode-jsonrpc/node`, so
31
+ // neither can be made portable — and keeping them in the neutral barrel taints
32
+ // every subpath that re-exports it, which is what made three of this repo's
33
+ // `./testing` entries unbundleable for a browser while having no Node code of
34
+ // their own.
35
+ __exportStar(require("./duplex-connection"), exports);
36
+ __exportStar(require("./duplex-stream"), exports);
37
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/testing/node/index.ts"],"names":[],"mappings":";AAAA;;;;;;;kFAOkF;;;;;;;;;;;;;;;;AAElF,8EAA8E;AAC9E,4EAA4E;AAC5E,sCAAsC;AACtC,EAAE;AACF,+EAA+E;AAC/E,+EAA+E;AAC/E,+EAA+E;AAC/E,4EAA4E;AAC5E,8EAA8E;AAC9E,aAAa;AAEb,sDAAoC;AACpC,kDAAgC"}
@@ -0,0 +1,69 @@
1
+ /********************************************************************************
2
+ * Copyright (c) 2026 CrossBreeze, EclipseSource and others.
3
+ *
4
+ * This program and the accompanying materials are made available under the
5
+ * terms of the MIT License which is available in the project root.
6
+ *
7
+ * SPDX-License-Identifier: MIT
8
+ ********************************************************************************/
9
+ /**
10
+ * Two test primitives for awaiting in-process asynchrony (RPC notifications
11
+ * crossing the duplex wire, `DocumentBuilder` phase events, etc.) WITHOUT a
12
+ * flaky fixed sleep.
13
+ *
14
+ * Decision rule:
15
+ * - Asserting an effect **will** happen ("eventually N events / a build ran /
16
+ * the doc reached a phase")? → {@link waitFor} with a predicate over the
17
+ * observable. Non-racy: resolves the instant it is true, tolerates a slow CI.
18
+ * - Asserting an effect **did not / has not yet** happened ("no event for an
19
+ * unsubscribed URI", "the gated call has not resolved")? → {@link tick}: a
20
+ * negative cannot be polled, so yield the loop a bounded moment to give the
21
+ * (unwanted) effect a chance, then assert its absence.
22
+ *
23
+ * Default to `waitFor`; reach for `tick` only when the assertion is an absence.
24
+ * A microtask flush (`await Promise.resolve()` / `queue-microtask`) is never the
25
+ * answer here — stream-delivered JSON-RPC notifications arrive on a macrotask/IO
26
+ * turn, after microtasks drain.
27
+ */
28
+ /** Options for {@link waitFor}. */
29
+ export interface WaitForOptions {
30
+ /** Reject after this many milliseconds if the predicate is still false. Default 2000. */
31
+ readonly timeoutMs?: number;
32
+ /** Poll the predicate every this-many milliseconds. Default 5. */
33
+ readonly intervalMs?: number;
34
+ /** Error message on timeout. Default a generic phrasing. */
35
+ readonly message?: string;
36
+ }
37
+ /**
38
+ * Resolve once `predicate()` returns true, polling at `intervalMs`; reject with
39
+ * `message` once `timeoutMs` elapses. The **non-racy** alternative to a fixed
40
+ * sleep for awaiting an asynchronous side effect that lands on an observable
41
+ * value.
42
+ *
43
+ * It resolves the instant the condition holds, so it is *faster* than a fixed
44
+ * delay on the happy path, and tolerates a slow event loop up to `timeoutMs`, so
45
+ * it does not flake under parallel CI where a fixed `setTimeout` can be starved
46
+ * past the test timeout.
47
+ *
48
+ * @example
49
+ * await proxy.updateModelDocument({ uri, clientId, model });
50
+ * await waitFor(() => harness.events.length === 1); // the notification crossed
51
+ * expect(harness.events[0].document.uri).toBe(uri);
52
+ */
53
+ export declare function waitFor(predicate: () => boolean, options?: WaitForOptions): Promise<void>;
54
+ /**
55
+ * Yield the event loop for `ms` (default 10). The bounded counterpart to
56
+ * {@link waitFor}, for the rare assertion that something has NOT happened — a
57
+ * *negative* you cannot poll positively. Give async delivery a real chance to
58
+ * (wrongly) occur, then assert it did not.
59
+ *
60
+ * A fixed yield is unavoidable here, but the failure mode is a false-green, not
61
+ * the flaky-red a fixed delay causes on a positive wait.
62
+ *
63
+ * @example
64
+ * await proxy.saveModelDocument({ uri, clientId, model }); // no subscriber yet
65
+ * await tick(); // give a (wrongly) fired event a chance to land
66
+ * expect(savedEvents).toHaveLength(0); // assert the ABSENCE
67
+ */
68
+ export declare function tick(ms?: number): Promise<void>;
69
+ //# sourceMappingURL=wait-for.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"wait-for.d.ts","sourceRoot":"","sources":["../../src/testing/wait-for.ts"],"names":[],"mappings":"AAAA;;;;;;;kFAOkF;AAElF;;;;;;;;;;;;;;;;;;GAkBG;AAEH,mCAAmC;AACnC,MAAM,WAAW,cAAc;IAC5B,yFAAyF;IACzF,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,CAAC;IAC5B,kEAAkE;IAClE,QAAQ,CAAC,UAAU,CAAC,EAAE,MAAM,CAAC;IAC7B,4DAA4D;IAC5D,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,CAAC;CAC5B;AAED;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,OAAO,CAAC,SAAS,EAAE,MAAM,OAAO,EAAE,OAAO,GAAE,cAAmB,GAAG,OAAO,CAAC,IAAI,CAAC,CAoB7F;AAED;;;;;;;;;;;;;GAaG;AACH,wBAAgB,IAAI,CAAC,EAAE,SAAK,GAAG,OAAO,CAAC,IAAI,CAAC,CAE3C"}