@hydranium/core 1.0.0-next.38 → 1.0.0-next.380

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 (805) hide show
  1. package/README.md +78 -82
  2. package/lib/browser/host-heads-in-worker.d.ts +77 -0
  3. package/lib/browser/host-heads-in-worker.d.ts.map +1 -0
  4. package/lib/browser/host-heads-in-worker.js +169 -0
  5. package/lib/browser/host-heads-in-worker.js.map +1 -0
  6. package/lib/browser/index.d.ts +12 -0
  7. package/lib/browser/index.d.ts.map +1 -0
  8. package/lib/browser/index.js +17 -0
  9. package/lib/browser/index.js.map +1 -0
  10. package/lib/browser/indexeddb-file-system-store.d.ts +82 -0
  11. package/lib/browser/indexeddb-file-system-store.d.ts.map +1 -0
  12. package/lib/browser/indexeddb-file-system-store.js +181 -0
  13. package/lib/browser/indexeddb-file-system-store.js.map +1 -0
  14. package/lib/browser/start-language-server-in-worker.d.ts +32 -0
  15. package/lib/browser/start-language-server-in-worker.d.ts.map +1 -0
  16. package/lib/browser/start-language-server-in-worker.js +40 -0
  17. package/lib/browser/start-language-server-in-worker.js.map +1 -0
  18. package/lib/documents/ast-document-manager.d.ts +254 -140
  19. package/lib/documents/ast-document-manager.d.ts.map +1 -1
  20. package/lib/documents/ast-document-manager.js +311 -127
  21. package/lib/documents/ast-document-manager.js.map +1 -1
  22. package/lib/documents/client-ids.d.ts +5 -19
  23. package/lib/documents/client-ids.d.ts.map +1 -1
  24. package/lib/documents/client-ids.js +5 -19
  25. package/lib/documents/client-ids.js.map +1 -1
  26. package/lib/documents/client-session-errors.d.ts +15 -0
  27. package/lib/documents/client-session-errors.d.ts.map +1 -0
  28. package/lib/documents/client-session-errors.js +15 -0
  29. package/lib/documents/client-session-errors.js.map +1 -0
  30. package/lib/documents/client-session-registry.d.ts +146 -0
  31. package/lib/documents/client-session-registry.d.ts.map +1 -0
  32. package/lib/documents/client-session-registry.js +207 -0
  33. package/lib/documents/client-session-registry.js.map +1 -0
  34. package/lib/documents/dirty-state-tracker.d.ts +101 -0
  35. package/lib/documents/dirty-state-tracker.d.ts.map +1 -0
  36. package/lib/documents/dirty-state-tracker.js +85 -0
  37. package/lib/documents/dirty-state-tracker.js.map +1 -0
  38. package/lib/documents/document-release-handler.d.ts +204 -0
  39. package/lib/documents/document-release-handler.d.ts.map +1 -0
  40. package/lib/documents/document-release-handler.js +317 -0
  41. package/lib/documents/document-release-handler.js.map +1 -0
  42. package/lib/documents/document-release-scheduler.d.ts +67 -0
  43. package/lib/documents/document-release-scheduler.d.ts.map +1 -0
  44. package/lib/documents/document-release-scheduler.js +80 -0
  45. package/lib/documents/document-release-scheduler.js.map +1 -0
  46. package/lib/documents/file-system-task-queue.d.ts +52 -0
  47. package/lib/documents/file-system-task-queue.d.ts.map +1 -0
  48. package/lib/documents/file-system-task-queue.js +37 -0
  49. package/lib/documents/file-system-task-queue.js.map +1 -0
  50. package/lib/documents/hydranium-text-documents.d.ts +445 -282
  51. package/lib/documents/hydranium-text-documents.d.ts.map +1 -1
  52. package/lib/documents/hydranium-text-documents.js +903 -504
  53. package/lib/documents/hydranium-text-documents.js.map +1 -1
  54. package/lib/documents/index.d.ts +10 -2
  55. package/lib/documents/index.d.ts.map +1 -1
  56. package/lib/documents/index.js +10 -2
  57. package/lib/documents/index.js.map +1 -1
  58. package/lib/documents/language-client-shadow.d.ts +234 -0
  59. package/lib/documents/language-client-shadow.d.ts.map +1 -0
  60. package/lib/documents/language-client-shadow.js +306 -0
  61. package/lib/documents/language-client-shadow.js.map +1 -0
  62. package/lib/documents/model-ledger.d.ts +47 -0
  63. package/lib/documents/model-ledger.d.ts.map +1 -0
  64. package/lib/documents/model-ledger.js +30 -0
  65. package/lib/documents/model-ledger.js.map +1 -0
  66. package/lib/documents/text-ledger.d.ts +64 -0
  67. package/lib/documents/text-ledger.d.ts.map +1 -0
  68. package/lib/documents/text-ledger.js +63 -0
  69. package/lib/documents/text-ledger.js.map +1 -0
  70. package/lib/documents/version-sync-service.d.ts +145 -0
  71. package/lib/documents/version-sync-service.d.ts.map +1 -0
  72. package/lib/documents/version-sync-service.js +177 -0
  73. package/lib/documents/version-sync-service.js.map +1 -0
  74. package/lib/index.d.ts +3 -0
  75. package/lib/index.d.ts.map +1 -1
  76. package/lib/index.js +3 -0
  77. package/lib/index.js.map +1 -1
  78. package/lib/langium/ast-extension/ast-extension-service.d.ts +42 -31
  79. package/lib/langium/ast-extension/ast-extension-service.d.ts.map +1 -1
  80. package/lib/langium/ast-extension/ast-extension-service.js +45 -19
  81. package/lib/langium/ast-extension/ast-extension-service.js.map +1 -1
  82. package/lib/langium/ast-extension/ast-node-builder.d.ts +12 -7
  83. package/lib/langium/ast-extension/ast-node-builder.d.ts.map +1 -1
  84. package/lib/langium/ast-extension/ast-node-builder.js +25 -9
  85. package/lib/langium/ast-extension/ast-node-builder.js.map +1 -1
  86. package/lib/langium/bootstrap.d.ts +49 -36
  87. package/lib/langium/bootstrap.d.ts.map +1 -1
  88. package/lib/langium/bootstrap.js +75 -36
  89. package/lib/langium/bootstrap.js.map +1 -1
  90. package/lib/langium/build-phase-pass/build-phase-pass-service.d.ts +9 -9
  91. package/lib/langium/build-phase-pass/build-phase-pass-service.d.ts.map +1 -1
  92. package/lib/langium/build-phase-pass/build-phase-pass-service.js +25 -16
  93. package/lib/langium/build-phase-pass/build-phase-pass-service.js.map +1 -1
  94. package/lib/langium/build-phase-pass/build-phase-pass.d.ts +20 -8
  95. package/lib/langium/build-phase-pass/build-phase-pass.d.ts.map +1 -1
  96. package/lib/langium/build-phase-pass/build-phase-pass.js +20 -0
  97. package/lib/langium/build-phase-pass/build-phase-pass.js.map +1 -1
  98. package/lib/langium/composite-ast-reflection.d.ts +46 -0
  99. package/lib/langium/composite-ast-reflection.d.ts.map +1 -0
  100. package/lib/langium/composite-ast-reflection.js +97 -0
  101. package/lib/langium/composite-ast-reflection.js.map +1 -0
  102. package/lib/langium/config/configuration-provider.d.ts +81 -0
  103. package/lib/langium/config/configuration-provider.d.ts.map +1 -0
  104. package/lib/langium/config/configuration-provider.js +112 -0
  105. package/lib/langium/config/configuration-provider.js.map +1 -0
  106. package/lib/langium/config/index.d.ts +1 -0
  107. package/lib/langium/config/index.d.ts.map +1 -1
  108. package/lib/langium/config/index.js +1 -0
  109. package/lib/langium/config/index.js.map +1 -1
  110. package/lib/langium/config/settings.js.map +1 -1
  111. package/lib/langium/diagnostics/console-tee.d.ts +27 -0
  112. package/lib/langium/diagnostics/console-tee.d.ts.map +1 -0
  113. package/lib/langium/diagnostics/console-tee.js +141 -0
  114. package/lib/langium/diagnostics/console-tee.js.map +1 -0
  115. package/lib/langium/diagnostics/hydranium-langium-profiler.d.ts +9 -20
  116. package/lib/langium/diagnostics/hydranium-langium-profiler.d.ts.map +1 -1
  117. package/lib/langium/diagnostics/hydranium-langium-profiler.js +15 -24
  118. package/lib/langium/diagnostics/hydranium-langium-profiler.js.map +1 -1
  119. package/lib/langium/diagnostics/log-preamble.js +1 -1
  120. package/lib/langium/diagnostics/log-preamble.js.map +1 -1
  121. package/lib/langium/diagnostics/logger.d.ts +25 -6
  122. package/lib/langium/diagnostics/logger.d.ts.map +1 -1
  123. package/lib/langium/diagnostics/logger.js +49 -17
  124. package/lib/langium/diagnostics/logger.js.map +1 -1
  125. package/lib/langium/diagnostics/lsp-logger.d.ts +25 -0
  126. package/lib/langium/diagnostics/lsp-logger.d.ts.map +1 -1
  127. package/lib/langium/diagnostics/lsp-logger.js +81 -46
  128. package/lib/langium/diagnostics/lsp-logger.js.map +1 -1
  129. package/lib/langium/diagnostics/server-tracer.d.ts.map +1 -1
  130. package/lib/langium/diagnostics/server-tracer.js.map +1 -1
  131. package/lib/langium/document-builder/build-pipeline-integration.d.ts +21 -1
  132. package/lib/langium/document-builder/build-pipeline-integration.d.ts.map +1 -1
  133. package/lib/langium/document-builder/build-pipeline-integration.js +43 -30
  134. package/lib/langium/document-builder/build-pipeline-integration.js.map +1 -1
  135. package/lib/langium/document-builder/build-session.d.ts +6 -5
  136. package/lib/langium/document-builder/build-session.d.ts.map +1 -1
  137. package/lib/langium/document-builder/build-session.js +5 -5
  138. package/lib/langium/document-builder/build-session.js.map +1 -1
  139. package/lib/langium/document-builder/document-builder.d.ts +355 -39
  140. package/lib/langium/document-builder/document-builder.d.ts.map +1 -1
  141. package/lib/langium/document-builder/document-builder.js +578 -102
  142. package/lib/langium/document-builder/document-builder.js.map +1 -1
  143. package/lib/langium/documentation/comment-provider.d.ts.map +1 -1
  144. package/lib/langium/documentation/comment-provider.js.map +1 -1
  145. package/lib/langium/integration-services.d.ts +39 -23
  146. package/lib/langium/integration-services.d.ts.map +1 -1
  147. package/lib/langium/integration-services.js +7 -4
  148. package/lib/langium/integration-services.js.map +1 -1
  149. package/lib/langium/integrity/integrity-rule.d.ts +22 -8
  150. package/lib/langium/integrity/integrity-rule.d.ts.map +1 -1
  151. package/lib/langium/integrity/integrity-rule.js.map +1 -1
  152. package/lib/langium/integrity/integrity-service.d.ts +104 -27
  153. package/lib/langium/integrity/integrity-service.d.ts.map +1 -1
  154. package/lib/langium/integrity/integrity-service.js +319 -65
  155. package/lib/langium/integrity/integrity-service.js.map +1 -1
  156. package/lib/langium/keys/containment.d.ts +3 -2
  157. package/lib/langium/keys/containment.d.ts.map +1 -1
  158. package/lib/langium/keys/containment.js.map +1 -1
  159. package/lib/langium/keys/name-based-key-provider.d.ts +17 -10
  160. package/lib/langium/keys/name-based-key-provider.d.ts.map +1 -1
  161. package/lib/langium/keys/name-based-key-provider.js +24 -12
  162. package/lib/langium/keys/name-based-key-provider.js.map +1 -1
  163. package/lib/langium/keys/positional-key-provider.d.ts.map +1 -1
  164. package/lib/langium/keys/positional-key-provider.js.map +1 -1
  165. package/lib/langium/labeling/label-provider.d.ts.map +1 -1
  166. package/lib/langium/labeling/label-provider.js.map +1 -1
  167. package/lib/langium/language-module.d.ts +30 -5
  168. package/lib/langium/language-module.d.ts.map +1 -1
  169. package/lib/langium/language-module.js +21 -5
  170. package/lib/langium/language-module.js.map +1 -1
  171. package/lib/langium/model-service/client-session.d.ts +405 -0
  172. package/lib/langium/model-service/client-session.d.ts.map +1 -0
  173. package/lib/langium/model-service/client-session.js +479 -0
  174. package/lib/langium/model-service/client-session.js.map +1 -0
  175. package/lib/langium/model-service/index.d.ts +2 -0
  176. package/lib/langium/model-service/index.d.ts.map +1 -1
  177. package/lib/langium/model-service/index.js +2 -0
  178. package/lib/langium/model-service/index.js.map +1 -1
  179. package/lib/langium/model-service/model-events.d.ts +68 -0
  180. package/lib/langium/model-service/model-events.d.ts.map +1 -0
  181. package/lib/langium/model-service/model-events.js +10 -0
  182. package/lib/langium/model-service/model-events.js.map +1 -0
  183. package/lib/langium/model-service/model-service.d.ts +441 -323
  184. package/lib/langium/model-service/model-service.d.ts.map +1 -1
  185. package/lib/langium/model-service/model-service.js +602 -397
  186. package/lib/langium/model-service/model-service.js.map +1 -1
  187. package/lib/langium/module.d.ts +96 -37
  188. package/lib/langium/module.d.ts.map +1 -1
  189. package/lib/langium/module.js +39 -27
  190. package/lib/langium/module.js.map +1 -1
  191. package/lib/langium/naming/name-provider.d.ts +32 -7
  192. package/lib/langium/naming/name-provider.d.ts.map +1 -1
  193. package/lib/langium/naming/name-provider.js +10 -4
  194. package/lib/langium/naming/name-provider.js.map +1 -1
  195. package/lib/langium/naming/name-separator-validation.d.ts.map +1 -1
  196. package/lib/langium/project/abstract-project-manager.d.ts +184 -13
  197. package/lib/langium/project/abstract-project-manager.d.ts.map +1 -1
  198. package/lib/langium/project/abstract-project-manager.js +336 -16
  199. package/lib/langium/project/abstract-project-manager.js.map +1 -1
  200. package/lib/langium/project/project-change-event.d.ts +22 -3
  201. package/lib/langium/project/project-change-event.d.ts.map +1 -1
  202. package/lib/langium/project/project-manager.d.ts +28 -2
  203. package/lib/langium/project/project-manager.d.ts.map +1 -1
  204. package/lib/langium/project/single-project-manager.d.ts +7 -1
  205. package/lib/langium/project/single-project-manager.d.ts.map +1 -1
  206. package/lib/langium/project/single-project-manager.js +12 -0
  207. package/lib/langium/project/single-project-manager.js.map +1 -1
  208. package/lib/langium/residency/cst-residency-service.d.ts +81 -44
  209. package/lib/langium/residency/cst-residency-service.d.ts.map +1 -1
  210. package/lib/langium/residency/cst-residency-service.js +142 -46
  211. package/lib/langium/residency/cst-residency-service.js.map +1 -1
  212. package/lib/langium/scope/ast-node-description-provider.d.ts +46 -10
  213. package/lib/langium/scope/ast-node-description-provider.d.ts.map +1 -1
  214. package/lib/langium/scope/ast-node-description-provider.js +88 -15
  215. package/lib/langium/scope/ast-node-description-provider.js.map +1 -1
  216. package/lib/langium/scope/built-local-symbols.d.ts +12 -0
  217. package/lib/langium/scope/built-local-symbols.d.ts.map +1 -0
  218. package/lib/langium/scope/built-local-symbols.js +11 -0
  219. package/lib/langium/scope/built-local-symbols.js.map +1 -0
  220. package/lib/langium/scope/fallback-scope.d.ts +27 -0
  221. package/lib/langium/scope/fallback-scope.d.ts.map +1 -0
  222. package/lib/langium/scope/fallback-scope.js +35 -0
  223. package/lib/langium/scope/fallback-scope.js.map +1 -0
  224. package/lib/langium/scope/hydranium-scope-computation.d.ts +21 -18
  225. package/lib/langium/scope/hydranium-scope-computation.d.ts.map +1 -1
  226. package/lib/langium/scope/hydranium-scope-computation.js +38 -39
  227. package/lib/langium/scope/hydranium-scope-computation.js.map +1 -1
  228. package/lib/langium/scope/hydranium-scope-provider.d.ts +122 -32
  229. package/lib/langium/scope/hydranium-scope-provider.d.ts.map +1 -1
  230. package/lib/langium/scope/hydranium-scope-provider.js +217 -39
  231. package/lib/langium/scope/hydranium-scope-provider.js.map +1 -1
  232. package/lib/langium/scope/index.d.ts +1 -0
  233. package/lib/langium/scope/index.d.ts.map +1 -1
  234. package/lib/langium/scope/index.js +1 -0
  235. package/lib/langium/scope/index.js.map +1 -1
  236. package/lib/langium/scope/reference-builder.d.ts.map +1 -1
  237. package/lib/langium/scope/reference-builder.js.map +1 -1
  238. package/lib/langium/scope/reference-candidate-provider.d.ts +6 -5
  239. package/lib/langium/scope/reference-candidate-provider.d.ts.map +1 -1
  240. package/lib/langium/scope/reference-candidate-provider.js +3 -2
  241. package/lib/langium/scope/reference-candidate-provider.js.map +1 -1
  242. package/lib/langium/scope/scope-extension-service.d.ts +69 -37
  243. package/lib/langium/scope/scope-extension-service.d.ts.map +1 -1
  244. package/lib/langium/scope/scope-extension-service.js +102 -29
  245. package/lib/langium/scope/scope-extension-service.js.map +1 -1
  246. package/lib/langium/scope/scoped-ast-node-description.d.ts +1 -3
  247. package/lib/langium/scope/scoped-ast-node-description.d.ts.map +1 -1
  248. package/lib/langium/scope/scoped-ast-node-description.js +1 -3
  249. package/lib/langium/scope/scoped-ast-node-description.js.map +1 -1
  250. package/lib/langium/serialization/abstract-serializer.d.ts +38 -27
  251. package/lib/langium/serialization/abstract-serializer.d.ts.map +1 -1
  252. package/lib/langium/serialization/abstract-serializer.js +54 -30
  253. package/lib/langium/serialization/abstract-serializer.js.map +1 -1
  254. package/lib/langium/serialization/json-serializer.d.ts +8 -1
  255. package/lib/langium/serialization/json-serializer.d.ts.map +1 -1
  256. package/lib/langium/serialization/json-serializer.js +13 -3
  257. package/lib/langium/serialization/json-serializer.js.map +1 -1
  258. package/lib/langium/serialization/serializer.d.ts +1 -1
  259. package/lib/langium/serialization/yaml-serializer.d.ts +12 -0
  260. package/lib/langium/serialization/yaml-serializer.d.ts.map +1 -1
  261. package/lib/langium/serialization/yaml-serializer.js +24 -4
  262. package/lib/langium/serialization/yaml-serializer.js.map +1 -1
  263. package/lib/langium/service-registry.d.ts +29 -1
  264. package/lib/langium/service-registry.d.ts.map +1 -1
  265. package/lib/langium/service-registry.js +37 -0
  266. package/lib/langium/service-registry.js.map +1 -1
  267. package/lib/langium/shared-services.d.ts +10 -4
  268. package/lib/langium/shared-services.d.ts.map +1 -1
  269. package/lib/langium/shared-services.js.map +1 -1
  270. package/lib/langium/single-langium-copy.d.ts +22 -0
  271. package/lib/langium/single-langium-copy.d.ts.map +1 -0
  272. package/lib/langium/single-langium-copy.js +36 -0
  273. package/lib/langium/single-langium-copy.js.map +1 -0
  274. package/lib/langium/transfer/transfer-encoder.d.ts +60 -39
  275. package/lib/langium/transfer/transfer-encoder.d.ts.map +1 -1
  276. package/lib/langium/transfer/transfer-encoder.js +35 -24
  277. package/lib/langium/transfer/transfer-encoder.js.map +1 -1
  278. package/lib/langium/trivia/comment-preserver.d.ts +543 -0
  279. package/lib/langium/trivia/comment-preserver.d.ts.map +1 -0
  280. package/lib/langium/trivia/comment-preserver.js +1165 -0
  281. package/lib/langium/trivia/comment-preserver.js.map +1 -0
  282. package/lib/langium/trivia/document-ending-preserver.d.ts +51 -0
  283. package/lib/langium/trivia/document-ending-preserver.d.ts.map +1 -0
  284. package/lib/langium/trivia/document-ending-preserver.js +62 -0
  285. package/lib/langium/trivia/document-ending-preserver.js.map +1 -0
  286. package/lib/langium/trivia/index.d.ts +14 -0
  287. package/lib/langium/trivia/index.d.ts.map +1 -0
  288. package/lib/langium/trivia/index.js +14 -0
  289. package/lib/langium/trivia/index.js.map +1 -0
  290. package/lib/langium/trivia/trivia-contribution.d.ts +37 -0
  291. package/lib/langium/trivia/trivia-contribution.d.ts.map +1 -0
  292. package/lib/langium/trivia/trivia-contribution.js +10 -0
  293. package/lib/langium/trivia/trivia-contribution.js.map +1 -0
  294. package/lib/langium/trivia/trivia-preserver.d.ts +52 -0
  295. package/lib/langium/trivia/trivia-preserver.d.ts.map +1 -0
  296. package/lib/langium/trivia/trivia-preserver.js +10 -0
  297. package/lib/langium/trivia/trivia-preserver.js.map +1 -0
  298. package/lib/langium/trivia/trivia-service.d.ts +70 -0
  299. package/lib/langium/trivia/trivia-service.d.ts.map +1 -0
  300. package/lib/langium/trivia/trivia-service.js +56 -0
  301. package/lib/langium/trivia/trivia-service.js.map +1 -0
  302. package/lib/langium/update-rewrite/normalize-empty-strings.d.ts.map +1 -1
  303. package/lib/langium/update-rewrite/update-rewrite-service.d.ts +1 -1
  304. package/lib/langium/update-rewrite/update-rewrite-service.d.ts.map +1 -1
  305. package/lib/langium/update-rewrite/update-rewrite-service.js.map +1 -1
  306. package/lib/langium/update-rewrite/update-rewrite.d.ts +1 -1
  307. package/lib/langium/validation/document-validator.d.ts +168 -23
  308. package/lib/langium/validation/document-validator.d.ts.map +1 -1
  309. package/lib/langium/validation/document-validator.js +264 -26
  310. package/lib/langium/validation/document-validator.js.map +1 -1
  311. package/lib/langium/validation/validation-contribution-collector.d.ts +9 -1
  312. package/lib/langium/validation/validation-contribution-collector.d.ts.map +1 -1
  313. package/lib/langium/validation/validation-contribution-collector.js +1 -1
  314. package/lib/langium/validation/validation-contribution-collector.js.map +1 -1
  315. package/lib/langium/workspace/ast-node-locator.d.ts +24 -0
  316. package/lib/langium/workspace/ast-node-locator.d.ts.map +1 -0
  317. package/lib/langium/workspace/ast-node-locator.js +32 -0
  318. package/lib/langium/workspace/ast-node-locator.js.map +1 -0
  319. package/lib/langium/workspace/document-uri-policy.d.ts +24 -15
  320. package/lib/langium/workspace/document-uri-policy.d.ts.map +1 -1
  321. package/lib/langium/workspace/document-uri-policy.js +22 -13
  322. package/lib/langium/workspace/document-uri-policy.js.map +1 -1
  323. package/lib/langium/workspace/file-not-found.d.ts +23 -0
  324. package/lib/langium/workspace/file-not-found.d.ts.map +1 -0
  325. package/lib/langium/workspace/file-not-found.js +31 -0
  326. package/lib/langium/workspace/file-not-found.js.map +1 -0
  327. package/lib/langium/workspace/file-system-provider.d.ts +167 -8
  328. package/lib/langium/workspace/file-system-provider.d.ts.map +1 -1
  329. package/lib/langium/workspace/file-system-provider.js +115 -13
  330. package/lib/langium/workspace/file-system-provider.js.map +1 -1
  331. package/lib/langium/workspace/hydranium-langium-document-factory.d.ts +35 -1
  332. package/lib/langium/workspace/hydranium-langium-document-factory.d.ts.map +1 -1
  333. package/lib/langium/workspace/hydranium-langium-document-factory.js +77 -0
  334. package/lib/langium/workspace/hydranium-langium-document-factory.js.map +1 -1
  335. package/lib/langium/workspace/hydranium-workspace-lock.d.ts +43 -1
  336. package/lib/langium/workspace/hydranium-workspace-lock.d.ts.map +1 -1
  337. package/lib/langium/workspace/hydranium-workspace-lock.js +58 -1
  338. package/lib/langium/workspace/hydranium-workspace-lock.js.map +1 -1
  339. package/lib/langium/workspace/hydranium-workspace-manager.d.ts +105 -21
  340. package/lib/langium/workspace/hydranium-workspace-manager.d.ts.map +1 -1
  341. package/lib/langium/workspace/hydranium-workspace-manager.js +186 -31
  342. package/lib/langium/workspace/hydranium-workspace-manager.js.map +1 -1
  343. package/lib/langium/workspace/in-memory-file-system-provider.d.ts +26 -9
  344. package/lib/langium/workspace/in-memory-file-system-provider.d.ts.map +1 -1
  345. package/lib/langium/workspace/in-memory-file-system-provider.js +45 -22
  346. package/lib/langium/workspace/in-memory-file-system-provider.js.map +1 -1
  347. package/lib/langium/workspace/index-manager.d.ts.map +1 -1
  348. package/lib/langium/workspace/index-manager.js.map +1 -1
  349. package/lib/langium/workspace/index.d.ts +3 -0
  350. package/lib/langium/workspace/index.d.ts.map +1 -1
  351. package/lib/langium/workspace/index.js +3 -0
  352. package/lib/langium/workspace/index.js.map +1 -1
  353. package/lib/langium/workspace/initialize-workspace.d.ts +40 -3
  354. package/lib/langium/workspace/initialize-workspace.d.ts.map +1 -1
  355. package/lib/langium/workspace/initialize-workspace.js +68 -3
  356. package/lib/langium/workspace/initialize-workspace.js.map +1 -1
  357. package/lib/langium/workspace/langium-documents.d.ts +7 -0
  358. package/lib/langium/workspace/langium-documents.d.ts.map +1 -1
  359. package/lib/langium/workspace/langium-documents.js +18 -1
  360. package/lib/langium/workspace/langium-documents.js.map +1 -1
  361. package/lib/langium/workspace/persistent-file-system-provider.d.ts +16 -10
  362. package/lib/langium/workspace/persistent-file-system-provider.d.ts.map +1 -1
  363. package/lib/langium/workspace/persistent-file-system-provider.js +25 -13
  364. package/lib/langium/workspace/persistent-file-system-provider.js.map +1 -1
  365. package/lib/{documents → langium/workspace}/self-save-registry.d.ts +7 -9
  366. package/lib/langium/workspace/self-save-registry.d.ts.map +1 -0
  367. package/lib/{documents → langium/workspace}/self-save-registry.js +9 -11
  368. package/lib/langium/workspace/self-save-registry.js.map +1 -0
  369. package/lib/langium/workspace/syntax-errors.d.ts +23 -0
  370. package/lib/langium/workspace/syntax-errors.d.ts.map +1 -0
  371. package/lib/langium/workspace/syntax-errors.js +29 -0
  372. package/lib/langium/workspace/syntax-errors.js.map +1 -0
  373. package/lib/langium/workspace/virtual-document.d.ts +55 -21
  374. package/lib/langium/workspace/virtual-document.d.ts.map +1 -1
  375. package/lib/langium/workspace/virtual-document.js +87 -24
  376. package/lib/langium/workspace/virtual-document.js.map +1 -1
  377. package/lib/langium/workspace/write-lock-scope.d.ts +22 -10
  378. package/lib/langium/workspace/write-lock-scope.d.ts.map +1 -1
  379. package/lib/langium/workspace/write-lock-scope.js +15 -5
  380. package/lib/langium/workspace/write-lock-scope.js.map +1 -1
  381. package/lib/launcher/integrated-server.d.ts +3 -1
  382. package/lib/launcher/integrated-server.d.ts.map +1 -1
  383. package/lib/locale/server-locale.d.ts +6 -6
  384. package/lib/locale/server-locale.d.ts.map +1 -1
  385. package/lib/locale/server-locale.js.map +1 -1
  386. package/lib/lsp/completion/hydranium-completion-provider.d.ts +44 -2
  387. package/lib/lsp/completion/hydranium-completion-provider.d.ts.map +1 -1
  388. package/lib/lsp/completion/hydranium-completion-provider.js +68 -0
  389. package/lib/lsp/completion/hydranium-completion-provider.js.map +1 -1
  390. package/lib/lsp/connection-features.d.ts +23 -0
  391. package/lib/lsp/connection-features.d.ts.map +1 -0
  392. package/lib/lsp/connection-features.js +60 -0
  393. package/lib/lsp/connection-features.js.map +1 -0
  394. package/lib/lsp/diagnostics-connection.d.ts +27 -0
  395. package/lib/lsp/diagnostics-connection.d.ts.map +1 -0
  396. package/lib/lsp/diagnostics-connection.js +53 -0
  397. package/lib/lsp/diagnostics-connection.js.map +1 -0
  398. package/lib/lsp/edit-requests-guard.d.ts +31 -0
  399. package/lib/lsp/edit-requests-guard.d.ts.map +1 -0
  400. package/lib/lsp/edit-requests-guard.js +125 -0
  401. package/lib/lsp/edit-requests-guard.js.map +1 -0
  402. package/lib/lsp/hydranium-document-update-handler.d.ts +126 -82
  403. package/lib/lsp/hydranium-document-update-handler.d.ts.map +1 -1
  404. package/lib/lsp/hydranium-document-update-handler.js +234 -101
  405. package/lib/lsp/hydranium-document-update-handler.js.map +1 -1
  406. package/lib/lsp/index.d.ts +6 -2
  407. package/lib/lsp/index.d.ts.map +1 -1
  408. package/lib/lsp/index.js +6 -2
  409. package/lib/lsp/index.js.map +1 -1
  410. package/lib/lsp/lsp-latency.d.ts +39 -0
  411. package/lib/lsp/lsp-latency.d.ts.map +1 -0
  412. package/lib/lsp/lsp-latency.js +58 -0
  413. package/lib/lsp/lsp-latency.js.map +1 -0
  414. package/lib/lsp/save-text-document.d.ts +31 -0
  415. package/lib/lsp/save-text-document.d.ts.map +1 -0
  416. package/lib/lsp/save-text-document.js +52 -0
  417. package/lib/lsp/save-text-document.js.map +1 -0
  418. package/lib/lsp/semantic-token-provider.d.ts +58 -2
  419. package/lib/lsp/semantic-token-provider.d.ts.map +1 -1
  420. package/lib/lsp/semantic-token-provider.js +98 -9
  421. package/lib/lsp/semantic-token-provider.js.map +1 -1
  422. package/lib/lsp/shared-module.d.ts +4 -8
  423. package/lib/lsp/shared-module.d.ts.map +1 -1
  424. package/lib/lsp/shared-module.js.map +1 -1
  425. package/lib/lsp/start-language-server.d.ts +12 -7
  426. package/lib/lsp/start-language-server.d.ts.map +1 -1
  427. package/lib/lsp/start-language-server.js +21 -7
  428. package/lib/lsp/start-language-server.js.map +1 -1
  429. package/lib/messages/carriers.d.ts +4 -6
  430. package/lib/messages/carriers.d.ts.map +1 -1
  431. package/lib/messages/carriers.js +4 -6
  432. package/lib/messages/carriers.js.map +1 -1
  433. package/lib/messages/index.d.ts +2 -2
  434. package/lib/messages/index.d.ts.map +1 -1
  435. package/lib/messages/index.js +2 -2
  436. package/lib/messages/index.js.map +1 -1
  437. package/lib/messages/renderer.d.ts +10 -4
  438. package/lib/messages/renderer.d.ts.map +1 -1
  439. package/lib/messages/renderer.js +6 -0
  440. package/lib/messages/renderer.js.map +1 -1
  441. package/lib/node/event-loop-monitor.d.ts.map +1 -1
  442. package/lib/node/event-loop-monitor.js +2 -1
  443. package/lib/node/event-loop-monitor.js.map +1 -1
  444. package/lib/node/heap-ceiling.d.ts +61 -0
  445. package/lib/node/heap-ceiling.d.ts.map +1 -0
  446. package/lib/node/heap-ceiling.js +72 -0
  447. package/lib/node/heap-ceiling.js.map +1 -0
  448. package/lib/node/index.d.ts +1 -1
  449. package/lib/node/index.d.ts.map +1 -1
  450. package/lib/node/index.js +5 -1
  451. package/lib/node/index.js.map +1 -1
  452. package/lib/node/latency-from-env.d.ts +1 -1
  453. package/lib/node/latency-from-env.js +1 -1
  454. package/lib/node/lint-grammar.js.map +1 -1
  455. package/lib/node/log-file-sink.d.ts +3 -2
  456. package/lib/node/log-file-sink.d.ts.map +1 -1
  457. package/lib/node/log-file-sink.js +6 -2
  458. package/lib/node/log-file-sink.js.map +1 -1
  459. package/lib/node/log-preamble-node.d.ts +5 -3
  460. package/lib/node/log-preamble-node.d.ts.map +1 -1
  461. package/lib/node/log-preamble-node.js +13 -10
  462. package/lib/node/log-preamble-node.js.map +1 -1
  463. package/lib/node/measure-memory.d.ts.map +1 -1
  464. package/lib/node/measure-memory.js +5 -4
  465. package/lib/node/measure-memory.js.map +1 -1
  466. package/lib/node/memory-monitor.d.ts +2 -2
  467. package/lib/node/memory-monitor.d.ts.map +1 -1
  468. package/lib/node/memory-monitor.js +9 -10
  469. package/lib/node/memory-monitor.js.map +1 -1
  470. package/lib/node/node-file-system-provider.d.ts +67 -9
  471. package/lib/node/node-file-system-provider.d.ts.map +1 -1
  472. package/lib/node/node-file-system-provider.js +198 -53
  473. package/lib/node/node-file-system-provider.js.map +1 -1
  474. package/lib/node/profile-capture.d.ts +12 -4
  475. package/lib/node/profile-capture.d.ts.map +1 -1
  476. package/lib/node/profile-capture.js +8 -6
  477. package/lib/node/profile-capture.js.map +1 -1
  478. package/lib/node/profile-digest.js.map +1 -1
  479. package/lib/node/profiling-run.d.ts +13 -3
  480. package/lib/node/profiling-run.d.ts.map +1 -1
  481. package/lib/node/profiling-run.js +17 -8
  482. package/lib/node/profiling-run.js.map +1 -1
  483. package/lib/node/rename-over-open-readers.d.ts +61 -0
  484. package/lib/node/rename-over-open-readers.d.ts.map +1 -0
  485. package/lib/node/rename-over-open-readers.js +80 -0
  486. package/lib/node/rename-over-open-readers.js.map +1 -0
  487. package/lib/node/server-diagnostics.js +1 -1
  488. package/lib/node/server-diagnostics.js.map +1 -1
  489. package/lib/node/server-state-snapshot.d.ts +1 -2
  490. package/lib/node/server-state-snapshot.d.ts.map +1 -1
  491. package/lib/node/server-state-snapshot.js +4 -4
  492. package/lib/node/server-state-snapshot.js.map +1 -1
  493. package/lib/node/socket-launcher.d.ts +43 -7
  494. package/lib/node/socket-launcher.d.ts.map +1 -1
  495. package/lib/node/socket-launcher.js +42 -7
  496. package/lib/node/socket-launcher.js.map +1 -1
  497. package/lib/node/startup-cpu-profile.d.ts +29 -0
  498. package/lib/node/startup-cpu-profile.d.ts.map +1 -0
  499. package/lib/node/startup-cpu-profile.js +91 -0
  500. package/lib/node/startup-cpu-profile.js.map +1 -0
  501. package/lib/node/stdio-launcher.d.ts +13 -13
  502. package/lib/node/stdio-launcher.d.ts.map +1 -1
  503. package/lib/node/stdio-launcher.js +21 -11
  504. package/lib/node/stdio-launcher.js.map +1 -1
  505. package/lib/node/validate-workspace.d.ts +1 -1
  506. package/lib/node/validate-workspace.d.ts.map +1 -1
  507. package/lib/node/validate-workspace.js +5 -1
  508. package/lib/node/validate-workspace.js.map +1 -1
  509. package/lib/testing/document-uri-policy-conformance.js +1 -1
  510. package/lib/testing/document-uri-policy-conformance.js.map +1 -1
  511. package/lib/testing/fake-description.js.map +1 -1
  512. package/lib/testing/fake-document.d.ts +2 -1
  513. package/lib/testing/fake-document.d.ts.map +1 -1
  514. package/lib/testing/fake-document.js.map +1 -1
  515. package/lib/testing/index.d.ts +1 -1
  516. package/lib/testing/index.d.ts.map +1 -1
  517. package/lib/testing/index.js +2 -1
  518. package/lib/testing/index.js.map +1 -1
  519. package/lib/testing/langium-test-helpers.d.ts.map +1 -1
  520. package/lib/testing/langium-test-helpers.js +1 -0
  521. package/lib/testing/langium-test-helpers.js.map +1 -1
  522. package/lib/testing/make-noop-language-services.js.map +1 -1
  523. package/lib/testing/make-noop-shared-services.js.map +1 -1
  524. package/lib/testing/make-test-services.d.ts +45 -14
  525. package/lib/testing/make-test-services.d.ts.map +1 -1
  526. package/lib/testing/make-test-services.js +23 -7
  527. package/lib/testing/make-test-services.js.map +1 -1
  528. package/lib/testing/make-test-tracer.d.ts +12 -0
  529. package/lib/testing/make-test-tracer.d.ts.map +1 -1
  530. package/lib/testing/make-test-tracer.js +13 -0
  531. package/lib/testing/make-test-tracer.js.map +1 -1
  532. package/lib/testing/node/applied-edit-capture.d.ts +29 -0
  533. package/lib/testing/node/applied-edit-capture.d.ts.map +1 -0
  534. package/lib/testing/node/applied-edit-capture.js +117 -0
  535. package/lib/testing/node/applied-edit-capture.js.map +1 -0
  536. package/lib/testing/node/golden-corpus.js.map +1 -1
  537. package/lib/testing/node/index.d.ts +1 -0
  538. package/lib/testing/node/index.d.ts.map +1 -1
  539. package/lib/testing/node/index.js +1 -0
  540. package/lib/testing/node/index.js.map +1 -1
  541. package/lib/testing/node/lsp-harness.d.ts.map +1 -1
  542. package/lib/testing/node/lsp-harness.js +2 -0
  543. package/lib/testing/node/lsp-harness.js.map +1 -1
  544. package/lib/testing/node/lsp-server-connection.d.ts +21 -6
  545. package/lib/testing/node/lsp-server-connection.d.ts.map +1 -1
  546. package/lib/testing/node/lsp-server-connection.js +49 -106
  547. package/lib/testing/node/lsp-server-connection.js.map +1 -1
  548. package/lib/testing/node/scratch-workspace.d.ts.map +1 -1
  549. package/lib/testing/node/scratch-workspace.js +10 -5
  550. package/lib/testing/node/scratch-workspace.js.map +1 -1
  551. package/lib/testing/node/spawned-server.d.ts +30 -1
  552. package/lib/testing/node/spawned-server.d.ts.map +1 -1
  553. package/lib/testing/node/spawned-server.js +39 -2
  554. package/lib/testing/node/spawned-server.js.map +1 -1
  555. package/lib/testing/node/unhandled-rejections.d.ts +20 -0
  556. package/lib/testing/node/unhandled-rejections.d.ts.map +1 -0
  557. package/lib/testing/node/unhandled-rejections.js +32 -0
  558. package/lib/testing/node/unhandled-rejections.js.map +1 -0
  559. package/lib/testing/playwright/browser-capture-bridge.js.map +1 -1
  560. package/lib/testing/playwright/e2e-profiling.js.map +1 -1
  561. package/lib/testing/playwright/flaky-network-proxy.d.ts +76 -0
  562. package/lib/testing/playwright/flaky-network-proxy.d.ts.map +1 -0
  563. package/lib/testing/playwright/flaky-network-proxy.js +164 -0
  564. package/lib/testing/playwright/flaky-network-proxy.js.map +1 -0
  565. package/lib/testing/playwright/index.d.ts +1 -0
  566. package/lib/testing/playwright/index.d.ts.map +1 -1
  567. package/lib/testing/playwright/index.js +1 -0
  568. package/lib/testing/playwright/index.js.map +1 -1
  569. package/lib/testing/playwright/server-log-capture.d.ts +46 -16
  570. package/lib/testing/playwright/server-log-capture.d.ts.map +1 -1
  571. package/lib/testing/playwright/server-log-capture.js +111 -40
  572. package/lib/testing/playwright/server-log-capture.js.map +1 -1
  573. package/lib/testing/playwright/server-log-fixture.d.ts +16 -0
  574. package/lib/testing/playwright/server-log-fixture.d.ts.map +1 -1
  575. package/lib/testing/playwright/server-log-fixture.js +25 -6
  576. package/lib/testing/playwright/server-log-fixture.js.map +1 -1
  577. package/lib/testing/playwright/server-log-region.d.ts +15 -0
  578. package/lib/testing/playwright/server-log-region.d.ts.map +1 -0
  579. package/lib/testing/playwright/server-log-region.js +30 -0
  580. package/lib/testing/playwright/server-log-region.js.map +1 -0
  581. package/lib/testing/playwright/server-log-rename-reporter.d.ts.map +1 -1
  582. package/lib/testing/playwright/server-log-rename-reporter.js +4 -3
  583. package/lib/testing/playwright/server-log-rename-reporter.js.map +1 -1
  584. package/lib/testing/run-update-pipeline.d.ts +8 -5
  585. package/lib/testing/run-update-pipeline.d.ts.map +1 -1
  586. package/lib/testing/run-update-pipeline.js.map +1 -1
  587. package/lib/testing/stub-ast-document-manager.d.ts +11 -51
  588. package/lib/testing/stub-ast-document-manager.d.ts.map +1 -1
  589. package/lib/testing/stub-ast-document-manager.js +31 -59
  590. package/lib/testing/stub-ast-document-manager.js.map +1 -1
  591. package/lib/testing/stub-document-builder.d.ts +33 -11
  592. package/lib/testing/stub-document-builder.d.ts.map +1 -1
  593. package/lib/testing/stub-document-builder.js +110 -5
  594. package/lib/testing/stub-document-builder.js.map +1 -1
  595. package/lib/testing/stub-hydranium-text-documents.d.ts +33 -10
  596. package/lib/testing/stub-hydranium-text-documents.d.ts.map +1 -1
  597. package/lib/testing/stub-hydranium-text-documents.js +132 -16
  598. package/lib/testing/stub-hydranium-text-documents.js.map +1 -1
  599. package/lib/testing/stub-index-manager.js.map +1 -1
  600. package/lib/testing/stub-langium-documents.d.ts +3 -2
  601. package/lib/testing/stub-langium-documents.d.ts.map +1 -1
  602. package/lib/testing/stub-langium-documents.js.map +1 -1
  603. package/lib/testing/stub-model-service.d.ts +8 -7
  604. package/lib/testing/stub-model-service.d.ts.map +1 -1
  605. package/lib/testing/stub-model-service.js +4 -4
  606. package/lib/testing/stub-model-service.js.map +1 -1
  607. package/lib/testing/stub-project-manager.d.ts.map +1 -1
  608. package/lib/testing/stub-project-manager.js +10 -0
  609. package/lib/testing/stub-project-manager.js.map +1 -1
  610. package/lib/testing/stub-self-save-registry.d.ts +1 -1
  611. package/lib/testing/stub-self-save-registry.d.ts.map +1 -1
  612. package/lib/testing/stub-service-registry.d.ts +1 -1
  613. package/lib/testing/stub-service-registry.js.map +1 -1
  614. package/lib/testing/stub-writable-file-system.d.ts +1 -1
  615. package/lib/testing/stub-writable-file-system.d.ts.map +1 -1
  616. package/lib/testing/stub-writable-file-system.js +2 -1
  617. package/lib/testing/stub-writable-file-system.js.map +1 -1
  618. package/lib/util/connection-liveness.d.ts +22 -6
  619. package/lib/util/connection-liveness.d.ts.map +1 -1
  620. package/lib/util/connection-liveness.js +75 -15
  621. package/lib/util/connection-liveness.js.map +1 -1
  622. package/lib/util/environment.d.ts +7 -0
  623. package/lib/util/environment.d.ts.map +1 -1
  624. package/lib/util/environment.js +15 -1
  625. package/lib/util/environment.js.map +1 -1
  626. package/lib/util/registry.d.ts.map +1 -1
  627. package/package.json +41 -60
  628. package/src/browser/host-heads-in-worker.ts +218 -0
  629. package/src/browser/index.ts +17 -0
  630. package/src/browser/indexeddb-file-system-store.ts +192 -0
  631. package/src/browser/start-language-server-in-worker.ts +56 -0
  632. package/src/documents/ast-document-manager.ts +477 -249
  633. package/src/documents/client-ids.ts +5 -22
  634. package/src/documents/client-session-errors.ts +26 -0
  635. package/src/documents/client-session-registry.ts +262 -0
  636. package/src/documents/dirty-state-tracker.ts +167 -0
  637. package/src/documents/document-release-handler.ts +404 -0
  638. package/src/documents/document-release-scheduler.ts +121 -0
  639. package/src/documents/file-system-task-queue.ts +74 -0
  640. package/src/documents/hydranium-text-documents.ts +1029 -616
  641. package/src/documents/index.ts +10 -2
  642. package/src/documents/language-client-shadow.ts +501 -0
  643. package/src/documents/model-ledger.ts +66 -0
  644. package/src/documents/text-ledger.ts +112 -0
  645. package/src/documents/version-sync-service.ts +289 -0
  646. package/src/index.ts +3 -0
  647. package/src/langium/ast-extension/ast-extension-service.ts +77 -41
  648. package/src/langium/ast-extension/ast-node-builder.ts +35 -13
  649. package/src/langium/bootstrap.ts +79 -43
  650. package/src/langium/build-phase-pass/build-phase-pass-service.ts +29 -19
  651. package/src/langium/build-phase-pass/build-phase-pass.ts +37 -8
  652. package/src/langium/composite-ast-reflection.ts +112 -0
  653. package/src/langium/config/configuration-provider.ts +119 -0
  654. package/src/langium/config/index.ts +1 -0
  655. package/src/langium/diagnostics/console-tee.ts +150 -0
  656. package/src/langium/diagnostics/hydranium-langium-profiler.ts +15 -39
  657. package/src/langium/diagnostics/log-preamble.ts +1 -1
  658. package/src/langium/diagnostics/logger.ts +51 -17
  659. package/src/langium/diagnostics/lsp-logger.ts +83 -45
  660. package/src/langium/document-builder/build-pipeline-integration.ts +57 -32
  661. package/src/langium/document-builder/build-session.ts +4 -3
  662. package/src/langium/document-builder/document-builder.ts +709 -105
  663. package/src/langium/integration-services.ts +58 -27
  664. package/src/langium/integrity/integrity-rule.ts +22 -8
  665. package/src/langium/integrity/integrity-service.ts +348 -71
  666. package/src/langium/keys/containment.ts +3 -2
  667. package/src/langium/keys/name-based-key-provider.ts +24 -12
  668. package/src/langium/language-module.ts +52 -9
  669. package/src/langium/model-service/client-session.ts +769 -0
  670. package/src/langium/model-service/index.ts +2 -0
  671. package/src/langium/model-service/model-events.ts +82 -0
  672. package/src/langium/model-service/model-service.ts +885 -522
  673. package/src/langium/module.ts +139 -63
  674. package/src/langium/naming/name-provider.ts +34 -8
  675. package/src/langium/project/abstract-project-manager.ts +409 -20
  676. package/src/langium/project/project-change-event.ts +25 -3
  677. package/src/langium/project/project-manager.ts +31 -2
  678. package/src/langium/project/single-project-manager.ts +16 -1
  679. package/src/langium/residency/cst-residency-service.ts +197 -73
  680. package/src/langium/scope/ast-node-description-provider.ts +111 -16
  681. package/src/langium/scope/built-local-symbols.ts +13 -0
  682. package/src/langium/scope/fallback-scope.ts +38 -0
  683. package/src/langium/scope/hydranium-scope-computation.ts +45 -44
  684. package/src/langium/scope/hydranium-scope-provider.ts +245 -41
  685. package/src/langium/scope/index.ts +1 -0
  686. package/src/langium/scope/reference-candidate-provider.ts +6 -5
  687. package/src/langium/scope/scope-extension-service.ts +148 -56
  688. package/src/langium/scope/scoped-ast-node-description.ts +1 -3
  689. package/src/langium/serialization/abstract-serializer.ts +57 -41
  690. package/src/langium/serialization/json-serializer.ts +14 -3
  691. package/src/langium/serialization/serializer.ts +1 -1
  692. package/src/langium/serialization/yaml-serializer.ts +26 -4
  693. package/src/langium/service-registry.ts +41 -2
  694. package/src/langium/shared-services.ts +13 -4
  695. package/src/langium/single-langium-copy.ts +42 -0
  696. package/src/langium/transfer/transfer-encoder.ts +76 -50
  697. package/src/langium/trivia/comment-preserver.ts +1410 -0
  698. package/src/langium/trivia/document-ending-preserver.ts +71 -0
  699. package/src/langium/trivia/index.ts +14 -0
  700. package/src/langium/trivia/trivia-contribution.ts +39 -0
  701. package/src/langium/trivia/trivia-preserver.ts +56 -0
  702. package/src/langium/trivia/trivia-service.ts +99 -0
  703. package/src/langium/update-rewrite/update-rewrite-service.ts +1 -1
  704. package/src/langium/update-rewrite/update-rewrite.ts +1 -1
  705. package/src/langium/validation/document-validator.ts +312 -31
  706. package/src/langium/validation/validation-contribution-collector.ts +10 -1
  707. package/src/langium/workspace/ast-node-locator.ts +33 -0
  708. package/src/langium/workspace/document-uri-policy.ts +32 -18
  709. package/src/langium/workspace/file-not-found.ts +35 -0
  710. package/src/langium/workspace/file-system-provider.ts +258 -16
  711. package/src/langium/workspace/hydranium-langium-document-factory.ts +107 -0
  712. package/src/langium/workspace/hydranium-workspace-lock.ts +86 -2
  713. package/src/langium/workspace/hydranium-workspace-manager.ts +214 -35
  714. package/src/langium/workspace/in-memory-file-system-provider.ts +54 -23
  715. package/src/langium/workspace/index.ts +3 -0
  716. package/src/langium/workspace/initialize-workspace.ts +96 -4
  717. package/src/langium/workspace/langium-documents.ts +19 -1
  718. package/src/langium/workspace/persistent-file-system-provider.ts +27 -15
  719. package/src/{documents → langium/workspace}/self-save-registry.ts +12 -14
  720. package/src/langium/workspace/syntax-errors.ts +34 -0
  721. package/src/langium/workspace/virtual-document.ts +106 -25
  722. package/src/langium/workspace/write-lock-scope.ts +27 -12
  723. package/src/launcher/integrated-server.ts +3 -1
  724. package/src/locale/server-locale.ts +6 -6
  725. package/src/lsp/completion/hydranium-completion-provider.ts +82 -2
  726. package/src/lsp/connection-features.ts +67 -0
  727. package/src/lsp/diagnostics-connection.ts +56 -0
  728. package/src/lsp/edit-requests-guard.ts +152 -0
  729. package/src/lsp/hydranium-document-update-handler.ts +284 -110
  730. package/src/lsp/index.ts +6 -2
  731. package/src/lsp/lsp-latency.ts +62 -0
  732. package/src/lsp/save-text-document.ts +63 -0
  733. package/src/lsp/semantic-token-provider.ts +146 -8
  734. package/src/lsp/shared-module.ts +4 -8
  735. package/src/lsp/start-language-server.ts +21 -7
  736. package/src/messages/carriers.ts +4 -6
  737. package/src/messages/index.ts +11 -2
  738. package/src/messages/renderer.ts +11 -3
  739. package/src/node/event-loop-monitor.ts +2 -1
  740. package/src/node/heap-ceiling.ts +108 -0
  741. package/src/node/index.ts +5 -1
  742. package/src/node/latency-from-env.ts +1 -1
  743. package/src/node/log-file-sink.ts +6 -2
  744. package/src/node/log-preamble-node.ts +20 -10
  745. package/src/node/measure-memory.ts +5 -4
  746. package/src/node/memory-monitor.ts +10 -10
  747. package/src/node/node-file-system-provider.ts +214 -57
  748. package/src/node/profile-capture.ts +16 -15
  749. package/src/node/profiling-run.ts +30 -8
  750. package/src/node/rename-over-open-readers.ts +94 -0
  751. package/src/node/server-diagnostics.ts +1 -1
  752. package/src/node/server-state-snapshot.ts +6 -7
  753. package/src/node/socket-launcher.ts +78 -14
  754. package/src/node/startup-cpu-profile.ts +94 -0
  755. package/src/node/stdio-launcher.ts +29 -19
  756. package/src/node/validate-workspace.ts +8 -2
  757. package/src/testing/document-uri-policy-conformance.ts +1 -1
  758. package/src/testing/fake-document.ts +2 -1
  759. package/src/testing/index.ts +2 -1
  760. package/src/testing/langium-test-helpers.ts +1 -0
  761. package/src/testing/make-test-services.ts +83 -31
  762. package/src/testing/make-test-tracer.ts +26 -0
  763. package/src/testing/node/applied-edit-capture.ts +141 -0
  764. package/src/testing/node/index.ts +1 -0
  765. package/src/testing/node/lsp-harness.ts +2 -0
  766. package/src/testing/node/lsp-server-connection.ts +83 -119
  767. package/src/testing/node/scratch-workspace.ts +10 -5
  768. package/src/testing/node/spawned-server.ts +57 -3
  769. package/src/testing/node/unhandled-rejections.ts +31 -0
  770. package/src/testing/parse-semantic-root.ts +1 -1
  771. package/src/testing/playwright/flaky-network-proxy.ts +240 -0
  772. package/src/testing/playwright/index.ts +1 -0
  773. package/src/testing/playwright/server-log-capture.ts +137 -47
  774. package/src/testing/playwright/server-log-fixture.ts +46 -6
  775. package/src/testing/playwright/server-log-region.ts +32 -0
  776. package/src/testing/playwright/server-log-rename-reporter.ts +4 -3
  777. package/src/testing/run-update-pipeline.ts +8 -5
  778. package/src/testing/stub-ast-document-manager.ts +47 -123
  779. package/src/testing/stub-document-builder.ts +155 -18
  780. package/src/testing/stub-hydranium-text-documents.ts +184 -27
  781. package/src/testing/stub-langium-documents.ts +3 -2
  782. package/src/testing/stub-model-service.ts +9 -8
  783. package/src/testing/stub-project-manager.ts +10 -0
  784. package/src/testing/stub-self-save-registry.ts +1 -1
  785. package/src/testing/stub-service-registry.ts +1 -1
  786. package/src/testing/stub-writable-file-system.ts +3 -2
  787. package/src/util/connection-liveness.ts +81 -15
  788. package/src/util/environment.ts +24 -2
  789. package/lib/documents/language-client-text-shadow.d.ts +0 -124
  790. package/lib/documents/language-client-text-shadow.d.ts.map +0 -1
  791. package/lib/documents/language-client-text-shadow.js +0 -190
  792. package/lib/documents/language-client-text-shadow.js.map +0 -1
  793. package/lib/documents/self-save-registry.d.ts.map +0 -1
  794. package/lib/documents/self-save-registry.js.map +0 -1
  795. package/lib/lsp/instrument-connection.d.ts +0 -36
  796. package/lib/lsp/instrument-connection.d.ts.map +0 -1
  797. package/lib/lsp/instrument-connection.js +0 -62
  798. package/lib/lsp/instrument-connection.js.map +0 -1
  799. package/lib/node/process-memory.d.ts +0 -66
  800. package/lib/node/process-memory.d.ts.map +0 -1
  801. package/lib/node/process-memory.js +0 -252
  802. package/lib/node/process-memory.js.map +0 -1
  803. package/src/documents/language-client-text-shadow.ts +0 -211
  804. package/src/lsp/instrument-connection.ts +0 -66
  805. package/src/node/process-memory.ts +0 -299
@@ -0,0 +1,769 @@
1
+ /********************************************************************************
2
+ * Copyright (c) 2026 CrossBreeze, EclipseSource and others.
3
+ *
4
+ * This program and the accompanying materials are made available under the
5
+ * terms of the MIT License which is available in the project root.
6
+ *
7
+ * SPDX-License-Identifier: MIT
8
+ ********************************************************************************/
9
+
10
+ import {
11
+ type BaseVersion,
12
+ ConflictError,
13
+ isModelVersion,
14
+ Logger,
15
+ type MaybeObservableValue,
16
+ type MaybePromise,
17
+ ObservableValue,
18
+ type TextVersion,
19
+ type Tracer,
20
+ type TransferElement,
21
+ describeErrorWithStack
22
+ } from '@hydranium/protocol';
23
+ import { type AstNode, isOperationCancelled, UriUtils } from '@hydranium/langium';
24
+ import { type CancellationToken, type Disposable, Emitter, type Event } from 'vscode-languageserver';
25
+ import { type SavedAstDocument, type WrittenAstDocument } from '../../documents/ast-document-manager.js';
26
+ import { DocumentNotOpenError, DocumentSyntaxError, SessionClosedError } from '../../documents/client-session-errors.js';
27
+ import { type OpenOptions, type SessionEndCause } from '../../documents/client-session-registry.js';
28
+ import { type LogNameOptions } from '../diagnostics/logger.js';
29
+ import { type ServerSharedServices } from '../module.js';
30
+ import { type AstDiagnostic } from '../validation/document-validator.js';
31
+ import { hasSkippedText } from '../workspace/syntax-errors.js';
32
+ import { type ModelService } from './model-service.js';
33
+
34
+ /** What a session's `update` and `save` write into one document; the session supplies its own client id. */
35
+ export interface ClientSessionWriteArgs<TTransfer> {
36
+ uri: string;
37
+ /** The whole structured model root, or its serialised textual form. */
38
+ model: TTransfer | string;
39
+ /**
40
+ * The version the write was authored against, or `'any'` to write
41
+ * unconditionally. Required, so an ungated write is a decision the caller
42
+ * makes rather than a field it forgot.
43
+ */
44
+ baseVersion: BaseVersion;
45
+ /**
46
+ * Set when the write restores one the session made before a reconnect. Its
47
+ * model was written over text that parsed, so it is not refused when the
48
+ * text no longer does.
49
+ */
50
+ restore?: boolean;
51
+ }
52
+
53
+ /** What a session's `persist` writes: the text the store holds for `uri`. */
54
+ export type ClientSessionPersistArgs = Omit<ClientSessionWriteArgs<never>, 'model' | 'restore'>;
55
+
56
+ /** What a session's `delete` removes: the document at `uri`, at the version it was based on. */
57
+ export type ClientSessionDeleteArgs = Omit<ClientSessionWriteArgs<never>, 'model' | 'restore'>;
58
+
59
+ /** What a session's `updateAll` writes, all or none. */
60
+ export interface ClientSessionUpdateAllArgs<TTransfer> {
61
+ updates: ClientSessionWriteArgs<TTransfer>[];
62
+ }
63
+
64
+ /**
65
+ * One participant's handle on the documents it works on, started by
66
+ * `ModelService.createSession`.
67
+ *
68
+ * The session writes only what it has open: `update`, `save`, `persist` and
69
+ * `delete` fail with `DocumentNotOpenError` unless this session has the URI
70
+ * open in the synchronous step that applies or takes the text, or marks the
71
+ * document for deletion, so a write either lands while the document is open or
72
+ * fails. They fail the same way while any session's `delete` of the URI is
73
+ * under way. A document stays open until this session closes it, the session
74
+ * ends, or the file is deleted.
75
+ *
76
+ * One open per URI, without reference counting: opening a URI the session
77
+ * already has open changes nothing, and one `close` ends it.
78
+ *
79
+ * After `dispose`, every other member throws `SessionClosedError`
80
+ * synchronously, before returning a promise.
81
+ *
82
+ * Reads need no session and live on `ModelService`.
83
+ */
84
+ export interface ClientSession<
85
+ TAst extends AstNode,
86
+ TDiagnostic extends AstDiagnostic = AstDiagnostic,
87
+ TTransfer extends TransferElement = TransferElement,
88
+ TOpenOptions extends OpenOptions = OpenOptions
89
+ > {
90
+ /** Unique in the process while the session is live: the author label on its writes and the key of its opens. */
91
+ readonly clientId: string;
92
+ readonly label: string;
93
+
94
+ /**
95
+ * Open `uri` for this session, reading it from disk unless some client has
96
+ * it open already or it holds this client's unsaved text within its release
97
+ * grace. `options` are kept for this open until it closes; a repeat open,
98
+ * concurrent or not, keeps the options of the first.
99
+ *
100
+ * Waits for the workspace to be brought up, as {@link create} does, and does
101
+ * not settle while nothing brings it up. So neither may be awaited from
102
+ * inside the bring-up, such as a workspace manager's document loading: the
103
+ * bring-up then waits for itself.
104
+ */
105
+ open(uri: string, options?: TOpenOptions): Promise<void>;
106
+ /** The options this session opened `uri` with, or `undefined` when it gave none or does not have `uri` open. */
107
+ openOptions(uri: string): TOpenOptions | undefined;
108
+ /**
109
+ * Create a document with `text` and open it for this session. It reaches
110
+ * disk on the first `save`. `text` is written as given: make it from a
111
+ * model with {@link ModelService.modelToText}, which gives it the ending a
112
+ * write would. Fails when the file exists, any client has the URI open, or
113
+ * the URI waits out the release grace, and of two creates of one URI at
114
+ * most one succeeds.
115
+ *
116
+ * Resolves with the version the created document took, which a write based
117
+ * on it names: once this resolves, the store's version may already be
118
+ * another client's write.
119
+ */
120
+ create(uri: string, text: string): Promise<TextVersion>;
121
+ /**
122
+ * Write `args.model` into a document this session has open. Resolves to the
123
+ * rebuilt document once it is validated, in whichever build carried the
124
+ * write, so the answer holds every diagnostic its update event does: that
125
+ * event names this session, and a client dropping its own echo would
126
+ * otherwise never see them. `written` names the version the text took.
127
+ * A model, not text, written to a document whose last build lacks some of
128
+ * its text, see `hasSkippedText`, fails with `DocumentSyntaxError`, unless
129
+ * the write is a `restore`.
130
+ */
131
+ update(args: ClientSessionWriteArgs<TTransfer>, cancelToken?: CancellationToken): Promise<WrittenAstDocument<TAst, TDiagnostic>>;
132
+ /**
133
+ * Write several documents this session has open, all or none: a
134
+ * `ConflictError`, `DocumentNotOpenError` or `DocumentSyntaxError` for any
135
+ * of them is thrown before any text applies. Resolves to the rebuilt
136
+ * documents, in the order given, each validated as {@link update}'s is.
137
+ */
138
+ updateAll(
139
+ args: ClientSessionUpdateAllArgs<TTransfer>,
140
+ cancelToken?: CancellationToken
141
+ ): Promise<WrittenAstDocument<TAst, TDiagnostic>[]>;
142
+ /**
143
+ * Write `args.model` as {@link update} does, then persist the document. A
144
+ * save is never a `restore`, so its model is always checked.
145
+ */
146
+ save(
147
+ args: Omit<ClientSessionWriteArgs<TTransfer>, 'restore'>,
148
+ cancelToken?: CancellationToken
149
+ ): Promise<SavedAstDocument<TAst, TDiagnostic>>;
150
+ /**
151
+ * Persist the text the store holds for `args.uri` as it is, with no update
152
+ * and no serialisation. Resolves with the version of the text written, once
153
+ * it is on disk, without waiting for a build. The saved event names this
154
+ * session, also when another client wrote the text.
155
+ */
156
+ persist(args: ClientSessionPersistArgs): Promise<TextVersion>;
157
+ /**
158
+ * Delete `args.uri` at once: its file, then the document, as a deletion a
159
+ * file watcher reports removes it. Every session's open of it closes, the
160
+ * editor's stays, and the deletion event names this session. Resolves once
161
+ * the build that removes the document has run. `args.baseVersion` is gated
162
+ * as {@link persist} gates it; a file already gone deletes only the
163
+ * document, and one that cannot be removed fails the call, deleting nothing.
164
+ * The file removed is the one the store keys the document by: under
165
+ * `RealpathDocumentUriPolicy`, a symlink's target rather than the link.
166
+ *
167
+ * A change requested before that build starts, by the editor or a file
168
+ * watcher, keeps the document, and only this session's open of it closes.
169
+ * From inside a build the call fails with `ReentrantWriteLockError`,
170
+ * whatever `ModelServiceOptions.allowReentrantBuilds` says.
171
+ */
172
+ delete(args: ClientSessionDeleteArgs): Promise<void>;
173
+ /** Close this session's open of `uri`, at once. A no-op when it does not have `uri` open. */
174
+ close(uri: string): Promise<void>;
175
+ /**
176
+ * Open `uri`, run `fn`, and close `uri` when `fn` settles, whether it
177
+ * returned or threw. A URI the session already had open, or is still
178
+ * opening through another call, stays open: the close undoes only the open
179
+ * this call made.
180
+ */
181
+ withOpen<T>(uri: string, fn: () => MaybePromise<T>): Promise<T>;
182
+ /** Whether an event's `sourceClientId` names this session, i.e. the event echoes its own write. */
183
+ isOwnEcho(sourceClientId: string): boolean;
184
+ /**
185
+ * End the session: close everything it has open and free its id.
186
+ * Idempotent. `cause` is `'lost'` when the session ends because its
187
+ * client's connection went away, which lets each document it was the last
188
+ * to have open wait out the store's release grace; ending it for any other
189
+ * reason releases such a document at once.
190
+ */
191
+ dispose(cause?: SessionEndCause): void;
192
+ /**
193
+ * Fires once the session has ended, its documents closed, with the cause it
194
+ * ended with. A takeover through `createSession` ends it as `'lost'` from
195
+ * another caller, so a holder that keeps per-session state releases it here.
196
+ */
197
+ readonly onDidDispose: Event<SessionEndCause>;
198
+ }
199
+
200
+ /**
201
+ * The framework's {@link ClientSession}, built by
202
+ * {@link DefaultClientSessionFactory}.
203
+ *
204
+ * Override the protected method behind a member to change how every session
205
+ * writes, and return the subclass from a {@link ClientSessionFactory} bound on
206
+ * `model.ClientSessionFactory`. Serialising a model and rebuilding a document
207
+ * are the {@link ModelService}'s.
208
+ *
209
+ * An override of {@link dispose} calls `super.dispose(cause)`: that is what
210
+ * closes the session's opens and frees its id, and dropping `cause` reverts
211
+ * a lost client's documents without their grace.
212
+ */
213
+ export class DefaultClientSession<
214
+ TAst extends AstNode,
215
+ TDiagnostic extends AstDiagnostic = AstDiagnostic,
216
+ TTransfer extends TransferElement = TransferElement,
217
+ TOpenOptions extends OpenOptions = OpenOptions
218
+ > implements ClientSession<TAst, TDiagnostic, TTransfer, TOpenOptions> {
219
+ protected disposed = false;
220
+ /**
221
+ * This session's opens still under way, by canonical URI. Recorded before
222
+ * the first await, so a second open of the same URI joins the first rather
223
+ * than racing it, and `withOpen` can tell an open another call is making.
224
+ */
225
+ protected readonly pendingOpens = new Map<string, Promise<void>>();
226
+ /**
227
+ * The options of this session's opens, by canonical URI. A first open
228
+ * records its entry before the store has the URI open, and the entry goes
229
+ * when that open closes, whoever ends it: this session, or the store for a
230
+ * deleted file. A first open that fails never opens, so nothing closes it
231
+ * and its entry stays until the next first open of the URI overwrites it;
232
+ * {@link openOptions} therefore reads an entry only while the store has the
233
+ * URI open for this session.
234
+ */
235
+ protected readonly openOptionsByUri = new Map<string, TOpenOptions | undefined>();
236
+ /** Drops an open's options from {@link openOptionsByUri} when the store closes the open. */
237
+ protected readonly closeListener: Disposable;
238
+ protected readonly disposeEmitter = new Emitter<SessionEndCause>();
239
+ /** Logs under `logName`, `ClientSession` when none is given, with this session's id in a bracket of its own, so a line names the session that wrote. */
240
+ protected readonly tracer: Tracer;
241
+ /** The service bound on `model.ModelService`, which serialises and rebuilds for this session. */
242
+ protected readonly modelService: ModelService<TAst, TDiagnostic, TTransfer>;
243
+ /** See {@link ClientSessionFactoryOptions.slowUpdateWarnMs}; `undefined` when not set. */
244
+ protected readonly slowUpdateWarn?: ObservableValue<number>;
245
+ readonly clientId: string;
246
+ readonly label: string;
247
+
248
+ constructor(
249
+ protected readonly services: ServerSharedServices,
250
+ options: ClientSessionOptions
251
+ ) {
252
+ this.clientId = options.clientId;
253
+ this.label = options.label ?? options.clientId;
254
+ // The slot is shared across grammars; this session's types hold for the
255
+ // grammar that started it, as `createSession`'s narrowing does.
256
+ this.modelService = services.model.ModelService as ModelService<TAst, TDiagnostic, TTransfer>;
257
+ this.slowUpdateWarn = options.slowUpdateWarnMs !== undefined ? ObservableValue.from(options.slowUpdateWarnMs) : undefined;
258
+ this.tracer = services.Tracer.for(options.logName ?? 'ClientSession').with(this.clientId);
259
+ this.closeListener = services.workspace.TextDocuments.onDidClose(event => {
260
+ if (event.clientId === this.clientId) {
261
+ this.openOptionsByUri.delete(event.document.uri);
262
+ }
263
+ });
264
+ }
265
+
266
+ open(uri: string, options?: TOpenOptions): Promise<void> {
267
+ this.assertLive();
268
+ return this.openDocument(uri, options);
269
+ }
270
+
271
+ openOptions(uri: string): TOpenOptions | undefined {
272
+ this.assertLive();
273
+ return this.services.workspace.TextDocuments.isOpenInClient(uri, this.clientId)
274
+ ? this.openOptionsByUri.get(this.canonicalKey(uri))
275
+ : undefined;
276
+ }
277
+
278
+ create(uri: string, text: string): Promise<TextVersion> {
279
+ this.assertLive();
280
+ return this.createDocument(uri, text);
281
+ }
282
+
283
+ update(args: ClientSessionWriteArgs<TTransfer>, cancelToken?: CancellationToken): Promise<WrittenAstDocument<TAst, TDiagnostic>> {
284
+ this.assertLive();
285
+ return this.updateDocument(args, cancelToken);
286
+ }
287
+
288
+ updateAll(
289
+ args: ClientSessionUpdateAllArgs<TTransfer>,
290
+ cancelToken?: CancellationToken
291
+ ): Promise<WrittenAstDocument<TAst, TDiagnostic>[]> {
292
+ this.assertLive();
293
+ return this.updateDocuments(args, cancelToken);
294
+ }
295
+
296
+ save(
297
+ args: Omit<ClientSessionWriteArgs<TTransfer>, 'restore'>,
298
+ cancelToken?: CancellationToken
299
+ ): Promise<SavedAstDocument<TAst, TDiagnostic>> {
300
+ this.assertLive();
301
+ return this.saveDocument(args, cancelToken);
302
+ }
303
+
304
+ persist(args: ClientSessionPersistArgs): Promise<TextVersion> {
305
+ this.assertLive();
306
+ return this.persistDocument(args);
307
+ }
308
+
309
+ close(uri: string): Promise<void> {
310
+ this.assertLive();
311
+ return this.closeDocument(uri);
312
+ }
313
+
314
+ delete(args: ClientSessionDeleteArgs): Promise<void> {
315
+ this.assertLive();
316
+ return this.deleteDocument(args);
317
+ }
318
+
319
+ withOpen<T>(uri: string, fn: () => MaybePromise<T>): Promise<T> {
320
+ this.assertLive();
321
+ return this.runWithOpen(uri, fn);
322
+ }
323
+
324
+ isOwnEcho(sourceClientId: string): boolean {
325
+ this.assertLive();
326
+ return sourceClientId === this.clientId;
327
+ }
328
+
329
+ dispose(cause?: SessionEndCause): void {
330
+ if (this.disposed) {
331
+ return;
332
+ }
333
+ this.disposed = true;
334
+ this.services.workspace.TextDocuments.closeSession(this.clientId, cause);
335
+ this.closeListener.dispose();
336
+ this.disposeEmitter.fire(cause ?? 'closed');
337
+ this.disposeEmitter.dispose();
338
+ }
339
+
340
+ get onDidDispose(): Event<SessionEndCause> {
341
+ return this.disposeEmitter.event;
342
+ }
343
+
344
+ protected assertLive(): void {
345
+ if (this.disposed) {
346
+ throw new SessionClosedError(this.clientId);
347
+ }
348
+ }
349
+
350
+ /** Throw `DocumentNotOpenError` unless this session has `uri` open and no delete of it is under way. */
351
+ protected assertOpen(uri: string): void {
352
+ const workspace = this.services.workspace;
353
+ if (!workspace.TextDocuments.isOpenInClient(uri, this.clientId) || workspace.AstDocumentManager.isDeleting(uri)) {
354
+ throw new DocumentNotOpenError(uri, this.clientId);
355
+ }
356
+ }
357
+
358
+ /**
359
+ * Throw `ConflictError` when `baseVersion` names a version other than
360
+ * `currentVersion`. A write calls it at the door and again in the
361
+ * synchronous step that applies the text, and has to call it synchronously
362
+ * there: a check separated from the apply by an await lets two writes based
363
+ * on one version both apply.
364
+ */
365
+ protected assertBaseVersion(uri: string, baseVersion: BaseVersion, currentVersion: number): void {
366
+ if (isModelVersion(baseVersion) && currentVersion !== baseVersion) {
367
+ // Distinct from the post-build "superseded" debug line of an update: this
368
+ // is a stale-base-version rejection (the write never applies), not two
369
+ // writes racing.
370
+ this.tracer.debug(`Conflict on ${uri}: stale base, model v${baseVersion} / text v${currentVersion}`);
371
+ throw new ConflictError(uri, baseVersion, currentVersion);
372
+ }
373
+ }
374
+
375
+ /**
376
+ * Throw `DocumentSyntaxError` when the parse of `uri`'s last build lacks
377
+ * some of its text, see `hasSkippedText`. A write of a model calls it beside
378
+ * {@link assertBaseVersion}: the model is serialized over the whole text,
379
+ * and one read from such a document lacks what the parser skipped.
380
+ */
381
+ protected assertParses(uri: string): void {
382
+ const document = this.modelService.getDocument(uri);
383
+ if (document && hasSkippedText(document)) {
384
+ throw new DocumentSyntaxError(uri);
385
+ }
386
+ }
387
+
388
+ /**
389
+ * Serialise `args.model`, apply it to the store under this session's id,
390
+ * rebuild, and resolve to the rebuilt document.
391
+ *
392
+ * The open check, the `baseVersion` gate and, for a model, the parse check
393
+ * run at the door, so a write that cannot land is refused before any
394
+ * adopter serialiser runs, and again in the synchronous step that applies
395
+ * the text: made only before the serialiser's await, a close during it
396
+ * lets the write land on a document this session no longer has open, and
397
+ * two writes based on one version both apply.
398
+ *
399
+ * Resolves with the latest build of the document, which may already carry
400
+ * a newer write; that is logged at debug, and a slow update at warn when
401
+ * `ClientSessionFactoryOptions.slowUpdateWarnMs` is set. It waits for the
402
+ * builder's final phase rather than the write's own build: a later write
403
+ * cancels that build, and the one that takes over validates the document
404
+ * after the answer was taken.
405
+ */
406
+ protected async updateDocument(
407
+ args: ClientSessionWriteArgs<TTransfer>,
408
+ cancelToken?: CancellationToken
409
+ ): Promise<WrittenAstDocument<TAst, TDiagnostic>> {
410
+ const service = this.modelService;
411
+ const slowWarn = this.slowUpdateWarn && { threshold: this.slowUpdateWarn, stopwatch: this.services.Clock.stopwatch() };
412
+ const uri = this.canonicalKey(args.uri);
413
+ const profile = Logger.isLevelEnabled('debug') ? this.tracer.profile(`model-update ${uri}`) : undefined;
414
+ const run = async <T>(stage: string, fn: () => MaybePromise<T>): Promise<T> => (profile ? profile.scope(stage, fn) : fn());
415
+ const textDocuments = this.services.workspace.TextDocuments;
416
+ const check = (): void => {
417
+ this.assertOpen(uri);
418
+ this.assertBaseVersion(uri, args.baseVersion, textDocuments.version(uri));
419
+ if (typeof args.model !== 'string' && !args.restore) {
420
+ this.assertParses(uri);
421
+ }
422
+ };
423
+ check();
424
+ service.assertCanBuild(uri);
425
+ const text = await run('serialize', () => service.modelToText(uri, args.model, cancelToken));
426
+ const appliedVersion = await run('apply', () => {
427
+ check();
428
+ return this.services.workspace.AstDocumentManager.update(uri, text, this.clientId);
429
+ });
430
+ // Through the public `rebuild`, so an override of it stays in the path.
431
+ // An override that awaits before calling the base can outlast the build
432
+ // this write already has, and then builds it twice; see
433
+ // `ModelService.rebuild`.
434
+ const doc = await run('rebuild', () => service.rebuild(uri, this.services.workspace.DocumentBuilder.finalBuildState(), cancelToken));
435
+ const finalVersion = textDocuments.version(uri);
436
+ if (finalVersion > appliedVersion) {
437
+ this.tracer.debug(`Update to v${appliedVersion} ready at v${finalVersion} (changed again before it settled)`);
438
+ } else {
439
+ this.tracer.debug(`Update to v${appliedVersion} ready`);
440
+ }
441
+ if (slowWarn) {
442
+ const elapsed = Math.round(slowWarn.stopwatch.elapsedMs);
443
+ const threshold = slowWarn.threshold.value;
444
+ if (elapsed >= threshold) {
445
+ this.tracer.withUri(uri).warn(`Slow update: ${elapsed}ms ≥ ${threshold}ms (v${appliedVersion}, client=${this.clientId})`);
446
+ }
447
+ }
448
+ profile?.report('debug');
449
+ return { ...doc, written: { version: appliedVersion } };
450
+ }
451
+
452
+ /**
453
+ * Write every document of `args.updates`, all or none: every model is
454
+ * serialised first, then every open check, `baseVersion` gate and parse
455
+ * check runs and every text is applied in one synchronous step. Checked at
456
+ * the door as well, so a stale set is refused before any adopter serialiser
457
+ * runs.
458
+ *
459
+ * The apply step relies on `AstDocumentManager.update` applying its text
460
+ * before its first await, as the default does: an override that awaits first
461
+ * lets another write land between two documents of the set.
462
+ */
463
+ protected async updateDocuments(
464
+ args: ClientSessionUpdateAllArgs<TTransfer>,
465
+ cancelToken?: CancellationToken
466
+ ): Promise<WrittenAstDocument<TAst, TDiagnostic>[]> {
467
+ const service = this.modelService;
468
+ const { updates } = args;
469
+ const textDocuments = this.services.workspace.TextDocuments;
470
+ const uris = updates.map(update => this.canonicalKey(update.uri));
471
+ if (new Set(uris).size !== uris.length) {
472
+ throw new Error(`updateAll names a document more than once: ${uris.join(', ')}`);
473
+ }
474
+ const check = (): void =>
475
+ updates.forEach((update, i) => {
476
+ this.assertOpen(uris[i]);
477
+ this.assertBaseVersion(uris[i], update.baseVersion, textDocuments.version(uris[i]));
478
+ if (typeof update.model !== 'string' && !update.restore) {
479
+ this.assertParses(uris[i]);
480
+ }
481
+ service.assertCanBuild(uris[i]);
482
+ });
483
+ check();
484
+ const texts: string[] = [];
485
+ for (const [i, update] of updates.entries()) {
486
+ texts.push(await service.modelToText(uris[i], update.model, cancelToken));
487
+ }
488
+ // One synchronous step from the first check to the last apply: an await
489
+ // anywhere in it lets a close or another write land after its document
490
+ // was checked, and the set then half-applies before a later check fails.
491
+ check();
492
+ const applied = uris.map((uri, i) => this.services.workspace.AstDocumentManager.update(uri, texts[i], this.clientId));
493
+ const versions = await Promise.all(applied);
494
+ const state = this.services.workspace.DocumentBuilder.finalBuildState();
495
+ const rebuilt = await Promise.allSettled(uris.map(uri => service.rebuild(uri, state, cancelToken)));
496
+ const failures = rebuilt.flatMap((result, i) => (result.status === 'rejected' ? [{ uri: uris[i], reason: result.reason }] : []));
497
+ if (failures.length === 0) {
498
+ return rebuilt.flatMap((result, i) =>
499
+ result.status === 'fulfilled' ? [{ ...result.value, written: { version: versions[i] } }] : []
500
+ );
501
+ }
502
+ // The first is thrown as it is, so a typed failure keeps its type; one build
503
+ // usually carries the set and fails each with the same error. Any other
504
+ // failure reaches no one else, so it is logged here.
505
+ const [{ uri: firstUri, reason: firstReason }] = failures;
506
+ for (const { uri, reason } of failures.slice(1)) {
507
+ if (isOperationCancelled(reason)) {
508
+ this.tracer.with(uri).debug(`Rebuild of ${uri} cancelled beside that of ${firstUri}`);
509
+ } else if (reason !== firstReason) {
510
+ this.tracer.with(uri).error(`Rebuild of ${uri} failed beside that of ${firstUri}. ${describeErrorWithStack(reason)}`);
511
+ }
512
+ }
513
+ throw firstReason;
514
+ }
515
+
516
+ /**
517
+ * Write `args.model` through {@link updateDocument}, then persist it through
518
+ * {@link persistDocument}, so an override of either applies to saves too.
519
+ *
520
+ * Fails with `DocumentNotOpenError` and writes nothing when this session
521
+ * closes the URI while the text is being built. Persisted at `'any'`: the
522
+ * update already gated on `args.baseVersion` and moved the text past it.
523
+ * A `restore` in `args` is dropped: a save puts the model on disk, so
524
+ * it is always checked.
525
+ */
526
+ protected async saveDocument(
527
+ args: ClientSessionWriteArgs<TTransfer>,
528
+ cancelToken?: CancellationToken
529
+ ): Promise<SavedAstDocument<TAst, TDiagnostic>> {
530
+ const doc = await this.updateDocument({ ...args, restore: undefined }, cancelToken);
531
+ const version = await this.persistDocument({ uri: args.uri, baseVersion: 'any' });
532
+ return { ...doc, persisted: { version } };
533
+ }
534
+
535
+ /**
536
+ * Persist the store's text for `args.uri` under this session's id. Every
537
+ * write to disk a session makes goes through here, so an override sees each
538
+ * of them.
539
+ *
540
+ * The open check and the `baseVersion` gate sit in the same synchronous step
541
+ * as the manager taking the text: an await between them lets another
542
+ * client's write land after the gate, and its text is then persisted under
543
+ * this session's id without this session ever having seen it. An override
544
+ * that awaits before calling the base lets a diagram save take its
545
+ * documents' texts at different moments, and a diagram that ends during the
546
+ * await fails the documents not yet taken with `DocumentNotOpenError`.
547
+ */
548
+ protected async persistDocument(args: ClientSessionPersistArgs): Promise<TextVersion> {
549
+ const uri = this.canonicalKey(args.uri);
550
+ this.assertOpen(uri);
551
+ this.assertBaseVersion(uri, args.baseVersion, this.services.workspace.TextDocuments.version(uri));
552
+ return this.services.workspace.AstDocumentManager.save(uri, this.clientId);
553
+ }
554
+
555
+ /**
556
+ * Delete `args.uri` under this session's id. The open check and the
557
+ * `baseVersion` gate sit in the same synchronous step as the manager's
558
+ * mark, which refuses every later write of the URI: an await between them
559
+ * lets another client's write land after the gate, and the delete then
560
+ * discards text this session never saw.
561
+ */
562
+ protected async deleteDocument(args: ClientSessionDeleteArgs): Promise<void> {
563
+ const uri = this.canonicalKey(args.uri);
564
+ this.assertOpen(uri);
565
+ this.assertBaseVersion(uri, args.baseVersion, this.services.workspace.TextDocuments.version(uri));
566
+ return this.services.workspace.AstDocumentManager.delete(uri, this.clientId);
567
+ }
568
+
569
+ protected async closeDocument(uri: string): Promise<void> {
570
+ await this.services.workspace.AstDocumentManager.close({ uri, clientId: this.clientId });
571
+ }
572
+
573
+ /** Open `uri`, or join the open of it this session already has under way, whose options then stand. */
574
+ protected openDocument(uri: string, options: TOpenOptions | undefined): Promise<void> {
575
+ const key = this.canonicalKey(uri);
576
+ const pending = this.pendingOpens.get(key);
577
+ if (pending) {
578
+ return pending;
579
+ }
580
+ const opening = this.registerOpen(uri, options).finally(() => {
581
+ if (this.pendingOpens.get(key) === opening) {
582
+ this.pendingOpens.delete(key);
583
+ }
584
+ });
585
+ this.pendingOpens.set(key, opening);
586
+ return opening;
587
+ }
588
+
589
+ /**
590
+ * Open `uri` in the store for this session. The open path does not thread
591
+ * cancellation: the file read behind it takes no token, so a cancelled
592
+ * caller still completes the open.
593
+ *
594
+ * A first open records its options before the store opens the URI, so a
595
+ * listener of the store's open reads this open's options rather than an
596
+ * earlier one's.
597
+ *
598
+ * It waits for the workspace first, as an LSP head's open does: a document
599
+ * opened before the bring-up links against a workspace that holds only
600
+ * itself, and the bring-up does not always relink it.
601
+ */
602
+ protected async registerOpen(uri: string, options: TOpenOptions | undefined): Promise<void> {
603
+ await this.modelService.ready;
604
+ // A session ended during the wait opens nothing.
605
+ this.assertLive();
606
+ const wasOpen = this.services.workspace.TextDocuments.isOpenInClient(uri, this.clientId);
607
+ if (!wasOpen) {
608
+ this.openOptionsByUri.set(this.canonicalKey(uri), options);
609
+ }
610
+ await this.services.workspace.AstDocumentManager.open({ uri, clientId: this.clientId });
611
+ await this.rejectIfEnded(uri, wasOpen);
612
+ }
613
+
614
+ protected canonicalKey(uri: string): string {
615
+ return this.services.workspace.DocumentUriPolicy.canonicalUri(uri);
616
+ }
617
+
618
+ protected async createDocument(uri: string, text: string): Promise<TextVersion> {
619
+ // As `registerOpen` does, and before the checks, which read the workspace.
620
+ await this.modelService.ready;
621
+ if (await this.services.workspace.FileSystemProvider.exists(UriUtils.toUri(uri))) {
622
+ throw new Error(`Cannot create ${uri}: the file exists`);
623
+ }
624
+ this.assertLive();
625
+ if (this.services.workspace.TextDocuments.isReleaseDeferred(uri)) {
626
+ throw new Error(`Cannot create ${uri}: it holds the unsaved text of a lost client, waiting out the release grace`);
627
+ }
628
+ if (this.modelService.isOpen(uri)) {
629
+ throw new Error(`Cannot create ${uri}: it is open in a client`);
630
+ }
631
+ // The check above cannot see an open that registers while this one is
632
+ // under way, and opening an already-open URI only attaches, dropping
633
+ // `text`. Only an open that creates the document fires `onDidOpen`, so
634
+ // hearing it for this session, during this open, is what proves the
635
+ // document holds `text`; the client list afterwards cannot, since a
636
+ // client that registered first may have closed again by then.
637
+ const key = this.canonicalKey(uri);
638
+ let created: TextVersion | undefined;
639
+ const listener = this.services.workspace.TextDocuments.onDidOpen(event => {
640
+ if (event.clientId === this.clientId && event.document.uri === key) {
641
+ created = event.document.version;
642
+ }
643
+ });
644
+ try {
645
+ await this.services.workspace.AstDocumentManager.open({ uri, clientId: this.clientId, text });
646
+ } finally {
647
+ listener.dispose();
648
+ }
649
+ await this.rejectIfEnded(uri, false);
650
+ if (created === undefined) {
651
+ await this.closeDocument(uri);
652
+ throw new Error(`Cannot create ${uri}: it is open in a client`);
653
+ }
654
+ return created;
655
+ }
656
+
657
+ protected async runWithOpen<T>(uri: string, fn: () => MaybePromise<T>): Promise<T> {
658
+ // An open another call of this session is still making counts as made:
659
+ // closing it afterwards would take away an open that call asked for.
660
+ const alreadyOpen =
661
+ this.services.workspace.TextDocuments.isOpenInClient(uri, this.clientId) || this.pendingOpens.has(this.canonicalKey(uri));
662
+ await this.openDocument(uri, undefined);
663
+ try {
664
+ return await fn();
665
+ } finally {
666
+ if (!alreadyOpen && !this.disposed) {
667
+ await this.closeDocument(uri);
668
+ }
669
+ }
670
+ }
671
+
672
+ /**
673
+ * Undo an open that completed after the session ended, then fail it.
674
+ *
675
+ * Ending the session closed only what it had open at that moment. An open
676
+ * still reading from disk registers afterwards, under an id that is no
677
+ * longer a session, and nothing would ever close it.
678
+ *
679
+ * Opens are keyed by id, so once a new session holds the same id this open
680
+ * is indistinguishable from one of its own, and closing it would close the
681
+ * new session's. It is left to that session, which releases it at its end.
682
+ */
683
+ protected async rejectIfEnded(uri: string, wasOpen: boolean): Promise<void> {
684
+ if (!this.disposed) {
685
+ return;
686
+ }
687
+ if (!wasOpen && this.modelService.getSession(this.clientId) === undefined) {
688
+ await this.closeDocument(uri);
689
+ }
690
+ throw new SessionClosedError(this.clientId);
691
+ }
692
+ }
693
+
694
+ /** Constructor options for {@link DefaultClientSessionFactory}. */
695
+ export interface ClientSessionFactoryOptions extends LogNameOptions {
696
+ /**
697
+ * The name the factory and every session it builds log under, so one
698
+ * option renames both. Default: `ClientSessionFactory` for the factory,
699
+ * and `ClientSession` for a session, which adds its client id in a bracket
700
+ * of its own.
701
+ */
702
+ readonly logName?: string;
703
+ /**
704
+ * When set, a session's `update` logs a `warn` line if its end-to-end wait
705
+ * (serialise, apply, rebuild) takes at least this many milliseconds. Default
706
+ * `undefined`: no warn line, and no per-update stopwatch.
707
+ *
708
+ * Observability only: the update is neither aborted nor resolved
709
+ * differently. A hard timeout that throws is an override of
710
+ * `DefaultClientSession.updateDocument` racing the parent call against a
711
+ * deadline.
712
+ *
713
+ * A recommended starting threshold is 2-5 seconds; workspaces with very
714
+ * large documents or slow validation can exceed 5 s on a cold build. A
715
+ * `Settings.number` binding retunes it live.
716
+ */
717
+ readonly slowUpdateWarnMs?: MaybeObservableValue<number>;
718
+ }
719
+
720
+ /**
721
+ * Constructor options for {@link DefaultClientSession}: the factory's options,
722
+ * which it forwards, plus the session's identity.
723
+ */
724
+ export interface ClientSessionOptions extends ClientSessionFactoryOptions {
725
+ readonly clientId: string;
726
+ /** What the session is. Pass one: the client id stands in for it otherwise. */
727
+ readonly label?: string;
728
+ }
729
+
730
+ /**
731
+ * Builds the handle for a session `ModelService.createSession` has already
732
+ * registered, so registration and the uniqueness check cannot be skipped by
733
+ * binding a factory of one's own. Bind one on `model.ClientSessionFactory` to
734
+ * use a session class of your own. A factory that does not pass
735
+ * {@link ClientSessionFactoryOptions.slowUpdateWarnMs} on to its sessions
736
+ * loses their slow-update warn; subclassing {@link DefaultClientSessionFactory}
737
+ * keeps it.
738
+ *
739
+ * Typed for every grammar, since the slot is shared: `createSession` narrows
740
+ * the result to its caller's types.
741
+ */
742
+ export interface ClientSessionFactory {
743
+ create(clientId: string, label: string): ClientSession<AstNode>;
744
+ }
745
+
746
+ /**
747
+ * The framework's {@link ClientSessionFactory}: a {@link DefaultClientSession}
748
+ * over the {@link ModelService} bound on `model.ModelService`, which the session
749
+ * serialises and rebuilds through. A model service constructed outside that
750
+ * slot therefore starts sessions that write through the bound one.
751
+ *
752
+ * A subclass that overrides {@link create} to build a session class of its
753
+ * own passes {@link options} on to that session's constructor; a session built
754
+ * without them has no slow-update warn and logs under the default name.
755
+ */
756
+ export class DefaultClientSessionFactory implements ClientSessionFactory {
757
+ protected readonly tracer: Tracer;
758
+
759
+ constructor(
760
+ protected readonly services: ServerSharedServices,
761
+ protected readonly options: ClientSessionFactoryOptions = {}
762
+ ) {
763
+ this.tracer = services.Tracer.for(options.logName ?? 'ClientSessionFactory').trace('instantiated');
764
+ }
765
+
766
+ create(clientId: string, label: string): ClientSession<AstNode> {
767
+ return new DefaultClientSession(this.services, { ...this.options, clientId, label });
768
+ }
769
+ }