@hydranium/core 1.0.0-next.9 → 1.0.0-next.91
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/lib/documents/ast-document-manager.d.ts +75 -16
- package/lib/documents/ast-document-manager.d.ts.map +1 -1
- package/lib/documents/ast-document-manager.js +57 -19
- 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/hydranium-text-documents.d.ts +55 -21
- package/lib/documents/hydranium-text-documents.d.ts.map +1 -1
- package/lib/documents/hydranium-text-documents.js +142 -46
- package/lib/documents/hydranium-text-documents.js.map +1 -1
- package/lib/documents/language-client-text-shadow.d.ts +41 -9
- package/lib/documents/language-client-text-shadow.d.ts.map +1 -1
- package/lib/documents/language-client-text-shadow.js +56 -11
- package/lib/documents/language-client-text-shadow.js.map +1 -1
- package/lib/documents/self-save-registry.d.ts +37 -6
- package/lib/documents/self-save-registry.d.ts.map +1 -1
- package/lib/documents/self-save-registry.js +28 -15
- package/lib/documents/self-save-registry.js.map +1 -1
- package/lib/index.d.ts +2 -0
- package/lib/index.d.ts.map +1 -1
- package/lib/index.js +5 -0
- package/lib/index.js.map +1 -1
- package/lib/langium/ast-extension/ast-node-builder.d.ts +32 -9
- package/lib/langium/ast-extension/ast-node-builder.d.ts.map +1 -1
- package/lib/langium/ast-extension/ast-node-builder.js +60 -22
- package/lib/langium/ast-extension/ast-node-builder.js.map +1 -1
- package/lib/langium/bootstrap.d.ts.map +1 -1
- package/lib/langium/bootstrap.js +16 -9
- package/lib/langium/bootstrap.js.map +1 -1
- 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/diagnostics/lsp-logger.d.ts +17 -0
- package/lib/langium/diagnostics/lsp-logger.d.ts.map +1 -1
- package/lib/langium/diagnostics/lsp-logger.js +40 -6
- package/lib/langium/diagnostics/lsp-logger.js.map +1 -1
- package/lib/langium/document-builder/build-pipeline-integration.d.ts +13 -1
- package/lib/langium/document-builder/build-pipeline-integration.d.ts.map +1 -1
- package/lib/langium/document-builder/build-pipeline-integration.js +1 -1
- package/lib/langium/document-builder/build-pipeline-integration.js.map +1 -1
- package/lib/langium/document-builder/build-session.d.ts +93 -0
- package/lib/langium/document-builder/build-session.d.ts.map +1 -0
- package/lib/langium/document-builder/build-session.js +72 -0
- package/lib/langium/document-builder/build-session.js.map +1 -0
- package/lib/langium/document-builder/document-builder.d.ts +150 -7
- package/lib/langium/document-builder/document-builder.d.ts.map +1 -1
- package/lib/langium/document-builder/document-builder.js +298 -11
- package/lib/langium/document-builder/document-builder.js.map +1 -1
- package/lib/langium/document-builder/index.d.ts +1 -0
- package/lib/langium/document-builder/index.d.ts.map +1 -1
- package/lib/langium/document-builder/index.js +1 -0
- package/lib/langium/document-builder/index.js.map +1 -1
- package/lib/langium/integration-services.d.ts +45 -1
- package/lib/langium/integration-services.d.ts.map +1 -1
- package/lib/langium/integration-services.js +10 -5
- package/lib/langium/integration-services.js.map +1 -1
- package/lib/langium/integrity/integrity-service.d.ts +5 -0
- package/lib/langium/integrity/integrity-service.d.ts.map +1 -1
- package/lib/langium/integrity/integrity-service.js +34 -1
- package/lib/langium/integrity/integrity-service.js.map +1 -1
- package/lib/langium/keys/containment.d.ts +64 -0
- package/lib/langium/keys/containment.d.ts.map +1 -0
- package/lib/langium/keys/containment.js +53 -0
- package/lib/langium/keys/containment.js.map +1 -0
- package/lib/langium/keys/index.d.ts +1 -0
- package/lib/langium/keys/index.d.ts.map +1 -1
- package/lib/langium/keys/index.js +1 -0
- package/lib/langium/keys/index.js.map +1 -1
- package/lib/langium/keys/name-based-key-provider.d.ts +4 -0
- package/lib/langium/keys/name-based-key-provider.d.ts.map +1 -1
- package/lib/langium/keys/name-based-key-provider.js +4 -0
- package/lib/langium/keys/name-based-key-provider.js.map +1 -1
- package/lib/langium/model-service/model-service.d.ts +149 -10
- package/lib/langium/model-service/model-service.d.ts.map +1 -1
- package/lib/langium/model-service/model-service.js +120 -93
- package/lib/langium/model-service/model-service.js.map +1 -1
- package/lib/langium/module.d.ts +84 -15
- package/lib/langium/module.d.ts.map +1 -1
- package/lib/langium/module.js +26 -12
- package/lib/langium/module.js.map +1 -1
- package/lib/langium/naming/name-provider.d.ts +25 -4
- package/lib/langium/naming/name-provider.d.ts.map +1 -1
- package/lib/langium/naming/name-provider.js +2 -1
- package/lib/langium/naming/name-provider.js.map +1 -1
- package/lib/langium/naming/name-separator-validation.d.ts +23 -0
- package/lib/langium/naming/name-separator-validation.d.ts.map +1 -1
- package/lib/langium/naming/name-separator-validation.js +30 -1
- package/lib/langium/naming/name-separator-validation.js.map +1 -1
- package/lib/langium/residency/cst-residency-service.d.ts +31 -9
- package/lib/langium/residency/cst-residency-service.d.ts.map +1 -1
- package/lib/langium/residency/cst-residency-service.js +13 -56
- package/lib/langium/residency/cst-residency-service.js.map +1 -1
- package/lib/langium/scope/hydranium-scope-provider.d.ts +32 -13
- package/lib/langium/scope/hydranium-scope-provider.d.ts.map +1 -1
- package/lib/langium/scope/hydranium-scope-provider.js +37 -20
- package/lib/langium/scope/hydranium-scope-provider.js.map +1 -1
- package/lib/langium/service-registry.d.ts +5 -1
- package/lib/langium/service-registry.d.ts.map +1 -1
- package/lib/langium/service-registry.js +4 -0
- package/lib/langium/service-registry.js.map +1 -1
- package/lib/langium/shared-services.d.ts +15 -2
- package/lib/langium/shared-services.d.ts.map +1 -1
- package/lib/langium/shared-services.js.map +1 -1
- package/lib/langium/transfer/transfer-encoder.d.ts +60 -17
- package/lib/langium/transfer/transfer-encoder.d.ts.map +1 -1
- package/lib/langium/transfer/transfer-encoder.js +38 -16
- package/lib/langium/transfer/transfer-encoder.js.map +1 -1
- package/lib/langium/validation/document-validator.d.ts +294 -10
- package/lib/langium/validation/document-validator.d.ts.map +1 -1
- package/lib/langium/validation/document-validator.js +448 -5
- package/lib/langium/validation/document-validator.js.map +1 -1
- package/lib/langium/workspace/document-uri-policy.d.ts +3 -4
- package/lib/langium/workspace/document-uri-policy.d.ts.map +1 -1
- package/lib/langium/workspace/document-uri-policy.js +3 -4
- package/lib/langium/workspace/document-uri-policy.js.map +1 -1
- package/lib/langium/workspace/hydranium-langium-document-factory.d.ts +25 -0
- package/lib/langium/workspace/hydranium-langium-document-factory.d.ts.map +1 -1
- package/lib/langium/workspace/hydranium-langium-document-factory.js +25 -0
- package/lib/langium/workspace/hydranium-langium-document-factory.js.map +1 -1
- package/lib/langium/workspace/hydranium-workspace-manager.d.ts +21 -1
- package/lib/langium/workspace/hydranium-workspace-manager.d.ts.map +1 -1
- package/lib/langium/workspace/hydranium-workspace-manager.js +28 -0
- package/lib/langium/workspace/hydranium-workspace-manager.js.map +1 -1
- package/lib/langium/workspace/in-memory-file-system-provider.d.ts +8 -0
- package/lib/langium/workspace/in-memory-file-system-provider.d.ts.map +1 -1
- package/lib/langium/workspace/in-memory-file-system-provider.js +11 -2
- package/lib/langium/workspace/in-memory-file-system-provider.js.map +1 -1
- package/lib/langium/workspace/initialize-workspace.d.ts +22 -2
- package/lib/langium/workspace/initialize-workspace.d.ts.map +1 -1
- package/lib/langium/workspace/initialize-workspace.js +13 -5
- package/lib/langium/workspace/initialize-workspace.js.map +1 -1
- package/lib/langium/workspace/langium-documents.d.ts +79 -17
- package/lib/langium/workspace/langium-documents.d.ts.map +1 -1
- package/lib/langium/workspace/langium-documents.js +83 -28
- package/lib/langium/workspace/langium-documents.js.map +1 -1
- package/lib/locale/index.d.ts +10 -0
- package/lib/locale/index.d.ts.map +1 -0
- package/lib/locale/index.js +10 -0
- package/lib/locale/index.js.map +1 -0
- package/lib/locale/server-locale.d.ts +73 -0
- package/lib/locale/server-locale.d.ts.map +1 -0
- package/lib/locale/server-locale.js +61 -0
- package/lib/locale/server-locale.js.map +1 -0
- package/lib/lsp/hydranium-document-update-handler.js +1 -1
- package/lib/lsp/hydranium-document-update-handler.js.map +1 -1
- package/lib/lsp/index.d.ts +1 -1
- package/lib/lsp/index.d.ts.map +1 -1
- package/lib/lsp/index.js +1 -1
- 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/semantic-token-provider.d.ts +34 -1
- package/lib/lsp/semantic-token-provider.d.ts.map +1 -1
- package/lib/lsp/semantic-token-provider.js +55 -8
- package/lib/lsp/semantic-token-provider.js.map +1 -1
- package/lib/messages/carriers.d.ts +54 -0
- package/lib/messages/carriers.d.ts.map +1 -0
- package/lib/messages/carriers.js +62 -0
- package/lib/messages/carriers.js.map +1 -0
- package/lib/messages/index.d.ts +25 -0
- package/lib/messages/index.d.ts.map +1 -0
- package/lib/messages/index.js +25 -0
- package/lib/messages/index.js.map +1 -0
- package/lib/messages/renderer.d.ts +136 -0
- package/lib/messages/renderer.d.ts.map +1 -0
- package/lib/messages/renderer.js +159 -0
- package/lib/messages/renderer.js.map +1 -0
- 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 -0
- package/lib/node/index.d.ts.map +1 -1
- package/lib/node/index.js +1 -0
- 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/node-file-system-provider.d.ts.map +1 -1
- package/lib/node/node-file-system-provider.js +1 -40
- package/lib/node/node-file-system-provider.js.map +1 -1
- package/lib/node/profiling-run.d.ts +2 -2
- package/lib/node/profiling-run.js +1 -1
- package/lib/node/profiling-run.js.map +1 -1
- package/lib/node/rename-over-open-readers.d.ts +52 -0
- package/lib/node/rename-over-open-readers.d.ts.map +1 -0
- package/lib/node/rename-over-open-readers.js +66 -0
- package/lib/node/rename-over-open-readers.js.map +1 -0
- package/lib/node/socket-launcher.d.ts +15 -0
- package/lib/node/socket-launcher.d.ts.map +1 -1
- package/lib/node/socket-launcher.js +3 -2
- package/lib/node/socket-launcher.js.map +1 -1
- package/lib/testing/fake-document.d.ts +16 -4
- package/lib/testing/fake-document.d.ts.map +1 -1
- package/lib/testing/fake-document.js +18 -3
- package/lib/testing/fake-document.js.map +1 -1
- package/lib/testing/make-noop-shared-services.d.ts +14 -0
- package/lib/testing/make-noop-shared-services.d.ts.map +1 -1
- package/lib/testing/make-noop-shared-services.js +28 -2
- package/lib/testing/make-noop-shared-services.js.map +1 -1
- package/lib/testing/make-test-services.d.ts +44 -8
- package/lib/testing/make-test-services.d.ts.map +1 -1
- package/lib/testing/make-test-services.js +19 -3
- package/lib/testing/make-test-services.js.map +1 -1
- package/lib/testing/node/spawned-server.d.ts +14 -0
- package/lib/testing/node/spawned-server.d.ts.map +1 -1
- package/lib/testing/node/spawned-server.js +33 -1
- package/lib/testing/node/spawned-server.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 +14 -4
- package/lib/testing/playwright/server-log-capture.d.ts.map +1 -1
- package/lib/testing/playwright/server-log-capture.js +21 -4
- package/lib/testing/playwright/server-log-capture.js.map +1 -1
- package/lib/testing/playwright/server-log-rename-reporter.d.ts.map +1 -1
- package/lib/testing/playwright/server-log-rename-reporter.js +10 -1
- package/lib/testing/playwright/server-log-rename-reporter.js.map +1 -1
- package/lib/testing/stub-ast-document-manager.d.ts +5 -5
- package/lib/testing/stub-ast-document-manager.d.ts.map +1 -1
- package/lib/testing/stub-ast-document-manager.js +4 -6
- package/lib/testing/stub-ast-document-manager.js.map +1 -1
- package/lib/testing/stub-document-builder.d.ts +8 -0
- package/lib/testing/stub-document-builder.d.ts.map +1 -1
- package/lib/testing/stub-document-builder.js +22 -3
- package/lib/testing/stub-document-builder.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 +5 -4
- package/lib/testing/stub-model-service.d.ts.map +1 -1
- package/lib/testing/stub-model-service.js +2 -2
- package/lib/testing/stub-model-service.js.map +1 -1
- package/package.json +17 -8
- package/src/documents/ast-document-manager.ts +129 -36
- package/src/documents/client-ids.ts +5 -22
- package/src/documents/hydranium-text-documents.ts +167 -61
- package/src/documents/language-client-text-shadow.ts +59 -11
- package/src/documents/self-save-registry.ts +52 -13
- package/src/index.ts +5 -0
- package/src/langium/ast-extension/ast-node-builder.ts +66 -22
- package/src/langium/bootstrap.ts +16 -9
- package/src/langium/config/configuration-provider.ts +119 -0
- package/src/langium/config/index.ts +1 -0
- package/src/langium/diagnostics/lsp-logger.ts +41 -6
- package/src/langium/document-builder/build-pipeline-integration.ts +14 -1
- package/src/langium/document-builder/build-session.ts +87 -0
- package/src/langium/document-builder/document-builder.ts +339 -11
- package/src/langium/document-builder/index.ts +1 -0
- package/src/langium/integration-services.ts +67 -6
- package/src/langium/integrity/integrity-service.ts +35 -1
- package/src/langium/keys/containment.ts +87 -0
- package/src/langium/keys/index.ts +1 -0
- package/src/langium/keys/name-based-key-provider.ts +4 -0
- package/src/langium/model-service/model-service.ts +211 -30
- package/src/langium/module.ts +106 -21
- package/src/langium/naming/name-provider.ts +27 -5
- package/src/langium/naming/name-separator-validation.ts +34 -5
- package/src/langium/residency/cst-residency-service.ts +36 -12
- package/src/langium/scope/hydranium-scope-provider.ts +40 -22
- package/src/langium/service-registry.ts +6 -2
- package/src/langium/shared-services.ts +19 -2
- package/src/langium/transfer/transfer-encoder.ts +85 -24
- package/src/langium/validation/document-validator.ts +537 -11
- package/src/langium/workspace/document-uri-policy.ts +3 -4
- package/src/langium/workspace/hydranium-langium-document-factory.ts +34 -0
- package/src/langium/workspace/hydranium-workspace-manager.ts +30 -1
- package/src/langium/workspace/in-memory-file-system-provider.ts +13 -3
- package/src/langium/workspace/initialize-workspace.ts +34 -5
- package/src/langium/workspace/langium-documents.ts +106 -33
- package/src/locale/index.ts +10 -0
- package/src/locale/server-locale.ts +86 -0
- package/src/lsp/hydranium-document-update-handler.ts +1 -1
- package/src/lsp/index.ts +1 -1
- package/src/lsp/lsp-latency.ts +62 -0
- package/src/lsp/semantic-token-provider.ts +74 -7
- package/src/messages/carriers.ts +78 -0
- package/src/messages/index.ts +36 -0
- package/src/messages/renderer.ts +204 -0
- package/src/node/heap-ceiling.ts +108 -0
- package/src/node/index.ts +1 -0
- package/src/node/latency-from-env.ts +1 -1
- package/src/node/node-file-system-provider.ts +1 -41
- package/src/node/profiling-run.ts +3 -3
- package/src/node/rename-over-open-readers.ts +78 -0
- package/src/node/socket-launcher.ts +18 -2
- package/src/testing/fake-document.ts +24 -5
- package/src/testing/make-noop-shared-services.ts +50 -2
- package/src/testing/make-test-services.ts +73 -18
- package/src/testing/node/spawned-server.ts +35 -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 +24 -5
- package/src/testing/playwright/server-log-rename-reporter.ts +12 -1
- package/src/testing/stub-ast-document-manager.ts +10 -14
- package/src/testing/stub-document-builder.ts +32 -3
- package/src/testing/stub-langium-documents.ts +3 -2
- package/src/testing/stub-model-service.ts +7 -6
- 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/src/lsp/instrument-connection.ts +0 -66
|
@@ -6,13 +6,30 @@
|
|
|
6
6
|
*
|
|
7
7
|
* SPDX-License-Identifier: MIT
|
|
8
8
|
********************************************************************************/
|
|
9
|
-
import { type CanonicalUri, type CloseModelArgs, type MaybeObservableValue, type MaybePromise, ObservableValue, type
|
|
9
|
+
import { type CanonicalUri, type CloseModelArgs, type MaybeObservableValue, type MaybePromise, ObservableValue, type TransferElement, type OpenModelArgs, type Tracer, type TransferSaveArgs, type TransferUpdateArgs } from '@hydranium/protocol';
|
|
10
10
|
import { type AstNode, DocumentState, type LangiumDocument, type URI } from '@hydranium/langium';
|
|
11
|
+
import { type AstDiagnostic } from '../validation/document-validator.js';
|
|
11
12
|
import { type DocumentUriPolicy } from '../workspace/document-uri-policy.js';
|
|
12
13
|
import { type CancellationToken, type Disposable } from 'vscode-languageserver';
|
|
13
14
|
import { AstDocument, type AstDocumentSavedEvent, type AstDocumentUpdatedEvent } from '../../documents/ast-document-manager.js';
|
|
14
15
|
import { type LogNameOptions } from '../diagnostics/logger.js';
|
|
15
16
|
import { type ServerSharedServices } from '../module.js';
|
|
17
|
+
/**
|
|
18
|
+
* The undo-stack entry for a server-authored write pushed to the editor.
|
|
19
|
+
*
|
|
20
|
+
* **A user-facing LABEL, not a log string**, which is easy to miss because it
|
|
21
|
+
* travels as an options field rather than as a message: LSP specifies
|
|
22
|
+
* `ApplyWorkspaceEditParams.label` as "presented in the user interface for
|
|
23
|
+
* example on an undo stack to undo the workspace edit". So a user who edits
|
|
24
|
+
* through a form or drags a diagram node reads this in their editor's undo menu
|
|
25
|
+
* — which is why it is rendered like any other message the server sends rather
|
|
26
|
+
* than left as the English literal it was.
|
|
27
|
+
*
|
|
28
|
+
* Parameterless deliberately. The obvious improvement is to name the document,
|
|
29
|
+
* and it is the wrong one: an undo menu is already grouped under the file, so
|
|
30
|
+
* the URI would be noise in the one place it is redundant.
|
|
31
|
+
*/
|
|
32
|
+
export declare const MODEL_UPDATE_EDIT: import("@hydranium/protocol").MessageDefinition<"Update Model">;
|
|
16
33
|
/**
|
|
17
34
|
* Constructor options for {@link ModelService}. All fields are optional,
|
|
18
35
|
* and the defaults are the behaviour described on each one.
|
|
@@ -142,13 +159,77 @@ export interface ModelServiceOptions extends LogNameOptions {
|
|
|
142
159
|
* **Generic parameters.**
|
|
143
160
|
* - `TAst` — the AST root type each consumer expects on the returned
|
|
144
161
|
* {@link AstDocument}. Constrained to {@link AstNode}.
|
|
145
|
-
* - `TDiagnostic` —
|
|
146
|
-
* `
|
|
162
|
+
* - `TDiagnostic` — the AST-layer diagnostic: whatever the build left on
|
|
163
|
+
* `LangiumDocument.diagnostics`, carried through on the returned
|
|
164
|
+
* {@link AstDocument}. Defaults to {@link AstDiagnostic}.
|
|
165
|
+
* **Not the `TransferEncoder`'s parameter of the same name**, which is
|
|
166
|
+
* that encoder's OUTPUT and so names the wire shape. This one names its
|
|
167
|
+
* input, and an adopter binds the two to different types.
|
|
147
168
|
* - `TTransfer` — transfer-model root accepted by `update` / `save`
|
|
148
169
|
* args. Constrained to {@link TransferElement}. Defaults to the
|
|
149
170
|
* structural base.
|
|
150
171
|
*/
|
|
151
|
-
|
|
172
|
+
/**
|
|
173
|
+
* The seam every non-LSP head talks to: the data server, the GLSP head and an
|
|
174
|
+
* adopter's own services reach documents through this slot rather than through
|
|
175
|
+
* the workspace stores.
|
|
176
|
+
*
|
|
177
|
+
* **Two families, and the distinction matters more than the names suggest.**
|
|
178
|
+
* `waitFor*` is a pure wait — it never triggers a build, so a caller waiting on
|
|
179
|
+
* a document no build has touched waits until something else builds it.
|
|
180
|
+
* `ensureDocumentState` and the phase shorthands over it *dispatch*: warm
|
|
181
|
+
* documents are awaited, cold ones are built.
|
|
182
|
+
*
|
|
183
|
+
* **Diagnostics are typed `never` below `Validated`.** Validation is the last
|
|
184
|
+
* phase, so at any earlier landmark the array either is not yet computed or
|
|
185
|
+
* still holds the previous build's, and reading it would take stale results
|
|
186
|
+
* for fresh ones. A caller that needs diagnostics asks for {@link validated}.
|
|
187
|
+
*
|
|
188
|
+
* What the `never` buys, exactly: reading a field off an element is a compile
|
|
189
|
+
* error, and nothing can be appended. It does NOT stop a caller assigning an
|
|
190
|
+
* element to a typed variable, because `never` is assignable to everything — so
|
|
191
|
+
* this is a guard against reaching for diagnostics by accident, not a seal
|
|
192
|
+
* against doing it deliberately.
|
|
193
|
+
*
|
|
194
|
+
* The waits resolve at or ABOVE their target, so an already-validated document
|
|
195
|
+
* does carry usable diagnostics and the `never` over-forbids there. That
|
|
196
|
+
* direction is the safe one: the alternative permits stale reads silently. A
|
|
197
|
+
* member taking a phase as a PARAMETER cannot judge statically and so returns
|
|
198
|
+
* `TDiagnostic`, leaving the choice to the caller.
|
|
199
|
+
*/
|
|
200
|
+
export interface ModelService<TAst extends AstNode, TDiagnostic extends AstDiagnostic = AstDiagnostic, TTransfer extends TransferElement = TransferElement> {
|
|
201
|
+
/**
|
|
202
|
+
* Resolves once the workspace has been initialised and its first build has
|
|
203
|
+
* completed — the gate every read should wait behind, since a document
|
|
204
|
+
* queried before it may be unbuilt and reach no phase.
|
|
205
|
+
*
|
|
206
|
+
* A property rather than a method, matching `ProjectManager.ready` and
|
|
207
|
+
* Langium's `WorkspaceManager.ready`. An implementation needing a stricter
|
|
208
|
+
* gate supplies a Promise that awaits its own concern as well.
|
|
209
|
+
*/
|
|
210
|
+
readonly ready: Promise<void>;
|
|
211
|
+
waitForDocumentState(uri: string, state: DocumentState, cancelToken?: CancellationToken): Promise<AstDocument<TAst, TDiagnostic>>;
|
|
212
|
+
waitForDocumentSettled(uri: string, cancelToken?: CancellationToken): Promise<AstDocument<TAst, never>>;
|
|
213
|
+
waitForBuilderState(state: DocumentState, cancelToken?: CancellationToken): Promise<void>;
|
|
214
|
+
ensureDocumentState(uri: string, state?: DocumentState, cancelToken?: CancellationToken): Promise<AstDocument<TAst, TDiagnostic>>;
|
|
215
|
+
rebuild(uri: string, state?: DocumentState, cancelToken?: CancellationToken): Promise<AstDocument<TAst, TDiagnostic>>;
|
|
216
|
+
parsed(uri: string, cancelToken?: CancellationToken): Promise<AstDocument<TAst, never>>;
|
|
217
|
+
linked(uri: string, cancelToken?: CancellationToken): Promise<AstDocument<TAst, never>>;
|
|
218
|
+
settled(uri: string, cancelToken?: CancellationToken): Promise<AstDocument<TAst, never>>;
|
|
219
|
+
indexed(uri: string, cancelToken?: CancellationToken): Promise<AstDocument<TAst, never>>;
|
|
220
|
+
validated(uri: string, cancelToken?: CancellationToken): Promise<AstDocument<TAst, TDiagnostic>>;
|
|
221
|
+
update(args: TransferUpdateArgs<TTransfer>, cancelToken?: CancellationToken): Promise<AstDocument<TAst, TDiagnostic>>;
|
|
222
|
+
save(args: TransferSaveArgs<TTransfer>, cancelToken?: CancellationToken): Promise<AstDocument<TAst, TDiagnostic>>;
|
|
223
|
+
open(args: OpenModelArgs): Promise<Disposable>;
|
|
224
|
+
close(args: CloseModelArgs): Promise<void>;
|
|
225
|
+
isOpen(uri: string): boolean;
|
|
226
|
+
snapshot(uri: string): AstDocument<TAst, TDiagnostic> | undefined;
|
|
227
|
+
getDocument(uri: string): LangiumDocument | undefined;
|
|
228
|
+
onModelUpdated(uri: string, listener: (event: AstDocumentUpdatedEvent<TAst, TDiagnostic>) => void): Disposable;
|
|
229
|
+
onModelSaved(uri: string, listener: (event: AstDocumentSavedEvent<TAst, TDiagnostic>) => void): Disposable;
|
|
230
|
+
onClientClosed(uri: string, clientId: string, listener: () => void): Disposable;
|
|
231
|
+
}
|
|
232
|
+
export declare class DefaultModelService<TAst extends AstNode, TDiagnostic extends AstDiagnostic = AstDiagnostic,
|
|
152
233
|
/**
|
|
153
234
|
* Structured payload accepted by `update` / `save`. Constrained to
|
|
154
235
|
* {@link TransferElement} — the minimal `{ readonly $type: string }`
|
|
@@ -158,7 +239,7 @@ export declare class ModelService<TAst extends AstNode, TDiagnostic = TransferDi
|
|
|
158
239
|
* constraint, so in-process callers (e.g. GLSP state or an
|
|
159
240
|
* integrity service) that pass AST roots remain compatible.
|
|
160
241
|
*/
|
|
161
|
-
TTransfer extends TransferElement = TransferElement> {
|
|
242
|
+
TTransfer extends TransferElement = TransferElement> implements ModelService<TAst, TDiagnostic, TTransfer> {
|
|
162
243
|
protected readonly services: ServerSharedServices;
|
|
163
244
|
protected readonly tracer: Tracer;
|
|
164
245
|
/**
|
|
@@ -238,7 +319,7 @@ TTransfer extends TransferElement = TransferElement> {
|
|
|
238
319
|
* {@link waitForDocumentState} for the common "wait until content is stable"
|
|
239
320
|
* case (e.g. settling a save). Pure wait — does not trigger a build.
|
|
240
321
|
*/
|
|
241
|
-
waitForDocumentSettled(uri: string, cancelToken?: CancellationToken): Promise<AstDocument<TAst,
|
|
322
|
+
waitForDocumentSettled(uri: string, cancelToken?: CancellationToken): Promise<AstDocument<TAst, never>>;
|
|
242
323
|
/**
|
|
243
324
|
* Internal wait core operating on an already-{@link CanonicalUri canonical}
|
|
244
325
|
* URI. The public string doors ({@link waitForDocumentState} /
|
|
@@ -316,11 +397,19 @@ TTransfer extends TransferElement = TransferElement> {
|
|
|
316
397
|
*
|
|
317
398
|
* Phase invariants encoded in the return type:
|
|
318
399
|
* - `parsed` / `linked` / `settled` / `indexed` return
|
|
319
|
-
* `AstDocument<TAst, never>` — diagnostics
|
|
320
|
-
*
|
|
400
|
+
* `AstDocument<TAst, never>` — no diagnostics have been computed at
|
|
401
|
+
* those phases.
|
|
321
402
|
* - `validated` returns `AstDocument<TAst, TDiagnostic>` — diagnostics
|
|
322
403
|
* are populated.
|
|
323
404
|
*
|
|
405
|
+
* **The `never` is enforced, not merely declared.** The wait underneath
|
|
406
|
+
* resolves at or ABOVE the requested state, so a document something else
|
|
407
|
+
* already carried past `Validated` would otherwise come back from
|
|
408
|
+
* `settled()` carrying a full diagnostics array typed `never`; these four
|
|
409
|
+
* strip it. An empty array here therefore means "this read does not report
|
|
410
|
+
* diagnostics", never "this document is clean" — call {@link validated}
|
|
411
|
+
* when the answer has to mean the second.
|
|
412
|
+
*
|
|
324
413
|
* `settled` is the integrity-overlay name for "all integrity rules
|
|
325
414
|
* have fired"; it maps to {@link IntegrityService.SettledState} (which
|
|
326
415
|
* equals `DocumentState.IndexedReferences`), but the dedicated method
|
|
@@ -435,6 +524,23 @@ TTransfer extends TransferElement = TransferElement> {
|
|
|
435
524
|
* client. Pure read; no side effects.
|
|
436
525
|
*/
|
|
437
526
|
isOpen(uri: string): boolean;
|
|
527
|
+
/**
|
|
528
|
+
* Snapshot of `uri` as it stands RIGHT NOW — the synchronous sibling of the
|
|
529
|
+
* phase reads, which all wait. `undefined` when no document is registered.
|
|
530
|
+
*
|
|
531
|
+
* **This is what a writer wants, and {@link getDocument} is not.** The
|
|
532
|
+
* envelope's `version` is copied by value at projection time, so it cannot
|
|
533
|
+
* move afterwards; a version read off the live document at write time is
|
|
534
|
+
* whatever the server is at *now*, which is the number an optimistic gate is
|
|
535
|
+
* about to compare it against.
|
|
536
|
+
*
|
|
537
|
+
* Diagnostics only from a document that has reached `Validated`, and an
|
|
538
|
+
* empty array otherwise. Unlike the phase reads this one names no phase, so
|
|
539
|
+
* the state it finds is the only thing that can say whether the array
|
|
540
|
+
* describes the content being handed back or whatever an earlier build left.
|
|
541
|
+
* A caller that needs them unconditionally waits, via {@link validated}.
|
|
542
|
+
*/
|
|
543
|
+
snapshot(uri: string): AstDocument<TAst, TDiagnostic> | undefined;
|
|
438
544
|
/**
|
|
439
545
|
* The built {@link LangiumDocument} for `uri`, looked up by canonical identity —
|
|
440
546
|
* the synchronous, phase-agnostic sibling of {@link ensureDocumentState} /
|
|
@@ -443,6 +549,13 @@ TTransfer extends TransferElement = TransferElement> {
|
|
|
443
549
|
* into `LangiumDocuments` directly: a symlinked / `..` / case-divergent URI
|
|
444
550
|
* still resolves to the one document the build keys by its real path. Returns
|
|
445
551
|
* `undefined` if no document is registered for `uri`.
|
|
552
|
+
*
|
|
553
|
+
* **Live, so do not take a based-on version off it.** `textDocument` is the
|
|
554
|
+
* store's own object rather than a copy, so `.version` read here answers for
|
|
555
|
+
* the moment of the READ, not the moment of the earlier content — pass it to
|
|
556
|
+
* a write and the server compares its current version against itself, the
|
|
557
|
+
* gate passes unconditionally, and a concurrent edit is overwritten with
|
|
558
|
+
* nothing logged. Use {@link snapshot} for that, or a phase read.
|
|
446
559
|
*/
|
|
447
560
|
getDocument(uri: string): LangiumDocument | undefined;
|
|
448
561
|
/**
|
|
@@ -503,11 +616,11 @@ TTransfer extends TransferElement = TransferElement> {
|
|
|
503
616
|
*
|
|
504
617
|
* The signal is "a known client other than the language client authored this
|
|
505
618
|
* version **and** the URI was in the last build's changed set
|
|
506
|
-
* (`
|
|
619
|
+
* (`isTriggeringEdit`)". A framework-internal rebuild reports no author
|
|
507
620
|
* (`getAuthor` → `undefined`), so it fails `hasKnownAuthor` without comparing
|
|
508
621
|
* against a sentinel. This is NOT redundant with content/registration — it
|
|
509
622
|
* distinguishes "client edited" from "framework rebuilt", which neither the
|
|
510
|
-
* shadow nor `
|
|
623
|
+
* shadow nor `isTriggeringEdit` alone can.
|
|
511
624
|
*/
|
|
512
625
|
protected isNonLanguageClientEdit(document: LangiumDocument): boolean;
|
|
513
626
|
/**
|
|
@@ -518,6 +631,16 @@ TTransfer extends TransferElement = TransferElement> {
|
|
|
518
631
|
* per URI so the shadow never drifts from Monaco.
|
|
519
632
|
*/
|
|
520
633
|
protected queueSync(uri: string, text: string): void;
|
|
634
|
+
/**
|
|
635
|
+
* The undo-stack label for a server-authored write, in the locale the server
|
|
636
|
+
* was handed at init.
|
|
637
|
+
*
|
|
638
|
+
* One method rather than the literal at each `applyEdit`, because the two
|
|
639
|
+
* call sites are the same edit — a push and its full-replace retry — and an
|
|
640
|
+
* undo menu showing two different words for one operation would read as two
|
|
641
|
+
* operations.
|
|
642
|
+
*/
|
|
643
|
+
protected editLabel(): string;
|
|
521
644
|
protected drainSyncQueue(uri: string): Promise<void>;
|
|
522
645
|
/**
|
|
523
646
|
* Subscribe to AST-snapshot updates for `uri`. Fires after each
|
|
@@ -594,5 +717,21 @@ TTransfer extends TransferElement = TransferElement> {
|
|
|
594
717
|
* registry — adopters that prefer to throw override on their subclass.
|
|
595
718
|
*/
|
|
596
719
|
protected toAstDocument(uri: URI): AstDocument<TAst, TDiagnostic>;
|
|
720
|
+
/**
|
|
721
|
+
* The same envelope with no diagnostics, for a read that names a phase below
|
|
722
|
+
* `Validated`.
|
|
723
|
+
*
|
|
724
|
+
* Langium fills `LangiumDocument.diagnostics` from inside `validateDocument`
|
|
725
|
+
* and from nowhere else, so below that phase the array holds whatever an
|
|
726
|
+
* EARLIER build left — a verdict about text the document may no longer have.
|
|
727
|
+
* The wait underneath resolves at or above the phase asked for, so a document
|
|
728
|
+
* something else carried past `Validated` would otherwise hand a full array
|
|
729
|
+
* back from `parsed()`.
|
|
730
|
+
*
|
|
731
|
+
* A copy rather than a clear: the envelope is freshly built here, but
|
|
732
|
+
* {@link toAstDocument} is overridable and an adopter's version may return
|
|
733
|
+
* one it also keeps.
|
|
734
|
+
*/
|
|
735
|
+
protected withoutDiagnostics(document: AstDocument<TAst, TDiagnostic>): AstDocument<TAst, never>;
|
|
597
736
|
}
|
|
598
737
|
//# sourceMappingURL=model-service.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"model-service.d.ts","sourceRoot":"","sources":["../../../src/langium/model-service/model-service.ts"],"names":[],"mappings":"AAAA;;;;;;;kFAOkF;AAElF,OAAO,EACJ,KAAK,YAAY,EACjB,KAAK,cAAc,
|
|
1
|
+
{"version":3,"file":"model-service.d.ts","sourceRoot":"","sources":["../../../src/langium/model-service/model-service.ts"],"names":[],"mappings":"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"}
|
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
*
|
|
7
7
|
* SPDX-License-Identifier: MIT
|
|
8
8
|
********************************************************************************/
|
|
9
|
-
import { ConflictError, Logger, ObservableValue } from '@hydranium/protocol';
|
|
9
|
+
import { ConflictError, isSnapshotVersion, defineMessage, Logger, ObservableValue } from '@hydranium/protocol';
|
|
10
10
|
import { DocumentState, UriUtils } from '@hydranium/langium';
|
|
11
11
|
import { ReentrantWriteLockError, isInsideWriteLock } from '../workspace/write-lock-scope.js';
|
|
12
12
|
import { AstDocument } from '../../documents/ast-document-manager.js';
|
|
@@ -14,6 +14,22 @@ import { isConnectionGoneError } from '../../util/connection-liveness.js';
|
|
|
14
14
|
import { IntegrityService } from '../integrity/integrity-service.js';
|
|
15
15
|
import { labelPhaseListener } from '../document-builder/labeled-phase-listener.js';
|
|
16
16
|
import { LANGUAGE_CLIENT_ID } from '../../documents/client-ids.js';
|
|
17
|
+
/**
|
|
18
|
+
* The undo-stack entry for a server-authored write pushed to the editor.
|
|
19
|
+
*
|
|
20
|
+
* **A user-facing LABEL, not a log string**, which is easy to miss because it
|
|
21
|
+
* travels as an options field rather than as a message: LSP specifies
|
|
22
|
+
* `ApplyWorkspaceEditParams.label` as "presented in the user interface for
|
|
23
|
+
* example on an undo stack to undo the workspace edit". So a user who edits
|
|
24
|
+
* through a form or drags a diagram node reads this in their editor's undo menu
|
|
25
|
+
* — which is why it is rendered like any other message the server sends rather
|
|
26
|
+
* than left as the English literal it was.
|
|
27
|
+
*
|
|
28
|
+
* Parameterless deliberately. The obvious improvement is to name the document,
|
|
29
|
+
* and it is the wrong one: an undo menu is already grouped under the file, so
|
|
30
|
+
* the URI would be noise in the one place it is redundant.
|
|
31
|
+
*/
|
|
32
|
+
export const MODEL_UPDATE_EDIT = defineMessage('hydranium/core/model-update-edit', 'Update Model');
|
|
17
33
|
/** Max time {@link ModelService.settleSave} waits for the build to settle and the sync chain to drain. */
|
|
18
34
|
const SAVE_SETTLE_TIMEOUT_MS = 10_000;
|
|
19
35
|
/**
|
|
@@ -25,75 +41,7 @@ const SAVE_SETTLE_TIMEOUT_MS = 10_000;
|
|
|
25
41
|
*/
|
|
26
42
|
class SaveSettleTimeoutError extends Error {
|
|
27
43
|
}
|
|
28
|
-
|
|
29
|
-
* In-process facade over the framework's document plumbing
|
|
30
|
-
* (`HydraniumTextDocuments`, `LangiumDocuments`,
|
|
31
|
-
* `DocumentBuilder`, `WritableFileSystemProvider`). Owns the
|
|
32
|
-
* `open / request / update / save / ready` lifecycle that protocol heads
|
|
33
|
-
* (LSP, data-server, GLSP) delegate to so coordinating those primitives
|
|
34
|
-
* doesn't have to be re-implemented per-head.
|
|
35
|
-
*
|
|
36
|
-
* "Model" here means the parsed AST — distinct from the wire-shape
|
|
37
|
-
* `TransferDocument` in `@hydranium/protocol`.
|
|
38
|
-
*
|
|
39
|
-
* **Why a facade**
|
|
40
|
-
*
|
|
41
|
-
* Multiple in-process consumers want the same workspace-level
|
|
42
|
-
* operations:
|
|
43
|
-
* - The data-server head turns these into typed RPC methods.
|
|
44
|
-
* - The GLSP head uses the same lifecycle for diagram-driven edits;
|
|
45
|
-
* GModel operation handlers route through `update` for AST mutation,
|
|
46
|
-
* `waitForDocumentState` for indexed-phase waits before reads, etc.
|
|
47
|
-
* - Server-internal callers (integrity service, ad-hoc bridges, tests)
|
|
48
|
-
* want the same operations without the wire serialisation step.
|
|
49
|
-
*
|
|
50
|
-
* Coordinating the primitives per-head drifts between heads — different
|
|
51
|
-
* superseded-version handling, different settled-phase choices, different
|
|
52
|
-
* content-change paths. The facade collapses that duplication and gives
|
|
53
|
-
* adopters one extension surface — {@link rewriteModel},
|
|
54
|
-
* {@link serialize} — to customise the in-process behaviour without
|
|
55
|
-
* re-implementing the plumbing.
|
|
56
|
-
*
|
|
57
|
-
* **Read-latest supersession**
|
|
58
|
-
*
|
|
59
|
-
* The default `update` and `save` flows use Langium's per-URI
|
|
60
|
-
* `DocumentBuilder.waitUntil` to wait for the integrity-settled landmark
|
|
61
|
-
* ({@link IntegrityService.SettledState}), then read the post-build state. Concurrent
|
|
62
|
-
* in-process callers on the same URI all see the latest post-build
|
|
63
|
-
* snapshot — none deadlock waiting for a specific version's settled
|
|
64
|
-
* event. Adopters wanting strict version-matched semantics (resolve
|
|
65
|
-
* with vN's snapshot specifically, log "vN superseded by vM at vN+1")
|
|
66
|
-
* override {@link update} to attach a phase-listener with explicit
|
|
67
|
-
* version checks; the framework default doesn't need it for safety.
|
|
68
|
-
*
|
|
69
|
-
* **Returns AST snapshots, not wire envelopes**
|
|
70
|
-
*
|
|
71
|
-
* The facade returns {@link AstDocument} (the in-process AST-typed
|
|
72
|
-
* envelope), not `TransferDocument` (the lossy wire shape). In-
|
|
73
|
-
* process callers consume `$container` / `Reference<T>` directly;
|
|
74
|
-
* encoding-on-return would be wasteful and would force the wire-side
|
|
75
|
-
* lossy `$refText` shape on every consumer. The wire-side caller
|
|
76
|
-
* (`DataServer.updateModelDocument` etc.) encodes once on return via
|
|
77
|
-
* the injected `TransferEncoder` — symmetric with the
|
|
78
|
-
* `getModelDocument` envelope path.
|
|
79
|
-
*
|
|
80
|
-
* **Subscriptions** ({@link onModelUpdated} / {@link onModelSaved} /
|
|
81
|
-
* {@link onClientClosed}) are thin pass-throughs over
|
|
82
|
-
* `DocumentBuilder.onDocumentPhase` and
|
|
83
|
-
* `HydraniumTextDocuments.onDidSave` / `onDidClose`. Filtering
|
|
84
|
-
* by URI happens here so consumers can subscribe per-document without
|
|
85
|
-
* implementing the URI gate at each callsite.
|
|
86
|
-
*
|
|
87
|
-
* **Generic parameters.**
|
|
88
|
-
* - `TAst` — the AST root type each consumer expects on the returned
|
|
89
|
-
* {@link AstDocument}. Constrained to {@link AstNode}.
|
|
90
|
-
* - `TDiagnostic` — wire diagnostic shape used by the injected
|
|
91
|
-
* `TransferEncoder`. Defaults to {@link TransferDiagnostic}.
|
|
92
|
-
* - `TTransfer` — transfer-model root accepted by `update` / `save`
|
|
93
|
-
* args. Constrained to {@link TransferElement}. Defaults to the
|
|
94
|
-
* structural base.
|
|
95
|
-
*/
|
|
96
|
-
export class ModelService {
|
|
44
|
+
export class DefaultModelService {
|
|
97
45
|
services;
|
|
98
46
|
tracer;
|
|
99
47
|
/**
|
|
@@ -219,7 +167,7 @@ export class ModelService {
|
|
|
219
167
|
* case (e.g. settling a save). Pure wait — does not trigger a build.
|
|
220
168
|
*/
|
|
221
169
|
async waitForDocumentSettled(uri, cancelToken) {
|
|
222
|
-
return this.waitForDocumentStateCanonical(this.uriPolicy.canonicalUri(uri), IntegrityService.SettledState, cancelToken);
|
|
170
|
+
return (await this.waitForDocumentStateCanonical(this.uriPolicy.canonicalUri(uri), IntegrityService.SettledState, cancelToken));
|
|
223
171
|
}
|
|
224
172
|
/**
|
|
225
173
|
* Internal wait core operating on an already-{@link CanonicalUri canonical}
|
|
@@ -351,11 +299,19 @@ export class ModelService {
|
|
|
351
299
|
*
|
|
352
300
|
* Phase invariants encoded in the return type:
|
|
353
301
|
* - `parsed` / `linked` / `settled` / `indexed` return
|
|
354
|
-
* `AstDocument<TAst, never>` — diagnostics
|
|
355
|
-
*
|
|
302
|
+
* `AstDocument<TAst, never>` — no diagnostics have been computed at
|
|
303
|
+
* those phases.
|
|
356
304
|
* - `validated` returns `AstDocument<TAst, TDiagnostic>` — diagnostics
|
|
357
305
|
* are populated.
|
|
358
306
|
*
|
|
307
|
+
* **The `never` is enforced, not merely declared.** The wait underneath
|
|
308
|
+
* resolves at or ABOVE the requested state, so a document something else
|
|
309
|
+
* already carried past `Validated` would otherwise come back from
|
|
310
|
+
* `settled()` carrying a full diagnostics array typed `never`; these four
|
|
311
|
+
* strip it. An empty array here therefore means "this read does not report
|
|
312
|
+
* diagnostics", never "this document is clean" — call {@link validated}
|
|
313
|
+
* when the answer has to mean the second.
|
|
314
|
+
*
|
|
359
315
|
* `settled` is the integrity-overlay name for "all integrity rules
|
|
360
316
|
* have fired"; it maps to {@link IntegrityService.SettledState} (which
|
|
361
317
|
* equals `DocumentState.IndexedReferences`), but the dedicated method
|
|
@@ -363,16 +319,16 @@ export class ModelService {
|
|
|
363
319
|
* ever moves.
|
|
364
320
|
*/
|
|
365
321
|
async parsed(uri, cancelToken) {
|
|
366
|
-
return this.ensureDocumentState(uri, DocumentState.Parsed, cancelToken);
|
|
322
|
+
return this.withoutDiagnostics(await this.ensureDocumentState(uri, DocumentState.Parsed, cancelToken));
|
|
367
323
|
}
|
|
368
324
|
async linked(uri, cancelToken) {
|
|
369
|
-
return this.ensureDocumentState(uri, DocumentState.Linked, cancelToken);
|
|
325
|
+
return this.withoutDiagnostics(await this.ensureDocumentState(uri, DocumentState.Linked, cancelToken));
|
|
370
326
|
}
|
|
371
327
|
async settled(uri, cancelToken) {
|
|
372
|
-
return this.ensureDocumentState(uri, IntegrityService.SettledState, cancelToken);
|
|
328
|
+
return this.withoutDiagnostics(await this.ensureDocumentState(uri, IntegrityService.SettledState, cancelToken));
|
|
373
329
|
}
|
|
374
330
|
async indexed(uri, cancelToken) {
|
|
375
|
-
return this.ensureDocumentState(uri, DocumentState.IndexedReferences, cancelToken);
|
|
331
|
+
return this.withoutDiagnostics(await this.ensureDocumentState(uri, DocumentState.IndexedReferences, cancelToken));
|
|
376
332
|
}
|
|
377
333
|
async validated(uri, cancelToken) {
|
|
378
334
|
return this.ensureDocumentState(uri, DocumentState.Validated, cancelToken);
|
|
@@ -454,19 +410,29 @@ export class ModelService {
|
|
|
454
410
|
// created from the payload rather than read from the filesystem — `update`
|
|
455
411
|
// is an upsert. For an already-open document `open` refreshes content (the
|
|
456
412
|
// text is ignored on that branch), so existing-document behaviour is
|
|
457
|
-
// unchanged. `version` is intentionally NOT forwarded to `open
|
|
458
|
-
// create stays at its initial version
|
|
459
|
-
//
|
|
413
|
+
// unchanged. `version` is intentionally NOT forwarded to `open`, so a cold
|
|
414
|
+
// create stays at its initial version rather than adopting a number the
|
|
415
|
+
// caller chose.
|
|
416
|
+
//
|
|
417
|
+
// The gate's version is read BEFORE that open, and must be: for a document
|
|
418
|
+
// no client holds open, the open assigns the shared version from the
|
|
419
|
+
// INCOMING text, so a version read afterwards has already absorbed the
|
|
420
|
+
// caller's own write. Gating on it rejected every modifying write to a
|
|
421
|
+
// closed document, having compared the caller's `basedOn` against a
|
|
422
|
+
// number the caller itself produced — and a serialised round-trip that is
|
|
423
|
+
// not byte-identical to the stored text was enough to trigger it. Reading
|
|
424
|
+
// first keeps both cases the gate exists for: an unknown URI answers 0, so
|
|
425
|
+
// a based-on-version update of a not-yet-existing document still trips it,
|
|
426
|
+
// and a genuine conflict still trips it, another writer having advanced the
|
|
427
|
+
// sequence past the version the caller read.
|
|
428
|
+
const currentVersion = this.services.workspace.TextDocuments.version(uri);
|
|
460
429
|
const text = await run('serialize', () => this.modelToText(uri, args.model, cancelToken));
|
|
461
430
|
await run('open', () => this.open({ uri, clientId: args.clientId, text }));
|
|
462
|
-
if (args.
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
this.tracer.debug(`Conflict on ${uri}: based-on v${args.baseVersion} stale, server at v${current}`);
|
|
468
|
-
throw new ConflictError(uri, args.baseVersion, current);
|
|
469
|
-
}
|
|
431
|
+
if (isSnapshotVersion(args.basedOn) && currentVersion !== args.basedOn) {
|
|
432
|
+
// Distinct from the post-build "superseded" debug line below: this is a
|
|
433
|
+
// based-on-stale rejection (the write never applies), not two writes racing.
|
|
434
|
+
this.tracer.debug(`Conflict on ${uri}: based-on v${args.basedOn} stale, server at v${currentVersion}`);
|
|
435
|
+
throw new ConflictError(uri, args.basedOn, currentVersion);
|
|
470
436
|
}
|
|
471
437
|
const appliedVersion = await run('apply', () => this.services.workspace.AstDocumentManager.update(uri, text, args.clientId));
|
|
472
438
|
// Dispatch through the public `rebuild` (which re-canonicalizes the already-
|
|
@@ -584,6 +550,30 @@ export class ModelService {
|
|
|
584
550
|
isOpen(uri) {
|
|
585
551
|
return this.services.workspace.AstDocumentManager.isOpen(uri);
|
|
586
552
|
}
|
|
553
|
+
/**
|
|
554
|
+
* Snapshot of `uri` as it stands RIGHT NOW — the synchronous sibling of the
|
|
555
|
+
* phase reads, which all wait. `undefined` when no document is registered.
|
|
556
|
+
*
|
|
557
|
+
* **This is what a writer wants, and {@link getDocument} is not.** The
|
|
558
|
+
* envelope's `version` is copied by value at projection time, so it cannot
|
|
559
|
+
* move afterwards; a version read off the live document at write time is
|
|
560
|
+
* whatever the server is at *now*, which is the number an optimistic gate is
|
|
561
|
+
* about to compare it against.
|
|
562
|
+
*
|
|
563
|
+
* Diagnostics only from a document that has reached `Validated`, and an
|
|
564
|
+
* empty array otherwise. Unlike the phase reads this one names no phase, so
|
|
565
|
+
* the state it finds is the only thing that can say whether the array
|
|
566
|
+
* describes the content being handed back or whatever an earlier build left.
|
|
567
|
+
* A caller that needs them unconditionally waits, via {@link validated}.
|
|
568
|
+
*/
|
|
569
|
+
snapshot(uri) {
|
|
570
|
+
const document = this.getDocument(uri);
|
|
571
|
+
if (!document) {
|
|
572
|
+
return undefined;
|
|
573
|
+
}
|
|
574
|
+
const envelope = AstDocument.from(document);
|
|
575
|
+
return document.state >= DocumentState.Validated ? envelope : this.withoutDiagnostics(envelope);
|
|
576
|
+
}
|
|
587
577
|
/**
|
|
588
578
|
* The built {@link LangiumDocument} for `uri`, looked up by canonical identity —
|
|
589
579
|
* the synchronous, phase-agnostic sibling of {@link ensureDocumentState} /
|
|
@@ -592,6 +582,13 @@ export class ModelService {
|
|
|
592
582
|
* into `LangiumDocuments` directly: a symlinked / `..` / case-divergent URI
|
|
593
583
|
* still resolves to the one document the build keys by its real path. Returns
|
|
594
584
|
* `undefined` if no document is registered for `uri`.
|
|
585
|
+
*
|
|
586
|
+
* **Live, so do not take a based-on version off it.** `textDocument` is the
|
|
587
|
+
* store's own object rather than a copy, so `.version` read here answers for
|
|
588
|
+
* the moment of the READ, not the moment of the earlier content — pass it to
|
|
589
|
+
* a write and the server compares its current version against itself, the
|
|
590
|
+
* gate passes unconditionally, and a concurrent edit is overwritten with
|
|
591
|
+
* nothing logged. Use {@link snapshot} for that, or a phase read.
|
|
595
592
|
*/
|
|
596
593
|
getDocument(uri) {
|
|
597
594
|
return this.services.workspace.AstDocumentManager.getDocument(uri);
|
|
@@ -681,17 +678,17 @@ export class ModelService {
|
|
|
681
678
|
*
|
|
682
679
|
* The signal is "a known client other than the language client authored this
|
|
683
680
|
* version **and** the URI was in the last build's changed set
|
|
684
|
-
* (`
|
|
681
|
+
* (`isTriggeringEdit`)". A framework-internal rebuild reports no author
|
|
685
682
|
* (`getAuthor` → `undefined`), so it fails `hasKnownAuthor` without comparing
|
|
686
683
|
* against a sentinel. This is NOT redundant with content/registration — it
|
|
687
684
|
* distinguishes "client edited" from "framework rebuilt", which neither the
|
|
688
|
-
* shadow nor `
|
|
685
|
+
* shadow nor `isTriggeringEdit` alone can.
|
|
689
686
|
*/
|
|
690
687
|
isNonLanguageClientEdit(document) {
|
|
691
688
|
const documents = this.services.workspace.AstDocumentManager;
|
|
692
689
|
const author = documents.getAuthor(document);
|
|
693
690
|
const hasKnownAuthor = !!author && author !== LANGUAGE_CLIENT_ID;
|
|
694
|
-
return hasKnownAuthor && documents.
|
|
691
|
+
return hasKnownAuthor && documents.isTriggeringEdit(document.textDocument.uri);
|
|
695
692
|
}
|
|
696
693
|
/**
|
|
697
694
|
* Enqueue a sync to the language client. The pending slot per URI holds only
|
|
@@ -723,13 +720,25 @@ export class ModelService {
|
|
|
723
720
|
});
|
|
724
721
|
this.syncChains.set(uri, chain);
|
|
725
722
|
}
|
|
723
|
+
/**
|
|
724
|
+
* The undo-stack label for a server-authored write, in the locale the server
|
|
725
|
+
* was handed at init.
|
|
726
|
+
*
|
|
727
|
+
* One method rather than the literal at each `applyEdit`, because the two
|
|
728
|
+
* call sites are the same edit — a push and its full-replace retry — and an
|
|
729
|
+
* undo menu showing two different words for one operation would read as two
|
|
730
|
+
* operations.
|
|
731
|
+
*/
|
|
732
|
+
editLabel() {
|
|
733
|
+
return this.services.MessageRenderer.renderMessage(MODEL_UPDATE_EDIT);
|
|
734
|
+
}
|
|
726
735
|
async drainSyncQueue(uri) {
|
|
727
736
|
const uriLogger = this.tracer.withUri(uri);
|
|
728
737
|
while (this.pendingSync.has(uri)) {
|
|
729
738
|
const text = this.pendingSync.get(uri);
|
|
730
739
|
this.pendingSync.delete(uri);
|
|
731
740
|
try {
|
|
732
|
-
let result = await this.services.workspace.TextDocuments.applyEditToLanguageClient(uri, text, { label:
|
|
741
|
+
let result = await this.services.workspace.TextDocuments.applyEditToLanguageClient(uri, text, { label: this.editLabel() });
|
|
733
742
|
if (result?.applied === false && !this.pendingSync.has(uri)) {
|
|
734
743
|
// The push is addressed at the client's LAST DECLARED VERSION, so a
|
|
735
744
|
// rejection normally means the client's buffer moved while the
|
|
@@ -750,7 +759,7 @@ export class ModelService {
|
|
|
750
759
|
// queued — best-effort, since a settle arriving later simply pushes
|
|
751
760
|
// after this and still wins.
|
|
752
761
|
uriLogger.warn(`Language client rejected applyEdit at its declared version — re-pushing a full replace`);
|
|
753
|
-
result = await this.services.workspace.TextDocuments.applyEditToLanguageClient(uri, text, { label:
|
|
762
|
+
result = await this.services.workspace.TextDocuments.applyEditToLanguageClient(uri, text, { label: this.editLabel() });
|
|
754
763
|
if (result?.applied === false) {
|
|
755
764
|
uriLogger.warn(`Language client rejected the full-replace retry too — client content is stale`);
|
|
756
765
|
}
|
|
@@ -885,5 +894,23 @@ export class ModelService {
|
|
|
885
894
|
? AstDocument.from(document)
|
|
886
895
|
: AstDocument.create(uri.toString(), 0, undefined, []);
|
|
887
896
|
}
|
|
897
|
+
/**
|
|
898
|
+
* The same envelope with no diagnostics, for a read that names a phase below
|
|
899
|
+
* `Validated`.
|
|
900
|
+
*
|
|
901
|
+
* Langium fills `LangiumDocument.diagnostics` from inside `validateDocument`
|
|
902
|
+
* and from nowhere else, so below that phase the array holds whatever an
|
|
903
|
+
* EARLIER build left — a verdict about text the document may no longer have.
|
|
904
|
+
* The wait underneath resolves at or above the phase asked for, so a document
|
|
905
|
+
* something else carried past `Validated` would otherwise hand a full array
|
|
906
|
+
* back from `parsed()`.
|
|
907
|
+
*
|
|
908
|
+
* A copy rather than a clear: the envelope is freshly built here, but
|
|
909
|
+
* {@link toAstDocument} is overridable and an adopter's version may return
|
|
910
|
+
* one it also keeps.
|
|
911
|
+
*/
|
|
912
|
+
withoutDiagnostics(document) {
|
|
913
|
+
return { ...document, diagnostics: [] };
|
|
914
|
+
}
|
|
888
915
|
}
|
|
889
916
|
//# sourceMappingURL=model-service.js.map
|