@hydranium/core 1.0.0-next.24 → 1.0.0-next.242

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 (649) hide show
  1. package/README.md +23 -18
  2. package/lib/documents/ast-document-manager.d.ts +219 -122
  3. package/lib/documents/ast-document-manager.d.ts.map +1 -1
  4. package/lib/documents/ast-document-manager.js +241 -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 +79 -0
  19. package/lib/documents/dirty-state-tracker.d.ts.map +1 -0
  20. package/lib/documents/dirty-state-tracker.js +69 -0
  21. package/lib/documents/dirty-state-tracker.js.map +1 -0
  22. package/lib/documents/document-release-handler.d.ts +179 -0
  23. package/lib/documents/document-release-handler.d.ts.map +1 -0
  24. package/lib/documents/document-release-handler.js +283 -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 +399 -282
  35. package/lib/documents/hydranium-text-documents.d.ts.map +1 -1
  36. package/lib/documents/hydranium-text-documents.js +816 -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 +283 -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 +134 -0
  55. package/lib/documents/version-sync-service.d.ts.map +1 -0
  56. package/lib/documents/version-sync-service.js +171 -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.map +1 -1
  63. package/lib/langium/ast-extension/ast-extension-service.js.map +1 -1
  64. package/lib/langium/ast-extension/ast-node-builder.d.ts +32 -9
  65. package/lib/langium/ast-extension/ast-node-builder.d.ts.map +1 -1
  66. package/lib/langium/ast-extension/ast-node-builder.js +60 -22
  67. package/lib/langium/ast-extension/ast-node-builder.js.map +1 -1
  68. package/lib/langium/bootstrap.d.ts +23 -16
  69. package/lib/langium/bootstrap.d.ts.map +1 -1
  70. package/lib/langium/bootstrap.js +66 -28
  71. package/lib/langium/bootstrap.js.map +1 -1
  72. package/lib/langium/build-phase-pass/build-phase-pass-service.d.ts.map +1 -1
  73. package/lib/langium/build-phase-pass/build-phase-pass-service.js.map +1 -1
  74. package/lib/langium/composite-ast-reflection.d.ts +46 -0
  75. package/lib/langium/composite-ast-reflection.d.ts.map +1 -0
  76. package/lib/langium/composite-ast-reflection.js +97 -0
  77. package/lib/langium/composite-ast-reflection.js.map +1 -0
  78. package/lib/langium/config/configuration-provider.d.ts +81 -0
  79. package/lib/langium/config/configuration-provider.d.ts.map +1 -0
  80. package/lib/langium/config/configuration-provider.js +112 -0
  81. package/lib/langium/config/configuration-provider.js.map +1 -0
  82. package/lib/langium/config/index.d.ts +1 -0
  83. package/lib/langium/config/index.d.ts.map +1 -1
  84. package/lib/langium/config/index.js +1 -0
  85. package/lib/langium/config/index.js.map +1 -1
  86. package/lib/langium/config/settings.js.map +1 -1
  87. package/lib/langium/diagnostics/hydranium-langium-profiler.d.ts.map +1 -1
  88. package/lib/langium/diagnostics/hydranium-langium-profiler.js.map +1 -1
  89. package/lib/langium/diagnostics/logger.d.ts +10 -3
  90. package/lib/langium/diagnostics/logger.d.ts.map +1 -1
  91. package/lib/langium/diagnostics/logger.js +12 -5
  92. package/lib/langium/diagnostics/logger.js.map +1 -1
  93. package/lib/langium/diagnostics/lsp-logger.d.ts +17 -0
  94. package/lib/langium/diagnostics/lsp-logger.d.ts.map +1 -1
  95. package/lib/langium/diagnostics/lsp-logger.js +57 -16
  96. package/lib/langium/diagnostics/lsp-logger.js.map +1 -1
  97. package/lib/langium/diagnostics/server-tracer.d.ts.map +1 -1
  98. package/lib/langium/diagnostics/server-tracer.js.map +1 -1
  99. package/lib/langium/document-builder/build-pipeline-integration.d.ts +21 -1
  100. package/lib/langium/document-builder/build-pipeline-integration.d.ts.map +1 -1
  101. package/lib/langium/document-builder/build-pipeline-integration.js +32 -5
  102. package/lib/langium/document-builder/build-pipeline-integration.js.map +1 -1
  103. package/lib/langium/document-builder/build-session.d.ts.map +1 -1
  104. package/lib/langium/document-builder/build-session.js.map +1 -1
  105. package/lib/langium/document-builder/document-builder.d.ts +294 -33
  106. package/lib/langium/document-builder/document-builder.d.ts.map +1 -1
  107. package/lib/langium/document-builder/document-builder.js +477 -61
  108. package/lib/langium/document-builder/document-builder.js.map +1 -1
  109. package/lib/langium/documentation/comment-provider.d.ts.map +1 -1
  110. package/lib/langium/documentation/comment-provider.js.map +1 -1
  111. package/lib/langium/integration-services.d.ts +61 -19
  112. package/lib/langium/integration-services.d.ts.map +1 -1
  113. package/lib/langium/integration-services.js +10 -5
  114. package/lib/langium/integration-services.js.map +1 -1
  115. package/lib/langium/integrity/integrity-rule.d.ts +16 -8
  116. package/lib/langium/integrity/integrity-rule.d.ts.map +1 -1
  117. package/lib/langium/integrity/integrity-rule.js.map +1 -1
  118. package/lib/langium/integrity/integrity-service.d.ts +81 -24
  119. package/lib/langium/integrity/integrity-service.d.ts.map +1 -1
  120. package/lib/langium/integrity/integrity-service.js +264 -57
  121. package/lib/langium/integrity/integrity-service.js.map +1 -1
  122. package/lib/langium/keys/containment.d.ts +64 -0
  123. package/lib/langium/keys/containment.d.ts.map +1 -0
  124. package/lib/langium/keys/containment.js +53 -0
  125. package/lib/langium/keys/containment.js.map +1 -0
  126. package/lib/langium/keys/index.d.ts +1 -0
  127. package/lib/langium/keys/index.d.ts.map +1 -1
  128. package/lib/langium/keys/index.js +1 -0
  129. package/lib/langium/keys/index.js.map +1 -1
  130. package/lib/langium/keys/name-based-key-provider.d.ts +4 -0
  131. package/lib/langium/keys/name-based-key-provider.d.ts.map +1 -1
  132. package/lib/langium/keys/name-based-key-provider.js +4 -0
  133. package/lib/langium/keys/name-based-key-provider.js.map +1 -1
  134. package/lib/langium/keys/positional-key-provider.d.ts.map +1 -1
  135. package/lib/langium/keys/positional-key-provider.js.map +1 -1
  136. package/lib/langium/labeling/label-provider.d.ts.map +1 -1
  137. package/lib/langium/labeling/label-provider.js.map +1 -1
  138. package/lib/langium/language-module.d.ts +29 -4
  139. package/lib/langium/language-module.d.ts.map +1 -1
  140. package/lib/langium/language-module.js +18 -4
  141. package/lib/langium/language-module.js.map +1 -1
  142. package/lib/langium/model-service/client-session.d.ts +343 -0
  143. package/lib/langium/model-service/client-session.d.ts.map +1 -0
  144. package/lib/langium/model-service/client-session.js +411 -0
  145. package/lib/langium/model-service/client-session.js.map +1 -0
  146. package/lib/langium/model-service/index.d.ts +2 -0
  147. package/lib/langium/model-service/index.d.ts.map +1 -1
  148. package/lib/langium/model-service/index.js +2 -0
  149. package/lib/langium/model-service/index.js.map +1 -1
  150. package/lib/langium/model-service/model-events.d.ts +61 -0
  151. package/lib/langium/model-service/model-events.d.ts.map +1 -0
  152. package/lib/langium/model-service/model-events.js +10 -0
  153. package/lib/langium/model-service/model-events.js.map +1 -0
  154. package/lib/langium/model-service/model-service.d.ts +432 -282
  155. package/lib/langium/model-service/model-service.d.ts.map +1 -1
  156. package/lib/langium/model-service/model-service.js +504 -438
  157. package/lib/langium/model-service/model-service.js.map +1 -1
  158. package/lib/langium/module.d.ts +150 -35
  159. package/lib/langium/module.d.ts.map +1 -1
  160. package/lib/langium/module.js +47 -35
  161. package/lib/langium/module.js.map +1 -1
  162. package/lib/langium/naming/name-provider.d.ts +25 -4
  163. package/lib/langium/naming/name-provider.d.ts.map +1 -1
  164. package/lib/langium/naming/name-provider.js +2 -1
  165. package/lib/langium/naming/name-provider.js.map +1 -1
  166. package/lib/langium/naming/name-separator-validation.d.ts +23 -0
  167. package/lib/langium/naming/name-separator-validation.d.ts.map +1 -1
  168. package/lib/langium/naming/name-separator-validation.js +30 -1
  169. package/lib/langium/naming/name-separator-validation.js.map +1 -1
  170. package/lib/langium/project/abstract-project-manager.d.ts.map +1 -1
  171. package/lib/langium/project/abstract-project-manager.js +9 -2
  172. package/lib/langium/project/abstract-project-manager.js.map +1 -1
  173. package/lib/langium/project/project-change-event.d.ts +2 -2
  174. package/lib/langium/project/single-project-manager.d.ts.map +1 -1
  175. package/lib/langium/project/single-project-manager.js.map +1 -1
  176. package/lib/langium/residency/cst-residency-service.d.ts +30 -10
  177. package/lib/langium/residency/cst-residency-service.d.ts.map +1 -1
  178. package/lib/langium/residency/cst-residency-service.js +23 -57
  179. package/lib/langium/residency/cst-residency-service.js.map +1 -1
  180. package/lib/langium/scope/ast-node-description-provider.d.ts.map +1 -1
  181. package/lib/langium/scope/ast-node-description-provider.js.map +1 -1
  182. package/lib/langium/scope/hydranium-scope-computation.d.ts.map +1 -1
  183. package/lib/langium/scope/hydranium-scope-computation.js.map +1 -1
  184. package/lib/langium/scope/hydranium-scope-provider.d.ts +48 -13
  185. package/lib/langium/scope/hydranium-scope-provider.d.ts.map +1 -1
  186. package/lib/langium/scope/hydranium-scope-provider.js +56 -20
  187. package/lib/langium/scope/hydranium-scope-provider.js.map +1 -1
  188. package/lib/langium/scope/reference-builder.d.ts.map +1 -1
  189. package/lib/langium/scope/reference-builder.js.map +1 -1
  190. package/lib/langium/scope/reference-candidate-provider.d.ts.map +1 -1
  191. package/lib/langium/scope/reference-candidate-provider.js.map +1 -1
  192. package/lib/langium/scope/scope-extension-service.d.ts.map +1 -1
  193. package/lib/langium/scope/scope-extension-service.js.map +1 -1
  194. package/lib/langium/serialization/abstract-serializer.d.ts +11 -20
  195. package/lib/langium/serialization/abstract-serializer.d.ts.map +1 -1
  196. package/lib/langium/serialization/abstract-serializer.js +12 -21
  197. package/lib/langium/serialization/abstract-serializer.js.map +1 -1
  198. package/lib/langium/serialization/json-serializer.d.ts +1 -1
  199. package/lib/langium/serialization/json-serializer.d.ts.map +1 -1
  200. package/lib/langium/serialization/json-serializer.js.map +1 -1
  201. package/lib/langium/serialization/yaml-serializer.d.ts.map +1 -1
  202. package/lib/langium/serialization/yaml-serializer.js.map +1 -1
  203. package/lib/langium/service-registry.d.ts +29 -1
  204. package/lib/langium/service-registry.d.ts.map +1 -1
  205. package/lib/langium/service-registry.js +37 -0
  206. package/lib/langium/service-registry.js.map +1 -1
  207. package/lib/langium/shared-services.d.ts +21 -6
  208. package/lib/langium/shared-services.d.ts.map +1 -1
  209. package/lib/langium/shared-services.js.map +1 -1
  210. package/lib/langium/single-langium-copy.d.ts +22 -0
  211. package/lib/langium/single-langium-copy.d.ts.map +1 -0
  212. package/lib/langium/single-langium-copy.js +36 -0
  213. package/lib/langium/single-langium-copy.js.map +1 -0
  214. package/lib/langium/transfer/transfer-encoder.d.ts +77 -26
  215. package/lib/langium/transfer/transfer-encoder.d.ts.map +1 -1
  216. package/lib/langium/transfer/transfer-encoder.js +46 -24
  217. package/lib/langium/transfer/transfer-encoder.js.map +1 -1
  218. package/lib/langium/trivia/comment-preserver.d.ts +423 -0
  219. package/lib/langium/trivia/comment-preserver.d.ts.map +1 -0
  220. package/lib/langium/trivia/comment-preserver.js +906 -0
  221. package/lib/langium/trivia/comment-preserver.js.map +1 -0
  222. package/lib/langium/trivia/document-ending-preserver.d.ts +43 -0
  223. package/lib/langium/trivia/document-ending-preserver.d.ts.map +1 -0
  224. package/lib/langium/trivia/document-ending-preserver.js +48 -0
  225. package/lib/langium/trivia/document-ending-preserver.js.map +1 -0
  226. package/lib/langium/trivia/index.d.ts +14 -0
  227. package/lib/langium/trivia/index.d.ts.map +1 -0
  228. package/lib/langium/trivia/index.js +14 -0
  229. package/lib/langium/trivia/index.js.map +1 -0
  230. package/lib/langium/trivia/trivia-contribution.d.ts +37 -0
  231. package/lib/langium/trivia/trivia-contribution.d.ts.map +1 -0
  232. package/lib/langium/trivia/trivia-contribution.js +10 -0
  233. package/lib/langium/trivia/trivia-contribution.js.map +1 -0
  234. package/lib/langium/trivia/trivia-preserver.d.ts +50 -0
  235. package/lib/langium/trivia/trivia-preserver.d.ts.map +1 -0
  236. package/lib/langium/trivia/trivia-preserver.js +10 -0
  237. package/lib/langium/trivia/trivia-preserver.js.map +1 -0
  238. package/lib/langium/trivia/trivia-service.d.ts +70 -0
  239. package/lib/langium/trivia/trivia-service.d.ts.map +1 -0
  240. package/lib/langium/trivia/trivia-service.js +56 -0
  241. package/lib/langium/trivia/trivia-service.js.map +1 -0
  242. package/lib/langium/update-rewrite/normalize-empty-strings.d.ts.map +1 -1
  243. package/lib/langium/update-rewrite/update-rewrite-service.d.ts.map +1 -1
  244. package/lib/langium/update-rewrite/update-rewrite-service.js.map +1 -1
  245. package/lib/langium/update-rewrite/update-rewrite.d.ts +1 -1
  246. package/lib/langium/validation/document-validator.d.ts +280 -9
  247. package/lib/langium/validation/document-validator.d.ts.map +1 -1
  248. package/lib/langium/validation/document-validator.js +448 -5
  249. package/lib/langium/validation/document-validator.js.map +1 -1
  250. package/lib/langium/validation/validation-contribution-collector.d.ts +9 -1
  251. package/lib/langium/validation/validation-contribution-collector.d.ts.map +1 -1
  252. package/lib/langium/validation/validation-contribution-collector.js +1 -1
  253. package/lib/langium/validation/validation-contribution-collector.js.map +1 -1
  254. package/lib/langium/workspace/document-uri-policy.d.ts +15 -10
  255. package/lib/langium/workspace/document-uri-policy.d.ts.map +1 -1
  256. package/lib/langium/workspace/document-uri-policy.js +7 -5
  257. package/lib/langium/workspace/document-uri-policy.js.map +1 -1
  258. package/lib/langium/workspace/file-not-found.d.ts +23 -0
  259. package/lib/langium/workspace/file-not-found.d.ts.map +1 -0
  260. package/lib/langium/workspace/file-not-found.js +31 -0
  261. package/lib/langium/workspace/file-not-found.js.map +1 -0
  262. package/lib/langium/workspace/file-system-provider.d.ts +135 -9
  263. package/lib/langium/workspace/file-system-provider.d.ts.map +1 -1
  264. package/lib/langium/workspace/file-system-provider.js +93 -14
  265. package/lib/langium/workspace/file-system-provider.js.map +1 -1
  266. package/lib/langium/workspace/hydranium-langium-document-factory.d.ts +56 -1
  267. package/lib/langium/workspace/hydranium-langium-document-factory.d.ts.map +1 -1
  268. package/lib/langium/workspace/hydranium-langium-document-factory.js +79 -0
  269. package/lib/langium/workspace/hydranium-langium-document-factory.js.map +1 -1
  270. package/lib/langium/workspace/hydranium-workspace-lock.d.ts +43 -1
  271. package/lib/langium/workspace/hydranium-workspace-lock.d.ts.map +1 -1
  272. package/lib/langium/workspace/hydranium-workspace-lock.js +58 -1
  273. package/lib/langium/workspace/hydranium-workspace-lock.js.map +1 -1
  274. package/lib/langium/workspace/hydranium-workspace-manager.d.ts +82 -9
  275. package/lib/langium/workspace/hydranium-workspace-manager.d.ts.map +1 -1
  276. package/lib/langium/workspace/hydranium-workspace-manager.js +128 -10
  277. package/lib/langium/workspace/hydranium-workspace-manager.js.map +1 -1
  278. package/lib/langium/workspace/in-memory-file-system-provider.d.ts +26 -3
  279. package/lib/langium/workspace/in-memory-file-system-provider.d.ts.map +1 -1
  280. package/lib/langium/workspace/in-memory-file-system-provider.js +41 -15
  281. package/lib/langium/workspace/in-memory-file-system-provider.js.map +1 -1
  282. package/lib/langium/workspace/index-manager.d.ts.map +1 -1
  283. package/lib/langium/workspace/index-manager.js.map +1 -1
  284. package/lib/langium/workspace/index.d.ts +1 -0
  285. package/lib/langium/workspace/index.d.ts.map +1 -1
  286. package/lib/langium/workspace/index.js +1 -0
  287. package/lib/langium/workspace/index.js.map +1 -1
  288. package/lib/langium/workspace/initialize-workspace.d.ts +31 -2
  289. package/lib/langium/workspace/initialize-workspace.d.ts.map +1 -1
  290. package/lib/langium/workspace/initialize-workspace.js +13 -5
  291. package/lib/langium/workspace/initialize-workspace.js.map +1 -1
  292. package/lib/langium/workspace/langium-documents.d.ts +46 -4
  293. package/lib/langium/workspace/langium-documents.d.ts.map +1 -1
  294. package/lib/langium/workspace/langium-documents.js +60 -5
  295. package/lib/langium/workspace/langium-documents.js.map +1 -1
  296. package/lib/langium/workspace/persistent-file-system-provider.d.ts +1 -8
  297. package/lib/langium/workspace/persistent-file-system-provider.d.ts.map +1 -1
  298. package/lib/langium/workspace/persistent-file-system-provider.js +0 -7
  299. package/lib/langium/workspace/persistent-file-system-provider.js.map +1 -1
  300. package/lib/{documents → langium/workspace}/self-save-registry.d.ts +38 -7
  301. package/lib/langium/workspace/self-save-registry.d.ts.map +1 -0
  302. package/lib/{documents → langium/workspace}/self-save-registry.js +29 -16
  303. package/lib/langium/workspace/self-save-registry.js.map +1 -0
  304. package/lib/langium/workspace/virtual-document.d.ts +48 -15
  305. package/lib/langium/workspace/virtual-document.d.ts.map +1 -1
  306. package/lib/langium/workspace/virtual-document.js +78 -18
  307. package/lib/langium/workspace/virtual-document.js.map +1 -1
  308. package/lib/langium/workspace/write-lock-scope.d.ts +20 -10
  309. package/lib/langium/workspace/write-lock-scope.d.ts.map +1 -1
  310. package/lib/langium/workspace/write-lock-scope.js +12 -4
  311. package/lib/langium/workspace/write-lock-scope.js.map +1 -1
  312. package/lib/locale/index.d.ts +10 -0
  313. package/lib/locale/index.d.ts.map +1 -0
  314. package/lib/locale/index.js +10 -0
  315. package/lib/locale/index.js.map +1 -0
  316. package/lib/locale/server-locale.d.ts +73 -0
  317. package/lib/locale/server-locale.d.ts.map +1 -0
  318. package/lib/locale/server-locale.js +61 -0
  319. package/lib/locale/server-locale.js.map +1 -0
  320. package/lib/lsp/completion/hydranium-completion-provider.d.ts +44 -2
  321. package/lib/lsp/completion/hydranium-completion-provider.d.ts.map +1 -1
  322. package/lib/lsp/completion/hydranium-completion-provider.js +68 -0
  323. package/lib/lsp/completion/hydranium-completion-provider.js.map +1 -1
  324. package/lib/lsp/connection-features.d.ts +23 -0
  325. package/lib/lsp/connection-features.d.ts.map +1 -0
  326. package/lib/lsp/connection-features.js +60 -0
  327. package/lib/lsp/connection-features.js.map +1 -0
  328. package/lib/lsp/diagnostics-connection.d.ts +27 -0
  329. package/lib/lsp/diagnostics-connection.d.ts.map +1 -0
  330. package/lib/lsp/diagnostics-connection.js +53 -0
  331. package/lib/lsp/diagnostics-connection.js.map +1 -0
  332. package/lib/lsp/hydranium-document-update-handler.d.ts +92 -81
  333. package/lib/lsp/hydranium-document-update-handler.d.ts.map +1 -1
  334. package/lib/lsp/hydranium-document-update-handler.js +153 -99
  335. package/lib/lsp/hydranium-document-update-handler.js.map +1 -1
  336. package/lib/lsp/index.d.ts +3 -1
  337. package/lib/lsp/index.d.ts.map +1 -1
  338. package/lib/lsp/index.js +3 -1
  339. package/lib/lsp/index.js.map +1 -1
  340. package/lib/lsp/lsp-latency.d.ts +39 -0
  341. package/lib/lsp/lsp-latency.d.ts.map +1 -0
  342. package/lib/lsp/lsp-latency.js +58 -0
  343. package/lib/lsp/lsp-latency.js.map +1 -0
  344. package/lib/lsp/semantic-token-provider.d.ts +34 -1
  345. package/lib/lsp/semantic-token-provider.d.ts.map +1 -1
  346. package/lib/lsp/semantic-token-provider.js +55 -8
  347. package/lib/lsp/semantic-token-provider.js.map +1 -1
  348. package/lib/lsp/shared-module.d.ts +4 -8
  349. package/lib/lsp/shared-module.d.ts.map +1 -1
  350. package/lib/lsp/shared-module.js.map +1 -1
  351. package/lib/lsp/start-language-server.d.ts +8 -7
  352. package/lib/lsp/start-language-server.d.ts.map +1 -1
  353. package/lib/lsp/start-language-server.js +13 -7
  354. package/lib/lsp/start-language-server.js.map +1 -1
  355. package/lib/messages/carriers.d.ts +54 -0
  356. package/lib/messages/carriers.d.ts.map +1 -0
  357. package/lib/messages/carriers.js +62 -0
  358. package/lib/messages/carriers.js.map +1 -0
  359. package/lib/messages/index.d.ts +25 -0
  360. package/lib/messages/index.d.ts.map +1 -0
  361. package/lib/messages/index.js +25 -0
  362. package/lib/messages/index.js.map +1 -0
  363. package/lib/messages/renderer.d.ts +142 -0
  364. package/lib/messages/renderer.d.ts.map +1 -0
  365. package/lib/messages/renderer.js +165 -0
  366. package/lib/messages/renderer.js.map +1 -0
  367. package/lib/node/event-loop-monitor.js.map +1 -1
  368. package/lib/node/heap-ceiling.d.ts +61 -0
  369. package/lib/node/heap-ceiling.d.ts.map +1 -0
  370. package/lib/node/heap-ceiling.js +72 -0
  371. package/lib/node/heap-ceiling.js.map +1 -0
  372. package/lib/node/index.d.ts +1 -1
  373. package/lib/node/index.d.ts.map +1 -1
  374. package/lib/node/index.js +1 -1
  375. package/lib/node/index.js.map +1 -1
  376. package/lib/node/latency-from-env.d.ts +1 -1
  377. package/lib/node/latency-from-env.js +1 -1
  378. package/lib/node/lint-grammar.js.map +1 -1
  379. package/lib/node/measure-memory.d.ts.map +1 -1
  380. package/lib/node/measure-memory.js +1 -0
  381. package/lib/node/measure-memory.js.map +1 -1
  382. package/lib/node/memory-monitor.js.map +1 -1
  383. package/lib/node/node-file-system-provider.d.ts +41 -6
  384. package/lib/node/node-file-system-provider.d.ts.map +1 -1
  385. package/lib/node/node-file-system-provider.js +109 -49
  386. package/lib/node/node-file-system-provider.js.map +1 -1
  387. package/lib/node/profile-capture.d.ts +8 -2
  388. package/lib/node/profile-capture.d.ts.map +1 -1
  389. package/lib/node/profile-capture.js +1 -1
  390. package/lib/node/profile-capture.js.map +1 -1
  391. package/lib/node/profile-digest.js.map +1 -1
  392. package/lib/node/profiling-run.d.ts +13 -3
  393. package/lib/node/profiling-run.d.ts.map +1 -1
  394. package/lib/node/profiling-run.js +17 -8
  395. package/lib/node/profiling-run.js.map +1 -1
  396. package/lib/node/rename-over-open-readers.d.ts +52 -0
  397. package/lib/node/rename-over-open-readers.d.ts.map +1 -0
  398. package/lib/node/rename-over-open-readers.js +66 -0
  399. package/lib/node/rename-over-open-readers.js.map +1 -0
  400. package/lib/node/socket-launcher.d.ts +20 -4
  401. package/lib/node/socket-launcher.d.ts.map +1 -1
  402. package/lib/node/socket-launcher.js +5 -4
  403. package/lib/node/socket-launcher.js.map +1 -1
  404. package/lib/node/stdio-launcher.d.ts +6 -5
  405. package/lib/node/stdio-launcher.d.ts.map +1 -1
  406. package/lib/node/stdio-launcher.js +2 -2
  407. package/lib/node/stdio-launcher.js.map +1 -1
  408. package/lib/testing/document-uri-policy-conformance.js.map +1 -1
  409. package/lib/testing/fake-description.js.map +1 -1
  410. package/lib/testing/fake-document.d.ts +16 -4
  411. package/lib/testing/fake-document.d.ts.map +1 -1
  412. package/lib/testing/fake-document.js +18 -3
  413. package/lib/testing/fake-document.js.map +1 -1
  414. package/lib/testing/index.d.ts +1 -1
  415. package/lib/testing/index.d.ts.map +1 -1
  416. package/lib/testing/index.js +2 -1
  417. package/lib/testing/index.js.map +1 -1
  418. package/lib/testing/langium-test-helpers.d.ts.map +1 -1
  419. package/lib/testing/langium-test-helpers.js +1 -0
  420. package/lib/testing/langium-test-helpers.js.map +1 -1
  421. package/lib/testing/make-noop-language-services.js.map +1 -1
  422. package/lib/testing/make-noop-shared-services.d.ts +14 -0
  423. package/lib/testing/make-noop-shared-services.d.ts.map +1 -1
  424. package/lib/testing/make-noop-shared-services.js +28 -2
  425. package/lib/testing/make-noop-shared-services.js.map +1 -1
  426. package/lib/testing/make-test-services.d.ts +72 -14
  427. package/lib/testing/make-test-services.d.ts.map +1 -1
  428. package/lib/testing/make-test-services.js +42 -10
  429. package/lib/testing/make-test-services.js.map +1 -1
  430. package/lib/testing/make-test-tracer.d.ts +12 -0
  431. package/lib/testing/make-test-tracer.d.ts.map +1 -1
  432. package/lib/testing/make-test-tracer.js +13 -0
  433. package/lib/testing/make-test-tracer.js.map +1 -1
  434. package/lib/testing/node/golden-corpus.js.map +1 -1
  435. package/lib/testing/node/index.d.ts +1 -0
  436. package/lib/testing/node/index.d.ts.map +1 -1
  437. package/lib/testing/node/index.js +1 -0
  438. package/lib/testing/node/index.js.map +1 -1
  439. package/lib/testing/node/lsp-harness.d.ts.map +1 -1
  440. package/lib/testing/node/lsp-harness.js +2 -0
  441. package/lib/testing/node/lsp-harness.js.map +1 -1
  442. package/lib/testing/node/lsp-server-connection.d.ts +11 -3
  443. package/lib/testing/node/lsp-server-connection.d.ts.map +1 -1
  444. package/lib/testing/node/lsp-server-connection.js +43 -10
  445. package/lib/testing/node/lsp-server-connection.js.map +1 -1
  446. package/lib/testing/node/scratch-workspace.d.ts.map +1 -1
  447. package/lib/testing/node/scratch-workspace.js +10 -5
  448. package/lib/testing/node/scratch-workspace.js.map +1 -1
  449. package/lib/testing/node/spawned-server.d.ts +14 -0
  450. package/lib/testing/node/spawned-server.d.ts.map +1 -1
  451. package/lib/testing/node/spawned-server.js +34 -2
  452. package/lib/testing/node/spawned-server.js.map +1 -1
  453. package/lib/testing/node/unhandled-rejections.d.ts +20 -0
  454. package/lib/testing/node/unhandled-rejections.d.ts.map +1 -0
  455. package/lib/testing/node/unhandled-rejections.js +32 -0
  456. package/lib/testing/node/unhandled-rejections.js.map +1 -0
  457. package/lib/testing/playwright/browser-capture-bridge.js.map +1 -1
  458. package/lib/testing/playwright/e2e-profiling.js.map +1 -1
  459. package/lib/testing/playwright/flaky-network-proxy.d.ts +76 -0
  460. package/lib/testing/playwright/flaky-network-proxy.d.ts.map +1 -0
  461. package/lib/testing/playwright/flaky-network-proxy.js +164 -0
  462. package/lib/testing/playwright/flaky-network-proxy.js.map +1 -0
  463. package/lib/testing/playwright/index.d.ts +1 -0
  464. package/lib/testing/playwright/index.d.ts.map +1 -1
  465. package/lib/testing/playwright/index.js +1 -0
  466. package/lib/testing/playwright/index.js.map +1 -1
  467. package/lib/testing/playwright/server-log-capture.d.ts +24 -8
  468. package/lib/testing/playwright/server-log-capture.d.ts.map +1 -1
  469. package/lib/testing/playwright/server-log-capture.js +27 -6
  470. package/lib/testing/playwright/server-log-capture.js.map +1 -1
  471. package/lib/testing/playwright/server-log-rename-reporter.d.ts.map +1 -1
  472. package/lib/testing/playwright/server-log-rename-reporter.js +10 -1
  473. package/lib/testing/playwright/server-log-rename-reporter.js.map +1 -1
  474. package/lib/testing/run-update-pipeline.d.ts +4 -4
  475. package/lib/testing/run-update-pipeline.d.ts.map +1 -1
  476. package/lib/testing/stub-ast-document-manager.d.ts +11 -52
  477. package/lib/testing/stub-ast-document-manager.d.ts.map +1 -1
  478. package/lib/testing/stub-ast-document-manager.js +24 -65
  479. package/lib/testing/stub-ast-document-manager.js.map +1 -1
  480. package/lib/testing/stub-document-builder.d.ts +26 -11
  481. package/lib/testing/stub-document-builder.d.ts.map +1 -1
  482. package/lib/testing/stub-document-builder.js +78 -5
  483. package/lib/testing/stub-document-builder.js.map +1 -1
  484. package/lib/testing/stub-hydranium-text-documents.d.ts +33 -10
  485. package/lib/testing/stub-hydranium-text-documents.d.ts.map +1 -1
  486. package/lib/testing/stub-hydranium-text-documents.js +115 -16
  487. package/lib/testing/stub-hydranium-text-documents.js.map +1 -1
  488. package/lib/testing/stub-index-manager.js.map +1 -1
  489. package/lib/testing/stub-langium-documents.d.ts +3 -2
  490. package/lib/testing/stub-langium-documents.d.ts.map +1 -1
  491. package/lib/testing/stub-langium-documents.js.map +1 -1
  492. package/lib/testing/stub-model-service.d.ts +7 -6
  493. package/lib/testing/stub-model-service.d.ts.map +1 -1
  494. package/lib/testing/stub-model-service.js +4 -4
  495. package/lib/testing/stub-model-service.js.map +1 -1
  496. package/lib/testing/stub-project-manager.js.map +1 -1
  497. package/lib/testing/stub-self-save-registry.d.ts +1 -1
  498. package/lib/testing/stub-self-save-registry.d.ts.map +1 -1
  499. package/lib/testing/stub-service-registry.d.ts +1 -1
  500. package/lib/testing/stub-service-registry.js.map +1 -1
  501. package/lib/testing/stub-writable-file-system.d.ts +1 -1
  502. package/lib/testing/stub-writable-file-system.d.ts.map +1 -1
  503. package/lib/util/connection-liveness.d.ts +7 -6
  504. package/lib/util/connection-liveness.d.ts.map +1 -1
  505. package/lib/util/connection-liveness.js +35 -14
  506. package/lib/util/connection-liveness.js.map +1 -1
  507. package/lib/util/environment.d.ts.map +1 -1
  508. package/lib/util/environment.js.map +1 -1
  509. package/lib/util/registry.d.ts.map +1 -1
  510. package/package.json +32 -48
  511. package/src/documents/ast-document-manager.ts +379 -231
  512. package/src/documents/client-ids.ts +5 -22
  513. package/src/documents/client-session-errors.ts +24 -0
  514. package/src/documents/client-session-registry.ts +262 -0
  515. package/src/documents/dirty-state-tracker.ts +130 -0
  516. package/src/documents/document-release-handler.ts +365 -0
  517. package/src/documents/document-release-scheduler.ts +121 -0
  518. package/src/documents/file-system-task-queue.ts +68 -0
  519. package/src/documents/hydranium-text-documents.ts +931 -595
  520. package/src/documents/index.ts +10 -2
  521. package/src/documents/language-client-shadow.ts +451 -0
  522. package/src/documents/model-ledger.ts +66 -0
  523. package/src/documents/text-ledger.ts +112 -0
  524. package/src/documents/version-sync-service.ts +267 -0
  525. package/src/index.ts +8 -0
  526. package/src/langium/ast-extension/ast-node-builder.ts +66 -22
  527. package/src/langium/bootstrap.ts +66 -28
  528. package/src/langium/composite-ast-reflection.ts +112 -0
  529. package/src/langium/config/configuration-provider.ts +119 -0
  530. package/src/langium/config/index.ts +1 -0
  531. package/src/langium/diagnostics/logger.ts +12 -5
  532. package/src/langium/diagnostics/lsp-logger.ts +59 -15
  533. package/src/langium/document-builder/build-pipeline-integration.ts +50 -5
  534. package/src/langium/document-builder/document-builder.ts +565 -59
  535. package/src/langium/integration-services.ts +83 -24
  536. package/src/langium/integrity/integrity-rule.ts +16 -8
  537. package/src/langium/integrity/integrity-service.ts +287 -62
  538. package/src/langium/keys/containment.ts +87 -0
  539. package/src/langium/keys/index.ts +1 -0
  540. package/src/langium/keys/name-based-key-provider.ts +4 -0
  541. package/src/langium/language-module.ts +48 -7
  542. package/src/langium/model-service/client-session.ts +644 -0
  543. package/src/langium/model-service/index.ts +2 -0
  544. package/src/langium/model-service/model-events.ts +75 -0
  545. package/src/langium/model-service/model-service.ts +790 -468
  546. package/src/langium/module.ts +199 -64
  547. package/src/langium/naming/name-provider.ts +27 -5
  548. package/src/langium/naming/name-separator-validation.ts +34 -5
  549. package/src/langium/project/abstract-project-manager.ts +9 -1
  550. package/src/langium/project/project-change-event.ts +2 -2
  551. package/src/langium/residency/cst-residency-service.ts +45 -14
  552. package/src/langium/scope/hydranium-scope-provider.ts +60 -22
  553. package/src/langium/serialization/abstract-serializer.ts +13 -32
  554. package/src/langium/service-registry.ts +41 -2
  555. package/src/langium/shared-services.ts +21 -6
  556. package/src/langium/single-langium-copy.ts +42 -0
  557. package/src/langium/transfer/transfer-encoder.ts +104 -37
  558. package/src/langium/trivia/comment-preserver.ts +1100 -0
  559. package/src/langium/trivia/document-ending-preserver.ts +55 -0
  560. package/src/langium/trivia/index.ts +14 -0
  561. package/src/langium/trivia/trivia-contribution.ts +39 -0
  562. package/src/langium/trivia/trivia-preserver.ts +54 -0
  563. package/src/langium/trivia/trivia-service.ts +99 -0
  564. package/src/langium/update-rewrite/update-rewrite.ts +1 -1
  565. package/src/langium/validation/document-validator.ts +523 -10
  566. package/src/langium/validation/validation-contribution-collector.ts +10 -1
  567. package/src/langium/workspace/document-uri-policy.ts +15 -10
  568. package/src/langium/workspace/file-not-found.ts +35 -0
  569. package/src/langium/workspace/file-system-provider.ts +205 -17
  570. package/src/langium/workspace/hydranium-langium-document-factory.ts +117 -0
  571. package/src/langium/workspace/hydranium-workspace-lock.ts +86 -2
  572. package/src/langium/workspace/hydranium-workspace-manager.ts +154 -14
  573. package/src/langium/workspace/in-memory-file-system-provider.ts +48 -17
  574. package/src/langium/workspace/index.ts +1 -0
  575. package/src/langium/workspace/initialize-workspace.ts +43 -5
  576. package/src/langium/workspace/langium-documents.ts +75 -6
  577. package/src/langium/workspace/persistent-file-system-provider.ts +1 -8
  578. package/src/{documents → langium/workspace}/self-save-registry.ts +54 -15
  579. package/src/langium/workspace/virtual-document.ts +96 -19
  580. package/src/langium/workspace/write-lock-scope.ts +24 -11
  581. package/src/locale/index.ts +10 -0
  582. package/src/locale/server-locale.ts +86 -0
  583. package/src/lsp/completion/hydranium-completion-provider.ts +82 -2
  584. package/src/lsp/connection-features.ts +67 -0
  585. package/src/lsp/diagnostics-connection.ts +56 -0
  586. package/src/lsp/hydranium-document-update-handler.ts +187 -108
  587. package/src/lsp/index.ts +3 -1
  588. package/src/lsp/lsp-latency.ts +62 -0
  589. package/src/lsp/semantic-token-provider.ts +74 -7
  590. package/src/lsp/shared-module.ts +4 -8
  591. package/src/lsp/start-language-server.ts +13 -7
  592. package/src/messages/carriers.ts +78 -0
  593. package/src/messages/index.ts +36 -0
  594. package/src/messages/renderer.ts +212 -0
  595. package/src/node/heap-ceiling.ts +108 -0
  596. package/src/node/index.ts +1 -1
  597. package/src/node/latency-from-env.ts +1 -1
  598. package/src/node/measure-memory.ts +1 -0
  599. package/src/node/node-file-system-provider.ts +124 -53
  600. package/src/node/profile-capture.ts +9 -3
  601. package/src/node/profiling-run.ts +30 -8
  602. package/src/node/rename-over-open-readers.ts +78 -0
  603. package/src/node/socket-launcher.ts +24 -8
  604. package/src/node/stdio-launcher.ts +8 -7
  605. package/src/testing/fake-document.ts +24 -5
  606. package/src/testing/index.ts +2 -1
  607. package/src/testing/langium-test-helpers.ts +1 -0
  608. package/src/testing/make-noop-shared-services.ts +50 -2
  609. package/src/testing/make-test-services.ts +125 -31
  610. package/src/testing/make-test-tracer.ts +26 -0
  611. package/src/testing/node/index.ts +1 -0
  612. package/src/testing/node/lsp-harness.ts +2 -0
  613. package/src/testing/node/lsp-server-connection.ts +66 -12
  614. package/src/testing/node/scratch-workspace.ts +10 -5
  615. package/src/testing/node/spawned-server.ts +36 -2
  616. package/src/testing/node/unhandled-rejections.ts +31 -0
  617. package/src/testing/parse-semantic-root.ts +1 -1
  618. package/src/testing/playwright/flaky-network-proxy.ts +240 -0
  619. package/src/testing/playwright/index.ts +1 -0
  620. package/src/testing/playwright/server-log-capture.ts +45 -11
  621. package/src/testing/playwright/server-log-rename-reporter.ts +12 -1
  622. package/src/testing/run-update-pipeline.ts +4 -4
  623. package/src/testing/stub-ast-document-manager.ts +36 -138
  624. package/src/testing/stub-document-builder.ts +102 -18
  625. package/src/testing/stub-hydranium-text-documents.ts +165 -27
  626. package/src/testing/stub-langium-documents.ts +3 -2
  627. package/src/testing/stub-model-service.ts +9 -8
  628. package/src/testing/stub-self-save-registry.ts +1 -1
  629. package/src/testing/stub-service-registry.ts +1 -1
  630. package/src/testing/stub-writable-file-system.ts +1 -1
  631. package/src/util/connection-liveness.ts +37 -14
  632. package/src/util/environment.ts +9 -1
  633. package/lib/documents/language-client-text-shadow.d.ts +0 -101
  634. package/lib/documents/language-client-text-shadow.d.ts.map +0 -1
  635. package/lib/documents/language-client-text-shadow.js +0 -156
  636. package/lib/documents/language-client-text-shadow.js.map +0 -1
  637. package/lib/documents/self-save-registry.d.ts.map +0 -1
  638. package/lib/documents/self-save-registry.js.map +0 -1
  639. package/lib/lsp/instrument-connection.d.ts +0 -36
  640. package/lib/lsp/instrument-connection.d.ts.map +0 -1
  641. package/lib/lsp/instrument-connection.js +0 -62
  642. package/lib/lsp/instrument-connection.js.map +0 -1
  643. package/lib/node/process-memory.d.ts +0 -66
  644. package/lib/node/process-memory.d.ts.map +0 -1
  645. package/lib/node/process-memory.js +0 -252
  646. package/lib/node/process-memory.js.map +0 -1
  647. package/src/documents/language-client-text-shadow.ts +0 -175
  648. package/src/lsp/instrument-connection.ts +0 -66
  649. package/src/node/process-memory.ts +0 -299
@@ -0,0 +1,267 @@
1
+ /********************************************************************************
2
+ * Copyright (c) 2026 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 { DocumentState, type LangiumDocument, type URI } from '@hydranium/langium';
11
+ import { type Tracer, UNRECORDED_VERSION } from '@hydranium/protocol';
12
+ import { Disposable, Emitter, type Event } from 'vscode-languageserver-protocol';
13
+ import { type LogNameOptions } from '../langium/diagnostics/logger.js';
14
+ import { type ServerSharedServices } from '../langium/module.js';
15
+ import { HydraniumWorkspaceLock } from '../langium/workspace/hydranium-workspace-lock.js';
16
+ import { HydraniumTextDocuments } from './hydranium-text-documents.js';
17
+
18
+ /** A build {@link VersionSyncService.requestRecoveryBuild} schedules. */
19
+ export interface RecoveryBuildRequest {
20
+ /** Remove the document instead of building it. */
21
+ readonly deleted?: boolean;
22
+ /** Staged for the build, as `HydraniumDocumentBuilder.scheduleUpdate` takes it. */
23
+ readonly reason?: string;
24
+ /** Asked again inside the lock, where a build that ran meanwhile may have made the request moot. */
25
+ readonly stillNeeded: () => boolean;
26
+ /** Build even while a {@link VersionSyncService.registerDeferredBuilds} check holds the URI back. */
27
+ readonly ignoreDeferred?: boolean;
28
+ }
29
+
30
+ /**
31
+ * Keeps each workspace root's `ModelLedger` record in step with the
32
+ * text store, and owns every build that syncs a root to its text or recovers
33
+ * one a build left behind.
34
+ */
35
+ export interface VersionSyncService {
36
+ /**
37
+ * Report a root a factory, registry, integrity repair or other producer
38
+ * made. Below `Parsed` it is marked a placeholder. Otherwise `origin.version`,
39
+ * the store's version read before the parse, is recorded; a registered
40
+ * document is then reconciled with the store, re-versioned and recorded at
41
+ * the store's version of its text, built if behind, and announced on
42
+ * {@link onDidRecordModel}. `origin.text` stands for a root whose CST is not
43
+ * the text it describes.
44
+ */
45
+ modelProduced(document: LangiumDocument, origin?: { version?: number; text?: string }): void;
46
+ /**
47
+ * Build `uri` from a `WorkspaceLock` read, so the build queues behind a
48
+ * running one rather than cancelling it. Requests made while one for `uri`
49
+ * is pending share its next build. Resolves `true` once a build that carried
50
+ * this request completed, or once a check before a build found it no longer
51
+ * needed or deferred. A build a later write cancelled does not count: the
52
+ * request rides the next one. Resolves `false` once builds carrying this
53
+ * request have failed more often than it may retry, so a caller waiting on
54
+ * the build can stop. Never rejects.
55
+ */
56
+ requestRecoveryBuild(uri: URI, request: RecoveryBuildRequest): Promise<boolean>;
57
+ /**
58
+ * Build `uri` unless it is {@link isSyncedTo synced to} `textVersion`, asked
59
+ * again inside the lock. `undefined` when no build is needed, else the
60
+ * {@link requestRecoveryBuild} answer.
61
+ */
62
+ syncTo(uri: URI, textVersion: number): Promise<boolean> | undefined;
63
+ /**
64
+ * Whether `uri`'s root was parsed from text at `textVersion` or later; requests
65
+ * nothing. A root with no recorded version or a placeholder counts as synced,
66
+ * since no build records a version for it, and so does a URI with no document.
67
+ */
68
+ isSyncedTo(uri: URI, textVersion: number): boolean;
69
+ /**
70
+ * Register `isDeferred`, which answers whether its caller holds back a build
71
+ * of a URI it will request later, as the update handler does for a debounced
72
+ * editor change. A caller that drops a held change has to leave the URI to
73
+ * another build.
74
+ */
75
+ registerDeferredBuilds(isDeferred: (uri: URI) => boolean): Disposable;
76
+ /**
77
+ * Fires for every reconciled root. A cancel cannot skip it, unlike a
78
+ * `Parsed` phase listener. It can fire inside a build's write lock, so a
79
+ * listener that requests a build must not await it.
80
+ */
81
+ readonly onDidRecordModel: Event<LangiumDocument>;
82
+ }
83
+
84
+ /** A request waiting in {@link PendingRecoveryBuilds}, with the failed builds that carried it. */
85
+ export interface QueuedRecoveryBuild {
86
+ readonly request: RecoveryBuildRequest;
87
+ failures: number;
88
+ readonly answer: (built: boolean) => void;
89
+ }
90
+
91
+ /** The requests waiting on one URI's builds in {@link DefaultVersionSyncService}. */
92
+ export interface PendingRecoveryBuilds {
93
+ readonly queued: QueuedRecoveryBuild[];
94
+ }
95
+
96
+ /**
97
+ * Collaborators are resolved per call: the registry and its document factory,
98
+ * which construct each other, report roots to this service.
99
+ */
100
+ export class DefaultVersionSyncService implements VersionSyncService {
101
+ protected readonly tracer: Tracer;
102
+ protected readonly recordedEmitter = new Emitter<LangiumDocument>();
103
+ protected readonly deferredBuildChecks = new Set<(uri: URI) => boolean>();
104
+ protected readonly pendingBuilds = new Map<string, PendingRecoveryBuilds>();
105
+ /** Retries of each request after a failed build before it is answered `false`. */
106
+ protected readonly maxBuildRetries: number = 1;
107
+
108
+ constructor(
109
+ protected readonly services: ServerSharedServices,
110
+ options: LogNameOptions = {}
111
+ ) {
112
+ this.tracer = services.Tracer.for(options.logName ?? 'VersionSyncService').trace('instantiated');
113
+ }
114
+
115
+ get onDidRecordModel(): Event<LangiumDocument> {
116
+ return this.recordedEmitter.event;
117
+ }
118
+
119
+ modelProduced(document: LangiumDocument, origin: { version?: number; text?: string } = {}): void {
120
+ const workspace = this.services.workspace;
121
+ const ledger = workspace.ModelLedger;
122
+ const root = document.parseResult.value;
123
+ if (document.state < DocumentState.Parsed) {
124
+ ledger.markPlaceholder(root);
125
+ return;
126
+ }
127
+ if (origin.version !== undefined) {
128
+ ledger.record(root, origin.version, origin.text);
129
+ }
130
+ const store = workspace.TextDocuments;
131
+ // Unregistered, it is a probe or a load whose registration reports it again.
132
+ if (!(store instanceof HydraniumTextDocuments) || workspace.LangiumDocuments.getDocument(document.uri) !== document) {
133
+ return;
134
+ }
135
+ const uri = document.uri.toString();
136
+ // Against the parsed text: the text document may already hold a newer edit.
137
+ const version = store.reconcileExternalContent(uri, origin.text ?? this.parsedText(document));
138
+ if (version !== undefined) {
139
+ if (document.textDocument.version !== version) {
140
+ // An empty-changes update only re-stamps the version.
141
+ store.update(document.textDocument, [], version);
142
+ }
143
+ ledger.record(root, version, origin.text);
144
+ }
145
+ void this.syncTo(document.uri, store.version(uri));
146
+ this.recordedEmitter.fire(document);
147
+ }
148
+
149
+ syncTo(uri: URI, textVersion: number): Promise<boolean> | undefined {
150
+ const behind = (): boolean => !this.isSyncedTo(uri, textVersion);
151
+ return behind() ? this.requestRecoveryBuild(uri, { stillNeeded: behind }) : undefined;
152
+ }
153
+
154
+ requestRecoveryBuild(uri: URI, request: RecoveryBuildRequest): Promise<boolean> {
155
+ return new Promise<boolean>(answer => {
156
+ const key = uri.toString();
157
+ const queued: QueuedRecoveryBuild = { request, failures: 0, answer };
158
+ const pending = this.pendingBuilds.get(key);
159
+ if (pending) {
160
+ // Not dropped: the pending build may have read the text before this request's change.
161
+ pending.queued.push(queued);
162
+ return;
163
+ }
164
+ const entry: PendingRecoveryBuilds = { queued: [queued] };
165
+ this.pendingBuilds.set(key, entry);
166
+ void this.runBuilds(key, uri, entry);
167
+ });
168
+ }
169
+
170
+ registerDeferredBuilds(isDeferred: (uri: URI) => boolean): Disposable {
171
+ this.deferredBuildChecks.add(isDeferred);
172
+ return Disposable.create(() => this.deferredBuildChecks.delete(isDeferred));
173
+ }
174
+
175
+ isSyncedTo(uri: URI, textVersion: number): boolean {
176
+ const root = this.services.workspace.LangiumDocuments.getDocument(uri)?.parseResult.value;
177
+ if (root === undefined) {
178
+ return true;
179
+ }
180
+ const ledger = this.services.workspace.ModelLedger;
181
+ const recorded = ledger.versionOf(root);
182
+ return recorded === UNRECORDED_VERSION || ledger.isPlaceholder(root) || recorded >= textVersion;
183
+ }
184
+
185
+ /** The text `document`'s root was parsed from, or for a root built without either record or CST, the document's own. */
186
+ protected parsedText(document: LangiumDocument): string {
187
+ return this.services.workspace.ModelLedger.textOf(document.parseResult.value) ?? document.textDocument.getText();
188
+ }
189
+
190
+ /**
191
+ * Run `entry`'s requests, one build per batch, until none is queued, and
192
+ * answer each. A request a failed build carried is queued again
193
+ * {@link maxBuildRetries} times, then answered `false`; one a cancelled
194
+ * build carried is queued again without counting. The entry is dropped
195
+ * in the same tick as the last check of the queue, so no request lands in
196
+ * an entry nothing runs any more.
197
+ */
198
+ protected async runBuilds(key: string, uri: URI, entry: PendingRecoveryBuilds): Promise<void> {
199
+ const tracer = this.tracer.withUri(key);
200
+ const lock = this.services.workspace.WorkspaceLock;
201
+ // Any other lock resolves a cancelled write as if it had completed, unnoticed.
202
+ const counting = lock instanceof HydraniumWorkspaceLock ? lock : undefined;
203
+ while (entry.queued.length > 0) {
204
+ let carried: QueuedRecoveryBuild[] = [];
205
+ let build: Promise<void> | undefined;
206
+ let cancellations: number | undefined;
207
+ try {
208
+ // The read waits until no write runs or is queued. It must not await
209
+ // the build, a write that queues behind it.
210
+ await lock.read(() => {
211
+ carried = entry.queued.splice(0);
212
+ const needed = carried.filter(queued => this.isStillNeeded(uri, queued.request));
213
+ carried.filter(queued => !needed.includes(queued)).forEach(queued => queued.answer(true));
214
+ carried = needed;
215
+ if (needed.length > 0) {
216
+ build = this.scheduleBatch(
217
+ uri,
218
+ needed.map(queued => queued.request)
219
+ );
220
+ // Read after the build is queued, which cancels the write before it.
221
+ cancellations = counting?.writeCancellations;
222
+ }
223
+ });
224
+ await build;
225
+ // A write cancelled the build, before it ran or while it did.
226
+ if (cancellations !== undefined && counting?.writeCancellations !== cancellations) {
227
+ entry.queued.unshift(...carried);
228
+ continue;
229
+ }
230
+ carried.forEach(queued => queued.answer(true));
231
+ } catch (err: unknown) {
232
+ const detail = err instanceof Error ? (err.stack ?? err.message) : String(err);
233
+ const retried = carried.filter(queued => queued.failures++ < this.maxBuildRetries);
234
+ const givenUp = carried.filter(queued => !retried.includes(queued));
235
+ if (retried.length > 0) {
236
+ tracer.warn(`Requested build failed; retrying. ${detail}`);
237
+ entry.queued.unshift(...retried);
238
+ }
239
+ if (givenUp.length > 0) {
240
+ tracer.error(`Requested build failed again; giving up. ${detail}`);
241
+ givenUp.forEach(queued => queued.answer(false));
242
+ }
243
+ }
244
+ }
245
+ this.pendingBuilds.delete(key);
246
+ }
247
+
248
+ /** Whether `request` still needs its build, and no deferral it heeds holds it back. Runs inside the lock read. */
249
+ protected isStillNeeded(uri: URI, request: RecoveryBuildRequest): boolean {
250
+ return request.stillNeeded() && (request.ignoreDeferred === true || !this.isDeferred(uri));
251
+ }
252
+
253
+ /**
254
+ * One build for every request of `batch`, removing the document when the
255
+ * latest of them asks to, as `HydraniumDocumentBuilder.scheduleUpdate`
256
+ * merges a change and a deletion. Runs inside the lock read.
257
+ */
258
+ protected scheduleBatch(uri: URI, batch: readonly RecoveryBuildRequest[]): Promise<void> {
259
+ const deleted = batch.at(-1)?.deleted === true;
260
+ const reason = batch.find(request => request.reason !== undefined)?.reason;
261
+ return this.services.workspace.DocumentBuilder.scheduleUpdate(deleted ? [] : [uri], deleted ? [uri] : [], reason);
262
+ }
263
+
264
+ protected isDeferred(uri: URI): boolean {
265
+ return [...this.deferredBuildChecks].some(isDeferred => isDeferred(uri));
266
+ }
267
+ }
package/src/index.ts CHANGED
@@ -28,12 +28,20 @@ export * from './langium/project/index.js';
28
28
  export * from './langium/residency/index.js';
29
29
  export * from './langium/scope/index.js';
30
30
  export * from './langium/serialization/index.js';
31
+ export * from './langium/trivia/index.js';
31
32
  export * from './langium/transfer/index.js';
32
33
  export * from './langium/update-rewrite/index.js';
33
34
  export * from './langium/validation/index.js';
34
35
  export * from './langium/workspace/index.js';
35
36
  export * from './langium/service-registry.js';
36
37
  export * from './langium/language-types.js';
38
+ export * from './langium/composite-ast-reflection.js';
39
+ export * from './langium/single-langium-copy.js';
37
40
  export * from './launcher/index.js';
41
+ export * from './locale/index.js';
42
+ // The renderer only. The `./messages` subpath additionally enumerates this
43
+ // package's own declarations, which the root barrel already re-exports through
44
+ // the modules that raise them.
45
+ export * from './messages/renderer.js';
38
46
  export * from './documents/index.js';
39
47
  export * from './util/index.js';
@@ -78,15 +78,13 @@ export type AstNodeBuilder<TMap> = <TType extends string & keyof TMap>(
78
78
  * AST-interface mapping, so call sites get full inference from the type
79
79
  * constant alone — no explicit generic parameter at every call site.
80
80
  *
81
- * Runtime behaviour: reads `reflection.getTypeMetaData(type).properties` and,
82
- * for every property whose metadata carries a `defaultValue`, pre-fills the
83
- * result before merging the caller's `init`. Array defaults are materialised
84
- * as a fresh `[]` per call (never shared with the metadata's array instance,
85
- * which downstream callers mutate); scalar defaults (`false`, `0`, `''`, …)
86
- * are copied as-is since they're immutable. Grammar-generated containment
87
- * lists and `?=`-style boolean flags therefore default automatically;
88
- * TS-augmented fields (declared via `declare module './generated/ast.js'`)
89
- * are unaffected by the runtime defaulting but remain typed at call sites.
81
+ * Runtime behaviour: pre-fills every grammar-declared default (see
82
+ * {@link withTypeDefaults}) before merging the caller's `init`, so containment
83
+ * lists and `?=`-style boolean flags default automatically. TS-augmented fields
84
+ * (declared via `declare module './generated/ast.js'`) are unaffected by the
85
+ * runtime defaulting but remain typed at call sites.
86
+ *
87
+ * Use {@link buildAstNode} instead when the type name is only known at runtime.
90
88
  *
91
89
  * The init shape only relaxes array-typed fields to optional (via
92
90
  * {@link ArrayKeys}) — there is no equivalent structural signal for "this
@@ -101,19 +99,7 @@ export function makeAstNodeBuilder<TMap>(reflection: AstReflection): AstNodeBuil
101
99
  init: AstNodeInit<Extract<TMap[TType], AstNode>>,
102
100
  extras?: Record<string, unknown>
103
101
  ): Extract<TMap[TType], AstNode> {
104
- const meta = reflection.getTypeMetaData(typeConstant.$type);
105
- const result: Record<string, unknown> = { $type: typeConstant.$type };
106
- if (meta?.properties) {
107
- for (const [propName, propInfo] of Object.entries(meta.properties)) {
108
- const defaultValue = propInfo.defaultValue;
109
- if (defaultValue === undefined) {
110
- continue;
111
- }
112
- // Arrays are duplicated so each node carries its own mutable instance;
113
- // scalars are immutable and safe to copy by reference.
114
- result[propName] = Array.isArray(defaultValue) ? [...defaultValue] : defaultValue;
115
- }
116
- }
102
+ const result = withTypeDefaults(reflection, typeConstant.$type);
117
103
  Object.assign(result, init);
118
104
  if (extras) {
119
105
  // Extras win over init: this is the explicit escape hatch, so when a
@@ -123,3 +109,61 @@ export function makeAstNodeBuilder<TMap>(reflection: AstReflection): AstNodeBuil
123
109
  return result as unknown as Extract<TMap[TType], AstNode>;
124
110
  };
125
111
  }
112
+
113
+ /**
114
+ * Build a node whose type is only known as a RUNTIME string.
115
+ *
116
+ * The typed {@link makeAstNodeBuilder} cannot express this: its `TMap` generic
117
+ * resolves the AST interface from a `$type` literal, and a type name that
118
+ * arrives over the wire — a protocol-layer reference request naming a node that
119
+ * does not exist yet — has no literal to resolve from. Callers that DO know the
120
+ * type at compile time want the typed builder, which checks their mandatory
121
+ * fields; this one checks nothing beyond the reflection lookup.
122
+ *
123
+ * Applies the same reflection-driven defaulting, so a node built here carries
124
+ * grammar-declared containment arrays rather than leaving them `undefined`. An
125
+ * unknown type name yields a node with `$type` and whatever `init` supplied,
126
+ * because reflection answers no metadata for it and refusing would turn a
127
+ * permissive lookup into a throw at a call site that can only guess.
128
+ *
129
+ * **The `type` argument is authoritative: `init` cannot rebind `$type`.** The
130
+ * typed builder gets this for free — `AstNodeInit` omits `$type`, so a call site
131
+ * cannot reach it — but here `init` is loosely typed, and the case that needs
132
+ * the guarantee is RETYPING: a caller spreading an existing node to produce one
133
+ * of a different type (`{ ...source }`) carries the SOURCE's `$type` in, which
134
+ * would silently win over the type actually requested and hand back a node of
135
+ * the wrong type with no error anywhere.
136
+ */
137
+ export function buildAstNode<TAst extends AstNode = AstNode>(
138
+ reflection: AstReflection,
139
+ type: string,
140
+ init?: Partial<AstNode> & Record<string, unknown>
141
+ ): TAst {
142
+ const result = withTypeDefaults(reflection, type);
143
+ if (init) {
144
+ Object.assign(result, init);
145
+ result.$type = type;
146
+ }
147
+ return result as unknown as TAst;
148
+ }
149
+
150
+ /**
151
+ * Seed a node with `$type` plus every property the grammar declares a default
152
+ * for. Array defaults are materialised as a fresh `[]` per call — never shared
153
+ * with the metadata's own array instance, which downstream callers mutate —
154
+ * while scalar defaults are copied as-is since they are immutable.
155
+ */
156
+ function withTypeDefaults(reflection: AstReflection, type: string): Record<string, unknown> {
157
+ const result: Record<string, unknown> = { $type: type };
158
+ const meta = reflection.getTypeMetaData(type);
159
+ if (meta?.properties) {
160
+ for (const [propName, propInfo] of Object.entries(meta.properties)) {
161
+ const defaultValue = propInfo.defaultValue;
162
+ if (defaultValue === undefined) {
163
+ continue;
164
+ }
165
+ result[propName] = Array.isArray(defaultValue) ? [...defaultValue] : defaultValue;
166
+ }
167
+ }
168
+ return result;
169
+ }
@@ -12,15 +12,18 @@ import { type LangiumSharedCoreServices } from '@hydranium/langium';
12
12
  import { type LangiumServices, type LangiumSharedServices } from '@hydranium/langium/lsp';
13
13
  import type { ServerSharedServicesMinimal } from './shared-services.js';
14
14
  import { collectProducibleTypes } from './language-types.js';
15
- import { AstDocumentManager } from '../documents/ast-document-manager.js';
15
+ import { assertSingleLangiumCopy } from './single-langium-copy.js';
16
+ import { DefaultAstDocumentManager } from '../documents/ast-document-manager.js';
16
17
  import { HydraniumTextDocuments } from '../documents/hydranium-text-documents.js';
17
- import { BuildPipelineIntegration } from './document-builder/build-pipeline-integration.js';
18
+ import { DefaultBuildPipelineIntegration } from './document-builder/build-pipeline-integration.js';
18
19
  import { HydraniumDocumentBuilder } from './document-builder/document-builder.js';
19
- import { ModelService } from './model-service/model-service.js';
20
+ import { DefaultModelService } from './model-service/model-service.js';
20
21
  import { HydraniumScopeComputation } from './scope/hydranium-scope-computation.js';
21
22
  import { HydraniumScopeProvider } from './scope/hydranium-scope-provider.js';
22
23
  import { processEnv } from '../util/environment.js';
23
- import { TransferEncoder } from './transfer/transfer-encoder.js';
24
+ import { DefaultTransferEncoder } from './transfer/transfer-encoder.js';
25
+ import { HydraniumLangiumDocumentFactory } from './workspace/hydranium-langium-document-factory.js';
26
+ import { HydraniumLangiumDocuments } from './workspace/langium-documents.js';
24
27
  import { HydraniumWorkspaceManager } from './workspace/hydranium-workspace-manager.js';
25
28
 
26
29
  /**
@@ -73,7 +76,14 @@ const EXPECTED_SHARED_SLOTS: readonly ExpectedSlot[] = [
73
76
  side: 'shared',
74
77
  path: 'workspace.BuildPipelineIntegration',
75
78
  get: services => nested(services, 'workspace', 'BuildPipelineIntegration')
76
- }
79
+ },
80
+ // Unbound, this fails where the cause is least visible: the render pass runs
81
+ // inside the `Validated` phase, so a `TypeError` there propagates out of
82
+ // `notifyDocumentPhase` and the document reaches `Validated` with Langium's
83
+ // publisher never invoked — the client receives no diagnostics for the file
84
+ // and the stack names the document builder.
85
+ { side: 'shared', path: 'MessageRenderer', get: services => nested(services, 'MessageRenderer') },
86
+ { side: 'shared', path: 'ServerLocale', get: services => nested(services, 'ServerLocale') }
77
87
  ];
78
88
 
79
89
  /**
@@ -184,6 +194,20 @@ interface StrictSlot {
184
194
 
185
195
  const STRICT_SHARED_SLOTS: readonly StrictSlot[] = [
186
196
  { side: 'shared', path: 'workspace.TextDocuments', base: HydraniumTextDocuments, get: s => nested(s, 'workspace', 'TextDocuments') },
197
+ // Every root it builds records no version, so every write gated on one conflicts.
198
+ {
199
+ side: 'shared',
200
+ path: 'workspace.LangiumDocumentFactory',
201
+ base: HydraniumLangiumDocumentFactory,
202
+ get: s => nested(s, 'workspace', 'LangiumDocumentFactory')
203
+ },
204
+ // It reports no registered root, so none is reconciled with the text store or announced.
205
+ {
206
+ side: 'shared',
207
+ path: 'workspace.LangiumDocuments',
208
+ base: HydraniumLangiumDocuments,
209
+ get: s => nested(s, 'workspace', 'LangiumDocuments')
210
+ },
187
211
  {
188
212
  side: 'shared',
189
213
  path: 'workspace.WorkspaceManager',
@@ -199,17 +223,17 @@ const STRICT_SHARED_SLOTS: readonly StrictSlot[] = [
199
223
  {
200
224
  side: 'shared',
201
225
  path: 'workspace.AstDocumentManager',
202
- base: AstDocumentManager,
226
+ base: DefaultAstDocumentManager,
203
227
  get: s => nested(s, 'workspace', 'AstDocumentManager')
204
228
  },
205
229
  {
206
230
  side: 'shared',
207
231
  path: 'workspace.BuildPipelineIntegration',
208
- base: BuildPipelineIntegration,
232
+ base: DefaultBuildPipelineIntegration,
209
233
  get: s => nested(s, 'workspace', 'BuildPipelineIntegration')
210
234
  },
211
- { side: 'shared', path: 'model.TransferEncoder', base: TransferEncoder, get: s => nested(s, 'model', 'TransferEncoder') },
212
- { side: 'shared', path: 'model.ModelService', base: ModelService, get: s => nested(s, 'model', 'ModelService') }
235
+ { side: 'shared', path: 'model.TransferEncoder', base: DefaultTransferEncoder, get: s => nested(s, 'model', 'TransferEncoder') },
236
+ { side: 'shared', path: 'model.ModelService', base: DefaultModelService, get: s => nested(s, 'model', 'ModelService') }
213
237
  ];
214
238
 
215
239
  const STRICT_LANGUAGE_SLOTS: readonly StrictSlot[] = [
@@ -329,30 +353,33 @@ export const DEFAULT_EAGER_SERVICES: ReadonlyArray<(services: ServerSharedServic
329
353
  * discarded.
330
354
  *
331
355
  * Bootstrap responsibilities, in order:
332
- * 1. Hand the shared services to `shared.ServiceRegistry` if it accepts
356
+ * 1. {@link assertSingleLangiumCopy} — fail fast when the shared
357
+ * `AstReflection` is built on a second copy of `langium`, before any
358
+ * later check can fail first and name the wrong cause.
359
+ * 2. Hand the shared services to `shared.ServiceRegistry` if it accepts
333
360
  * them after construction, so Langium's declared-languageId lookup
334
361
  * rung works however the adopter's registry binding was built.
335
- * 2. {@link assertDistinctFileRouting} — before registration, because
362
+ * 3. {@link assertDistinctFileRouting} — before registration, because
336
363
  * `register` resolves a routing collision by last-wins and afterwards
337
364
  * the evidence is gone.
338
- * 3. Register `language` against `shared.ServiceRegistry`, the
365
+ * 4. Register `language` against `shared.ServiceRegistry`, the
339
366
  * required final step of any Langium DI bootstrap. Done before slot
340
367
  * validation so subclassed registries (typed-accessor extensions)
341
368
  * populate any side state before validation walks construct services
342
369
  * that read from the registry.
343
- * 4. {@link assertCoreSlotsBound} — fail fast if the consumer's
370
+ * 5. {@link assertCoreSlotsBound} — fail fast if the consumer's
344
371
  * `inject(...)` composition is missing a `@hydranium/core` module. May
345
372
  * trigger lazy service construction as side effect of walking the
346
373
  * slots; that construction expects a populated `ServiceRegistry`,
347
374
  * hence the order.
348
- * 5. {@link warnOnUnexpectedBindings} — opt-in (gated by
375
+ * 6. {@link warnOnUnexpectedBindings} — opt-in (gated by
349
376
  * {@link STRICT_BINDINGS_ENV}); warns when a framework slot is bound
350
377
  * to a non-subclass of its framework base. No-op unless the env is set.
351
- * 6. {@link assertReflectionCoversLanguages} — catch a clobbered shared
378
+ * 7. {@link assertReflectionCoversLanguages} — catch a clobbered shared
352
379
  * `AstReflection` before it starts silently answering `isSubtype`
353
380
  * false for a registered language's types. Skipped here, since a lone
354
381
  * language has no sibling that could clobber it.
355
- * 7. Invoke eager-construction accessors in array order.
382
+ * 8. Invoke eager-construction accessors in array order.
356
383
  *
357
384
  * Multi-grammar adopters use {@link bootstrapLangiumLanguages}, which
358
385
  * registers every language before validating slots or constructing the
@@ -377,16 +404,20 @@ export function bootstrapLangium<TShared extends LangiumSharedServices & ServerS
377
404
  * ORDER across languages is what makes this a distinct function rather
378
405
  * than a loop the caller could write:
379
406
  *
380
- * 1. **Every** language is registered against `shared.ServiceRegistry`
381
- * first. Slot validation and eager construction both build services
407
+ * 1. {@link assertSingleLangiumCopy} runs **once**, before anything else,
408
+ * since every language shares the one `AstReflection`.
409
+ * 2. **Every** language is registered against `shared.ServiceRegistry`
410
+ * next. Slot validation and eager construction both build services
382
411
  * that read the registry — a per-language
383
412
  * register-then-validate-then-eager loop would run them while later
384
413
  * languages were still missing, so a shared service that walks
385
414
  * `ServiceRegistry.all` (or resolves by extension) would see a
386
415
  * half-populated registry and cache the wrong answer.
387
- * 2. `assertCoreSlotsBound` / `warnOnUnexpectedBindings` per language —
416
+ * 3. `assertCoreSlotsBound` / `warnOnUnexpectedBindings` per language —
388
417
  * each language composes its own module chain, so each is checked.
389
- * 3. Eager accessors run **once**, after all registrations. They take
418
+ * 4. {@link assertReflectionCoversLanguages} runs **once**, on the one
419
+ * shared `AstReflection`.
420
+ * 5. Eager accessors run **once**, after all registrations. They take
390
421
  * the shared tier, and the framework's eager set is shared-tier only
391
422
  * (`ProjectManager`, `BuildPipelineIntegration`, `LangiumProfiler`,
392
423
  * `CstResidencyService`) — `BuildPipelineIntegration` in particular
@@ -414,6 +445,11 @@ export function bootstrapLangiumLanguages<
414
445
  '`inject(...)` composition.'
415
446
  );
416
447
  }
448
+ // First, because a second copy of `langium` can make a later check fail
449
+ // first and name the wrong cause.
450
+ if (shared.AstReflection) {
451
+ assertSingleLangiumCopy(shared.AstReflection);
452
+ }
417
453
  // Back-fill the shared services onto a registry that was constructed
418
454
  // without them, so Langium's declared-languageId lookup rung works no
419
455
  // matter how the adopter's `ServiceRegistry` binding built it. An adopter
@@ -521,11 +557,11 @@ export function assertDistinctFileRouting(languages: ReadonlyArray<LangiumServic
521
557
  *
522
558
  * The check is per language, on the types its grammar can produce, and costs
523
559
  * one grammar walk per language at boot; a single-language composition, which
524
- * nothing can clobber, is skipped entirely. It cannot repair the situation — a
525
- * reflection that spans independently generated grammars is a real design piece
526
- * (a composite reflection dispatching per owning language) and is not attempted
527
- * here; the point is to turn a silent runtime misbehaviour into a boot failure
528
- * that names the language and the mistake.
560
+ * nothing can clobber, is skipped entirely. It cannot repair the situation, since
561
+ * the losing reflection is already gone; the point is to turn a silent runtime
562
+ * misbehaviour into a boot failure that names the language and the mistake. The
563
+ * repair is the adopter's: bind a `CompositeAstReflection` over every package's
564
+ * generated reflection, or generate all grammars in one `langium-cli` run.
529
565
  *
530
566
  * **Two severities, because a clobber is not always total.** Throwing only when
531
567
  * NONE of a language's types are known misses the realistic case: two grammars
@@ -567,8 +603,9 @@ export function assertReflectionCoversLanguages(shared: LangiumSharedServices, l
567
603
  `[hydranium] the shared AstReflection knows NONE of the ${produced.size} types the language ` +
568
604
  `'${languageId}' can produce (e.g. ${missing.slice(0, 3).join(', ')}). ` +
569
605
  'AstReflection is a single shared slot, so composing two independently generated language ' +
570
- 'packages leaves only the last one bound. Generate all grammars in ONE langium-cli run (one ' +
571
- 'langium-config with several entry grammars) so a single combined reflection covers them all.'
606
+ "packages leaves only the last one bound. Bind a CompositeAstReflection over every package's " +
607
+ 'generated reflection, or generate all grammars in ONE langium-cli run (one langium-config with ' +
608
+ 'several entry grammars) so a single combined reflection covers them all.'
572
609
  );
573
610
  }
574
611
  }
@@ -590,7 +627,8 @@ function warnPartialReflectionCoverage(
590
627
  'For those types `isSubtype` answers false and `getTypeMetaData` is empty, so `IndexManager.allElements` ' +
591
628
  'finds nothing, reference routing misses, and the encoder emits nothing. Most likely two independently ' +
592
629
  'generated language packages each bound the single shared AstReflection slot and the last one won — ' +
593
- 'generate all grammars in ONE langium-cli run so a single combined reflection covers them. If instead ' +
630
+ "bind a CompositeAstReflection over every package's generated reflection, or generate all grammars in " +
631
+ 'ONE langium-cli run so a single combined reflection covers them. If instead ' +
594
632
  'these are rules your generator legitimately folded away, this warning is expected.';
595
633
  if (logger) {
596
634
  logger.warn(message);