@hydranium/core 1.0.0-next.19 → 1.0.0-next.193

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 (588) hide show
  1. package/README.md +6 -2
  2. package/lib/documents/ast-document-manager.d.ts +222 -63
  3. package/lib/documents/ast-document-manager.d.ts.map +1 -1
  4. package/lib/documents/ast-document-manager.js +250 -83
  5. package/lib/documents/ast-document-manager.js.map +1 -1
  6. package/lib/documents/client-ids.d.ts +5 -19
  7. package/lib/documents/client-ids.d.ts.map +1 -1
  8. package/lib/documents/client-ids.js +5 -19
  9. package/lib/documents/client-ids.js.map +1 -1
  10. package/lib/documents/client-session-errors.d.ts +15 -0
  11. package/lib/documents/client-session-errors.d.ts.map +1 -0
  12. package/lib/documents/client-session-errors.js +15 -0
  13. package/lib/documents/client-session-errors.js.map +1 -0
  14. package/lib/documents/client-session-registry.d.ts +138 -0
  15. package/lib/documents/client-session-registry.d.ts.map +1 -0
  16. package/lib/documents/client-session-registry.js +187 -0
  17. package/lib/documents/client-session-registry.js.map +1 -0
  18. package/lib/documents/file-system-task-queue.d.ts +49 -0
  19. package/lib/documents/file-system-task-queue.d.ts.map +1 -0
  20. package/lib/documents/file-system-task-queue.js +34 -0
  21. package/lib/documents/file-system-task-queue.js.map +1 -0
  22. package/lib/documents/hydranium-text-documents.d.ts +523 -101
  23. package/lib/documents/hydranium-text-documents.d.ts.map +1 -1
  24. package/lib/documents/hydranium-text-documents.js +961 -177
  25. package/lib/documents/hydranium-text-documents.js.map +1 -1
  26. package/lib/documents/index.d.ts +5 -0
  27. package/lib/documents/index.d.ts.map +1 -1
  28. package/lib/documents/index.js +5 -0
  29. package/lib/documents/index.js.map +1 -1
  30. package/lib/documents/language-client-text-shadow.d.ts +41 -9
  31. package/lib/documents/language-client-text-shadow.d.ts.map +1 -1
  32. package/lib/documents/language-client-text-shadow.js +56 -11
  33. package/lib/documents/language-client-text-shadow.js.map +1 -1
  34. package/lib/documents/model-ledger.d.ts +47 -0
  35. package/lib/documents/model-ledger.d.ts.map +1 -0
  36. package/lib/documents/model-ledger.js +30 -0
  37. package/lib/documents/model-ledger.js.map +1 -0
  38. package/lib/documents/self-save-registry.d.ts +37 -6
  39. package/lib/documents/self-save-registry.d.ts.map +1 -1
  40. package/lib/documents/self-save-registry.js +28 -15
  41. package/lib/documents/self-save-registry.js.map +1 -1
  42. package/lib/documents/version-sync-service.d.ts +134 -0
  43. package/lib/documents/version-sync-service.d.ts.map +1 -0
  44. package/lib/documents/version-sync-service.js +171 -0
  45. package/lib/documents/version-sync-service.js.map +1 -0
  46. package/lib/index.d.ts +3 -0
  47. package/lib/index.d.ts.map +1 -1
  48. package/lib/index.js +6 -0
  49. package/lib/index.js.map +1 -1
  50. package/lib/langium/ast-extension/ast-extension-service.d.ts.map +1 -1
  51. package/lib/langium/ast-extension/ast-extension-service.js.map +1 -1
  52. package/lib/langium/ast-extension/ast-node-builder.d.ts +32 -9
  53. package/lib/langium/ast-extension/ast-node-builder.d.ts.map +1 -1
  54. package/lib/langium/ast-extension/ast-node-builder.js +60 -22
  55. package/lib/langium/ast-extension/ast-node-builder.js.map +1 -1
  56. package/lib/langium/bootstrap.d.ts.map +1 -1
  57. package/lib/langium/bootstrap.js +32 -9
  58. package/lib/langium/bootstrap.js.map +1 -1
  59. package/lib/langium/build-phase-pass/build-phase-pass-service.d.ts.map +1 -1
  60. package/lib/langium/build-phase-pass/build-phase-pass-service.js.map +1 -1
  61. package/lib/langium/config/configuration-provider.d.ts +81 -0
  62. package/lib/langium/config/configuration-provider.d.ts.map +1 -0
  63. package/lib/langium/config/configuration-provider.js +112 -0
  64. package/lib/langium/config/configuration-provider.js.map +1 -0
  65. package/lib/langium/config/index.d.ts +1 -0
  66. package/lib/langium/config/index.d.ts.map +1 -1
  67. package/lib/langium/config/index.js +1 -0
  68. package/lib/langium/config/index.js.map +1 -1
  69. package/lib/langium/config/settings.js.map +1 -1
  70. package/lib/langium/diagnostics/hydranium-langium-profiler.d.ts.map +1 -1
  71. package/lib/langium/diagnostics/hydranium-langium-profiler.js.map +1 -1
  72. package/lib/langium/diagnostics/logger.d.ts +10 -3
  73. package/lib/langium/diagnostics/logger.d.ts.map +1 -1
  74. package/lib/langium/diagnostics/logger.js +12 -5
  75. package/lib/langium/diagnostics/logger.js.map +1 -1
  76. package/lib/langium/diagnostics/lsp-logger.d.ts +17 -0
  77. package/lib/langium/diagnostics/lsp-logger.d.ts.map +1 -1
  78. package/lib/langium/diagnostics/lsp-logger.js +56 -13
  79. package/lib/langium/diagnostics/lsp-logger.js.map +1 -1
  80. package/lib/langium/diagnostics/server-tracer.d.ts.map +1 -1
  81. package/lib/langium/diagnostics/server-tracer.js.map +1 -1
  82. package/lib/langium/document-builder/build-pipeline-integration.d.ts +21 -1
  83. package/lib/langium/document-builder/build-pipeline-integration.d.ts.map +1 -1
  84. package/lib/langium/document-builder/build-pipeline-integration.js +32 -5
  85. package/lib/langium/document-builder/build-pipeline-integration.js.map +1 -1
  86. package/lib/langium/document-builder/build-session.d.ts +93 -0
  87. package/lib/langium/document-builder/build-session.d.ts.map +1 -0
  88. package/lib/langium/document-builder/build-session.js +72 -0
  89. package/lib/langium/document-builder/build-session.js.map +1 -0
  90. package/lib/langium/document-builder/document-builder.d.ts +382 -29
  91. package/lib/langium/document-builder/document-builder.d.ts.map +1 -1
  92. package/lib/langium/document-builder/document-builder.js +659 -61
  93. package/lib/langium/document-builder/document-builder.js.map +1 -1
  94. package/lib/langium/document-builder/index.d.ts +1 -0
  95. package/lib/langium/document-builder/index.d.ts.map +1 -1
  96. package/lib/langium/document-builder/index.js +1 -0
  97. package/lib/langium/document-builder/index.js.map +1 -1
  98. package/lib/langium/documentation/comment-provider.d.ts.map +1 -1
  99. package/lib/langium/documentation/comment-provider.js.map +1 -1
  100. package/lib/langium/integration-services.d.ts +45 -1
  101. package/lib/langium/integration-services.d.ts.map +1 -1
  102. package/lib/langium/integration-services.js +10 -5
  103. package/lib/langium/integration-services.js.map +1 -1
  104. package/lib/langium/integrity/integrity-rule.d.ts +13 -5
  105. package/lib/langium/integrity/integrity-rule.d.ts.map +1 -1
  106. package/lib/langium/integrity/integrity-rule.js.map +1 -1
  107. package/lib/langium/integrity/integrity-service.d.ts +58 -13
  108. package/lib/langium/integrity/integrity-service.d.ts.map +1 -1
  109. package/lib/langium/integrity/integrity-service.js +204 -29
  110. package/lib/langium/integrity/integrity-service.js.map +1 -1
  111. package/lib/langium/keys/containment.d.ts +64 -0
  112. package/lib/langium/keys/containment.d.ts.map +1 -0
  113. package/lib/langium/keys/containment.js +53 -0
  114. package/lib/langium/keys/containment.js.map +1 -0
  115. package/lib/langium/keys/index.d.ts +1 -0
  116. package/lib/langium/keys/index.d.ts.map +1 -1
  117. package/lib/langium/keys/index.js +1 -0
  118. package/lib/langium/keys/index.js.map +1 -1
  119. package/lib/langium/keys/name-based-key-provider.d.ts +4 -0
  120. package/lib/langium/keys/name-based-key-provider.d.ts.map +1 -1
  121. package/lib/langium/keys/name-based-key-provider.js +4 -0
  122. package/lib/langium/keys/name-based-key-provider.js.map +1 -1
  123. package/lib/langium/keys/positional-key-provider.d.ts.map +1 -1
  124. package/lib/langium/keys/positional-key-provider.js.map +1 -1
  125. package/lib/langium/labeling/label-provider.d.ts.map +1 -1
  126. package/lib/langium/labeling/label-provider.js.map +1 -1
  127. package/lib/langium/language-module.d.ts +27 -2
  128. package/lib/langium/language-module.d.ts.map +1 -1
  129. package/lib/langium/language-module.js +16 -2
  130. package/lib/langium/language-module.js.map +1 -1
  131. package/lib/langium/model-service/client-session.d.ts +330 -0
  132. package/lib/langium/model-service/client-session.d.ts.map +1 -0
  133. package/lib/langium/model-service/client-session.js +418 -0
  134. package/lib/langium/model-service/client-session.js.map +1 -0
  135. package/lib/langium/model-service/index.d.ts +1 -0
  136. package/lib/langium/model-service/index.d.ts.map +1 -1
  137. package/lib/langium/model-service/index.js +1 -0
  138. package/lib/langium/model-service/index.js.map +1 -1
  139. package/lib/langium/model-service/model-service.d.ts +353 -253
  140. package/lib/langium/model-service/model-service.d.ts.map +1 -1
  141. package/lib/langium/model-service/model-service.js +361 -408
  142. package/lib/langium/model-service/model-service.js.map +1 -1
  143. package/lib/langium/module.d.ts +150 -35
  144. package/lib/langium/module.d.ts.map +1 -1
  145. package/lib/langium/module.js +50 -35
  146. package/lib/langium/module.js.map +1 -1
  147. package/lib/langium/naming/name-provider.d.ts +25 -4
  148. package/lib/langium/naming/name-provider.d.ts.map +1 -1
  149. package/lib/langium/naming/name-provider.js +2 -1
  150. package/lib/langium/naming/name-provider.js.map +1 -1
  151. package/lib/langium/naming/name-separator-validation.d.ts +23 -0
  152. package/lib/langium/naming/name-separator-validation.d.ts.map +1 -1
  153. package/lib/langium/naming/name-separator-validation.js +30 -1
  154. package/lib/langium/naming/name-separator-validation.js.map +1 -1
  155. package/lib/langium/project/abstract-project-manager.d.ts.map +1 -1
  156. package/lib/langium/project/abstract-project-manager.js +9 -2
  157. package/lib/langium/project/abstract-project-manager.js.map +1 -1
  158. package/lib/langium/project/project-change-event.d.ts +2 -2
  159. package/lib/langium/project/single-project-manager.d.ts.map +1 -1
  160. package/lib/langium/project/single-project-manager.js.map +1 -1
  161. package/lib/langium/residency/cst-residency-service.d.ts +31 -11
  162. package/lib/langium/residency/cst-residency-service.d.ts.map +1 -1
  163. package/lib/langium/residency/cst-residency-service.js +23 -57
  164. package/lib/langium/residency/cst-residency-service.js.map +1 -1
  165. package/lib/langium/scope/ast-node-description-provider.d.ts.map +1 -1
  166. package/lib/langium/scope/ast-node-description-provider.js.map +1 -1
  167. package/lib/langium/scope/hydranium-scope-computation.d.ts.map +1 -1
  168. package/lib/langium/scope/hydranium-scope-computation.js.map +1 -1
  169. package/lib/langium/scope/hydranium-scope-provider.d.ts +48 -13
  170. package/lib/langium/scope/hydranium-scope-provider.d.ts.map +1 -1
  171. package/lib/langium/scope/hydranium-scope-provider.js +56 -20
  172. package/lib/langium/scope/hydranium-scope-provider.js.map +1 -1
  173. package/lib/langium/scope/reference-builder.d.ts.map +1 -1
  174. package/lib/langium/scope/reference-builder.js.map +1 -1
  175. package/lib/langium/scope/reference-candidate-provider.d.ts.map +1 -1
  176. package/lib/langium/scope/reference-candidate-provider.js.map +1 -1
  177. package/lib/langium/scope/scope-extension-service.d.ts.map +1 -1
  178. package/lib/langium/scope/scope-extension-service.js.map +1 -1
  179. package/lib/langium/serialization/abstract-serializer.d.ts +11 -20
  180. package/lib/langium/serialization/abstract-serializer.d.ts.map +1 -1
  181. package/lib/langium/serialization/abstract-serializer.js +12 -21
  182. package/lib/langium/serialization/abstract-serializer.js.map +1 -1
  183. package/lib/langium/serialization/json-serializer.d.ts +1 -1
  184. package/lib/langium/serialization/json-serializer.d.ts.map +1 -1
  185. package/lib/langium/serialization/json-serializer.js.map +1 -1
  186. package/lib/langium/serialization/yaml-serializer.d.ts.map +1 -1
  187. package/lib/langium/serialization/yaml-serializer.js.map +1 -1
  188. package/lib/langium/service-registry.d.ts +15 -1
  189. package/lib/langium/service-registry.d.ts.map +1 -1
  190. package/lib/langium/service-registry.js +16 -0
  191. package/lib/langium/service-registry.js.map +1 -1
  192. package/lib/langium/shared-services.d.ts +21 -4
  193. package/lib/langium/shared-services.d.ts.map +1 -1
  194. package/lib/langium/shared-services.js.map +1 -1
  195. package/lib/langium/transfer/transfer-encoder.d.ts +75 -23
  196. package/lib/langium/transfer/transfer-encoder.d.ts.map +1 -1
  197. package/lib/langium/transfer/transfer-encoder.js +44 -21
  198. package/lib/langium/transfer/transfer-encoder.js.map +1 -1
  199. package/lib/langium/trivia/comment-preserver.d.ts +423 -0
  200. package/lib/langium/trivia/comment-preserver.d.ts.map +1 -0
  201. package/lib/langium/trivia/comment-preserver.js +906 -0
  202. package/lib/langium/trivia/comment-preserver.js.map +1 -0
  203. package/lib/langium/trivia/document-ending-preserver.d.ts +43 -0
  204. package/lib/langium/trivia/document-ending-preserver.d.ts.map +1 -0
  205. package/lib/langium/trivia/document-ending-preserver.js +48 -0
  206. package/lib/langium/trivia/document-ending-preserver.js.map +1 -0
  207. package/lib/langium/trivia/index.d.ts +14 -0
  208. package/lib/langium/trivia/index.d.ts.map +1 -0
  209. package/lib/langium/trivia/index.js +14 -0
  210. package/lib/langium/trivia/index.js.map +1 -0
  211. package/lib/langium/trivia/trivia-contribution.d.ts +37 -0
  212. package/lib/langium/trivia/trivia-contribution.d.ts.map +1 -0
  213. package/lib/langium/trivia/trivia-contribution.js +10 -0
  214. package/lib/langium/trivia/trivia-contribution.js.map +1 -0
  215. package/lib/langium/trivia/trivia-preserver.d.ts +50 -0
  216. package/lib/langium/trivia/trivia-preserver.d.ts.map +1 -0
  217. package/lib/langium/trivia/trivia-preserver.js +10 -0
  218. package/lib/langium/trivia/trivia-preserver.js.map +1 -0
  219. package/lib/langium/trivia/trivia-service.d.ts +70 -0
  220. package/lib/langium/trivia/trivia-service.d.ts.map +1 -0
  221. package/lib/langium/trivia/trivia-service.js +56 -0
  222. package/lib/langium/trivia/trivia-service.js.map +1 -0
  223. package/lib/langium/update-rewrite/normalize-empty-strings.d.ts.map +1 -1
  224. package/lib/langium/update-rewrite/update-rewrite-service.d.ts.map +1 -1
  225. package/lib/langium/update-rewrite/update-rewrite-service.js.map +1 -1
  226. package/lib/langium/update-rewrite/update-rewrite.d.ts +1 -1
  227. package/lib/langium/validation/document-validator.d.ts +294 -10
  228. package/lib/langium/validation/document-validator.d.ts.map +1 -1
  229. package/lib/langium/validation/document-validator.js +448 -5
  230. package/lib/langium/validation/document-validator.js.map +1 -1
  231. package/lib/langium/validation/validation-contribution-collector.d.ts.map +1 -1
  232. package/lib/langium/validation/validation-contribution-collector.js.map +1 -1
  233. package/lib/langium/workspace/document-uri-policy.d.ts +17 -12
  234. package/lib/langium/workspace/document-uri-policy.d.ts.map +1 -1
  235. package/lib/langium/workspace/document-uri-policy.js +10 -9
  236. package/lib/langium/workspace/document-uri-policy.js.map +1 -1
  237. package/lib/langium/workspace/file-not-found.d.ts +17 -0
  238. package/lib/langium/workspace/file-not-found.d.ts.map +1 -0
  239. package/lib/langium/workspace/file-not-found.js +20 -0
  240. package/lib/langium/workspace/file-not-found.js.map +1 -0
  241. package/lib/langium/workspace/file-system-provider.d.ts +84 -8
  242. package/lib/langium/workspace/file-system-provider.d.ts.map +1 -1
  243. package/lib/langium/workspace/file-system-provider.js +93 -14
  244. package/lib/langium/workspace/file-system-provider.js.map +1 -1
  245. package/lib/langium/workspace/hydranium-langium-document-factory.d.ts +56 -1
  246. package/lib/langium/workspace/hydranium-langium-document-factory.d.ts.map +1 -1
  247. package/lib/langium/workspace/hydranium-langium-document-factory.js +79 -0
  248. package/lib/langium/workspace/hydranium-langium-document-factory.js.map +1 -1
  249. package/lib/langium/workspace/hydranium-workspace-lock.d.ts +43 -1
  250. package/lib/langium/workspace/hydranium-workspace-lock.d.ts.map +1 -1
  251. package/lib/langium/workspace/hydranium-workspace-lock.js +58 -1
  252. package/lib/langium/workspace/hydranium-workspace-lock.js.map +1 -1
  253. package/lib/langium/workspace/hydranium-workspace-manager.d.ts +81 -8
  254. package/lib/langium/workspace/hydranium-workspace-manager.d.ts.map +1 -1
  255. package/lib/langium/workspace/hydranium-workspace-manager.js +128 -10
  256. package/lib/langium/workspace/hydranium-workspace-manager.js.map +1 -1
  257. package/lib/langium/workspace/in-memory-file-system-provider.d.ts +25 -2
  258. package/lib/langium/workspace/in-memory-file-system-provider.d.ts.map +1 -1
  259. package/lib/langium/workspace/in-memory-file-system-provider.js +41 -15
  260. package/lib/langium/workspace/in-memory-file-system-provider.js.map +1 -1
  261. package/lib/langium/workspace/index-manager.d.ts.map +1 -1
  262. package/lib/langium/workspace/index-manager.js.map +1 -1
  263. package/lib/langium/workspace/initialize-workspace.d.ts +31 -2
  264. package/lib/langium/workspace/initialize-workspace.d.ts.map +1 -1
  265. package/lib/langium/workspace/initialize-workspace.js +13 -5
  266. package/lib/langium/workspace/initialize-workspace.js.map +1 -1
  267. package/lib/langium/workspace/langium-documents.d.ts +86 -17
  268. package/lib/langium/workspace/langium-documents.d.ts.map +1 -1
  269. package/lib/langium/workspace/langium-documents.js +101 -29
  270. package/lib/langium/workspace/langium-documents.js.map +1 -1
  271. package/lib/langium/workspace/persistent-file-system-provider.d.ts +0 -7
  272. package/lib/langium/workspace/persistent-file-system-provider.d.ts.map +1 -1
  273. package/lib/langium/workspace/persistent-file-system-provider.js +0 -7
  274. package/lib/langium/workspace/persistent-file-system-provider.js.map +1 -1
  275. package/lib/langium/workspace/virtual-document.d.ts +48 -15
  276. package/lib/langium/workspace/virtual-document.d.ts.map +1 -1
  277. package/lib/langium/workspace/virtual-document.js +78 -18
  278. package/lib/langium/workspace/virtual-document.js.map +1 -1
  279. package/lib/langium/workspace/write-lock-scope.d.ts +20 -10
  280. package/lib/langium/workspace/write-lock-scope.d.ts.map +1 -1
  281. package/lib/langium/workspace/write-lock-scope.js +12 -4
  282. package/lib/langium/workspace/write-lock-scope.js.map +1 -1
  283. package/lib/locale/index.d.ts +10 -0
  284. package/lib/locale/index.d.ts.map +1 -0
  285. package/lib/locale/index.js +10 -0
  286. package/lib/locale/index.js.map +1 -0
  287. package/lib/locale/server-locale.d.ts +73 -0
  288. package/lib/locale/server-locale.d.ts.map +1 -0
  289. package/lib/locale/server-locale.js +61 -0
  290. package/lib/locale/server-locale.js.map +1 -0
  291. package/lib/lsp/completion/hydranium-completion-provider.d.ts +44 -2
  292. package/lib/lsp/completion/hydranium-completion-provider.d.ts.map +1 -1
  293. package/lib/lsp/completion/hydranium-completion-provider.js +68 -0
  294. package/lib/lsp/completion/hydranium-completion-provider.js.map +1 -1
  295. package/lib/lsp/connection-features.d.ts +23 -0
  296. package/lib/lsp/connection-features.d.ts.map +1 -0
  297. package/lib/lsp/connection-features.js +60 -0
  298. package/lib/lsp/connection-features.js.map +1 -0
  299. package/lib/lsp/diagnostics-connection.d.ts +27 -0
  300. package/lib/lsp/diagnostics-connection.d.ts.map +1 -0
  301. package/lib/lsp/diagnostics-connection.js +53 -0
  302. package/lib/lsp/diagnostics-connection.js.map +1 -0
  303. package/lib/lsp/hydranium-document-update-handler.d.ts +90 -79
  304. package/lib/lsp/hydranium-document-update-handler.d.ts.map +1 -1
  305. package/lib/lsp/hydranium-document-update-handler.js +153 -99
  306. package/lib/lsp/hydranium-document-update-handler.js.map +1 -1
  307. package/lib/lsp/index.d.ts +3 -1
  308. package/lib/lsp/index.d.ts.map +1 -1
  309. package/lib/lsp/index.js +3 -1
  310. package/lib/lsp/index.js.map +1 -1
  311. package/lib/lsp/lsp-latency.d.ts +39 -0
  312. package/lib/lsp/lsp-latency.d.ts.map +1 -0
  313. package/lib/lsp/lsp-latency.js +58 -0
  314. package/lib/lsp/lsp-latency.js.map +1 -0
  315. package/lib/lsp/semantic-token-provider.d.ts +34 -1
  316. package/lib/lsp/semantic-token-provider.d.ts.map +1 -1
  317. package/lib/lsp/semantic-token-provider.js +55 -8
  318. package/lib/lsp/semantic-token-provider.js.map +1 -1
  319. package/lib/lsp/shared-module.d.ts +4 -8
  320. package/lib/lsp/shared-module.d.ts.map +1 -1
  321. package/lib/lsp/shared-module.js.map +1 -1
  322. package/lib/lsp/start-language-server.d.ts +8 -7
  323. package/lib/lsp/start-language-server.d.ts.map +1 -1
  324. package/lib/lsp/start-language-server.js +13 -7
  325. package/lib/lsp/start-language-server.js.map +1 -1
  326. package/lib/messages/carriers.d.ts +54 -0
  327. package/lib/messages/carriers.d.ts.map +1 -0
  328. package/lib/messages/carriers.js +62 -0
  329. package/lib/messages/carriers.js.map +1 -0
  330. package/lib/messages/index.d.ts +25 -0
  331. package/lib/messages/index.d.ts.map +1 -0
  332. package/lib/messages/index.js +25 -0
  333. package/lib/messages/index.js.map +1 -0
  334. package/lib/messages/renderer.d.ts +142 -0
  335. package/lib/messages/renderer.d.ts.map +1 -0
  336. package/lib/messages/renderer.js +165 -0
  337. package/lib/messages/renderer.js.map +1 -0
  338. package/lib/node/event-loop-monitor.js.map +1 -1
  339. package/lib/node/heap-ceiling.d.ts +61 -0
  340. package/lib/node/heap-ceiling.d.ts.map +1 -0
  341. package/lib/node/heap-ceiling.js +72 -0
  342. package/lib/node/heap-ceiling.js.map +1 -0
  343. package/lib/node/index.d.ts +1 -0
  344. package/lib/node/index.d.ts.map +1 -1
  345. package/lib/node/index.js +1 -0
  346. package/lib/node/index.js.map +1 -1
  347. package/lib/node/latency-from-env.d.ts +1 -1
  348. package/lib/node/latency-from-env.js +1 -1
  349. package/lib/node/lint-grammar.js.map +1 -1
  350. package/lib/node/measure-memory.d.ts.map +1 -1
  351. package/lib/node/measure-memory.js +1 -0
  352. package/lib/node/measure-memory.js.map +1 -1
  353. package/lib/node/memory-monitor.js.map +1 -1
  354. package/lib/node/node-file-system-provider.d.ts +39 -4
  355. package/lib/node/node-file-system-provider.d.ts.map +1 -1
  356. package/lib/node/node-file-system-provider.js +109 -49
  357. package/lib/node/node-file-system-provider.js.map +1 -1
  358. package/lib/node/process-memory.js.map +1 -1
  359. package/lib/node/profile-capture.d.ts +8 -2
  360. package/lib/node/profile-capture.d.ts.map +1 -1
  361. package/lib/node/profile-capture.js.map +1 -1
  362. package/lib/node/profile-digest.js.map +1 -1
  363. package/lib/node/profiling-run.d.ts +13 -3
  364. package/lib/node/profiling-run.d.ts.map +1 -1
  365. package/lib/node/profiling-run.js +17 -8
  366. package/lib/node/profiling-run.js.map +1 -1
  367. package/lib/node/rename-over-open-readers.d.ts +52 -0
  368. package/lib/node/rename-over-open-readers.d.ts.map +1 -0
  369. package/lib/node/rename-over-open-readers.js +66 -0
  370. package/lib/node/rename-over-open-readers.js.map +1 -0
  371. package/lib/node/socket-launcher.d.ts +16 -1
  372. package/lib/node/socket-launcher.d.ts.map +1 -1
  373. package/lib/node/socket-launcher.js +4 -3
  374. package/lib/node/socket-launcher.js.map +1 -1
  375. package/lib/node/stdio-launcher.d.ts +1 -1
  376. package/lib/node/stdio-launcher.d.ts.map +1 -1
  377. package/lib/node/stdio-launcher.js +1 -1
  378. package/lib/node/stdio-launcher.js.map +1 -1
  379. package/lib/testing/document-uri-policy-conformance.js.map +1 -1
  380. package/lib/testing/fake-description.js.map +1 -1
  381. package/lib/testing/fake-document.d.ts +16 -4
  382. package/lib/testing/fake-document.d.ts.map +1 -1
  383. package/lib/testing/fake-document.js +18 -3
  384. package/lib/testing/fake-document.js.map +1 -1
  385. package/lib/testing/index.d.ts +1 -1
  386. package/lib/testing/index.d.ts.map +1 -1
  387. package/lib/testing/index.js +2 -1
  388. package/lib/testing/index.js.map +1 -1
  389. package/lib/testing/langium-test-helpers.d.ts.map +1 -1
  390. package/lib/testing/langium-test-helpers.js +1 -0
  391. package/lib/testing/langium-test-helpers.js.map +1 -1
  392. package/lib/testing/make-noop-language-services.js.map +1 -1
  393. package/lib/testing/make-noop-shared-services.d.ts +14 -0
  394. package/lib/testing/make-noop-shared-services.d.ts.map +1 -1
  395. package/lib/testing/make-noop-shared-services.js +28 -2
  396. package/lib/testing/make-noop-shared-services.js.map +1 -1
  397. package/lib/testing/make-test-services.d.ts +69 -14
  398. package/lib/testing/make-test-services.d.ts.map +1 -1
  399. package/lib/testing/make-test-services.js +39 -10
  400. package/lib/testing/make-test-services.js.map +1 -1
  401. package/lib/testing/make-test-tracer.js.map +1 -1
  402. package/lib/testing/node/golden-corpus.js.map +1 -1
  403. package/lib/testing/node/index.d.ts +1 -0
  404. package/lib/testing/node/index.d.ts.map +1 -1
  405. package/lib/testing/node/index.js +1 -0
  406. package/lib/testing/node/index.js.map +1 -1
  407. package/lib/testing/node/lsp-harness.d.ts.map +1 -1
  408. package/lib/testing/node/lsp-harness.js +2 -0
  409. package/lib/testing/node/lsp-harness.js.map +1 -1
  410. package/lib/testing/node/lsp-server-connection.d.ts +11 -3
  411. package/lib/testing/node/lsp-server-connection.d.ts.map +1 -1
  412. package/lib/testing/node/lsp-server-connection.js +42 -9
  413. package/lib/testing/node/lsp-server-connection.js.map +1 -1
  414. package/lib/testing/node/scratch-workspace.d.ts.map +1 -1
  415. package/lib/testing/node/scratch-workspace.js +10 -5
  416. package/lib/testing/node/scratch-workspace.js.map +1 -1
  417. package/lib/testing/node/spawned-server.d.ts +14 -0
  418. package/lib/testing/node/spawned-server.d.ts.map +1 -1
  419. package/lib/testing/node/spawned-server.js +33 -1
  420. package/lib/testing/node/spawned-server.js.map +1 -1
  421. package/lib/testing/node/unhandled-rejections.d.ts +20 -0
  422. package/lib/testing/node/unhandled-rejections.d.ts.map +1 -0
  423. package/lib/testing/node/unhandled-rejections.js +32 -0
  424. package/lib/testing/node/unhandled-rejections.js.map +1 -0
  425. package/lib/testing/playwright/browser-capture-bridge.js.map +1 -1
  426. package/lib/testing/playwright/e2e-profiling.js.map +1 -1
  427. package/lib/testing/playwright/flaky-network-proxy.d.ts +76 -0
  428. package/lib/testing/playwright/flaky-network-proxy.d.ts.map +1 -0
  429. package/lib/testing/playwright/flaky-network-proxy.js +164 -0
  430. package/lib/testing/playwright/flaky-network-proxy.js.map +1 -0
  431. package/lib/testing/playwright/index.d.ts +1 -0
  432. package/lib/testing/playwright/index.d.ts.map +1 -1
  433. package/lib/testing/playwright/index.js +1 -0
  434. package/lib/testing/playwright/index.js.map +1 -1
  435. package/lib/testing/playwright/server-log-capture.d.ts +24 -8
  436. package/lib/testing/playwright/server-log-capture.d.ts.map +1 -1
  437. package/lib/testing/playwright/server-log-capture.js +27 -6
  438. package/lib/testing/playwright/server-log-capture.js.map +1 -1
  439. package/lib/testing/playwright/server-log-rename-reporter.d.ts.map +1 -1
  440. package/lib/testing/playwright/server-log-rename-reporter.js +10 -1
  441. package/lib/testing/playwright/server-log-rename-reporter.js.map +1 -1
  442. package/lib/testing/run-update-pipeline.d.ts +4 -4
  443. package/lib/testing/run-update-pipeline.d.ts.map +1 -1
  444. package/lib/testing/stub-ast-document-manager.d.ts +11 -9
  445. package/lib/testing/stub-ast-document-manager.d.ts.map +1 -1
  446. package/lib/testing/stub-ast-document-manager.js +25 -9
  447. package/lib/testing/stub-ast-document-manager.js.map +1 -1
  448. package/lib/testing/stub-document-builder.d.ts +26 -11
  449. package/lib/testing/stub-document-builder.d.ts.map +1 -1
  450. package/lib/testing/stub-document-builder.js +57 -4
  451. package/lib/testing/stub-document-builder.js.map +1 -1
  452. package/lib/testing/stub-hydranium-text-documents.d.ts +22 -7
  453. package/lib/testing/stub-hydranium-text-documents.d.ts.map +1 -1
  454. package/lib/testing/stub-hydranium-text-documents.js +97 -15
  455. package/lib/testing/stub-hydranium-text-documents.js.map +1 -1
  456. package/lib/testing/stub-index-manager.js.map +1 -1
  457. package/lib/testing/stub-langium-documents.d.ts +3 -2
  458. package/lib/testing/stub-langium-documents.d.ts.map +1 -1
  459. package/lib/testing/stub-langium-documents.js.map +1 -1
  460. package/lib/testing/stub-model-service.d.ts +7 -6
  461. package/lib/testing/stub-model-service.d.ts.map +1 -1
  462. package/lib/testing/stub-model-service.js +4 -4
  463. package/lib/testing/stub-model-service.js.map +1 -1
  464. package/lib/testing/stub-project-manager.js.map +1 -1
  465. package/lib/testing/stub-service-registry.js.map +1 -1
  466. package/lib/util/connection-liveness.d.ts +7 -6
  467. package/lib/util/connection-liveness.d.ts.map +1 -1
  468. package/lib/util/connection-liveness.js +35 -14
  469. package/lib/util/connection-liveness.js.map +1 -1
  470. package/lib/util/environment.d.ts.map +1 -1
  471. package/lib/util/environment.js.map +1 -1
  472. package/lib/util/registry.d.ts.map +1 -1
  473. package/package.json +35 -26
  474. package/src/documents/ast-document-manager.ts +395 -126
  475. package/src/documents/client-ids.ts +5 -22
  476. package/src/documents/client-session-errors.ts +24 -0
  477. package/src/documents/client-session-registry.ts +240 -0
  478. package/src/documents/file-system-task-queue.ts +68 -0
  479. package/src/documents/hydranium-text-documents.ts +1175 -225
  480. package/src/documents/index.ts +5 -0
  481. package/src/documents/language-client-text-shadow.ts +59 -11
  482. package/src/documents/model-ledger.ts +66 -0
  483. package/src/documents/self-save-registry.ts +52 -13
  484. package/src/documents/version-sync-service.ts +267 -0
  485. package/src/index.ts +6 -0
  486. package/src/langium/ast-extension/ast-node-builder.ts +66 -22
  487. package/src/langium/bootstrap.ts +32 -9
  488. package/src/langium/config/configuration-provider.ts +119 -0
  489. package/src/langium/config/index.ts +1 -0
  490. package/src/langium/diagnostics/logger.ts +12 -5
  491. package/src/langium/diagnostics/lsp-logger.ts +58 -12
  492. package/src/langium/document-builder/build-pipeline-integration.ts +50 -5
  493. package/src/langium/document-builder/build-session.ts +87 -0
  494. package/src/langium/document-builder/document-builder.ts +776 -59
  495. package/src/langium/document-builder/index.ts +1 -0
  496. package/src/langium/integration-services.ts +67 -6
  497. package/src/langium/integrity/integrity-rule.ts +13 -5
  498. package/src/langium/integrity/integrity-service.ts +220 -30
  499. package/src/langium/keys/containment.ts +87 -0
  500. package/src/langium/keys/index.ts +1 -0
  501. package/src/langium/keys/name-based-key-provider.ts +4 -0
  502. package/src/langium/language-module.ts +42 -4
  503. package/src/langium/model-service/client-session.ts +649 -0
  504. package/src/langium/model-service/index.ts +1 -0
  505. package/src/langium/model-service/model-service.ts +570 -433
  506. package/src/langium/module.ts +201 -64
  507. package/src/langium/naming/name-provider.ts +27 -5
  508. package/src/langium/naming/name-separator-validation.ts +34 -5
  509. package/src/langium/project/abstract-project-manager.ts +9 -1
  510. package/src/langium/project/project-change-event.ts +2 -2
  511. package/src/langium/residency/cst-residency-service.ts +46 -15
  512. package/src/langium/scope/hydranium-scope-provider.ts +60 -22
  513. package/src/langium/serialization/abstract-serializer.ts +13 -32
  514. package/src/langium/service-registry.ts +19 -2
  515. package/src/langium/shared-services.ts +25 -4
  516. package/src/langium/transfer/transfer-encoder.ts +102 -34
  517. package/src/langium/trivia/comment-preserver.ts +1100 -0
  518. package/src/langium/trivia/document-ending-preserver.ts +55 -0
  519. package/src/langium/trivia/index.ts +14 -0
  520. package/src/langium/trivia/trivia-contribution.ts +39 -0
  521. package/src/langium/trivia/trivia-preserver.ts +54 -0
  522. package/src/langium/trivia/trivia-service.ts +99 -0
  523. package/src/langium/update-rewrite/update-rewrite.ts +1 -1
  524. package/src/langium/validation/document-validator.ts +537 -11
  525. package/src/langium/workspace/document-uri-policy.ts +17 -12
  526. package/src/langium/workspace/file-not-found.ts +23 -0
  527. package/src/langium/workspace/file-system-provider.ts +153 -16
  528. package/src/langium/workspace/hydranium-langium-document-factory.ts +117 -0
  529. package/src/langium/workspace/hydranium-workspace-lock.ts +86 -2
  530. package/src/langium/workspace/hydranium-workspace-manager.ts +153 -13
  531. package/src/langium/workspace/in-memory-file-system-provider.ts +47 -16
  532. package/src/langium/workspace/initialize-workspace.ts +43 -5
  533. package/src/langium/workspace/langium-documents.ts +124 -33
  534. package/src/langium/workspace/persistent-file-system-provider.ts +0 -7
  535. package/src/langium/workspace/virtual-document.ts +96 -19
  536. package/src/langium/workspace/write-lock-scope.ts +24 -11
  537. package/src/locale/index.ts +10 -0
  538. package/src/locale/server-locale.ts +86 -0
  539. package/src/lsp/completion/hydranium-completion-provider.ts +82 -2
  540. package/src/lsp/connection-features.ts +67 -0
  541. package/src/lsp/diagnostics-connection.ts +56 -0
  542. package/src/lsp/hydranium-document-update-handler.ts +185 -106
  543. package/src/lsp/index.ts +3 -1
  544. package/src/lsp/lsp-latency.ts +62 -0
  545. package/src/lsp/semantic-token-provider.ts +74 -7
  546. package/src/lsp/shared-module.ts +4 -8
  547. package/src/lsp/start-language-server.ts +13 -7
  548. package/src/messages/carriers.ts +78 -0
  549. package/src/messages/index.ts +36 -0
  550. package/src/messages/renderer.ts +212 -0
  551. package/src/node/heap-ceiling.ts +108 -0
  552. package/src/node/index.ts +1 -0
  553. package/src/node/latency-from-env.ts +1 -1
  554. package/src/node/measure-memory.ts +1 -0
  555. package/src/node/node-file-system-provider.ts +122 -51
  556. package/src/node/profile-capture.ts +8 -2
  557. package/src/node/profiling-run.ts +30 -8
  558. package/src/node/rename-over-open-readers.ts +78 -0
  559. package/src/node/socket-launcher.ts +19 -4
  560. package/src/node/stdio-launcher.ts +1 -2
  561. package/src/testing/fake-document.ts +24 -5
  562. package/src/testing/index.ts +2 -1
  563. package/src/testing/langium-test-helpers.ts +1 -0
  564. package/src/testing/make-noop-shared-services.ts +50 -2
  565. package/src/testing/make-test-services.ts +120 -31
  566. package/src/testing/node/index.ts +1 -0
  567. package/src/testing/node/lsp-harness.ts +2 -0
  568. package/src/testing/node/lsp-server-connection.ts +61 -11
  569. package/src/testing/node/scratch-workspace.ts +10 -5
  570. package/src/testing/node/spawned-server.ts +35 -1
  571. package/src/testing/node/unhandled-rejections.ts +31 -0
  572. package/src/testing/playwright/flaky-network-proxy.ts +240 -0
  573. package/src/testing/playwright/index.ts +1 -0
  574. package/src/testing/playwright/server-log-capture.ts +45 -11
  575. package/src/testing/playwright/server-log-rename-reporter.ts +12 -1
  576. package/src/testing/run-update-pipeline.ts +4 -4
  577. package/src/testing/stub-ast-document-manager.ts +40 -23
  578. package/src/testing/stub-document-builder.ts +83 -17
  579. package/src/testing/stub-hydranium-text-documents.ts +133 -23
  580. package/src/testing/stub-langium-documents.ts +3 -2
  581. package/src/testing/stub-model-service.ts +9 -8
  582. package/src/util/connection-liveness.ts +37 -14
  583. package/src/util/environment.ts +9 -1
  584. package/lib/lsp/instrument-connection.d.ts +0 -36
  585. package/lib/lsp/instrument-connection.d.ts.map +0 -1
  586. package/lib/lsp/instrument-connection.js +0 -62
  587. package/lib/lsp/instrument-connection.js.map +0 -1
  588. package/src/lsp/instrument-connection.ts +0 -66
@@ -9,13 +9,16 @@
9
9
 
10
10
  import {
11
11
  type DocumentBuilder,
12
+ type DocumentBuildListener,
12
13
  type DocumentPhaseListener,
13
14
  type DocumentState,
14
15
  type DocumentUpdateListener,
15
16
  type LangiumDocument,
16
- type URI
17
+ type URI,
18
+ type WorkspaceLock
17
19
  } from '@hydranium/langium';
18
20
  import { type CancellationToken, Disposable } from 'vscode-languageserver';
21
+ import { type HydraniumDocumentBuilder } from '../langium/document-builder/document-builder.js';
19
22
 
20
23
  /** Recorded call to a stubbed {@link DocumentBuilder} method. */
21
24
  export interface RecordedBuilderCall<TArgs extends unknown[]> {
@@ -45,8 +48,7 @@ export interface StubWaitUntilGate {
45
48
 
46
49
  /**
47
50
  * Stub for Langium's {@link DocumentBuilder}. Implements the slice production
48
- * code reads from on the framework's test paths (`update` / `waitUntil` /
49
- * `onDocumentPhase` / `onUpdate`) plus test-only helpers:
51
+ * code reads on the framework's test paths, plus test-only helpers:
50
52
  *
51
53
  * - {@link firePhase} — synchronously dispatch the registered phase
52
54
  * listener(s) for a document, simulating a build completing.
@@ -64,16 +66,17 @@ export interface StubWaitUntilGate {
64
66
  * Picks the methods the framework reads from {@link DocumentBuilder} on
65
67
  * the slot path — the compiler enforces those signatures stay aligned.
66
68
  * `update`, `onDocumentPhase`, `onUpdate`, and `waitUntil` carry stubbed
67
- * implementations; `build`, `onBuildPhase`, and `resetToState` are
68
- * implemented as loud-failing `notSupported` throwers so production code
69
- * that goes through the cast at the bind site (i.e. accesses methods the
69
+ * implementations, and `scheduleUpdate` calls `update` in one lock write per
70
+ * call (see {@link makeStubDocumentBuilder}); `build`, `onBuildPhase`, and
71
+ * `resetToState` are implemented as loud-failing `notSupported` throwers
72
+ * so production code that goes through the cast at the bind site (i.e. accesses methods the
70
73
  * stub claims but doesn't meaningfully implement) fails with a clear
71
74
  * message instead of "undefined is not a function".
72
75
  */
73
- export interface StubDocumentBuilder extends Pick<
74
- DocumentBuilder,
75
- 'update' | 'onDocumentPhase' | 'onUpdate' | 'build' | 'onBuildPhase' | 'resetToState'
76
- > {
76
+ export interface StubDocumentBuilder
77
+ extends
78
+ Pick<DocumentBuilder, 'update' | 'onDocumentPhase' | 'onUpdate' | 'build' | 'onBuildPhase' | 'resetToState' | 'updateBuildOptions'>,
79
+ Pick<HydraniumDocumentBuilder, 'onDocumentPhaseDelivered' | 'scheduleUpdate'> {
77
80
  /**
78
81
  * Single-overload stub of {@link DocumentBuilder.waitUntil}. Real has
79
82
  * two overloads (`(state, cancelToken?): Promise<void>` and
@@ -87,13 +90,22 @@ export interface StubDocumentBuilder extends Pick<
87
90
  readonly waitUntilCalls: ReadonlyArray<RecordedBuilderCall<[DocumentState, URI | undefined]>>;
88
91
  /**
89
92
  * Synchronously fire the phase listener(s) registered for `state` with
90
- * `document`. `cancelToken` defaults to a non-cancelled token; pass a
91
- * cancelled token to simulate a build preempted by a concurrent write
92
- * lock.
93
+ * `document`, then, unless `cancelToken` is cancelled, the
94
+ * `onDocumentPhaseDelivered` listeners. `cancelToken` defaults to a
95
+ * non-cancelled token; pass a cancelled token to simulate a build preempted
96
+ * by a concurrent write lock.
93
97
  */
94
98
  firePhase(state: DocumentState, document: LangiumDocument, cancelToken?: CancellationToken): void;
95
99
  /** Synchronously fire every registered `onUpdate` listener. */
96
100
  fireOnUpdate(changed: URI[], deleted: URI[]): void;
101
+ /**
102
+ * Synchronously fire the BUILD-phase listener(s) for `state` with the whole
103
+ * batch. The per-build counterpart of {@link firePhase}: a subject that
104
+ * reports once per build rather than once per document subscribes here, and
105
+ * a stub that only fired {@link firePhase} would leave it silent while
106
+ * looking wired.
107
+ */
108
+ fireBuildPhase(state: DocumentState, built: LangiumDocument[], cancelToken?: CancellationToken): void;
97
109
  /**
98
110
  * Hold the next {@link waitUntil} call. The returned handle releases it;
99
111
  * the call's return value resolves on the next tick after `resolve` runs.
@@ -128,9 +140,16 @@ function reraise(result: unknown): void {
128
140
  * want to observe rebuilt state should `set` the new root on the document
129
141
  * registry and then call `firePhase` to trigger the framework's post-build
130
142
  * read path.
143
+ *
144
+ * `workspaceLock` is the lock `scheduleUpdate` writes under, without the real
145
+ * builder's sharing: pass the services tree's own, so a caller's lock ordering
146
+ * and reentrancy behave as against the real builder. Without one,
147
+ * `scheduleUpdate` records the update unlocked.
131
148
  */
132
- export function makeStubDocumentBuilder(): StubDocumentBuilder {
149
+ export function makeStubDocumentBuilder(workspaceLock?: WorkspaceLock): StubDocumentBuilder {
133
150
  const phaseListeners = new Map<DocumentState, DocumentPhaseListener[]>();
151
+ const deliveredListeners = new Map<DocumentState, Array<(document: LangiumDocument, version: number) => void>>();
152
+ const buildPhaseListeners = new Map<DocumentState, DocumentBuildListener[]>();
134
153
  const onUpdateListeners: DocumentUpdateListener[] = [];
135
154
  const gates: Array<{ take(release: () => void): void }> = [];
136
155
  const updateCalls: RecordedBuilderCall<[URI[], URI[]]>[] = [];
@@ -140,6 +159,9 @@ export function makeStubDocumentBuilder(): StubDocumentBuilder {
140
159
  throw new Error(`StubDocumentBuilder.${method} is not implemented; wire a real DocumentBuilder if your test needs it.`);
141
160
  };
142
161
  const stub: StubDocumentBuilder = {
162
+ // Langium's own default, so a session write waits for `Validated` here
163
+ // as it does against the real builder.
164
+ updateBuildOptions: { validation: { categories: ['built-in', 'fast'] } },
143
165
  get updateCalls() {
144
166
  return updateCalls;
145
167
  },
@@ -149,6 +171,9 @@ export function makeStubDocumentBuilder(): StubDocumentBuilder {
149
171
  async update(changed: URI[], deleted: URI[]) {
150
172
  updateCalls.push({ args: [changed, deleted] });
151
173
  },
174
+ scheduleUpdate(changed: URI[], deleted: URI[]) {
175
+ return workspaceLock ? workspaceLock.write(() => stub.update(changed, deleted)) : stub.update(changed, deleted);
176
+ },
152
177
  async waitUntil(state: DocumentState, uri?: URI) {
153
178
  waitUntilCalls.push({ args: [state, uri] });
154
179
  const gate = gates.shift();
@@ -185,15 +210,58 @@ export function makeStubDocumentBuilder(): StubDocumentBuilder {
185
210
  onCancellationRequested: () => Disposable.create(() => undefined)
186
211
  } as CancellationToken);
187
212
  const listeners = phaseListeners.get(state) ?? [];
213
+ const delivered = deliveredListeners.get(state) ?? [];
214
+ // Taken before the listeners, as the real builder does: one of them
215
+ // may stand in for a write that moves the version on. Read only when
216
+ // someone is told, since many fakes carry no text document.
217
+ const version = delivered.length > 0 ? document.textDocument.version : 0;
188
218
  for (const listener of listeners) {
189
219
  reraise(listener(document, token));
190
220
  }
221
+ if (!token.isCancellationRequested) {
222
+ for (const listener of delivered) {
223
+ listener(document, version);
224
+ }
225
+ }
226
+ },
227
+ onDocumentPhaseDelivered(state: DocumentState, listener: (document: LangiumDocument, version: number) => void) {
228
+ const list = deliveredListeners.get(state) ?? [];
229
+ list.push(listener);
230
+ deliveredListeners.set(state, list);
231
+ return Disposable.create(() => {
232
+ const idx = list.indexOf(listener);
233
+ if (idx >= 0) {
234
+ list.splice(idx, 1);
235
+ }
236
+ });
191
237
  },
192
238
  fireOnUpdate(changed: URI[], deleted: URI[]) {
193
239
  for (const listener of onUpdateListeners.slice()) {
194
240
  reraise(listener(changed, deleted));
195
241
  }
196
242
  },
243
+ onBuildPhase(state: DocumentState, listener: DocumentBuildListener) {
244
+ const list = buildPhaseListeners.get(state) ?? [];
245
+ list.push(listener);
246
+ buildPhaseListeners.set(state, list);
247
+ return Disposable.create(() => {
248
+ const idx = list.indexOf(listener);
249
+ if (idx >= 0) {
250
+ list.splice(idx, 1);
251
+ }
252
+ });
253
+ },
254
+ fireBuildPhase(state: DocumentState, built: LangiumDocument[], cancelToken?: CancellationToken) {
255
+ const token =
256
+ cancelToken ??
257
+ ({
258
+ isCancellationRequested: false,
259
+ onCancellationRequested: () => Disposable.create(() => undefined)
260
+ } as CancellationToken);
261
+ for (const listener of buildPhaseListeners.get(state) ?? []) {
262
+ reraise(listener(built, token));
263
+ }
264
+ },
197
265
  gateNextWaitUntil(): StubWaitUntilGate {
198
266
  let release: (() => void) | undefined;
199
267
  const entry = {
@@ -224,14 +292,12 @@ export function makeStubDocumentBuilder(): StubDocumentBuilder {
224
292
  build() {
225
293
  return notSupported('build');
226
294
  },
227
- onBuildPhase() {
228
- return notSupported('onBuildPhase');
229
- },
230
295
  resetToState() {
231
296
  return notSupported('resetToState');
232
297
  },
233
298
  reset() {
234
299
  phaseListeners.clear();
300
+ deliveredListeners.clear();
235
301
  onUpdateListeners.length = 0;
236
302
  gates.length = 0;
237
303
  updateCalls.length = 0;
@@ -7,12 +7,18 @@
7
7
  * SPDX-License-Identifier: MIT
8
8
  ********************************************************************************/
9
9
 
10
- import type { CanonicalUri } from '@hydranium/protocol';
10
+ import { type CanonicalUri, textHash } from '@hydranium/protocol';
11
11
  import type { ApplyWorkspaceEditResult } from 'vscode-languageserver';
12
- import { Disposable } from 'vscode-languageserver';
12
+ import { Disposable, Emitter } from 'vscode-languageserver';
13
13
  import type { TextDocument } from 'vscode-languageserver-textdocument';
14
14
  import { LANGUAGE_CLIENT_ID } from '../documents/client-ids.js';
15
- import type { ClientTextDocumentChangeEvent, HydraniumTextDocuments } from '../documents/hydranium-text-documents.js';
15
+ import { ClientSessionRegistry } from '../documents/client-session-registry.js';
16
+ import type {
17
+ ClientTextDocumentChangeEvent,
18
+ DocumentDirtyChangedEvent,
19
+ HydraniumTextDocuments,
20
+ LastOpenClosedEvent
21
+ } from '../documents/hydranium-text-documents.js';
16
22
 
17
23
  /** Snapshot of an open document tracked by the stub. */
18
24
  export interface StubTextDocumentEntry {
@@ -27,9 +33,14 @@ export interface StubTextDocumentEntry {
27
33
  * reads from on test paths — the content channel
28
34
  * (`notifyDidChangeTextDocument` / `applyContentChange` / `version` /
29
35
  * `getAuthor`), the open-state probes (`isOpenInLanguageClient` /
30
- * `isOpenInAnyClient` / `openDocuments`), the push channel to the language
31
- * client (`applyEditToLanguageClient` / `stagePendingContent`) and the
32
- * save / close notifications — plus test-only helpers:
36
+ * `isOpenInAnyClient` / `isOpenInClient` / `isRevertPending` /
37
+ * `openDocuments`), the push channel
38
+ * to the language client (`applyEditToLanguageClient` / `stagePendingContent`),
39
+ * the save / close notifications, the dirty state (`isDirty` / `textState` /
40
+ * `onDidChangeDirty` / `updateDiskBaseline`, against a baseline {@link seedOpen}
41
+ * sets and a save that carries its text moves), and the client-session table
42
+ * (`registerSession` / `closeSession` / `onDidCloseSession`), which is a real
43
+ * `ClientSessionRegistry` — plus test-only helpers:
33
44
  *
34
45
  * - {@link seedOpen} — pre-populate an open document without firing change
35
46
  * events. Use to set up a baseline version before exercising an `update`.
@@ -66,9 +77,20 @@ export interface StubHydraniumTextDocuments extends Pick<
66
77
  | 'getAuthor'
67
78
  | 'isOpenInLanguageClient'
68
79
  | 'isOpenInAnyClient'
80
+ | 'isRevertPending'
69
81
  | 'applyEditToLanguageClient'
70
82
  | 'stagePendingContent'
71
83
  | 'openDocuments'
84
+ | 'isOpenInClient'
85
+ | 'attachClient'
86
+ | 'registerSession'
87
+ | 'closeSession'
88
+ | 'onDidCloseSession'
89
+ | 'onDidCloseLastOpen'
90
+ | 'isDirty'
91
+ | 'textState'
92
+ | 'onDidChangeDirty'
93
+ | 'updateDiskBaseline'
72
94
  > {
73
95
  /**
74
96
  * Stub-tailored read accessor. Returns just the surface the framework's
@@ -87,13 +109,23 @@ export interface StubHydraniumTextDocuments extends Pick<
87
109
  onDidSave(listener: (event: { document: { uri: string }; clientId: string }) => void): Disposable;
88
110
  /** Real-shaped close subscription — listener gets {@link ClientTextDocumentChangeEvent}. */
89
111
  onDidClose(listener: (event: ClientTextDocumentChangeEvent<TextDocument>) => void): Disposable;
90
- /** Pre-populate an open document without firing change events. */
112
+ /** Pre-populate an open document without firing change events; `text` is also its disk baseline. */
91
113
  seedOpen(uri: string, text: string, clientId: string): void;
92
114
  /** Mark `uri` as open in the LSP textual language client (drives {@link isOpenInLanguageClient}). */
93
115
  seedOpenInLanguageClient(uri: string): void;
94
- /** Synchronously deliver `onDidClose` to subscribers. */
116
+ /**
117
+ * Synchronously deliver `onDidClose` to subscribers, then `onDidCloseLastOpen`
118
+ * when no client has `uri` open any more. The stub keeps no revert grace, so
119
+ * a last close is announced at once.
120
+ */
95
121
  fireClose(uri: string, clientId: string): void;
96
- /** Drop recorded state. Useful for `beforeEach` resets. */
122
+ /**
123
+ * Drop recorded state. Useful for `beforeEach` resets.
124
+ *
125
+ * Sessions end without announcing it, so a model service built on this
126
+ * stub still holds the handles it started before the reset. Build a fresh
127
+ * service after a reset rather than reusing one across it.
128
+ */
97
129
  reset(): void;
98
130
  readonly changes: readonly StubTextDocumentEntry[];
99
131
  readonly saves: readonly { uri: string; clientId: string }[];
@@ -125,8 +157,31 @@ export function makeStubHydraniumTextDocuments(): StubHydraniumTextDocuments {
125
157
  let applyEditHandler: (uri: string, text: string) => ApplyWorkspaceEditResult | undefined = () => ({ applied: true });
126
158
  const saveListeners: Array<(event: { document: { uri: string }; clientId: string }) => void> = [];
127
159
  const closeListeners: Array<(event: ClientTextDocumentChangeEvent<TextDocument>) => void> = [];
160
+ // The real registry, so the session table, the opens and the closing state
161
+ // behave as the store's do. The stub's plain-string keys
162
+ // stand in for canonical URIs (one stub-boundary cast, like `fireClose`).
163
+ const sessions = new ClientSessionRegistry();
164
+ const key = (uri: string): CanonicalUri => uri as CanonicalUri;
165
+ const lastOpenClosed = new Emitter<LastOpenClosedEvent>();
166
+ const baselines = new Map<string, string | undefined>();
167
+ const dirty = new Set<string>();
168
+ const dirtyChanged = new Emitter<DocumentDirtyChangedEvent>();
169
+ // As the real store: dirty while held with text other than the baseline,
170
+ // announced only when the answer changes.
171
+ const refreshDirty = (uri: string): void => {
172
+ const held = docs.get(uri);
173
+ const now = held !== undefined && held.text !== baselines.get(uri);
174
+ if (now !== dirty.has(uri)) {
175
+ if (now) {
176
+ dirty.add(uri);
177
+ } else {
178
+ dirty.delete(uri);
179
+ }
180
+ dirtyChanged.fire({ uri: key(uri), text: { version: held?.version ?? 0, hash: textHash(held?.text ?? ''), dirty: now } });
181
+ }
182
+ };
128
183
 
129
- return {
184
+ const stub: StubHydraniumTextDocuments = {
130
185
  get changes() {
131
186
  return changes;
132
187
  },
@@ -146,6 +201,10 @@ export function makeStubHydraniumTextDocuments(): StubHydraniumTextDocuments {
146
201
  version(uri) {
147
202
  return docs.get(uri)?.version ?? 0;
148
203
  },
204
+ textState(uri) {
205
+ const held = docs.get(uri);
206
+ return held && { version: held.version, hash: textHash(held.text), dirty: dirty.has(uri) };
207
+ },
149
208
  notifyDidChangeTextDocument(event, clientId = LANGUAGE_CLIENT_ID) {
150
209
  const existing = docs.get(event.textDocument.uri);
151
210
  const next: StubTextDocumentEntry = {
@@ -159,6 +218,7 @@ export function makeStubHydraniumTextDocuments(): StubHydraniumTextDocuments {
159
218
  }
160
219
  docs.set(event.textDocument.uri, next);
161
220
  changes.push(next);
221
+ refreshDirty(event.textDocument.uri);
162
222
  },
163
223
  applyContentChange(uri, text, clientId) {
164
224
  const existing = docs.get(uri);
@@ -172,9 +232,13 @@ export function makeStubHydraniumTextDocuments(): StubHydraniumTextDocuments {
172
232
  const next: StubTextDocumentEntry = changed ? { uri, version: existing.version + 1, text, clientId } : existing;
173
233
  docs.set(uri, next);
174
234
  changes.push({ uri, version: next.version, text, clientId });
235
+ refreshDirty(uri);
175
236
  return next.version;
176
237
  },
177
238
  notifyDidSaveTextDocument(event, clientId) {
239
+ if (event.text !== undefined) {
240
+ stub.updateDiskBaseline(event.textDocument.uri, event.text);
241
+ }
178
242
  saves.push({ uri: event.textDocument.uri, clientId });
179
243
  for (const listener of saveListeners.slice()) {
180
244
  listener({ document: { uri: event.textDocument.uri }, clientId });
@@ -207,21 +271,52 @@ export function makeStubHydraniumTextDocuments(): StubHydraniumTextDocuments {
207
271
  isOpenInAnyClient(uri) {
208
272
  return docs.has(uri) || languageClientOpen.has(uri);
209
273
  },
210
- openDocuments() {
211
- // Merge the two seeding channels: `seedOpen` records the holding client
212
- // on the doc entry, `seedOpenInLanguageClient` marks the LSP client.
213
- const clientsByUri = new Map<string, Set<string>>();
214
- for (const [uri, entry] of docs) {
215
- clientsByUri.set(uri, new Set([entry.clientId]));
274
+ isOpenInClient(uri, clientId) {
275
+ return sessions.isOpenIn(key(uri), clientId);
276
+ },
277
+ isRevertPending(uri) {
278
+ return sessions.isRevertPending(key(uri));
279
+ },
280
+ attachClient(uri, clientId) {
281
+ return docs.has(uri) && sessions.addOpen(key(uri), clientId);
282
+ },
283
+ registerSession(clientId) {
284
+ sessions.register(clientId);
285
+ },
286
+ closeSession(clientId) {
287
+ if (!sessions.isRegistered(clientId)) {
288
+ return;
216
289
  }
217
- for (const uri of languageClientOpen) {
218
- const clients = clientsByUri.get(uri) ?? new Set<string>();
219
- clients.add(LANGUAGE_CLIENT_ID);
220
- clientsByUri.set(uri, clients);
290
+ try {
291
+ for (const uri of sessions.beginClose(clientId)) {
292
+ stub.fireClose(uri, clientId);
293
+ }
294
+ } finally {
295
+ sessions.unregister(clientId);
221
296
  }
222
- // The real store keys by canonical identity; the stub's plain-string
223
- // keys stand in for it (single stub-boundary cast, like `fireClose`).
224
- return [...clientsByUri].map(([uri, clients]) => ({ uri: uri as CanonicalUri, clients: [...clients] }));
297
+ },
298
+ get onDidCloseSession() {
299
+ return sessions.onDidCloseSession;
300
+ },
301
+ get onDidCloseLastOpen() {
302
+ return lastOpenClosed.event;
303
+ },
304
+ isDirty(uri) {
305
+ return dirty.has(uri);
306
+ },
307
+ get onDidChangeDirty() {
308
+ return dirtyChanged.event;
309
+ },
310
+ updateDiskBaseline(uri, text) {
311
+ if (docs.has(uri)) {
312
+ baselines.set(uri, text);
313
+ refreshDirty(uri);
314
+ }
315
+ },
316
+ openDocuments() {
317
+ // From the registry that also answers `isOpenInClient`, which both
318
+ // seeding channels feed, so the two never disagree about an open.
319
+ return sessions.openDocuments();
225
320
  },
226
321
  setApplyEditHandler(handler) {
227
322
  applyEditHandler = handler;
@@ -234,9 +329,12 @@ export function makeStubHydraniumTextDocuments(): StubHydraniumTextDocuments {
234
329
  staged.push({ uri, text });
235
330
  },
236
331
  seedOpen(uri, text, clientId) {
332
+ sessions.addOpen(key(uri), clientId);
237
333
  docs.set(uri, { uri, version: 1, text, clientId });
334
+ baselines.set(uri, text);
238
335
  },
239
336
  seedOpenInLanguageClient(uri) {
337
+ sessions.addOpen(key(uri), LANGUAGE_CLIENT_ID);
240
338
  languageClientOpen.add(uri);
241
339
  },
242
340
  fireClose(uri, clientId) {
@@ -246,7 +344,9 @@ export function makeStubHydraniumTextDocuments(): StubHydraniumTextDocuments {
246
344
  const holder = docs.get(uri);
247
345
  if (holder && holder.clientId === clientId) {
248
346
  docs.delete(uri);
347
+ refreshDirty(uri);
249
348
  }
349
+ const removed = sessions.removeOpen(key(uri), clientId);
250
350
  if (clientId === LANGUAGE_CLIENT_ID) {
251
351
  languageClientOpen.delete(uri);
252
352
  }
@@ -254,6 +354,9 @@ export function makeStubHydraniumTextDocuments(): StubHydraniumTextDocuments {
254
354
  for (const listener of closeListeners.slice()) {
255
355
  listener(event);
256
356
  }
357
+ if (removed && !sessions.isOpen(key(uri))) {
358
+ lastOpenClosed.fire({ uri: key(uri) });
359
+ }
257
360
  },
258
361
  reset() {
259
362
  docs.clear();
@@ -262,9 +365,16 @@ export function makeStubHydraniumTextDocuments(): StubHydraniumTextDocuments {
262
365
  languageClientOpen.clear();
263
366
  appliedEdits.length = 0;
264
367
  staged.length = 0;
368
+ baselines.clear();
369
+ dirty.clear();
265
370
  saveListeners.length = 0;
266
371
  closeListeners.length = 0;
267
372
  applyEditHandler = () => ({ applied: true });
373
+ // Cleared in place rather than replaced: a model service built on the
374
+ // stub subscribed to `onDidCloseSession` once, and a new registry would
375
+ // leave that subscription on one nothing fires.
376
+ sessions.clear();
268
377
  }
269
378
  };
379
+ return stub;
270
380
  }
@@ -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
 
@@ -52,8 +53,8 @@ export type StubModelService<
52
53
  * `makeTestServices` wires this stub automatically.
53
54
  *
54
55
  * `options` are the framework {@link ModelServiceOptions}, forwarded verbatim, so
55
- * a test can exercise an option-gated code path (`serializeBuilds`, the slow-warn
56
- * threshold) without hand-rolling a subclass just to reach the constructor.
56
+ * a test can exercise an option-gated code path (`allowReentrantBuilds`) without
57
+ * hand-rolling a subclass just to reach the constructor.
57
58
  *
58
59
  * Adopters that need richer override behaviour — the framework's own extension
59
60
  * surface is {@link ModelService.rewriteModel} alongside `serialize` — should
@@ -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,
@@ -8,39 +8,62 @@
8
8
  ********************************************************************************/
9
9
 
10
10
  /**
11
- * Phrases `vscode-jsonrpc` uses when a call loses its connection. Matched on the
12
- * message because the condition surfaces in two different shapes:
11
+ * Phrases that mean a call lost its connection. Matched on the message because
12
+ * the condition surfaces in shapes that share no discriminator:
13
13
  *
14
14
  * - a **throw** from `throwIfClosedOrDisposed` (`Connection is disposed.` /
15
15
  * `Connection is closed.`), a `ConnectionError` raised synchronously by
16
16
  * `sendRequest` / `sendNotification` and by `RemoteConsole.send`;
17
17
  * - a **rejection** of an already-issued request (`Pending response rejected
18
18
  * since connection got disposed`), a `ResponseError` produced when the
19
- * pending-response map is drained on teardown.
19
+ * pending-response map is drained on teardown;
20
+ * - a **write into a destroyed transport** (`Cannot call write after a stream
21
+ * was destroyed`), Node's own error for a message the writer queued before
22
+ * the connection was disposed and flushed after its stream was destroyed.
23
+ * A notification rejects with Node's error itself, which
24
+ * {@link isDestroyedStreamError} catches by its code; a request rejects with
25
+ * a `ResponseError` that copies only the message, so the phrase is needed
26
+ * too.
20
27
  *
21
- * Both are typed, but they are different error classes carrying codes from
22
- * different enums, so no single code check covers both. Kept
23
- * lowercase-normalised and anchored on `connection` so an unrelated "disposed"
24
- * message cannot match.
28
+ * The typed errors come from different classes carrying codes from different
29
+ * enums, so no single code check covers them. Kept lowercase-normalised and
30
+ * anchored on `connection` or `stream` so an unrelated "disposed" message
31
+ * cannot match.
25
32
  */
26
- const CONNECTION_GONE_PATTERNS = [/connection is disposed/, /connection is closed/, /connection got disposed/, /connection got closed/];
33
+ const CONNECTION_GONE_PATTERNS = [
34
+ /connection is disposed/,
35
+ /connection is closed/,
36
+ /connection got disposed/,
37
+ /connection got closed/,
38
+ /after a stream was destroyed/
39
+ ];
40
+
41
+ const DESTROYED_STREAM_CODE = 'ERR_STREAM_DESTROYED';
42
+
43
+ function isDestroyedStreamError(err: unknown): boolean {
44
+ return err instanceof Error && 'code' in err && err.code === DESTROYED_STREAM_CODE;
45
+ }
27
46
 
28
47
  /**
29
48
  * Whether `err` means "the peer is gone", as opposed to a genuine failure of
30
49
  * the operation.
31
50
  *
32
- * The distinction is a **log-severity** one, and it matters because the two are
33
- * indistinguishable at the call site otherwise. Pushing an edit to a language
34
- * client that has already disconnected is a no-op, not a fault — it happens on
35
- * every ordinary shutdown, and reporting it at `error` turns routine teardown
36
- * into something that looks like it needs investigation. A real `applyEdit`
37
- * failure (the client refused, the request malformed) still deserves `error`.
51
+ * The two are indistinguishable at the call site otherwise, and callers act on
52
+ * the answer: a gone peer is logged at `debug` or dropped, a genuine failure is
53
+ * logged at `error` or re-raised as an unhandled rejection. Pushing an edit to
54
+ * a language client that has already disconnected is a no-op, not a fault — it
55
+ * happens on every ordinary shutdown — so a `false` here turns routine teardown
56
+ * into errors that look like they need investigation. A `true` for a real
57
+ * `applyEdit` failure (the client refused, the request malformed) hides it.
38
58
  *
39
59
  * Callers that only need to *survive* a dead connection rather than classify it
40
60
  * should just catch — see `LspLogger.emit`, whose fallback path does exactly
41
61
  * that, since a logger has nowhere to report a logging failure anyway.
42
62
  */
43
63
  export function isConnectionGoneError(err: unknown): boolean {
64
+ if (isDestroyedStreamError(err)) {
65
+ return true;
66
+ }
44
67
  const message = err instanceof Error ? err.message : String(err);
45
68
  const normalized = message.toLowerCase();
46
69
  return CONNECTION_GONE_PATTERNS.some(pattern => pattern.test(normalized));
@@ -44,7 +44,15 @@ export function isCaseInsensitiveFileSystem(): boolean {
44
44
 
45
45
  /** Node `process` lifecycle / error / signal events accepted by {@link onProcessEvent}. */
46
46
  export type ProcessEvent =
47
- 'exit' | 'beforeExit' | 'uncaughtException' | 'unhandledRejection' | 'rejectionHandled' | 'warning' | 'SIGINT' | 'SIGTERM' | 'SIGHUP';
47
+ | 'exit'
48
+ | 'beforeExit'
49
+ | 'uncaughtException'
50
+ | 'unhandledRejection'
51
+ | 'rejectionHandled'
52
+ | 'warning'
53
+ | 'SIGINT'
54
+ | 'SIGTERM'
55
+ | 'SIGHUP';
48
56
 
49
57
  /**
50
58
  * Register a process lifecycle handler (`'exit'`, `'unhandledRejection'`, …) if