@hydranium/core 1.0.0-next.39 → 1.0.0-next.391
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.
- package/README.md +78 -82
- package/lib/browser/host-heads-in-worker.d.ts +77 -0
- package/lib/browser/host-heads-in-worker.d.ts.map +1 -0
- package/lib/browser/host-heads-in-worker.js +169 -0
- package/lib/browser/host-heads-in-worker.js.map +1 -0
- package/lib/browser/index.d.ts +12 -0
- package/lib/browser/index.d.ts.map +1 -0
- package/lib/browser/index.js +17 -0
- package/lib/browser/index.js.map +1 -0
- package/lib/browser/indexeddb-file-system-store.d.ts +82 -0
- package/lib/browser/indexeddb-file-system-store.d.ts.map +1 -0
- package/lib/browser/indexeddb-file-system-store.js +181 -0
- package/lib/browser/indexeddb-file-system-store.js.map +1 -0
- package/lib/browser/start-language-server-in-worker.d.ts +32 -0
- package/lib/browser/start-language-server-in-worker.d.ts.map +1 -0
- package/lib/browser/start-language-server-in-worker.js +40 -0
- package/lib/browser/start-language-server-in-worker.js.map +1 -0
- package/lib/documents/ast-document-manager.d.ts +254 -140
- package/lib/documents/ast-document-manager.d.ts.map +1 -1
- package/lib/documents/ast-document-manager.js +311 -128
- package/lib/documents/ast-document-manager.js.map +1 -1
- package/lib/documents/client-ids.d.ts +5 -19
- package/lib/documents/client-ids.d.ts.map +1 -1
- package/lib/documents/client-ids.js +5 -19
- package/lib/documents/client-ids.js.map +1 -1
- package/lib/documents/client-session-errors.d.ts +15 -0
- package/lib/documents/client-session-errors.d.ts.map +1 -0
- package/lib/documents/client-session-errors.js +15 -0
- package/lib/documents/client-session-errors.js.map +1 -0
- package/lib/documents/client-session-registry.d.ts +146 -0
- package/lib/documents/client-session-registry.d.ts.map +1 -0
- package/lib/documents/client-session-registry.js +207 -0
- package/lib/documents/client-session-registry.js.map +1 -0
- package/lib/documents/dirty-state-tracker.d.ts +101 -0
- package/lib/documents/dirty-state-tracker.d.ts.map +1 -0
- package/lib/documents/dirty-state-tracker.js +85 -0
- package/lib/documents/dirty-state-tracker.js.map +1 -0
- package/lib/documents/document-release-handler.d.ts +204 -0
- package/lib/documents/document-release-handler.d.ts.map +1 -0
- package/lib/documents/document-release-handler.js +317 -0
- package/lib/documents/document-release-handler.js.map +1 -0
- package/lib/documents/document-release-scheduler.d.ts +67 -0
- package/lib/documents/document-release-scheduler.d.ts.map +1 -0
- package/lib/documents/document-release-scheduler.js +80 -0
- package/lib/documents/document-release-scheduler.js.map +1 -0
- package/lib/documents/file-system-task-queue.d.ts +52 -0
- package/lib/documents/file-system-task-queue.d.ts.map +1 -0
- package/lib/documents/file-system-task-queue.js +40 -0
- package/lib/documents/file-system-task-queue.js.map +1 -0
- package/lib/documents/hydranium-text-documents.d.ts +453 -282
- package/lib/documents/hydranium-text-documents.d.ts.map +1 -1
- package/lib/documents/hydranium-text-documents.js +918 -504
- package/lib/documents/hydranium-text-documents.js.map +1 -1
- package/lib/documents/index.d.ts +10 -2
- package/lib/documents/index.d.ts.map +1 -1
- package/lib/documents/index.js +10 -2
- package/lib/documents/index.js.map +1 -1
- package/lib/documents/language-client-shadow.d.ts +234 -0
- package/lib/documents/language-client-shadow.d.ts.map +1 -0
- package/lib/documents/language-client-shadow.js +306 -0
- package/lib/documents/language-client-shadow.js.map +1 -0
- package/lib/documents/model-ledger.d.ts +47 -0
- package/lib/documents/model-ledger.d.ts.map +1 -0
- package/lib/documents/model-ledger.js +30 -0
- package/lib/documents/model-ledger.js.map +1 -0
- package/lib/documents/text-ledger.d.ts +64 -0
- package/lib/documents/text-ledger.d.ts.map +1 -0
- package/lib/documents/text-ledger.js +63 -0
- package/lib/documents/text-ledger.js.map +1 -0
- package/lib/documents/version-sync-service.d.ts +153 -0
- package/lib/documents/version-sync-service.d.ts.map +1 -0
- package/lib/documents/version-sync-service.js +186 -0
- package/lib/documents/version-sync-service.js.map +1 -0
- package/lib/index.d.ts +3 -0
- package/lib/index.d.ts.map +1 -1
- package/lib/index.js +3 -0
- package/lib/index.js.map +1 -1
- package/lib/langium/ast-extension/ast-extension-service.d.ts +42 -31
- package/lib/langium/ast-extension/ast-extension-service.d.ts.map +1 -1
- package/lib/langium/ast-extension/ast-extension-service.js +45 -19
- package/lib/langium/ast-extension/ast-extension-service.js.map +1 -1
- package/lib/langium/ast-extension/ast-node-builder.d.ts +12 -7
- package/lib/langium/ast-extension/ast-node-builder.d.ts.map +1 -1
- package/lib/langium/ast-extension/ast-node-builder.js +25 -9
- package/lib/langium/ast-extension/ast-node-builder.js.map +1 -1
- package/lib/langium/bootstrap.d.ts +49 -36
- package/lib/langium/bootstrap.d.ts.map +1 -1
- package/lib/langium/bootstrap.js +75 -36
- package/lib/langium/bootstrap.js.map +1 -1
- package/lib/langium/build-phase-pass/build-phase-pass-service.d.ts +9 -9
- package/lib/langium/build-phase-pass/build-phase-pass-service.d.ts.map +1 -1
- package/lib/langium/build-phase-pass/build-phase-pass-service.js +25 -16
- package/lib/langium/build-phase-pass/build-phase-pass-service.js.map +1 -1
- package/lib/langium/build-phase-pass/build-phase-pass.d.ts +20 -8
- package/lib/langium/build-phase-pass/build-phase-pass.d.ts.map +1 -1
- package/lib/langium/build-phase-pass/build-phase-pass.js +20 -0
- package/lib/langium/build-phase-pass/build-phase-pass.js.map +1 -1
- package/lib/langium/composite-ast-reflection.d.ts +46 -0
- package/lib/langium/composite-ast-reflection.d.ts.map +1 -0
- package/lib/langium/composite-ast-reflection.js +97 -0
- package/lib/langium/composite-ast-reflection.js.map +1 -0
- package/lib/langium/config/configuration-provider.d.ts +81 -0
- package/lib/langium/config/configuration-provider.d.ts.map +1 -0
- package/lib/langium/config/configuration-provider.js +112 -0
- package/lib/langium/config/configuration-provider.js.map +1 -0
- package/lib/langium/config/index.d.ts +1 -0
- package/lib/langium/config/index.d.ts.map +1 -1
- package/lib/langium/config/index.js +1 -0
- package/lib/langium/config/index.js.map +1 -1
- package/lib/langium/config/settings.js.map +1 -1
- package/lib/langium/diagnostics/console-tee.d.ts +27 -0
- package/lib/langium/diagnostics/console-tee.d.ts.map +1 -0
- package/lib/langium/diagnostics/console-tee.js +141 -0
- package/lib/langium/diagnostics/console-tee.js.map +1 -0
- package/lib/langium/diagnostics/hydranium-langium-profiler.d.ts +9 -20
- package/lib/langium/diagnostics/hydranium-langium-profiler.d.ts.map +1 -1
- package/lib/langium/diagnostics/hydranium-langium-profiler.js +15 -24
- package/lib/langium/diagnostics/hydranium-langium-profiler.js.map +1 -1
- package/lib/langium/diagnostics/log-preamble.js +1 -1
- package/lib/langium/diagnostics/log-preamble.js.map +1 -1
- package/lib/langium/diagnostics/logger.d.ts +25 -6
- package/lib/langium/diagnostics/logger.d.ts.map +1 -1
- package/lib/langium/diagnostics/logger.js +49 -17
- package/lib/langium/diagnostics/logger.js.map +1 -1
- package/lib/langium/diagnostics/lsp-logger.d.ts +25 -0
- package/lib/langium/diagnostics/lsp-logger.d.ts.map +1 -1
- package/lib/langium/diagnostics/lsp-logger.js +81 -46
- package/lib/langium/diagnostics/lsp-logger.js.map +1 -1
- package/lib/langium/diagnostics/server-tracer.d.ts.map +1 -1
- package/lib/langium/diagnostics/server-tracer.js.map +1 -1
- package/lib/langium/document-builder/build-pipeline-integration.d.ts +21 -1
- package/lib/langium/document-builder/build-pipeline-integration.d.ts.map +1 -1
- package/lib/langium/document-builder/build-pipeline-integration.js +43 -30
- package/lib/langium/document-builder/build-pipeline-integration.js.map +1 -1
- package/lib/langium/document-builder/build-session.d.ts +6 -5
- package/lib/langium/document-builder/build-session.d.ts.map +1 -1
- package/lib/langium/document-builder/build-session.js +5 -5
- package/lib/langium/document-builder/build-session.js.map +1 -1
- package/lib/langium/document-builder/document-builder.d.ts +390 -40
- package/lib/langium/document-builder/document-builder.d.ts.map +1 -1
- package/lib/langium/document-builder/document-builder.js +635 -102
- package/lib/langium/document-builder/document-builder.js.map +1 -1
- package/lib/langium/documentation/comment-provider.d.ts.map +1 -1
- package/lib/langium/documentation/comment-provider.js.map +1 -1
- package/lib/langium/integration-services.d.ts +20 -23
- package/lib/langium/integration-services.d.ts.map +1 -1
- package/lib/langium/integration-services.js.map +1 -1
- package/lib/langium/integrity/integrity-rule.d.ts +22 -8
- package/lib/langium/integrity/integrity-rule.d.ts.map +1 -1
- package/lib/langium/integrity/integrity-rule.js.map +1 -1
- package/lib/langium/integrity/integrity-service.d.ts +217 -29
- package/lib/langium/integrity/integrity-service.d.ts.map +1 -1
- package/lib/langium/integrity/integrity-service.js +588 -84
- package/lib/langium/integrity/integrity-service.js.map +1 -1
- package/lib/langium/keys/containment.d.ts +3 -2
- package/lib/langium/keys/containment.d.ts.map +1 -1
- package/lib/langium/keys/containment.js.map +1 -1
- package/lib/langium/keys/name-based-key-provider.d.ts +17 -10
- package/lib/langium/keys/name-based-key-provider.d.ts.map +1 -1
- package/lib/langium/keys/name-based-key-provider.js +24 -12
- package/lib/langium/keys/name-based-key-provider.js.map +1 -1
- package/lib/langium/keys/positional-key-provider.d.ts.map +1 -1
- package/lib/langium/keys/positional-key-provider.js.map +1 -1
- package/lib/langium/labeling/label-provider.d.ts.map +1 -1
- package/lib/langium/labeling/label-provider.js.map +1 -1
- package/lib/langium/language-module.d.ts +30 -5
- package/lib/langium/language-module.d.ts.map +1 -1
- package/lib/langium/language-module.js +21 -5
- package/lib/langium/language-module.js.map +1 -1
- package/lib/langium/model-service/client-session.d.ts +405 -0
- package/lib/langium/model-service/client-session.d.ts.map +1 -0
- package/lib/langium/model-service/client-session.js +479 -0
- package/lib/langium/model-service/client-session.js.map +1 -0
- package/lib/langium/model-service/index.d.ts +2 -0
- package/lib/langium/model-service/index.d.ts.map +1 -1
- package/lib/langium/model-service/index.js +2 -0
- package/lib/langium/model-service/index.js.map +1 -1
- package/lib/langium/model-service/model-events.d.ts +68 -0
- package/lib/langium/model-service/model-events.d.ts.map +1 -0
- package/lib/langium/model-service/model-events.js +10 -0
- package/lib/langium/model-service/model-events.js.map +1 -0
- package/lib/langium/model-service/model-service.d.ts +441 -323
- package/lib/langium/model-service/model-service.d.ts.map +1 -1
- package/lib/langium/model-service/model-service.js +602 -407
- package/lib/langium/model-service/model-service.js.map +1 -1
- package/lib/langium/module.d.ts +96 -37
- package/lib/langium/module.d.ts.map +1 -1
- package/lib/langium/module.js +41 -29
- package/lib/langium/module.js.map +1 -1
- package/lib/langium/naming/name-provider.d.ts +32 -7
- package/lib/langium/naming/name-provider.d.ts.map +1 -1
- package/lib/langium/naming/name-provider.js +10 -4
- package/lib/langium/naming/name-provider.js.map +1 -1
- package/lib/langium/naming/name-separator-validation.d.ts.map +1 -1
- package/lib/langium/project/abstract-project-manager.d.ts +184 -13
- package/lib/langium/project/abstract-project-manager.d.ts.map +1 -1
- package/lib/langium/project/abstract-project-manager.js +336 -16
- package/lib/langium/project/abstract-project-manager.js.map +1 -1
- package/lib/langium/project/project-change-event.d.ts +22 -3
- package/lib/langium/project/project-change-event.d.ts.map +1 -1
- package/lib/langium/project/project-manager.d.ts +28 -2
- package/lib/langium/project/project-manager.d.ts.map +1 -1
- package/lib/langium/project/single-project-manager.d.ts +7 -1
- package/lib/langium/project/single-project-manager.d.ts.map +1 -1
- package/lib/langium/project/single-project-manager.js +12 -0
- package/lib/langium/project/single-project-manager.js.map +1 -1
- package/lib/langium/residency/cst-residency-service.d.ts +92 -52
- package/lib/langium/residency/cst-residency-service.d.ts.map +1 -1
- package/lib/langium/residency/cst-residency-service.js +154 -58
- package/lib/langium/residency/cst-residency-service.js.map +1 -1
- package/lib/langium/scope/ast-node-description-provider.d.ts +46 -10
- package/lib/langium/scope/ast-node-description-provider.d.ts.map +1 -1
- package/lib/langium/scope/ast-node-description-provider.js +88 -15
- package/lib/langium/scope/ast-node-description-provider.js.map +1 -1
- package/lib/langium/scope/built-local-symbols.d.ts +12 -0
- package/lib/langium/scope/built-local-symbols.d.ts.map +1 -0
- package/lib/langium/scope/built-local-symbols.js +11 -0
- package/lib/langium/scope/built-local-symbols.js.map +1 -0
- package/lib/langium/scope/fallback-scope.d.ts +27 -0
- package/lib/langium/scope/fallback-scope.d.ts.map +1 -0
- package/lib/langium/scope/fallback-scope.js +35 -0
- package/lib/langium/scope/fallback-scope.js.map +1 -0
- package/lib/langium/scope/hydranium-scope-computation.d.ts +21 -18
- package/lib/langium/scope/hydranium-scope-computation.d.ts.map +1 -1
- package/lib/langium/scope/hydranium-scope-computation.js +38 -39
- package/lib/langium/scope/hydranium-scope-computation.js.map +1 -1
- package/lib/langium/scope/hydranium-scope-provider.d.ts +122 -32
- package/lib/langium/scope/hydranium-scope-provider.d.ts.map +1 -1
- package/lib/langium/scope/hydranium-scope-provider.js +217 -39
- package/lib/langium/scope/hydranium-scope-provider.js.map +1 -1
- package/lib/langium/scope/index.d.ts +1 -0
- package/lib/langium/scope/index.d.ts.map +1 -1
- package/lib/langium/scope/index.js +1 -0
- package/lib/langium/scope/index.js.map +1 -1
- package/lib/langium/scope/reference-builder.d.ts.map +1 -1
- package/lib/langium/scope/reference-builder.js.map +1 -1
- package/lib/langium/scope/reference-candidate-provider.d.ts +6 -5
- package/lib/langium/scope/reference-candidate-provider.d.ts.map +1 -1
- package/lib/langium/scope/reference-candidate-provider.js +3 -2
- package/lib/langium/scope/reference-candidate-provider.js.map +1 -1
- package/lib/langium/scope/scope-extension-service.d.ts +69 -37
- package/lib/langium/scope/scope-extension-service.d.ts.map +1 -1
- package/lib/langium/scope/scope-extension-service.js +102 -29
- package/lib/langium/scope/scope-extension-service.js.map +1 -1
- package/lib/langium/scope/scoped-ast-node-description.d.ts +1 -3
- package/lib/langium/scope/scoped-ast-node-description.d.ts.map +1 -1
- package/lib/langium/scope/scoped-ast-node-description.js +1 -3
- package/lib/langium/scope/scoped-ast-node-description.js.map +1 -1
- package/lib/langium/serialization/abstract-serializer.d.ts +38 -27
- package/lib/langium/serialization/abstract-serializer.d.ts.map +1 -1
- package/lib/langium/serialization/abstract-serializer.js +54 -30
- package/lib/langium/serialization/abstract-serializer.js.map +1 -1
- package/lib/langium/serialization/json-serializer.d.ts +8 -1
- package/lib/langium/serialization/json-serializer.d.ts.map +1 -1
- package/lib/langium/serialization/json-serializer.js +13 -3
- package/lib/langium/serialization/json-serializer.js.map +1 -1
- package/lib/langium/serialization/serializer.d.ts +1 -1
- package/lib/langium/serialization/yaml-serializer.d.ts +12 -0
- package/lib/langium/serialization/yaml-serializer.d.ts.map +1 -1
- package/lib/langium/serialization/yaml-serializer.js +24 -4
- package/lib/langium/serialization/yaml-serializer.js.map +1 -1
- package/lib/langium/service-registry.d.ts +29 -1
- package/lib/langium/service-registry.d.ts.map +1 -1
- package/lib/langium/service-registry.js +37 -0
- package/lib/langium/service-registry.js.map +1 -1
- package/lib/langium/shared-services.d.ts +10 -4
- package/lib/langium/shared-services.d.ts.map +1 -1
- package/lib/langium/shared-services.js.map +1 -1
- package/lib/langium/single-langium-copy.d.ts +22 -0
- package/lib/langium/single-langium-copy.d.ts.map +1 -0
- package/lib/langium/single-langium-copy.js +36 -0
- package/lib/langium/single-langium-copy.js.map +1 -0
- package/lib/langium/transfer/transfer-encoder.d.ts +60 -39
- package/lib/langium/transfer/transfer-encoder.d.ts.map +1 -1
- package/lib/langium/transfer/transfer-encoder.js +35 -24
- package/lib/langium/transfer/transfer-encoder.js.map +1 -1
- package/lib/langium/trivia/comment-preserver.d.ts +543 -0
- package/lib/langium/trivia/comment-preserver.d.ts.map +1 -0
- package/lib/langium/trivia/comment-preserver.js +1165 -0
- package/lib/langium/trivia/comment-preserver.js.map +1 -0
- package/lib/langium/trivia/document-ending-preserver.d.ts +51 -0
- package/lib/langium/trivia/document-ending-preserver.d.ts.map +1 -0
- package/lib/langium/trivia/document-ending-preserver.js +62 -0
- package/lib/langium/trivia/document-ending-preserver.js.map +1 -0
- package/lib/langium/trivia/index.d.ts +14 -0
- package/lib/langium/trivia/index.d.ts.map +1 -0
- package/lib/langium/trivia/index.js +14 -0
- package/lib/langium/trivia/index.js.map +1 -0
- package/lib/langium/trivia/trivia-contribution.d.ts +37 -0
- package/lib/langium/trivia/trivia-contribution.d.ts.map +1 -0
- package/lib/langium/trivia/trivia-contribution.js +10 -0
- package/lib/langium/trivia/trivia-contribution.js.map +1 -0
- package/lib/langium/trivia/trivia-preserver.d.ts +52 -0
- package/lib/langium/trivia/trivia-preserver.d.ts.map +1 -0
- package/lib/langium/trivia/trivia-preserver.js +10 -0
- package/lib/langium/trivia/trivia-preserver.js.map +1 -0
- package/lib/langium/trivia/trivia-service.d.ts +70 -0
- package/lib/langium/trivia/trivia-service.d.ts.map +1 -0
- package/lib/langium/trivia/trivia-service.js +56 -0
- package/lib/langium/trivia/trivia-service.js.map +1 -0
- package/lib/langium/update-rewrite/normalize-empty-strings.d.ts.map +1 -1
- package/lib/langium/update-rewrite/update-rewrite-service.d.ts +1 -1
- package/lib/langium/update-rewrite/update-rewrite-service.d.ts.map +1 -1
- package/lib/langium/update-rewrite/update-rewrite-service.js.map +1 -1
- package/lib/langium/update-rewrite/update-rewrite.d.ts +1 -1
- package/lib/langium/validation/document-validator.d.ts +168 -23
- package/lib/langium/validation/document-validator.d.ts.map +1 -1
- package/lib/langium/validation/document-validator.js +264 -26
- package/lib/langium/validation/document-validator.js.map +1 -1
- package/lib/langium/validation/validation-contribution-collector.d.ts +9 -1
- package/lib/langium/validation/validation-contribution-collector.d.ts.map +1 -1
- package/lib/langium/validation/validation-contribution-collector.js +1 -1
- package/lib/langium/validation/validation-contribution-collector.js.map +1 -1
- package/lib/langium/workspace/ast-node-locator.d.ts +24 -0
- package/lib/langium/workspace/ast-node-locator.d.ts.map +1 -0
- package/lib/langium/workspace/ast-node-locator.js +32 -0
- package/lib/langium/workspace/ast-node-locator.js.map +1 -0
- package/lib/langium/workspace/document-uri-policy.d.ts +24 -15
- package/lib/langium/workspace/document-uri-policy.d.ts.map +1 -1
- package/lib/langium/workspace/document-uri-policy.js +22 -13
- package/lib/langium/workspace/document-uri-policy.js.map +1 -1
- package/lib/langium/workspace/file-not-found.d.ts +23 -0
- package/lib/langium/workspace/file-not-found.d.ts.map +1 -0
- package/lib/langium/workspace/file-not-found.js +31 -0
- package/lib/langium/workspace/file-not-found.js.map +1 -0
- package/lib/langium/workspace/file-system-provider.d.ts +167 -8
- package/lib/langium/workspace/file-system-provider.d.ts.map +1 -1
- package/lib/langium/workspace/file-system-provider.js +115 -13
- package/lib/langium/workspace/file-system-provider.js.map +1 -1
- package/lib/langium/workspace/hydranium-langium-document-factory.d.ts +78 -4
- package/lib/langium/workspace/hydranium-langium-document-factory.d.ts.map +1 -1
- package/lib/langium/workspace/hydranium-langium-document-factory.js +188 -5
- package/lib/langium/workspace/hydranium-langium-document-factory.js.map +1 -1
- package/lib/langium/workspace/hydranium-workspace-lock.d.ts +50 -1
- package/lib/langium/workspace/hydranium-workspace-lock.d.ts.map +1 -1
- package/lib/langium/workspace/hydranium-workspace-lock.js +73 -1
- package/lib/langium/workspace/hydranium-workspace-lock.js.map +1 -1
- package/lib/langium/workspace/hydranium-workspace-manager.d.ts +105 -21
- package/lib/langium/workspace/hydranium-workspace-manager.d.ts.map +1 -1
- package/lib/langium/workspace/hydranium-workspace-manager.js +186 -31
- package/lib/langium/workspace/hydranium-workspace-manager.js.map +1 -1
- package/lib/langium/workspace/in-memory-file-system-provider.d.ts +26 -9
- package/lib/langium/workspace/in-memory-file-system-provider.d.ts.map +1 -1
- package/lib/langium/workspace/in-memory-file-system-provider.js +45 -22
- package/lib/langium/workspace/in-memory-file-system-provider.js.map +1 -1
- package/lib/langium/workspace/index-manager.d.ts.map +1 -1
- package/lib/langium/workspace/index-manager.js.map +1 -1
- package/lib/langium/workspace/index.d.ts +3 -0
- package/lib/langium/workspace/index.d.ts.map +1 -1
- package/lib/langium/workspace/index.js +3 -0
- package/lib/langium/workspace/index.js.map +1 -1
- package/lib/langium/workspace/initialize-workspace.d.ts +40 -3
- package/lib/langium/workspace/initialize-workspace.d.ts.map +1 -1
- package/lib/langium/workspace/initialize-workspace.js +68 -3
- package/lib/langium/workspace/initialize-workspace.js.map +1 -1
- package/lib/langium/workspace/langium-documents.d.ts +7 -0
- package/lib/langium/workspace/langium-documents.d.ts.map +1 -1
- package/lib/langium/workspace/langium-documents.js +18 -1
- package/lib/langium/workspace/langium-documents.js.map +1 -1
- package/lib/langium/workspace/persistent-file-system-provider.d.ts +16 -10
- package/lib/langium/workspace/persistent-file-system-provider.d.ts.map +1 -1
- package/lib/langium/workspace/persistent-file-system-provider.js +25 -13
- package/lib/langium/workspace/persistent-file-system-provider.js.map +1 -1
- package/lib/{documents → langium/workspace}/self-save-registry.d.ts +7 -9
- package/lib/langium/workspace/self-save-registry.d.ts.map +1 -0
- package/lib/{documents → langium/workspace}/self-save-registry.js +9 -11
- package/lib/langium/workspace/self-save-registry.js.map +1 -0
- package/lib/langium/workspace/syntax-errors.d.ts +23 -0
- package/lib/langium/workspace/syntax-errors.d.ts.map +1 -0
- package/lib/langium/workspace/syntax-errors.js +29 -0
- package/lib/langium/workspace/syntax-errors.js.map +1 -0
- package/lib/langium/workspace/virtual-document.d.ts +55 -21
- package/lib/langium/workspace/virtual-document.d.ts.map +1 -1
- package/lib/langium/workspace/virtual-document.js +87 -24
- package/lib/langium/workspace/virtual-document.js.map +1 -1
- package/lib/langium/workspace/write-lock-scope.d.ts +22 -10
- package/lib/langium/workspace/write-lock-scope.d.ts.map +1 -1
- package/lib/langium/workspace/write-lock-scope.js +15 -5
- package/lib/langium/workspace/write-lock-scope.js.map +1 -1
- package/lib/launcher/integrated-server.d.ts +3 -1
- package/lib/launcher/integrated-server.d.ts.map +1 -1
- package/lib/locale/server-locale.d.ts +6 -6
- package/lib/locale/server-locale.d.ts.map +1 -1
- package/lib/locale/server-locale.js.map +1 -1
- package/lib/lsp/completion/hydranium-completion-provider.d.ts +44 -2
- package/lib/lsp/completion/hydranium-completion-provider.d.ts.map +1 -1
- package/lib/lsp/completion/hydranium-completion-provider.js +68 -0
- package/lib/lsp/completion/hydranium-completion-provider.js.map +1 -1
- package/lib/lsp/connection-features.d.ts +23 -0
- package/lib/lsp/connection-features.d.ts.map +1 -0
- package/lib/lsp/connection-features.js +60 -0
- package/lib/lsp/connection-features.js.map +1 -0
- package/lib/lsp/diagnostics-connection.d.ts +27 -0
- package/lib/lsp/diagnostics-connection.d.ts.map +1 -0
- package/lib/lsp/diagnostics-connection.js +53 -0
- package/lib/lsp/diagnostics-connection.js.map +1 -0
- package/lib/lsp/edit-requests-guard.d.ts +31 -0
- package/lib/lsp/edit-requests-guard.d.ts.map +1 -0
- package/lib/lsp/edit-requests-guard.js +125 -0
- package/lib/lsp/edit-requests-guard.js.map +1 -0
- package/lib/lsp/hydranium-document-update-handler.d.ts +126 -82
- package/lib/lsp/hydranium-document-update-handler.d.ts.map +1 -1
- package/lib/lsp/hydranium-document-update-handler.js +234 -101
- package/lib/lsp/hydranium-document-update-handler.js.map +1 -1
- package/lib/lsp/index.d.ts +6 -2
- package/lib/lsp/index.d.ts.map +1 -1
- package/lib/lsp/index.js +6 -2
- package/lib/lsp/index.js.map +1 -1
- package/lib/lsp/lsp-latency.d.ts +39 -0
- package/lib/lsp/lsp-latency.d.ts.map +1 -0
- package/lib/lsp/lsp-latency.js +58 -0
- package/lib/lsp/lsp-latency.js.map +1 -0
- package/lib/lsp/save-text-document.d.ts +31 -0
- package/lib/lsp/save-text-document.d.ts.map +1 -0
- package/lib/lsp/save-text-document.js +52 -0
- package/lib/lsp/save-text-document.js.map +1 -0
- package/lib/lsp/semantic-token-provider.d.ts +58 -2
- package/lib/lsp/semantic-token-provider.d.ts.map +1 -1
- package/lib/lsp/semantic-token-provider.js +98 -9
- package/lib/lsp/semantic-token-provider.js.map +1 -1
- package/lib/lsp/shared-module.d.ts +4 -8
- package/lib/lsp/shared-module.d.ts.map +1 -1
- package/lib/lsp/shared-module.js.map +1 -1
- package/lib/lsp/start-language-server.d.ts +12 -7
- package/lib/lsp/start-language-server.d.ts.map +1 -1
- package/lib/lsp/start-language-server.js +21 -7
- package/lib/lsp/start-language-server.js.map +1 -1
- package/lib/messages/carriers.d.ts +4 -6
- package/lib/messages/carriers.d.ts.map +1 -1
- package/lib/messages/carriers.js +4 -6
- package/lib/messages/carriers.js.map +1 -1
- package/lib/messages/index.d.ts +2 -2
- package/lib/messages/index.d.ts.map +1 -1
- package/lib/messages/index.js +2 -2
- package/lib/messages/index.js.map +1 -1
- package/lib/messages/renderer.d.ts +10 -4
- package/lib/messages/renderer.d.ts.map +1 -1
- package/lib/messages/renderer.js +6 -0
- package/lib/messages/renderer.js.map +1 -1
- package/lib/node/event-loop-monitor.d.ts.map +1 -1
- package/lib/node/event-loop-monitor.js +3 -2
- package/lib/node/event-loop-monitor.js.map +1 -1
- package/lib/node/heap-ceiling.d.ts +61 -0
- package/lib/node/heap-ceiling.d.ts.map +1 -0
- package/lib/node/heap-ceiling.js +72 -0
- package/lib/node/heap-ceiling.js.map +1 -0
- package/lib/node/index.d.ts +1 -1
- package/lib/node/index.d.ts.map +1 -1
- package/lib/node/index.js +5 -1
- package/lib/node/index.js.map +1 -1
- package/lib/node/latency-from-env.d.ts +1 -1
- package/lib/node/latency-from-env.js +1 -1
- package/lib/node/lint-grammar.js.map +1 -1
- package/lib/node/log-file-sink.d.ts +3 -2
- package/lib/node/log-file-sink.d.ts.map +1 -1
- package/lib/node/log-file-sink.js +6 -2
- package/lib/node/log-file-sink.js.map +1 -1
- package/lib/node/log-preamble-node.d.ts +5 -3
- package/lib/node/log-preamble-node.d.ts.map +1 -1
- package/lib/node/log-preamble-node.js +13 -10
- package/lib/node/log-preamble-node.js.map +1 -1
- package/lib/node/measure-memory.d.ts.map +1 -1
- package/lib/node/measure-memory.js +5 -4
- package/lib/node/measure-memory.js.map +1 -1
- package/lib/node/memory-monitor.d.ts +2 -2
- package/lib/node/memory-monitor.d.ts.map +1 -1
- package/lib/node/memory-monitor.js +9 -10
- package/lib/node/memory-monitor.js.map +1 -1
- package/lib/node/node-file-system-provider.d.ts +67 -9
- package/lib/node/node-file-system-provider.d.ts.map +1 -1
- package/lib/node/node-file-system-provider.js +198 -53
- package/lib/node/node-file-system-provider.js.map +1 -1
- package/lib/node/profile-capture.d.ts +12 -4
- package/lib/node/profile-capture.d.ts.map +1 -1
- package/lib/node/profile-capture.js +8 -6
- package/lib/node/profile-capture.js.map +1 -1
- package/lib/node/profile-digest.js.map +1 -1
- package/lib/node/profiling-run.d.ts +13 -3
- package/lib/node/profiling-run.d.ts.map +1 -1
- package/lib/node/profiling-run.js +17 -8
- package/lib/node/profiling-run.js.map +1 -1
- package/lib/node/rename-over-open-readers.d.ts +61 -0
- package/lib/node/rename-over-open-readers.d.ts.map +1 -0
- package/lib/node/rename-over-open-readers.js +80 -0
- package/lib/node/rename-over-open-readers.js.map +1 -0
- package/lib/node/server-diagnostics.js +1 -1
- package/lib/node/server-diagnostics.js.map +1 -1
- package/lib/node/server-state-snapshot.d.ts +6 -5
- package/lib/node/server-state-snapshot.d.ts.map +1 -1
- package/lib/node/server-state-snapshot.js +20 -17
- package/lib/node/server-state-snapshot.js.map +1 -1
- package/lib/node/socket-launcher.d.ts +43 -7
- package/lib/node/socket-launcher.d.ts.map +1 -1
- package/lib/node/socket-launcher.js +42 -7
- package/lib/node/socket-launcher.js.map +1 -1
- package/lib/node/startup-cpu-profile.d.ts +29 -0
- package/lib/node/startup-cpu-profile.d.ts.map +1 -0
- package/lib/node/startup-cpu-profile.js +91 -0
- package/lib/node/startup-cpu-profile.js.map +1 -0
- package/lib/node/stdio-launcher.d.ts +13 -13
- package/lib/node/stdio-launcher.d.ts.map +1 -1
- package/lib/node/stdio-launcher.js +21 -11
- package/lib/node/stdio-launcher.js.map +1 -1
- package/lib/node/validate-workspace.d.ts +1 -1
- package/lib/node/validate-workspace.d.ts.map +1 -1
- package/lib/node/validate-workspace.js +5 -1
- package/lib/node/validate-workspace.js.map +1 -1
- package/lib/testing/document-uri-policy-conformance.js +1 -1
- package/lib/testing/document-uri-policy-conformance.js.map +1 -1
- package/lib/testing/fake-description.js.map +1 -1
- package/lib/testing/fake-document.d.ts +2 -1
- package/lib/testing/fake-document.d.ts.map +1 -1
- package/lib/testing/fake-document.js.map +1 -1
- package/lib/testing/index.d.ts +1 -1
- package/lib/testing/index.d.ts.map +1 -1
- package/lib/testing/index.js +2 -1
- package/lib/testing/index.js.map +1 -1
- package/lib/testing/langium-test-helpers.d.ts.map +1 -1
- package/lib/testing/langium-test-helpers.js +1 -0
- package/lib/testing/langium-test-helpers.js.map +1 -1
- package/lib/testing/make-noop-language-services.js.map +1 -1
- package/lib/testing/make-noop-shared-services.js.map +1 -1
- package/lib/testing/make-test-services.d.ts +45 -14
- package/lib/testing/make-test-services.d.ts.map +1 -1
- package/lib/testing/make-test-services.js +23 -7
- package/lib/testing/make-test-services.js.map +1 -1
- package/lib/testing/make-test-tracer.d.ts +12 -0
- package/lib/testing/make-test-tracer.d.ts.map +1 -1
- package/lib/testing/make-test-tracer.js +13 -0
- package/lib/testing/make-test-tracer.js.map +1 -1
- package/lib/testing/node/applied-edit-capture.d.ts +29 -0
- package/lib/testing/node/applied-edit-capture.d.ts.map +1 -0
- package/lib/testing/node/applied-edit-capture.js +117 -0
- package/lib/testing/node/applied-edit-capture.js.map +1 -0
- package/lib/testing/node/golden-corpus.js.map +1 -1
- package/lib/testing/node/index.d.ts +4 -1
- package/lib/testing/node/index.d.ts.map +1 -1
- package/lib/testing/node/index.js +4 -1
- package/lib/testing/node/index.js.map +1 -1
- package/lib/testing/node/lsp-harness.d.ts.map +1 -1
- package/lib/testing/node/lsp-harness.js +2 -0
- package/lib/testing/node/lsp-harness.js.map +1 -1
- package/lib/testing/node/lsp-server-connection.d.ts +21 -6
- package/lib/testing/node/lsp-server-connection.d.ts.map +1 -1
- package/lib/testing/node/lsp-server-connection.js +49 -106
- package/lib/testing/node/lsp-server-connection.js.map +1 -1
- package/lib/testing/node/scratch-workspace.d.ts +2 -1
- package/lib/testing/node/scratch-workspace.d.ts.map +1 -1
- package/lib/testing/node/scratch-workspace.js +12 -6
- package/lib/testing/node/scratch-workspace.js.map +1 -1
- package/lib/testing/node/settle-server.d.ts +33 -0
- package/lib/testing/node/settle-server.d.ts.map +1 -0
- package/lib/testing/node/settle-server.js +84 -0
- package/lib/testing/node/settle-server.js.map +1 -0
- package/lib/testing/node/spawned-server.d.ts +30 -1
- package/lib/testing/node/spawned-server.d.ts.map +1 -1
- package/lib/testing/node/spawned-server.js +39 -2
- package/lib/testing/node/spawned-server.js.map +1 -1
- package/lib/testing/playwright/browser-capture-bridge.js.map +1 -1
- package/lib/testing/playwright/e2e-profiling.js.map +1 -1
- package/lib/testing/playwright/flaky-network-proxy.d.ts +76 -0
- package/lib/testing/playwright/flaky-network-proxy.d.ts.map +1 -0
- package/lib/testing/playwright/flaky-network-proxy.js +164 -0
- package/lib/testing/playwright/flaky-network-proxy.js.map +1 -0
- package/lib/testing/playwright/index.d.ts +1 -0
- package/lib/testing/playwright/index.d.ts.map +1 -1
- package/lib/testing/playwright/index.js +1 -0
- package/lib/testing/playwright/index.js.map +1 -1
- package/lib/testing/playwright/server-log-capture.d.ts +46 -16
- package/lib/testing/playwright/server-log-capture.d.ts.map +1 -1
- package/lib/testing/playwright/server-log-capture.js +111 -40
- package/lib/testing/playwright/server-log-capture.js.map +1 -1
- package/lib/testing/playwright/server-log-fixture.d.ts +16 -0
- package/lib/testing/playwright/server-log-fixture.d.ts.map +1 -1
- package/lib/testing/playwright/server-log-fixture.js +25 -6
- package/lib/testing/playwright/server-log-fixture.js.map +1 -1
- package/lib/testing/playwright/server-log-region.d.ts +15 -0
- package/lib/testing/playwright/server-log-region.d.ts.map +1 -0
- package/lib/testing/playwright/server-log-region.js +30 -0
- package/lib/testing/playwright/server-log-region.js.map +1 -0
- package/lib/testing/playwright/server-log-rename-reporter.d.ts.map +1 -1
- package/lib/testing/playwright/server-log-rename-reporter.js +4 -3
- package/lib/testing/playwright/server-log-rename-reporter.js.map +1 -1
- package/lib/testing/run-update-pipeline.d.ts +8 -5
- package/lib/testing/run-update-pipeline.d.ts.map +1 -1
- package/lib/testing/run-update-pipeline.js.map +1 -1
- package/lib/testing/stub-ast-document-manager.d.ts +11 -51
- package/lib/testing/stub-ast-document-manager.d.ts.map +1 -1
- package/lib/testing/stub-ast-document-manager.js +31 -59
- package/lib/testing/stub-ast-document-manager.js.map +1 -1
- package/lib/testing/stub-document-builder.d.ts +25 -11
- package/lib/testing/stub-document-builder.d.ts.map +1 -1
- package/lib/testing/stub-document-builder.js +91 -2
- package/lib/testing/stub-document-builder.js.map +1 -1
- package/lib/testing/stub-hydranium-text-documents.d.ts +33 -10
- package/lib/testing/stub-hydranium-text-documents.d.ts.map +1 -1
- package/lib/testing/stub-hydranium-text-documents.js +132 -16
- package/lib/testing/stub-hydranium-text-documents.js.map +1 -1
- package/lib/testing/stub-index-manager.js.map +1 -1
- package/lib/testing/stub-langium-documents.d.ts +3 -2
- package/lib/testing/stub-langium-documents.d.ts.map +1 -1
- package/lib/testing/stub-langium-documents.js.map +1 -1
- package/lib/testing/stub-model-service.d.ts +8 -7
- package/lib/testing/stub-model-service.d.ts.map +1 -1
- package/lib/testing/stub-model-service.js +4 -4
- package/lib/testing/stub-model-service.js.map +1 -1
- package/lib/testing/stub-project-manager.d.ts.map +1 -1
- package/lib/testing/stub-project-manager.js +10 -0
- package/lib/testing/stub-project-manager.js.map +1 -1
- package/lib/testing/stub-self-save-registry.d.ts +1 -1
- package/lib/testing/stub-self-save-registry.d.ts.map +1 -1
- package/lib/testing/stub-service-registry.d.ts +1 -1
- package/lib/testing/stub-service-registry.js.map +1 -1
- package/lib/testing/stub-writable-file-system.d.ts +1 -1
- package/lib/testing/stub-writable-file-system.d.ts.map +1 -1
- package/lib/testing/stub-writable-file-system.js +2 -1
- package/lib/testing/stub-writable-file-system.js.map +1 -1
- package/lib/util/connection-liveness.d.ts +22 -6
- package/lib/util/connection-liveness.d.ts.map +1 -1
- package/lib/util/connection-liveness.js +75 -15
- package/lib/util/connection-liveness.js.map +1 -1
- package/lib/util/environment.d.ts +7 -0
- package/lib/util/environment.d.ts.map +1 -1
- package/lib/util/environment.js +15 -1
- package/lib/util/environment.js.map +1 -1
- package/lib/util/registry.d.ts.map +1 -1
- package/package.json +41 -60
- package/src/browser/host-heads-in-worker.ts +218 -0
- package/src/browser/index.ts +17 -0
- package/src/browser/indexeddb-file-system-store.ts +192 -0
- package/src/browser/start-language-server-in-worker.ts +56 -0
- package/src/documents/ast-document-manager.ts +477 -250
- package/src/documents/client-ids.ts +5 -22
- package/src/documents/client-session-errors.ts +26 -0
- package/src/documents/client-session-registry.ts +262 -0
- package/src/documents/dirty-state-tracker.ts +167 -0
- package/src/documents/document-release-handler.ts +404 -0
- package/src/documents/document-release-scheduler.ts +121 -0
- package/src/documents/file-system-task-queue.ts +77 -0
- package/src/documents/hydranium-text-documents.ts +1044 -615
- package/src/documents/index.ts +10 -2
- package/src/documents/language-client-shadow.ts +501 -0
- package/src/documents/model-ledger.ts +66 -0
- package/src/documents/text-ledger.ts +112 -0
- package/src/documents/version-sync-service.ts +304 -0
- package/src/index.ts +3 -0
- package/src/langium/ast-extension/ast-extension-service.ts +77 -41
- package/src/langium/ast-extension/ast-node-builder.ts +35 -13
- package/src/langium/bootstrap.ts +79 -43
- package/src/langium/build-phase-pass/build-phase-pass-service.ts +29 -19
- package/src/langium/build-phase-pass/build-phase-pass.ts +37 -8
- package/src/langium/composite-ast-reflection.ts +112 -0
- package/src/langium/config/configuration-provider.ts +119 -0
- package/src/langium/config/index.ts +1 -0
- package/src/langium/diagnostics/console-tee.ts +150 -0
- package/src/langium/diagnostics/hydranium-langium-profiler.ts +15 -39
- package/src/langium/diagnostics/log-preamble.ts +1 -1
- package/src/langium/diagnostics/logger.ts +51 -17
- package/src/langium/diagnostics/lsp-logger.ts +83 -45
- package/src/langium/document-builder/build-pipeline-integration.ts +57 -32
- package/src/langium/document-builder/build-session.ts +4 -3
- package/src/langium/document-builder/document-builder.ts +773 -106
- package/src/langium/integration-services.ts +20 -23
- package/src/langium/integrity/integrity-rule.ts +22 -8
- package/src/langium/integrity/integrity-service.ts +656 -90
- package/src/langium/keys/containment.ts +3 -2
- package/src/langium/keys/name-based-key-provider.ts +24 -12
- package/src/langium/language-module.ts +52 -9
- package/src/langium/model-service/client-session.ts +769 -0
- package/src/langium/model-service/index.ts +2 -0
- package/src/langium/model-service/model-events.ts +82 -0
- package/src/langium/model-service/model-service.ts +885 -532
- package/src/langium/module.ts +141 -65
- package/src/langium/naming/name-provider.ts +34 -8
- package/src/langium/project/abstract-project-manager.ts +409 -20
- package/src/langium/project/project-change-event.ts +25 -3
- package/src/langium/project/project-manager.ts +31 -2
- package/src/langium/project/single-project-manager.ts +16 -1
- package/src/langium/residency/cst-residency-service.ts +210 -87
- package/src/langium/scope/ast-node-description-provider.ts +111 -16
- package/src/langium/scope/built-local-symbols.ts +13 -0
- package/src/langium/scope/fallback-scope.ts +38 -0
- package/src/langium/scope/hydranium-scope-computation.ts +45 -44
- package/src/langium/scope/hydranium-scope-provider.ts +245 -41
- package/src/langium/scope/index.ts +1 -0
- package/src/langium/scope/reference-candidate-provider.ts +6 -5
- package/src/langium/scope/scope-extension-service.ts +148 -56
- package/src/langium/scope/scoped-ast-node-description.ts +1 -3
- package/src/langium/serialization/abstract-serializer.ts +57 -41
- package/src/langium/serialization/json-serializer.ts +14 -3
- package/src/langium/serialization/serializer.ts +1 -1
- package/src/langium/serialization/yaml-serializer.ts +26 -4
- package/src/langium/service-registry.ts +41 -2
- package/src/langium/shared-services.ts +13 -4
- package/src/langium/single-langium-copy.ts +42 -0
- package/src/langium/transfer/transfer-encoder.ts +76 -50
- package/src/langium/trivia/comment-preserver.ts +1410 -0
- package/src/langium/trivia/document-ending-preserver.ts +71 -0
- package/src/langium/trivia/index.ts +14 -0
- package/src/langium/trivia/trivia-contribution.ts +39 -0
- package/src/langium/trivia/trivia-preserver.ts +56 -0
- package/src/langium/trivia/trivia-service.ts +99 -0
- package/src/langium/update-rewrite/update-rewrite-service.ts +1 -1
- package/src/langium/update-rewrite/update-rewrite.ts +1 -1
- package/src/langium/validation/document-validator.ts +312 -31
- package/src/langium/validation/validation-contribution-collector.ts +10 -1
- package/src/langium/workspace/ast-node-locator.ts +33 -0
- package/src/langium/workspace/document-uri-policy.ts +32 -18
- package/src/langium/workspace/file-not-found.ts +35 -0
- package/src/langium/workspace/file-system-provider.ts +258 -16
- package/src/langium/workspace/hydranium-langium-document-factory.ts +239 -4
- package/src/langium/workspace/hydranium-workspace-lock.ts +101 -2
- package/src/langium/workspace/hydranium-workspace-manager.ts +214 -35
- package/src/langium/workspace/in-memory-file-system-provider.ts +54 -23
- package/src/langium/workspace/index.ts +3 -0
- package/src/langium/workspace/initialize-workspace.ts +96 -4
- package/src/langium/workspace/langium-documents.ts +19 -1
- package/src/langium/workspace/persistent-file-system-provider.ts +27 -15
- package/src/{documents → langium/workspace}/self-save-registry.ts +12 -14
- package/src/langium/workspace/syntax-errors.ts +34 -0
- package/src/langium/workspace/virtual-document.ts +106 -25
- package/src/langium/workspace/write-lock-scope.ts +27 -12
- package/src/launcher/integrated-server.ts +3 -1
- package/src/locale/server-locale.ts +6 -6
- package/src/lsp/completion/hydranium-completion-provider.ts +82 -2
- package/src/lsp/connection-features.ts +67 -0
- package/src/lsp/diagnostics-connection.ts +56 -0
- package/src/lsp/edit-requests-guard.ts +152 -0
- package/src/lsp/hydranium-document-update-handler.ts +284 -110
- package/src/lsp/index.ts +6 -2
- package/src/lsp/lsp-latency.ts +62 -0
- package/src/lsp/save-text-document.ts +63 -0
- package/src/lsp/semantic-token-provider.ts +146 -8
- package/src/lsp/shared-module.ts +4 -8
- package/src/lsp/start-language-server.ts +21 -7
- package/src/messages/carriers.ts +4 -6
- package/src/messages/index.ts +11 -2
- package/src/messages/renderer.ts +11 -3
- package/src/node/event-loop-monitor.ts +3 -4
- package/src/node/heap-ceiling.ts +108 -0
- package/src/node/index.ts +5 -1
- package/src/node/latency-from-env.ts +1 -1
- package/src/node/log-file-sink.ts +6 -2
- package/src/node/log-preamble-node.ts +20 -10
- package/src/node/measure-memory.ts +5 -4
- package/src/node/memory-monitor.ts +10 -10
- package/src/node/node-file-system-provider.ts +214 -57
- package/src/node/profile-capture.ts +16 -15
- package/src/node/profiling-run.ts +30 -8
- package/src/node/rename-over-open-readers.ts +94 -0
- package/src/node/server-diagnostics.ts +1 -1
- package/src/node/server-state-snapshot.ts +28 -20
- package/src/node/socket-launcher.ts +78 -14
- package/src/node/startup-cpu-profile.ts +94 -0
- package/src/node/stdio-launcher.ts +29 -19
- package/src/node/validate-workspace.ts +8 -2
- package/src/testing/document-uri-policy-conformance.ts +1 -1
- package/src/testing/fake-document.ts +2 -1
- package/src/testing/index.ts +2 -1
- package/src/testing/langium-test-helpers.ts +1 -0
- package/src/testing/make-test-services.ts +83 -31
- package/src/testing/make-test-tracer.ts +26 -0
- package/src/testing/node/applied-edit-capture.ts +141 -0
- package/src/testing/node/index.ts +4 -1
- package/src/testing/node/lsp-harness.ts +2 -0
- package/src/testing/node/lsp-server-connection.ts +83 -119
- package/src/testing/node/scratch-workspace.ts +12 -6
- package/src/testing/node/settle-server.ts +89 -0
- package/src/testing/node/spawned-server.ts +57 -3
- package/src/testing/parse-semantic-root.ts +1 -1
- package/src/testing/playwright/flaky-network-proxy.ts +240 -0
- package/src/testing/playwright/index.ts +1 -0
- package/src/testing/playwright/server-log-capture.ts +137 -47
- package/src/testing/playwright/server-log-fixture.ts +46 -6
- package/src/testing/playwright/server-log-region.ts +32 -0
- package/src/testing/playwright/server-log-rename-reporter.ts +4 -3
- package/src/testing/run-update-pipeline.ts +8 -5
- package/src/testing/stub-ast-document-manager.ts +47 -123
- package/src/testing/stub-document-builder.ts +128 -15
- package/src/testing/stub-hydranium-text-documents.ts +184 -27
- package/src/testing/stub-langium-documents.ts +3 -2
- package/src/testing/stub-model-service.ts +9 -8
- package/src/testing/stub-project-manager.ts +10 -0
- package/src/testing/stub-self-save-registry.ts +1 -1
- package/src/testing/stub-service-registry.ts +1 -1
- package/src/testing/stub-writable-file-system.ts +3 -2
- package/src/util/connection-liveness.ts +81 -15
- package/src/util/environment.ts +24 -2
- package/lib/documents/language-client-text-shadow.d.ts +0 -124
- package/lib/documents/language-client-text-shadow.d.ts.map +0 -1
- package/lib/documents/language-client-text-shadow.js +0 -190
- package/lib/documents/language-client-text-shadow.js.map +0 -1
- package/lib/documents/self-save-registry.d.ts.map +0 -1
- package/lib/documents/self-save-registry.js.map +0 -1
- package/lib/lsp/instrument-connection.d.ts +0 -36
- package/lib/lsp/instrument-connection.d.ts.map +0 -1
- package/lib/lsp/instrument-connection.js +0 -62
- package/lib/lsp/instrument-connection.js.map +0 -1
- package/lib/node/process-memory.d.ts +0 -66
- package/lib/node/process-memory.d.ts.map +0 -1
- package/lib/node/process-memory.js +0 -252
- package/lib/node/process-memory.js.map +0 -1
- package/src/documents/language-client-text-shadow.ts +0 -211
- package/src/lsp/instrument-connection.ts +0 -66
- package/src/node/process-memory.ts +0 -299
|
@@ -7,13 +7,13 @@
|
|
|
7
7
|
* SPDX-License-Identifier: MIT
|
|
8
8
|
********************************************************************************/
|
|
9
9
|
|
|
10
|
-
import { Format } from '@hydranium/protocol';
|
|
10
|
+
import { Format, type Stopwatch, SystemClock } from '@hydranium/protocol';
|
|
11
11
|
import * as v8 from 'node:v8';
|
|
12
12
|
import { type ServerSharedServicesMinimal } from '../langium/shared-services.js';
|
|
13
13
|
|
|
14
14
|
/** Heap usage ratio (heapUsed / heap_size_limit) above which we emit a warning. */
|
|
15
15
|
export const DEFAULT_MEMORY_WARN_THRESHOLD = 0.85;
|
|
16
|
-
/** Heap usage ratio above which
|
|
16
|
+
/** Heap usage ratio above which the warning says out-of-memory is imminent. */
|
|
17
17
|
export const DEFAULT_MEMORY_CRITICAL_THRESHOLD = 0.95;
|
|
18
18
|
/** Cooldown between repeated warnings at the same level, in ms. */
|
|
19
19
|
export const DEFAULT_COOLDOWN_MS = 30_000;
|
|
@@ -25,7 +25,7 @@ type Severity = 'ok' | 'warn' | 'critical';
|
|
|
25
25
|
export interface MemoryMonitorOptions {
|
|
26
26
|
/** Heap-usage ratio (0..1) above which a warning is emitted. Default {@link DEFAULT_MEMORY_WARN_THRESHOLD}. */
|
|
27
27
|
warnThreshold?: number;
|
|
28
|
-
/** Heap-usage ratio above which
|
|
28
|
+
/** Heap-usage ratio above which the warning says out-of-memory is imminent. Default {@link DEFAULT_MEMORY_CRITICAL_THRESHOLD}. */
|
|
29
29
|
criticalThreshold?: number;
|
|
30
30
|
/** Sample interval, in ms. Default {@link DEFAULT_MEMORY_INTERVAL_MS}. */
|
|
31
31
|
intervalMs?: number;
|
|
@@ -52,8 +52,10 @@ export function startMemoryMonitor(shared: ServerSharedServicesMinimal, options:
|
|
|
52
52
|
const criticalThreshold = options.criticalThreshold ?? DEFAULT_MEMORY_CRITICAL_THRESHOLD;
|
|
53
53
|
const intervalMs = options.intervalMs ?? DEFAULT_MEMORY_INTERVAL_MS;
|
|
54
54
|
const cooldownMs = options.cooldownMs ?? DEFAULT_COOLDOWN_MS;
|
|
55
|
+
// Not `shared.Clock`, which a test may fake: the samples come on a real interval, so the cooldown runs on real time too.
|
|
56
|
+
const clock = new SystemClock();
|
|
55
57
|
let lastSeverity: Severity = 'ok';
|
|
56
|
-
let
|
|
58
|
+
let sinceEmitted: Stopwatch | undefined;
|
|
57
59
|
|
|
58
60
|
const severityFor = (ratio: number): Severity => {
|
|
59
61
|
if (ratio >= criticalThreshold) {
|
|
@@ -73,8 +75,7 @@ export function startMemoryMonitor(shared: ServerSharedServicesMinimal, options:
|
|
|
73
75
|
if (severity === 'ok' && lastSeverity === 'ok') {
|
|
74
76
|
return;
|
|
75
77
|
}
|
|
76
|
-
const
|
|
77
|
-
const shouldEmit = severity !== lastSeverity || now - lastEmittedAt >= cooldownMs;
|
|
78
|
+
const shouldEmit = severity !== lastSeverity || sinceEmitted === undefined || sinceEmitted.elapsedMs >= cooldownMs;
|
|
78
79
|
if (!shouldEmit) {
|
|
79
80
|
return;
|
|
80
81
|
}
|
|
@@ -86,15 +87,14 @@ export function startMemoryMonitor(shared: ServerSharedServicesMinimal, options:
|
|
|
86
87
|
: severity === 'warn'
|
|
87
88
|
? ' - garbage collection pressure may slow operations'
|
|
88
89
|
: ' - recovered below warning threshold');
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
} else if (severity === 'warn') {
|
|
90
|
+
// Critical is still a warning: nothing has failed yet.
|
|
91
|
+
if (severity !== 'ok') {
|
|
92
92
|
logger.warn(message);
|
|
93
93
|
} else {
|
|
94
94
|
logger.info(message);
|
|
95
95
|
}
|
|
96
96
|
lastSeverity = severity;
|
|
97
|
-
|
|
97
|
+
sinceEmitted = clock.stopwatch();
|
|
98
98
|
};
|
|
99
99
|
|
|
100
100
|
const interval = setInterval(check, intervalMs);
|
|
@@ -8,29 +8,40 @@
|
|
|
8
8
|
********************************************************************************/
|
|
9
9
|
|
|
10
10
|
import { type Tracer } from '@hydranium/protocol';
|
|
11
|
-
import { URI, UriUtils } from '@hydranium/langium';
|
|
11
|
+
import { type FileSystemNode, URI, UriUtils } from '@hydranium/langium';
|
|
12
12
|
import { NodeFileSystemProvider } from '@hydranium/langium/node';
|
|
13
13
|
import { randomUUID } from 'node:crypto';
|
|
14
|
-
import { realpathSync } from 'node:fs';
|
|
14
|
+
import { readlinkSync, realpathSync } from 'node:fs';
|
|
15
15
|
import * as fsp from 'node:fs/promises';
|
|
16
|
-
import {
|
|
17
|
-
import { type
|
|
16
|
+
import { basename, dirname, join, resolve } from 'node:path';
|
|
17
|
+
import { type WritableFileSystemProvider } from '../langium/workspace/file-system-provider.js';
|
|
18
|
+
import { isFileNotFound } from '../langium/workspace/file-not-found.js';
|
|
19
|
+
import { type SelfSaveRegistry } from '../langium/workspace/self-save-registry.js';
|
|
20
|
+
import { RENAME_GAP_BUDGET_MS, renameOverOpenReaders } from './rename-over-open-readers.js';
|
|
18
21
|
import { type LogNameOptions } from '../langium/diagnostics/logger.js';
|
|
19
22
|
import { serverSharedFactory, type ServerSharedServicesMinimal } from '../langium/shared-services.js';
|
|
20
|
-
import {
|
|
23
|
+
import { NO_SUCH_FILE, NO_SUCH_PATH, UNSUPPORTED_DELETE, UNSUPPORTED_WRITE } from '../langium/workspace/in-memory-file-system-provider.js';
|
|
21
24
|
|
|
22
25
|
/**
|
|
23
26
|
* Node-based default {@link WritableFileSystemProvider}. Extends Langium's
|
|
24
27
|
* {@link NodeFileSystemProvider} with an async {@link writeFile} that
|
|
25
|
-
* creates parent directories on demand, replaces the target
|
|
28
|
+
* creates parent directories on demand, replaces the target whole unless
|
|
26
29
|
* that would break a hard link, and registers the resulting mtime with the
|
|
27
30
|
* {@link SelfSaveRegistry} bound at `services.workspace.SelfSaveRegistry` — so
|
|
28
31
|
* consumers can suppress the `didChangeWatchedFiles` echo for their own writes.
|
|
29
32
|
*
|
|
33
|
+
* Its read surface refuses to derive a disk path from a URI that names no disk
|
|
34
|
+
* location — see {@link servesFromDisk}, which is the one place that judgement
|
|
35
|
+
* is made. Every method that derives an OS path is held to it, writes most of
|
|
36
|
+
* all: a read that skipped it would only mis-report, while a write would CREATE
|
|
37
|
+
* a file at a path the URI never named. Behind the framework's
|
|
38
|
+
* `FileSystemProviderRegistry`, a `virtual:` URI goes to the framework's own
|
|
39
|
+
* provider for that scheme, not here.
|
|
40
|
+
*
|
|
30
41
|
* Server-only (`@hydranium/core/node`): pulls `node:fs`. The portable `.`
|
|
31
|
-
* entry
|
|
32
|
-
*
|
|
33
|
-
* get real disk I/O.
|
|
42
|
+
* entry falls back to `DefaultEmptyFileSystemProvider`, so a Node host passes
|
|
43
|
+
* this one through `context.fileSystemProvider` (see {@link NodeFileSystem})
|
|
44
|
+
* to get real disk I/O.
|
|
34
45
|
*/
|
|
35
46
|
export class DefaultFileSystemProvider extends NodeFileSystemProvider implements WritableFileSystemProvider {
|
|
36
47
|
readonly selfSaveRegistry: SelfSaveRegistry;
|
|
@@ -45,15 +56,109 @@ export class DefaultFileSystemProvider extends NodeFileSystemProvider implements
|
|
|
45
56
|
this.tracer = services.Tracer.for(options.logName ?? this.constructor.name).trace('instantiated');
|
|
46
57
|
}
|
|
47
58
|
|
|
48
|
-
|
|
49
|
-
|
|
59
|
+
/**
|
|
60
|
+
* Whether `uri` names something this provider can reach on disk.
|
|
61
|
+
*
|
|
62
|
+
* Only a `file:` URI does. `URI.fsPath` yields a path for ANY scheme — for a
|
|
63
|
+
* hierarchical one it is the path component, which for a schemed URI with no
|
|
64
|
+
* authority comes out RELATIVE — so delegating an unrecognised scheme to Node
|
|
65
|
+
* does not fail, it probes `<cwd>/<path>` and answers about whatever
|
|
66
|
+
* unrelated file happens to sit there. A server whose working directory is
|
|
67
|
+
* the workspace root makes that collision ordinary rather than exotic.
|
|
68
|
+
*
|
|
69
|
+
* Note the deliberate disagreement with {@link realpath}, which treats a
|
|
70
|
+
* non-`file:` URI as PRESENT. The two degrade in opposite directions because
|
|
71
|
+
* they answer different questions: identity has to hand back a usable URI, so
|
|
72
|
+
* its safe answer is the one it was given, while occupancy and content must
|
|
73
|
+
* not be invented from an unrelated path, so their safe answer is "nothing
|
|
74
|
+
* here". A subclass adding a second on-disk scheme widens this and nothing
|
|
75
|
+
* else.
|
|
76
|
+
*/
|
|
77
|
+
protected servesFromDisk(uri: URI): boolean {
|
|
78
|
+
return uri.scheme === 'file';
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
// Each read answers from disk for a path this provider can reach, and
|
|
82
|
+
// otherwise with the filesystem's own "nothing here" — never a probe
|
|
83
|
+
// against a path derived from a URI that names no disk location.
|
|
50
84
|
override readFile(uri: URI): Promise<string> {
|
|
51
|
-
|
|
52
|
-
return served !== undefined ? Promise.resolve(served) : super.readFile(uri);
|
|
85
|
+
return this.servesFromDisk(uri) ? super.readFile(uri) : Promise.reject(noSuchFile(uri));
|
|
53
86
|
}
|
|
54
87
|
|
|
55
88
|
override readFileSync(uri: URI): string {
|
|
56
|
-
|
|
89
|
+
if (!this.servesFromDisk(uri)) {
|
|
90
|
+
throw noSuchFile(uri);
|
|
91
|
+
}
|
|
92
|
+
return super.readFileSync(uri);
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
override readBinary(uri: URI): Promise<Uint8Array> {
|
|
96
|
+
return this.servesFromDisk(uri) ? super.readBinary(uri) : Promise.reject(noSuchFile(uri));
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
override readBinarySync(uri: URI): Uint8Array {
|
|
100
|
+
if (!this.servesFromDisk(uri)) {
|
|
101
|
+
throw noSuchFile(uri);
|
|
102
|
+
}
|
|
103
|
+
return super.readBinarySync(uri);
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
override stat(uri: URI): Promise<FileSystemNode> {
|
|
107
|
+
return this.servesFromDisk(uri) ? super.stat(uri) : Promise.reject(noSuchPath(uri));
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
override statSync(uri: URI): FileSystemNode {
|
|
111
|
+
if (!this.servesFromDisk(uri)) {
|
|
112
|
+
throw noSuchPath(uri);
|
|
113
|
+
}
|
|
114
|
+
return super.statSync(uri);
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
// Delegating to `existsSync` would be shorter and would put a blocking stat
|
|
118
|
+
// on the async path.
|
|
119
|
+
override async exists(uri: URI): Promise<boolean> {
|
|
120
|
+
return this.servesFromDisk(uri) ? super.exists(uri) : false;
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
override existsSync(uri: URI): boolean {
|
|
124
|
+
return this.servesFromDisk(uri) ? super.existsSync(uri) : false;
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
/**
|
|
128
|
+
* On Windows a miss is polled for up to {@link RENAME_GAP_BUDGET_MS}, since a
|
|
129
|
+
* replacing rename there can hide the name from a reader for a while; it
|
|
130
|
+
* answers `true` as soon as the file is back. Elsewhere a miss is final.
|
|
131
|
+
*/
|
|
132
|
+
async existsSettled(uri: URI): Promise<boolean> {
|
|
133
|
+
if (await this.exists(uri)) {
|
|
134
|
+
return true;
|
|
135
|
+
}
|
|
136
|
+
if (!this.servesFromDisk(uri) || process.platform !== 'win32') {
|
|
137
|
+
return false;
|
|
138
|
+
}
|
|
139
|
+
// A stopwatch, not two `now()` readings: a wall-clock jump would end the
|
|
140
|
+
// wait early, removing a file that is only being replaced.
|
|
141
|
+
const waited = this.services.Clock.stopwatch();
|
|
142
|
+
while (waited.elapsedMs < RENAME_GAP_BUDGET_MS) {
|
|
143
|
+
// Not `clock.setTimer`: it unrefs its timer, so a process with only
|
|
144
|
+
// this check pending could exit mid-wait.
|
|
145
|
+
await new Promise(resolve => setTimeout(resolve, 10));
|
|
146
|
+
if (await this.exists(uri)) {
|
|
147
|
+
return true;
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
return false;
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
// A URI this provider cannot reach on disk has no children rather than an
|
|
154
|
+
// error: a workspace walk enumerates folders it was handed, and failing one
|
|
155
|
+
// aborts the walk where an empty listing simply contributes nothing.
|
|
156
|
+
override readDirectory(uri: URI): Promise<FileSystemNode[]> {
|
|
157
|
+
return this.servesFromDisk(uri) ? super.readDirectory(uri) : Promise.resolve([]);
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
override readDirectorySync(uri: URI): FileSystemNode[] {
|
|
161
|
+
return this.servesFromDisk(uri) ? super.readDirectorySync(uri) : [];
|
|
57
162
|
}
|
|
58
163
|
|
|
59
164
|
/**
|
|
@@ -66,8 +171,12 @@ export class DefaultFileSystemProvider extends NodeFileSystemProvider implements
|
|
|
66
171
|
* overwrite cannot offer that, because the target is truncated before the
|
|
67
172
|
* first byte lands, so a reader in that window gets a short or empty file —
|
|
68
173
|
* and a model file that fails to parse is worse than one holding a previous
|
|
69
|
-
* good revision.
|
|
70
|
-
*
|
|
174
|
+
* good revision. On Windows the replacing rename also leaves the name
|
|
175
|
+
* unresolvable for a moment, so a reader there can find the file missing
|
|
176
|
+
* (`ENOENT`) or refused (`EPERM`), never torn, and must not take either for
|
|
177
|
+
* a deletion; {@link existsSettled} waits that moment out. It does NOT
|
|
178
|
+
* serialise writers: two writers still race, and the loser's content is
|
|
179
|
+
* replaced wholesale rather than interleaved.
|
|
71
180
|
*
|
|
72
181
|
* The destination is the RESOLVED path, via {@link realpath}: a `rename`
|
|
73
182
|
* onto a symlink replaces the link itself with a regular file and leaves the
|
|
@@ -103,6 +212,17 @@ export class DefaultFileSystemProvider extends NodeFileSystemProvider implements
|
|
|
103
212
|
* only possible, which is what settles the trade.
|
|
104
213
|
*/
|
|
105
214
|
async writeFile(uri: URI, content: string): Promise<void> {
|
|
215
|
+
// BEFORE the `mkdir`, and before any other OS path is derived. The read
|
|
216
|
+
// surface degrades to "nothing here" for a URI naming no disk location;
|
|
217
|
+
// a write has no such harmless degradation — `fsPath` would hand it a
|
|
218
|
+
// real path regardless of scheme, so an unguarded write does not fail,
|
|
219
|
+
// it CREATES a file (and the directories above it) somewhere unrelated.
|
|
220
|
+
// Rejecting is the only safe answer: a caller holding a `memory:` or
|
|
221
|
+
// `untitled:` document has nowhere for it to go, and inventing a
|
|
222
|
+
// destination from the path component is never what it meant.
|
|
223
|
+
if (!this.servesFromDisk(uri)) {
|
|
224
|
+
throw unsupportedWrite(uri);
|
|
225
|
+
}
|
|
106
226
|
await fsp.mkdir(UriUtils.dirname(uri).fsPath, { recursive: true });
|
|
107
227
|
const destination = this.realpath(uri)?.fsPath ?? uri.fsPath;
|
|
108
228
|
const replaced = await replacedFile(destination);
|
|
@@ -134,7 +254,36 @@ export class DefaultFileSystemProvider extends NodeFileSystemProvider implements
|
|
|
134
254
|
}
|
|
135
255
|
}
|
|
136
256
|
|
|
257
|
+
/**
|
|
258
|
+
* Unlink `uri`, which removes a symlink rather than the file it points at
|
|
259
|
+
* and leaves a parent directory it empties in place. A file already gone is
|
|
260
|
+
* no error; a directory is refused, as `unlink` refuses it.
|
|
261
|
+
*/
|
|
262
|
+
async deleteFile(uri: URI): Promise<void> {
|
|
263
|
+
// Before the path is derived, for the reason `writeFile` gives: `fsPath`
|
|
264
|
+
// would name an unrelated file for a URI naming no disk location.
|
|
265
|
+
if (!this.servesFromDisk(uri)) {
|
|
266
|
+
throw new Error(UNSUPPORTED_DELETE.format({ uri: uri.toString() }));
|
|
267
|
+
}
|
|
268
|
+
try {
|
|
269
|
+
await fsp.unlink(uri.fsPath);
|
|
270
|
+
} catch (error: unknown) {
|
|
271
|
+
if (!isFileNotFound(error, uri)) {
|
|
272
|
+
throw error;
|
|
273
|
+
}
|
|
274
|
+
}
|
|
275
|
+
}
|
|
276
|
+
|
|
137
277
|
async mtimeMs(uri: URI): Promise<number | undefined> {
|
|
278
|
+
// Same rule as the read surface, and "unknown" is already the answer the
|
|
279
|
+
// caller handles — so a URI naming no disk location reports no mtime
|
|
280
|
+
// rather than the modification time of whatever occupies its `fsPath`.
|
|
281
|
+
// A stamp borrowed from an unrelated file is worse than none: the
|
|
282
|
+
// self-save registry keys on it to suppress a watcher echo, so a
|
|
283
|
+
// coincidental match would drop a real external change.
|
|
284
|
+
if (!this.servesFromDisk(uri)) {
|
|
285
|
+
return undefined;
|
|
286
|
+
}
|
|
138
287
|
try {
|
|
139
288
|
const stat = await fsp.stat(uri.fsPath);
|
|
140
289
|
return stat.mtimeMs;
|
|
@@ -166,6 +315,55 @@ export class DefaultFileSystemProvider extends NodeFileSystemProvider implements
|
|
|
166
315
|
return undefined;
|
|
167
316
|
}
|
|
168
317
|
}
|
|
318
|
+
|
|
319
|
+
/**
|
|
320
|
+
* The path `uri` names with every link followed, a link to nothing
|
|
321
|
+
* included, so a file reached through a link keys the same before it
|
|
322
|
+
* exists and once it does. What is missing is joined as spelled under the
|
|
323
|
+
* real path of what exists. A non-`file:` URI passes through unchanged.
|
|
324
|
+
*/
|
|
325
|
+
resolveLinks(uri: URI): URI {
|
|
326
|
+
return uri.scheme === 'file' ? URI.file(followLinks(uri.fsPath)) : uri;
|
|
327
|
+
}
|
|
328
|
+
}
|
|
329
|
+
|
|
330
|
+
/** `path` with its links followed; see `DefaultFileSystemProvider.resolveLinks`. */
|
|
331
|
+
function followLinks(path: string, hops = 0): string {
|
|
332
|
+
try {
|
|
333
|
+
return realpathSync(path);
|
|
334
|
+
} catch {
|
|
335
|
+
// Absent somewhere along the way.
|
|
336
|
+
}
|
|
337
|
+
// A link to nothing is followed to what it names; a chain is bounded as
|
|
338
|
+
// the kernel bounds one.
|
|
339
|
+
if (hops < 40) {
|
|
340
|
+
let target: string | undefined;
|
|
341
|
+
try {
|
|
342
|
+
target = readlinkSync(path);
|
|
343
|
+
} catch {
|
|
344
|
+
// Not a link, or not there.
|
|
345
|
+
}
|
|
346
|
+
if (target !== undefined) {
|
|
347
|
+
return followLinks(resolve(dirname(path), target), hops + 1);
|
|
348
|
+
}
|
|
349
|
+
}
|
|
350
|
+
const parent = dirname(path);
|
|
351
|
+
return parent === path ? path : join(followLinks(parent, hops), basename(path));
|
|
352
|
+
}
|
|
353
|
+
|
|
354
|
+
/** The "no content here" rejection, for a URI naming no readable file. */
|
|
355
|
+
function noSuchFile(uri: URI): Error {
|
|
356
|
+
return new Error(NO_SUCH_FILE.format({ uri: uri.toString() }));
|
|
357
|
+
}
|
|
358
|
+
|
|
359
|
+
/** The "nothing occupies this" rejection, for a URI naming no filesystem node. */
|
|
360
|
+
function noSuchPath(uri: URI): Error {
|
|
361
|
+
return new Error(NO_SUCH_PATH.format({ uri: uri.toString() }));
|
|
362
|
+
}
|
|
363
|
+
|
|
364
|
+
/** The "nowhere to put this" rejection, for a write to a URI with no disk backing. */
|
|
365
|
+
function unsupportedWrite(uri: URI): Error {
|
|
366
|
+
return new Error(UNSUPPORTED_WRITE.format({ uri: uri.toString() }));
|
|
169
367
|
}
|
|
170
368
|
|
|
171
369
|
/**
|
|
@@ -195,47 +393,6 @@ async function replacedFile(path: string): Promise<ReplacedFile | undefined> {
|
|
|
195
393
|
}
|
|
196
394
|
}
|
|
197
395
|
|
|
198
|
-
/**
|
|
199
|
-
* Errno values a rename reports on Windows when another handle holds the
|
|
200
|
-
* destination open. POSIX renames are unaffected by open handles, so this
|
|
201
|
-
* cannot fire there and the retry below costs nothing.
|
|
202
|
-
*/
|
|
203
|
-
const RENAME_CONTENTION_CODES = new Set(['EPERM', 'EACCES', 'EBUSY']);
|
|
204
|
-
|
|
205
|
-
/**
|
|
206
|
-
* `rename` the staged content over `destination`, retrying while Windows
|
|
207
|
-
* reports the destination as held open.
|
|
208
|
-
*
|
|
209
|
-
* The staging file exists so a reader never sees a half-written file, and on
|
|
210
|
-
* Windows the very presence of that reader is what makes the replacing rename
|
|
211
|
-
* fail — so the indivisible write breaks under exactly the contention it was
|
|
212
|
-
* built for, and it breaks intermittently, which is worse than never working.
|
|
213
|
-
* A reader's handle is released in milliseconds, so waiting turns a spurious
|
|
214
|
-
* failure into a slightly later success.
|
|
215
|
-
*
|
|
216
|
-
* BOUNDED, not open-ended: a genuine permission fault raises the same errno and
|
|
217
|
-
* is distinguishable from contention only by never clearing, so an unbounded
|
|
218
|
-
* wait would convert a hard error into a hang. Exhausting the budget rethrows
|
|
219
|
-
* the last failure, leaving the caller's cleanup and error contract unchanged.
|
|
220
|
-
*/
|
|
221
|
-
async function renameOverOpenReaders(staging: string, destination: string): Promise<void> {
|
|
222
|
-
const deadline = Date.now() + 2_000;
|
|
223
|
-
for (let attempt = 0; ; attempt++) {
|
|
224
|
-
try {
|
|
225
|
-
await fsp.rename(staging, destination);
|
|
226
|
-
return;
|
|
227
|
-
} catch (err: unknown) {
|
|
228
|
-
const code = err instanceof Error && 'code' in err ? String((err as NodeJS.ErrnoException).code) : undefined;
|
|
229
|
-
if (code === undefined || !RENAME_CONTENTION_CODES.has(code) || Date.now() >= deadline) {
|
|
230
|
-
throw err;
|
|
231
|
-
}
|
|
232
|
-
// Backs off to keep a long contention window from spinning, capped so
|
|
233
|
-
// a late attempt still lands promptly once the handle is released.
|
|
234
|
-
await new Promise(resolve => setTimeout(resolve, Math.min(2 ** attempt, 50)));
|
|
235
|
-
}
|
|
236
|
-
}
|
|
237
|
-
}
|
|
238
|
-
|
|
239
396
|
/**
|
|
240
397
|
* Module fragment that binds the writable Node {@link DefaultFileSystemProvider},
|
|
241
398
|
* spread into the services context on a Node host.
|
|
@@ -17,18 +17,11 @@
|
|
|
17
17
|
* `ProfileSession` (aggregate self-time spans).
|
|
18
18
|
*/
|
|
19
19
|
|
|
20
|
-
import { Format, type ProfileCaptureOptions } from '@hydranium/protocol';
|
|
20
|
+
import { type Clock, Format, type ProfileCaptureOptions, type Stopwatch, SystemClock } from '@hydranium/protocol';
|
|
21
21
|
import * as fs from 'node:fs';
|
|
22
22
|
import { Session } from 'node:inspector';
|
|
23
|
-
import {
|
|
24
|
-
|
|
25
|
-
monitorEventLoopDelay,
|
|
26
|
-
PerformanceObserver,
|
|
27
|
-
performance,
|
|
28
|
-
type IntervalHistogram,
|
|
29
|
-
type PerformanceEntry
|
|
30
|
-
} from 'node:perf_hooks';
|
|
31
|
-
import { snapshotFilePath, writeHeapSnapshotToDir } from './process-memory.js';
|
|
23
|
+
import { constants, monitorEventLoopDelay, PerformanceObserver, type IntervalHistogram, type PerformanceEntry } from 'node:perf_hooks';
|
|
24
|
+
import { snapshotFilePath, writeHeapSnapshotToDir } from '@hydranium/protocol/node';
|
|
32
25
|
|
|
33
26
|
export const DEFAULT_CPU_INTERVAL_MICROS = 1000;
|
|
34
27
|
export const DEFAULT_ALLOCATION_INTERVAL_BYTES = 32768;
|
|
@@ -147,8 +140,14 @@ export function formatProfileReport(report: ProfileReport, label = 'Profile repo
|
|
|
147
140
|
return lines.join('\n');
|
|
148
141
|
}
|
|
149
142
|
|
|
150
|
-
/**
|
|
151
|
-
|
|
143
|
+
/**
|
|
144
|
+
* Minimal structural view of a `node:inspector` `Session` — its typed per-method
|
|
145
|
+
* overloads can't be called generically.
|
|
146
|
+
*
|
|
147
|
+
* Held by the `protected` {@link ProfileCapture.session}, so a subclass reaching
|
|
148
|
+
* the inspector names this rather than `Session`.
|
|
149
|
+
*/
|
|
150
|
+
export interface InspectorSessionLike {
|
|
152
151
|
connect(): void;
|
|
153
152
|
disconnect(): void;
|
|
154
153
|
post(method: string, params: Record<string, unknown>, callback: (error: Error | null, result?: unknown) => void): void;
|
|
@@ -175,7 +174,9 @@ let active: ProfileCapture | undefined;
|
|
|
175
174
|
* session at a time); prefer {@link profileWorkload} for the common wrap-a-block case.
|
|
176
175
|
*/
|
|
177
176
|
export class ProfileCapture {
|
|
178
|
-
|
|
177
|
+
/** Times the window: real time, since what it frames is real CPU and memory. */
|
|
178
|
+
protected readonly clock: Clock = new SystemClock();
|
|
179
|
+
protected sinceStart: Stopwatch = this.clock.stopwatch();
|
|
179
180
|
protected startCpu: NodeJS.CpuUsage = { user: 0, system: 0 };
|
|
180
181
|
protected startMem: NodeJS.MemoryUsage = process.memoryUsage();
|
|
181
182
|
protected session?: InspectorSessionLike;
|
|
@@ -208,7 +209,7 @@ export class ProfileCapture {
|
|
|
208
209
|
}
|
|
209
210
|
|
|
210
211
|
protected async begin(): Promise<void> {
|
|
211
|
-
this.
|
|
212
|
+
this.sinceStart = this.clock.stopwatch();
|
|
212
213
|
this.startCpu = process.cpuUsage();
|
|
213
214
|
this.startMem = process.memoryUsage();
|
|
214
215
|
if (this.options.cpu || this.options.allocation) {
|
|
@@ -248,7 +249,7 @@ export class ProfileCapture {
|
|
|
248
249
|
if (active !== this) {
|
|
249
250
|
throw new Error('ProfileCapture.stop called on an inactive capture.');
|
|
250
251
|
}
|
|
251
|
-
const durationMs =
|
|
252
|
+
const durationMs = this.sinceStart.elapsedMs;
|
|
252
253
|
// Sample cpu + memory at the workload boundary (alongside durationMs), NOT
|
|
253
254
|
// after teardown: the synchronous profile write inflates RSS and the heap
|
|
254
255
|
// snapshot forces a full GC, so a post-teardown read would fold the
|
|
@@ -19,7 +19,11 @@
|
|
|
19
19
|
|
|
20
20
|
import {
|
|
21
21
|
DEFAULT_LOG_FILE_ENV,
|
|
22
|
+
DEFAULT_LOG_FILE_LEVEL_ENV,
|
|
23
|
+
DEFAULT_LOG_LEVEL_ENV,
|
|
24
|
+
parseLogLevel,
|
|
22
25
|
PROFILING_SCHEMA_VERSION,
|
|
26
|
+
type LogThreshold,
|
|
23
27
|
type LatencyCollector,
|
|
24
28
|
type ProfilingArtifact,
|
|
25
29
|
type ProfilingArtifactKind,
|
|
@@ -55,10 +59,26 @@ export interface ProfilingRunOptions {
|
|
|
55
59
|
/**
|
|
56
60
|
* Optional latency collector. When present, {@link ProfilingRun.finish} writes
|
|
57
61
|
* its report to `server-latency.json` and records a `server-latency` manifest artefact. A
|
|
58
|
-
* head feeds it via the RPC binding / `
|
|
59
|
-
*
|
|
62
|
+
* head feeds it via the RPC binding / `lspLatencyOptions`; a pure headless
|
|
63
|
+
* build with no request traffic leaves it empty.
|
|
60
64
|
*/
|
|
61
65
|
latency?: LatencyCollector;
|
|
66
|
+
/**
|
|
67
|
+
* Threshold `server.log` is written at. Defaults to `HYDRANIUM_LOG_FILE_LEVEL`,
|
|
68
|
+
* then `HYDRANIUM_LOG_LEVEL`, then `'info'`, read at {@link ProfilingRun.start}
|
|
69
|
+
* and held for the run, so a log-level setting arriving mid-run leaves the log
|
|
70
|
+
* alone. Above `'info'` the framework's own debug profile sessions run inside
|
|
71
|
+
* the captured windows and show up in the profiles.
|
|
72
|
+
*/
|
|
73
|
+
logFileLevel?: LogThreshold;
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
function restoreEnv(name: string, value: string | undefined): void {
|
|
77
|
+
if (value === undefined) {
|
|
78
|
+
delete process.env[name];
|
|
79
|
+
} else {
|
|
80
|
+
process.env[name] = value;
|
|
81
|
+
}
|
|
62
82
|
}
|
|
63
83
|
|
|
64
84
|
/** A cgroup memory controller signals we are inside a container/pod. */
|
|
@@ -80,6 +100,8 @@ export class ProfilingRun {
|
|
|
80
100
|
protected finished = false;
|
|
81
101
|
/** The `HYDRANIUM_LOG_FILE` value seen before this run pointed it at the session (restored on {@link finish}). */
|
|
82
102
|
protected readonly previousLogFileEnv?: string;
|
|
103
|
+
/** The `HYDRANIUM_LOG_FILE_LEVEL` value seen before this run set it (restored on {@link finish}). */
|
|
104
|
+
protected readonly previousLogFileLevelEnv?: string;
|
|
83
105
|
/** Absolute path of the session's teed server log. */
|
|
84
106
|
readonly serverLogPath: string;
|
|
85
107
|
|
|
@@ -97,10 +119,13 @@ export class ProfilingRun {
|
|
|
97
119
|
// `HYDRANIUM_LOG_FILE` env, which every `@hydranium/core` copy reads when
|
|
98
120
|
// its logger is CONSTRUCTED — so `ProfilingRun.start` must run before the
|
|
99
121
|
// head's services are created (as `measureModelMemory` does). This is the
|
|
100
|
-
// only mechanism that crosses
|
|
122
|
+
// only mechanism that crosses an adopter's separate core copy; a
|
|
101
123
|
// process-local `setLogFilePath` would only reach this module's own copy.
|
|
102
124
|
this.previousLogFileEnv = process.env[DEFAULT_LOG_FILE_ENV];
|
|
103
125
|
process.env[DEFAULT_LOG_FILE_ENV] = this.serverLogPath;
|
|
126
|
+
this.previousLogFileLevelEnv = process.env[DEFAULT_LOG_FILE_LEVEL_ENV];
|
|
127
|
+
process.env[DEFAULT_LOG_FILE_LEVEL_ENV] =
|
|
128
|
+
options.logFileLevel ?? parseLogLevel(this.previousLogFileLevelEnv) ?? parseLogLevel(process.env[DEFAULT_LOG_LEVEL_ENV]) ?? 'info';
|
|
104
129
|
}
|
|
105
130
|
|
|
106
131
|
static async start(options: ProfilingRunOptions = {}): Promise<ProfilingRun> {
|
|
@@ -179,11 +204,8 @@ export class ProfilingRun {
|
|
|
179
204
|
this.finished = true;
|
|
180
205
|
// Restore the prior log-file env, then record the log as an artefact only
|
|
181
206
|
// if the run actually produced one.
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
} else {
|
|
185
|
-
process.env[DEFAULT_LOG_FILE_ENV] = this.previousLogFileEnv;
|
|
186
|
-
}
|
|
207
|
+
restoreEnv(DEFAULT_LOG_FILE_ENV, this.previousLogFileEnv);
|
|
208
|
+
restoreEnv(DEFAULT_LOG_FILE_LEVEL_ENV, this.previousLogFileLevelEnv);
|
|
187
209
|
if (fs.existsSync(this.serverLogPath)) {
|
|
188
210
|
this.artifacts.push({ kind: 'server-log', path: 'server.log' });
|
|
189
211
|
}
|
|
@@ -0,0 +1,94 @@
|
|
|
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 Clock, SystemClock } from '@hydranium/protocol';
|
|
11
|
+
import * as fsp from 'node:fs/promises';
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* Errnos Windows raises when a replacing `rename` meets a handle already on the
|
|
15
|
+
* destination open. POSIX renames are unaffected by open handles, so these
|
|
16
|
+
* cannot fire there and the retry below costs nothing.
|
|
17
|
+
*/
|
|
18
|
+
export const RENAME_CONTENTION_CODES = new Set(['EPERM', 'EACCES', 'EBUSY']);
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
* How long a replacing rename may keep retrying before it gives up.
|
|
22
|
+
*
|
|
23
|
+
* BOUNDED, not open-ended: a genuine permission fault raises the same errno as
|
|
24
|
+
* contention and is distinguishable from it only by never clearing, so an
|
|
25
|
+
* unbounded wait would convert a hard error into a hang.
|
|
26
|
+
*
|
|
27
|
+
* The figure is a judgement, not a measurement, and the honest bound on it is
|
|
28
|
+
* that the previous 2s was observed EXHAUSTED on a loaded Windows CI runner
|
|
29
|
+
* while no upper bound has been established. What would settle it is recording
|
|
30
|
+
* how long a real contended rename takes to clear. graceful-fs tolerates 60s
|
|
31
|
+
* for Windows rename contention, but that is weaker support than it looks: it
|
|
32
|
+
* retries only where the destination has GONE, which is the opposite of
|
|
33
|
+
* replacing one a reader holds open.
|
|
34
|
+
*/
|
|
35
|
+
export const RENAME_BUDGET_MS = 10_000;
|
|
36
|
+
|
|
37
|
+
/**
|
|
38
|
+
* How long a miss is waited out on Windows before it counts as an absence,
|
|
39
|
+
* since a replacing rename there can hide the name from a reader for a while.
|
|
40
|
+
* Bounded: a real deletion differs only by never ending, so it pays the whole
|
|
41
|
+
* budget. The figure is a judgement, not an established bound.
|
|
42
|
+
*/
|
|
43
|
+
export const RENAME_GAP_BUDGET_MS = 2_000;
|
|
44
|
+
|
|
45
|
+
/** Seams for the test, which cannot make a real rename fail on demand. */
|
|
46
|
+
export interface RenameOverOpenReadersOptions {
|
|
47
|
+
readonly rename?: (from: string, to: string) => Promise<void>;
|
|
48
|
+
readonly budgetMs?: number;
|
|
49
|
+
readonly clock?: Clock;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
/**
|
|
53
|
+
* `rename` the staged content over `destination`, retrying while Windows
|
|
54
|
+
* reports the destination as held open.
|
|
55
|
+
*
|
|
56
|
+
* The staging file exists so a reader never sees a half-written file, and on
|
|
57
|
+
* Windows the very presence of that reader is what makes the replacing rename
|
|
58
|
+
* fail — so the indivisible write breaks under exactly the contention it was
|
|
59
|
+
* built for, and it breaks intermittently, which is worse than never working.
|
|
60
|
+
* A reader's handle is released in milliseconds, so waiting turns a spurious
|
|
61
|
+
* failure into a slightly later success.
|
|
62
|
+
*
|
|
63
|
+
* Exhausting the budget rethrows the last failure, leaving the caller's cleanup
|
|
64
|
+
* and error contract unchanged. An errno OUTSIDE the contention set is rethrown
|
|
65
|
+
* without waiting at all: retrying a fault that will not clear only delays it.
|
|
66
|
+
*/
|
|
67
|
+
export async function renameOverOpenReaders(
|
|
68
|
+
staging: string,
|
|
69
|
+
destination: string,
|
|
70
|
+
options: RenameOverOpenReadersOptions = {}
|
|
71
|
+
): Promise<void> {
|
|
72
|
+
const rename = options.rename ?? fsp.rename;
|
|
73
|
+
const clock = options.clock ?? new SystemClock();
|
|
74
|
+
const budgetMs = options.budgetMs ?? RENAME_BUDGET_MS;
|
|
75
|
+
// A stopwatch, not two `now()` readings: a wall-clock jump would end the
|
|
76
|
+
// budget early or stretch it.
|
|
77
|
+
const waited = clock.stopwatch();
|
|
78
|
+
for (let attempt = 0; ; attempt++) {
|
|
79
|
+
try {
|
|
80
|
+
await rename(staging, destination);
|
|
81
|
+
return;
|
|
82
|
+
} catch (err: unknown) {
|
|
83
|
+
const code = err instanceof Error && 'code' in err ? String((err as NodeJS.ErrnoException).code) : undefined;
|
|
84
|
+
if (code === undefined || !RENAME_CONTENTION_CODES.has(code) || waited.elapsedMs >= budgetMs) {
|
|
85
|
+
throw err;
|
|
86
|
+
}
|
|
87
|
+
// Backs off to keep a long contention window from spinning, capped so
|
|
88
|
+
// a late attempt still lands promptly once the handle is released.
|
|
89
|
+
// Not `clock.setTimer`: it unrefs its timer, so a process with only
|
|
90
|
+
// this write pending could exit mid-backoff.
|
|
91
|
+
await new Promise(resolve => setTimeout(resolve, Math.min(2 ** attempt, 50)));
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
}
|
|
@@ -49,7 +49,7 @@ export function startServerDiagnostics(shared: ServerSharedServicesMinimal, opti
|
|
|
49
49
|
productName,
|
|
50
50
|
version,
|
|
51
51
|
phaseDetailThresholdMs,
|
|
52
|
-
...nodeLogPreambleSections(phaseDetailThresholdMs)
|
|
52
|
+
...nodeLogPreambleSections(phaseDetailThresholdMs, options)
|
|
53
53
|
});
|
|
54
54
|
if (options.logInitialMemory ?? true) {
|
|
55
55
|
shared.Tracer.for('Process').memory('Initial Memory');
|