@hydranium/core 1.0.0-next.10

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (868) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +100 -0
  3. package/lib/documents/ast-document-manager.d.ts +243 -0
  4. package/lib/documents/ast-document-manager.d.ts.map +1 -0
  5. package/lib/documents/ast-document-manager.js +302 -0
  6. package/lib/documents/ast-document-manager.js.map +1 -0
  7. package/lib/documents/client-ids.d.ts +30 -0
  8. package/lib/documents/client-ids.d.ts.map +1 -0
  9. package/lib/documents/client-ids.js +30 -0
  10. package/lib/documents/client-ids.js.map +1 -0
  11. package/lib/documents/hydranium-text-documents.d.ts +490 -0
  12. package/lib/documents/hydranium-text-documents.d.ts.map +1 -0
  13. package/lib/documents/hydranium-text-documents.js +893 -0
  14. package/lib/documents/hydranium-text-documents.js.map +1 -0
  15. package/lib/documents/index.d.ts +14 -0
  16. package/lib/documents/index.d.ts.map +1 -0
  17. package/lib/documents/index.js +14 -0
  18. package/lib/documents/index.js.map +1 -0
  19. package/lib/documents/language-client-text-shadow.d.ts +101 -0
  20. package/lib/documents/language-client-text-shadow.d.ts.map +1 -0
  21. package/lib/documents/language-client-text-shadow.js +156 -0
  22. package/lib/documents/language-client-text-shadow.js.map +1 -0
  23. package/lib/documents/self-save-registry.d.ts +55 -0
  24. package/lib/documents/self-save-registry.d.ts.map +1 -0
  25. package/lib/documents/self-save-registry.js +68 -0
  26. package/lib/documents/self-save-registry.js.map +1 -0
  27. package/lib/index.d.ts +38 -0
  28. package/lib/index.d.ts.map +1 -0
  29. package/lib/index.js +39 -0
  30. package/lib/index.js.map +1 -0
  31. package/lib/langium/ast-extension/ast-extension-contribution.d.ts +33 -0
  32. package/lib/langium/ast-extension/ast-extension-contribution.d.ts.map +1 -0
  33. package/lib/langium/ast-extension/ast-extension-contribution.js +10 -0
  34. package/lib/langium/ast-extension/ast-extension-contribution.js.map +1 -0
  35. package/lib/langium/ast-extension/ast-extension-service.d.ts +212 -0
  36. package/lib/langium/ast-extension/ast-extension-service.d.ts.map +1 -0
  37. package/lib/langium/ast-extension/ast-extension-service.js +181 -0
  38. package/lib/langium/ast-extension/ast-extension-service.js.map +1 -0
  39. package/lib/langium/ast-extension/ast-node-builder.d.ts +90 -0
  40. package/lib/langium/ast-extension/ast-node-builder.d.ts.map +1 -0
  41. package/lib/langium/ast-extension/ast-node-builder.js +61 -0
  42. package/lib/langium/ast-extension/ast-node-builder.js.map +1 -0
  43. package/lib/langium/ast-extension/index.d.ts +12 -0
  44. package/lib/langium/ast-extension/index.d.ts.map +1 -0
  45. package/lib/langium/ast-extension/index.js +12 -0
  46. package/lib/langium/ast-extension/index.js.map +1 -0
  47. package/lib/langium/bootstrap.d.ts +224 -0
  48. package/lib/langium/bootstrap.d.ts.map +1 -0
  49. package/lib/langium/bootstrap.js +512 -0
  50. package/lib/langium/bootstrap.js.map +1 -0
  51. package/lib/langium/build-phase-pass/build-phase-pass-service.d.ts +77 -0
  52. package/lib/langium/build-phase-pass/build-phase-pass-service.d.ts.map +1 -0
  53. package/lib/langium/build-phase-pass/build-phase-pass-service.js +102 -0
  54. package/lib/langium/build-phase-pass/build-phase-pass-service.js.map +1 -0
  55. package/lib/langium/build-phase-pass/build-phase-pass.d.ts +106 -0
  56. package/lib/langium/build-phase-pass/build-phase-pass.d.ts.map +1 -0
  57. package/lib/langium/build-phase-pass/build-phase-pass.js +43 -0
  58. package/lib/langium/build-phase-pass/build-phase-pass.js.map +1 -0
  59. package/lib/langium/build-phase-pass/index.d.ts +11 -0
  60. package/lib/langium/build-phase-pass/index.d.ts.map +1 -0
  61. package/lib/langium/build-phase-pass/index.js +11 -0
  62. package/lib/langium/build-phase-pass/index.js.map +1 -0
  63. package/lib/langium/config/index.d.ts +10 -0
  64. package/lib/langium/config/index.d.ts.map +1 -0
  65. package/lib/langium/config/index.js +10 -0
  66. package/lib/langium/config/index.js.map +1 -0
  67. package/lib/langium/config/settings.d.ts +173 -0
  68. package/lib/langium/config/settings.d.ts.map +1 -0
  69. package/lib/langium/config/settings.js +196 -0
  70. package/lib/langium/config/settings.js.map +1 -0
  71. package/lib/langium/diagnostics/hydranium-langium-profiler.d.ts +109 -0
  72. package/lib/langium/diagnostics/hydranium-langium-profiler.d.ts.map +1 -0
  73. package/lib/langium/diagnostics/hydranium-langium-profiler.js +153 -0
  74. package/lib/langium/diagnostics/hydranium-langium-profiler.js.map +1 -0
  75. package/lib/langium/diagnostics/index.d.ts +14 -0
  76. package/lib/langium/diagnostics/index.d.ts.map +1 -0
  77. package/lib/langium/diagnostics/index.js +19 -0
  78. package/lib/langium/diagnostics/index.js.map +1 -0
  79. package/lib/langium/diagnostics/log-file-token.d.ts +16 -0
  80. package/lib/langium/diagnostics/log-file-token.d.ts.map +1 -0
  81. package/lib/langium/diagnostics/log-file-token.js +25 -0
  82. package/lib/langium/diagnostics/log-file-token.js.map +1 -0
  83. package/lib/langium/diagnostics/log-preamble.d.ts +42 -0
  84. package/lib/langium/diagnostics/log-preamble.d.ts.map +1 -0
  85. package/lib/langium/diagnostics/log-preamble.js +57 -0
  86. package/lib/langium/diagnostics/log-preamble.js.map +1 -0
  87. package/lib/langium/diagnostics/logger.d.ts +104 -0
  88. package/lib/langium/diagnostics/logger.d.ts.map +1 -0
  89. package/lib/langium/diagnostics/logger.js +178 -0
  90. package/lib/langium/diagnostics/logger.js.map +1 -0
  91. package/lib/langium/diagnostics/lsp-logger.d.ts +76 -0
  92. package/lib/langium/diagnostics/lsp-logger.d.ts.map +1 -0
  93. package/lib/langium/diagnostics/lsp-logger.js +223 -0
  94. package/lib/langium/diagnostics/lsp-logger.js.map +1 -0
  95. package/lib/langium/diagnostics/server-tracer.d.ts +27 -0
  96. package/lib/langium/diagnostics/server-tracer.d.ts.map +1 -0
  97. package/lib/langium/diagnostics/server-tracer.js +66 -0
  98. package/lib/langium/diagnostics/server-tracer.js.map +1 -0
  99. package/lib/langium/document-builder/build-pipeline-integration.d.ts +88 -0
  100. package/lib/langium/document-builder/build-pipeline-integration.d.ts.map +1 -0
  101. package/lib/langium/document-builder/build-pipeline-integration.js +151 -0
  102. package/lib/langium/document-builder/build-pipeline-integration.js.map +1 -0
  103. package/lib/langium/document-builder/document-builder.d.ts +405 -0
  104. package/lib/langium/document-builder/document-builder.d.ts.map +1 -0
  105. package/lib/langium/document-builder/document-builder.js +729 -0
  106. package/lib/langium/document-builder/document-builder.js.map +1 -0
  107. package/lib/langium/document-builder/index.d.ts +12 -0
  108. package/lib/langium/document-builder/index.d.ts.map +1 -0
  109. package/lib/langium/document-builder/index.js +12 -0
  110. package/lib/langium/document-builder/index.js.map +1 -0
  111. package/lib/langium/document-builder/labeled-phase-listener.d.ts +21 -0
  112. package/lib/langium/document-builder/labeled-phase-listener.d.ts.map +1 -0
  113. package/lib/langium/document-builder/labeled-phase-listener.js +15 -0
  114. package/lib/langium/document-builder/labeled-phase-listener.js.map +1 -0
  115. package/lib/langium/documentation/comment-provider.d.ts +31 -0
  116. package/lib/langium/documentation/comment-provider.d.ts.map +1 -0
  117. package/lib/langium/documentation/comment-provider.js +36 -0
  118. package/lib/langium/documentation/comment-provider.js.map +1 -0
  119. package/lib/langium/documentation/index.d.ts +10 -0
  120. package/lib/langium/documentation/index.d.ts.map +1 -0
  121. package/lib/langium/documentation/index.js +10 -0
  122. package/lib/langium/documentation/index.js.map +1 -0
  123. package/lib/langium/integration-services.d.ts +200 -0
  124. package/lib/langium/integration-services.d.ts.map +1 -0
  125. package/lib/langium/integration-services.js +65 -0
  126. package/lib/langium/integration-services.js.map +1 -0
  127. package/lib/langium/integrity/index.d.ts +12 -0
  128. package/lib/langium/integrity/index.d.ts.map +1 -0
  129. package/lib/langium/integrity/index.js +12 -0
  130. package/lib/langium/integrity/index.js.map +1 -0
  131. package/lib/langium/integrity/integrity-contribution.d.ts +42 -0
  132. package/lib/langium/integrity/integrity-contribution.d.ts.map +1 -0
  133. package/lib/langium/integrity/integrity-contribution.js +10 -0
  134. package/lib/langium/integrity/integrity-contribution.js.map +1 -0
  135. package/lib/langium/integrity/integrity-rule.d.ts +82 -0
  136. package/lib/langium/integrity/integrity-rule.d.ts.map +1 -0
  137. package/lib/langium/integrity/integrity-rule.js +52 -0
  138. package/lib/langium/integrity/integrity-rule.js.map +1 -0
  139. package/lib/langium/integrity/integrity-service.d.ts +221 -0
  140. package/lib/langium/integrity/integrity-service.d.ts.map +1 -0
  141. package/lib/langium/integrity/integrity-service.js +328 -0
  142. package/lib/langium/integrity/integrity-service.js.map +1 -0
  143. package/lib/langium/keys/default-element-key-provider.d.ts +19 -0
  144. package/lib/langium/keys/default-element-key-provider.d.ts.map +1 -0
  145. package/lib/langium/keys/default-element-key-provider.js +18 -0
  146. package/lib/langium/keys/default-element-key-provider.js.map +1 -0
  147. package/lib/langium/keys/element-key-provider.d.ts +106 -0
  148. package/lib/langium/keys/element-key-provider.d.ts.map +1 -0
  149. package/lib/langium/keys/element-key-provider.js +25 -0
  150. package/lib/langium/keys/element-key-provider.js.map +1 -0
  151. package/lib/langium/keys/index.d.ts +13 -0
  152. package/lib/langium/keys/index.d.ts.map +1 -0
  153. package/lib/langium/keys/index.js +13 -0
  154. package/lib/langium/keys/index.js.map +1 -0
  155. package/lib/langium/keys/name-based-key-provider.d.ts +99 -0
  156. package/lib/langium/keys/name-based-key-provider.d.ts.map +1 -0
  157. package/lib/langium/keys/name-based-key-provider.js +134 -0
  158. package/lib/langium/keys/name-based-key-provider.js.map +1 -0
  159. package/lib/langium/keys/positional-key-provider.d.ts +41 -0
  160. package/lib/langium/keys/positional-key-provider.d.ts.map +1 -0
  161. package/lib/langium/keys/positional-key-provider.js +48 -0
  162. package/lib/langium/keys/positional-key-provider.js.map +1 -0
  163. package/lib/langium/labeling/index.d.ts +10 -0
  164. package/lib/langium/labeling/index.d.ts.map +1 -0
  165. package/lib/langium/labeling/index.js +10 -0
  166. package/lib/langium/labeling/index.js.map +1 -0
  167. package/lib/langium/labeling/label-provider.d.ts +79 -0
  168. package/lib/langium/labeling/label-provider.d.ts.map +1 -0
  169. package/lib/langium/labeling/label-provider.js +44 -0
  170. package/lib/langium/labeling/label-provider.js.map +1 -0
  171. package/lib/langium/language-module.d.ts +281 -0
  172. package/lib/langium/language-module.d.ts.map +1 -0
  173. package/lib/langium/language-module.js +103 -0
  174. package/lib/langium/language-module.js.map +1 -0
  175. package/lib/langium/language-types.d.ts +85 -0
  176. package/lib/langium/language-types.d.ts.map +1 -0
  177. package/lib/langium/language-types.js +173 -0
  178. package/lib/langium/language-types.js.map +1 -0
  179. package/lib/langium/model-service/index.d.ts +10 -0
  180. package/lib/langium/model-service/index.d.ts.map +1 -0
  181. package/lib/langium/model-service/index.js +10 -0
  182. package/lib/langium/model-service/index.js.map +1 -0
  183. package/lib/langium/model-service/model-service.d.ts +598 -0
  184. package/lib/langium/model-service/model-service.d.ts.map +1 -0
  185. package/lib/langium/model-service/model-service.js +889 -0
  186. package/lib/langium/model-service/model-service.js.map +1 -0
  187. package/lib/langium/module.d.ts +308 -0
  188. package/lib/langium/module.d.ts.map +1 -0
  189. package/lib/langium/module.js +165 -0
  190. package/lib/langium/module.js.map +1 -0
  191. package/lib/langium/naming/index.d.ts +11 -0
  192. package/lib/langium/naming/index.d.ts.map +1 -0
  193. package/lib/langium/naming/index.js +11 -0
  194. package/lib/langium/naming/index.js.map +1 -0
  195. package/lib/langium/naming/name-provider.d.ts +360 -0
  196. package/lib/langium/naming/name-provider.d.ts.map +1 -0
  197. package/lib/langium/naming/name-provider.js +240 -0
  198. package/lib/langium/naming/name-provider.js.map +1 -0
  199. package/lib/langium/naming/name-separator-validation.d.ts +47 -0
  200. package/lib/langium/naming/name-separator-validation.d.ts.map +1 -0
  201. package/lib/langium/naming/name-separator-validation.js +61 -0
  202. package/lib/langium/naming/name-separator-validation.js.map +1 -0
  203. package/lib/langium/project/abstract-project-manager.d.ts +242 -0
  204. package/lib/langium/project/abstract-project-manager.d.ts.map +1 -0
  205. package/lib/langium/project/abstract-project-manager.js +545 -0
  206. package/lib/langium/project/abstract-project-manager.js.map +1 -0
  207. package/lib/langium/project/index.d.ts +13 -0
  208. package/lib/langium/project/index.d.ts.map +1 -0
  209. package/lib/langium/project/index.js +13 -0
  210. package/lib/langium/project/index.js.map +1 -0
  211. package/lib/langium/project/project-change-event.d.ts +64 -0
  212. package/lib/langium/project/project-change-event.d.ts.map +1 -0
  213. package/lib/langium/project/project-change-event.js +10 -0
  214. package/lib/langium/project/project-change-event.js.map +1 -0
  215. package/lib/langium/project/project-manager.d.ts +196 -0
  216. package/lib/langium/project/project-manager.d.ts.map +1 -0
  217. package/lib/langium/project/project-manager.js +10 -0
  218. package/lib/langium/project/project-manager.js.map +1 -0
  219. package/lib/langium/project/single-project-manager.d.ts +69 -0
  220. package/lib/langium/project/single-project-manager.d.ts.map +1 -0
  221. package/lib/langium/project/single-project-manager.js +104 -0
  222. package/lib/langium/project/single-project-manager.js.map +1 -0
  223. package/lib/langium/residency/cst-residency-service.d.ts +214 -0
  224. package/lib/langium/residency/cst-residency-service.d.ts.map +1 -0
  225. package/lib/langium/residency/cst-residency-service.js +349 -0
  226. package/lib/langium/residency/cst-residency-service.js.map +1 -0
  227. package/lib/langium/residency/index.d.ts +10 -0
  228. package/lib/langium/residency/index.d.ts.map +1 -0
  229. package/lib/langium/residency/index.js +10 -0
  230. package/lib/langium/residency/index.js.map +1 -0
  231. package/lib/langium/scope/ast-node-description-provider.d.ts +122 -0
  232. package/lib/langium/scope/ast-node-description-provider.d.ts.map +1 -0
  233. package/lib/langium/scope/ast-node-description-provider.js +115 -0
  234. package/lib/langium/scope/ast-node-description-provider.js.map +1 -0
  235. package/lib/langium/scope/hydranium-scope-computation.d.ts +163 -0
  236. package/lib/langium/scope/hydranium-scope-computation.d.ts.map +1 -0
  237. package/lib/langium/scope/hydranium-scope-computation.js +220 -0
  238. package/lib/langium/scope/hydranium-scope-computation.js.map +1 -0
  239. package/lib/langium/scope/hydranium-scope-provider.d.ts +411 -0
  240. package/lib/langium/scope/hydranium-scope-provider.d.ts.map +1 -0
  241. package/lib/langium/scope/hydranium-scope-provider.js +543 -0
  242. package/lib/langium/scope/hydranium-scope-provider.js.map +1 -0
  243. package/lib/langium/scope/index.d.ts +18 -0
  244. package/lib/langium/scope/index.d.ts.map +1 -0
  245. package/lib/langium/scope/index.js +18 -0
  246. package/lib/langium/scope/index.js.map +1 -0
  247. package/lib/langium/scope/reference-builder.d.ts +125 -0
  248. package/lib/langium/scope/reference-builder.d.ts.map +1 -0
  249. package/lib/langium/scope/reference-builder.js +115 -0
  250. package/lib/langium/scope/reference-builder.js.map +1 -0
  251. package/lib/langium/scope/reference-candidate-provider.d.ts +228 -0
  252. package/lib/langium/scope/reference-candidate-provider.d.ts.map +1 -0
  253. package/lib/langium/scope/reference-candidate-provider.js +185 -0
  254. package/lib/langium/scope/reference-candidate-provider.js.map +1 -0
  255. package/lib/langium/scope/scope-extension-contribution.d.ts +32 -0
  256. package/lib/langium/scope/scope-extension-contribution.d.ts.map +1 -0
  257. package/lib/langium/scope/scope-extension-contribution.js +10 -0
  258. package/lib/langium/scope/scope-extension-contribution.js.map +1 -0
  259. package/lib/langium/scope/scope-extension-service.d.ts +149 -0
  260. package/lib/langium/scope/scope-extension-service.d.ts.map +1 -0
  261. package/lib/langium/scope/scope-extension-service.js +94 -0
  262. package/lib/langium/scope/scope-extension-service.js.map +1 -0
  263. package/lib/langium/scope/scoped-ast-node-description.d.ts +160 -0
  264. package/lib/langium/scope/scoped-ast-node-description.d.ts.map +1 -0
  265. package/lib/langium/scope/scoped-ast-node-description.js +98 -0
  266. package/lib/langium/scope/scoped-ast-node-description.js.map +1 -0
  267. package/lib/langium/scope/tier-specificity.d.ts +47 -0
  268. package/lib/langium/scope/tier-specificity.d.ts.map +1 -0
  269. package/lib/langium/scope/tier-specificity.js +83 -0
  270. package/lib/langium/scope/tier-specificity.js.map +1 -0
  271. package/lib/langium/serialization/abstract-serializer.d.ts +316 -0
  272. package/lib/langium/serialization/abstract-serializer.d.ts.map +1 -0
  273. package/lib/langium/serialization/abstract-serializer.js +351 -0
  274. package/lib/langium/serialization/abstract-serializer.js.map +1 -0
  275. package/lib/langium/serialization/index.d.ts +14 -0
  276. package/lib/langium/serialization/index.d.ts.map +1 -0
  277. package/lib/langium/serialization/index.js +14 -0
  278. package/lib/langium/serialization/index.js.map +1 -0
  279. package/lib/langium/serialization/json-serializer.d.ts +106 -0
  280. package/lib/langium/serialization/json-serializer.d.ts.map +1 -0
  281. package/lib/langium/serialization/json-serializer.js +198 -0
  282. package/lib/langium/serialization/json-serializer.js.map +1 -0
  283. package/lib/langium/serialization/serialization-util.d.ts +29 -0
  284. package/lib/langium/serialization/serialization-util.d.ts.map +1 -0
  285. package/lib/langium/serialization/serialization-util.js +37 -0
  286. package/lib/langium/serialization/serialization-util.js.map +1 -0
  287. package/lib/langium/serialization/serializer.d.ts +66 -0
  288. package/lib/langium/serialization/serializer.d.ts.map +1 -0
  289. package/lib/langium/serialization/serializer.js +10 -0
  290. package/lib/langium/serialization/serializer.js.map +1 -0
  291. package/lib/langium/serialization/yaml-serializer.d.ts +166 -0
  292. package/lib/langium/serialization/yaml-serializer.d.ts.map +1 -0
  293. package/lib/langium/serialization/yaml-serializer.js +228 -0
  294. package/lib/langium/serialization/yaml-serializer.js.map +1 -0
  295. package/lib/langium/service-registry.d.ts +220 -0
  296. package/lib/langium/service-registry.d.ts.map +1 -0
  297. package/lib/langium/service-registry.js +258 -0
  298. package/lib/langium/service-registry.js.map +1 -0
  299. package/lib/langium/shared-services.d.ts +98 -0
  300. package/lib/langium/shared-services.d.ts.map +1 -0
  301. package/lib/langium/shared-services.js +30 -0
  302. package/lib/langium/shared-services.js.map +1 -0
  303. package/lib/langium/transfer/index.d.ts +10 -0
  304. package/lib/langium/transfer/index.d.ts.map +1 -0
  305. package/lib/langium/transfer/index.js +10 -0
  306. package/lib/langium/transfer/index.js.map +1 -0
  307. package/lib/langium/transfer/transfer-encoder.d.ts +294 -0
  308. package/lib/langium/transfer/transfer-encoder.d.ts.map +1 -0
  309. package/lib/langium/transfer/transfer-encoder.js +328 -0
  310. package/lib/langium/transfer/transfer-encoder.js.map +1 -0
  311. package/lib/langium/update-rewrite/index.d.ts +14 -0
  312. package/lib/langium/update-rewrite/index.d.ts.map +1 -0
  313. package/lib/langium/update-rewrite/index.js +14 -0
  314. package/lib/langium/update-rewrite/index.js.map +1 -0
  315. package/lib/langium/update-rewrite/normalize-empty-strings.d.ts +52 -0
  316. package/lib/langium/update-rewrite/normalize-empty-strings.d.ts.map +1 -0
  317. package/lib/langium/update-rewrite/normalize-empty-strings.js +83 -0
  318. package/lib/langium/update-rewrite/normalize-empty-strings.js.map +1 -0
  319. package/lib/langium/update-rewrite/semantic-root-rewrite.d.ts +37 -0
  320. package/lib/langium/update-rewrite/semantic-root-rewrite.d.ts.map +1 -0
  321. package/lib/langium/update-rewrite/semantic-root-rewrite.js +51 -0
  322. package/lib/langium/update-rewrite/semantic-root-rewrite.js.map +1 -0
  323. package/lib/langium/update-rewrite/update-rewrite-contribution.d.ts +42 -0
  324. package/lib/langium/update-rewrite/update-rewrite-contribution.d.ts.map +1 -0
  325. package/lib/langium/update-rewrite/update-rewrite-contribution.js +10 -0
  326. package/lib/langium/update-rewrite/update-rewrite-contribution.js.map +1 -0
  327. package/lib/langium/update-rewrite/update-rewrite-service.d.ts +89 -0
  328. package/lib/langium/update-rewrite/update-rewrite-service.d.ts.map +1 -0
  329. package/lib/langium/update-rewrite/update-rewrite-service.js +75 -0
  330. package/lib/langium/update-rewrite/update-rewrite-service.js.map +1 -0
  331. package/lib/langium/update-rewrite/update-rewrite.d.ts +59 -0
  332. package/lib/langium/update-rewrite/update-rewrite.d.ts.map +1 -0
  333. package/lib/langium/update-rewrite/update-rewrite.js +10 -0
  334. package/lib/langium/update-rewrite/update-rewrite.js.map +1 -0
  335. package/lib/langium/validation/document-validator.d.ts +106 -0
  336. package/lib/langium/validation/document-validator.d.ts.map +1 -0
  337. package/lib/langium/validation/document-validator.js +118 -0
  338. package/lib/langium/validation/document-validator.js.map +1 -0
  339. package/lib/langium/validation/index.d.ts +12 -0
  340. package/lib/langium/validation/index.d.ts.map +1 -0
  341. package/lib/langium/validation/index.js +12 -0
  342. package/lib/langium/validation/index.js.map +1 -0
  343. package/lib/langium/validation/validation-contribution-collector.d.ts +34 -0
  344. package/lib/langium/validation/validation-contribution-collector.d.ts.map +1 -0
  345. package/lib/langium/validation/validation-contribution-collector.js +51 -0
  346. package/lib/langium/validation/validation-contribution-collector.js.map +1 -0
  347. package/lib/langium/validation/validation-contribution.d.ts +36 -0
  348. package/lib/langium/validation/validation-contribution.d.ts.map +1 -0
  349. package/lib/langium/validation/validation-contribution.js +10 -0
  350. package/lib/langium/validation/validation-contribution.js.map +1 -0
  351. package/lib/langium/workspace/additional-document-contribution.d.ts +68 -0
  352. package/lib/langium/workspace/additional-document-contribution.d.ts.map +1 -0
  353. package/lib/langium/workspace/additional-document-contribution.js +23 -0
  354. package/lib/langium/workspace/additional-document-contribution.js.map +1 -0
  355. package/lib/langium/workspace/document-uri-policy.d.ts +151 -0
  356. package/lib/langium/workspace/document-uri-policy.d.ts.map +1 -0
  357. package/lib/langium/workspace/document-uri-policy.js +121 -0
  358. package/lib/langium/workspace/document-uri-policy.js.map +1 -0
  359. package/lib/langium/workspace/file-system-provider.d.ts +30 -0
  360. package/lib/langium/workspace/file-system-provider.d.ts.map +1 -0
  361. package/lib/langium/workspace/file-system-provider.js +41 -0
  362. package/lib/langium/workspace/file-system-provider.js.map +1 -0
  363. package/lib/langium/workspace/hydranium-langium-document-factory.d.ts +45 -0
  364. package/lib/langium/workspace/hydranium-langium-document-factory.d.ts.map +1 -0
  365. package/lib/langium/workspace/hydranium-langium-document-factory.js +64 -0
  366. package/lib/langium/workspace/hydranium-langium-document-factory.js.map +1 -0
  367. package/lib/langium/workspace/hydranium-workspace-lock.d.ts +31 -0
  368. package/lib/langium/workspace/hydranium-workspace-lock.d.ts.map +1 -0
  369. package/lib/langium/workspace/hydranium-workspace-lock.js +33 -0
  370. package/lib/langium/workspace/hydranium-workspace-lock.js.map +1 -0
  371. package/lib/langium/workspace/hydranium-workspace-manager.d.ts +232 -0
  372. package/lib/langium/workspace/hydranium-workspace-manager.d.ts.map +1 -0
  373. package/lib/langium/workspace/hydranium-workspace-manager.js +368 -0
  374. package/lib/langium/workspace/hydranium-workspace-manager.js.map +1 -0
  375. package/lib/langium/workspace/in-memory-file-system-provider.d.ts +127 -0
  376. package/lib/langium/workspace/in-memory-file-system-provider.d.ts.map +1 -0
  377. package/lib/langium/workspace/in-memory-file-system-provider.js +195 -0
  378. package/lib/langium/workspace/in-memory-file-system-provider.js.map +1 -0
  379. package/lib/langium/workspace/index-manager.d.ts +142 -0
  380. package/lib/langium/workspace/index-manager.d.ts.map +1 -0
  381. package/lib/langium/workspace/index-manager.js +245 -0
  382. package/lib/langium/workspace/index-manager.js.map +1 -0
  383. package/lib/langium/workspace/index.d.ts +23 -0
  384. package/lib/langium/workspace/index.d.ts.map +1 -0
  385. package/lib/langium/workspace/index.js +23 -0
  386. package/lib/langium/workspace/index.js.map +1 -0
  387. package/lib/langium/workspace/initialize-workspace.d.ts +63 -0
  388. package/lib/langium/workspace/initialize-workspace.d.ts.map +1 -0
  389. package/lib/langium/workspace/initialize-workspace.js +88 -0
  390. package/lib/langium/workspace/initialize-workspace.js.map +1 -0
  391. package/lib/langium/workspace/langium-documents.d.ts +47 -0
  392. package/lib/langium/workspace/langium-documents.d.ts.map +1 -0
  393. package/lib/langium/workspace/langium-documents.js +85 -0
  394. package/lib/langium/workspace/langium-documents.js.map +1 -0
  395. package/lib/langium/workspace/persistent-file-system-provider.d.ts +207 -0
  396. package/lib/langium/workspace/persistent-file-system-provider.d.ts.map +1 -0
  397. package/lib/langium/workspace/persistent-file-system-provider.js +208 -0
  398. package/lib/langium/workspace/persistent-file-system-provider.js.map +1 -0
  399. package/lib/langium/workspace/synthetic.d.ts +38 -0
  400. package/lib/langium/workspace/synthetic.d.ts.map +1 -0
  401. package/lib/langium/workspace/synthetic.js +58 -0
  402. package/lib/langium/workspace/synthetic.js.map +1 -0
  403. package/lib/langium/workspace/virtual-document.d.ts +78 -0
  404. package/lib/langium/workspace/virtual-document.d.ts.map +1 -0
  405. package/lib/langium/workspace/virtual-document.js +89 -0
  406. package/lib/langium/workspace/virtual-document.js.map +1 -0
  407. package/lib/langium/workspace/write-lock-scope.d.ts +69 -0
  408. package/lib/langium/workspace/write-lock-scope.d.ts.map +1 -0
  409. package/lib/langium/workspace/write-lock-scope.js +54 -0
  410. package/lib/langium/workspace/write-lock-scope.js.map +1 -0
  411. package/lib/launcher/index.d.ts +10 -0
  412. package/lib/launcher/index.d.ts.map +1 -0
  413. package/lib/launcher/index.js +12 -0
  414. package/lib/launcher/index.js.map +1 -0
  415. package/lib/launcher/integrated-server.d.ts +28 -0
  416. package/lib/launcher/integrated-server.d.ts.map +1 -0
  417. package/lib/launcher/integrated-server.js +10 -0
  418. package/lib/launcher/integrated-server.js.map +1 -0
  419. package/lib/lsp/completion/hydranium-completion-provider.d.ts +89 -0
  420. package/lib/lsp/completion/hydranium-completion-provider.d.ts.map +1 -0
  421. package/lib/lsp/completion/hydranium-completion-provider.js +123 -0
  422. package/lib/lsp/completion/hydranium-completion-provider.js.map +1 -0
  423. package/lib/lsp/hydranium-document-update-handler.d.ts +204 -0
  424. package/lib/lsp/hydranium-document-update-handler.d.ts.map +1 -0
  425. package/lib/lsp/hydranium-document-update-handler.js +288 -0
  426. package/lib/lsp/hydranium-document-update-handler.js.map +1 -0
  427. package/lib/lsp/index.d.ts +23 -0
  428. package/lib/lsp/index.d.ts.map +1 -0
  429. package/lib/lsp/index.js +23 -0
  430. package/lib/lsp/index.js.map +1 -0
  431. package/lib/lsp/instrument-connection.d.ts +36 -0
  432. package/lib/lsp/instrument-connection.d.ts.map +1 -0
  433. package/lib/lsp/instrument-connection.js +62 -0
  434. package/lib/lsp/instrument-connection.js.map +1 -0
  435. package/lib/lsp/language-module.d.ts +53 -0
  436. package/lib/lsp/language-module.d.ts.map +1 -0
  437. package/lib/lsp/language-module.js +28 -0
  438. package/lib/lsp/language-module.js.map +1 -0
  439. package/lib/lsp/semantic-token-provider.d.ts +131 -0
  440. package/lib/lsp/semantic-token-provider.d.ts.map +1 -0
  441. package/lib/lsp/semantic-token-provider.js +148 -0
  442. package/lib/lsp/semantic-token-provider.js.map +1 -0
  443. package/lib/lsp/shared-module.d.ts +76 -0
  444. package/lib/lsp/shared-module.d.ts.map +1 -0
  445. package/lib/lsp/shared-module.js +33 -0
  446. package/lib/lsp/shared-module.js.map +1 -0
  447. package/lib/lsp/start-language-server.d.ts +43 -0
  448. package/lib/lsp/start-language-server.d.ts.map +1 -0
  449. package/lib/lsp/start-language-server.js +60 -0
  450. package/lib/lsp/start-language-server.js.map +1 -0
  451. package/lib/node/ast-ground-truth.d.ts +57 -0
  452. package/lib/node/ast-ground-truth.d.ts.map +1 -0
  453. package/lib/node/ast-ground-truth.js +46 -0
  454. package/lib/node/ast-ground-truth.js.map +1 -0
  455. package/lib/node/event-loop-monitor.d.ts +40 -0
  456. package/lib/node/event-loop-monitor.d.ts.map +1 -0
  457. package/lib/node/event-loop-monitor.js +62 -0
  458. package/lib/node/event-loop-monitor.js.map +1 -0
  459. package/lib/node/index.d.ts +29 -0
  460. package/lib/node/index.d.ts.map +1 -0
  461. package/lib/node/index.js +50 -0
  462. package/lib/node/index.js.map +1 -0
  463. package/lib/node/latency-from-env.d.ts +32 -0
  464. package/lib/node/latency-from-env.d.ts.map +1 -0
  465. package/lib/node/latency-from-env.js +36 -0
  466. package/lib/node/latency-from-env.js.map +1 -0
  467. package/lib/node/lint-grammar.d.ts +87 -0
  468. package/lib/node/lint-grammar.d.ts.map +1 -0
  469. package/lib/node/lint-grammar.js +124 -0
  470. package/lib/node/lint-grammar.js.map +1 -0
  471. package/lib/node/log-file-sink.d.ts +22 -0
  472. package/lib/node/log-file-sink.d.ts.map +1 -0
  473. package/lib/node/log-file-sink.js +43 -0
  474. package/lib/node/log-file-sink.js.map +1 -0
  475. package/lib/node/log-preamble-node.d.ts +28 -0
  476. package/lib/node/log-preamble-node.d.ts.map +1 -0
  477. package/lib/node/log-preamble-node.js +55 -0
  478. package/lib/node/log-preamble-node.js.map +1 -0
  479. package/lib/node/measure-memory.d.ts +86 -0
  480. package/lib/node/measure-memory.d.ts.map +1 -0
  481. package/lib/node/measure-memory.js +128 -0
  482. package/lib/node/measure-memory.js.map +1 -0
  483. package/lib/node/memory-monitor.d.ts +42 -0
  484. package/lib/node/memory-monitor.d.ts.map +1 -0
  485. package/lib/node/memory-monitor.js +83 -0
  486. package/lib/node/memory-monitor.js.map +1 -0
  487. package/lib/node/node-file-system-provider.d.ts +112 -0
  488. package/lib/node/node-file-system-provider.d.ts.map +1 -0
  489. package/lib/node/node-file-system-provider.js +230 -0
  490. package/lib/node/node-file-system-provider.js.map +1 -0
  491. package/lib/node/process-memory.d.ts +66 -0
  492. package/lib/node/process-memory.d.ts.map +1 -0
  493. package/lib/node/process-memory.js +252 -0
  494. package/lib/node/process-memory.js.map +1 -0
  495. package/lib/node/profile-capture.d.ts +118 -0
  496. package/lib/node/profile-capture.d.ts.map +1 -0
  497. package/lib/node/profile-capture.js +315 -0
  498. package/lib/node/profile-capture.js.map +1 -0
  499. package/lib/node/profile-digest.d.ts +49 -0
  500. package/lib/node/profile-digest.d.ts.map +1 -0
  501. package/lib/node/profile-digest.js +74 -0
  502. package/lib/node/profile-digest.js.map +1 -0
  503. package/lib/node/profiling-run.d.ts +80 -0
  504. package/lib/node/profiling-run.d.ts.map +1 -0
  505. package/lib/node/profiling-run.js +183 -0
  506. package/lib/node/profiling-run.js.map +1 -0
  507. package/lib/node/reflect-grammar.d.ts +109 -0
  508. package/lib/node/reflect-grammar.d.ts.map +1 -0
  509. package/lib/node/reflect-grammar.js +96 -0
  510. package/lib/node/reflect-grammar.js.map +1 -0
  511. package/lib/node/server-diagnostics.d.ts +43 -0
  512. package/lib/node/server-diagnostics.d.ts.map +1 -0
  513. package/lib/node/server-diagnostics.js +46 -0
  514. package/lib/node/server-diagnostics.js.map +1 -0
  515. package/lib/node/server-state-snapshot.d.ts +48 -0
  516. package/lib/node/server-state-snapshot.d.ts.map +1 -0
  517. package/lib/node/server-state-snapshot.js +139 -0
  518. package/lib/node/server-state-snapshot.js.map +1 -0
  519. package/lib/node/socket-launcher.d.ts +106 -0
  520. package/lib/node/socket-launcher.d.ts.map +1 -0
  521. package/lib/node/socket-launcher.js +138 -0
  522. package/lib/node/socket-launcher.js.map +1 -0
  523. package/lib/node/stdio-launcher.d.ts +88 -0
  524. package/lib/node/stdio-launcher.d.ts.map +1 -0
  525. package/lib/node/stdio-launcher.js +83 -0
  526. package/lib/node/stdio-launcher.js.map +1 -0
  527. package/lib/node/validate-workspace.d.ts +80 -0
  528. package/lib/node/validate-workspace.d.ts.map +1 -0
  529. package/lib/node/validate-workspace.js +72 -0
  530. package/lib/node/validate-workspace.js.map +1 -0
  531. package/lib/node/write-lock-scope-node.d.ts +27 -0
  532. package/lib/node/write-lock-scope-node.d.ts.map +1 -0
  533. package/lib/node/write-lock-scope-node.js +38 -0
  534. package/lib/node/write-lock-scope-node.js.map +1 -0
  535. package/lib/testing/ast-snapshot.d.ts +38 -0
  536. package/lib/testing/ast-snapshot.d.ts.map +1 -0
  537. package/lib/testing/ast-snapshot.js +78 -0
  538. package/lib/testing/ast-snapshot.js.map +1 -0
  539. package/lib/testing/document-uri-policy-conformance.d.ts +65 -0
  540. package/lib/testing/document-uri-policy-conformance.d.ts.map +1 -0
  541. package/lib/testing/document-uri-policy-conformance.js +69 -0
  542. package/lib/testing/document-uri-policy-conformance.js.map +1 -0
  543. package/lib/testing/fake-description.d.ts +35 -0
  544. package/lib/testing/fake-description.d.ts.map +1 -0
  545. package/lib/testing/fake-description.js +38 -0
  546. package/lib/testing/fake-description.js.map +1 -0
  547. package/lib/testing/fake-document.d.ts +71 -0
  548. package/lib/testing/fake-document.d.ts.map +1 -0
  549. package/lib/testing/fake-document.js +85 -0
  550. package/lib/testing/fake-document.js.map +1 -0
  551. package/lib/testing/fake-reflection.d.ts +29 -0
  552. package/lib/testing/fake-reflection.d.ts.map +1 -0
  553. package/lib/testing/fake-reflection.js +30 -0
  554. package/lib/testing/fake-reflection.js.map +1 -0
  555. package/lib/testing/index.d.ts +44 -0
  556. package/lib/testing/index.d.ts.map +1 -0
  557. package/lib/testing/index.js +44 -0
  558. package/lib/testing/index.js.map +1 -0
  559. package/lib/testing/langium-test-helpers.d.ts +26 -0
  560. package/lib/testing/langium-test-helpers.d.ts.map +1 -0
  561. package/lib/testing/langium-test-helpers.js +26 -0
  562. package/lib/testing/langium-test-helpers.js.map +1 -0
  563. package/lib/testing/make-noop-language-services.d.ts +39 -0
  564. package/lib/testing/make-noop-language-services.d.ts.map +1 -0
  565. package/lib/testing/make-noop-language-services.js +30 -0
  566. package/lib/testing/make-noop-language-services.js.map +1 -0
  567. package/lib/testing/make-noop-shared-services.d.ts +61 -0
  568. package/lib/testing/make-noop-shared-services.d.ts.map +1 -0
  569. package/lib/testing/make-noop-shared-services.js +49 -0
  570. package/lib/testing/make-noop-shared-services.js.map +1 -0
  571. package/lib/testing/make-test-services.d.ts +217 -0
  572. package/lib/testing/make-test-services.d.ts.map +1 -0
  573. package/lib/testing/make-test-services.js +128 -0
  574. package/lib/testing/make-test-services.js.map +1 -0
  575. package/lib/testing/make-test-tracer.d.ts +67 -0
  576. package/lib/testing/make-test-tracer.d.ts.map +1 -0
  577. package/lib/testing/make-test-tracer.js +68 -0
  578. package/lib/testing/make-test-tracer.js.map +1 -0
  579. package/lib/testing/node/generated-workspace.d.ts +95 -0
  580. package/lib/testing/node/generated-workspace.d.ts.map +1 -0
  581. package/lib/testing/node/generated-workspace.js +134 -0
  582. package/lib/testing/node/generated-workspace.js.map +1 -0
  583. package/lib/testing/node/golden-corpus.d.ts +50 -0
  584. package/lib/testing/node/golden-corpus.d.ts.map +1 -0
  585. package/lib/testing/node/golden-corpus.js +80 -0
  586. package/lib/testing/node/golden-corpus.js.map +1 -0
  587. package/lib/testing/node/index.d.ts +28 -0
  588. package/lib/testing/node/index.d.ts.map +1 -0
  589. package/lib/testing/node/index.js +28 -0
  590. package/lib/testing/node/index.js.map +1 -0
  591. package/lib/testing/node/lsp-harness.d.ts +139 -0
  592. package/lib/testing/node/lsp-harness.d.ts.map +1 -0
  593. package/lib/testing/node/lsp-harness.js +119 -0
  594. package/lib/testing/node/lsp-harness.js.map +1 -0
  595. package/lib/testing/node/lsp-server-connection.d.ts +232 -0
  596. package/lib/testing/node/lsp-server-connection.d.ts.map +1 -0
  597. package/lib/testing/node/lsp-server-connection.js +304 -0
  598. package/lib/testing/node/lsp-server-connection.js.map +1 -0
  599. package/lib/testing/node/scratch-workspace.d.ts +60 -0
  600. package/lib/testing/node/scratch-workspace.d.ts.map +1 -0
  601. package/lib/testing/node/scratch-workspace.js +87 -0
  602. package/lib/testing/node/scratch-workspace.js.map +1 -0
  603. package/lib/testing/node/spawned-server.d.ts +170 -0
  604. package/lib/testing/node/spawned-server.d.ts.map +1 -0
  605. package/lib/testing/node/spawned-server.js +265 -0
  606. package/lib/testing/node/spawned-server.js.map +1 -0
  607. package/lib/testing/parse-semantic-root.d.ts +83 -0
  608. package/lib/testing/parse-semantic-root.d.ts.map +1 -0
  609. package/lib/testing/parse-semantic-root.js +119 -0
  610. package/lib/testing/parse-semantic-root.js.map +1 -0
  611. package/lib/testing/playwright/browser-capture-bridge.d.ts +80 -0
  612. package/lib/testing/playwright/browser-capture-bridge.d.ts.map +1 -0
  613. package/lib/testing/playwright/browser-capture-bridge.js +161 -0
  614. package/lib/testing/playwright/browser-capture-bridge.js.map +1 -0
  615. package/lib/testing/playwright/e2e-profiling.d.ts +132 -0
  616. package/lib/testing/playwright/e2e-profiling.d.ts.map +1 -0
  617. package/lib/testing/playwright/e2e-profiling.js +270 -0
  618. package/lib/testing/playwright/e2e-profiling.js.map +1 -0
  619. package/lib/testing/playwright/index.d.ts +13 -0
  620. package/lib/testing/playwright/index.d.ts.map +1 -0
  621. package/lib/testing/playwright/index.js +16 -0
  622. package/lib/testing/playwright/index.js.map +1 -0
  623. package/lib/testing/playwright/server-log-capture.d.ts +230 -0
  624. package/lib/testing/playwright/server-log-capture.d.ts.map +1 -0
  625. package/lib/testing/playwright/server-log-capture.js +336 -0
  626. package/lib/testing/playwright/server-log-capture.js.map +1 -0
  627. package/lib/testing/playwright/server-log-fixture.d.ts +36 -0
  628. package/lib/testing/playwright/server-log-fixture.d.ts.map +1 -0
  629. package/lib/testing/playwright/server-log-fixture.js +38 -0
  630. package/lib/testing/playwright/server-log-fixture.js.map +1 -0
  631. package/lib/testing/playwright/server-log-rename-reporter.d.ts +22 -0
  632. package/lib/testing/playwright/server-log-rename-reporter.d.ts.map +1 -0
  633. package/lib/testing/playwright/server-log-rename-reporter.js +26 -0
  634. package/lib/testing/playwright/server-log-rename-reporter.js.map +1 -0
  635. package/lib/testing/run-update-pipeline.d.ts +99 -0
  636. package/lib/testing/run-update-pipeline.d.ts.map +1 -0
  637. package/lib/testing/run-update-pipeline.js +24 -0
  638. package/lib/testing/run-update-pipeline.js.map +1 -0
  639. package/lib/testing/stub-ast-document-manager.d.ts +82 -0
  640. package/lib/testing/stub-ast-document-manager.d.ts.map +1 -0
  641. package/lib/testing/stub-ast-document-manager.js +125 -0
  642. package/lib/testing/stub-ast-document-manager.js.map +1 -0
  643. package/lib/testing/stub-document-builder.d.ts +99 -0
  644. package/lib/testing/stub-document-builder.d.ts.map +1 -0
  645. package/lib/testing/stub-document-builder.js +142 -0
  646. package/lib/testing/stub-document-builder.js.map +1 -0
  647. package/lib/testing/stub-hydranium-text-documents.d.ts +125 -0
  648. package/lib/testing/stub-hydranium-text-documents.d.ts.map +1 -0
  649. package/lib/testing/stub-hydranium-text-documents.js +164 -0
  650. package/lib/testing/stub-hydranium-text-documents.js.map +1 -0
  651. package/lib/testing/stub-index-manager.d.ts +40 -0
  652. package/lib/testing/stub-index-manager.d.ts.map +1 -0
  653. package/lib/testing/stub-index-manager.js +38 -0
  654. package/lib/testing/stub-index-manager.js.map +1 -0
  655. package/lib/testing/stub-langium-documents.d.ts +53 -0
  656. package/lib/testing/stub-langium-documents.d.ts.map +1 -0
  657. package/lib/testing/stub-langium-documents.js +62 -0
  658. package/lib/testing/stub-langium-documents.js.map +1 -0
  659. package/lib/testing/stub-model-service.d.ts +31 -0
  660. package/lib/testing/stub-model-service.d.ts.map +1 -0
  661. package/lib/testing/stub-model-service.js +45 -0
  662. package/lib/testing/stub-model-service.js.map +1 -0
  663. package/lib/testing/stub-project-manager.d.ts +43 -0
  664. package/lib/testing/stub-project-manager.d.ts.map +1 -0
  665. package/lib/testing/stub-project-manager.js +125 -0
  666. package/lib/testing/stub-project-manager.js.map +1 -0
  667. package/lib/testing/stub-self-save-registry.d.ts +31 -0
  668. package/lib/testing/stub-self-save-registry.d.ts.map +1 -0
  669. package/lib/testing/stub-self-save-registry.js +23 -0
  670. package/lib/testing/stub-self-save-registry.js.map +1 -0
  671. package/lib/testing/stub-service-registry.d.ts +95 -0
  672. package/lib/testing/stub-service-registry.d.ts.map +1 -0
  673. package/lib/testing/stub-service-registry.js +108 -0
  674. package/lib/testing/stub-service-registry.js.map +1 -0
  675. package/lib/testing/stub-writable-file-system.d.ts +42 -0
  676. package/lib/testing/stub-writable-file-system.d.ts.map +1 -0
  677. package/lib/testing/stub-writable-file-system.js +26 -0
  678. package/lib/testing/stub-writable-file-system.js.map +1 -0
  679. package/lib/util/connection-liveness.d.ts +25 -0
  680. package/lib/util/connection-liveness.d.ts.map +1 -0
  681. package/lib/util/connection-liveness.js +46 -0
  682. package/lib/util/connection-liveness.js.map +1 -0
  683. package/lib/util/environment.d.ts +53 -0
  684. package/lib/util/environment.d.ts.map +1 -0
  685. package/lib/util/environment.js +78 -0
  686. package/lib/util/environment.js.map +1 -0
  687. package/lib/util/index.d.ts +13 -0
  688. package/lib/util/index.d.ts.map +1 -0
  689. package/lib/util/index.js +18 -0
  690. package/lib/util/index.js.map +1 -0
  691. package/lib/util/registry.d.ts +88 -0
  692. package/lib/util/registry.d.ts.map +1 -0
  693. package/lib/util/registry.js +105 -0
  694. package/lib/util/registry.js.map +1 -0
  695. package/package.json +134 -0
  696. package/src/documents/ast-document-manager.ts +455 -0
  697. package/src/documents/client-ids.ts +33 -0
  698. package/src/documents/hydranium-text-documents.ts +1142 -0
  699. package/src/documents/index.ts +14 -0
  700. package/src/documents/language-client-text-shadow.ts +175 -0
  701. package/src/documents/self-save-registry.ts +81 -0
  702. package/src/index.ts +39 -0
  703. package/src/langium/ast-extension/ast-extension-contribution.ts +35 -0
  704. package/src/langium/ast-extension/ast-extension-service.ts +311 -0
  705. package/src/langium/ast-extension/ast-node-builder.ts +125 -0
  706. package/src/langium/ast-extension/index.ts +12 -0
  707. package/src/langium/bootstrap.ts +600 -0
  708. package/src/langium/build-phase-pass/build-phase-pass-service.ts +141 -0
  709. package/src/langium/build-phase-pass/build-phase-pass.ts +123 -0
  710. package/src/langium/build-phase-pass/index.ts +11 -0
  711. package/src/langium/config/index.ts +10 -0
  712. package/src/langium/config/settings.ts +353 -0
  713. package/src/langium/diagnostics/hydranium-langium-profiler.ts +187 -0
  714. package/src/langium/diagnostics/index.ts +19 -0
  715. package/src/langium/diagnostics/log-file-token.ts +26 -0
  716. package/src/langium/diagnostics/log-preamble.ts +87 -0
  717. package/src/langium/diagnostics/logger.ts +246 -0
  718. package/src/langium/diagnostics/lsp-logger.ts +277 -0
  719. package/src/langium/diagnostics/server-tracer.ts +73 -0
  720. package/src/langium/document-builder/build-pipeline-integration.ts +193 -0
  721. package/src/langium/document-builder/document-builder.ts +839 -0
  722. package/src/langium/document-builder/index.ts +12 -0
  723. package/src/langium/document-builder/labeled-phase-listener.ts +26 -0
  724. package/src/langium/documentation/comment-provider.ts +37 -0
  725. package/src/langium/documentation/index.ts +10 -0
  726. package/src/langium/integration-services.ts +281 -0
  727. package/src/langium/integrity/index.ts +12 -0
  728. package/src/langium/integrity/integrity-contribution.ts +44 -0
  729. package/src/langium/integrity/integrity-rule.ts +100 -0
  730. package/src/langium/integrity/integrity-service.ts +423 -0
  731. package/src/langium/keys/default-element-key-provider.ts +20 -0
  732. package/src/langium/keys/element-key-provider.ts +114 -0
  733. package/src/langium/keys/index.ts +13 -0
  734. package/src/langium/keys/name-based-key-provider.ts +146 -0
  735. package/src/langium/keys/positional-key-provider.ts +57 -0
  736. package/src/langium/labeling/index.ts +10 -0
  737. package/src/langium/labeling/label-provider.ts +110 -0
  738. package/src/langium/language-module.ts +367 -0
  739. package/src/langium/language-types.ts +214 -0
  740. package/src/langium/model-service/index.ts +10 -0
  741. package/src/langium/model-service/model-service.ts +1051 -0
  742. package/src/langium/module.ts +446 -0
  743. package/src/langium/naming/index.ts +11 -0
  744. package/src/langium/naming/name-provider.ts +533 -0
  745. package/src/langium/naming/name-separator-validation.ts +73 -0
  746. package/src/langium/project/abstract-project-manager.ts +630 -0
  747. package/src/langium/project/index.ts +13 -0
  748. package/src/langium/project/project-change-event.ts +66 -0
  749. package/src/langium/project/project-manager.ts +221 -0
  750. package/src/langium/project/single-project-manager.ts +126 -0
  751. package/src/langium/residency/cst-residency-service.ts +412 -0
  752. package/src/langium/residency/index.ts +10 -0
  753. package/src/langium/scope/ast-node-description-provider.ts +141 -0
  754. package/src/langium/scope/hydranium-scope-computation.ts +246 -0
  755. package/src/langium/scope/hydranium-scope-provider.ts +659 -0
  756. package/src/langium/scope/index.ts +18 -0
  757. package/src/langium/scope/reference-builder.ts +194 -0
  758. package/src/langium/scope/reference-candidate-provider.ts +314 -0
  759. package/src/langium/scope/scope-extension-contribution.ts +34 -0
  760. package/src/langium/scope/scope-extension-service.ts +207 -0
  761. package/src/langium/scope/scoped-ast-node-description.ts +174 -0
  762. package/src/langium/scope/tier-specificity.ts +89 -0
  763. package/src/langium/serialization/abstract-serializer.ts +474 -0
  764. package/src/langium/serialization/index.ts +14 -0
  765. package/src/langium/serialization/json-serializer.ts +264 -0
  766. package/src/langium/serialization/serialization-util.ts +40 -0
  767. package/src/langium/serialization/serializer.ts +68 -0
  768. package/src/langium/serialization/yaml-serializer.ts +348 -0
  769. package/src/langium/service-registry.ts +323 -0
  770. package/src/langium/shared-services.ts +107 -0
  771. package/src/langium/transfer/index.ts +10 -0
  772. package/src/langium/transfer/transfer-encoder.ts +434 -0
  773. package/src/langium/update-rewrite/index.ts +14 -0
  774. package/src/langium/update-rewrite/normalize-empty-strings.ts +86 -0
  775. package/src/langium/update-rewrite/semantic-root-rewrite.ts +57 -0
  776. package/src/langium/update-rewrite/update-rewrite-contribution.ts +44 -0
  777. package/src/langium/update-rewrite/update-rewrite-service.ts +129 -0
  778. package/src/langium/update-rewrite/update-rewrite.ts +60 -0
  779. package/src/langium/validation/document-validator.ts +188 -0
  780. package/src/langium/validation/index.ts +12 -0
  781. package/src/langium/validation/validation-contribution-collector.ts +61 -0
  782. package/src/langium/validation/validation-contribution.ts +38 -0
  783. package/src/langium/workspace/additional-document-contribution.ts +80 -0
  784. package/src/langium/workspace/document-uri-policy.ts +187 -0
  785. package/src/langium/workspace/file-system-provider.ts +52 -0
  786. package/src/langium/workspace/hydranium-langium-document-factory.ts +78 -0
  787. package/src/langium/workspace/hydranium-workspace-lock.ts +35 -0
  788. package/src/langium/workspace/hydranium-workspace-manager.ts +412 -0
  789. package/src/langium/workspace/in-memory-file-system-provider.ts +241 -0
  790. package/src/langium/workspace/index-manager.ts +266 -0
  791. package/src/langium/workspace/index.ts +23 -0
  792. package/src/langium/workspace/initialize-workspace.ts +102 -0
  793. package/src/langium/workspace/langium-documents.ts +94 -0
  794. package/src/langium/workspace/persistent-file-system-provider.ts +287 -0
  795. package/src/langium/workspace/synthetic.ts +63 -0
  796. package/src/langium/workspace/virtual-document.ts +94 -0
  797. package/src/langium/workspace/write-lock-scope.ts +88 -0
  798. package/src/launcher/index.ts +12 -0
  799. package/src/launcher/integrated-server.ts +28 -0
  800. package/src/lsp/completion/hydranium-completion-provider.ts +132 -0
  801. package/src/lsp/hydranium-document-update-handler.ts +345 -0
  802. package/src/lsp/index.ts +24 -0
  803. package/src/lsp/instrument-connection.ts +66 -0
  804. package/src/lsp/language-module.ts +64 -0
  805. package/src/lsp/semantic-token-provider.ts +215 -0
  806. package/src/lsp/shared-module.ts +88 -0
  807. package/src/lsp/start-language-server.ts +68 -0
  808. package/src/node/ast-ground-truth.ts +76 -0
  809. package/src/node/event-loop-monitor.ts +89 -0
  810. package/src/node/index.ts +53 -0
  811. package/src/node/latency-from-env.ts +39 -0
  812. package/src/node/lint-grammar.ts +189 -0
  813. package/src/node/log-file-sink.ts +43 -0
  814. package/src/node/log-preamble-node.ts +63 -0
  815. package/src/node/measure-memory.ts +196 -0
  816. package/src/node/memory-monitor.ts +103 -0
  817. package/src/node/node-file-system-provider.ts +252 -0
  818. package/src/node/process-memory.ts +299 -0
  819. package/src/node/profile-capture.ts +377 -0
  820. package/src/node/profile-digest.ts +112 -0
  821. package/src/node/profiling-run.ts +236 -0
  822. package/src/node/reflect-grammar.ts +182 -0
  823. package/src/node/server-diagnostics.ts +63 -0
  824. package/src/node/server-state-snapshot.ts +192 -0
  825. package/src/node/socket-launcher.ts +210 -0
  826. package/src/node/stdio-launcher.ts +150 -0
  827. package/src/node/validate-workspace.ts +133 -0
  828. package/src/node/write-lock-scope-node.ts +41 -0
  829. package/src/testing/ast-snapshot.ts +88 -0
  830. package/src/testing/document-uri-policy-conformance.ts +104 -0
  831. package/src/testing/fake-description.ts +52 -0
  832. package/src/testing/fake-document.ts +120 -0
  833. package/src/testing/fake-reflection.ts +39 -0
  834. package/src/testing/index.ts +45 -0
  835. package/src/testing/langium-test-helpers.ts +26 -0
  836. package/src/testing/make-noop-language-services.ts +47 -0
  837. package/src/testing/make-noop-shared-services.ts +78 -0
  838. package/src/testing/make-test-services.ts +356 -0
  839. package/src/testing/make-test-tracer.ts +92 -0
  840. package/src/testing/node/generated-workspace.ts +222 -0
  841. package/src/testing/node/golden-corpus.ts +114 -0
  842. package/src/testing/node/index.ts +29 -0
  843. package/src/testing/node/lsp-harness.ts +230 -0
  844. package/src/testing/node/lsp-server-connection.ts +575 -0
  845. package/src/testing/node/scratch-workspace.ts +137 -0
  846. package/src/testing/node/spawned-server.ts +447 -0
  847. package/src/testing/parse-semantic-root.ts +150 -0
  848. package/src/testing/playwright/browser-capture-bridge.ts +258 -0
  849. package/src/testing/playwright/e2e-profiling.ts +362 -0
  850. package/src/testing/playwright/index.ts +16 -0
  851. package/src/testing/playwright/server-log-capture.ts +433 -0
  852. package/src/testing/playwright/server-log-fixture.ts +57 -0
  853. package/src/testing/playwright/server-log-rename-reporter.ts +29 -0
  854. package/src/testing/run-update-pipeline.ts +113 -0
  855. package/src/testing/stub-ast-document-manager.ts +224 -0
  856. package/src/testing/stub-document-builder.ts +242 -0
  857. package/src/testing/stub-hydranium-text-documents.ts +270 -0
  858. package/src/testing/stub-index-manager.ts +79 -0
  859. package/src/testing/stub-langium-documents.ts +104 -0
  860. package/src/testing/stub-model-service.ts +72 -0
  861. package/src/testing/stub-project-manager.ts +161 -0
  862. package/src/testing/stub-self-save-registry.ts +43 -0
  863. package/src/testing/stub-service-registry.ts +192 -0
  864. package/src/testing/stub-writable-file-system.ts +58 -0
  865. package/src/util/connection-liveness.ts +47 -0
  866. package/src/util/environment.ts +88 -0
  867. package/src/util/index.ts +18 -0
  868. package/src/util/registry.ts +129 -0
@@ -0,0 +1,1142 @@
1
+ /********************************************************************************
2
+ * Copyright (c) 2026 CrossBreeze, EclipseSource and others.
3
+ * Copyright (c) Microsoft Corporation and EclipseSource. All rights reserved.
4
+ *
5
+ * This program and the accompanying materials are made available under the
6
+ * terms of the MIT License which is available in the project root.
7
+ *
8
+ * SPDX-License-Identifier: MIT
9
+ ********************************************************************************/
10
+
11
+ // Adapted from Langium's `NormalizedTextDocuments`, itself an adaptation of
12
+ // Microsoft's `TextDocuments` — hence the Microsoft copyright above. The
13
+ // `listen()` override below follows that handler-registration sequence:
14
+ // https://github.com/microsoft/vscode-languageserver-node/blob/8f5fa710d3a9f60ff5e7583a9e61b19f86e39da3/server/src/common/textDocuments.ts
15
+
16
+ // Deliberate exception to `@hydranium/core`'s no-runtime-langium/lsp rule:
17
+ // this class IS the shared LSP-style document-sync primitive that every
18
+ // protocol head (lsp-server, data-server, glsp-server) coordinates through.
19
+ // Moving it into lsp-server would force data-server / glsp-server to depend
20
+ // on lsp-server, contradicting the peer architecture.
21
+ // eslint-disable-next-line @typescript-eslint/no-restricted-imports
22
+ import { NormalizedTextDocuments } from '@hydranium/langium/lsp';
23
+ import { UriUtils } from '@hydranium/langium';
24
+ import { type ServerSharedServices } from '../langium/module.js';
25
+ import {
26
+ type ApplyWorkspaceEditResult,
27
+ type CancellationToken,
28
+ type Connection,
29
+ type DidChangeTextDocumentParams,
30
+ type DidCloseTextDocumentParams,
31
+ type DidOpenTextDocumentParams,
32
+ type DidSaveTextDocumentParams,
33
+ type Disposable,
34
+ type Emitter,
35
+ type Event,
36
+ type HandlerResult,
37
+ OptionalVersionedTextDocumentIdentifier,
38
+ type RequestHandler,
39
+ type TextDocumentChangeEvent,
40
+ TextDocumentEdit,
41
+ TextDocumentSyncKind,
42
+ type TextDocumentWillSaveEvent,
43
+ type TextDocumentsConfiguration,
44
+ type TextEdit,
45
+ type WillSaveTextDocumentParams
46
+ } from 'vscode-languageserver';
47
+ import { type DocumentUri, TextDocument, type TextDocumentContentChangeEvent } from 'vscode-languageserver-textdocument';
48
+ import { type CanonicalUri, type LanguageClientUri, asLanguageClientUri, DisposableCollection, type Tracer } from '@hydranium/protocol';
49
+ import { type LogNameOptions } from '../langium/diagnostics/logger.js';
50
+ import { LANGUAGE_CLIENT_ID } from './client-ids.js';
51
+ import { isFullReplace, LanguageClientTextShadow } from './language-client-text-shadow.js';
52
+
53
+ /**
54
+ * The LSP spec's "version is intentionally unknown" for an
55
+ * {@link OptionalVersionedTextDocumentIdentifier} is `null`, but
56
+ * `OptionalVersionedTextDocumentIdentifier.create` requires `number` in its TS
57
+ * signature — so the null routes through this one typed bridge rather than a
58
+ * cast at each call site.
59
+ */
60
+ const UNKNOWN_CLIENT_VERSION = null as unknown as number;
61
+
62
+ export interface ClientTextDocumentChangeEvent<T> extends TextDocumentChangeEvent<T> {
63
+ clientId: string;
64
+ }
65
+
66
+ /**
67
+ * Construction options for {@link HydraniumTextDocuments}. All fields optional —
68
+ * defaults reproduce the framework's behaviour exactly.
69
+ */
70
+ export interface HydraniumTextDocumentsOptions<T extends TextDocument = TextDocument> extends LogNameOptions {
71
+ /**
72
+ * Factory for the text-document type `T` (provides `create` / `update`).
73
+ * Defaults to `TextDocument` from `vscode-languageserver-textdocument`.
74
+ * Adopters with a custom text-document type (rare) pass their factory.
75
+ */
76
+ readonly configuration?: TextDocumentsConfiguration<T>;
77
+ }
78
+
79
+ /**
80
+ * All per-URI client-facing tracking the manager keys by normalized URI,
81
+ * collapsed into one record so a URI's full state lives in one place and the
82
+ * last-client close clears every axis in a single delete. (Parallel per-axis
83
+ * maps are the substrate of a close-on-stale-state desync — one map can be
84
+ * cleared while another lingers.)
85
+ *
86
+ * Two neighbours deliberately stay separate:
87
+ * - The inherited `__syncedDocuments` (Langium's parsed `TextDocument` store).
88
+ * - {@link LanguageClientTextShadow} (`__shadow`), a self-contained,
89
+ * separately-tested diff/apply-verify abstraction that owns its own baseline
90
+ * text; folding its storage here would couple a clean utility to this record
91
+ * for no real gain.
92
+ */
93
+ interface DocumentTracking {
94
+ /** Client ids currently holding this document open (multi-client membership). */
95
+ readonly clients: Set<string>;
96
+ /** Author of each version, sparse-indexed by the SHARED (server-assigned) version number. */
97
+ readonly versionAuthors: string[];
98
+ /**
99
+ * Last version id each client declared for this document (didOpen baseline,
100
+ * advanced by every accepted didChange). Client version ids are CLIENT-owned
101
+ * per LSP (Monaco numbers its own buffer) and are used ONLY for this
102
+ * per-client staleness guard — they never leak into the shared version
103
+ * sequence, which the server assigns (see {@link HydraniumTextDocuments.__versionSequences}).
104
+ */
105
+ readonly clientVersions: Map<string, number>;
106
+ /** Content staged by integrity rules for a closed document. Consumed on next open. */
107
+ pendingContent?: string;
108
+ /**
109
+ * The URI(s) the LSP textual language client opened this (canonically-keyed)
110
+ * document under. Usually one; a set because the same physical file can be
111
+ * opened under more than one URI (a symlink path and its real path). This is
112
+ * the egress address: `applyEditToLanguageClient`
113
+ * targets these, since the document is *keyed* by its canonical identity but
114
+ * Monaco holds it under the URI it opened. Lifecycle-bound — cleared with the
115
+ * record on last close.
116
+ */
117
+ languageClientUris?: Set<LanguageClientUri>;
118
+ }
119
+
120
+ /**
121
+ * A document held open by at least one client, with the client ids holding it —
122
+ * one entry of {@link HydraniumTextDocuments.openDocuments}.
123
+ */
124
+ export interface OpenDocument {
125
+ /** Canonical identity the store keys the document by. */
126
+ readonly uri: CanonicalUri;
127
+ /** Client ids currently holding the document open (never empty). */
128
+ readonly clients: readonly string[];
129
+ }
130
+
131
+ /**
132
+ * Where a URI's shared version sequence left off — written once at last-client
133
+ * close, consulted at the next open so the sequence CONTINUES instead of
134
+ * restarting at whatever version id the reopening client declares. One entry
135
+ * of {@link HydraniumTextDocuments.__versionSequences}.
136
+ */
137
+ interface VersionSequence {
138
+ /** The shared version at last-client close. */
139
+ readonly version: number;
140
+ /** {@link contentHash} of the synced text at last-client close. */
141
+ readonly contentHash: string;
142
+ }
143
+
144
+ /**
145
+ * Upper bound on {@link HydraniumTextDocuments.__pendingPushes} entries
146
+ * per URI. Echoes normally return within milliseconds and consume their
147
+ * entry; a queue this deep means the client stopped echoing — cap instead
148
+ * of leaking.
149
+ */
150
+ const PENDING_ECHO_CAP = 32;
151
+
152
+ /**
153
+ * The one field of `vscode-languageserver`'s `Connection` this class has to
154
+ * reach that its public type does not declare. Named here rather than cast
155
+ * inline so the write states which shape it assumes.
156
+ */
157
+ interface ConnectionWithTextDocumentSync {
158
+ __textDocumentSync?: TextDocumentSyncKind;
159
+ }
160
+
161
+ /**
162
+ * One text pushed to the LSP textual language client by
163
+ * {@link HydraniumTextDocuments.applyEditToLanguageClient} whose echo has not
164
+ * come back yet. One entry of {@link HydraniumTextDocuments.__pendingPushes}.
165
+ */
166
+ interface PendingPush {
167
+ /**
168
+ * The text the client held BEFORE this push — the shadow baseline the
169
+ * push's edits were diffed against, and therefore the text the client's
170
+ * echo addresses with its ranges.
171
+ *
172
+ * `undefined` when the push was a full replace sent with no baseline (a
173
+ * first sync, or the recovery push after a rejection). There is then no
174
+ * knowing what the client held, so the echo is reconstructed against the
175
+ * synced text instead — which is sound for a full replace, whose
176
+ * application is position-independent.
177
+ */
178
+ readonly before: string | undefined;
179
+ /** {@link contentHash} of the text this push moves the client to. */
180
+ readonly afterHash: string;
181
+ }
182
+
183
+ /**
184
+ * What an incoming language-client change turns out to be once reconstructed
185
+ * against the pushes still in flight — the return of
186
+ * {@link HydraniumTextDocuments.classifyLanguageClientChange}.
187
+ */
188
+ type LanguageClientChangeOrigin =
189
+ /** The client is reporting a text we pushed it. The synced document is already there. */
190
+ | { readonly kind: 'echo' }
191
+ /**
192
+ * The client's buffer has moved somewhere we did not push it — it coalesced
193
+ * a genuine keystroke into the echo, or typed before the push arrived. The
194
+ * reconstructed text is what it now holds, and is authoritative.
195
+ */
196
+ | { readonly kind: 'divergent'; readonly text: string };
197
+
198
+ /**
199
+ * Cheap, stable, non-cryptographic content hash (cyrb53) for the version
200
+ * sequence's "did the content change across close/reopen?" question. Only
201
+ * needs to be collision-resistant enough that an accidental match across two
202
+ * DIFFERENT revisions of the same file is practically impossible; 53 bits of
203
+ * a well-mixed hash over full text + length gives that without pulling in
204
+ * `node:crypto` (this module must stay runnable in browser hosts).
205
+ */
206
+ function contentHash(text: string): string {
207
+ let h1 = 0xdeadbeef;
208
+ let h2 = 0x41c6ce57;
209
+ for (let index = 0; index < text.length; index++) {
210
+ const code = text.charCodeAt(index);
211
+ h1 = Math.imul(h1 ^ code, 2654435761);
212
+ h2 = Math.imul(h2 ^ code, 1597334677);
213
+ }
214
+ h1 = Math.imul(h1 ^ (h1 >>> 16), 2246822507);
215
+ h1 ^= Math.imul(h2 ^ (h2 >>> 13), 3266489909);
216
+ h2 = Math.imul(h2 ^ (h2 >>> 16), 2246822507);
217
+ h2 ^= Math.imul(h1 ^ (h1 >>> 13), 3266489909);
218
+ return `${(4294967296 * (2097151 & h2) + (h1 >>> 0)).toString(36)}:${text.length}`;
219
+ }
220
+
221
+ /**
222
+ * Multi-client text-document tracking on top of Langium's `NormalizedTextDocuments`.
223
+ *
224
+ * Adds the framework features used by the integrity, model-server, and GLSP layers:
225
+ * - Per-document client membership (multiple clients can attach to the same URI).
226
+ * - A SERVER-OWNED shared version sequence: per-URI, monotonic across
227
+ * close/reopen cycles, advancing exactly when the synced content changes.
228
+ * Client-declared version ids (Monaco's buffer numbering) feed only a
229
+ * per-client staleness guard and never leak into the shared sequence —
230
+ * the two are different things (an editor's edit-operation counter vs the
231
+ * document's content-revision number), and splicing them lets versions drift
232
+ * silently past `baseVersion` gate holders.
233
+ * - Version-author history so each edit is attributable to its originating client.
234
+ * - Pending-content staging used by the integrity service to thread corrections
235
+ * through `workspace/applyEdit` cycles for currently-closed documents.
236
+ * - `didOpen` notifications arriving over the LSP connection wait on the
237
+ * workspace-ready promise, so a client's first open cannot race workspace
238
+ * discovery. Direct {@link notifyDidOpenTextDocument} calls (the non-LSP
239
+ * heads) do not pass that gate — their caller owns the ordering.
240
+ */
241
+ export class HydraniumTextDocuments<T extends TextDocument = TextDocument> extends NormalizedTextDocuments<T> {
242
+ /**
243
+ * Per-URI client-facing tracking ({@link DocumentTracking}): client
244
+ * membership, version-author history, and integrity-staged pending content,
245
+ * keyed by normalized URI. One record per URI so the last-client close clears
246
+ * every axis atomically. The language-client diff baseline stays in
247
+ * {@link __shadow} (its own abstraction); the parsed-document store stays in
248
+ * the inherited `__syncedDocuments`.
249
+ */
250
+ protected __documents = new Map<CanonicalUri, DocumentTracking>();
251
+
252
+ /**
253
+ * Per-URI shared-version continuity across close/reopen cycles
254
+ * ({@link VersionSequence}), written at last-client close and consulted by
255
+ * the next first-client open. DELIBERATELY outside {@link DocumentTracking}:
256
+ * that record is deleted on last close, while the version sequence must
257
+ * survive it — the shared version is a server-owned, monotonic,
258
+ * advances-iff-content-changes counter that never resets while the server
259
+ * lives. That invariant is what makes an optimistic `baseVersion` gate
260
+ * sound: "version unchanged ⇔ content unchanged", with no false conflicts
261
+ * from close/reopen version resets and no false passes from a reopened
262
+ * sequence coincidentally landing on a stale writer's number.
263
+ *
264
+ * Never pruned: two small values per URI ever touched — bounded by
265
+ * workspace size, not by activity.
266
+ */
267
+ protected readonly __versionSequences = new Map<CanonicalUri, VersionSequence>();
268
+
269
+ /**
270
+ * Texts pushed to the LSP textual language client via
271
+ * {@link applyEditToLanguageClient} whose echoes have not come back yet
272
+ * ({@link PendingPush}), keyed like the shadow by language-client URI.
273
+ * Outbound pushes and inbound echoes are uncorrelated on the wire; this
274
+ * FIFO is the explicit correlation, and it is what
275
+ * {@link classifyLanguageClientChange} reconstructs against.
276
+ *
277
+ * **Each entry keeps the client's PRE-push text, not only a hash of the
278
+ * post-push one.** A hash alone can classify a full-text echo, whose
279
+ * application is a no-op either way — and that is all it ever classified,
280
+ * because a conforming client echoes INCREMENTAL ranges keyed to its
281
+ * previous buffer. Those ranges cannot be applied to the synced text (which
282
+ * the authored write already advanced) and cannot be reconstructed without
283
+ * the baseline: the line they insert lands twice, validates cleanly, and
284
+ * compounds on every later edit.
285
+ *
286
+ * Lifecycle: entries are consumed by the matching echo (together with any
287
+ * older entries it supersedes), and the whole queue drops when the client
288
+ * stops being a pure mirror — a divergent change, an `applyEdit`
289
+ * failure/rejection (shadow invalidation), a close, or an explicit
290
+ * shadow (re)baseline. {@link PENDING_ECHO_CAP} bounds the queue against
291
+ * a pathological echo that never arrives; the memory cost until then is
292
+ * one pre-push text per in-flight push, for milliseconds.
293
+ */
294
+ protected readonly __pendingPushes = new Map<LanguageClientUri, PendingPush[]>();
295
+
296
+ /**
297
+ * Tracked text content per URI for the LSP textual language client (Monaco / VS Code).
298
+ * Owned here so {@link applyEditToLanguageClient} can compute minimal `workspace/applyEdit`
299
+ * diffs instead of full-document replaces (5–20 s → <500 ms on 20-30 KB YAML diagrams).
300
+ *
301
+ * Auto-tracked from the multi-client text-document events: open / change / close of
302
+ * the language client (re)baseline or invalidate the shadow. Other client ids
303
+ * (form editor, GLSP, integrity) do NOT touch the shadow — only what Monaco believes
304
+ * it has matters for the diff.
305
+ *
306
+ * Apply-verify safety net is built in: if the diff doesn't reconstruct `newText`
307
+ * exactly, {@link LanguageClientTextShadow.computeEdits} falls back to a full-range
308
+ * replace and invokes the `onFallback` callback — a diff regression becomes log
309
+ * noise, not a 0-byte save.
310
+ *
311
+ * Assigned in the constructor body so the `onFallback` callback can capture
312
+ * `this.logger` after the parameter-property assignment has run (field
313
+ * initializers fire BEFORE parameter-property assignment in TS).
314
+ */
315
+ protected readonly __shadow: LanguageClientTextShadow;
316
+
317
+ protected readonly tracer: Tracer;
318
+ protected readonly configuration: TextDocumentsConfiguration<T>;
319
+
320
+ constructor(
321
+ protected services: ServerSharedServices,
322
+ options: HydraniumTextDocumentsOptions<T> = {}
323
+ ) {
324
+ const configuration = options.configuration ?? (TextDocument as unknown as TextDocumentsConfiguration<T>);
325
+ super(configuration);
326
+ this.configuration = configuration;
327
+ this.tracer = services.Tracer.for(options.logName ?? 'TextDocuments').trace('instantiated');
328
+ this.__shadow = new LanguageClientTextShadow(
329
+ (uri, reason) => this.tracer.with(uri).warn(`Diff apply-verify fallback (${reason}) — using full-document replace`),
330
+ this
331
+ );
332
+ }
333
+
334
+ // Re-exposed configuration factories — for framework-internal callers
335
+ // (LanguageClientTextShadow's apply-verify probe; IntegrityService.resyncDocument)
336
+ // that need to materialise documents outside the canonical didOpen/didChange flow
337
+ // and must respect the adopter's custom text-document type.
338
+
339
+ public create(uri: string, languageId: string, version: number, content: string): T {
340
+ return this.configuration.create(uri, languageId, version, content);
341
+ }
342
+
343
+ public update(document: T, changes: TextDocumentContentChangeEvent[], version: number): T {
344
+ return this.configuration.update(document, changes, version);
345
+ }
346
+
347
+ protected get __syncedDocuments(): Map<string, T> {
348
+ return this['_syncedDocuments'];
349
+ }
350
+
351
+ protected get __onDidChangeContent(): Emitter<ClientTextDocumentChangeEvent<T>> {
352
+ return this['_onDidChangeContent'];
353
+ }
354
+
355
+ override get onDidChangeContent(): Event<ClientTextDocumentChangeEvent<T>> {
356
+ return this.__onDidChangeContent.event;
357
+ }
358
+
359
+ protected get __onDidOpen(): Emitter<ClientTextDocumentChangeEvent<T>> {
360
+ return this['_onDidOpen'];
361
+ }
362
+
363
+ override get onDidOpen(): Event<ClientTextDocumentChangeEvent<T>> {
364
+ return this.__onDidOpen.event;
365
+ }
366
+
367
+ protected get __onDidClose(): Emitter<ClientTextDocumentChangeEvent<T>> {
368
+ return this['_onDidClose'];
369
+ }
370
+
371
+ override get onDidClose(): Event<ClientTextDocumentChangeEvent<T>> {
372
+ return this.__onDidClose.event;
373
+ }
374
+
375
+ protected get __onDidSave(): Emitter<ClientTextDocumentChangeEvent<T>> {
376
+ return this['_onDidSave'];
377
+ }
378
+
379
+ override get onDidSave(): Event<ClientTextDocumentChangeEvent<T>> {
380
+ return this['__onDidSave'].event;
381
+ }
382
+
383
+ protected get __onWillSave(): Emitter<TextDocumentWillSaveEvent<T>> {
384
+ return this['_onWillSave'];
385
+ }
386
+
387
+ protected get __willSaveWaitUntil(): RequestHandler<TextDocumentWillSaveEvent<T>, TextEdit[], void> | undefined {
388
+ return this['_willSaveWaitUntil'];
389
+ }
390
+
391
+ public override listen(connection: Connection): Disposable {
392
+ // The advertised `textDocumentSync` capability is read off this field
393
+ // while `initialize` is answered, and it falls back to
394
+ // `TextDocumentSyncKind.None` when the field holds anything but a number
395
+ // — at which point the client stops sending change notifications at all
396
+ // and every document goes stale after its first open. Upstream's own
397
+ // `TextDocuments.listen` performs this write; replacing that class means
398
+ // taking it over. The field is private to `vscode-languageserver`, so on
399
+ // a bump of the pinned wire chain re-check that it still exists: a rename
400
+ // makes this line a silent no-op, whose symptom is no `didChange` traffic
401
+ // rather than an error.
402
+ (connection as unknown as ConnectionWithTextDocumentSync).__textDocumentSync = TextDocumentSyncKind.Incremental;
403
+ const disposables = new DisposableCollection();
404
+ disposables.push(
405
+ connection.onDidOpenTextDocument(async (event: DidOpenTextDocumentParams) => {
406
+ await this.services.workspace.WorkspaceManager.workspaceInitialized;
407
+ this.notifyDidOpenTextDocument(event);
408
+ })
409
+ );
410
+ disposables.push(
411
+ connection.onDidChangeTextDocument((event: DidChangeTextDocumentParams) => {
412
+ this.notifyDidChangeTextDocument(event);
413
+ })
414
+ );
415
+ disposables.push(
416
+ connection.onDidCloseTextDocument((event: DidCloseTextDocumentParams) => {
417
+ this.notifyDidCloseTextDocument(event);
418
+ })
419
+ );
420
+ disposables.push(
421
+ connection.onWillSaveTextDocument((event: WillSaveTextDocumentParams) => {
422
+ this.notifyWillSaveTextDocument(event);
423
+ })
424
+ );
425
+ disposables.push(
426
+ connection.onWillSaveTextDocumentWaitUntil((event: WillSaveTextDocumentParams, token: CancellationToken) =>
427
+ this.notifyWillSaveTextDocumentWaitUntil(event, token)
428
+ )
429
+ );
430
+ disposables.push(
431
+ connection.onDidSaveTextDocument((event: DidSaveTextDocumentParams) => {
432
+ this.notifyDidSaveTextDocument(event);
433
+ })
434
+ );
435
+ return disposables;
436
+ }
437
+
438
+ public notifyDidChangeTextDocument(event: DidChangeTextDocumentParams, clientId = LANGUAGE_CLIENT_ID): void {
439
+ const td = event.textDocument;
440
+ const changes = event.contentChanges;
441
+ if (changes.length === 0) {
442
+ return;
443
+ }
444
+
445
+ const { version } = td;
446
+ if (version === null || version === undefined) {
447
+ throw new Error(`Received document change event for ${td.uri} without valid version identifier`);
448
+ }
449
+
450
+ const uri = this.documentKey(td.uri);
451
+ let document = this.__syncedDocuments.get(uri);
452
+ if (document !== undefined) {
453
+ // Per-client staleness guard: client version ids are CLIENT-owned per
454
+ // LSP (Monaco numbers its own buffer), so an incoming id is compared
455
+ // against THAT client's last declared id — never against the shared
456
+ // version, which the server assigns and which routinely runs ahead of
457
+ // a client's ids (authored ModelService writes advance it without the
458
+ // client knowing). Gating on the shared version drops real edits in
459
+ // exactly that lag window. A client with no baseline (never opened —
460
+ // a protocol anomaly) falls back to the shared-version compare, the
461
+ // conservative answer.
462
+ const record = this.trackingFor(uri);
463
+ const lastSeen = record.clientVersions.get(clientId) ?? document.version;
464
+ if (lastSeen >= td.version) {
465
+ // Distinguish "already at this version" (common: an echo from the client that triggered
466
+ // the update) from "incoming version older than ours" (stale race).
467
+ const reason =
468
+ lastSeen === td.version ? `already at version ${lastSeen}` : `incoming version ${td.version} older than current ${lastSeen}`;
469
+ this.logUri(uri, `Ignore update by ${clientId}: ${reason}`, 'debug');
470
+ return;
471
+ }
472
+ record.clientVersions.set(clientId, td.version);
473
+
474
+ // A language-client change arriving while one of our own pushes is in
475
+ // flight is keyed to the buffer the client held BEFORE that push, NOT
476
+ // to the synced text — the authored write already advanced the latter.
477
+ // Resolve which it is, and against what, before touching anything.
478
+ const inFlight =
479
+ clientId === LANGUAGE_CLIENT_ID
480
+ ? this.classifyLanguageClientChange(this.toLanguageClientUri(td.uri), document, changes)
481
+ : undefined;
482
+ if (inFlight?.kind === 'echo') {
483
+ // The client is reporting a text we pushed it, so the synced
484
+ // document is ALREADY there and the changes must not be applied a
485
+ // second time. Nothing is minted and no rebuild fires. The
486
+ // per-client baseline advanced above (the client's ids keep
487
+ // counting); the shadow is deliberately NOT touched — it
488
+ // optimistically tracks the NEWEST pushed text, and dragging it
489
+ // back would make the next outbound diff wrong against what the
490
+ // client actually holds.
491
+ this.logUri(uri, `Skip rebuild: echo of a server-authored push (client version ${td.version})`, 'debug');
492
+ return;
493
+ }
494
+
495
+ // The SHARED version advances iff the content actually changes — the
496
+ // invariant optimistic `baseVersion` gates rely on. The new text is
497
+ // only known after applying the (possibly incremental) changes, so
498
+ // apply at a tentative +1 and roll the version back on an identical
499
+ // result (an empty-changes update only re-stamps the version).
500
+ //
501
+ // A divergent in-flight change is applied as its RECONSTRUCTED text
502
+ // rather than as its own ranges: the ranges address the pre-push
503
+ // baseline, so applying them here would splice the wrong lines.
504
+ const previousText = document.getText();
505
+ const sharedVersion = document.version;
506
+ document = this.configuration.update(document, inFlight === undefined ? changes : [{ text: inFlight.text }], sharedVersion + 1);
507
+ const changed = document.getText() !== previousText;
508
+ if (!changed) {
509
+ document = this.configuration.update(document, [], sharedVersion);
510
+ }
511
+ this.__syncedDocuments.set(uri, document);
512
+ if (changed) {
513
+ this.setAuthor(uri, document.version, clientId);
514
+ }
515
+ if (clientId === LANGUAGE_CLIENT_ID) {
516
+ // Monaco just told us about its new content; record it so the next outbound
517
+ // applyEditToLanguageClient diffs against the right baseline. Keyed by the
518
+ // language-client URI (what Monaco holds), not the canonical document key.
519
+ this.__shadow.set(this.toLanguageClientUri(td.uri), document.getText());
520
+ // Content-identical echo: the language client is echoing text we already had
521
+ // (e.g. Monaco re-emitting a server-pushed applyEditToLanguageClient). The model is
522
+ // unchanged, so skip the rebuild. The per-client baseline + shadow still advanced
523
+ // above so future staleness checks and diffs are correct. Restricted to the
524
+ // language client: a ModelService-authored change is never skipped.
525
+ if (!changed) {
526
+ this.logUri(uri, `Skip rebuild: content unchanged (echo at client version ${td.version})`, 'debug');
527
+ return;
528
+ }
529
+ }
530
+ this.log(document.uri, `Update to version ${document.version} by ${clientId}${changed ? '' : ' (content unchanged)'}`);
531
+ this.__onDidChangeContent.fire(Object.freeze({ document, clientId }));
532
+ }
533
+ }
534
+
535
+ /**
536
+ * Apply a full-text content change authored server-side (ModelService /
537
+ * GLSP / integrity — any writer that is not an LSP wire client). The store
538
+ * assigns the shared version itself: step iff `text` differs from the
539
+ * current synced content, keep otherwise. Contrast
540
+ * {@link notifyDidChangeTextDocument}, the LSP wire path, where the client
541
+ * declares ITS version id and that id feeds only the per-client staleness
542
+ * guard.
543
+ *
544
+ * A content-identical write still fires the change event (rebuild): the
545
+ * authored write's server-side rebuild is correctness-bearing, it just
546
+ * mints no new version — nothing observable changed, so watchers'
547
+ * `baseVersion` pointers stay valid.
548
+ *
549
+ * Returns the resulting shared version. Throws when the document is not
550
+ * open — callers (`AstDocumentManager.update`) open first.
551
+ */
552
+ applyContentChange(uri: DocumentUri, text: string, clientId: string): number {
553
+ const key = this.documentKey(uri);
554
+ let document = this.__syncedDocuments.get(key);
555
+ if (document === undefined) {
556
+ throw new Error(`Document ${uri} is not open for content changes`);
557
+ }
558
+ const changed = document.getText() !== text;
559
+ if (changed) {
560
+ document = this.configuration.update(document, [{ text }], document.version + 1);
561
+ this.__syncedDocuments.set(key, document);
562
+ this.setAuthor(key, document.version, clientId);
563
+ }
564
+ this.log(document.uri, `Update to version ${document.version} by ${clientId}${changed ? '' : ' (content unchanged)'}`);
565
+ this.__onDidChangeContent.fire(Object.freeze({ document, clientId }));
566
+ return document.version;
567
+ }
568
+
569
+ public notifyDidCloseTextDocument(event: DidCloseTextDocumentParams, clientId = LANGUAGE_CLIENT_ID): void {
570
+ const uri = this.documentKey(event.textDocument.uri);
571
+ if (!this.isOpenInClient(uri, clientId)) {
572
+ return;
573
+ }
574
+ const closingRecord = this.__documents.get(uri);
575
+ closingRecord?.clients.delete(clientId);
576
+ closingRecord?.clientVersions.delete(clientId);
577
+ const syncedDocument = this.__syncedDocuments.get(uri);
578
+ if (syncedDocument !== undefined) {
579
+ this.log(syncedDocument.uri, `Closed synced document: ${syncedDocument.version} by ${clientId}`);
580
+ this.__onDidClose.fire(Object.freeze({ document: syncedDocument, clientId }));
581
+
582
+ if (clientId === LANGUAGE_CLIENT_ID) {
583
+ // Monaco closed the document; drop the URI it held and the shadow
584
+ // baselined under it. (If this was the last URI/client the whole record
585
+ // is deleted below, clearing the set anyway.)
586
+ const droppedUri = this.toLanguageClientUri(event.textDocument.uri);
587
+ this.__documents.get(uri)?.languageClientUris?.delete(droppedUri);
588
+ this.__shadow.invalidate(droppedUri);
589
+ this.__pendingPushes.delete(droppedUri);
590
+ }
591
+ if (!this.__documents.get(uri)?.clients.size) {
592
+ // Last client closed the document; delete sync state. The downstream
593
+ // "rebuild from disk for file URIs / drop from index for ephemeral
594
+ // URIs" decision lives in `HydraniumDocumentUpdateHandler.didCloseDocument`,
595
+ // which subscribes to `onDidClose` and consults `isOpenInAnyClient`
596
+ // to detect the last-close transition.
597
+ this.log(syncedDocument.uri, `Remove synced document: ${syncedDocument.version} (no client left)`);
598
+ // Persist where the shared version sequence left off (version +
599
+ // content hash) so the next open CONTINUES the sequence instead of
600
+ // restarting at the reopening client's declared id. Hashed once
601
+ // here at close, not on every change.
602
+ this.__versionSequences.set(uri, {
603
+ version: syncedDocument.version,
604
+ contentHash: contentHash(syncedDocument.getText())
605
+ });
606
+ this.__syncedDocuments.delete(uri);
607
+ // One delete clears every per-URI axis (version history + any staged
608
+ // pending content) so a future open with the same URI starts fresh.
609
+ this.__documents.delete(uri);
610
+ }
611
+ }
612
+ }
613
+
614
+ public notifyWillSaveTextDocument(event: WillSaveTextDocumentParams): void {
615
+ const syncedDocument = this.__syncedDocuments.get(this.documentKey(event.textDocument.uri));
616
+ if (syncedDocument !== undefined) {
617
+ this.__onWillSave.fire(Object.freeze({ document: syncedDocument, reason: event.reason }));
618
+ }
619
+ }
620
+
621
+ public notifyWillSaveTextDocumentWaitUntil(
622
+ event: WillSaveTextDocumentParams,
623
+ token: CancellationToken
624
+ ): HandlerResult<TextEdit[], void> {
625
+ const syncedDocument = this.__syncedDocuments.get(this.documentKey(event.textDocument.uri));
626
+ if (syncedDocument !== undefined && this.__willSaveWaitUntil) {
627
+ return this.__willSaveWaitUntil(Object.freeze({ document: syncedDocument, reason: event.reason }), token);
628
+ } else {
629
+ return [];
630
+ }
631
+ }
632
+
633
+ public notifyDidSaveTextDocument(event: DidSaveTextDocumentParams, clientId = LANGUAGE_CLIENT_ID): void {
634
+ const syncedDocument = this.__syncedDocuments.get(this.documentKey(event.textDocument.uri));
635
+ if (syncedDocument !== undefined) {
636
+ this.log(syncedDocument.uri, `Saved synced document: ${syncedDocument.version} by ${clientId}`);
637
+ this.__onDidSave.fire(Object.freeze({ document: syncedDocument, clientId }));
638
+ }
639
+ }
640
+
641
+ public notifyDidOpenTextDocument(event: DidOpenTextDocumentParams, clientId = LANGUAGE_CLIENT_ID): void {
642
+ const td = event.textDocument;
643
+ const uri = this.documentKey(td.uri);
644
+ if (this.isOpenInClient(uri, clientId)) {
645
+ // Already open for this client under this canonical identity. If this is a
646
+ // NEW client-facing URI for the same file (a second tab reached via a
647
+ // divergent path, e.g. a symlink and its real path), record it and baseline
648
+ // its shadow so outbound edits reach this tab too — but do NOT re-fire
649
+ // open/rebuild; the document is already live.
650
+ if (clientId === LANGUAGE_CLIENT_ID) {
651
+ const clientFacing = this.toLanguageClientUri(td.uri);
652
+ const record = this.__documents.get(uri);
653
+ if (record && !record.languageClientUris?.has(clientFacing)) {
654
+ (record.languageClientUris ??= new Set<LanguageClientUri>()).add(clientFacing);
655
+ const open = this.__syncedDocuments.get(uri);
656
+ if (open) {
657
+ this.__shadow.set(clientFacing, open.getText());
658
+ }
659
+ }
660
+ }
661
+ return;
662
+ }
663
+ let document = this.__syncedDocuments.get(uri);
664
+ const record = this.trackingFor(uri);
665
+ const existingClients = [...record.clients];
666
+ record.clients.add(clientId);
667
+ // Baseline the per-client staleness guard at the version id the client
668
+ // declared for its own buffer (client-owned per LSP).
669
+ record.clientVersions.set(clientId, td.version);
670
+ if (clientId === LANGUAGE_CLIENT_ID) {
671
+ // Remember the URI Monaco opened under (may differ from the canonical key)
672
+ // so outbound applyEditToLanguageClient can address the URI it actually holds.
673
+ (record.languageClientUris ??= new Set<LanguageClientUri>()).add(this.toLanguageClientUri(td.uri));
674
+ }
675
+ if (!document) {
676
+ // Use integrity-staged content if available, otherwise the client-provided (disk) text.
677
+ const pendingText = this.consumePendingContent(uri);
678
+ const text = pendingText ?? td.text;
679
+ const source = pendingText ? ', source=pending' : '';
680
+ // The SHARED version is server-assigned: continue the persisted
681
+ // sequence — same version when the content is unchanged since the
682
+ // last close (so watchers' `baseVersion` pointers stay valid), one
683
+ // step when it changed (so no stale pointer can coincidentally pass
684
+ // the optimistic gate). Only a first-ever open adopts the client's
685
+ // declared id as the sequence seed.
686
+ const sequence = this.__versionSequences.get(uri);
687
+ const version =
688
+ sequence === undefined ? td.version : sequence.contentHash === contentHash(text) ? sequence.version : sequence.version + 1;
689
+ this.log(uri, `Open document: Version ${version} by ${clientId} [first client${source}]`);
690
+ document = this.configuration.create(uri, td.languageId, version, text);
691
+ this.__syncedDocuments.set(uri, document);
692
+ this.setAuthor(uri, version, clientId);
693
+ if (clientId === LANGUAGE_CLIENT_ID) {
694
+ // Baseline the shadow to what Monaco just opened so the next outbound
695
+ // applyEditToLanguageClient diffs against the right starting point. Keyed by the
696
+ // language-client URI (what Monaco holds), not the canonical document key.
697
+ this.__shadow.set(this.toLanguageClientUri(td.uri), document.getText());
698
+ }
699
+ const toFire = Object.freeze({ document, clientId });
700
+ this.__onDidOpen.fire(toFire);
701
+ this.__onDidChangeContent.fire(toFire);
702
+ } else {
703
+ // An additional client attaches to a document already open by another client.
704
+ this.log(
705
+ uri,
706
+ `Attach client: ${clientId} joined existing document (version ${document.version}, ` +
707
+ `now open in: ${[...existingClients, clientId].join(', ')})`
708
+ );
709
+ this.refreshContent(uri, clientId);
710
+ }
711
+ }
712
+
713
+ refreshContent(uri: DocumentUri, clientId: string): void {
714
+ const syncedDocument = this.__syncedDocuments.get(this.documentKey(uri));
715
+ if (syncedDocument) {
716
+ // Trigger a (re-)build by firing a change event.
717
+ const timer = this.startTimerForUri(
718
+ syncedDocument.uri,
719
+ `Refresh synced document: Version ${syncedDocument.version} by ${clientId}`
720
+ );
721
+ this.__onDidChangeContent.fire(Object.freeze({ document: syncedDocument, clientId }));
722
+ timer.dispose();
723
+ }
724
+ }
725
+
726
+ /**
727
+ * The canonical key a document is stored under — the single point this store
728
+ * turns an incoming URI into its identity, the store-side analogue of
729
+ * `DocumentUriPolicy.canonicalUri`. Keying by the CANONICAL identity collapses
730
+ * two URIs for one physical file (a symlink path and its real path) into a
731
+ * single registration — dedup at the editor layer, not just in
732
+ * `LangiumDocuments`. The URI the client opened under is preserved separately
733
+ * for egress addressing (see {@link DocumentTracking.languageClientUris}). The
734
+ * policy is always bound (the framework defaults it to
735
+ * `DefaultDocumentUriPolicy`, where canonical ≡ syntactic normalize).
736
+ */
737
+ protected documentKey(uri: string): CanonicalUri {
738
+ return this.services.workspace.DocumentUriPolicy.canonicalUri(uri);
739
+ }
740
+
741
+ /**
742
+ * The language-client URI for `uri` — syntactic `normalize` only, NOT
743
+ * canonicalized. This is the URI the LSP textual client (Monaco / VS Code)
744
+ * actually holds the document under (what `applyEditToLanguageClient` must address and
745
+ * what the shadow is keyed by), distinct from {@link documentKey} (the canonical
746
+ * identity the document is stored under). They coincide unless the path diverges
747
+ * from its real path (symlink / `..` / case).
748
+ */
749
+ protected toLanguageClientUri(uri: string): LanguageClientUri {
750
+ return asLanguageClientUri(UriUtils.normalize(uri));
751
+ }
752
+
753
+ /** Get-or-create the per-URI tracking record. `uri` must already be a {@link documentKey}. */
754
+ protected trackingFor(uri: CanonicalUri): DocumentTracking {
755
+ let record = this.__documents.get(uri);
756
+ if (!record) {
757
+ record = { clients: new Set(), versionAuthors: [], clientVersions: new Map() };
758
+ this.__documents.set(uri, record);
759
+ }
760
+ return record;
761
+ }
762
+
763
+ setAuthor(uri: DocumentUri, version: number, author: string): void {
764
+ this.trackingFor(this.documentKey(uri)).versionAuthors[version] = author;
765
+ }
766
+
767
+ /**
768
+ * Resolve the synced `TextDocument` for `uri`. The store keys documents by
769
+ * their canonical identity ({@link documentKey}), so a direct normalized hit
770
+ * wins the common case (the caller passes the canonical URI, or the opened URI
771
+ * coincides with it) with no canonicalization, and a miss falls back to the
772
+ * single canonical-key lookup — which is what bridges a client-space caller
773
+ * that addresses a symlinked path `S` to the document the build keys by its
774
+ * real path `R` (`documentKey(S) === R`).
775
+ *
776
+ * O(1): no scan. Because the interior is already canonically keyed, looking the
777
+ * canonical key up directly is equivalent to reverse-matching every entry, and
778
+ * the `super.get` fast path keeps the common case syscall-free (the
779
+ * canonical lookup, and its one `canonicalUri` realpath, runs only on a miss).
780
+ * Under the default policy `documentKey ≡ normalize`, so the fallback can never
781
+ * find a key the direct lookup didn't — `get` is then identical to the base.
782
+ */
783
+ override get(uri: DocumentUri): T | undefined {
784
+ return super.get(uri) ?? this.__syncedDocuments.get(this.documentKey(uri));
785
+ }
786
+
787
+ /**
788
+ * Current SHARED version of the document at `uri`: the open document's
789
+ * version, else where the persisted sequence left off at last close, else
790
+ * `0` for a URI this store has never seen. The shared sequence is
791
+ * server-owned and monotonic across close/reopen cycles, and advances
792
+ * exactly when the synced content changes — which is what makes it a sound
793
+ * optimistic-concurrency token (`baseVersion` gates): version unchanged ⇔
794
+ * content unchanged.
795
+ */
796
+ version(uri: DocumentUri): number {
797
+ return this.get(uri)?.version ?? this.__versionSequences.get(this.documentKey(uri))?.version ?? 0;
798
+ }
799
+
800
+ /**
801
+ * Reconcile the persisted version sequence with content that reached the
802
+ * build OUTSIDE the store's write paths — a closed document rebuilt from
803
+ * disk (last-close revert) or replaced by a watched-file change. Steps the
804
+ * sequence iff `text` differs from the sequence's last-known content and
805
+ * returns the resulting sequence version so the caller can re-stamp the
806
+ * rebuilt document (see the `AstDocumentManager` Parsed-phase listener) —
807
+ * keeping the "version advances iff content changes" invariant for
808
+ * documents no client currently holds.
809
+ *
810
+ * Returns `undefined` — and does nothing — when the document is open (the
811
+ * store's own content is authoritative; external transitions never reach
812
+ * the Langium factory for open documents) or was never tracked (no gate
813
+ * holder can hold a version pointer for it, and the early exit keeps
814
+ * workspace-wide builds from hashing every untouched document).
815
+ */
816
+ reconcileExternalContent(uri: DocumentUri, text: string): number | undefined {
817
+ const key = this.documentKey(uri);
818
+ if (this.__syncedDocuments.has(key)) {
819
+ return undefined;
820
+ }
821
+ const sequence = this.__versionSequences.get(key);
822
+ if (sequence === undefined) {
823
+ return undefined;
824
+ }
825
+ const hash = contentHash(text);
826
+ if (hash === sequence.contentHash) {
827
+ return sequence.version;
828
+ }
829
+ const stepped: VersionSequence = { version: sequence.version + 1, contentHash: hash };
830
+ this.__versionSequences.set(key, stepped);
831
+ this.logUri(key, `External content change while closed: sequence stepped to version ${stepped.version}`, 'debug');
832
+ return stepped.version;
833
+ }
834
+
835
+ getAuthor(uri: DocumentUri, version?: number): string | undefined {
836
+ const history = this.__documents.get(this.documentKey(uri))?.versionAuthors;
837
+ // Either the requested version, or the latest. `version !== undefined` so we treat 0 correctly.
838
+ const clientId = version !== undefined ? history?.[version] : history?.at(-1);
839
+ if (!clientId && history) {
840
+ // Only warn when there IS a history but the specific version is missing; no history at all
841
+ // means the document was rebuilt internally (e.g. by a project manager), not an error.
842
+ this.log(uri, `Could not detect author of version ${version}.`);
843
+ }
844
+ return clientId;
845
+ }
846
+
847
+ isOpen(uri: DocumentUri): boolean {
848
+ return this.__syncedDocuments.has(this.documentKey(uri));
849
+ }
850
+
851
+ /**
852
+ * True iff any client still holds `uri` open. Distinct from {@link isOpen},
853
+ * which reads `__syncedDocuments` — that map is cleared only AFTER the
854
+ * `onDidClose` event fires for the last client, so `isOpen` returns `true`
855
+ * during the close event itself. `isOpenInAnyClient` reads the tracking
856
+ * record's `clients` set, which is updated BEFORE the fire, so an `onDidClose`
857
+ * subscriber that finds this `false` knows the last client just closed and a
858
+ * disk re-read / rebuild can proceed.
859
+ */
860
+ isOpenInAnyClient(uri: DocumentUri): boolean {
861
+ return (this.__documents.get(this.documentKey(uri))?.clients.size ?? 0) > 0;
862
+ }
863
+
864
+ isOpenInClient(uri: DocumentUri, client: string): boolean {
865
+ return !!this.__documents.get(this.documentKey(uri))?.clients.has(client);
866
+ }
867
+
868
+ isOpenInLanguageClient(uri: DocumentUri): boolean {
869
+ // Takes any URI form (canonicalizes internally via `documentKey`, like
870
+ // `isOpen`); the document is keyed canonically, so a canonical or a
871
+ // client-facing URI both resolve to the same registration.
872
+ return this.isOpenInClient(uri, LANGUAGE_CLIENT_ID);
873
+ }
874
+
875
+ isOnlyOpenInClient(uri: DocumentUri, client: string): boolean {
876
+ const key = this.documentKey(uri);
877
+ return this.__documents.get(key)?.clients.size === 1 && this.isOpenInClient(key, client);
878
+ }
879
+
880
+ /**
881
+ * Every document currently held open by at least one client, with the client
882
+ * ids holding it. Reads the same per-URI tracking records as
883
+ * {@link isOpenInAnyClient}, so it reflects a last-client close immediately.
884
+ *
885
+ * Diagnostics-oriented — the server-state snapshot lists these so an operator
886
+ * can see WHY a document is pinned: a document that lingers here after its
887
+ * editor closed points directly at the client that failed to close it (and,
888
+ * under a shedding policy, explains why its CST is never shed).
889
+ */
890
+ openDocuments(): OpenDocument[] {
891
+ const result: OpenDocument[] = [];
892
+ for (const [uri, tracking] of this.__documents) {
893
+ if (tracking.clients.size > 0) {
894
+ result.push({ uri, clients: [...tracking.clients] });
895
+ }
896
+ }
897
+ return result;
898
+ }
899
+
900
+ /**
901
+ * Stages integrity-updated content for a closed document.
902
+ *
903
+ * When `workspace/applyEdit` targets a closed file, the client opens it from
904
+ * disk (stale) and sends `didOpen` before applying the edit. This staged
905
+ * content is consumed by {@link notifyDidOpenTextDocument} to replace the
906
+ * stale disk text, preventing a brief revert of the integrity update.
907
+ *
908
+ * Not cleared on close: pending content is only staged for already-closed
909
+ * documents (the integrity service checks `isOpenInLanguageClient` first), so
910
+ * a close → stage → open cycle cannot occur. The only scenario where an
911
+ * entry lingers is if `workspace/applyEdit` fails and the file is never
912
+ * opened — the memory cost is one serialised string per URI.
913
+ */
914
+ stagePendingContent(uri: DocumentUri, text: string): void {
915
+ this.trackingFor(this.documentKey(uri)).pendingContent = text;
916
+ }
917
+
918
+ /**
919
+ * Send `newText` to the LSP textual language client (Monaco / VS Code) via
920
+ * `workspace/applyEdit`, using the tracked shadow to produce minimal
921
+ * `TextEdit`s instead of a full-document replace.
922
+ *
923
+ * Returns `undefined` when:
924
+ * - The shared services have no LSP {@link Connection} bound (non-LSP
925
+ * hosts like CLI / tests).
926
+ * - The shadow already matches `newText` (no edits needed; quiet skip).
927
+ *
928
+ * On `applyEdit` rejection (`result.applied === false`) or RPC failure the
929
+ * shadow is invalidated so the next call sends a full-replace baseline.
930
+ * Errors are re-thrown — callers wrap with their own retry / coalescing
931
+ * policy as needed.
932
+ *
933
+ * The diff path is apply-verify-safe: the shadow internally checks that
934
+ * `TextDocument.applyEdits(old, edits) === newText` and falls back to a
935
+ * full replace on mismatch (logged via the warn-callback wired in the
936
+ * constructor), so a diff regression becomes log noise, not data loss.
937
+ *
938
+ * That safety net verifies the diff against the SHADOW, which is what the
939
+ * client is *believed* to hold — so it cannot see the client's buffer moving
940
+ * underneath a push. A line-keyed edit is position-dependent: if a genuine
941
+ * client keystroke lands between {@link LanguageClientTextShadow.computeEdits}
942
+ * and the client applying, the ranges address the wrong lines and splice the
943
+ * buffer (observed as a duplicated declaration, which the integrity tier then
944
+ * "repairs" into a suffixed name and persists). The edit is therefore
945
+ * addressed at the language client's LAST DECLARED VERSION rather than at
946
+ * `null` ("version intentionally unknown"), which is what lets the client
947
+ * reject a push its buffer has outrun. On rejection the shadow is invalidated,
948
+ * so the caller's retry is a full-range replace — position-independent, and
949
+ * safe to apply to whatever the client now holds.
950
+ */
951
+ async applyEditToLanguageClient(
952
+ uri: DocumentUri,
953
+ newText: string,
954
+ options?: { label?: string }
955
+ ): Promise<ApplyWorkspaceEditResult | undefined> {
956
+ const connection = this.services.lsp?.Connection;
957
+ if (!connection) {
958
+ return undefined;
959
+ }
960
+ // The document is keyed by its canonical identity, but Monaco holds it under
961
+ // the URI(s) it opened. Address each of those language-client URIs — the one
962
+ // R→S translation, kept here at the egress. Usually one; more than one only
963
+ // when the same file was opened under a symlink and its real path. Falls back
964
+ // to the normalized URI when nothing is tracked. The shadow is keyed by each
965
+ // URI, so every diff is against the right baseline.
966
+ const recorded = this.__documents.get(this.documentKey(uri))?.languageClientUris;
967
+ const targets: Iterable<LanguageClientUri> = recorded && recorded.size > 0 ? recorded : [this.toLanguageClientUri(uri)];
968
+ let lastResult: ApplyWorkspaceEditResult | undefined;
969
+ for (const targetUri of targets) {
970
+ // Read BEFORE computeEdits, which overwrites it. This is the text the
971
+ // edits below are keyed to, and therefore the only text the client's
972
+ // echo of them can be reconstructed against.
973
+ const before = this.__shadow.get(targetUri);
974
+ const edits = this.__shadow.computeEdits(targetUri, newText);
975
+ if (edits.length === 0) {
976
+ continue;
977
+ }
978
+ // Record the push for echo correlation BEFORE the RPC — the client's
979
+ // echo can race the applyEdit response. See `__pendingPushes`.
980
+ this.recordPendingPush(targetUri, before, newText);
981
+ try {
982
+ // Version the push only when it is position-DEPENDENT. A full-range
983
+ // replace lands correctly on any buffer, so gating it would turn a
984
+ // stale-by-one version into a refused update for no safety gain — and
985
+ // it is exactly what the caller retries with after a rejection, so
986
+ // gating it there would refuse the recovery too.
987
+ const version = isFullReplace(edits) ? UNKNOWN_CLIENT_VERSION : this.languageClientVersion(uri);
988
+ const result = await connection.workspace.applyEdit({
989
+ label: options?.label,
990
+ documentChanges: [TextDocumentEdit.create(OptionalVersionedTextDocumentIdentifier.create(targetUri, version), edits)]
991
+ });
992
+ if (result && result.applied === false) {
993
+ this.__shadow.invalidate(targetUri);
994
+ this.__pendingPushes.delete(targetUri);
995
+ }
996
+ lastResult = result;
997
+ } catch (err) {
998
+ this.__shadow.invalidate(targetUri);
999
+ this.__pendingPushes.delete(targetUri);
1000
+ throw err;
1001
+ }
1002
+ }
1003
+ return lastResult;
1004
+ }
1005
+
1006
+ /**
1007
+ * The version the LSP textual language client last declared for `uri`, for
1008
+ * addressing an outgoing `workspace/applyEdit`.
1009
+ *
1010
+ * Client version ids are CLIENT-owned per LSP, so this is the id the client
1011
+ * itself stamped on its last `didOpen` / `didChange` — never the shared
1012
+ * server version, which advances on authored writes the client knows nothing
1013
+ * about and would therefore reject every push.
1014
+ *
1015
+ * Falls back to {@link UNKNOWN_CLIENT_VERSION} when the client has never
1016
+ * declared one, which is the honest answer for a document it has not opened.
1017
+ * That is also the case in which there is no shadow, so the push is already a
1018
+ * position-independent full replace and has nothing to gain from a gate.
1019
+ */
1020
+ protected languageClientVersion(uri: DocumentUri): number {
1021
+ return this.__documents.get(this.documentKey(uri))?.clientVersions.get(LANGUAGE_CLIENT_ID) ?? UNKNOWN_CLIENT_VERSION;
1022
+ }
1023
+
1024
+ /**
1025
+ * Append a push to the in-flight queue for `targetUri`
1026
+ * (see {@link __pendingPushes}). Bounded: beyond
1027
+ * {@link PENDING_ECHO_CAP} the oldest entry drops with a debug log — an
1028
+ * echo that far outstanding means the client is not echoing at all, and
1029
+ * an unbounded queue must not become the leak.
1030
+ */
1031
+ protected recordPendingPush(targetUri: LanguageClientUri, before: string | undefined, newText: string): void {
1032
+ let pending = this.__pendingPushes.get(targetUri);
1033
+ if (!pending) {
1034
+ pending = [];
1035
+ this.__pendingPushes.set(targetUri, pending);
1036
+ }
1037
+ pending.push({ before, afterHash: contentHash(newText) });
1038
+ if (pending.length > PENDING_ECHO_CAP) {
1039
+ pending.shift();
1040
+ this.logUri(targetUri, `Pending-echo queue exceeded ${PENDING_ECHO_CAP} entries; dropped the oldest`, 'debug');
1041
+ }
1042
+ }
1043
+
1044
+ /**
1045
+ * Decide what an incoming language-client change actually is, by
1046
+ * reconstructing the client's resulting buffer against the OLDEST push still
1047
+ * in flight for `clientFacing`.
1048
+ *
1049
+ * `undefined` when nothing of ours is in flight, which is the ordinary path:
1050
+ * the client's ranges then address the synced text and the caller applies
1051
+ * them to it directly.
1052
+ *
1053
+ * **Why the oldest, and why reconstruct at all.** The client applies our
1054
+ * pushes in order and echoes each against the buffer it held before that
1055
+ * push, so the first echo to arrive belongs to the oldest entry — a FIFO
1056
+ * correspondence the queue preserves by consuming from the front. Comparing
1057
+ * the reconstruction against every pending hash, not only the oldest, is
1058
+ * what recognises an echo that a newer write already superseded: a rapid
1059
+ * write sequence can deliver the echo of push N after the store applied
1060
+ * push N+1, and everything older is then accounted for too.
1061
+ *
1062
+ * A reconstruction matching NO pending push means the client's buffer went
1063
+ * somewhere we did not send it — it coalesced a keystroke into the echo, or
1064
+ * typed before the push landed. That text is authoritative, and the queue
1065
+ * drops: the client has stopped being a pure mirror, so no outstanding echo
1066
+ * can match again. (A push still in flight at that point will be refused by
1067
+ * the client's own version gate, which invalidates the shadow and makes the
1068
+ * next sync a position-independent full replace.)
1069
+ *
1070
+ * Content equality is a sound echo proof because entries live only between a
1071
+ * push and its echo — a milliseconds window, never history — and the
1072
+ * client's `didChange` stream is ordered, so every buffer state arrives in
1073
+ * mutation order. An UNDO returning the buffer to previously-pushed text is
1074
+ * therefore never swallowed: the edit that preceded it already emptied the
1075
+ * queue, so undo revisits PAST states while the queue holds IN-FLIGHT ones.
1076
+ */
1077
+ protected classifyLanguageClientChange(
1078
+ clientFacing: LanguageClientUri,
1079
+ document: T,
1080
+ changes: TextDocumentContentChangeEvent[]
1081
+ ): LanguageClientChangeOrigin | undefined {
1082
+ const pending = this.__pendingPushes.get(clientFacing);
1083
+ if (pending === undefined || pending.length === 0) {
1084
+ return undefined;
1085
+ }
1086
+ // Through the configured factories, not `TextDocument` directly, so an
1087
+ // adopter's custom text-document type governs how the ranges are applied
1088
+ // here exactly as it does on the synced document.
1089
+ const probe = this.create(clientFacing, document.languageId, 0, pending[0].before ?? document.getText());
1090
+ const clientText = this.update(probe, changes, 0).getText();
1091
+ const matchIndex = pending.findIndex(push => push.afterHash === contentHash(clientText));
1092
+ if (matchIndex >= 0) {
1093
+ pending.splice(0, matchIndex + 1);
1094
+ return { kind: 'echo' };
1095
+ }
1096
+ pending.length = 0;
1097
+ return { kind: 'divergent', text: clientText };
1098
+ }
1099
+
1100
+ /**
1101
+ * Explicitly baseline the language-client text shadow for a URI. Useful in
1102
+ * tests and for adopters that need to seed the shadow without going through
1103
+ * a `didOpen` event (e.g. after a sideband save). Normal didOpen / didChange
1104
+ * paths from the LSP language client already auto-track the shadow.
1105
+ */
1106
+ setLanguageClientText(uri: DocumentUri, text: string): void {
1107
+ const clientFacing = this.toLanguageClientUri(uri);
1108
+ this.__shadow.set(clientFacing, text);
1109
+ // An explicit rebaseline supersedes whatever was in flight.
1110
+ this.__pendingPushes.delete(clientFacing);
1111
+ }
1112
+
1113
+ /** Drop the shadow baseline for a URI; the next applyEditToLanguageClient sends a full replace. */
1114
+ invalidateLanguageClientText(uri: DocumentUri): void {
1115
+ const clientFacing = this.toLanguageClientUri(uri);
1116
+ this.__shadow.invalidate(clientFacing);
1117
+ this.__pendingPushes.delete(clientFacing);
1118
+ }
1119
+
1120
+ protected consumePendingContent(uri: DocumentUri): string | undefined {
1121
+ const record = this.__documents.get(this.documentKey(uri));
1122
+ const content = record?.pendingContent;
1123
+ if (record) {
1124
+ record.pendingContent = undefined;
1125
+ }
1126
+ return content;
1127
+ }
1128
+
1129
+ protected log(uri: DocumentUri, message: string): void {
1130
+ this.logUri(uri, message, 'info');
1131
+ }
1132
+
1133
+ /** Hook for subclasses that want to attach a workspace-relative path component. */
1134
+ protected logUri(uri: DocumentUri, message: string, level: 'info' | 'debug' = 'info'): void {
1135
+ this.tracer.with(uri)[level](message);
1136
+ }
1137
+
1138
+ /** Hook for subclasses that want a URI-tagged timer. */
1139
+ protected startTimerForUri(uri: DocumentUri, message: string): { dispose(): void } {
1140
+ return this.tracer.with(uri).startTimer(message);
1141
+ }
1142
+ }