@hydranium/core 1.0.0-next.29 → 1.0.0-next.298

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