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

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (588) hide show
  1. package/README.md +6 -2
  2. package/lib/documents/ast-document-manager.d.ts +222 -63
  3. package/lib/documents/ast-document-manager.d.ts.map +1 -1
  4. package/lib/documents/ast-document-manager.js +250 -83
  5. package/lib/documents/ast-document-manager.js.map +1 -1
  6. package/lib/documents/client-ids.d.ts +5 -19
  7. package/lib/documents/client-ids.d.ts.map +1 -1
  8. package/lib/documents/client-ids.js +5 -19
  9. package/lib/documents/client-ids.js.map +1 -1
  10. package/lib/documents/client-session-errors.d.ts +15 -0
  11. package/lib/documents/client-session-errors.d.ts.map +1 -0
  12. package/lib/documents/client-session-errors.js +15 -0
  13. package/lib/documents/client-session-errors.js.map +1 -0
  14. package/lib/documents/client-session-registry.d.ts +138 -0
  15. package/lib/documents/client-session-registry.d.ts.map +1 -0
  16. package/lib/documents/client-session-registry.js +187 -0
  17. package/lib/documents/client-session-registry.js.map +1 -0
  18. package/lib/documents/file-system-task-queue.d.ts +49 -0
  19. package/lib/documents/file-system-task-queue.d.ts.map +1 -0
  20. package/lib/documents/file-system-task-queue.js +34 -0
  21. package/lib/documents/file-system-task-queue.js.map +1 -0
  22. package/lib/documents/hydranium-text-documents.d.ts +523 -101
  23. package/lib/documents/hydranium-text-documents.d.ts.map +1 -1
  24. package/lib/documents/hydranium-text-documents.js +961 -177
  25. package/lib/documents/hydranium-text-documents.js.map +1 -1
  26. package/lib/documents/index.d.ts +5 -0
  27. package/lib/documents/index.d.ts.map +1 -1
  28. package/lib/documents/index.js +5 -0
  29. package/lib/documents/index.js.map +1 -1
  30. package/lib/documents/language-client-text-shadow.d.ts +41 -9
  31. package/lib/documents/language-client-text-shadow.d.ts.map +1 -1
  32. package/lib/documents/language-client-text-shadow.js +56 -11
  33. package/lib/documents/language-client-text-shadow.js.map +1 -1
  34. package/lib/documents/model-ledger.d.ts +47 -0
  35. package/lib/documents/model-ledger.d.ts.map +1 -0
  36. package/lib/documents/model-ledger.js +30 -0
  37. package/lib/documents/model-ledger.js.map +1 -0
  38. package/lib/documents/self-save-registry.d.ts +37 -6
  39. package/lib/documents/self-save-registry.d.ts.map +1 -1
  40. package/lib/documents/self-save-registry.js +28 -15
  41. package/lib/documents/self-save-registry.js.map +1 -1
  42. package/lib/documents/version-sync-service.d.ts +134 -0
  43. package/lib/documents/version-sync-service.d.ts.map +1 -0
  44. package/lib/documents/version-sync-service.js +171 -0
  45. package/lib/documents/version-sync-service.js.map +1 -0
  46. package/lib/index.d.ts +3 -0
  47. package/lib/index.d.ts.map +1 -1
  48. package/lib/index.js +6 -0
  49. package/lib/index.js.map +1 -1
  50. package/lib/langium/ast-extension/ast-extension-service.d.ts.map +1 -1
  51. package/lib/langium/ast-extension/ast-extension-service.js.map +1 -1
  52. package/lib/langium/ast-extension/ast-node-builder.d.ts +32 -9
  53. package/lib/langium/ast-extension/ast-node-builder.d.ts.map +1 -1
  54. package/lib/langium/ast-extension/ast-node-builder.js +60 -22
  55. package/lib/langium/ast-extension/ast-node-builder.js.map +1 -1
  56. package/lib/langium/bootstrap.d.ts.map +1 -1
  57. package/lib/langium/bootstrap.js +32 -9
  58. package/lib/langium/bootstrap.js.map +1 -1
  59. package/lib/langium/build-phase-pass/build-phase-pass-service.d.ts.map +1 -1
  60. package/lib/langium/build-phase-pass/build-phase-pass-service.js.map +1 -1
  61. package/lib/langium/config/configuration-provider.d.ts +81 -0
  62. package/lib/langium/config/configuration-provider.d.ts.map +1 -0
  63. package/lib/langium/config/configuration-provider.js +112 -0
  64. package/lib/langium/config/configuration-provider.js.map +1 -0
  65. package/lib/langium/config/index.d.ts +1 -0
  66. package/lib/langium/config/index.d.ts.map +1 -1
  67. package/lib/langium/config/index.js +1 -0
  68. package/lib/langium/config/index.js.map +1 -1
  69. package/lib/langium/config/settings.js.map +1 -1
  70. package/lib/langium/diagnostics/hydranium-langium-profiler.d.ts.map +1 -1
  71. package/lib/langium/diagnostics/hydranium-langium-profiler.js.map +1 -1
  72. package/lib/langium/diagnostics/logger.d.ts +10 -3
  73. package/lib/langium/diagnostics/logger.d.ts.map +1 -1
  74. package/lib/langium/diagnostics/logger.js +12 -5
  75. package/lib/langium/diagnostics/logger.js.map +1 -1
  76. package/lib/langium/diagnostics/lsp-logger.d.ts +17 -0
  77. package/lib/langium/diagnostics/lsp-logger.d.ts.map +1 -1
  78. package/lib/langium/diagnostics/lsp-logger.js +56 -13
  79. package/lib/langium/diagnostics/lsp-logger.js.map +1 -1
  80. package/lib/langium/diagnostics/server-tracer.d.ts.map +1 -1
  81. package/lib/langium/diagnostics/server-tracer.js.map +1 -1
  82. package/lib/langium/document-builder/build-pipeline-integration.d.ts +21 -1
  83. package/lib/langium/document-builder/build-pipeline-integration.d.ts.map +1 -1
  84. package/lib/langium/document-builder/build-pipeline-integration.js +32 -5
  85. package/lib/langium/document-builder/build-pipeline-integration.js.map +1 -1
  86. package/lib/langium/document-builder/build-session.d.ts +93 -0
  87. package/lib/langium/document-builder/build-session.d.ts.map +1 -0
  88. package/lib/langium/document-builder/build-session.js +72 -0
  89. package/lib/langium/document-builder/build-session.js.map +1 -0
  90. package/lib/langium/document-builder/document-builder.d.ts +382 -29
  91. package/lib/langium/document-builder/document-builder.d.ts.map +1 -1
  92. package/lib/langium/document-builder/document-builder.js +659 -61
  93. package/lib/langium/document-builder/document-builder.js.map +1 -1
  94. package/lib/langium/document-builder/index.d.ts +1 -0
  95. package/lib/langium/document-builder/index.d.ts.map +1 -1
  96. package/lib/langium/document-builder/index.js +1 -0
  97. package/lib/langium/document-builder/index.js.map +1 -1
  98. package/lib/langium/documentation/comment-provider.d.ts.map +1 -1
  99. package/lib/langium/documentation/comment-provider.js.map +1 -1
  100. package/lib/langium/integration-services.d.ts +45 -1
  101. package/lib/langium/integration-services.d.ts.map +1 -1
  102. package/lib/langium/integration-services.js +10 -5
  103. package/lib/langium/integration-services.js.map +1 -1
  104. package/lib/langium/integrity/integrity-rule.d.ts +13 -5
  105. package/lib/langium/integrity/integrity-rule.d.ts.map +1 -1
  106. package/lib/langium/integrity/integrity-rule.js.map +1 -1
  107. package/lib/langium/integrity/integrity-service.d.ts +58 -13
  108. package/lib/langium/integrity/integrity-service.d.ts.map +1 -1
  109. package/lib/langium/integrity/integrity-service.js +204 -29
  110. package/lib/langium/integrity/integrity-service.js.map +1 -1
  111. package/lib/langium/keys/containment.d.ts +64 -0
  112. package/lib/langium/keys/containment.d.ts.map +1 -0
  113. package/lib/langium/keys/containment.js +53 -0
  114. package/lib/langium/keys/containment.js.map +1 -0
  115. package/lib/langium/keys/index.d.ts +1 -0
  116. package/lib/langium/keys/index.d.ts.map +1 -1
  117. package/lib/langium/keys/index.js +1 -0
  118. package/lib/langium/keys/index.js.map +1 -1
  119. package/lib/langium/keys/name-based-key-provider.d.ts +4 -0
  120. package/lib/langium/keys/name-based-key-provider.d.ts.map +1 -1
  121. package/lib/langium/keys/name-based-key-provider.js +4 -0
  122. package/lib/langium/keys/name-based-key-provider.js.map +1 -1
  123. package/lib/langium/keys/positional-key-provider.d.ts.map +1 -1
  124. package/lib/langium/keys/positional-key-provider.js.map +1 -1
  125. package/lib/langium/labeling/label-provider.d.ts.map +1 -1
  126. package/lib/langium/labeling/label-provider.js.map +1 -1
  127. package/lib/langium/language-module.d.ts +27 -2
  128. package/lib/langium/language-module.d.ts.map +1 -1
  129. package/lib/langium/language-module.js +16 -2
  130. package/lib/langium/language-module.js.map +1 -1
  131. package/lib/langium/model-service/client-session.d.ts +330 -0
  132. package/lib/langium/model-service/client-session.d.ts.map +1 -0
  133. package/lib/langium/model-service/client-session.js +418 -0
  134. package/lib/langium/model-service/client-session.js.map +1 -0
  135. package/lib/langium/model-service/index.d.ts +1 -0
  136. package/lib/langium/model-service/index.d.ts.map +1 -1
  137. package/lib/langium/model-service/index.js +1 -0
  138. package/lib/langium/model-service/index.js.map +1 -1
  139. package/lib/langium/model-service/model-service.d.ts +353 -253
  140. package/lib/langium/model-service/model-service.d.ts.map +1 -1
  141. package/lib/langium/model-service/model-service.js +361 -408
  142. package/lib/langium/model-service/model-service.js.map +1 -1
  143. package/lib/langium/module.d.ts +150 -35
  144. package/lib/langium/module.d.ts.map +1 -1
  145. package/lib/langium/module.js +50 -35
  146. package/lib/langium/module.js.map +1 -1
  147. package/lib/langium/naming/name-provider.d.ts +25 -4
  148. package/lib/langium/naming/name-provider.d.ts.map +1 -1
  149. package/lib/langium/naming/name-provider.js +2 -1
  150. package/lib/langium/naming/name-provider.js.map +1 -1
  151. package/lib/langium/naming/name-separator-validation.d.ts +23 -0
  152. package/lib/langium/naming/name-separator-validation.d.ts.map +1 -1
  153. package/lib/langium/naming/name-separator-validation.js +30 -1
  154. package/lib/langium/naming/name-separator-validation.js.map +1 -1
  155. package/lib/langium/project/abstract-project-manager.d.ts.map +1 -1
  156. package/lib/langium/project/abstract-project-manager.js +9 -2
  157. package/lib/langium/project/abstract-project-manager.js.map +1 -1
  158. package/lib/langium/project/project-change-event.d.ts +2 -2
  159. package/lib/langium/project/single-project-manager.d.ts.map +1 -1
  160. package/lib/langium/project/single-project-manager.js.map +1 -1
  161. package/lib/langium/residency/cst-residency-service.d.ts +31 -11
  162. package/lib/langium/residency/cst-residency-service.d.ts.map +1 -1
  163. package/lib/langium/residency/cst-residency-service.js +23 -57
  164. package/lib/langium/residency/cst-residency-service.js.map +1 -1
  165. package/lib/langium/scope/ast-node-description-provider.d.ts.map +1 -1
  166. package/lib/langium/scope/ast-node-description-provider.js.map +1 -1
  167. package/lib/langium/scope/hydranium-scope-computation.d.ts.map +1 -1
  168. package/lib/langium/scope/hydranium-scope-computation.js.map +1 -1
  169. package/lib/langium/scope/hydranium-scope-provider.d.ts +48 -13
  170. package/lib/langium/scope/hydranium-scope-provider.d.ts.map +1 -1
  171. package/lib/langium/scope/hydranium-scope-provider.js +56 -20
  172. package/lib/langium/scope/hydranium-scope-provider.js.map +1 -1
  173. package/lib/langium/scope/reference-builder.d.ts.map +1 -1
  174. package/lib/langium/scope/reference-builder.js.map +1 -1
  175. package/lib/langium/scope/reference-candidate-provider.d.ts.map +1 -1
  176. package/lib/langium/scope/reference-candidate-provider.js.map +1 -1
  177. package/lib/langium/scope/scope-extension-service.d.ts.map +1 -1
  178. package/lib/langium/scope/scope-extension-service.js.map +1 -1
  179. package/lib/langium/serialization/abstract-serializer.d.ts +11 -20
  180. package/lib/langium/serialization/abstract-serializer.d.ts.map +1 -1
  181. package/lib/langium/serialization/abstract-serializer.js +12 -21
  182. package/lib/langium/serialization/abstract-serializer.js.map +1 -1
  183. package/lib/langium/serialization/json-serializer.d.ts +1 -1
  184. package/lib/langium/serialization/json-serializer.d.ts.map +1 -1
  185. package/lib/langium/serialization/json-serializer.js.map +1 -1
  186. package/lib/langium/serialization/yaml-serializer.d.ts.map +1 -1
  187. package/lib/langium/serialization/yaml-serializer.js.map +1 -1
  188. package/lib/langium/service-registry.d.ts +15 -1
  189. package/lib/langium/service-registry.d.ts.map +1 -1
  190. package/lib/langium/service-registry.js +16 -0
  191. package/lib/langium/service-registry.js.map +1 -1
  192. package/lib/langium/shared-services.d.ts +21 -4
  193. package/lib/langium/shared-services.d.ts.map +1 -1
  194. package/lib/langium/shared-services.js.map +1 -1
  195. package/lib/langium/transfer/transfer-encoder.d.ts +75 -23
  196. package/lib/langium/transfer/transfer-encoder.d.ts.map +1 -1
  197. package/lib/langium/transfer/transfer-encoder.js +44 -21
  198. package/lib/langium/transfer/transfer-encoder.js.map +1 -1
  199. package/lib/langium/trivia/comment-preserver.d.ts +423 -0
  200. package/lib/langium/trivia/comment-preserver.d.ts.map +1 -0
  201. package/lib/langium/trivia/comment-preserver.js +906 -0
  202. package/lib/langium/trivia/comment-preserver.js.map +1 -0
  203. package/lib/langium/trivia/document-ending-preserver.d.ts +43 -0
  204. package/lib/langium/trivia/document-ending-preserver.d.ts.map +1 -0
  205. package/lib/langium/trivia/document-ending-preserver.js +48 -0
  206. package/lib/langium/trivia/document-ending-preserver.js.map +1 -0
  207. package/lib/langium/trivia/index.d.ts +14 -0
  208. package/lib/langium/trivia/index.d.ts.map +1 -0
  209. package/lib/langium/trivia/index.js +14 -0
  210. package/lib/langium/trivia/index.js.map +1 -0
  211. package/lib/langium/trivia/trivia-contribution.d.ts +37 -0
  212. package/lib/langium/trivia/trivia-contribution.d.ts.map +1 -0
  213. package/lib/langium/trivia/trivia-contribution.js +10 -0
  214. package/lib/langium/trivia/trivia-contribution.js.map +1 -0
  215. package/lib/langium/trivia/trivia-preserver.d.ts +50 -0
  216. package/lib/langium/trivia/trivia-preserver.d.ts.map +1 -0
  217. package/lib/langium/trivia/trivia-preserver.js +10 -0
  218. package/lib/langium/trivia/trivia-preserver.js.map +1 -0
  219. package/lib/langium/trivia/trivia-service.d.ts +70 -0
  220. package/lib/langium/trivia/trivia-service.d.ts.map +1 -0
  221. package/lib/langium/trivia/trivia-service.js +56 -0
  222. package/lib/langium/trivia/trivia-service.js.map +1 -0
  223. package/lib/langium/update-rewrite/normalize-empty-strings.d.ts.map +1 -1
  224. package/lib/langium/update-rewrite/update-rewrite-service.d.ts.map +1 -1
  225. package/lib/langium/update-rewrite/update-rewrite-service.js.map +1 -1
  226. package/lib/langium/update-rewrite/update-rewrite.d.ts +1 -1
  227. package/lib/langium/validation/document-validator.d.ts +294 -10
  228. package/lib/langium/validation/document-validator.d.ts.map +1 -1
  229. package/lib/langium/validation/document-validator.js +448 -5
  230. package/lib/langium/validation/document-validator.js.map +1 -1
  231. package/lib/langium/validation/validation-contribution-collector.d.ts.map +1 -1
  232. package/lib/langium/validation/validation-contribution-collector.js.map +1 -1
  233. package/lib/langium/workspace/document-uri-policy.d.ts +17 -12
  234. package/lib/langium/workspace/document-uri-policy.d.ts.map +1 -1
  235. package/lib/langium/workspace/document-uri-policy.js +10 -9
  236. package/lib/langium/workspace/document-uri-policy.js.map +1 -1
  237. package/lib/langium/workspace/file-not-found.d.ts +17 -0
  238. package/lib/langium/workspace/file-not-found.d.ts.map +1 -0
  239. package/lib/langium/workspace/file-not-found.js +20 -0
  240. package/lib/langium/workspace/file-not-found.js.map +1 -0
  241. package/lib/langium/workspace/file-system-provider.d.ts +84 -8
  242. package/lib/langium/workspace/file-system-provider.d.ts.map +1 -1
  243. package/lib/langium/workspace/file-system-provider.js +93 -14
  244. package/lib/langium/workspace/file-system-provider.js.map +1 -1
  245. package/lib/langium/workspace/hydranium-langium-document-factory.d.ts +56 -1
  246. package/lib/langium/workspace/hydranium-langium-document-factory.d.ts.map +1 -1
  247. package/lib/langium/workspace/hydranium-langium-document-factory.js +79 -0
  248. package/lib/langium/workspace/hydranium-langium-document-factory.js.map +1 -1
  249. package/lib/langium/workspace/hydranium-workspace-lock.d.ts +43 -1
  250. package/lib/langium/workspace/hydranium-workspace-lock.d.ts.map +1 -1
  251. package/lib/langium/workspace/hydranium-workspace-lock.js +58 -1
  252. package/lib/langium/workspace/hydranium-workspace-lock.js.map +1 -1
  253. package/lib/langium/workspace/hydranium-workspace-manager.d.ts +81 -8
  254. package/lib/langium/workspace/hydranium-workspace-manager.d.ts.map +1 -1
  255. package/lib/langium/workspace/hydranium-workspace-manager.js +128 -10
  256. package/lib/langium/workspace/hydranium-workspace-manager.js.map +1 -1
  257. package/lib/langium/workspace/in-memory-file-system-provider.d.ts +25 -2
  258. package/lib/langium/workspace/in-memory-file-system-provider.d.ts.map +1 -1
  259. package/lib/langium/workspace/in-memory-file-system-provider.js +41 -15
  260. package/lib/langium/workspace/in-memory-file-system-provider.js.map +1 -1
  261. package/lib/langium/workspace/index-manager.d.ts.map +1 -1
  262. package/lib/langium/workspace/index-manager.js.map +1 -1
  263. package/lib/langium/workspace/initialize-workspace.d.ts +31 -2
  264. package/lib/langium/workspace/initialize-workspace.d.ts.map +1 -1
  265. package/lib/langium/workspace/initialize-workspace.js +13 -5
  266. package/lib/langium/workspace/initialize-workspace.js.map +1 -1
  267. package/lib/langium/workspace/langium-documents.d.ts +86 -17
  268. package/lib/langium/workspace/langium-documents.d.ts.map +1 -1
  269. package/lib/langium/workspace/langium-documents.js +101 -29
  270. package/lib/langium/workspace/langium-documents.js.map +1 -1
  271. package/lib/langium/workspace/persistent-file-system-provider.d.ts +0 -7
  272. package/lib/langium/workspace/persistent-file-system-provider.d.ts.map +1 -1
  273. package/lib/langium/workspace/persistent-file-system-provider.js +0 -7
  274. package/lib/langium/workspace/persistent-file-system-provider.js.map +1 -1
  275. package/lib/langium/workspace/virtual-document.d.ts +48 -15
  276. package/lib/langium/workspace/virtual-document.d.ts.map +1 -1
  277. package/lib/langium/workspace/virtual-document.js +78 -18
  278. package/lib/langium/workspace/virtual-document.js.map +1 -1
  279. package/lib/langium/workspace/write-lock-scope.d.ts +20 -10
  280. package/lib/langium/workspace/write-lock-scope.d.ts.map +1 -1
  281. package/lib/langium/workspace/write-lock-scope.js +12 -4
  282. package/lib/langium/workspace/write-lock-scope.js.map +1 -1
  283. package/lib/locale/index.d.ts +10 -0
  284. package/lib/locale/index.d.ts.map +1 -0
  285. package/lib/locale/index.js +10 -0
  286. package/lib/locale/index.js.map +1 -0
  287. package/lib/locale/server-locale.d.ts +73 -0
  288. package/lib/locale/server-locale.d.ts.map +1 -0
  289. package/lib/locale/server-locale.js +61 -0
  290. package/lib/locale/server-locale.js.map +1 -0
  291. package/lib/lsp/completion/hydranium-completion-provider.d.ts +44 -2
  292. package/lib/lsp/completion/hydranium-completion-provider.d.ts.map +1 -1
  293. package/lib/lsp/completion/hydranium-completion-provider.js +68 -0
  294. package/lib/lsp/completion/hydranium-completion-provider.js.map +1 -1
  295. package/lib/lsp/connection-features.d.ts +23 -0
  296. package/lib/lsp/connection-features.d.ts.map +1 -0
  297. package/lib/lsp/connection-features.js +60 -0
  298. package/lib/lsp/connection-features.js.map +1 -0
  299. package/lib/lsp/diagnostics-connection.d.ts +27 -0
  300. package/lib/lsp/diagnostics-connection.d.ts.map +1 -0
  301. package/lib/lsp/diagnostics-connection.js +53 -0
  302. package/lib/lsp/diagnostics-connection.js.map +1 -0
  303. package/lib/lsp/hydranium-document-update-handler.d.ts +90 -79
  304. package/lib/lsp/hydranium-document-update-handler.d.ts.map +1 -1
  305. package/lib/lsp/hydranium-document-update-handler.js +153 -99
  306. package/lib/lsp/hydranium-document-update-handler.js.map +1 -1
  307. package/lib/lsp/index.d.ts +3 -1
  308. package/lib/lsp/index.d.ts.map +1 -1
  309. package/lib/lsp/index.js +3 -1
  310. package/lib/lsp/index.js.map +1 -1
  311. package/lib/lsp/lsp-latency.d.ts +39 -0
  312. package/lib/lsp/lsp-latency.d.ts.map +1 -0
  313. package/lib/lsp/lsp-latency.js +58 -0
  314. package/lib/lsp/lsp-latency.js.map +1 -0
  315. package/lib/lsp/semantic-token-provider.d.ts +34 -1
  316. package/lib/lsp/semantic-token-provider.d.ts.map +1 -1
  317. package/lib/lsp/semantic-token-provider.js +55 -8
  318. package/lib/lsp/semantic-token-provider.js.map +1 -1
  319. package/lib/lsp/shared-module.d.ts +4 -8
  320. package/lib/lsp/shared-module.d.ts.map +1 -1
  321. package/lib/lsp/shared-module.js.map +1 -1
  322. package/lib/lsp/start-language-server.d.ts +8 -7
  323. package/lib/lsp/start-language-server.d.ts.map +1 -1
  324. package/lib/lsp/start-language-server.js +13 -7
  325. package/lib/lsp/start-language-server.js.map +1 -1
  326. package/lib/messages/carriers.d.ts +54 -0
  327. package/lib/messages/carriers.d.ts.map +1 -0
  328. package/lib/messages/carriers.js +62 -0
  329. package/lib/messages/carriers.js.map +1 -0
  330. package/lib/messages/index.d.ts +25 -0
  331. package/lib/messages/index.d.ts.map +1 -0
  332. package/lib/messages/index.js +25 -0
  333. package/lib/messages/index.js.map +1 -0
  334. package/lib/messages/renderer.d.ts +142 -0
  335. package/lib/messages/renderer.d.ts.map +1 -0
  336. package/lib/messages/renderer.js +165 -0
  337. package/lib/messages/renderer.js.map +1 -0
  338. package/lib/node/event-loop-monitor.js.map +1 -1
  339. package/lib/node/heap-ceiling.d.ts +61 -0
  340. package/lib/node/heap-ceiling.d.ts.map +1 -0
  341. package/lib/node/heap-ceiling.js +72 -0
  342. package/lib/node/heap-ceiling.js.map +1 -0
  343. package/lib/node/index.d.ts +1 -0
  344. package/lib/node/index.d.ts.map +1 -1
  345. package/lib/node/index.js +1 -0
  346. package/lib/node/index.js.map +1 -1
  347. package/lib/node/latency-from-env.d.ts +1 -1
  348. package/lib/node/latency-from-env.js +1 -1
  349. package/lib/node/lint-grammar.js.map +1 -1
  350. package/lib/node/measure-memory.d.ts.map +1 -1
  351. package/lib/node/measure-memory.js +1 -0
  352. package/lib/node/measure-memory.js.map +1 -1
  353. package/lib/node/memory-monitor.js.map +1 -1
  354. package/lib/node/node-file-system-provider.d.ts +39 -4
  355. package/lib/node/node-file-system-provider.d.ts.map +1 -1
  356. package/lib/node/node-file-system-provider.js +109 -49
  357. package/lib/node/node-file-system-provider.js.map +1 -1
  358. package/lib/node/process-memory.js.map +1 -1
  359. package/lib/node/profile-capture.d.ts +8 -2
  360. package/lib/node/profile-capture.d.ts.map +1 -1
  361. package/lib/node/profile-capture.js.map +1 -1
  362. package/lib/node/profile-digest.js.map +1 -1
  363. package/lib/node/profiling-run.d.ts +13 -3
  364. package/lib/node/profiling-run.d.ts.map +1 -1
  365. package/lib/node/profiling-run.js +17 -8
  366. package/lib/node/profiling-run.js.map +1 -1
  367. package/lib/node/rename-over-open-readers.d.ts +52 -0
  368. package/lib/node/rename-over-open-readers.d.ts.map +1 -0
  369. package/lib/node/rename-over-open-readers.js +66 -0
  370. package/lib/node/rename-over-open-readers.js.map +1 -0
  371. package/lib/node/socket-launcher.d.ts +16 -1
  372. package/lib/node/socket-launcher.d.ts.map +1 -1
  373. package/lib/node/socket-launcher.js +4 -3
  374. package/lib/node/socket-launcher.js.map +1 -1
  375. package/lib/node/stdio-launcher.d.ts +1 -1
  376. package/lib/node/stdio-launcher.d.ts.map +1 -1
  377. package/lib/node/stdio-launcher.js +1 -1
  378. package/lib/node/stdio-launcher.js.map +1 -1
  379. package/lib/testing/document-uri-policy-conformance.js.map +1 -1
  380. package/lib/testing/fake-description.js.map +1 -1
  381. package/lib/testing/fake-document.d.ts +16 -4
  382. package/lib/testing/fake-document.d.ts.map +1 -1
  383. package/lib/testing/fake-document.js +18 -3
  384. package/lib/testing/fake-document.js.map +1 -1
  385. package/lib/testing/index.d.ts +1 -1
  386. package/lib/testing/index.d.ts.map +1 -1
  387. package/lib/testing/index.js +2 -1
  388. package/lib/testing/index.js.map +1 -1
  389. package/lib/testing/langium-test-helpers.d.ts.map +1 -1
  390. package/lib/testing/langium-test-helpers.js +1 -0
  391. package/lib/testing/langium-test-helpers.js.map +1 -1
  392. package/lib/testing/make-noop-language-services.js.map +1 -1
  393. package/lib/testing/make-noop-shared-services.d.ts +14 -0
  394. package/lib/testing/make-noop-shared-services.d.ts.map +1 -1
  395. package/lib/testing/make-noop-shared-services.js +28 -2
  396. package/lib/testing/make-noop-shared-services.js.map +1 -1
  397. package/lib/testing/make-test-services.d.ts +69 -14
  398. package/lib/testing/make-test-services.d.ts.map +1 -1
  399. package/lib/testing/make-test-services.js +39 -10
  400. package/lib/testing/make-test-services.js.map +1 -1
  401. package/lib/testing/make-test-tracer.js.map +1 -1
  402. package/lib/testing/node/golden-corpus.js.map +1 -1
  403. package/lib/testing/node/index.d.ts +1 -0
  404. package/lib/testing/node/index.d.ts.map +1 -1
  405. package/lib/testing/node/index.js +1 -0
  406. package/lib/testing/node/index.js.map +1 -1
  407. package/lib/testing/node/lsp-harness.d.ts.map +1 -1
  408. package/lib/testing/node/lsp-harness.js +2 -0
  409. package/lib/testing/node/lsp-harness.js.map +1 -1
  410. package/lib/testing/node/lsp-server-connection.d.ts +11 -3
  411. package/lib/testing/node/lsp-server-connection.d.ts.map +1 -1
  412. package/lib/testing/node/lsp-server-connection.js +42 -9
  413. package/lib/testing/node/lsp-server-connection.js.map +1 -1
  414. package/lib/testing/node/scratch-workspace.d.ts.map +1 -1
  415. package/lib/testing/node/scratch-workspace.js +10 -5
  416. package/lib/testing/node/scratch-workspace.js.map +1 -1
  417. package/lib/testing/node/spawned-server.d.ts +14 -0
  418. package/lib/testing/node/spawned-server.d.ts.map +1 -1
  419. package/lib/testing/node/spawned-server.js +33 -1
  420. package/lib/testing/node/spawned-server.js.map +1 -1
  421. package/lib/testing/node/unhandled-rejections.d.ts +20 -0
  422. package/lib/testing/node/unhandled-rejections.d.ts.map +1 -0
  423. package/lib/testing/node/unhandled-rejections.js +32 -0
  424. package/lib/testing/node/unhandled-rejections.js.map +1 -0
  425. package/lib/testing/playwright/browser-capture-bridge.js.map +1 -1
  426. package/lib/testing/playwright/e2e-profiling.js.map +1 -1
  427. package/lib/testing/playwright/flaky-network-proxy.d.ts +76 -0
  428. package/lib/testing/playwright/flaky-network-proxy.d.ts.map +1 -0
  429. package/lib/testing/playwright/flaky-network-proxy.js +164 -0
  430. package/lib/testing/playwright/flaky-network-proxy.js.map +1 -0
  431. package/lib/testing/playwright/index.d.ts +1 -0
  432. package/lib/testing/playwright/index.d.ts.map +1 -1
  433. package/lib/testing/playwright/index.js +1 -0
  434. package/lib/testing/playwright/index.js.map +1 -1
  435. package/lib/testing/playwright/server-log-capture.d.ts +24 -8
  436. package/lib/testing/playwright/server-log-capture.d.ts.map +1 -1
  437. package/lib/testing/playwright/server-log-capture.js +27 -6
  438. package/lib/testing/playwright/server-log-capture.js.map +1 -1
  439. package/lib/testing/playwright/server-log-rename-reporter.d.ts.map +1 -1
  440. package/lib/testing/playwright/server-log-rename-reporter.js +10 -1
  441. package/lib/testing/playwright/server-log-rename-reporter.js.map +1 -1
  442. package/lib/testing/run-update-pipeline.d.ts +4 -4
  443. package/lib/testing/run-update-pipeline.d.ts.map +1 -1
  444. package/lib/testing/stub-ast-document-manager.d.ts +11 -9
  445. package/lib/testing/stub-ast-document-manager.d.ts.map +1 -1
  446. package/lib/testing/stub-ast-document-manager.js +25 -9
  447. package/lib/testing/stub-ast-document-manager.js.map +1 -1
  448. package/lib/testing/stub-document-builder.d.ts +26 -11
  449. package/lib/testing/stub-document-builder.d.ts.map +1 -1
  450. package/lib/testing/stub-document-builder.js +57 -4
  451. package/lib/testing/stub-document-builder.js.map +1 -1
  452. package/lib/testing/stub-hydranium-text-documents.d.ts +22 -7
  453. package/lib/testing/stub-hydranium-text-documents.d.ts.map +1 -1
  454. package/lib/testing/stub-hydranium-text-documents.js +97 -15
  455. package/lib/testing/stub-hydranium-text-documents.js.map +1 -1
  456. package/lib/testing/stub-index-manager.js.map +1 -1
  457. package/lib/testing/stub-langium-documents.d.ts +3 -2
  458. package/lib/testing/stub-langium-documents.d.ts.map +1 -1
  459. package/lib/testing/stub-langium-documents.js.map +1 -1
  460. package/lib/testing/stub-model-service.d.ts +7 -6
  461. package/lib/testing/stub-model-service.d.ts.map +1 -1
  462. package/lib/testing/stub-model-service.js +4 -4
  463. package/lib/testing/stub-model-service.js.map +1 -1
  464. package/lib/testing/stub-project-manager.js.map +1 -1
  465. package/lib/testing/stub-service-registry.js.map +1 -1
  466. package/lib/util/connection-liveness.d.ts +7 -6
  467. package/lib/util/connection-liveness.d.ts.map +1 -1
  468. package/lib/util/connection-liveness.js +35 -14
  469. package/lib/util/connection-liveness.js.map +1 -1
  470. package/lib/util/environment.d.ts.map +1 -1
  471. package/lib/util/environment.js.map +1 -1
  472. package/lib/util/registry.d.ts.map +1 -1
  473. package/package.json +35 -26
  474. package/src/documents/ast-document-manager.ts +395 -126
  475. package/src/documents/client-ids.ts +5 -22
  476. package/src/documents/client-session-errors.ts +24 -0
  477. package/src/documents/client-session-registry.ts +240 -0
  478. package/src/documents/file-system-task-queue.ts +68 -0
  479. package/src/documents/hydranium-text-documents.ts +1175 -225
  480. package/src/documents/index.ts +5 -0
  481. package/src/documents/language-client-text-shadow.ts +59 -11
  482. package/src/documents/model-ledger.ts +66 -0
  483. package/src/documents/self-save-registry.ts +52 -13
  484. package/src/documents/version-sync-service.ts +267 -0
  485. package/src/index.ts +6 -0
  486. package/src/langium/ast-extension/ast-node-builder.ts +66 -22
  487. package/src/langium/bootstrap.ts +32 -9
  488. package/src/langium/config/configuration-provider.ts +119 -0
  489. package/src/langium/config/index.ts +1 -0
  490. package/src/langium/diagnostics/logger.ts +12 -5
  491. package/src/langium/diagnostics/lsp-logger.ts +58 -12
  492. package/src/langium/document-builder/build-pipeline-integration.ts +50 -5
  493. package/src/langium/document-builder/build-session.ts +87 -0
  494. package/src/langium/document-builder/document-builder.ts +776 -59
  495. package/src/langium/document-builder/index.ts +1 -0
  496. package/src/langium/integration-services.ts +67 -6
  497. package/src/langium/integrity/integrity-rule.ts +13 -5
  498. package/src/langium/integrity/integrity-service.ts +220 -30
  499. package/src/langium/keys/containment.ts +87 -0
  500. package/src/langium/keys/index.ts +1 -0
  501. package/src/langium/keys/name-based-key-provider.ts +4 -0
  502. package/src/langium/language-module.ts +42 -4
  503. package/src/langium/model-service/client-session.ts +649 -0
  504. package/src/langium/model-service/index.ts +1 -0
  505. package/src/langium/model-service/model-service.ts +570 -433
  506. package/src/langium/module.ts +201 -64
  507. package/src/langium/naming/name-provider.ts +27 -5
  508. package/src/langium/naming/name-separator-validation.ts +34 -5
  509. package/src/langium/project/abstract-project-manager.ts +9 -1
  510. package/src/langium/project/project-change-event.ts +2 -2
  511. package/src/langium/residency/cst-residency-service.ts +46 -15
  512. package/src/langium/scope/hydranium-scope-provider.ts +60 -22
  513. package/src/langium/serialization/abstract-serializer.ts +13 -32
  514. package/src/langium/service-registry.ts +19 -2
  515. package/src/langium/shared-services.ts +25 -4
  516. package/src/langium/transfer/transfer-encoder.ts +102 -34
  517. package/src/langium/trivia/comment-preserver.ts +1100 -0
  518. package/src/langium/trivia/document-ending-preserver.ts +55 -0
  519. package/src/langium/trivia/index.ts +14 -0
  520. package/src/langium/trivia/trivia-contribution.ts +39 -0
  521. package/src/langium/trivia/trivia-preserver.ts +54 -0
  522. package/src/langium/trivia/trivia-service.ts +99 -0
  523. package/src/langium/update-rewrite/update-rewrite.ts +1 -1
  524. package/src/langium/validation/document-validator.ts +537 -11
  525. package/src/langium/workspace/document-uri-policy.ts +17 -12
  526. package/src/langium/workspace/file-not-found.ts +23 -0
  527. package/src/langium/workspace/file-system-provider.ts +153 -16
  528. package/src/langium/workspace/hydranium-langium-document-factory.ts +117 -0
  529. package/src/langium/workspace/hydranium-workspace-lock.ts +86 -2
  530. package/src/langium/workspace/hydranium-workspace-manager.ts +153 -13
  531. package/src/langium/workspace/in-memory-file-system-provider.ts +47 -16
  532. package/src/langium/workspace/initialize-workspace.ts +43 -5
  533. package/src/langium/workspace/langium-documents.ts +124 -33
  534. package/src/langium/workspace/persistent-file-system-provider.ts +0 -7
  535. package/src/langium/workspace/virtual-document.ts +96 -19
  536. package/src/langium/workspace/write-lock-scope.ts +24 -11
  537. package/src/locale/index.ts +10 -0
  538. package/src/locale/server-locale.ts +86 -0
  539. package/src/lsp/completion/hydranium-completion-provider.ts +82 -2
  540. package/src/lsp/connection-features.ts +67 -0
  541. package/src/lsp/diagnostics-connection.ts +56 -0
  542. package/src/lsp/hydranium-document-update-handler.ts +185 -106
  543. package/src/lsp/index.ts +3 -1
  544. package/src/lsp/lsp-latency.ts +62 -0
  545. package/src/lsp/semantic-token-provider.ts +74 -7
  546. package/src/lsp/shared-module.ts +4 -8
  547. package/src/lsp/start-language-server.ts +13 -7
  548. package/src/messages/carriers.ts +78 -0
  549. package/src/messages/index.ts +36 -0
  550. package/src/messages/renderer.ts +212 -0
  551. package/src/node/heap-ceiling.ts +108 -0
  552. package/src/node/index.ts +1 -0
  553. package/src/node/latency-from-env.ts +1 -1
  554. package/src/node/measure-memory.ts +1 -0
  555. package/src/node/node-file-system-provider.ts +122 -51
  556. package/src/node/profile-capture.ts +8 -2
  557. package/src/node/profiling-run.ts +30 -8
  558. package/src/node/rename-over-open-readers.ts +78 -0
  559. package/src/node/socket-launcher.ts +19 -4
  560. package/src/node/stdio-launcher.ts +1 -2
  561. package/src/testing/fake-document.ts +24 -5
  562. package/src/testing/index.ts +2 -1
  563. package/src/testing/langium-test-helpers.ts +1 -0
  564. package/src/testing/make-noop-shared-services.ts +50 -2
  565. package/src/testing/make-test-services.ts +120 -31
  566. package/src/testing/node/index.ts +1 -0
  567. package/src/testing/node/lsp-harness.ts +2 -0
  568. package/src/testing/node/lsp-server-connection.ts +61 -11
  569. package/src/testing/node/scratch-workspace.ts +10 -5
  570. package/src/testing/node/spawned-server.ts +35 -1
  571. package/src/testing/node/unhandled-rejections.ts +31 -0
  572. package/src/testing/playwright/flaky-network-proxy.ts +240 -0
  573. package/src/testing/playwright/index.ts +1 -0
  574. package/src/testing/playwright/server-log-capture.ts +45 -11
  575. package/src/testing/playwright/server-log-rename-reporter.ts +12 -1
  576. package/src/testing/run-update-pipeline.ts +4 -4
  577. package/src/testing/stub-ast-document-manager.ts +40 -23
  578. package/src/testing/stub-document-builder.ts +83 -17
  579. package/src/testing/stub-hydranium-text-documents.ts +133 -23
  580. package/src/testing/stub-langium-documents.ts +3 -2
  581. package/src/testing/stub-model-service.ts +9 -8
  582. package/src/util/connection-liveness.ts +37 -14
  583. package/src/util/environment.ts +9 -1
  584. package/lib/lsp/instrument-connection.d.ts +0 -36
  585. package/lib/lsp/instrument-connection.d.ts.map +0 -1
  586. package/lib/lsp/instrument-connection.js +0 -62
  587. package/lib/lsp/instrument-connection.js.map +0 -1
  588. package/src/lsp/instrument-connection.ts +0 -66
@@ -8,11 +8,13 @@
8
8
  * SPDX-License-Identifier: MIT
9
9
  ********************************************************************************/
10
10
  import { NormalizedTextDocuments } from '@hydranium/langium/lsp';
11
+ import { type URI } from '@hydranium/langium';
11
12
  import { type ServerSharedServices } from '../langium/module.js';
12
- import { type ApplyWorkspaceEditResult, type CancellationToken, type Connection, type DidChangeTextDocumentParams, type DidCloseTextDocumentParams, type DidOpenTextDocumentParams, type DidSaveTextDocumentParams, type Disposable, type Emitter, type Event, type HandlerResult, type RequestHandler, type TextDocumentChangeEvent, type TextDocumentWillSaveEvent, type TextDocumentsConfiguration, type TextEdit, type WillSaveTextDocumentParams } from 'vscode-languageserver';
13
+ import { type ApplyWorkspaceEditResult, type CancellationToken, type Connection, type DidChangeTextDocumentParams, type DidCloseTextDocumentParams, type DidOpenTextDocumentParams, type DidSaveTextDocumentParams, type Disposable, Emitter, type Event, type HandlerResult, type RequestHandler, type TextDocumentChangeEvent, type TextDocumentWillSaveEvent, type TextDocumentsConfiguration, type TextEdit, type WillSaveTextDocumentParams } from 'vscode-languageserver';
13
14
  import { type DocumentUri, TextDocument, type TextDocumentContentChangeEvent } from 'vscode-languageserver-textdocument';
14
- import { type CanonicalUri, type LanguageClientUri, type Tracer } from '@hydranium/protocol';
15
+ import { type CanonicalUri, type LanguageClientUri, type Stopwatch, type TextState, type TextVersion, type Tracer } from '@hydranium/protocol';
15
16
  import { type LogNameOptions } from '../langium/diagnostics/logger.js';
17
+ import { type ClientSessionClosedEvent, ClientSessionRegistry, type SessionEndCause } from './client-session-registry.js';
16
18
  import { LanguageClientTextShadow } from './language-client-text-shadow.js';
17
19
  export interface ClientTextDocumentChangeEvent<T> extends TextDocumentChangeEvent<T> {
18
20
  clientId: string;
@@ -28,6 +30,56 @@ export interface HydraniumTextDocumentsOptions<T extends TextDocument = TextDocu
28
30
  * Adopters with a custom text-document type (rare) pass their factory.
29
31
  */
30
32
  readonly configuration?: TextDocumentsConfiguration<T>;
33
+ /**
34
+ * How long a document whose last open closed because its client's
35
+ * connection was lost keeps its text before it reverts to disk. An open by
36
+ * a client lost from the document, within this time of its own loss,
37
+ * cancels the revert, so a client that registers again under its id after
38
+ * a dropped connection finds its unsaved edits. Any other open releases the
39
+ * document first and then opens it as a first open does, from the text the
40
+ * opener supplies (an editor's own) or else from the file. Meanwhile the
41
+ * document counts as open for the integrity service, which therefore writes
42
+ * none of its unsaved text to disk. A close the client makes itself, or
43
+ * ending its session, reverts at once whatever this is.
44
+ *
45
+ * Defaults to 10 s. `0` reverts such a document at once as well, released
46
+ * in the close itself rather than on a timer.
47
+ */
48
+ readonly revertGraceMs?: number;
49
+ }
50
+ /** Delivered by {@link HydraniumTextDocuments.onDidSaveInLanguageClient}. */
51
+ export interface LanguageClientSavedEvent {
52
+ readonly uri: string;
53
+ }
54
+ /** Delivered by {@link HydraniumTextDocuments.onDidCloseLastOpen}. */
55
+ export interface LastOpenClosedEvent {
56
+ readonly uri: CanonicalUri;
57
+ }
58
+ /** Delivered by {@link HydraniumTextDocuments.onDidChangeDirty}. */
59
+ export interface DocumentDirtyChangedEvent {
60
+ readonly uri: CanonicalUri;
61
+ /**
62
+ * The text the new answer of {@link HydraniumTextDocuments.isDirty} was
63
+ * decided on. The answer changes with the text, before any build, so it can
64
+ * name text whose model has not been sent yet. Absent when the document no
65
+ * longer exists, or when the build that follows its release failed.
66
+ */
67
+ readonly text?: TextState;
68
+ }
69
+ /**
70
+ * The language client's open of a document under one URI, from its didOpen to
71
+ * its didClose. Each URI is its own editor buffer with its own version counter,
72
+ * so a file reached through a symlink and its real path has one of these each.
73
+ */
74
+ export interface LanguageClientDocumentState {
75
+ /** The version the client last declared for this URI. */
76
+ declaredVersion: number;
77
+ /**
78
+ * The version an applied versioned push moved this URI to, ahead of its
79
+ * echo. Apart from `declaredVersion`, whose staleness guard would drop that
80
+ * echo and strand its pending push.
81
+ */
82
+ pushedVersion?: number;
31
83
  }
32
84
  /**
33
85
  * All per-URI client-facing tracking the manager keys by normalized URI,
@@ -42,32 +94,60 @@ export interface HydraniumTextDocumentsOptions<T extends TextDocument = TextDocu
42
94
  * separately-tested diff/apply-verify abstraction that owns its own baseline
43
95
  * text; folding its storage here would couple a clean utility to this record
44
96
  * for no real gain.
97
+ *
98
+ * Returned by the `protected` {@link HydraniumTextDocuments.trackingFor}, so an
99
+ * override has to name it. Restating the shape structurally instead compiles
100
+ * until a field is added here, and then fails at the adopter rather than at the
101
+ * change that caused it.
45
102
  */
46
- interface DocumentTracking {
47
- /** Client ids currently holding this document open (multi-client membership). */
48
- readonly clients: Set<string>;
103
+ export interface DocumentTrackingRecord {
49
104
  /** Author of each version, sparse-indexed by the SHARED (server-assigned) version number. */
50
105
  readonly versionAuthors: string[];
51
106
  /**
52
107
  * Last version id each client declared for this document (didOpen baseline,
53
- * advanced by every accepted didChange). Client version ids are CLIENT-owned
54
- * per LSP (Monaco numbers its own buffer) and are used ONLY for this
55
- * per-client staleness guard — they never leak into the shared version
56
- * sequence, which the server assigns (see {@link HydraniumTextDocuments.__versionSequences}).
108
+ * advanced by every accepted didChange), for the per-client staleness guard.
109
+ * Client version ids are CLIENT-owned per LSP (Monaco numbers its own
110
+ * buffer) — they never leak into the shared version sequence, which the
111
+ * server assigns (see {@link HydraniumTextDocuments.__versionSequences}).
112
+ * The language client's entry is the latest any of its URIs declared; the
113
+ * store checks and addresses it per URI, through
114
+ * {@link DocumentTrackingRecord.languageClientDocuments}.
57
115
  */
58
116
  readonly clientVersions: Map<string, number>;
59
117
  /** Content staged by integrity rules for a closed document. Consumed on next open. */
60
118
  pendingContent?: string;
61
119
  /**
62
- * The URI(s) the LSP textual language client opened this (canonically-keyed)
63
- * document under. Usually one; a set because the same physical file can be
64
- * opened under more than one URI (a symlink path and its real path). This is
65
- * the egress address: `applyEditToLanguageClient`
66
- * targets these, since the document is *keyed* by its canonical identity but
67
- * Monaco holds it under the URI it opened. Lifecycle-bound — cleared with the
68
- * record on last close.
120
+ * Each URI the LSP textual language client opened this (canonically-keyed)
121
+ * document under, with that open's state. Usually one; more when the same
122
+ * file is opened under a symlink path and its real path. These are the
123
+ * egress addresses: the document is *keyed* by its canonical identity, but
124
+ * Monaco holds it under the URI it opened. The language client holds the
125
+ * document while any entry remains.
126
+ */
127
+ languageClientDocuments?: Map<LanguageClientUri, LanguageClientDocumentState>;
128
+ /**
129
+ * The clients whose close of this document was caused by a lost connection
130
+ * and that have not opened it again, each with a stopwatch started at its
131
+ * loss on the store's `Clock`. While the document waits out the revert grace, only an
132
+ * open by one of them within its own
133
+ * {@link HydraniumTextDocumentsOptions.revertGraceMs} of that loss cancels
134
+ * the revert. Every such client counts, not only the last to close: one
135
+ * connection's sessions all end lost together, and any of them may reopen
136
+ * first. Without the time limit, a client that returns late inherits the
137
+ * unsaved text of a holder lost after it. A stopwatch rather than a `now()`
138
+ * reading, because a wall-clock step would otherwise expire a claim early or
139
+ * revive one past its grace, against a grace timer that the step leaves
140
+ * alone. An entry past its grace counts as any other client's and is pruned
141
+ * at the next open of the document.
142
+ */
143
+ lostClients?: Map<string, Stopwatch>;
144
+ /**
145
+ * The text the server last knew the file to hold, `undefined` for no file.
146
+ * Set by the first open and moved by {@link HydraniumTextDocuments.updateDiskBaseline}.
69
147
  */
70
- languageClientUris?: Set<LanguageClientUri>;
148
+ diskBaseline?: string;
149
+ /** The last answer {@link HydraniumTextDocuments.onDidChangeDirty} announced. */
150
+ dirty?: boolean;
71
151
  }
72
152
  /**
73
153
  * A document held open by at least one client, with the client ids holding it —
@@ -80,70 +160,110 @@ export interface OpenDocument {
80
160
  readonly clients: readonly string[];
81
161
  }
82
162
  /**
83
- * Where a URI's shared version sequence left off — written once at last-client
84
- * close, consulted at the next open so the sequence CONTINUES instead of
85
- * restarting at whatever version id the reopening client declares. One entry
86
- * of {@link HydraniumTextDocuments.__versionSequences}.
163
+ * What {@link HydraniumTextDocuments.commitRepair} did with an integrity repair.
164
+ *
165
+ * Three outcomes rather than a document-or-nothing, because the two ways of
166
+ * getting nothing call for opposite responses: `not-open` means there is no
167
+ * store document to correct and the caller carries on with the one it holds,
168
+ * while `stale` means there IS one and it has moved past the text the repair
169
+ * was computed against — so carrying on would persist a correction over an edit
170
+ * that superseded it. Collapsing them lets the second read as permission to
171
+ * proceed, which is the failure this shape exists to make unrepresentable.
172
+ */
173
+ export type RepairCommit<T extends TextDocument> = {
174
+ readonly status: 'committed';
175
+ readonly document: T;
176
+ } | {
177
+ readonly status: 'stale';
178
+ } | {
179
+ readonly status: 'not-open';
180
+ };
181
+ /**
182
+ * Where a URI's shared version sequence left off while no client holds it —
183
+ * started by its first build, stepped by builds of changed text, written at
184
+ * last-client close, and consulted at the next open so the sequence CONTINUES
185
+ * instead of restarting at whatever version id the opening client declares. One entry
186
+ * of {@link HydraniumTextDocuments.__versionSequences} — a `protected` field, so
187
+ * a subclass reading the map has to name what it holds.
87
188
  */
88
- interface VersionSequence {
89
- /** The shared version at last-client close. */
189
+ export interface VersionSequence {
190
+ /** The shared version of the text last closed or built. */
90
191
  readonly version: number;
91
- /** {@link contentHash} of the synced text at last-client close. */
192
+ /** {@link textHash} of that text. */
92
193
  readonly contentHash: string;
93
194
  }
94
195
  /**
95
196
  * One text pushed to the LSP textual language client by
96
197
  * {@link HydraniumTextDocuments.applyEditToLanguageClient} whose echo has not
97
- * come back yet. One entry of {@link HydraniumTextDocuments.__pendingPushes}.
198
+ * come back yet. One entry of {@link HydraniumTextDocuments.__pendingPushes} —
199
+ * a `protected` field, so a subclass reading the queue has to name what it holds.
98
200
  */
99
- interface PendingPush {
201
+ export interface PendingLanguageClientPush {
100
202
  /**
101
- * The text the client held BEFORE this push — the shadow baseline the
102
- * push's edits were diffed against, and therefore the text the client's
103
- * echo addresses with its ranges.
203
+ * The text the client held BEFORE this push, and therefore the text its
204
+ * echo addresses with its ranges. Wider than the baseline the push's edits
205
+ * were diffed against: a full replace is sent with no diff baseline and
206
+ * still lands on a buffer the echo is keyed to.
104
207
  *
105
- * `undefined` when the push was a full replace sent with no baseline (a
106
- * first sync, or the recovery push after a rejection). There is then no
107
- * knowing what the client held, so the echo is reconstructed against the
108
- * synced text instead — which is sound for a full replace, whose
109
- * application is position-independent.
208
+ * `undefined` only when that buffer is unknown — the client never declared
209
+ * one, or a rejection invalidated what was tracked. The echo is then
210
+ * reconstructed against the synced text, which is sound only for a
211
+ * position-independent (full-text) change.
110
212
  */
111
213
  readonly before: string | undefined;
112
- /** {@link contentHash} of the text this push moves the client to. */
214
+ /** {@link textHash} of the text this push moves the client to. */
113
215
  readonly afterHash: string;
114
216
  }
115
217
  /**
116
218
  * What an incoming language-client change turns out to be once reconstructed
117
- * against the pushes still in flight — the return of
118
- * {@link HydraniumTextDocuments.classifyLanguageClientChange}.
219
+ * against the buffer its ranges address — the return of
220
+ * {@link HydraniumTextDocuments.classifyLanguageClientChange}. That method is
221
+ * `protected`, so an override has to name every arm it can return.
119
222
  */
120
- type LanguageClientChangeOrigin =
223
+ export type LanguageClientChangeOrigin =
121
224
  /** The client is reporting a text we pushed it. The synced document is already there. */
122
225
  {
123
226
  readonly kind: 'echo';
124
227
  }
125
228
  /**
126
- * The client's buffer has moved somewhere we did not push it — it coalesced
127
- * a genuine keystroke into the echo, or typed before the push arrived. The
128
- * reconstructed text is what it now holds, and is authoritative.
229
+ * The client's buffer holds a text we did not push it — a keystroke that
230
+ * raced a push, or an edit to a buffer the store has already been written
231
+ * past. The reconstructed text is what it now holds, and is authoritative.
129
232
  */
130
233
  | {
131
234
  readonly kind: 'divergent';
132
235
  readonly text: string;
236
+ }
237
+ /**
238
+ * The change carries ranges and no known text addresses them, so no
239
+ * reconstruction is offered. Adopting one anyway splices the document and
240
+ * stores an edit nobody made; dropping costs at most the one keystroke the
241
+ * client still holds and the next push contradicts.
242
+ */
243
+ | {
244
+ readonly kind: 'unreconstructable';
133
245
  };
134
246
  /**
135
247
  * Multi-client text-document tracking on top of Langium's `NormalizedTextDocuments`.
136
248
  *
137
249
  * Adds the framework features used by the integrity, model-server, and GLSP layers:
138
- * - Per-document client membership (multiple clients can attach to the same URI).
250
+ * - Per-document client membership (multiple clients can attach to the same
251
+ * URI) and the client-session table, both kept by {@link __sessions}.
139
252
  * - A SERVER-OWNED shared version sequence: per-URI, monotonic across
140
253
  * close/reopen cycles, advancing exactly when the synced content changes.
141
254
  * Client-declared version ids (Monaco's buffer numbering) feed only a
142
- * per-client staleness guard and never leak into the shared sequence —
255
+ * per-client staleness guard and never leak into a running sequence —
143
256
  * the two are different things (an editor's edit-operation counter vs the
144
257
  * document's content-revision number), and splicing them lets versions drift
145
- * silently past `baseVersion` gate holders.
258
+ * silently past base-version gate holders. A URI with no sequence, and no
259
+ * root that records a version, starts at its opener's declared id: no version
260
+ * was handed out for it.
146
261
  * - Version-author history so each edit is attributable to its originating client.
262
+ * - The revert to disk once no client has a document open, for every head
263
+ * ({@link revertToDisk}), deferred by
264
+ * {@link HydraniumTextDocumentsOptions.revertGraceMs} after a lost connection.
265
+ * - A disk baseline per open document, and whether its text differs from it
266
+ * ({@link isDirty}).
147
267
  * - Pending-content staging used by the integrity service to thread corrections
148
268
  * through `workspace/applyEdit` cycles for currently-closed documents.
149
269
  * - `didOpen` notifications arriving over the LSP connection wait on the
@@ -154,34 +274,54 @@ type LanguageClientChangeOrigin =
154
274
  export declare class HydraniumTextDocuments<T extends TextDocument = TextDocument> extends NormalizedTextDocuments<T> {
155
275
  protected services: ServerSharedServices;
156
276
  /**
157
- * Per-URI client-facing tracking ({@link DocumentTracking}): client
158
- * membership, version-author history, and integrity-staged pending content,
159
- * keyed by normalized URI. One record per URI so the last-client close clears
160
- * every axis atomically. The language-client diff baseline stays in
161
- * {@link __shadow} (its own abstraction); the parsed-document store stays in
162
- * the inherited `__syncedDocuments`.
277
+ * Per-URI client-facing tracking ({@link DocumentTrackingRecord}), keyed by
278
+ * canonical URI. One record per URI, so dropping it clears every axis at
279
+ * once. Which client has the document open is kept apart, in
280
+ * {@link __sessions}.
281
+ */
282
+ protected __documents: Map<CanonicalUri, DocumentTrackingRecord>;
283
+ /**
284
+ * Which client has which document open, and which client ids are registered
285
+ * sessions. Every open-state predicate on this class reads it, so an open
286
+ * recorded anywhere else is invisible to the last-close transition.
163
287
  */
164
- protected __documents: Map<CanonicalUri, DocumentTracking>;
288
+ protected readonly __sessions: ClientSessionRegistry;
165
289
  /**
166
290
  * Per-URI shared-version continuity across close/reopen cycles
167
- * ({@link VersionSequence}), written at last-client close and consulted by
168
- * the next first-client open. DELIBERATELY outside {@link DocumentTracking}:
169
- * that record is deleted on last close, while the version sequence must
291
+ * ({@link VersionSequence}), kept for every document a build or a client
292
+ * gave the store, and consulted by the next first-client open. A URI
293
+ * with none, and no root that records a version, starts at its opener's
294
+ * declared version.
295
+ * DELIBERATELY outside {@link DocumentTrackingRecord}: that record is deleted on last close, while the version sequence must
170
296
  * survive it — the shared version is a server-owned, monotonic,
171
297
  * advances-iff-content-changes counter that never resets while the server
172
- * lives. That invariant is what makes an optimistic `baseVersion` gate
298
+ * lives. That invariant is what makes an optimistic base-version gate
173
299
  * sound: "version unchanged ⇔ content unchanged", with no false conflicts
174
300
  * from close/reopen version resets and no false passes from a reopened
175
301
  * sequence coincidentally landing on a stale writer's number.
176
302
  *
177
- * Never pruned: two small values per URI ever touched — bounded by
178
- * workspace size, not by activity.
303
+ * Never pruned, not even when the file is deleted: a recreated file
304
+ * restarting at `0` would let a write based on the deleted text pass. Two
305
+ * small values per URI ever built, however often it changes.
179
306
  */
180
307
  protected readonly __versionSequences: Map<CanonicalUri, VersionSequence>;
308
+ /**
309
+ * Released documents last announced dirty. Their clean flip waits for the
310
+ * revert, so it carries the reverted text's version; a first open before the
311
+ * revert takes the entry over, and its own dirty answer decides the flip.
312
+ * Each release enters a token of its own, so the revert of an earlier
313
+ * release cannot announce a later one clean before that one's revert.
314
+ */
315
+ protected readonly __releasedDirty: Map<CanonicalUri, object>;
316
+ /** Per held document, the {@link textHash} of its text at the version it was taken. */
317
+ protected readonly __textHashes: WeakMap<TextDocument, {
318
+ readonly version: number;
319
+ readonly hash: string;
320
+ }>;
181
321
  /**
182
322
  * Texts pushed to the LSP textual language client via
183
323
  * {@link applyEditToLanguageClient} whose echoes have not come back yet
184
- * ({@link PendingPush}), keyed like the shadow by language-client URI.
324
+ * ({@link PendingLanguageClientPush}), keyed like the shadow by language-client URI.
185
325
  * Outbound pushes and inbound echoes are uncorrelated on the wire; this
186
326
  * FIFO is the explicit correlation, and it is what
187
327
  * {@link classifyLanguageClientChange} reconstructs against.
@@ -203,7 +343,7 @@ export declare class HydraniumTextDocuments<T extends TextDocument = TextDocumen
203
343
  * a pathological echo that never arrives; the memory cost until then is
204
344
  * one pre-push text per in-flight push, for milliseconds.
205
345
  */
206
- protected readonly __pendingPushes: Map<LanguageClientUri, PendingPush[]>;
346
+ protected readonly __pendingPushes: Map<LanguageClientUri, PendingLanguageClientPush[]>;
207
347
  /**
208
348
  * Tracked text content per URI for the LSP textual language client (Monaco / VS Code).
209
349
  * Owned here so {@link applyEditToLanguageClient} can compute minimal `workspace/applyEdit`
@@ -226,6 +366,11 @@ export declare class HydraniumTextDocuments<T extends TextDocument = TextDocumen
226
366
  protected readonly __shadow: LanguageClientTextShadow;
227
367
  protected readonly tracer: Tracer;
228
368
  protected readonly configuration: TextDocumentsConfiguration<T>;
369
+ /** See {@link HydraniumTextDocumentsOptions.revertGraceMs}. */
370
+ protected readonly revertGraceMs: number;
371
+ protected readonly lastOpenClosedEmitter: Emitter<LastOpenClosedEvent>;
372
+ protected readonly languageClientSavedEmitter: Emitter<LanguageClientSavedEvent>;
373
+ protected readonly dirtyChangedEmitter: Emitter<DocumentDirtyChangedEvent>;
229
374
  constructor(services: ServerSharedServices, options?: HydraniumTextDocumentsOptions<T>);
230
375
  create(uri: string, languageId: string, version: number, content: string): T;
231
376
  update(document: T, changes: TextDocumentContentChangeEvent[], version: number): T;
@@ -254,17 +399,119 @@ export declare class HydraniumTextDocuments<T extends TextDocument = TextDocumen
254
399
  * A content-identical write still fires the change event (rebuild): the
255
400
  * authored write's server-side rebuild is correctness-bearing, it just
256
401
  * mints no new version — nothing observable changed, so watchers'
257
- * `baseVersion` pointers stay valid.
402
+ * base versions stay valid.
258
403
  *
259
404
  * Returns the resulting shared version. Throws when the document is not
260
405
  * open — callers (`AstDocumentManager.update`) open first.
261
406
  */
262
- applyContentChange(uri: DocumentUri, text: string, clientId: string): number;
263
- notifyDidCloseTextDocument(event: DidCloseTextDocumentParams, clientId?: string): void;
407
+ applyContentChange(uri: DocumentUri, text: string, clientId: string): TextVersion;
408
+ /**
409
+ * Close `clientId`'s open of the document. When it was the last open, the
410
+ * document is released and reverts to disk, at once or, for a `'lost'`
411
+ * close, after {@link HydraniumTextDocumentsOptions.revertGraceMs}.
412
+ */
413
+ notifyDidCloseTextDocument(event: DidCloseTextDocumentParams, clientId?: string, cause?: SessionEndCause): void;
414
+ /**
415
+ * Keep the document, text and all, for the revert grace, then release it.
416
+ * The document stays in the store meanwhile, so a lost client that opens it
417
+ * again within its own grace attaches to it and finds its unsaved text
418
+ * rather than reading disk; see {@link resolvePendingRevert} for any other
419
+ * open.
420
+ */
421
+ protected deferRelease(uri: CanonicalUri): void;
422
+ /**
423
+ * Resolve the pending revert of `uri` for an open by `clientId`. An open by a
424
+ * client lost from the document within its grace cancels the revert, and
425
+ * the client finds its unsaved text. Any other open releases the document
426
+ * first, so it opens as a first open does: cancelling for every open hands
427
+ * a lost client's unsaved text to whoever opens next, a reloaded page or an
428
+ * editor, with nothing marking it unsaved.
429
+ */
430
+ protected resolvePendingRevert(uri: CanonicalUri, clientId: string): void;
431
+ /** Drop the entries of {@link DocumentTrackingRecord.lostClients} whose grace has run out. */
432
+ protected pruneLostClients(record: DocumentTrackingRecord): void;
433
+ /**
434
+ * Drop the document no client has open any more, then announce it on
435
+ * {@link onDidCloseLastOpen}, which is what reverts it to disk.
436
+ */
437
+ protected releaseDocument(uri: CanonicalUri): void;
438
+ /**
439
+ * Rebuild a released document from the file system provider, so the build
440
+ * stops carrying the unsaved text of its last client.
441
+ *
442
+ * The provider decides, for every scheme, by `exists`: a document it can
443
+ * serve is rebuilt from its text, and any other — an editor's `untitled:`
444
+ * buffer, a file never saved, or one deleted meanwhile — is removed
445
+ * from the workspace. A `virtual:` document survives, since the framework's
446
+ * provider for that scheme serves it from the index, whatever provider the
447
+ * host passes as `context.fileSystemProvider`; an edited one therefore keeps
448
+ * its last client's text, and keeping it read-only is the client's job.
449
+ *
450
+ * The answer is read in the document's disk queue, so the rebuild follows
451
+ * any save still queued rather than reverting past it; a file that goes
452
+ * after that read is removed when its rebuild finds none.
453
+ *
454
+ * Whether to revert at all is decided inside the write lock, as its holder:
455
+ * decided before waiting for the lock, a client that opens or re-creates the
456
+ * document meanwhile would have its text rebuilt over, or the document
457
+ * removed. A document some client has open again, or that waits out a new
458
+ * grace, is left to that client.
459
+ *
460
+ * A document released dirty is announced clean, so a watcher is never left
461
+ * holding it dirty: once the revert has parsed the file, even if it is then
462
+ * cancelled, or else once the build it requests in its place has parsed it,
463
+ * as the announcement names the store's text. One the revert or that build
464
+ * removed, or that build failed, is announced without text. A reopen before
465
+ * that takes the announcement over.
466
+ */
467
+ protected revertToDisk(uri: CanonicalUri): Promise<void>;
264
468
  notifyWillSaveTextDocument(event: WillSaveTextDocumentParams): void;
265
469
  notifyWillSaveTextDocumentWaitUntil(event: WillSaveTextDocumentParams, token: CancellationToken): HandlerResult<TextEdit[], void>;
470
+ /**
471
+ * Handle a save the language client reports: fire
472
+ * {@link onDidSaveInLanguageClient}, then announce it on {@link onDidSave}
473
+ * only once the file read back from disk holds the store's current text.
474
+ */
475
+ protected notifyLanguageClientSave(event: DidSaveTextDocumentParams): Promise<void>;
476
+ /**
477
+ * Announce a save the server made. `event.text`, when given, is what the
478
+ * file now holds, written or found there, and becomes the disk baseline
479
+ * before the save is announced. It lags the store when an edit landed
480
+ * after the save took its text, and the document then stays dirty.
481
+ */
266
482
  notifyDidSaveTextDocument(event: DidSaveTextDocumentParams, clientId?: string): void;
483
+ /** Fire {@link onDidSave} for `document`, which need not be synced any more. */
484
+ protected announceSave(document: T, clientId: string): void;
267
485
  notifyDidOpenTextDocument(event: DidOpenTextDocumentParams, clientId?: string): void;
486
+ /**
487
+ * Record `clientId` as an additional holder of a document another client
488
+ * already has open.
489
+ *
490
+ * Unlike the attach branch of {@link notifyDidOpenTextDocument} this does
491
+ * not refresh. That branch re-renders an attaching TEXTUAL view; a client
492
+ * reaching a document through a non-textual route has nothing to re-render,
493
+ * and refreshing per attach turns each into a Langium rebuild and dependent
494
+ * relink cascade.
495
+ *
496
+ * The staleness guard baselines at the SYNCED version, not a declared buffer
497
+ * version, because a client arriving this way holds no buffer of its own.
498
+ * Unifying the two routes therefore rebaselines a textual client's guard to a
499
+ * version it never declared.
500
+ *
501
+ * Returns whether a hold was added — `false` when `uri` is not open,
502
+ * `clientId` already holds it, or the document was waiting out the revert
503
+ * grace for other clients and was released instead (see
504
+ * {@link resolvePendingRevert}); the caller then opens it anew.
505
+ */
506
+ attachClient(uri: DocumentUri, clientId: string): boolean;
507
+ /**
508
+ * The built root's recorded version, one on when `text` differs from the root's;
509
+ * `declared` when the root records no store version. Seeded from `declared`, a write based
510
+ * on the root passes the gate over other text, and the same text looks newer than its model.
511
+ * A built root has no sequence only under a `LangiumDocuments` that does not reconcile at registration.
512
+ */
513
+ protected firstOpenVersion(uri: CanonicalUri, text: string, declared: number): number;
514
+ protected logClientJoined(uri: DocumentUri, clientId: string, version: number, existingClients: readonly string[]): void;
268
515
  refreshContent(uri: DocumentUri, clientId: string): void;
269
516
  /**
270
517
  * The canonical key a document is stored under — the single point this store
@@ -273,7 +520,7 @@ export declare class HydraniumTextDocuments<T extends TextDocument = TextDocumen
273
520
  * two URIs for one physical file (a symlink path and its real path) into a
274
521
  * single registration — dedup at the editor layer, not just in
275
522
  * `LangiumDocuments`. The URI the client opened under is preserved separately
276
- * for egress addressing (see {@link DocumentTracking.languageClientUris}). The
523
+ * for egress addressing (see {@link DocumentTrackingRecord.languageClientDocuments}). The
277
524
  * policy is always bound (the framework defaults it to
278
525
  * `DefaultDocumentUriPolicy`, where canonical ≡ syntactic normalize).
279
526
  */
@@ -288,7 +535,7 @@ export declare class HydraniumTextDocuments<T extends TextDocument = TextDocumen
288
535
  */
289
536
  protected toLanguageClientUri(uri: string): LanguageClientUri;
290
537
  /** Get-or-create the per-URI tracking record. `uri` must already be a {@link documentKey}. */
291
- protected trackingFor(uri: CanonicalUri): DocumentTracking;
538
+ protected trackingFor(uri: CanonicalUri): DocumentTrackingRecord;
292
539
  setAuthor(uri: DocumentUri, version: number, author: string): void;
293
540
  /**
294
541
  * Resolve the synced `TextDocument` for `uri`. The store keys documents by
@@ -309,39 +556,83 @@ export declare class HydraniumTextDocuments<T extends TextDocument = TextDocumen
309
556
  get(uri: DocumentUri): T | undefined;
310
557
  /**
311
558
  * Current SHARED version of the document at `uri`: the open document's
312
- * version, else where the persisted sequence left off at last close, else
313
- * `0` for a URI this store has never seen. The shared sequence is
559
+ * version, else where its persisted sequence left off, else `0` for a URI
560
+ * this store has never seen. The shared sequence is
314
561
  * server-owned and monotonic across close/reopen cycles, and advances
315
562
  * exactly when the synced content changes — which is what makes it a sound
316
- * optimistic-concurrency token (`baseVersion` gates): version unchanged ⇔
563
+ * optimistic-concurrency token (base-version gates): version unchanged ⇔
317
564
  * content unchanged.
318
565
  */
319
- version(uri: DocumentUri): number;
566
+ version(uri: DocumentUri): TextVersion;
567
+ /**
568
+ * The text the store holds for `uri`: an open document's, or for a closed
569
+ * one, the clean text its version sequence left off at, which for a deleted
570
+ * document is its last text. `undefined` for a URI no build and no client
571
+ * gave the store.
572
+ */
573
+ textState(uri: DocumentUri): TextState | undefined;
574
+ /**
575
+ * {@link textHash} of `document`'s text, taken once per version: the store
576
+ * moves a document's version with every change of its text.
577
+ */
578
+ protected heldTextHash(document: T): string;
320
579
  /**
321
580
  * Reconcile the persisted version sequence with content that reached the
322
581
  * build OUTSIDE the store's write paths — a closed document rebuilt from
323
582
  * disk (last-close revert) or replaced by a watched-file change. Steps the
324
583
  * sequence iff `text` differs from the sequence's last-known content and
325
584
  * returns the resulting sequence version so the caller can re-stamp the
326
- * rebuilt document (see the `AstDocumentManager` Parsed-phase listener) —
585
+ * rebuilt document (`VersionSyncService.modelProduced`) —
327
586
  * keeping the "version advances iff content changes" invariant for
328
587
  * documents no client currently holds.
329
588
  *
330
- * Returns `undefined` — and does nothing — when the document is open (the
331
- * store's own content is authoritative; external transitions never reach
332
- * the Langium factory for open documents) or was never tracked (no gate
333
- * holder can hold a version pointer for it, and the early exit keeps
334
- * workspace-wide builds from hashing every untouched document).
589
+ * For an open document, its version when it holds `text`, since a build
590
+ * that read the file while the document was closed can finish after an
591
+ * open; else `undefined`, and the caller has to build the document again.
592
+ *
593
+ * A document without a sequence starts one at `0` with `text`: snapshots
594
+ * hand out versions for documents no client opened, so an uncounted change
595
+ * would let a write based on the old text pass the gate.
335
596
  */
336
597
  reconcileExternalContent(uri: DocumentUri, text: string): number | undefined;
598
+ /**
599
+ * Commit an integrity repair into the OPEN document for `uri`, returning the
600
+ * document that now holds it, or `undefined` when there was nothing here to
601
+ * commit into.
602
+ *
603
+ * The one thing this exists to do is address the store BY URI. A repair
604
+ * reaches the resync as a text-document object, and that object is the
605
+ * store's own only on the LSP path; a document built for an already-open URI
606
+ * through `LangiumDocumentFactory.fromString` carries its own, so writing the
607
+ * repair into it corrects a copy the store does not know about and the editor
608
+ * never sees.
609
+ *
610
+ * `parsedFrom` is the text the repaired AST was parsed from, and a mismatch
611
+ * against the current content REFUSES the commit: the store has moved on,
612
+ * which means an editor change landed after that parse, and committing would
613
+ * overwrite a newer edit with a repair computed against text the user has
614
+ * already replaced. The build that change provokes recomputes the repair.
615
+ *
616
+ * Deliberately NOT compared by version. A separately created document seeds
617
+ * its own numbering, so requiring the two to agree would refuse every commit
618
+ * on the path this exists for. Content is the thing both sides can be held to.
619
+ *
620
+ * A changed text is a new version authored by {@link INTEGRITY_CLIENT_ID}.
621
+ * Kept at the old version, the repair is invisible to every reader keyed on
622
+ * versions: a write based on the unrepaired version passes the base-version gate
623
+ * and replaces the repair, and an echo filter credits the repair to the
624
+ * client whose edit it corrected. No change event is fired: the repair
625
+ * rides the build already under way, and an event would re-enter it.
626
+ */
627
+ commitRepair(uri: DocumentUri, parsedFrom: string, repaired: string): RepairCommit<T>;
337
628
  getAuthor(uri: DocumentUri, version?: number): string | undefined;
338
629
  isOpen(uri: DocumentUri): boolean;
339
630
  /**
340
631
  * True iff any client still holds `uri` open. Distinct from {@link isOpen},
341
632
  * which reads `__syncedDocuments` — that map is cleared only AFTER the
342
633
  * `onDidClose` event fires for the last client, so `isOpen` returns `true`
343
- * during the close event itself. `isOpenInAnyClient` reads the tracking
344
- * record's `clients` set, which is updated BEFORE the fire, so an `onDidClose`
634
+ * during the close event itself. `isOpenInAnyClient` reads the open table
635
+ * ({@link __sessions}), which is updated BEFORE the fire, so an `onDidClose`
345
636
  * subscriber that finds this `false` knows the last client just closed and a
346
637
  * disk re-read / rebuild can proceed.
347
638
  */
@@ -351,8 +642,8 @@ export declare class HydraniumTextDocuments<T extends TextDocument = TextDocumen
351
642
  isOnlyOpenInClient(uri: DocumentUri, client: string): boolean;
352
643
  /**
353
644
  * Every document currently held open by at least one client, with the client
354
- * ids holding it. Reads the same per-URI tracking records as
355
- * {@link isOpenInAnyClient}, so it reflects a last-client close immediately.
645
+ * ids holding it. Reads the same open table as {@link isOpenInAnyClient}, so
646
+ * it reflects a last-client close immediately.
356
647
  *
357
648
  * Diagnostics-oriented — the server-state snapshot lists these so an operator
358
649
  * can see WHY a document is pinned: a document that lingers here after its
@@ -360,19 +651,143 @@ export declare class HydraniumTextDocuments<T extends TextDocument = TextDocumen
360
651
  * under a shedding policy, explains why its CST is never shed).
361
652
  */
362
653
  openDocuments(): OpenDocument[];
654
+ /** Fires once a client session has ended, after every document it had open was closed. */
655
+ get onDidCloseSession(): Event<ClientSessionClosedEvent>;
656
+ /**
657
+ * Fires once a document no client has open is released: at its last close,
658
+ * or, for a lost client's last close, when its revert grace runs out,
659
+ * another client opens it, or it is deleted. The document then reverts to
660
+ * disk.
661
+ */
662
+ get onDidCloseLastOpen(): Event<LastOpenClosedEvent>;
663
+ /**
664
+ * Fires for every save the language client reports of a document it has
665
+ * open: the editor has written the file. {@link onDidSave} follows only
666
+ * when the file holds the store's text.
667
+ */
668
+ get onDidSaveInLanguageClient(): Event<LanguageClientSavedEvent>;
669
+ /**
670
+ * Whether `uri` is waiting out the revert grace: its last open closed with a
671
+ * lost connection, and it still holds its unsaved text. Such a document is
672
+ * open for no client, yet not closed either, so a caller that would persist
673
+ * a closed document's text to disk treats it as open.
674
+ */
675
+ isRevertPending(uri: DocumentUri): boolean;
676
+ /**
677
+ * Whether the store holds `uri` with text that differs from its disk
678
+ * baseline: what the server last knew the file to hold. `false` for a URI
679
+ * the store does not hold; a document waiting out the revert grace is still
680
+ * held.
681
+ *
682
+ * The baseline is the text a first open brought, or what the server wrote,
683
+ * or read back after an editor's save or a watched-file change, so it can
684
+ * trail a change to the file that none of these has seen yet. A check that
685
+ * must know the file reads it instead.
686
+ */
687
+ isDirty(uri: DocumentUri): boolean;
688
+ /**
689
+ * Fires each time the answer of {@link isDirty} changes. A dirty document's
690
+ * release fires once a parse of the file reaches the store, at that text's
691
+ * version, or without text once its revert removed the document or could
692
+ * not rebuild it, though {@link isDirty} answers clean from the release on.
693
+ */
694
+ get onDidChangeDirty(): Event<DocumentDirtyChangedEvent>;
695
+ /**
696
+ * Record that the file behind `uri` holds `text`, or no file at all for
697
+ * `undefined`. A no-op for a URI the store does not hold: the next first
698
+ * open sets the baseline from its own text.
699
+ */
700
+ updateDiskBaseline(uri: DocumentUri, text: string | undefined): void;
701
+ /**
702
+ * Read the file behind `uri` through its disk queue and take it as the
703
+ * baseline. A file that cannot be read counts as none, the side that
704
+ * leaves the document dirty.
705
+ */
706
+ reloadDiskBaseline(uri: DocumentUri): Promise<void>;
707
+ /** Compare the held text of `uri` with its baseline, and announce a changed answer. */
708
+ protected refreshDirty(uri: CanonicalUri): void;
709
+ /**
710
+ * Start a client session under `clientId`. Throws where
711
+ * {@link ClientSessionRegistry.register} refuses the id.
712
+ */
713
+ registerSession(clientId: string): void;
714
+ /**
715
+ * End the client session `clientId`: close every document it has open, then
716
+ * free the id. Immediate — each close runs the ordinary close path before
717
+ * this returns, with `cause` as its cause. A no-op for an id that is not a
718
+ * registered session.
719
+ */
720
+ closeSession(clientId: string, cause?: SessionEndCause): void;
721
+ /**
722
+ * Close every document the language client has open, as a `didClose` for
723
+ * each would, so each last close reverts. For a host whose editor connection
724
+ * can end while the process lives on, such as a worker whose port's peer
725
+ * closed: the language client is no session, so nothing else closes them.
726
+ *
727
+ * It first waits for the workspace initialization the open handler waits
728
+ * for, so an open that arrived before the close is closed too; closing at
729
+ * once would leave that open to land afterwards, held by a client that is
730
+ * gone.
731
+ */
732
+ closeLanguageClientDocuments(): Promise<void>;
733
+ /**
734
+ * Settles once the initial workspace build has finished, whether it
735
+ * completed, was cancelled or failed. Awaiting `workspaceInitialized` itself
736
+ * throws after a cancelled build, which any write during startup causes, and
737
+ * every open and close gated on it is then dropped for the process lifetime.
738
+ * The workspace manager logs a failed build.
739
+ */
740
+ protected initialBuildFinished(): Promise<void>;
741
+ /**
742
+ * Stop tracking every URI the language client holds the document `key`
743
+ * under, with its shadow and pending pushes. Call before a close by
744
+ * canonical key that means all of them: a close for one URI while others
745
+ * remain drops only that URI's and keeps the client's hold.
746
+ */
747
+ protected untrackLanguageClientDocuments(key: CanonicalUri): void;
748
+ /**
749
+ * The file behind `uri` was deleted: close every open of it except the
750
+ * language client's.
751
+ *
752
+ * The editor's open is left alone because the editor owns it: it keeps the
753
+ * buffer of a deleted file and goes on sending changes for it, and a store
754
+ * that had closed the document would drop every one of them until the editor
755
+ * reopened.
756
+ */
757
+ notifyDocumentDeleted(uri: DocumentUri): void;
758
+ /**
759
+ * Remove the document for `uri`, closing every open of it first — the
760
+ * editor's included, since the document it would keep editing is gone.
761
+ *
762
+ * The base removes the synced document without consulting the open table,
763
+ * which leaves every open recorded against a document that no longer exists:
764
+ * the store then answers that the URI is open, and the next open attaches to
765
+ * nothing.
766
+ */
767
+ delete(uri: string | URI | T): void;
768
+ /**
769
+ * A client id as log lines print it. An id containing `#` is cut eight
770
+ * characters after its last `#`, which leaves a minted `label#uuid` as the
771
+ * label and enough of the UUID to tell sessions apart; an id without `#`
772
+ * prints whole. The full id goes out at trace level wherever a session
773
+ * starts or ends.
774
+ */
775
+ protected formatClientId(clientId: string): string;
363
776
  /**
364
- * Stages integrity-updated content for a closed document.
777
+ * Stages integrity-updated content for a document no client holds.
365
778
  *
366
779
  * When `workspace/applyEdit` targets a closed file, the client opens it from
367
780
  * disk (stale) and sends `didOpen` before applying the edit. This staged
368
781
  * content is consumed by {@link notifyDidOpenTextDocument} to replace the
369
782
  * stale disk text, preventing a brief revert of the integrity update.
370
783
  *
371
- * Not cleared on close: pending content is only staged for already-closed
372
- * documents (the integrity service checks `isOpenInLanguageClient` first), so
373
- * a close → stage → open cycle cannot occur. The only scenario where an
374
- * entry lingers is if `workspace/applyEdit` fails and the file is never
375
- * opened — the memory cost is one serialised string per URI.
784
+ * Only a FIRST open consumes it, so stage only for a URI no client holds
785
+ * ({@link isOpenInAnyClient} is `false`). A URI held only through another
786
+ * head is not closed: an editor attaching to it joins the existing entry and
787
+ * never reads the stage, and the last close discards the stage with the
788
+ * tracking record. An entry lingers only if `workspace/applyEdit` fails and
789
+ * the file is never opened — the memory cost is one serialised string per
790
+ * URI.
376
791
  */
377
792
  stagePendingContent(uri: DocumentUri, text: string): void;
378
793
  /**
@@ -402,8 +817,9 @@ export declare class HydraniumTextDocuments<T extends TextDocument = TextDocumen
402
817
  * and the client applying, the ranges address the wrong lines and splice the
403
818
  * buffer (observed as a duplicated declaration, which the integrity tier then
404
819
  * "repairs" into a suffixed name and persists). The edit is therefore
405
- * addressed at the language client's LAST DECLARED VERSION rather than at
406
- * `null` ("version intentionally unknown"), which is what lets the client
820
+ * addressed at the language client's last known version for that URI (see
821
+ * {@link languageClientVersion}) rather than at `null` ("version
822
+ * intentionally unknown"), which is what lets the client
407
823
  * reject a push its buffer has outrun. On rejection the shadow is invalidated,
408
824
  * so the caller's retry is a full-range replace — position-independent, and
409
825
  * safe to apply to whatever the client now holds.
@@ -412,20 +828,22 @@ export declare class HydraniumTextDocuments<T extends TextDocument = TextDocumen
412
828
  label?: string;
413
829
  }): Promise<ApplyWorkspaceEditResult | undefined>;
414
830
  /**
415
- * The version the LSP textual language client last declared for `uri`, for
416
- * addressing an outgoing `workspace/applyEdit`.
831
+ * The version the LSP textual language client holds `uri` at under
832
+ * `targetUri`, for addressing an outgoing `workspace/applyEdit`.
417
833
  *
418
834
  * Client version ids are CLIENT-owned per LSP, so this is the id the client
419
- * itself stamped on its last `didOpen` / `didChange` — never the shared
420
- * server version, which advances on authored writes the client knows nothing
421
- * about and would therefore reject every push.
835
+ * itself stamped on its last `didOpen` / `didChange` for `targetUri`, or the
836
+ * one an applied push moved it to ahead of the push's echo
837
+ * ({@link LanguageClientDocumentState}) — never the shared server version,
838
+ * which advances on authored writes the client knows nothing about and would
839
+ * therefore reject every push.
422
840
  *
423
- * Falls back to {@link UNKNOWN_CLIENT_VERSION} when the client has never
424
- * declared one, which is the honest answer for a document it has not opened.
425
- * That is also the case in which there is no shadow, so the push is already a
841
+ * Falls back to {@link UNKNOWN_CLIENT_VERSION} when the client has not opened
842
+ * the document under `targetUri`, which is the honest answer. That is also
843
+ * the case in which there is no shadow, so the push is already a
426
844
  * position-independent full replace and has nothing to gain from a gate.
427
845
  */
428
- protected languageClientVersion(uri: DocumentUri): number;
846
+ protected languageClientVersion(uri: DocumentUri, targetUri?: LanguageClientUri): number;
429
847
  /**
430
848
  * Append a push to the in-flight queue for `targetUri`
431
849
  * (see {@link __pendingPushes}). Bounded: beyond
@@ -436,12 +854,17 @@ export declare class HydraniumTextDocuments<T extends TextDocument = TextDocumen
436
854
  protected recordPendingPush(targetUri: LanguageClientUri, before: string | undefined, newText: string): void;
437
855
  /**
438
856
  * Decide what an incoming language-client change actually is, by
439
- * reconstructing the client's resulting buffer against the OLDEST push still
440
- * in flight for `clientFacing`.
857
+ * reconstructing the client's resulting buffer against the text its ranges
858
+ * address — the pre-push buffer of the OLDEST push still in flight for
859
+ * `clientFacing`, else whatever that client is believed to hold.
441
860
  *
442
- * `undefined` when nothing of ours is in flight, which is the ordinary path:
443
- * the client's ranges then address the synced text and the caller applies
444
- * them to it directly.
861
+ * `undefined` when the client's ranges address the synced text itself —
862
+ * nothing in flight, and no evidence the client holds anything else. That
863
+ * is the ordinary path, and the caller then applies the ranges directly.
864
+ * The two texts part company without a push in flight whenever a client
865
+ * attaches to a document another client has already written: it opened
866
+ * from disk, so applying its ranges to the synced text splices lines they
867
+ * never addressed.
445
868
  *
446
869
  * **Why the oldest, and why reconstruct at all.** The client applies our
447
870
  * pushes in order and echoes each against the buffer it held before that
@@ -486,5 +909,4 @@ export declare class HydraniumTextDocuments<T extends TextDocument = TextDocumen
486
909
  dispose(): void;
487
910
  };
488
911
  }
489
- export {};
490
912
  //# sourceMappingURL=hydranium-text-documents.d.ts.map