@hydranium/core 1.0.0-next.10 → 1.0.0-next.104

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 (375) hide show
  1. package/lib/documents/ast-document-manager.d.ts +75 -16
  2. package/lib/documents/ast-document-manager.d.ts.map +1 -1
  3. package/lib/documents/ast-document-manager.js +57 -19
  4. package/lib/documents/ast-document-manager.js.map +1 -1
  5. package/lib/documents/client-ids.d.ts +5 -19
  6. package/lib/documents/client-ids.d.ts.map +1 -1
  7. package/lib/documents/client-ids.js +5 -19
  8. package/lib/documents/client-ids.js.map +1 -1
  9. package/lib/documents/hydranium-text-documents.d.ts +124 -36
  10. package/lib/documents/hydranium-text-documents.d.ts.map +1 -1
  11. package/lib/documents/hydranium-text-documents.js +191 -51
  12. package/lib/documents/hydranium-text-documents.js.map +1 -1
  13. package/lib/documents/language-client-text-shadow.d.ts +41 -9
  14. package/lib/documents/language-client-text-shadow.d.ts.map +1 -1
  15. package/lib/documents/language-client-text-shadow.js +56 -11
  16. package/lib/documents/language-client-text-shadow.js.map +1 -1
  17. package/lib/documents/self-save-registry.d.ts +37 -6
  18. package/lib/documents/self-save-registry.d.ts.map +1 -1
  19. package/lib/documents/self-save-registry.js +28 -15
  20. package/lib/documents/self-save-registry.js.map +1 -1
  21. package/lib/index.d.ts +3 -0
  22. package/lib/index.d.ts.map +1 -1
  23. package/lib/index.js +6 -0
  24. package/lib/index.js.map +1 -1
  25. package/lib/langium/ast-extension/ast-node-builder.d.ts +32 -9
  26. package/lib/langium/ast-extension/ast-node-builder.d.ts.map +1 -1
  27. package/lib/langium/ast-extension/ast-node-builder.js +60 -22
  28. package/lib/langium/ast-extension/ast-node-builder.js.map +1 -1
  29. package/lib/langium/bootstrap.d.ts.map +1 -1
  30. package/lib/langium/bootstrap.js +16 -9
  31. package/lib/langium/bootstrap.js.map +1 -1
  32. package/lib/langium/config/configuration-provider.d.ts +81 -0
  33. package/lib/langium/config/configuration-provider.d.ts.map +1 -0
  34. package/lib/langium/config/configuration-provider.js +112 -0
  35. package/lib/langium/config/configuration-provider.js.map +1 -0
  36. package/lib/langium/config/index.d.ts +1 -0
  37. package/lib/langium/config/index.d.ts.map +1 -1
  38. package/lib/langium/config/index.js +1 -0
  39. package/lib/langium/config/index.js.map +1 -1
  40. package/lib/langium/diagnostics/lsp-logger.d.ts +17 -0
  41. package/lib/langium/diagnostics/lsp-logger.d.ts.map +1 -1
  42. package/lib/langium/diagnostics/lsp-logger.js +40 -6
  43. package/lib/langium/diagnostics/lsp-logger.js.map +1 -1
  44. package/lib/langium/document-builder/build-pipeline-integration.d.ts +21 -1
  45. package/lib/langium/document-builder/build-pipeline-integration.d.ts.map +1 -1
  46. package/lib/langium/document-builder/build-pipeline-integration.js +32 -5
  47. package/lib/langium/document-builder/build-pipeline-integration.js.map +1 -1
  48. package/lib/langium/document-builder/build-session.d.ts +93 -0
  49. package/lib/langium/document-builder/build-session.d.ts.map +1 -0
  50. package/lib/langium/document-builder/build-session.js +72 -0
  51. package/lib/langium/document-builder/build-session.js.map +1 -0
  52. package/lib/langium/document-builder/document-builder.d.ts +150 -7
  53. package/lib/langium/document-builder/document-builder.d.ts.map +1 -1
  54. package/lib/langium/document-builder/document-builder.js +298 -11
  55. package/lib/langium/document-builder/document-builder.js.map +1 -1
  56. package/lib/langium/document-builder/index.d.ts +1 -0
  57. package/lib/langium/document-builder/index.d.ts.map +1 -1
  58. package/lib/langium/document-builder/index.js +1 -0
  59. package/lib/langium/document-builder/index.js.map +1 -1
  60. package/lib/langium/integration-services.d.ts +45 -1
  61. package/lib/langium/integration-services.d.ts.map +1 -1
  62. package/lib/langium/integration-services.js +10 -5
  63. package/lib/langium/integration-services.js.map +1 -1
  64. package/lib/langium/integrity/integrity-service.d.ts +16 -0
  65. package/lib/langium/integrity/integrity-service.d.ts.map +1 -1
  66. package/lib/langium/integrity/integrity-service.js +110 -2
  67. package/lib/langium/integrity/integrity-service.js.map +1 -1
  68. package/lib/langium/keys/containment.d.ts +64 -0
  69. package/lib/langium/keys/containment.d.ts.map +1 -0
  70. package/lib/langium/keys/containment.js +53 -0
  71. package/lib/langium/keys/containment.js.map +1 -0
  72. package/lib/langium/keys/index.d.ts +1 -0
  73. package/lib/langium/keys/index.d.ts.map +1 -1
  74. package/lib/langium/keys/index.js +1 -0
  75. package/lib/langium/keys/index.js.map +1 -1
  76. package/lib/langium/keys/name-based-key-provider.d.ts +4 -0
  77. package/lib/langium/keys/name-based-key-provider.d.ts.map +1 -1
  78. package/lib/langium/keys/name-based-key-provider.js +4 -0
  79. package/lib/langium/keys/name-based-key-provider.js.map +1 -1
  80. package/lib/langium/language-module.d.ts +25 -0
  81. package/lib/langium/language-module.d.ts.map +1 -1
  82. package/lib/langium/language-module.js +14 -0
  83. package/lib/langium/language-module.js.map +1 -1
  84. package/lib/langium/model-service/model-service.d.ts +161 -10
  85. package/lib/langium/model-service/model-service.d.ts.map +1 -1
  86. package/lib/langium/model-service/model-service.js +174 -95
  87. package/lib/langium/model-service/model-service.js.map +1 -1
  88. package/lib/langium/module.d.ts +84 -15
  89. package/lib/langium/module.d.ts.map +1 -1
  90. package/lib/langium/module.js +26 -12
  91. package/lib/langium/module.js.map +1 -1
  92. package/lib/langium/naming/name-provider.d.ts +25 -4
  93. package/lib/langium/naming/name-provider.d.ts.map +1 -1
  94. package/lib/langium/naming/name-provider.js +2 -1
  95. package/lib/langium/naming/name-provider.js.map +1 -1
  96. package/lib/langium/naming/name-separator-validation.d.ts +23 -0
  97. package/lib/langium/naming/name-separator-validation.d.ts.map +1 -1
  98. package/lib/langium/naming/name-separator-validation.js +30 -1
  99. package/lib/langium/naming/name-separator-validation.js.map +1 -1
  100. package/lib/langium/residency/cst-residency-service.d.ts +31 -11
  101. package/lib/langium/residency/cst-residency-service.d.ts.map +1 -1
  102. package/lib/langium/residency/cst-residency-service.js +13 -56
  103. package/lib/langium/residency/cst-residency-service.js.map +1 -1
  104. package/lib/langium/scope/hydranium-scope-provider.d.ts +48 -13
  105. package/lib/langium/scope/hydranium-scope-provider.d.ts.map +1 -1
  106. package/lib/langium/scope/hydranium-scope-provider.js +56 -20
  107. package/lib/langium/scope/hydranium-scope-provider.js.map +1 -1
  108. package/lib/langium/serialization/abstract-serializer.d.ts +11 -20
  109. package/lib/langium/serialization/abstract-serializer.d.ts.map +1 -1
  110. package/lib/langium/serialization/abstract-serializer.js +12 -21
  111. package/lib/langium/serialization/abstract-serializer.js.map +1 -1
  112. package/lib/langium/service-registry.d.ts +15 -1
  113. package/lib/langium/service-registry.d.ts.map +1 -1
  114. package/lib/langium/service-registry.js +16 -0
  115. package/lib/langium/service-registry.js.map +1 -1
  116. package/lib/langium/shared-services.d.ts +15 -2
  117. package/lib/langium/shared-services.d.ts.map +1 -1
  118. package/lib/langium/shared-services.js.map +1 -1
  119. package/lib/langium/transfer/transfer-encoder.d.ts +60 -17
  120. package/lib/langium/transfer/transfer-encoder.d.ts.map +1 -1
  121. package/lib/langium/transfer/transfer-encoder.js +38 -16
  122. package/lib/langium/transfer/transfer-encoder.js.map +1 -1
  123. package/lib/langium/trivia/comment-preserver.d.ts +423 -0
  124. package/lib/langium/trivia/comment-preserver.d.ts.map +1 -0
  125. package/lib/langium/trivia/comment-preserver.js +906 -0
  126. package/lib/langium/trivia/comment-preserver.js.map +1 -0
  127. package/lib/langium/trivia/document-ending-preserver.d.ts +43 -0
  128. package/lib/langium/trivia/document-ending-preserver.d.ts.map +1 -0
  129. package/lib/langium/trivia/document-ending-preserver.js +48 -0
  130. package/lib/langium/trivia/document-ending-preserver.js.map +1 -0
  131. package/lib/langium/trivia/index.d.ts +14 -0
  132. package/lib/langium/trivia/index.d.ts.map +1 -0
  133. package/lib/langium/trivia/index.js +14 -0
  134. package/lib/langium/trivia/index.js.map +1 -0
  135. package/lib/langium/trivia/trivia-contribution.d.ts +37 -0
  136. package/lib/langium/trivia/trivia-contribution.d.ts.map +1 -0
  137. package/lib/langium/trivia/trivia-contribution.js +10 -0
  138. package/lib/langium/trivia/trivia-contribution.js.map +1 -0
  139. package/lib/langium/trivia/trivia-preserver.d.ts +50 -0
  140. package/lib/langium/trivia/trivia-preserver.d.ts.map +1 -0
  141. package/lib/langium/trivia/trivia-preserver.js +10 -0
  142. package/lib/langium/trivia/trivia-preserver.js.map +1 -0
  143. package/lib/langium/trivia/trivia-service.d.ts +70 -0
  144. package/lib/langium/trivia/trivia-service.d.ts.map +1 -0
  145. package/lib/langium/trivia/trivia-service.js +56 -0
  146. package/lib/langium/trivia/trivia-service.js.map +1 -0
  147. package/lib/langium/validation/document-validator.d.ts +294 -10
  148. package/lib/langium/validation/document-validator.d.ts.map +1 -1
  149. package/lib/langium/validation/document-validator.js +448 -5
  150. package/lib/langium/validation/document-validator.js.map +1 -1
  151. package/lib/langium/workspace/document-uri-policy.d.ts +3 -4
  152. package/lib/langium/workspace/document-uri-policy.d.ts.map +1 -1
  153. package/lib/langium/workspace/document-uri-policy.js +3 -4
  154. package/lib/langium/workspace/document-uri-policy.js.map +1 -1
  155. package/lib/langium/workspace/file-system-provider.d.ts +9 -1
  156. package/lib/langium/workspace/file-system-provider.d.ts.map +1 -1
  157. package/lib/langium/workspace/file-system-provider.js +40 -7
  158. package/lib/langium/workspace/file-system-provider.js.map +1 -1
  159. package/lib/langium/workspace/hydranium-langium-document-factory.d.ts +25 -0
  160. package/lib/langium/workspace/hydranium-langium-document-factory.d.ts.map +1 -1
  161. package/lib/langium/workspace/hydranium-langium-document-factory.js +25 -0
  162. package/lib/langium/workspace/hydranium-langium-document-factory.js.map +1 -1
  163. package/lib/langium/workspace/hydranium-workspace-manager.d.ts +21 -1
  164. package/lib/langium/workspace/hydranium-workspace-manager.d.ts.map +1 -1
  165. package/lib/langium/workspace/hydranium-workspace-manager.js +28 -0
  166. package/lib/langium/workspace/hydranium-workspace-manager.js.map +1 -1
  167. package/lib/langium/workspace/in-memory-file-system-provider.d.ts +23 -0
  168. package/lib/langium/workspace/in-memory-file-system-provider.d.ts.map +1 -1
  169. package/lib/langium/workspace/in-memory-file-system-provider.js +47 -9
  170. package/lib/langium/workspace/in-memory-file-system-provider.js.map +1 -1
  171. package/lib/langium/workspace/initialize-workspace.d.ts +22 -2
  172. package/lib/langium/workspace/initialize-workspace.d.ts.map +1 -1
  173. package/lib/langium/workspace/initialize-workspace.js +13 -5
  174. package/lib/langium/workspace/initialize-workspace.js.map +1 -1
  175. package/lib/langium/workspace/langium-documents.d.ts +79 -17
  176. package/lib/langium/workspace/langium-documents.d.ts.map +1 -1
  177. package/lib/langium/workspace/langium-documents.js +83 -28
  178. package/lib/langium/workspace/langium-documents.js.map +1 -1
  179. package/lib/langium/workspace/virtual-document.d.ts +18 -3
  180. package/lib/langium/workspace/virtual-document.d.ts.map +1 -1
  181. package/lib/langium/workspace/virtual-document.js +19 -2
  182. package/lib/langium/workspace/virtual-document.js.map +1 -1
  183. package/lib/locale/index.d.ts +10 -0
  184. package/lib/locale/index.d.ts.map +1 -0
  185. package/lib/locale/index.js +10 -0
  186. package/lib/locale/index.js.map +1 -0
  187. package/lib/locale/server-locale.d.ts +73 -0
  188. package/lib/locale/server-locale.d.ts.map +1 -0
  189. package/lib/locale/server-locale.js +61 -0
  190. package/lib/locale/server-locale.js.map +1 -0
  191. package/lib/lsp/hydranium-document-update-handler.js +1 -1
  192. package/lib/lsp/hydranium-document-update-handler.js.map +1 -1
  193. package/lib/lsp/index.d.ts +1 -1
  194. package/lib/lsp/index.d.ts.map +1 -1
  195. package/lib/lsp/index.js +1 -1
  196. package/lib/lsp/index.js.map +1 -1
  197. package/lib/lsp/lsp-latency.d.ts +39 -0
  198. package/lib/lsp/lsp-latency.d.ts.map +1 -0
  199. package/lib/lsp/lsp-latency.js +58 -0
  200. package/lib/lsp/lsp-latency.js.map +1 -0
  201. package/lib/lsp/semantic-token-provider.d.ts +34 -1
  202. package/lib/lsp/semantic-token-provider.d.ts.map +1 -1
  203. package/lib/lsp/semantic-token-provider.js +55 -8
  204. package/lib/lsp/semantic-token-provider.js.map +1 -1
  205. package/lib/messages/carriers.d.ts +54 -0
  206. package/lib/messages/carriers.d.ts.map +1 -0
  207. package/lib/messages/carriers.js +62 -0
  208. package/lib/messages/carriers.js.map +1 -0
  209. package/lib/messages/index.d.ts +25 -0
  210. package/lib/messages/index.d.ts.map +1 -0
  211. package/lib/messages/index.js +25 -0
  212. package/lib/messages/index.js.map +1 -0
  213. package/lib/messages/renderer.d.ts +136 -0
  214. package/lib/messages/renderer.d.ts.map +1 -0
  215. package/lib/messages/renderer.js +159 -0
  216. package/lib/messages/renderer.js.map +1 -0
  217. package/lib/node/heap-ceiling.d.ts +61 -0
  218. package/lib/node/heap-ceiling.d.ts.map +1 -0
  219. package/lib/node/heap-ceiling.js +72 -0
  220. package/lib/node/heap-ceiling.js.map +1 -0
  221. package/lib/node/index.d.ts +1 -0
  222. package/lib/node/index.d.ts.map +1 -1
  223. package/lib/node/index.js +1 -0
  224. package/lib/node/index.js.map +1 -1
  225. package/lib/node/latency-from-env.d.ts +1 -1
  226. package/lib/node/latency-from-env.js +1 -1
  227. package/lib/node/node-file-system-provider.d.ts +35 -1
  228. package/lib/node/node-file-system-provider.d.ts.map +1 -1
  229. package/lib/node/node-file-system-provider.js +140 -45
  230. package/lib/node/node-file-system-provider.js.map +1 -1
  231. package/lib/node/profile-capture.d.ts +8 -2
  232. package/lib/node/profile-capture.d.ts.map +1 -1
  233. package/lib/node/profile-capture.js.map +1 -1
  234. package/lib/node/profiling-run.d.ts +2 -2
  235. package/lib/node/profiling-run.js +1 -1
  236. package/lib/node/profiling-run.js.map +1 -1
  237. package/lib/node/rename-over-open-readers.d.ts +52 -0
  238. package/lib/node/rename-over-open-readers.d.ts.map +1 -0
  239. package/lib/node/rename-over-open-readers.js +66 -0
  240. package/lib/node/rename-over-open-readers.js.map +1 -0
  241. package/lib/node/socket-launcher.d.ts +15 -0
  242. package/lib/node/socket-launcher.d.ts.map +1 -1
  243. package/lib/node/socket-launcher.js +3 -2
  244. package/lib/node/socket-launcher.js.map +1 -1
  245. package/lib/testing/fake-document.d.ts +16 -4
  246. package/lib/testing/fake-document.d.ts.map +1 -1
  247. package/lib/testing/fake-document.js +18 -3
  248. package/lib/testing/fake-document.js.map +1 -1
  249. package/lib/testing/make-noop-shared-services.d.ts +14 -0
  250. package/lib/testing/make-noop-shared-services.d.ts.map +1 -1
  251. package/lib/testing/make-noop-shared-services.js +28 -2
  252. package/lib/testing/make-noop-shared-services.js.map +1 -1
  253. package/lib/testing/make-test-services.d.ts +44 -8
  254. package/lib/testing/make-test-services.d.ts.map +1 -1
  255. package/lib/testing/make-test-services.js +19 -3
  256. package/lib/testing/make-test-services.js.map +1 -1
  257. package/lib/testing/node/scratch-workspace.d.ts.map +1 -1
  258. package/lib/testing/node/scratch-workspace.js +9 -4
  259. package/lib/testing/node/scratch-workspace.js.map +1 -1
  260. package/lib/testing/node/spawned-server.d.ts +14 -0
  261. package/lib/testing/node/spawned-server.d.ts.map +1 -1
  262. package/lib/testing/node/spawned-server.js +33 -1
  263. package/lib/testing/node/spawned-server.js.map +1 -1
  264. package/lib/testing/playwright/flaky-network-proxy.d.ts +76 -0
  265. package/lib/testing/playwright/flaky-network-proxy.d.ts.map +1 -0
  266. package/lib/testing/playwright/flaky-network-proxy.js +164 -0
  267. package/lib/testing/playwright/flaky-network-proxy.js.map +1 -0
  268. package/lib/testing/playwright/index.d.ts +1 -0
  269. package/lib/testing/playwright/index.d.ts.map +1 -1
  270. package/lib/testing/playwright/index.js +1 -0
  271. package/lib/testing/playwright/index.js.map +1 -1
  272. package/lib/testing/playwright/server-log-capture.d.ts +14 -4
  273. package/lib/testing/playwright/server-log-capture.d.ts.map +1 -1
  274. package/lib/testing/playwright/server-log-capture.js +21 -4
  275. package/lib/testing/playwright/server-log-capture.js.map +1 -1
  276. package/lib/testing/playwright/server-log-rename-reporter.d.ts.map +1 -1
  277. package/lib/testing/playwright/server-log-rename-reporter.js +10 -1
  278. package/lib/testing/playwright/server-log-rename-reporter.js.map +1 -1
  279. package/lib/testing/stub-ast-document-manager.d.ts +5 -5
  280. package/lib/testing/stub-ast-document-manager.d.ts.map +1 -1
  281. package/lib/testing/stub-ast-document-manager.js +4 -6
  282. package/lib/testing/stub-ast-document-manager.js.map +1 -1
  283. package/lib/testing/stub-document-builder.d.ts +8 -0
  284. package/lib/testing/stub-document-builder.d.ts.map +1 -1
  285. package/lib/testing/stub-document-builder.js +22 -3
  286. package/lib/testing/stub-document-builder.js.map +1 -1
  287. package/lib/testing/stub-langium-documents.d.ts +3 -2
  288. package/lib/testing/stub-langium-documents.d.ts.map +1 -1
  289. package/lib/testing/stub-langium-documents.js.map +1 -1
  290. package/lib/testing/stub-model-service.d.ts +5 -4
  291. package/lib/testing/stub-model-service.d.ts.map +1 -1
  292. package/lib/testing/stub-model-service.js +2 -2
  293. package/lib/testing/stub-model-service.js.map +1 -1
  294. package/package.json +17 -8
  295. package/src/documents/ast-document-manager.ts +129 -36
  296. package/src/documents/client-ids.ts +5 -22
  297. package/src/documents/hydranium-text-documents.ts +248 -75
  298. package/src/documents/language-client-text-shadow.ts +59 -11
  299. package/src/documents/self-save-registry.ts +52 -13
  300. package/src/index.ts +6 -0
  301. package/src/langium/ast-extension/ast-node-builder.ts +66 -22
  302. package/src/langium/bootstrap.ts +16 -9
  303. package/src/langium/config/configuration-provider.ts +119 -0
  304. package/src/langium/config/index.ts +1 -0
  305. package/src/langium/diagnostics/lsp-logger.ts +41 -6
  306. package/src/langium/document-builder/build-pipeline-integration.ts +50 -5
  307. package/src/langium/document-builder/build-session.ts +87 -0
  308. package/src/langium/document-builder/document-builder.ts +339 -11
  309. package/src/langium/document-builder/index.ts +1 -0
  310. package/src/langium/integration-services.ts +67 -6
  311. package/src/langium/integrity/integrity-service.ts +116 -2
  312. package/src/langium/keys/containment.ts +87 -0
  313. package/src/langium/keys/index.ts +1 -0
  314. package/src/langium/keys/name-based-key-provider.ts +4 -0
  315. package/src/langium/language-module.ts +38 -0
  316. package/src/langium/model-service/model-service.ts +264 -32
  317. package/src/langium/module.ts +106 -21
  318. package/src/langium/naming/name-provider.ts +27 -5
  319. package/src/langium/naming/name-separator-validation.ts +34 -5
  320. package/src/langium/residency/cst-residency-service.ts +36 -14
  321. package/src/langium/scope/hydranium-scope-provider.ts +60 -22
  322. package/src/langium/serialization/abstract-serializer.ts +13 -32
  323. package/src/langium/service-registry.ts +19 -2
  324. package/src/langium/shared-services.ts +19 -2
  325. package/src/langium/transfer/transfer-encoder.ts +85 -24
  326. package/src/langium/trivia/comment-preserver.ts +1100 -0
  327. package/src/langium/trivia/document-ending-preserver.ts +55 -0
  328. package/src/langium/trivia/index.ts +14 -0
  329. package/src/langium/trivia/trivia-contribution.ts +39 -0
  330. package/src/langium/trivia/trivia-preserver.ts +54 -0
  331. package/src/langium/trivia/trivia-service.ts +99 -0
  332. package/src/langium/validation/document-validator.ts +537 -11
  333. package/src/langium/workspace/document-uri-policy.ts +3 -4
  334. package/src/langium/workspace/file-system-provider.ts +48 -8
  335. package/src/langium/workspace/hydranium-langium-document-factory.ts +34 -0
  336. package/src/langium/workspace/hydranium-workspace-manager.ts +30 -1
  337. package/src/langium/workspace/in-memory-file-system-provider.ts +53 -10
  338. package/src/langium/workspace/initialize-workspace.ts +34 -5
  339. package/src/langium/workspace/langium-documents.ts +106 -33
  340. package/src/langium/workspace/virtual-document.ts +21 -3
  341. package/src/locale/index.ts +10 -0
  342. package/src/locale/server-locale.ts +86 -0
  343. package/src/lsp/hydranium-document-update-handler.ts +1 -1
  344. package/src/lsp/index.ts +1 -1
  345. package/src/lsp/lsp-latency.ts +62 -0
  346. package/src/lsp/semantic-token-provider.ts +74 -7
  347. package/src/messages/carriers.ts +78 -0
  348. package/src/messages/index.ts +36 -0
  349. package/src/messages/renderer.ts +204 -0
  350. package/src/node/heap-ceiling.ts +108 -0
  351. package/src/node/index.ts +1 -0
  352. package/src/node/latency-from-env.ts +1 -1
  353. package/src/node/node-file-system-provider.ts +154 -47
  354. package/src/node/profile-capture.ts +8 -2
  355. package/src/node/profiling-run.ts +3 -3
  356. package/src/node/rename-over-open-readers.ts +78 -0
  357. package/src/node/socket-launcher.ts +18 -2
  358. package/src/testing/fake-document.ts +24 -5
  359. package/src/testing/make-noop-shared-services.ts +50 -2
  360. package/src/testing/make-test-services.ts +73 -18
  361. package/src/testing/node/scratch-workspace.ts +9 -4
  362. package/src/testing/node/spawned-server.ts +35 -1
  363. package/src/testing/playwright/flaky-network-proxy.ts +240 -0
  364. package/src/testing/playwright/index.ts +1 -0
  365. package/src/testing/playwright/server-log-capture.ts +24 -5
  366. package/src/testing/playwright/server-log-rename-reporter.ts +12 -1
  367. package/src/testing/stub-ast-document-manager.ts +10 -14
  368. package/src/testing/stub-document-builder.ts +32 -3
  369. package/src/testing/stub-langium-documents.ts +3 -2
  370. package/src/testing/stub-model-service.ts +7 -6
  371. package/lib/lsp/instrument-connection.d.ts +0 -36
  372. package/lib/lsp/instrument-connection.d.ts.map +0 -1
  373. package/lib/lsp/instrument-connection.js +0 -62
  374. package/lib/lsp/instrument-connection.js.map +0 -1
  375. package/src/lsp/instrument-connection.ts +0 -66
@@ -24,6 +24,17 @@ export default class ServerLogRenameReporter {
24
24
  }
25
25
 
26
26
  onEnd(): void {
27
- renameServerLogs(this.dir);
27
+ const unattributed = renameServerLogs(this.dir);
28
+ if (unattributed.length > 0) {
29
+ // Loud, because the alternative is a capture run that reads as
30
+ // complete: these logs exist and have content, but are named by an
31
+ // opaque workspace token and carry no test boundaries, so nothing
32
+ // about them says which spec they belong to.
33
+ console.warn(
34
+ `[server-log] ${unattributed.length} captured log(s) belong to no test: ${unattributed.join(', ')}.\n` +
35
+ '[server-log] Those specs never marked a boundary — apply the `serverLog` fixture, ' +
36
+ 'or call `markServerLog`/`attachServerLog` from the suite, or their logs cannot be read per test.'
37
+ );
38
+ }
28
39
  }
29
40
  }
@@ -9,8 +9,9 @@
9
9
 
10
10
  import { type AstNode, type LangiumDocument, UriUtils } from '@hydranium/langium';
11
11
  import { Disposable } from 'vscode-languageserver';
12
+ import { type AstDiagnostic } from '../langium/validation/document-validator.js';
12
13
  import {
13
- type AstDocument,
14
+ AstDocument,
14
15
  type AstDocumentManager,
15
16
  type AstDocumentUpdatedEvent,
16
17
  type WritableFileSystemProvider
@@ -27,9 +28,8 @@ import type { StubLangiumDocuments } from './stub-langium-documents.js';
27
28
  * underlying stub text-document manager, `onUpdate` is driven explicitly
28
29
  * through {@link StubAstDocumentManager.emitUpdate} because the stub tree runs
29
30
  * no build phases to emit from, and the remaining read helpers
30
- * (`isDirectChange`, `getAuthor`, `readFile`) throw if invoked — tests that
31
- * need them should wire a richer stub or use the real
32
- * {@link AstDocumentManager}.
31
+ * (`isTriggeringEdit`, `getAuthor`) throw if invoked — tests that need them
32
+ * should wire a richer stub or use the real {@link AstDocumentManager}.
33
33
  *
34
34
  * Open state is tracked per URI as the set of holding client ids, so a
35
35
  * document stays open until its last client closes. The stub forwards
@@ -45,7 +45,7 @@ import type { StubLangiumDocuments } from './stub-langium-documents.js';
45
45
  * are still picked so signature drift on them produces a compile
46
46
  * error rather than silent divergence.
47
47
  */
48
- export interface StubAstDocumentManager<TAst extends AstNode, TDiagnostic = unknown> extends Pick<
48
+ export interface StubAstDocumentManager<TAst extends AstNode, TDiagnostic extends AstDiagnostic = AstDiagnostic> extends Pick<
49
49
  AstDocumentManager<TAst, TDiagnostic>,
50
50
  | 'open'
51
51
  | 'close'
@@ -57,8 +57,7 @@ export interface StubAstDocumentManager<TAst extends AstNode, TDiagnostic = unkn
57
57
  | 'onClientClosed'
58
58
  | 'getAuthor'
59
59
  | 'getDocument'
60
- | 'isDirectChange'
61
- | 'readFile'
60
+ | 'isTriggeringEdit'
62
61
  > {
63
62
  readonly openClients: Map<string, Set<string>>;
64
63
 
@@ -104,7 +103,7 @@ export interface StubAstDocumentManager<TAst extends AstNode, TDiagnostic = unkn
104
103
  updateSubscriptions(uri?: string): number;
105
104
  }
106
105
 
107
- export function makeStubAstDocumentManager<TAst extends AstNode, TDiagnostic = unknown>(
106
+ export function makeStubAstDocumentManager<TAst extends AstNode, TDiagnostic extends AstDiagnostic = AstDiagnostic>(
108
107
  textDocuments: StubHydraniumTextDocuments,
109
108
  fileSystem: Pick<WritableFileSystemProvider, 'writeFile'>,
110
109
  documents?: StubLangiumDocuments<TAst, TDiagnostic>
@@ -193,7 +192,7 @@ export function makeStubAstDocumentManager<TAst extends AstNode, TDiagnostic = u
193
192
  return;
194
193
  }
195
194
  listener({
196
- document: { uri, version: textDocuments.version(uri), root: undefined as unknown as TAst, diagnostics: [] as TDiagnostic[] },
195
+ document: AstDocument.create<TAst, TDiagnostic>(uri, textDocuments.version(uri), undefined as unknown as TAst),
197
196
  sourceClientId: event.clientId
198
197
  });
199
198
  });
@@ -214,11 +213,8 @@ export function makeStubAstDocumentManager<TAst extends AstNode, TDiagnostic = u
214
213
  getDocument(uri: string): LangiumDocument | undefined {
215
214
  return documents?.getDocument(UriUtils.toUri(uri));
216
215
  },
217
- isDirectChange(): boolean {
218
- return notSupported('isDirectChange');
219
- },
220
- async readFile(uri: string): Promise<string> {
221
- return notSupported(`readFile(${uri})`);
216
+ isTriggeringEdit(): boolean {
217
+ return notSupported('isTriggeringEdit');
222
218
  }
223
219
  };
224
220
  }
@@ -9,6 +9,7 @@
9
9
 
10
10
  import {
11
11
  type DocumentBuilder,
12
+ type DocumentBuildListener,
12
13
  type DocumentPhaseListener,
13
14
  type DocumentState,
14
15
  type DocumentUpdateListener,
@@ -94,6 +95,14 @@ export interface StubDocumentBuilder extends Pick<
94
95
  firePhase(state: DocumentState, document: LangiumDocument, cancelToken?: CancellationToken): void;
95
96
  /** Synchronously fire every registered `onUpdate` listener. */
96
97
  fireOnUpdate(changed: URI[], deleted: URI[]): void;
98
+ /**
99
+ * Synchronously fire the BUILD-phase listener(s) for `state` with the whole
100
+ * batch. The per-build counterpart of {@link firePhase}: a subject that
101
+ * reports once per build rather than once per document subscribes here, and
102
+ * a stub that only fired {@link firePhase} would leave it silent while
103
+ * looking wired.
104
+ */
105
+ fireBuildPhase(state: DocumentState, built: LangiumDocument[], cancelToken?: CancellationToken): void;
97
106
  /**
98
107
  * Hold the next {@link waitUntil} call. The returned handle releases it;
99
108
  * the call's return value resolves on the next tick after `resolve` runs.
@@ -131,6 +140,7 @@ function reraise(result: unknown): void {
131
140
  */
132
141
  export function makeStubDocumentBuilder(): StubDocumentBuilder {
133
142
  const phaseListeners = new Map<DocumentState, DocumentPhaseListener[]>();
143
+ const buildPhaseListeners = new Map<DocumentState, DocumentBuildListener[]>();
134
144
  const onUpdateListeners: DocumentUpdateListener[] = [];
135
145
  const gates: Array<{ take(release: () => void): void }> = [];
136
146
  const updateCalls: RecordedBuilderCall<[URI[], URI[]]>[] = [];
@@ -194,6 +204,28 @@ export function makeStubDocumentBuilder(): StubDocumentBuilder {
194
204
  reraise(listener(changed, deleted));
195
205
  }
196
206
  },
207
+ onBuildPhase(state: DocumentState, listener: DocumentBuildListener) {
208
+ const list = buildPhaseListeners.get(state) ?? [];
209
+ list.push(listener);
210
+ buildPhaseListeners.set(state, list);
211
+ return Disposable.create(() => {
212
+ const idx = list.indexOf(listener);
213
+ if (idx >= 0) {
214
+ list.splice(idx, 1);
215
+ }
216
+ });
217
+ },
218
+ fireBuildPhase(state: DocumentState, built: LangiumDocument[], cancelToken?: CancellationToken) {
219
+ const token =
220
+ cancelToken ??
221
+ ({
222
+ isCancellationRequested: false,
223
+ onCancellationRequested: () => Disposable.create(() => undefined)
224
+ } as CancellationToken);
225
+ for (const listener of buildPhaseListeners.get(state) ?? []) {
226
+ reraise(listener(built, token));
227
+ }
228
+ },
197
229
  gateNextWaitUntil(): StubWaitUntilGate {
198
230
  let release: (() => void) | undefined;
199
231
  const entry = {
@@ -224,9 +256,6 @@ export function makeStubDocumentBuilder(): StubDocumentBuilder {
224
256
  build() {
225
257
  return notSupported('build');
226
258
  },
227
- onBuildPhase() {
228
- return notSupported('onBuildPhase');
229
- },
230
259
  resetToState() {
231
260
  return notSupported('resetToState');
232
261
  },
@@ -9,6 +9,7 @@
9
9
 
10
10
  import { type AstNode, type LangiumDocument, type LangiumDocuments, stream, type URI } from '@hydranium/langium';
11
11
  import { makeFakeAstNode, makeFakeDocument, type FakeDocumentOptions } from './fake-document.js';
12
+ import { type AstDiagnostic } from '../langium/validation/document-validator.js';
12
13
 
13
14
  /**
14
15
  * Map-backed stub for Langium's {@link LangiumDocuments} registry. Implements
@@ -31,7 +32,7 @@ import { makeFakeAstNode, makeFakeDocument, type FakeDocumentOptions } from './f
31
32
  * production code reads the slot value through the `LangiumDocuments`
32
33
  * interface and a narrowing cast bridges the stub at the binding site.
33
34
  */
34
- export interface StubLangiumDocuments<TAst extends AstNode = AstNode, TDiagnostic = unknown> extends Pick<
35
+ export interface StubLangiumDocuments<TAst extends AstNode = AstNode, TDiagnostic extends AstDiagnostic = AstDiagnostic> extends Pick<
35
36
  LangiumDocuments,
36
37
  'getDocument' | 'hasDocument' | 'getOrCreateDocument' | 'all'
37
38
  > {
@@ -51,7 +52,7 @@ export interface StubLangiumDocuments<TAst extends AstNode = AstNode, TDiagnosti
51
52
  * Build a {@link StubLangiumDocuments}. Seed entries via the optional
52
53
  * `seeds` parameter so simple tests don't need a separate `set` call.
53
54
  */
54
- export function makeStubLangiumDocuments<TAst extends AstNode = AstNode, TDiagnostic = unknown>(
55
+ export function makeStubLangiumDocuments<TAst extends AstNode = AstNode, TDiagnostic extends AstDiagnostic = AstDiagnostic>(
55
56
  seeds: ReadonlyArray<{ uri: string | URI; root: TAst; options?: FakeDocumentOptions<TAst, TDiagnostic> }> = []
56
57
  ): StubLangiumDocuments<TAst, TDiagnostic> {
57
58
  const docs = new Map<string, LangiumDocument<TAst>>();
@@ -7,9 +7,10 @@
7
7
  * SPDX-License-Identifier: MIT
8
8
  ********************************************************************************/
9
9
 
10
- import type { TransferDiagnostic, TransferElement } from '@hydranium/protocol';
10
+ import type { TransferElement } from '@hydranium/protocol';
11
+ import type { AstDiagnostic } from '../langium/validation/document-validator.js';
11
12
  import type { AstNode } from '@hydranium/langium';
12
- import { ModelService, type ModelServiceOptions } from '../langium/model-service/model-service.js';
13
+ import { DefaultModelService, type ModelService, type ModelServiceOptions } from '../langium/model-service/model-service.js';
13
14
  import type { ServerSharedServices } from '../langium/module.js';
14
15
 
15
16
  /**
@@ -21,9 +22,9 @@ import type { ServerSharedServices } from '../langium/module.js';
21
22
  */
22
23
  class StubModelServiceImpl<
23
24
  TAst extends AstNode,
24
- TDiagnostic extends TransferDiagnostic = TransferDiagnostic,
25
+ TDiagnostic extends AstDiagnostic = AstDiagnostic,
25
26
  TTransfer extends TransferElement = TransferElement
26
- > extends ModelService<TAst, TDiagnostic, TTransfer> {
27
+ > extends DefaultModelService<TAst, TDiagnostic, TTransfer> {
27
28
  constructor(
28
29
  services: ServerSharedServices,
29
30
  protected readonly serializeFn: (uri: string, root: TTransfer) => string,
@@ -40,7 +41,7 @@ class StubModelServiceImpl<
40
41
  /** The type of the model-service test double produced by {@link makeStubModelService}. */
41
42
  export type StubModelService<
42
43
  TAst extends AstNode,
43
- TDiagnostic extends TransferDiagnostic = TransferDiagnostic,
44
+ TDiagnostic extends AstDiagnostic = AstDiagnostic,
44
45
  TTransfer extends TransferElement = TransferElement
45
46
  > = ModelService<TAst, TDiagnostic, TTransfer>;
46
47
 
@@ -61,7 +62,7 @@ export type StubModelService<
61
62
  */
62
63
  export function makeStubModelService<
63
64
  TAst extends AstNode,
64
- TDiagnostic extends TransferDiagnostic = TransferDiagnostic,
65
+ TDiagnostic extends AstDiagnostic = AstDiagnostic,
65
66
  TTransfer extends TransferElement = TransferElement
66
67
  >(
67
68
  services: ServerSharedServices,
@@ -1,36 +0,0 @@
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 { LatencyCollector } from '@hydranium/protocol';
10
- /**
11
- * Wrap an LSP `Connection` so every request handler registered through
12
- * `onRequest` is timed into `latency` under its method name — the LSP analog of
13
- * the data-server RPC chokepoint. Langium's `startLanguageServer` registers
14
- * `onCompletion`/`onHover`/… one handler at a time, so there is no single
15
- * dispatch point; but every registration funnels through the ONE `onRequest`
16
- * on the shared `Connection`, so decorating it catches every method with no
17
- * Langium fork and no per-handler code.
18
- *
19
- * Opt in where the head creates the connection, before it hands it to the
20
- * services factory — wrapping it afterwards is too late, because Langium has
21
- * already registered its handlers against the raw connection.
22
- *
23
- * `onRequest` has several overloads: most register a handler for a specific
24
- * method (a string, or a typed request whose `.method` names it) and one is the
25
- * `StarRequestHandler` catch-all `onRequest(handler)`. The star form fires only
26
- * for methods with no registered handler, so timing it would be misleading — it
27
- * is passed through untouched. Every other member of the connection is
28
- * forwarded unchanged.
29
- *
30
- * When `latency` is `undefined` the seam is off: the connection is returned
31
- * unchanged (no Proxy, no per-request timing), so a head can pass the result of
32
- * an env-gated factory (`latencyFromEnv()`) straight through and pay nothing
33
- * when latency is not enabled.
34
- */
35
- export declare function instrumentLspConnection<C extends object>(connection: C, latency: LatencyCollector | undefined): C;
36
- //# sourceMappingURL=instrument-connection.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"instrument-connection.d.ts","sourceRoot":"","sources":["../../src/lsp/instrument-connection.ts"],"names":[],"mappings":"AAAA;;;;;;;kFAOkF;AAElF,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,qBAAqB,CAAC;AAI5D;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AACH,wBAAgB,uBAAuB,CAAC,CAAC,SAAS,MAAM,EAAE,UAAU,EAAE,CAAC,EAAE,OAAO,EAAE,gBAAgB,GAAG,SAAS,GAAG,CAAC,CA2BjH"}
@@ -1,62 +0,0 @@
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
- * Wrap an LSP `Connection` so every request handler registered through
11
- * `onRequest` is timed into `latency` under its method name — the LSP analog of
12
- * the data-server RPC chokepoint. Langium's `startLanguageServer` registers
13
- * `onCompletion`/`onHover`/… one handler at a time, so there is no single
14
- * dispatch point; but every registration funnels through the ONE `onRequest`
15
- * on the shared `Connection`, so decorating it catches every method with no
16
- * Langium fork and no per-handler code.
17
- *
18
- * Opt in where the head creates the connection, before it hands it to the
19
- * services factory — wrapping it afterwards is too late, because Langium has
20
- * already registered its handlers against the raw connection.
21
- *
22
- * `onRequest` has several overloads: most register a handler for a specific
23
- * method (a string, or a typed request whose `.method` names it) and one is the
24
- * `StarRequestHandler` catch-all `onRequest(handler)`. The star form fires only
25
- * for methods with no registered handler, so timing it would be misleading — it
26
- * is passed through untouched. Every other member of the connection is
27
- * forwarded unchanged.
28
- *
29
- * When `latency` is `undefined` the seam is off: the connection is returned
30
- * unchanged (no Proxy, no per-request timing), so a head can pass the result of
31
- * an env-gated factory (`latencyFromEnv()`) straight through and pay nothing
32
- * when latency is not enabled.
33
- */
34
- export function instrumentLspConnection(connection, latency) {
35
- if (!latency) {
36
- return connection;
37
- }
38
- return new Proxy(connection, {
39
- get(target, property, receiver) {
40
- const value = Reflect.get(target, property, receiver);
41
- if (property !== 'onRequest' || typeof value !== 'function') {
42
- return value;
43
- }
44
- const onRequest = value;
45
- return (...args) => {
46
- const [first, handler] = args;
47
- // Star form `onRequest(handler)` — pass through; it is not a timer.
48
- if (typeof first === 'function' || typeof handler !== 'function') {
49
- return onRequest.apply(target, args);
50
- }
51
- const method = typeof first === 'string' ? first : first.method;
52
- if (typeof method !== 'string') {
53
- return onRequest.apply(target, args);
54
- }
55
- const original = handler;
56
- const timed = (...handlerArgs) => latency.time(method, () => original(...handlerArgs));
57
- return onRequest.apply(target, [first, timed, ...args.slice(2)]);
58
- };
59
- }
60
- });
61
- }
62
- //# sourceMappingURL=instrument-connection.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"instrument-connection.js","sourceRoot":"","sources":["../../src/lsp/instrument-connection.ts"],"names":[],"mappings":"AAAA;;;;;;;kFAOkF;AAMlF;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AACH,MAAM,UAAU,uBAAuB,CAAmB,UAAa,EAAE,OAAqC;IAC3G,IAAI,CAAC,OAAO,EAAE,CAAC;QACZ,OAAO,UAAU,CAAC;IACrB,CAAC;IACD,OAAO,IAAI,KAAK,CAAC,UAAU,EAAE;QAC1B,GAAG,CAAC,MAAM,EAAE,QAAQ,EAAE,QAAQ;YAC3B,MAAM,KAAK,GAAY,OAAO,CAAC,GAAG,CAAC,MAAM,EAAE,QAAQ,EAAE,QAAQ,CAAC,CAAC;YAC/D,IAAI,QAAQ,KAAK,WAAW,IAAI,OAAO,KAAK,KAAK,UAAU,EAAE,CAAC;gBAC3D,OAAO,KAAK,CAAC;YAChB,CAAC;YACD,MAAM,SAAS,GAAG,KAAwC,CAAC;YAC3D,OAAO,CAAC,GAAG,IAAe,EAAW,EAAE;gBACpC,MAAM,CAAC,KAAK,EAAE,OAAO,CAAC,GAAG,IAAI,CAAC;gBAC9B,oEAAoE;gBACpE,IAAI,OAAO,KAAK,KAAK,UAAU,IAAI,OAAO,OAAO,KAAK,UAAU,EAAE,CAAC;oBAChE,OAAO,SAAS,CAAC,KAAK,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC;gBACxC,CAAC;gBACD,MAAM,MAAM,GAAG,OAAO,KAAK,KAAK,QAAQ,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAE,KAA8B,CAAC,MAAM,CAAC;gBAC1F,IAAI,OAAO,MAAM,KAAK,QAAQ,EAAE,CAAC;oBAC9B,OAAO,SAAS,CAAC,KAAK,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC;gBACxC,CAAC;gBACD,MAAM,QAAQ,GAAG,OAAyB,CAAC;gBAC3C,MAAM,KAAK,GAAmB,CAAC,GAAG,WAAW,EAAE,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC,MAAM,EAAE,GAAG,EAAE,CAAC,QAAQ,CAAC,GAAG,WAAW,CAAC,CAAC,CAAC;gBACvG,OAAO,SAAS,CAAC,KAAK,CAAC,MAAM,EAAE,CAAC,KAAK,EAAE,KAAK,EAAE,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;YACpE,CAAC,CAAC;QACL,CAAC;KACH,CAAC,CAAC;AACN,CAAC"}
@@ -1,66 +0,0 @@
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
- import type { LatencyCollector } from '@hydranium/protocol';
11
-
12
- type RequestHandler = (...args: unknown[]) => unknown;
13
-
14
- /**
15
- * Wrap an LSP `Connection` so every request handler registered through
16
- * `onRequest` is timed into `latency` under its method name — the LSP analog of
17
- * the data-server RPC chokepoint. Langium's `startLanguageServer` registers
18
- * `onCompletion`/`onHover`/… one handler at a time, so there is no single
19
- * dispatch point; but every registration funnels through the ONE `onRequest`
20
- * on the shared `Connection`, so decorating it catches every method with no
21
- * Langium fork and no per-handler code.
22
- *
23
- * Opt in where the head creates the connection, before it hands it to the
24
- * services factory — wrapping it afterwards is too late, because Langium has
25
- * already registered its handlers against the raw connection.
26
- *
27
- * `onRequest` has several overloads: most register a handler for a specific
28
- * method (a string, or a typed request whose `.method` names it) and one is the
29
- * `StarRequestHandler` catch-all `onRequest(handler)`. The star form fires only
30
- * for methods with no registered handler, so timing it would be misleading — it
31
- * is passed through untouched. Every other member of the connection is
32
- * forwarded unchanged.
33
- *
34
- * When `latency` is `undefined` the seam is off: the connection is returned
35
- * unchanged (no Proxy, no per-request timing), so a head can pass the result of
36
- * an env-gated factory (`latencyFromEnv()`) straight through and pay nothing
37
- * when latency is not enabled.
38
- */
39
- export function instrumentLspConnection<C extends object>(connection: C, latency: LatencyCollector | undefined): C {
40
- if (!latency) {
41
- return connection;
42
- }
43
- return new Proxy(connection, {
44
- get(target, property, receiver): unknown {
45
- const value: unknown = Reflect.get(target, property, receiver);
46
- if (property !== 'onRequest' || typeof value !== 'function') {
47
- return value;
48
- }
49
- const onRequest = value as (...args: unknown[]) => unknown;
50
- return (...args: unknown[]): unknown => {
51
- const [first, handler] = args;
52
- // Star form `onRequest(handler)` — pass through; it is not a timer.
53
- if (typeof first === 'function' || typeof handler !== 'function') {
54
- return onRequest.apply(target, args);
55
- }
56
- const method = typeof first === 'string' ? first : (first as { method?: unknown }).method;
57
- if (typeof method !== 'string') {
58
- return onRequest.apply(target, args);
59
- }
60
- const original = handler as RequestHandler;
61
- const timed: RequestHandler = (...handlerArgs) => latency.time(method, () => original(...handlerArgs));
62
- return onRequest.apply(target, [first, timed, ...args.slice(2)]);
63
- };
64
- }
65
- });
66
- }