@hydranium/core 1.0.0-next.28 → 1.0.0-next.281

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 (740) hide show
  1. package/README.md +64 -82
  2. package/lib/documents/ast-document-manager.d.ts +252 -122
  3. package/lib/documents/ast-document-manager.d.ts.map +1 -1
  4. package/lib/documents/ast-document-manager.js +290 -130
  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 +146 -0
  15. package/lib/documents/client-session-registry.d.ts.map +1 -0
  16. package/lib/documents/client-session-registry.js +207 -0
  17. package/lib/documents/client-session-registry.js.map +1 -0
  18. package/lib/documents/dirty-state-tracker.d.ts +101 -0
  19. package/lib/documents/dirty-state-tracker.d.ts.map +1 -0
  20. package/lib/documents/dirty-state-tracker.js +85 -0
  21. package/lib/documents/dirty-state-tracker.js.map +1 -0
  22. package/lib/documents/document-release-handler.d.ts +204 -0
  23. package/lib/documents/document-release-handler.d.ts.map +1 -0
  24. package/lib/documents/document-release-handler.js +317 -0
  25. package/lib/documents/document-release-handler.js.map +1 -0
  26. package/lib/documents/document-release-scheduler.d.ts +67 -0
  27. package/lib/documents/document-release-scheduler.d.ts.map +1 -0
  28. package/lib/documents/document-release-scheduler.js +80 -0
  29. package/lib/documents/document-release-scheduler.js.map +1 -0
  30. package/lib/documents/file-system-task-queue.d.ts +49 -0
  31. package/lib/documents/file-system-task-queue.d.ts.map +1 -0
  32. package/lib/documents/file-system-task-queue.js +34 -0
  33. package/lib/documents/file-system-task-queue.js.map +1 -0
  34. package/lib/documents/hydranium-text-documents.d.ts +415 -282
  35. package/lib/documents/hydranium-text-documents.d.ts.map +1 -1
  36. package/lib/documents/hydranium-text-documents.js +849 -483
  37. package/lib/documents/hydranium-text-documents.js.map +1 -1
  38. package/lib/documents/index.d.ts +10 -2
  39. package/lib/documents/index.d.ts.map +1 -1
  40. package/lib/documents/index.js +10 -2
  41. package/lib/documents/index.js.map +1 -1
  42. package/lib/documents/language-client-shadow.d.ts +218 -0
  43. package/lib/documents/language-client-shadow.d.ts.map +1 -0
  44. package/lib/documents/language-client-shadow.js +284 -0
  45. package/lib/documents/language-client-shadow.js.map +1 -0
  46. package/lib/documents/model-ledger.d.ts +47 -0
  47. package/lib/documents/model-ledger.d.ts.map +1 -0
  48. package/lib/documents/model-ledger.js +30 -0
  49. package/lib/documents/model-ledger.js.map +1 -0
  50. package/lib/documents/text-ledger.d.ts +64 -0
  51. package/lib/documents/text-ledger.d.ts.map +1 -0
  52. package/lib/documents/text-ledger.js +63 -0
  53. package/lib/documents/text-ledger.js.map +1 -0
  54. package/lib/documents/version-sync-service.d.ts +138 -0
  55. package/lib/documents/version-sync-service.d.ts.map +1 -0
  56. package/lib/documents/version-sync-service.js +173 -0
  57. package/lib/documents/version-sync-service.js.map +1 -0
  58. package/lib/index.d.ts +5 -0
  59. package/lib/index.d.ts.map +1 -1
  60. package/lib/index.js +8 -0
  61. package/lib/index.js.map +1 -1
  62. package/lib/langium/ast-extension/ast-extension-service.d.ts +3 -0
  63. package/lib/langium/ast-extension/ast-extension-service.d.ts.map +1 -1
  64. package/lib/langium/ast-extension/ast-extension-service.js.map +1 -1
  65. package/lib/langium/ast-extension/ast-node-builder.d.ts +32 -9
  66. package/lib/langium/ast-extension/ast-node-builder.d.ts.map +1 -1
  67. package/lib/langium/ast-extension/ast-node-builder.js +60 -22
  68. package/lib/langium/ast-extension/ast-node-builder.js.map +1 -1
  69. package/lib/langium/bootstrap.d.ts +49 -36
  70. package/lib/langium/bootstrap.d.ts.map +1 -1
  71. package/lib/langium/bootstrap.js +91 -45
  72. package/lib/langium/bootstrap.js.map +1 -1
  73. package/lib/langium/build-phase-pass/build-phase-pass-service.d.ts +1 -1
  74. package/lib/langium/build-phase-pass/build-phase-pass-service.d.ts.map +1 -1
  75. package/lib/langium/build-phase-pass/build-phase-pass-service.js.map +1 -1
  76. package/lib/langium/build-phase-pass/build-phase-pass.d.ts +1 -1
  77. package/lib/langium/composite-ast-reflection.d.ts +46 -0
  78. package/lib/langium/composite-ast-reflection.d.ts.map +1 -0
  79. package/lib/langium/composite-ast-reflection.js +97 -0
  80. package/lib/langium/composite-ast-reflection.js.map +1 -0
  81. package/lib/langium/config/configuration-provider.d.ts +81 -0
  82. package/lib/langium/config/configuration-provider.d.ts.map +1 -0
  83. package/lib/langium/config/configuration-provider.js +112 -0
  84. package/lib/langium/config/configuration-provider.js.map +1 -0
  85. package/lib/langium/config/index.d.ts +1 -0
  86. package/lib/langium/config/index.d.ts.map +1 -1
  87. package/lib/langium/config/index.js +1 -0
  88. package/lib/langium/config/index.js.map +1 -1
  89. package/lib/langium/config/settings.js.map +1 -1
  90. package/lib/langium/diagnostics/hydranium-langium-profiler.d.ts +9 -20
  91. package/lib/langium/diagnostics/hydranium-langium-profiler.d.ts.map +1 -1
  92. package/lib/langium/diagnostics/hydranium-langium-profiler.js +15 -24
  93. package/lib/langium/diagnostics/hydranium-langium-profiler.js.map +1 -1
  94. package/lib/langium/diagnostics/log-preamble.js +1 -1
  95. package/lib/langium/diagnostics/log-preamble.js.map +1 -1
  96. package/lib/langium/diagnostics/logger.d.ts +10 -3
  97. package/lib/langium/diagnostics/logger.d.ts.map +1 -1
  98. package/lib/langium/diagnostics/logger.js +12 -5
  99. package/lib/langium/diagnostics/logger.js.map +1 -1
  100. package/lib/langium/diagnostics/lsp-logger.d.ts +17 -0
  101. package/lib/langium/diagnostics/lsp-logger.d.ts.map +1 -1
  102. package/lib/langium/diagnostics/lsp-logger.js +58 -17
  103. package/lib/langium/diagnostics/lsp-logger.js.map +1 -1
  104. package/lib/langium/diagnostics/server-tracer.d.ts.map +1 -1
  105. package/lib/langium/diagnostics/server-tracer.js.map +1 -1
  106. package/lib/langium/document-builder/build-pipeline-integration.d.ts +21 -1
  107. package/lib/langium/document-builder/build-pipeline-integration.d.ts.map +1 -1
  108. package/lib/langium/document-builder/build-pipeline-integration.js +32 -5
  109. package/lib/langium/document-builder/build-pipeline-integration.js.map +1 -1
  110. package/lib/langium/document-builder/build-session.d.ts +6 -5
  111. package/lib/langium/document-builder/build-session.d.ts.map +1 -1
  112. package/lib/langium/document-builder/build-session.js +5 -5
  113. package/lib/langium/document-builder/build-session.js.map +1 -1
  114. package/lib/langium/document-builder/document-builder.d.ts +309 -35
  115. package/lib/langium/document-builder/document-builder.d.ts.map +1 -1
  116. package/lib/langium/document-builder/document-builder.js +511 -75
  117. package/lib/langium/document-builder/document-builder.js.map +1 -1
  118. package/lib/langium/documentation/comment-provider.d.ts.map +1 -1
  119. package/lib/langium/documentation/comment-provider.js.map +1 -1
  120. package/lib/langium/integration-services.d.ts +40 -24
  121. package/lib/langium/integration-services.d.ts.map +1 -1
  122. package/lib/langium/integration-services.js +7 -4
  123. package/lib/langium/integration-services.js.map +1 -1
  124. package/lib/langium/integrity/integrity-rule.d.ts +16 -8
  125. package/lib/langium/integrity/integrity-rule.d.ts.map +1 -1
  126. package/lib/langium/integrity/integrity-rule.js.map +1 -1
  127. package/lib/langium/integrity/integrity-service.d.ts +83 -27
  128. package/lib/langium/integrity/integrity-service.d.ts.map +1 -1
  129. package/lib/langium/integrity/integrity-service.js +273 -63
  130. package/lib/langium/integrity/integrity-service.js.map +1 -1
  131. package/lib/langium/keys/containment.d.ts +64 -0
  132. package/lib/langium/keys/containment.d.ts.map +1 -0
  133. package/lib/langium/keys/containment.js +53 -0
  134. package/lib/langium/keys/containment.js.map +1 -0
  135. package/lib/langium/keys/index.d.ts +1 -0
  136. package/lib/langium/keys/index.d.ts.map +1 -1
  137. package/lib/langium/keys/index.js +1 -0
  138. package/lib/langium/keys/index.js.map +1 -1
  139. package/lib/langium/keys/name-based-key-provider.d.ts +4 -0
  140. package/lib/langium/keys/name-based-key-provider.d.ts.map +1 -1
  141. package/lib/langium/keys/name-based-key-provider.js +4 -0
  142. package/lib/langium/keys/name-based-key-provider.js.map +1 -1
  143. package/lib/langium/keys/positional-key-provider.d.ts.map +1 -1
  144. package/lib/langium/keys/positional-key-provider.js.map +1 -1
  145. package/lib/langium/labeling/label-provider.d.ts.map +1 -1
  146. package/lib/langium/labeling/label-provider.js.map +1 -1
  147. package/lib/langium/language-module.d.ts +30 -5
  148. package/lib/langium/language-module.d.ts.map +1 -1
  149. package/lib/langium/language-module.js +18 -4
  150. package/lib/langium/language-module.js.map +1 -1
  151. package/lib/langium/model-service/client-session.d.ts +372 -0
  152. package/lib/langium/model-service/client-session.d.ts.map +1 -0
  153. package/lib/langium/model-service/client-session.js +446 -0
  154. package/lib/langium/model-service/client-session.js.map +1 -0
  155. package/lib/langium/model-service/index.d.ts +2 -0
  156. package/lib/langium/model-service/index.d.ts.map +1 -1
  157. package/lib/langium/model-service/index.js +2 -0
  158. package/lib/langium/model-service/index.js.map +1 -1
  159. package/lib/langium/model-service/model-events.d.ts +66 -0
  160. package/lib/langium/model-service/model-events.d.ts.map +1 -0
  161. package/lib/langium/model-service/model-events.js +10 -0
  162. package/lib/langium/model-service/model-events.js.map +1 -0
  163. package/lib/langium/model-service/model-service.d.ts +440 -282
  164. package/lib/langium/model-service/model-service.d.ts.map +1 -1
  165. package/lib/langium/model-service/model-service.js +542 -446
  166. package/lib/langium/model-service/model-service.js.map +1 -1
  167. package/lib/langium/module.d.ts +158 -37
  168. package/lib/langium/module.d.ts.map +1 -1
  169. package/lib/langium/module.js +52 -36
  170. package/lib/langium/module.js.map +1 -1
  171. package/lib/langium/naming/name-provider.d.ts +27 -6
  172. package/lib/langium/naming/name-provider.d.ts.map +1 -1
  173. package/lib/langium/naming/name-provider.js +4 -3
  174. package/lib/langium/naming/name-provider.js.map +1 -1
  175. package/lib/langium/naming/name-separator-validation.d.ts +23 -1
  176. package/lib/langium/naming/name-separator-validation.d.ts.map +1 -1
  177. package/lib/langium/naming/name-separator-validation.js +22 -0
  178. package/lib/langium/naming/name-separator-validation.js.map +1 -1
  179. package/lib/langium/project/abstract-project-manager.d.ts.map +1 -1
  180. package/lib/langium/project/abstract-project-manager.js +13 -6
  181. package/lib/langium/project/abstract-project-manager.js.map +1 -1
  182. package/lib/langium/project/project-change-event.d.ts +2 -2
  183. package/lib/langium/project/single-project-manager.d.ts.map +1 -1
  184. package/lib/langium/project/single-project-manager.js.map +1 -1
  185. package/lib/langium/residency/cst-residency-service.d.ts +35 -12
  186. package/lib/langium/residency/cst-residency-service.d.ts.map +1 -1
  187. package/lib/langium/residency/cst-residency-service.js +23 -57
  188. package/lib/langium/residency/cst-residency-service.js.map +1 -1
  189. package/lib/langium/scope/ast-node-description-provider.d.ts.map +1 -1
  190. package/lib/langium/scope/ast-node-description-provider.js.map +1 -1
  191. package/lib/langium/scope/fallback-scope.d.ts +27 -0
  192. package/lib/langium/scope/fallback-scope.d.ts.map +1 -0
  193. package/lib/langium/scope/fallback-scope.js +35 -0
  194. package/lib/langium/scope/fallback-scope.js.map +1 -0
  195. package/lib/langium/scope/hydranium-scope-computation.d.ts +21 -18
  196. package/lib/langium/scope/hydranium-scope-computation.d.ts.map +1 -1
  197. package/lib/langium/scope/hydranium-scope-computation.js +38 -39
  198. package/lib/langium/scope/hydranium-scope-computation.js.map +1 -1
  199. package/lib/langium/scope/hydranium-scope-provider.d.ts +61 -24
  200. package/lib/langium/scope/hydranium-scope-provider.d.ts.map +1 -1
  201. package/lib/langium/scope/hydranium-scope-provider.js +74 -35
  202. package/lib/langium/scope/hydranium-scope-provider.js.map +1 -1
  203. package/lib/langium/scope/index.d.ts +1 -0
  204. package/lib/langium/scope/index.d.ts.map +1 -1
  205. package/lib/langium/scope/index.js +1 -0
  206. package/lib/langium/scope/index.js.map +1 -1
  207. package/lib/langium/scope/reference-builder.d.ts.map +1 -1
  208. package/lib/langium/scope/reference-builder.js.map +1 -1
  209. package/lib/langium/scope/reference-candidate-provider.d.ts +6 -5
  210. package/lib/langium/scope/reference-candidate-provider.d.ts.map +1 -1
  211. package/lib/langium/scope/reference-candidate-provider.js +3 -2
  212. package/lib/langium/scope/reference-candidate-provider.js.map +1 -1
  213. package/lib/langium/scope/scope-extension-service.d.ts +41 -37
  214. package/lib/langium/scope/scope-extension-service.d.ts.map +1 -1
  215. package/lib/langium/scope/scope-extension-service.js +57 -29
  216. package/lib/langium/scope/scope-extension-service.js.map +1 -1
  217. package/lib/langium/scope/scoped-ast-node-description.d.ts +1 -3
  218. package/lib/langium/scope/scoped-ast-node-description.d.ts.map +1 -1
  219. package/lib/langium/scope/scoped-ast-node-description.js +1 -3
  220. package/lib/langium/scope/scoped-ast-node-description.js.map +1 -1
  221. package/lib/langium/serialization/abstract-serializer.d.ts +38 -27
  222. package/lib/langium/serialization/abstract-serializer.d.ts.map +1 -1
  223. package/lib/langium/serialization/abstract-serializer.js +54 -30
  224. package/lib/langium/serialization/abstract-serializer.js.map +1 -1
  225. package/lib/langium/serialization/json-serializer.d.ts +8 -1
  226. package/lib/langium/serialization/json-serializer.d.ts.map +1 -1
  227. package/lib/langium/serialization/json-serializer.js +13 -3
  228. package/lib/langium/serialization/json-serializer.js.map +1 -1
  229. package/lib/langium/serialization/serializer.d.ts +1 -1
  230. package/lib/langium/serialization/yaml-serializer.d.ts +4 -0
  231. package/lib/langium/serialization/yaml-serializer.d.ts.map +1 -1
  232. package/lib/langium/serialization/yaml-serializer.js +4 -0
  233. package/lib/langium/serialization/yaml-serializer.js.map +1 -1
  234. package/lib/langium/service-registry.d.ts +29 -1
  235. package/lib/langium/service-registry.d.ts.map +1 -1
  236. package/lib/langium/service-registry.js +37 -0
  237. package/lib/langium/service-registry.js.map +1 -1
  238. package/lib/langium/shared-services.d.ts +23 -6
  239. package/lib/langium/shared-services.d.ts.map +1 -1
  240. package/lib/langium/shared-services.js.map +1 -1
  241. package/lib/langium/single-langium-copy.d.ts +22 -0
  242. package/lib/langium/single-langium-copy.d.ts.map +1 -0
  243. package/lib/langium/single-langium-copy.js +36 -0
  244. package/lib/langium/single-langium-copy.js.map +1 -0
  245. package/lib/langium/transfer/transfer-encoder.d.ts +84 -35
  246. package/lib/langium/transfer/transfer-encoder.d.ts.map +1 -1
  247. package/lib/langium/transfer/transfer-encoder.js +34 -23
  248. package/lib/langium/transfer/transfer-encoder.js.map +1 -1
  249. package/lib/langium/trivia/comment-preserver.d.ts +423 -0
  250. package/lib/langium/trivia/comment-preserver.d.ts.map +1 -0
  251. package/lib/langium/trivia/comment-preserver.js +906 -0
  252. package/lib/langium/trivia/comment-preserver.js.map +1 -0
  253. package/lib/langium/trivia/document-ending-preserver.d.ts +43 -0
  254. package/lib/langium/trivia/document-ending-preserver.d.ts.map +1 -0
  255. package/lib/langium/trivia/document-ending-preserver.js +48 -0
  256. package/lib/langium/trivia/document-ending-preserver.js.map +1 -0
  257. package/lib/langium/trivia/index.d.ts +14 -0
  258. package/lib/langium/trivia/index.d.ts.map +1 -0
  259. package/lib/langium/trivia/index.js +14 -0
  260. package/lib/langium/trivia/index.js.map +1 -0
  261. package/lib/langium/trivia/trivia-contribution.d.ts +37 -0
  262. package/lib/langium/trivia/trivia-contribution.d.ts.map +1 -0
  263. package/lib/langium/trivia/trivia-contribution.js +10 -0
  264. package/lib/langium/trivia/trivia-contribution.js.map +1 -0
  265. package/lib/langium/trivia/trivia-preserver.d.ts +50 -0
  266. package/lib/langium/trivia/trivia-preserver.d.ts.map +1 -0
  267. package/lib/langium/trivia/trivia-preserver.js +10 -0
  268. package/lib/langium/trivia/trivia-preserver.js.map +1 -0
  269. package/lib/langium/trivia/trivia-service.d.ts +70 -0
  270. package/lib/langium/trivia/trivia-service.d.ts.map +1 -0
  271. package/lib/langium/trivia/trivia-service.js +56 -0
  272. package/lib/langium/trivia/trivia-service.js.map +1 -0
  273. package/lib/langium/update-rewrite/normalize-empty-strings.d.ts.map +1 -1
  274. package/lib/langium/update-rewrite/update-rewrite-service.d.ts +1 -1
  275. package/lib/langium/update-rewrite/update-rewrite-service.d.ts.map +1 -1
  276. package/lib/langium/update-rewrite/update-rewrite-service.js.map +1 -1
  277. package/lib/langium/update-rewrite/update-rewrite.d.ts +1 -1
  278. package/lib/langium/validation/document-validator.d.ts +280 -9
  279. package/lib/langium/validation/document-validator.d.ts.map +1 -1
  280. package/lib/langium/validation/document-validator.js +453 -8
  281. package/lib/langium/validation/document-validator.js.map +1 -1
  282. package/lib/langium/validation/validation-contribution-collector.d.ts +9 -1
  283. package/lib/langium/validation/validation-contribution-collector.d.ts.map +1 -1
  284. package/lib/langium/validation/validation-contribution-collector.js +1 -1
  285. package/lib/langium/validation/validation-contribution-collector.js.map +1 -1
  286. package/lib/langium/workspace/document-uri-policy.d.ts +15 -10
  287. package/lib/langium/workspace/document-uri-policy.d.ts.map +1 -1
  288. package/lib/langium/workspace/document-uri-policy.js +7 -5
  289. package/lib/langium/workspace/document-uri-policy.js.map +1 -1
  290. package/lib/langium/workspace/file-not-found.d.ts +23 -0
  291. package/lib/langium/workspace/file-not-found.d.ts.map +1 -0
  292. package/lib/langium/workspace/file-not-found.js +31 -0
  293. package/lib/langium/workspace/file-not-found.js.map +1 -0
  294. package/lib/langium/workspace/file-system-provider.d.ts +154 -8
  295. package/lib/langium/workspace/file-system-provider.d.ts.map +1 -1
  296. package/lib/langium/workspace/file-system-provider.js +102 -13
  297. package/lib/langium/workspace/file-system-provider.js.map +1 -1
  298. package/lib/langium/workspace/hydranium-langium-document-factory.d.ts +56 -1
  299. package/lib/langium/workspace/hydranium-langium-document-factory.d.ts.map +1 -1
  300. package/lib/langium/workspace/hydranium-langium-document-factory.js +79 -0
  301. package/lib/langium/workspace/hydranium-langium-document-factory.js.map +1 -1
  302. package/lib/langium/workspace/hydranium-workspace-lock.d.ts +43 -1
  303. package/lib/langium/workspace/hydranium-workspace-lock.d.ts.map +1 -1
  304. package/lib/langium/workspace/hydranium-workspace-lock.js +58 -1
  305. package/lib/langium/workspace/hydranium-workspace-lock.js.map +1 -1
  306. package/lib/langium/workspace/hydranium-workspace-manager.d.ts +109 -9
  307. package/lib/langium/workspace/hydranium-workspace-manager.d.ts.map +1 -1
  308. package/lib/langium/workspace/hydranium-workspace-manager.js +192 -12
  309. package/lib/langium/workspace/hydranium-workspace-manager.js.map +1 -1
  310. package/lib/langium/workspace/in-memory-file-system-provider.d.ts +26 -9
  311. package/lib/langium/workspace/in-memory-file-system-provider.d.ts.map +1 -1
  312. package/lib/langium/workspace/in-memory-file-system-provider.js +45 -22
  313. package/lib/langium/workspace/in-memory-file-system-provider.js.map +1 -1
  314. package/lib/langium/workspace/index-manager.d.ts.map +1 -1
  315. package/lib/langium/workspace/index-manager.js.map +1 -1
  316. package/lib/langium/workspace/index.d.ts +1 -0
  317. package/lib/langium/workspace/index.d.ts.map +1 -1
  318. package/lib/langium/workspace/index.js +1 -0
  319. package/lib/langium/workspace/index.js.map +1 -1
  320. package/lib/langium/workspace/initialize-workspace.d.ts +31 -2
  321. package/lib/langium/workspace/initialize-workspace.d.ts.map +1 -1
  322. package/lib/langium/workspace/initialize-workspace.js +13 -5
  323. package/lib/langium/workspace/initialize-workspace.js.map +1 -1
  324. package/lib/langium/workspace/langium-documents.d.ts +37 -4
  325. package/lib/langium/workspace/langium-documents.d.ts.map +1 -1
  326. package/lib/langium/workspace/langium-documents.js +49 -4
  327. package/lib/langium/workspace/langium-documents.js.map +1 -1
  328. package/lib/langium/workspace/persistent-file-system-provider.d.ts +7 -9
  329. package/lib/langium/workspace/persistent-file-system-provider.d.ts.map +1 -1
  330. package/lib/langium/workspace/persistent-file-system-provider.js +14 -13
  331. package/lib/langium/workspace/persistent-file-system-provider.js.map +1 -1
  332. package/lib/langium/workspace/self-save-registry.d.ts +84 -0
  333. package/lib/langium/workspace/self-save-registry.d.ts.map +1 -0
  334. package/lib/{documents → langium/workspace}/self-save-registry.js +33 -22
  335. package/lib/langium/workspace/self-save-registry.js.map +1 -0
  336. package/lib/langium/workspace/virtual-document.d.ts +49 -15
  337. package/lib/langium/workspace/virtual-document.d.ts.map +1 -1
  338. package/lib/langium/workspace/virtual-document.js +81 -18
  339. package/lib/langium/workspace/virtual-document.js.map +1 -1
  340. package/lib/langium/workspace/write-lock-scope.d.ts +22 -10
  341. package/lib/langium/workspace/write-lock-scope.d.ts.map +1 -1
  342. package/lib/langium/workspace/write-lock-scope.js +15 -5
  343. package/lib/langium/workspace/write-lock-scope.js.map +1 -1
  344. package/lib/launcher/integrated-server.d.ts +3 -1
  345. package/lib/launcher/integrated-server.d.ts.map +1 -1
  346. package/lib/locale/index.d.ts +10 -0
  347. package/lib/locale/index.d.ts.map +1 -0
  348. package/lib/locale/index.js +10 -0
  349. package/lib/locale/index.js.map +1 -0
  350. package/lib/locale/server-locale.d.ts +73 -0
  351. package/lib/locale/server-locale.d.ts.map +1 -0
  352. package/lib/locale/server-locale.js +61 -0
  353. package/lib/locale/server-locale.js.map +1 -0
  354. package/lib/lsp/completion/hydranium-completion-provider.d.ts +44 -2
  355. package/lib/lsp/completion/hydranium-completion-provider.d.ts.map +1 -1
  356. package/lib/lsp/completion/hydranium-completion-provider.js +68 -0
  357. package/lib/lsp/completion/hydranium-completion-provider.js.map +1 -1
  358. package/lib/lsp/connection-features.d.ts +23 -0
  359. package/lib/lsp/connection-features.d.ts.map +1 -0
  360. package/lib/lsp/connection-features.js +60 -0
  361. package/lib/lsp/connection-features.js.map +1 -0
  362. package/lib/lsp/diagnostics-connection.d.ts +27 -0
  363. package/lib/lsp/diagnostics-connection.d.ts.map +1 -0
  364. package/lib/lsp/diagnostics-connection.js +53 -0
  365. package/lib/lsp/diagnostics-connection.js.map +1 -0
  366. package/lib/lsp/hydranium-document-update-handler.d.ts +106 -82
  367. package/lib/lsp/hydranium-document-update-handler.d.ts.map +1 -1
  368. package/lib/lsp/hydranium-document-update-handler.js +182 -102
  369. package/lib/lsp/hydranium-document-update-handler.js.map +1 -1
  370. package/lib/lsp/index.d.ts +3 -1
  371. package/lib/lsp/index.d.ts.map +1 -1
  372. package/lib/lsp/index.js +3 -1
  373. package/lib/lsp/index.js.map +1 -1
  374. package/lib/lsp/lsp-latency.d.ts +39 -0
  375. package/lib/lsp/lsp-latency.d.ts.map +1 -0
  376. package/lib/lsp/lsp-latency.js +58 -0
  377. package/lib/lsp/lsp-latency.js.map +1 -0
  378. package/lib/lsp/semantic-token-provider.d.ts +34 -1
  379. package/lib/lsp/semantic-token-provider.d.ts.map +1 -1
  380. package/lib/lsp/semantic-token-provider.js +55 -8
  381. package/lib/lsp/semantic-token-provider.js.map +1 -1
  382. package/lib/lsp/shared-module.d.ts +4 -8
  383. package/lib/lsp/shared-module.d.ts.map +1 -1
  384. package/lib/lsp/shared-module.js.map +1 -1
  385. package/lib/lsp/start-language-server.d.ts +8 -7
  386. package/lib/lsp/start-language-server.d.ts.map +1 -1
  387. package/lib/lsp/start-language-server.js +13 -7
  388. package/lib/lsp/start-language-server.js.map +1 -1
  389. package/lib/messages/carriers.d.ts +18 -12
  390. package/lib/messages/carriers.d.ts.map +1 -1
  391. package/lib/messages/carriers.js +22 -13
  392. package/lib/messages/carriers.js.map +1 -1
  393. package/lib/messages/index.d.ts +4 -1
  394. package/lib/messages/index.d.ts.map +1 -1
  395. package/lib/messages/index.js +4 -1
  396. package/lib/messages/index.js.map +1 -1
  397. package/lib/messages/renderer.d.ts +142 -0
  398. package/lib/messages/renderer.d.ts.map +1 -0
  399. package/lib/messages/renderer.js +165 -0
  400. package/lib/messages/renderer.js.map +1 -0
  401. package/lib/node/event-loop-monitor.d.ts.map +1 -1
  402. package/lib/node/event-loop-monitor.js +2 -1
  403. package/lib/node/event-loop-monitor.js.map +1 -1
  404. package/lib/node/heap-ceiling.d.ts +61 -0
  405. package/lib/node/heap-ceiling.d.ts.map +1 -0
  406. package/lib/node/heap-ceiling.js +72 -0
  407. package/lib/node/heap-ceiling.js.map +1 -0
  408. package/lib/node/index.d.ts +1 -1
  409. package/lib/node/index.d.ts.map +1 -1
  410. package/lib/node/index.js +1 -1
  411. package/lib/node/index.js.map +1 -1
  412. package/lib/node/latency-from-env.d.ts +1 -1
  413. package/lib/node/latency-from-env.js +1 -1
  414. package/lib/node/lint-grammar.js.map +1 -1
  415. package/lib/node/log-preamble-node.d.ts +5 -3
  416. package/lib/node/log-preamble-node.d.ts.map +1 -1
  417. package/lib/node/log-preamble-node.js +13 -10
  418. package/lib/node/log-preamble-node.js.map +1 -1
  419. package/lib/node/measure-memory.d.ts.map +1 -1
  420. package/lib/node/measure-memory.js +5 -4
  421. package/lib/node/measure-memory.js.map +1 -1
  422. package/lib/node/memory-monitor.d.ts +2 -2
  423. package/lib/node/memory-monitor.d.ts.map +1 -1
  424. package/lib/node/memory-monitor.js +9 -10
  425. package/lib/node/memory-monitor.js.map +1 -1
  426. package/lib/node/node-file-system-provider.d.ts +60 -9
  427. package/lib/node/node-file-system-provider.d.ts.map +1 -1
  428. package/lib/node/node-file-system-provider.js +162 -52
  429. package/lib/node/node-file-system-provider.js.map +1 -1
  430. package/lib/node/profile-capture.d.ts +12 -4
  431. package/lib/node/profile-capture.d.ts.map +1 -1
  432. package/lib/node/profile-capture.js +8 -6
  433. package/lib/node/profile-capture.js.map +1 -1
  434. package/lib/node/profile-digest.js.map +1 -1
  435. package/lib/node/profiling-run.d.ts +13 -3
  436. package/lib/node/profiling-run.d.ts.map +1 -1
  437. package/lib/node/profiling-run.js +17 -8
  438. package/lib/node/profiling-run.js.map +1 -1
  439. package/lib/node/rename-over-open-readers.d.ts +61 -0
  440. package/lib/node/rename-over-open-readers.d.ts.map +1 -0
  441. package/lib/node/rename-over-open-readers.js +80 -0
  442. package/lib/node/rename-over-open-readers.js.map +1 -0
  443. package/lib/node/server-diagnostics.js +1 -1
  444. package/lib/node/server-diagnostics.js.map +1 -1
  445. package/lib/node/server-state-snapshot.js +4 -4
  446. package/lib/node/server-state-snapshot.js.map +1 -1
  447. package/lib/node/socket-launcher.d.ts +20 -4
  448. package/lib/node/socket-launcher.d.ts.map +1 -1
  449. package/lib/node/socket-launcher.js +8 -7
  450. package/lib/node/socket-launcher.js.map +1 -1
  451. package/lib/node/stdio-launcher.d.ts +10 -10
  452. package/lib/node/stdio-launcher.d.ts.map +1 -1
  453. package/lib/node/stdio-launcher.js +17 -9
  454. package/lib/node/stdio-launcher.js.map +1 -1
  455. package/lib/testing/document-uri-policy-conformance.js +1 -1
  456. package/lib/testing/document-uri-policy-conformance.js.map +1 -1
  457. package/lib/testing/fake-description.js.map +1 -1
  458. package/lib/testing/fake-document.d.ts +16 -4
  459. package/lib/testing/fake-document.d.ts.map +1 -1
  460. package/lib/testing/fake-document.js +18 -3
  461. package/lib/testing/fake-document.js.map +1 -1
  462. package/lib/testing/index.d.ts +1 -1
  463. package/lib/testing/index.d.ts.map +1 -1
  464. package/lib/testing/index.js +2 -1
  465. package/lib/testing/index.js.map +1 -1
  466. package/lib/testing/langium-test-helpers.d.ts.map +1 -1
  467. package/lib/testing/langium-test-helpers.js +1 -0
  468. package/lib/testing/langium-test-helpers.js.map +1 -1
  469. package/lib/testing/make-noop-language-services.js.map +1 -1
  470. package/lib/testing/make-noop-shared-services.d.ts +14 -0
  471. package/lib/testing/make-noop-shared-services.d.ts.map +1 -1
  472. package/lib/testing/make-noop-shared-services.js +28 -2
  473. package/lib/testing/make-noop-shared-services.js.map +1 -1
  474. package/lib/testing/make-test-services.d.ts +72 -14
  475. package/lib/testing/make-test-services.d.ts.map +1 -1
  476. package/lib/testing/make-test-services.js +42 -10
  477. package/lib/testing/make-test-services.js.map +1 -1
  478. package/lib/testing/make-test-tracer.d.ts +12 -0
  479. package/lib/testing/make-test-tracer.d.ts.map +1 -1
  480. package/lib/testing/make-test-tracer.js +13 -0
  481. package/lib/testing/make-test-tracer.js.map +1 -1
  482. package/lib/testing/node/applied-edit-capture.d.ts +29 -0
  483. package/lib/testing/node/applied-edit-capture.d.ts.map +1 -0
  484. package/lib/testing/node/applied-edit-capture.js +115 -0
  485. package/lib/testing/node/applied-edit-capture.js.map +1 -0
  486. package/lib/testing/node/golden-corpus.js.map +1 -1
  487. package/lib/testing/node/index.d.ts +1 -0
  488. package/lib/testing/node/index.d.ts.map +1 -1
  489. package/lib/testing/node/index.js +1 -0
  490. package/lib/testing/node/index.js.map +1 -1
  491. package/lib/testing/node/lsp-harness.d.ts.map +1 -1
  492. package/lib/testing/node/lsp-harness.js +2 -0
  493. package/lib/testing/node/lsp-harness.js.map +1 -1
  494. package/lib/testing/node/lsp-server-connection.d.ts +12 -4
  495. package/lib/testing/node/lsp-server-connection.d.ts.map +1 -1
  496. package/lib/testing/node/lsp-server-connection.js +45 -106
  497. package/lib/testing/node/lsp-server-connection.js.map +1 -1
  498. package/lib/testing/node/scratch-workspace.d.ts.map +1 -1
  499. package/lib/testing/node/scratch-workspace.js +10 -5
  500. package/lib/testing/node/scratch-workspace.js.map +1 -1
  501. package/lib/testing/node/spawned-server.d.ts +30 -1
  502. package/lib/testing/node/spawned-server.d.ts.map +1 -1
  503. package/lib/testing/node/spawned-server.js +39 -2
  504. package/lib/testing/node/spawned-server.js.map +1 -1
  505. package/lib/testing/node/unhandled-rejections.d.ts +20 -0
  506. package/lib/testing/node/unhandled-rejections.d.ts.map +1 -0
  507. package/lib/testing/node/unhandled-rejections.js +32 -0
  508. package/lib/testing/node/unhandled-rejections.js.map +1 -0
  509. package/lib/testing/playwright/browser-capture-bridge.js.map +1 -1
  510. package/lib/testing/playwright/e2e-profiling.js.map +1 -1
  511. package/lib/testing/playwright/flaky-network-proxy.d.ts +76 -0
  512. package/lib/testing/playwright/flaky-network-proxy.d.ts.map +1 -0
  513. package/lib/testing/playwright/flaky-network-proxy.js +164 -0
  514. package/lib/testing/playwright/flaky-network-proxy.js.map +1 -0
  515. package/lib/testing/playwright/index.d.ts +1 -0
  516. package/lib/testing/playwright/index.d.ts.map +1 -1
  517. package/lib/testing/playwright/index.js +1 -0
  518. package/lib/testing/playwright/index.js.map +1 -1
  519. package/lib/testing/playwright/server-log-capture.d.ts +35 -8
  520. package/lib/testing/playwright/server-log-capture.d.ts.map +1 -1
  521. package/lib/testing/playwright/server-log-capture.js +39 -6
  522. package/lib/testing/playwright/server-log-capture.js.map +1 -1
  523. package/lib/testing/playwright/server-log-fixture.d.ts +16 -0
  524. package/lib/testing/playwright/server-log-fixture.d.ts.map +1 -1
  525. package/lib/testing/playwright/server-log-fixture.js +25 -6
  526. package/lib/testing/playwright/server-log-fixture.js.map +1 -1
  527. package/lib/testing/playwright/server-log-region.d.ts +15 -0
  528. package/lib/testing/playwright/server-log-region.d.ts.map +1 -0
  529. package/lib/testing/playwright/server-log-region.js +30 -0
  530. package/lib/testing/playwright/server-log-region.js.map +1 -0
  531. package/lib/testing/playwright/server-log-rename-reporter.d.ts.map +1 -1
  532. package/lib/testing/playwright/server-log-rename-reporter.js +10 -1
  533. package/lib/testing/playwright/server-log-rename-reporter.js.map +1 -1
  534. package/lib/testing/run-update-pipeline.d.ts +6 -5
  535. package/lib/testing/run-update-pipeline.d.ts.map +1 -1
  536. package/lib/testing/run-update-pipeline.js.map +1 -1
  537. package/lib/testing/stub-ast-document-manager.d.ts +11 -52
  538. package/lib/testing/stub-ast-document-manager.d.ts.map +1 -1
  539. package/lib/testing/stub-ast-document-manager.js +31 -62
  540. package/lib/testing/stub-ast-document-manager.js.map +1 -1
  541. package/lib/testing/stub-document-builder.d.ts +33 -11
  542. package/lib/testing/stub-document-builder.d.ts.map +1 -1
  543. package/lib/testing/stub-document-builder.js +103 -5
  544. package/lib/testing/stub-document-builder.js.map +1 -1
  545. package/lib/testing/stub-hydranium-text-documents.d.ts +33 -10
  546. package/lib/testing/stub-hydranium-text-documents.d.ts.map +1 -1
  547. package/lib/testing/stub-hydranium-text-documents.js +132 -16
  548. package/lib/testing/stub-hydranium-text-documents.js.map +1 -1
  549. package/lib/testing/stub-index-manager.js.map +1 -1
  550. package/lib/testing/stub-langium-documents.d.ts +3 -2
  551. package/lib/testing/stub-langium-documents.d.ts.map +1 -1
  552. package/lib/testing/stub-langium-documents.js.map +1 -1
  553. package/lib/testing/stub-model-service.d.ts +9 -8
  554. package/lib/testing/stub-model-service.d.ts.map +1 -1
  555. package/lib/testing/stub-model-service.js +6 -6
  556. package/lib/testing/stub-model-service.js.map +1 -1
  557. package/lib/testing/stub-project-manager.js.map +1 -1
  558. package/lib/testing/stub-self-save-registry.d.ts +1 -1
  559. package/lib/testing/stub-self-save-registry.d.ts.map +1 -1
  560. package/lib/testing/stub-service-registry.d.ts +1 -1
  561. package/lib/testing/stub-service-registry.js.map +1 -1
  562. package/lib/testing/stub-writable-file-system.d.ts +1 -1
  563. package/lib/testing/stub-writable-file-system.d.ts.map +1 -1
  564. package/lib/testing/stub-writable-file-system.js +2 -1
  565. package/lib/testing/stub-writable-file-system.js.map +1 -1
  566. package/lib/util/connection-liveness.d.ts +19 -6
  567. package/lib/util/connection-liveness.d.ts.map +1 -1
  568. package/lib/util/connection-liveness.js +61 -15
  569. package/lib/util/connection-liveness.js.map +1 -1
  570. package/lib/util/environment.d.ts.map +1 -1
  571. package/lib/util/environment.js.map +1 -1
  572. package/lib/util/registry.d.ts.map +1 -1
  573. package/package.json +29 -53
  574. package/src/documents/ast-document-manager.ts +463 -231
  575. package/src/documents/client-ids.ts +5 -22
  576. package/src/documents/client-session-errors.ts +24 -0
  577. package/src/documents/client-session-registry.ts +262 -0
  578. package/src/documents/dirty-state-tracker.ts +167 -0
  579. package/src/documents/document-release-handler.ts +404 -0
  580. package/src/documents/document-release-scheduler.ts +121 -0
  581. package/src/documents/file-system-task-queue.ts +68 -0
  582. package/src/documents/hydranium-text-documents.ts +968 -595
  583. package/src/documents/index.ts +10 -2
  584. package/src/documents/language-client-shadow.ts +452 -0
  585. package/src/documents/model-ledger.ts +66 -0
  586. package/src/documents/text-ledger.ts +112 -0
  587. package/src/documents/version-sync-service.ts +275 -0
  588. package/src/index.ts +8 -0
  589. package/src/langium/ast-extension/ast-extension-service.ts +3 -0
  590. package/src/langium/ast-extension/ast-node-builder.ts +66 -22
  591. package/src/langium/bootstrap.ts +95 -52
  592. package/src/langium/build-phase-pass/build-phase-pass-service.ts +1 -1
  593. package/src/langium/build-phase-pass/build-phase-pass.ts +1 -1
  594. package/src/langium/composite-ast-reflection.ts +112 -0
  595. package/src/langium/config/configuration-provider.ts +119 -0
  596. package/src/langium/config/index.ts +1 -0
  597. package/src/langium/diagnostics/hydranium-langium-profiler.ts +15 -39
  598. package/src/langium/diagnostics/log-preamble.ts +1 -1
  599. package/src/langium/diagnostics/logger.ts +12 -5
  600. package/src/langium/diagnostics/lsp-logger.ts +61 -16
  601. package/src/langium/document-builder/build-pipeline-integration.ts +50 -5
  602. package/src/langium/document-builder/build-session.ts +4 -3
  603. package/src/langium/document-builder/document-builder.ts +616 -73
  604. package/src/langium/integration-services.ts +59 -28
  605. package/src/langium/integrity/integrity-rule.ts +16 -8
  606. package/src/langium/integrity/integrity-service.ts +296 -69
  607. package/src/langium/keys/containment.ts +87 -0
  608. package/src/langium/keys/index.ts +1 -0
  609. package/src/langium/keys/name-based-key-provider.ts +4 -0
  610. package/src/langium/language-module.ts +49 -8
  611. package/src/langium/model-service/client-session.ts +702 -0
  612. package/src/langium/model-service/index.ts +2 -0
  613. package/src/langium/model-service/model-events.ts +80 -0
  614. package/src/langium/model-service/model-service.ts +835 -475
  615. package/src/langium/module.ts +212 -67
  616. package/src/langium/naming/name-provider.ts +29 -7
  617. package/src/langium/naming/name-separator-validation.ts +25 -3
  618. package/src/langium/project/abstract-project-manager.ts +13 -5
  619. package/src/langium/project/project-change-event.ts +2 -2
  620. package/src/langium/residency/cst-residency-service.ts +50 -16
  621. package/src/langium/scope/fallback-scope.ts +38 -0
  622. package/src/langium/scope/hydranium-scope-computation.ts +45 -44
  623. package/src/langium/scope/hydranium-scope-provider.ts +89 -38
  624. package/src/langium/scope/index.ts +1 -0
  625. package/src/langium/scope/reference-candidate-provider.ts +6 -5
  626. package/src/langium/scope/scope-extension-service.ts +74 -59
  627. package/src/langium/scope/scoped-ast-node-description.ts +1 -3
  628. package/src/langium/serialization/abstract-serializer.ts +57 -41
  629. package/src/langium/serialization/json-serializer.ts +14 -3
  630. package/src/langium/serialization/serializer.ts +1 -1
  631. package/src/langium/serialization/yaml-serializer.ts +4 -0
  632. package/src/langium/service-registry.ts +41 -2
  633. package/src/langium/shared-services.ts +26 -6
  634. package/src/langium/single-langium-copy.ts +42 -0
  635. package/src/langium/transfer/transfer-encoder.ts +102 -45
  636. package/src/langium/trivia/comment-preserver.ts +1100 -0
  637. package/src/langium/trivia/document-ending-preserver.ts +55 -0
  638. package/src/langium/trivia/index.ts +14 -0
  639. package/src/langium/trivia/trivia-contribution.ts +39 -0
  640. package/src/langium/trivia/trivia-preserver.ts +54 -0
  641. package/src/langium/trivia/trivia-service.ts +99 -0
  642. package/src/langium/update-rewrite/update-rewrite-service.ts +1 -1
  643. package/src/langium/update-rewrite/update-rewrite.ts +1 -1
  644. package/src/langium/validation/document-validator.ts +528 -13
  645. package/src/langium/validation/validation-contribution-collector.ts +10 -1
  646. package/src/langium/workspace/document-uri-policy.ts +15 -10
  647. package/src/langium/workspace/file-not-found.ts +35 -0
  648. package/src/langium/workspace/file-system-provider.ts +234 -16
  649. package/src/langium/workspace/hydranium-langium-document-factory.ts +117 -0
  650. package/src/langium/workspace/hydranium-workspace-lock.ts +86 -2
  651. package/src/langium/workspace/hydranium-workspace-manager.ts +221 -16
  652. package/src/langium/workspace/in-memory-file-system-provider.ts +54 -23
  653. package/src/langium/workspace/index.ts +1 -0
  654. package/src/langium/workspace/initialize-workspace.ts +43 -5
  655. package/src/langium/workspace/langium-documents.ts +63 -5
  656. package/src/langium/workspace/persistent-file-system-provider.ts +15 -14
  657. package/src/langium/workspace/self-save-registry.ts +118 -0
  658. package/src/langium/workspace/virtual-document.ts +100 -19
  659. package/src/langium/workspace/write-lock-scope.ts +27 -12
  660. package/src/launcher/integrated-server.ts +3 -1
  661. package/src/locale/index.ts +10 -0
  662. package/src/locale/server-locale.ts +86 -0
  663. package/src/lsp/completion/hydranium-completion-provider.ts +82 -2
  664. package/src/lsp/connection-features.ts +67 -0
  665. package/src/lsp/diagnostics-connection.ts +56 -0
  666. package/src/lsp/hydranium-document-update-handler.ts +227 -111
  667. package/src/lsp/index.ts +3 -1
  668. package/src/lsp/lsp-latency.ts +62 -0
  669. package/src/lsp/semantic-token-provider.ts +74 -7
  670. package/src/lsp/shared-module.ts +4 -8
  671. package/src/lsp/start-language-server.ts +13 -7
  672. package/src/messages/carriers.ts +23 -15
  673. package/src/messages/index.ts +13 -1
  674. package/src/messages/renderer.ts +212 -0
  675. package/src/node/event-loop-monitor.ts +2 -1
  676. package/src/node/heap-ceiling.ts +108 -0
  677. package/src/node/index.ts +1 -1
  678. package/src/node/latency-from-env.ts +1 -1
  679. package/src/node/log-preamble-node.ts +20 -10
  680. package/src/node/measure-memory.ts +5 -4
  681. package/src/node/memory-monitor.ts +10 -10
  682. package/src/node/node-file-system-provider.ts +178 -56
  683. package/src/node/profile-capture.ts +16 -15
  684. package/src/node/profiling-run.ts +30 -8
  685. package/src/node/rename-over-open-readers.ts +94 -0
  686. package/src/node/server-diagnostics.ts +1 -1
  687. package/src/node/server-state-snapshot.ts +5 -5
  688. package/src/node/socket-launcher.ts +27 -11
  689. package/src/node/stdio-launcher.ts +22 -14
  690. package/src/testing/document-uri-policy-conformance.ts +1 -1
  691. package/src/testing/fake-document.ts +24 -5
  692. package/src/testing/index.ts +2 -1
  693. package/src/testing/langium-test-helpers.ts +1 -0
  694. package/src/testing/make-noop-shared-services.ts +50 -2
  695. package/src/testing/make-test-services.ts +125 -31
  696. package/src/testing/make-test-tracer.ts +26 -0
  697. package/src/testing/node/applied-edit-capture.ts +139 -0
  698. package/src/testing/node/index.ts +1 -0
  699. package/src/testing/node/lsp-harness.ts +2 -0
  700. package/src/testing/node/lsp-server-connection.ts +74 -117
  701. package/src/testing/node/scratch-workspace.ts +10 -5
  702. package/src/testing/node/spawned-server.ts +57 -3
  703. package/src/testing/node/unhandled-rejections.ts +31 -0
  704. package/src/testing/parse-semantic-root.ts +1 -1
  705. package/src/testing/playwright/flaky-network-proxy.ts +240 -0
  706. package/src/testing/playwright/index.ts +1 -0
  707. package/src/testing/playwright/server-log-capture.ts +63 -11
  708. package/src/testing/playwright/server-log-fixture.ts +46 -6
  709. package/src/testing/playwright/server-log-region.ts +32 -0
  710. package/src/testing/playwright/server-log-rename-reporter.ts +12 -1
  711. package/src/testing/run-update-pipeline.ts +6 -5
  712. package/src/testing/stub-ast-document-manager.ts +47 -128
  713. package/src/testing/stub-document-builder.ts +133 -18
  714. package/src/testing/stub-hydranium-text-documents.ts +184 -27
  715. package/src/testing/stub-langium-documents.ts +3 -2
  716. package/src/testing/stub-model-service.ts +11 -10
  717. package/src/testing/stub-self-save-registry.ts +1 -1
  718. package/src/testing/stub-service-registry.ts +1 -1
  719. package/src/testing/stub-writable-file-system.ts +3 -2
  720. package/src/util/connection-liveness.ts +67 -15
  721. package/src/util/environment.ts +9 -1
  722. package/lib/documents/language-client-text-shadow.d.ts +0 -101
  723. package/lib/documents/language-client-text-shadow.d.ts.map +0 -1
  724. package/lib/documents/language-client-text-shadow.js +0 -156
  725. package/lib/documents/language-client-text-shadow.js.map +0 -1
  726. package/lib/documents/self-save-registry.d.ts +0 -55
  727. package/lib/documents/self-save-registry.d.ts.map +0 -1
  728. package/lib/documents/self-save-registry.js.map +0 -1
  729. package/lib/lsp/instrument-connection.d.ts +0 -36
  730. package/lib/lsp/instrument-connection.d.ts.map +0 -1
  731. package/lib/lsp/instrument-connection.js +0 -62
  732. package/lib/lsp/instrument-connection.js.map +0 -1
  733. package/lib/node/process-memory.d.ts +0 -66
  734. package/lib/node/process-memory.d.ts.map +0 -1
  735. package/lib/node/process-memory.js +0 -252
  736. package/lib/node/process-memory.js.map +0 -1
  737. package/src/documents/language-client-text-shadow.ts +0 -175
  738. package/src/documents/self-save-registry.ts +0 -81
  739. package/src/lsp/instrument-connection.ts +0 -66
  740. package/src/node/process-memory.ts +0 -299
@@ -51,16 +51,17 @@ export function findRealpathDivergence(uri: URI | string, fs: RealpathCapableFil
51
51
  * - {@link canonicalUri} — TOTAL: maps any URI to the single canonical *string*
52
52
  * the framework keys a document by, regardless of whether the file exists.
53
53
  * This is the form that MUST match the adopter's `LangiumDocuments` keying so
54
- * the text store, AST-document event filters
55
- * (`AstDocumentManager.onUpdate` / `onSave` / `onClientClosed`), and
54
+ * the text store, `ModelService`'s event filters, and
56
55
  * `LangiumDocuments` lookups all agree on one identity for the same file. Use
57
56
  * for keying, comparison, and the text-store ↔ document-store bridges.
58
57
  *
59
58
  * - {@link loadUri} — EXISTENCE-AWARE: maps a URI to the *load* URI, or
60
59
  * `undefined` when there is no loadable on-disk content for it. Use where the
61
60
  * next step actually touches the filesystem (loading a document, walking a
62
- * directory): `undefined` means "skip / treat as empty" rather than attempt a
63
- * doomed read. The default treats every URI as loadable (returns it
61
+ * directory): `undefined` means "skip the read" rather than attempt a doomed
62
+ * one. It does not mean there is no document: one created and not yet saved
63
+ * has no file, and the text store and `LangiumDocuments` hold it under
64
+ * {@link canonicalUri}. The default treats every URI as loadable (returns it
64
65
  * unchanged); a real-path policy returns the resolved file URI, or `undefined`
65
66
  * for a not-yet-written path.
66
67
  *
@@ -84,7 +85,9 @@ export interface DocumentUriPolicy {
84
85
  /**
85
86
  * Existence-aware resolution to the load URI, or `undefined` when there is
86
87
  * no loadable content for `uri` (missing / synthetic). Callers that read the
87
- * filesystem next use `undefined` to skip rather than attempt a doomed read.
88
+ * filesystem next use `undefined` to skip rather than attempt a doomed read,
89
+ * and still look the URI up under {@link canonicalUri}: a document created
90
+ * and not yet saved is held there with no file behind it.
88
91
  */
89
92
  loadUri(uri: URI | string): URI | undefined;
90
93
  }
@@ -152,11 +155,13 @@ export class DefaultDocumentUriPolicy implements DocumentUriPolicy {
152
155
  * `loadUri` returns `undefined` for an absent path (honest about existence, so a
153
156
  * caller about to read the filesystem skips it).
154
157
  *
155
- * If the bound provider has no `realpath` (in-memory / browser / empty),
156
- * both methods degrade to {@link DefaultDocumentUriPolicy} automatically — the
157
- * `loadUri` ternary tests the *method's presence*, not its return, so the
158
- * existence signal is preserved: `loadUri` returns `undefined` only when
159
- * `realpath` is present and reports the path absent.
158
+ * If the provider for a URI's scheme has no `realpath` (in-memory / browser /
159
+ * empty), the framework's `FileSystemProviderRegistry` returns the URI
160
+ * unchanged and both methods answer as {@link DefaultDocumentUriPolicy} does. A
161
+ * slot bound to a provider without `realpath` degrades the same way: the
162
+ * `loadUri` ternary tests the *method's presence*, not its return, so
163
+ * `loadUri` returns `undefined` only when `realpath` is present and reports the
164
+ * path absent.
160
165
  */
161
166
  export class RealpathDocumentUriPolicy extends DefaultDocumentUriPolicy {
162
167
  protected readonly fs: RealpathCapableFileSystem;
@@ -0,0 +1,35 @@
1
+ /********************************************************************************
2
+ * Copyright (c) 2026 CrossBreeze, EclipseSource and others.
3
+ *
4
+ * This program and the accompanying materials are made available under the
5
+ * terms of the MIT License which is available in the project root.
6
+ *
7
+ * SPDX-License-Identifier: MIT
8
+ ********************************************************************************/
9
+
10
+ import { type URI } from '@hydranium/langium';
11
+
12
+ // Not re-exported from the workspace barrel: the framework's providers and
13
+ // the release handler share it, and it is no API of theirs.
14
+
15
+ /**
16
+ * A missing-file error shaped as a Node file system raises it, with code
17
+ * `ENOENT` and the path: callers tell a missing file from any other failure by
18
+ * those two fields, whichever provider is bound. The release relies on it to
19
+ * tell a document gone meanwhile from any other failed rebuild.
20
+ */
21
+ export function notFound(message: string, uri: URI): Error {
22
+ return Object.assign(new Error(message), { code: 'ENOENT', path: uri.fsPath });
23
+ }
24
+
25
+ /**
26
+ * Whether `err` reports that the file of `target` does not exist, as a Node
27
+ * file system and {@link notFound} do: code `ENOENT`, with `target`'s path. A
28
+ * missing file of another document is a different failure.
29
+ */
30
+ export function isFileNotFound(err: unknown, target: URI): boolean {
31
+ if (typeof err !== 'object' || err === null || !('code' in err) || err.code !== 'ENOENT') {
32
+ return false;
33
+ }
34
+ return !('path' in err) || err.path === target.fsPath;
35
+ }
@@ -9,17 +9,85 @@
9
9
 
10
10
  import { type Tracer } from '@hydranium/protocol';
11
11
  import { EmptyFileSystemProvider } from '@hydranium/langium';
12
- import type { URI } from '@hydranium/langium';
13
- import { type WritableFileSystemProvider } from '../../documents/ast-document-manager.js';
12
+ import type { FileSystemNode, FileSystemProvider, URI } from '@hydranium/langium';
13
+ import { type SelfSaveRegistry } from './self-save-registry.js';
14
14
  import { type LogNameOptions } from '../diagnostics/logger.js';
15
15
  import { type ServerSharedServicesMinimal } from '../shared-services.js';
16
- import { serveVirtualDocument } from './virtual-document.js';
17
16
 
18
17
  /**
19
- * Empty-filesystem default {@link WritableFileSystemProvider}. For
20
- * in-memory / browser / test / CLI hosts that don't have a real filesystem.
21
- * All writes are no-ops. This is the portable `.`-entry default; the
22
- * Node-backed `DefaultFileSystemProvider`
18
+ * File-system provider extension that supports writes. Langium's standard
19
+ * {@link FileSystemProvider} is read-only; `AstDocumentManager` needs to persist
20
+ * saves, so consumers wire in a provider that implements this superset.
21
+ *
22
+ * Implementations may optionally hold a reference to a
23
+ * {@link SelfSaveRegistry} so they can record their own write mtimes and
24
+ * help downstream file-watchers suppress echo events for those writes.
25
+ * The framework's `DefaultFileSystemProvider` reads it from
26
+ * `services.workspace.SelfSaveRegistry`; alternative implementations can do
27
+ * the same or leave the field unset.
28
+ */
29
+ export interface WritableFileSystemProvider extends FileSystemProvider {
30
+ writeFile(uri: URI, content: string): Promise<void>;
31
+ /**
32
+ * Remove the file at `uri`: the name the URI gives, never the file a
33
+ * symlink there points at, leaving a parent directory it empties in place.
34
+ * A no-op when nothing is there; a directory is refused.
35
+ */
36
+ deleteFile(uri: URI): Promise<void>;
37
+ /**
38
+ * Last-modified time (ms) of the file at `uri`, or `undefined` if it can't
39
+ * be determined (missing file, or a provider with no disk — in-memory /
40
+ * browser). Optional: the only consumer is self-save echo suppression
41
+ * (`didChangeWatchedFiles`), which simply lets a change through when the
42
+ * mtime is unavailable. Distinct from Langium's `stat` (whose
43
+ * `FileSystemNode` carries no mtime). Keeping disk access on the provider
44
+ * seam is what lets the LSP update handler avoid a direct `node:fs` import.
45
+ */
46
+ mtimeMs?(uri: URI): Promise<number | undefined>;
47
+ /**
48
+ * Resolve `uri` to its real on-disk identity (symlinks collapsed, `..`/`.`
49
+ * walked, case-folded on case-insensitive filesystems), or `undefined` *iff
50
+ * the filesystem knows the path is absent*. The single source of the
51
+ * "nothing loadable here" signal `RealpathDocumentUriPolicy` turns into
52
+ * the synthetic-placeholder branch of `getOrCreateDocument`.
53
+ *
54
+ * Contract for implementers:
55
+ * - A `file:`-backed provider returns the resolved URI when the file exists,
56
+ * and `undefined` when it cannot resolve the path (missing / unreadable).
57
+ * - A non-`file:` URI (or any URI the provider cannot stat) passes through
58
+ * **unchanged** — it is treated as present, never reported absent.
59
+ * - A provider with no disk to check (in-memory / browser / empty) simply
60
+ * omits this method; the framework's `FileSystemProviderRegistry` then
61
+ * returns the URI unchanged, and `RealpathDocumentUriPolicy` answers as
62
+ * the syntactic `DefaultDocumentUriPolicy` does.
63
+ *
64
+ * Synchronous (a `realpath` is a kernel-cached syscall) and optional — the
65
+ * only consumers are the document-identity policy's `canonicalUri`/`loadUri`.
66
+ * Keeping the syscall on the provider seam is what lets the policy stay
67
+ * browser-neutral (no `node:fs` import).
68
+ */
69
+ realpath?(uri: URI): URI | undefined;
70
+ /**
71
+ * Whether a file is at `uri`, where a miss counts only once it has lasted:
72
+ * on a disk where replacing a file can hide its name for a moment, a single
73
+ * {@link exists} cannot tell that from a deletion. Ask this before acting on
74
+ * a miss as a deletion; a caller expecting a miss, such as a create, asks
75
+ * {@link exists}, since here a real miss costs the whole wait.
76
+ *
77
+ * Optional: a provider whose misses are always final omits it, and a caller
78
+ * takes the answer of {@link exists} as settled.
79
+ */
80
+ existsSettled?(uri: URI): Promise<boolean>;
81
+ /** Registry the provider records its own writes against. Optional — providers without watcher integration may omit. */
82
+ readonly selfSaveRegistry?: SelfSaveRegistry;
83
+ }
84
+
85
+ /**
86
+ * Empty-filesystem {@link WritableFileSystemProvider}. For browser / test / CLI
87
+ * hosts that don't have a real filesystem. All writes and deletes are no-ops.
88
+ * On the portable `.` entry it is the
89
+ * {@link FileSystemProviderRegistry.host} when `context.fileSystemProvider`
90
+ * gives no writable provider; the Node-backed `DefaultFileSystemProvider`
23
91
  * lives in `@hydranium/core/node` (it pulls `node:fs`).
24
92
  */
25
93
  export class DefaultEmptyFileSystemProvider extends EmptyFileSystemProvider implements WritableFileSystemProvider {
@@ -37,16 +105,166 @@ export class DefaultEmptyFileSystemProvider extends EmptyFileSystemProvider impl
37
105
  // no-op
38
106
  }
39
107
 
40
- // Serve virtual documents from the registered document (there is no disk to
41
- // read); delegate everything else to the empty base (which throws). The
42
- // base declares these param-less, so the param is optional here.
43
- override readFile(uri?: URI): Promise<string> {
44
- const served = uri !== undefined ? serveVirtualDocument(this.services, uri) : undefined;
45
- return served !== undefined ? Promise.resolve(served) : super.readFile();
108
+ async deleteFile(_uri: URI): Promise<void> {
109
+ // no-op
110
+ }
111
+
112
+ // `async` so the base's refusal becomes a rejection: it throws
113
+ // SYNCHRONOUSLY from a method declared to return a promise, and a
114
+ // synchronous throw escapes the promise chain — `.catch()` never attaches
115
+ // and `Promise.all` dies while its argument array is still being built, so
116
+ // a caller reading several URIs cannot handle the miss it asked about. The
117
+ // base declares `readFile` and `readBinary` param-less, so the param is
118
+ // optional there.
119
+ override async readFile(_uri?: URI): Promise<string> {
120
+ return super.readFile();
121
+ }
122
+
123
+ override async readBinary(_uri?: URI): Promise<Uint8Array> {
124
+ return super.readBinary();
125
+ }
126
+
127
+ override async stat(uri: URI): Promise<FileSystemNode> {
128
+ return super.stat(uri);
129
+ }
130
+ }
131
+
132
+ /**
133
+ * The provider bound on `workspace.FileSystemProvider`: it dispatches each call
134
+ * by the URI's scheme to the provider registered for it in the shared
135
+ * `fileSystemProviders` group, and to the {@link host} for any scheme without
136
+ * one.
137
+ *
138
+ * So one provider answers for each scheme, and a host's provider needs to know
139
+ * only its own: the framework registers `virtual:` there, and an adopter adds a
140
+ * scheme by contributing to the group. The host takes every unclaimed scheme
141
+ * rather than `file:` alone, which keeps an in-memory workspace under `memory:`
142
+ * or any other scheme on the host's provider.
143
+ *
144
+ * `THost` types the host, so an adopter whose own provider has more members
145
+ * than the base declares the slot as `FileSystemProviderRegistry<MyProvider>`,
146
+ * binds a {@link DefaultFileSystemProviderRegistry} with that host, and reads
147
+ * those members through `services.workspace.FileSystemProvider.host`.
148
+ */
149
+ export interface FileSystemProviderRegistry<
150
+ THost extends WritableFileSystemProvider = WritableFileSystemProvider
151
+ > extends WritableFileSystemProvider {
152
+ /** The provider for every scheme no entry of `fileSystemProviders` claims. */
153
+ readonly host: THost;
154
+ /** The provider that answers for `uri`. */
155
+ providerFor(uri: URI): WritableFileSystemProvider;
156
+ }
157
+
158
+ /** Options for {@link DefaultFileSystemProviderRegistry}. */
159
+ export interface FileSystemProviderRegistryOptions<
160
+ THost extends WritableFileSystemProvider = WritableFileSystemProvider
161
+ > extends LogNameOptions {
162
+ /**
163
+ * The provider for every scheme no entry of `fileSystemProviders` claims.
164
+ * The framework passes the provider `context.fileSystemProvider` returns,
165
+ * or a {@link DefaultEmptyFileSystemProvider} when that is not writable.
166
+ */
167
+ host: THost;
168
+ }
169
+
170
+ /**
171
+ * The framework's {@link FileSystemProviderRegistry}.
172
+ *
173
+ * A directory is listed by the provider of its own scheme, so a workspace
174
+ * root's tree comes from that provider alone.
175
+ *
176
+ * `realpath`, `mtimeMs` and `existsSettled` are always present and forward to
177
+ * the scheme's provider. Where that provider lacks one, `realpath` returns the
178
+ * URI unchanged, `mtimeMs` returns `undefined` and `existsSettled` answers as
179
+ * `exists`: the answers their callers already give a provider without them.
180
+ */
181
+ export class DefaultFileSystemProviderRegistry<
182
+ THost extends WritableFileSystemProvider = WritableFileSystemProvider
183
+ > implements FileSystemProviderRegistry<THost> {
184
+ readonly host: THost;
185
+ protected readonly tracer: Tracer;
186
+
187
+ constructor(
188
+ protected readonly services: ServerSharedServicesMinimal & { fileSystemProviders: Record<string, WritableFileSystemProvider> },
189
+ options: FileSystemProviderRegistryOptions<THost>
190
+ ) {
191
+ this.host = options.host;
192
+ this.tracer = services.Tracer.for(options.logName ?? this.constructor.name).trace('instantiated');
193
+ }
194
+
195
+ /**
196
+ * The group is read per call, not in the constructor, so a registered
197
+ * provider is built on first use and may read slots that reach back to this
198
+ * one. Only an OWN key of the group counts: the DI container resolves any
199
+ * key found on the prototype chain, so a scheme such as `constructor` would
200
+ * otherwise dispatch to a function.
201
+ */
202
+ providerFor(uri: URI): WritableFileSystemProvider {
203
+ const providers = this.services.fileSystemProviders;
204
+ return Object.hasOwn(providers, uri.scheme) ? providers[uri.scheme] : this.host;
205
+ }
206
+
207
+ // The async methods are `async` so a provider that throws synchronously from
208
+ // one still rejects, for the reason `DefaultEmptyFileSystemProvider` gives.
209
+ async writeFile(uri: URI, content: string): Promise<void> {
210
+ return this.providerFor(uri).writeFile(uri, content);
211
+ }
212
+
213
+ async deleteFile(uri: URI): Promise<void> {
214
+ return this.providerFor(uri).deleteFile(uri);
215
+ }
216
+
217
+ async mtimeMs(uri: URI): Promise<number | undefined> {
218
+ return this.providerFor(uri).mtimeMs?.(uri);
219
+ }
220
+
221
+ realpath(uri: URI): URI | undefined {
222
+ const provider = this.providerFor(uri);
223
+ return provider.realpath ? provider.realpath(uri) : uri;
224
+ }
225
+
226
+ async existsSettled(uri: URI): Promise<boolean> {
227
+ const provider = this.providerFor(uri);
228
+ return provider.existsSettled ? provider.existsSettled(uri) : provider.exists(uri);
229
+ }
230
+
231
+ async stat(uri: URI): Promise<FileSystemNode> {
232
+ return this.providerFor(uri).stat(uri);
233
+ }
234
+
235
+ statSync(uri: URI): FileSystemNode {
236
+ return this.providerFor(uri).statSync(uri);
237
+ }
238
+
239
+ async exists(uri: URI): Promise<boolean> {
240
+ return this.providerFor(uri).exists(uri);
241
+ }
242
+
243
+ existsSync(uri: URI): boolean {
244
+ return this.providerFor(uri).existsSync(uri);
245
+ }
246
+
247
+ async readBinary(uri: URI): Promise<Uint8Array> {
248
+ return this.providerFor(uri).readBinary(uri);
249
+ }
250
+
251
+ readBinarySync(uri: URI): Uint8Array {
252
+ return this.providerFor(uri).readBinarySync(uri);
253
+ }
254
+
255
+ async readFile(uri: URI): Promise<string> {
256
+ return this.providerFor(uri).readFile(uri);
257
+ }
258
+
259
+ readFileSync(uri: URI): string {
260
+ return this.providerFor(uri).readFileSync(uri);
261
+ }
262
+
263
+ async readDirectory(uri: URI): Promise<FileSystemNode[]> {
264
+ return this.providerFor(uri).readDirectory(uri);
46
265
  }
47
266
 
48
- override readFileSync(uri?: URI): string {
49
- const served = uri !== undefined ? serveVirtualDocument(this.services, uri) : undefined;
50
- return served !== undefined ? served : super.readFileSync();
267
+ readDirectorySync(uri: URI): FileSystemNode[] {
268
+ return this.providerFor(uri).readDirectorySync(uri);
51
269
  }
52
270
  }
@@ -12,9 +12,17 @@ import {
12
12
  AstUtils,
13
13
  DefaultLangiumDocumentFactory,
14
14
  type LangiumDocument,
15
+ type Mutable,
15
16
  type ParseResult,
16
17
  type URI
17
18
  } from '@hydranium/langium';
19
+ import { type CancellationToken } from 'vscode-languageserver-protocol';
20
+ import { type TextDocument } from 'vscode-languageserver-textdocument';
21
+ import { STALE_VERSION } from '@hydranium/protocol';
22
+ import { type ModelLedger } from '../../documents/model-ledger.js';
23
+ import { type VersionSyncService } from '../../documents/version-sync-service.js';
24
+ import { type ExtendedServiceRegistry } from '../service-registry.js';
25
+ import { type ServerSharedServicesMinimal } from '../shared-services.js';
18
26
  import { type Serializer } from '../serialization/serializer.js';
19
27
 
20
28
  /** Structural view of the per-language serializer slot on the resolved services. */
@@ -49,6 +57,49 @@ interface WithSerializer {
49
57
  * node identity is preserved.
50
58
  */
51
59
  export class HydraniumLangiumDocumentFactory extends DefaultLangiumDocumentFactory {
60
+ /**
61
+ * Narrows the inherited Langium `ServiceRegistry` field to the framework's
62
+ * {@link ExtendedServiceRegistry}, so the by-id lookup below needs no
63
+ * per-callsite cast. The framework's shared module binds that class.
64
+ */
65
+ declare protected readonly serviceRegistry: ExtendedServiceRegistry;
66
+
67
+ /** Resolved per call: the sync service reaches the registry, which is built with this factory. */
68
+ protected readonly versionSyncService: () => VersionSyncService;
69
+ protected readonly modelLedger: () => ModelLedger;
70
+
71
+ constructor(services: ServerSharedServicesMinimal) {
72
+ super(services);
73
+ this.versionSyncService = () => services.workspace.VersionSyncService;
74
+ this.modelLedger = () => services.workspace.ModelLedger;
75
+ }
76
+
77
+ /**
78
+ * Parse `text` for `uri` under the grammar `languageId` names, instead of
79
+ * the one `uri` routes to.
80
+ *
81
+ * For a URI that routes to no grammar at all: a directory, or any other URI
82
+ * that names no file and so carries no extension. Langium's ladder ends at
83
+ * the extension, so it reports `no services for the extension ''` from
84
+ * inside the parse — naming neither the URI nor the caller that could have
85
+ * said which grammar it meant.
86
+ *
87
+ * The caller supplies the language because nothing else can. A URI with no
88
+ * extension carries no routing signal, and choosing on its behalf would be a
89
+ * guess the moment a second grammar is registered — which is why this takes
90
+ * the id rather than falling back to a sole registered language.
91
+ *
92
+ * @throws when `languageId` names no registered grammar.
93
+ */
94
+ fromStringInLanguage<T extends AstNode = AstNode>(text: string, uri: URI, languageId: string): LangiumDocument<T> {
95
+ const services = this.serviceRegistry.getServicesById(languageId);
96
+ if (!services) {
97
+ throw new Error(`No grammar is registered for the language id '${languageId}' (parsing ${uri.toString()}).`);
98
+ }
99
+ const parseResult: ParseResult<T> = services.parser.LangiumParser.parse<T>(text);
100
+ return this.createLangiumDocument<T>(parseResult, uri, undefined, text);
101
+ }
102
+
52
103
  override fromModel<T extends AstNode = AstNode>(model: T, uri: URI): LangiumDocument<T> {
53
104
  // Make the code-built AST as structurally complete as a parsed one — the
54
105
  // parser links containers, `fromModel` does not. In place (identity kept).
@@ -61,6 +112,72 @@ export class HydraniumLangiumDocumentFactory extends DefaultLangiumDocumentFacto
61
112
  return this.createLangiumDocument<T>(parseResult, uri, undefined, text);
62
113
  }
63
114
 
115
+ protected override createLangiumDocument<T extends AstNode = AstNode>(
116
+ parseResult: ParseResult<T>,
117
+ uri: URI,
118
+ textDocument?: TextDocument,
119
+ text?: string
120
+ ): LangiumDocument<T> {
121
+ const document = super.createLangiumDocument(parseResult, uri, textDocument, text);
122
+ // Without `textDocument` Langium creates one at version 0 on first read,
123
+ // which needs a language for `uri` that a folder URI does not have.
124
+ const parsed = parseResult.value.$cstNode?.root.fullText ?? text ?? textDocument?.getText();
125
+ this.versionSyncService().modelProduced(document, { version: this.versionOfParsedText(uri, parsed, textDocument?.version ?? 0) });
126
+ return document;
127
+ }
128
+
129
+ /**
130
+ * The version is read before the parse, for the same reason as in
131
+ * {@link update}: the text document is the store's, which an edit updates
132
+ * in place while the parse runs.
133
+ */
134
+ protected override async createAsync<T extends AstNode = AstNode>(
135
+ uri: URI,
136
+ content: string | TextDocument,
137
+ cancelToken: CancellationToken
138
+ ): Promise<LangiumDocument<T>> {
139
+ const version = typeof content === 'string' ? undefined : content.version;
140
+ const document = await super.createAsync<T>(uri, content, cancelToken);
141
+ if (version !== undefined) {
142
+ this.versionSyncService().modelProduced(document, { version });
143
+ }
144
+ return document;
145
+ }
146
+
147
+ /**
148
+ * The store's version is read before Langium's `update`, which reads the
149
+ * store's text before its first await: read after, it can belong to an
150
+ * edit that arrived while the parse ran.
151
+ *
152
+ * Reconciled with the store here rather than in a `Parsed` listener, which
153
+ * a cancel skips, leaving the root on the version of its earlier text.
154
+ */
155
+ override async update<T extends AstNode = AstNode>(
156
+ document: Mutable<LangiumDocument<T>>,
157
+ cancellationToken: CancellationToken
158
+ ): Promise<LangiumDocument<T>> {
159
+ const stored = this.textDocuments?.get(document.uri.toString())?.version;
160
+ const updated = await super.update(document, cancellationToken);
161
+ const version =
162
+ stored ??
163
+ this.versionOfParsedText(
164
+ updated.uri,
165
+ this.modelLedger().textOf(updated.parseResult.value) ?? updated.textDocument.getText(),
166
+ updated.textDocument.version
167
+ );
168
+ this.versionSyncService().modelProduced(updated, { version });
169
+ return updated;
170
+ }
171
+
172
+ /**
173
+ * `version`, or {@link STALE_VERSION} when the store holds `uri` open with
174
+ * other text than `parsed`: text read from the file while an open landed.
175
+ */
176
+ protected versionOfParsedText(uri: URI, parsed: string | undefined, version: number): number {
177
+ const open = this.textDocuments?.get(uri.toString());
178
+ return open !== undefined && parsed !== undefined && open.getText() !== parsed ? STALE_VERSION : version;
179
+ }
180
+
64
181
  /**
65
182
  * Serialize `model` via the per-language serializer, or `undefined` if none
66
183
  * is bound, it fails, or it is async — `fromModel` is synchronous, so an
@@ -7,10 +7,31 @@
7
7
  * SPDX-License-Identifier: MIT
8
8
  ********************************************************************************/
9
9
 
10
+ import { type Clock, type Tracer } from '@hydranium/protocol';
10
11
  import { DefaultWorkspaceLock, type MaybePromise } from '@hydranium/langium';
11
- import { type CancellationToken } from 'vscode-languageserver-protocol';
12
+ import { type CancellationToken, type Disposable } from 'vscode-languageserver-protocol';
13
+ import { type LogNameOptions } from '../diagnostics/logger.js';
14
+ import { type ServerSharedServicesMinimal } from '../shared-services.js';
12
15
  import { runInWriteLockScope } from './write-lock-scope.js';
13
16
 
17
+ /** Constructor options for {@link HydraniumWorkspaceLock}. */
18
+ export interface HydraniumWorkspaceLockOptions extends LogNameOptions {
19
+ /**
20
+ * How long a write may keep running after a later write cancelled it before
21
+ * the lock logs a warning. Every write and read waits behind it meanwhile, so
22
+ * one that never ends stops the server. Defaults to 10 s; `0` turns the
23
+ * check off.
24
+ */
25
+ readonly stalledWriteWarnMs?: number;
26
+ }
27
+
28
+ const DEFAULT_STALLED_WRITE_WARN_MS = 10_000;
29
+
30
+ /** The write action a {@link HydraniumWorkspaceLock} is running, with the timer its cancellation started. */
31
+ export interface RunningWrite {
32
+ stallTimer?: Disposable;
33
+ }
34
+
14
35
  /**
15
36
  * Langium's {@link DefaultWorkspaceLock} with the write action marked as a
16
37
  * write-lock scope, so anything it reaches can be asked whether the lock is
@@ -29,7 +50,70 @@ import { runInWriteLockScope } from './write-lock-scope.js';
29
50
  * would turn ordinary read-then-write sequences into false positives.
30
51
  */
31
52
  export class HydraniumWorkspaceLock extends DefaultWorkspaceLock {
53
+ /** Backs {@link writeCancellations}. */
54
+ protected cancelledWriteCount = 0;
55
+ protected readonly clock: Clock;
56
+ protected readonly tracer: Tracer;
57
+ protected readonly stalledWriteWarnMs: number;
58
+ protected runningWrite?: RunningWrite;
59
+
60
+ constructor(services: Pick<ServerSharedServicesMinimal, 'Clock' | 'Tracer'>, options: HydraniumWorkspaceLockOptions = {}) {
61
+ super();
62
+ this.clock = services.Clock;
63
+ this.tracer = services.Tracer.for(options.logName ?? 'WorkspaceLock');
64
+ this.stalledWriteWarnMs = options.stalledWriteWarnMs ?? DEFAULT_STALLED_WRITE_WARN_MS;
65
+ }
66
+
67
+ /**
68
+ * How many calls have cancelled the lock's latest write: every `write`,
69
+ * which cancels the write before it, and every `cancelWrite`. A caller that
70
+ * reads this right after queuing a write, and reads the same number later,
71
+ * holds a write nothing has cancelled, whether it is still queued or
72
+ * already running. Its token answers that only once the write runs, since
73
+ * a queued write has not been handed it yet.
74
+ */
75
+ get writeCancellations(): number {
76
+ return this.cancelledWriteCount;
77
+ }
78
+
32
79
  override write(action: (token: CancellationToken) => MaybePromise<void>): Promise<void> {
33
- return super.write(token => runInWriteLockScope(() => action(token)));
80
+ return super.write(token => runInWriteLockScope(() => this.runWrite(action, token)));
81
+ }
82
+
83
+ /** Run `action` as {@link runningWrite}, so a cancellation while it runs can time it. */
84
+ protected async runWrite(action: (token: CancellationToken) => MaybePromise<void>, token: CancellationToken): Promise<void> {
85
+ const running: RunningWrite = {};
86
+ this.runningWrite = running;
87
+ try {
88
+ await action(token);
89
+ } finally {
90
+ running.stallTimer?.dispose();
91
+ if (this.runningWrite === running) {
92
+ this.runningWrite = undefined;
93
+ }
94
+ }
95
+ }
96
+
97
+ /**
98
+ * Counted here rather than in {@link write}, because Langium's `write` cancels
99
+ * through this method too. A write running when this is called has been
100
+ * cancelled, by this call or an earlier one, so its timer starts here.
101
+ */
102
+ override cancelWrite(): void {
103
+ this.cancelledWriteCount++;
104
+ const running = this.runningWrite;
105
+ if (running && !running.stallTimer && this.stalledWriteWarnMs > 0) {
106
+ running.stallTimer = this.clock.setTimer(() => this.reportStalledWrite(), this.stalledWriteWarnMs);
107
+ }
108
+ super.cancelWrite();
109
+ }
110
+
111
+ protected reportStalledWrite(): void {
112
+ this.tracer.warn(
113
+ `A write is still running ${this.stalledWriteWarnMs} ms after it was cancelled, and every write and read waits behind it. ` +
114
+ 'Likely causes: a model-service write or rebuild from inside a build in a host with no write-lock scope tracker, ' +
115
+ 'which waits for the build it runs in, or a write action that ignores its cancellation token. ' +
116
+ 'See https://github.com/eclipse-emfcloud/hydranium/issues/245.'
117
+ );
34
118
  }
35
119
  }