@hydranium/core 1.0.0-next.36 → 1.0.0-next.38
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 +42 -5
- package/lib/documents/ast-document-manager.d.ts.map +1 -1
- package/lib/documents/ast-document-manager.js +3 -7
- package/lib/documents/ast-document-manager.js.map +1 -1
- package/lib/documents/hydranium-text-documents.d.ts.map +1 -1
- package/lib/documents/hydranium-text-documents.js +29 -8
- package/lib/documents/hydranium-text-documents.js.map +1 -1
- package/lib/documents/language-client-text-shadow.d.ts +24 -1
- package/lib/documents/language-client-text-shadow.d.ts.map +1 -1
- package/lib/documents/language-client-text-shadow.js +36 -2
- 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 +1 -0
- package/lib/index.d.ts.map +1 -1
- package/lib/index.js +4 -0
- package/lib/index.js.map +1 -1
- package/lib/langium/bootstrap.js +8 -8
- package/lib/langium/bootstrap.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/document-builder.d.ts +2 -2
- package/lib/langium/document-builder/document-builder.d.ts.map +1 -1
- package/lib/langium/document-builder/document-builder.js.map +1 -1
- package/lib/langium/integration-services.d.ts +1 -1
- package/lib/langium/model-service/model-service.d.ts +64 -5
- package/lib/langium/model-service/model-service.d.ts.map +1 -1
- package/lib/langium/model-service/model-service.js +5 -73
- package/lib/langium/model-service/model-service.js.map +1 -1
- package/lib/langium/module.d.ts +58 -16
- package/lib/langium/module.d.ts.map +1 -1
- package/lib/langium/module.js +16 -16
- package/lib/langium/module.js.map +1 -1
- package/lib/langium/residency/cst-residency-service.d.ts +30 -8
- 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/shared-services.d.ts +3 -3
- package/lib/langium/shared-services.d.ts.map +1 -1
- package/lib/langium/transfer/transfer-encoder.d.ts +29 -1
- package/lib/langium/transfer/transfer-encoder.d.ts.map +1 -1
- package/lib/langium/transfer/transfer-encoder.js +1 -1
- package/lib/langium/transfer/transfer-encoder.js.map +1 -1
- package/lib/locale/server-locale.d.ts +15 -1
- package/lib/locale/server-locale.d.ts.map +1 -1
- package/lib/locale/server-locale.js +1 -1
- package/lib/locale/server-locale.js.map +1 -1
- package/lib/lsp/hydranium-document-update-handler.js +1 -1
- package/lib/lsp/hydranium-document-update-handler.js.map +1 -1
- package/lib/messages/renderer.d.ts +23 -4
- package/lib/messages/renderer.d.ts.map +1 -1
- package/lib/messages/renderer.js +1 -1
- package/lib/messages/renderer.js.map +1 -1
- package/lib/testing/make-noop-shared-services.d.ts +4 -4
- package/lib/testing/make-noop-shared-services.d.ts.map +1 -1
- package/lib/testing/make-noop-shared-services.js +4 -4
- package/lib/testing/make-noop-shared-services.js.map +1 -1
- package/lib/testing/make-test-services.d.ts +9 -9
- package/lib/testing/make-test-services.d.ts.map +1 -1
- package/lib/testing/make-test-services.js +6 -6
- package/lib/testing/make-test-services.js.map +1 -1
- package/lib/testing/stub-ast-document-manager.d.ts +3 -4
- package/lib/testing/stub-ast-document-manager.d.ts.map +1 -1
- package/lib/testing/stub-ast-document-manager.js +2 -5
- package/lib/testing/stub-ast-document-manager.js.map +1 -1
- package/lib/testing/stub-model-service.d.ts +1 -1
- 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 +5 -5
- package/src/documents/ast-document-manager.ts +49 -9
- package/src/documents/hydranium-text-documents.ts +29 -8
- package/src/documents/language-client-text-shadow.ts +38 -2
- package/src/documents/self-save-registry.ts +52 -13
- package/src/index.ts +4 -0
- package/src/langium/bootstrap.ts +8 -8
- package/src/langium/document-builder/build-pipeline-integration.ts +14 -1
- package/src/langium/document-builder/document-builder.ts +2 -2
- package/src/langium/integration-services.ts +1 -1
- package/src/langium/model-service/model-service.ts +78 -7
- package/src/langium/module.ts +71 -24
- package/src/langium/residency/cst-residency-service.ts +35 -11
- package/src/langium/shared-services.ts +3 -3
- package/src/langium/transfer/transfer-encoder.ts +32 -1
- package/src/locale/server-locale.ts +16 -1
- package/src/lsp/hydranium-document-update-handler.ts +1 -1
- package/src/messages/renderer.ts +24 -4
- package/src/testing/make-noop-shared-services.ts +6 -6
- package/src/testing/make-test-services.ts +15 -15
- package/src/testing/stub-ast-document-manager.ts +5 -10
- package/src/testing/stub-model-service.ts +2 -2
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"stub-ast-document-manager.d.ts","sourceRoot":"","sources":["../../src/testing/stub-ast-document-manager.ts"],"names":[],"mappings":"AAAA;;;;;;;kFAOkF;AAElF,OAAO,EAAE,KAAK,OAAO,EAAkC,MAAM,oBAAoB,CAAC;AAElF,OAAO,EAEJ,KAAK,kBAAkB,EACvB,KAAK,uBAAuB,EAC5B,KAAK,0BAA0B,EACjC,MAAM,sCAAsC,CAAC;AAE9C,OAAO,KAAK,EAAE,0BAA0B,EAAE,MAAM,oCAAoC,CAAC;AACrF,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,6BAA6B,CAAC;AAExE
|
|
1
|
+
{"version":3,"file":"stub-ast-document-manager.d.ts","sourceRoot":"","sources":["../../src/testing/stub-ast-document-manager.ts"],"names":[],"mappings":"AAAA;;;;;;;kFAOkF;AAElF,OAAO,EAAE,KAAK,OAAO,EAAkC,MAAM,oBAAoB,CAAC;AAElF,OAAO,EAEJ,KAAK,kBAAkB,EACvB,KAAK,uBAAuB,EAC5B,KAAK,0BAA0B,EACjC,MAAM,sCAAsC,CAAC;AAE9C,OAAO,KAAK,EAAE,0BAA0B,EAAE,MAAM,oCAAoC,CAAC;AACrF,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,6BAA6B,CAAC;AAExE;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AACH,MAAM,WAAW,sBAAsB,CAAC,IAAI,SAAS,OAAO,EAAE,WAAW,GAAG,OAAO,CAAE,SAAQ,IAAI,CAC9F,kBAAkB,CAAC,IAAI,EAAE,WAAW,CAAC,EACnC,MAAM,GACN,OAAO,GACP,QAAQ,GACR,QAAQ,GACR,MAAM,GACN,UAAU,GACV,QAAQ,GACR,gBAAgB,GAChB,WAAW,GACX,aAAa,GACb,kBAAkB,CACtB;IACE,QAAQ,CAAC,WAAW,EAAE,GAAG,CAAC,MAAM,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC;IAE/C;;;;;;;;;;;;;;;;;;;;;;;;;;;;;OA6BG;IACH,UAAU,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,uBAAuB,CAAC,IAAI,EAAE,WAAW,CAAC,GAAG,MAAM,CAAC;IAEnF;;;;;;OAMG;IACH,mBAAmB,CAAC,GAAG,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;CAC5C;AAED,wBAAgB,0BAA0B,CAAC,IAAI,SAAS,OAAO,EAAE,WAAW,GAAG,OAAO,EACnF,aAAa,EAAE,0BAA0B,EACzC,UAAU,EAAE,IAAI,CAAC,0BAA0B,EAAE,WAAW,CAAC,EACzD,SAAS,CAAC,EAAE,oBAAoB,CAAC,IAAI,EAAE,WAAW,CAAC,GACnD,sBAAsB,CAAC,IAAI,EAAE,WAAW,CAAC,CA8G3C"}
|
|
@@ -114,11 +114,8 @@ export function makeStubAstDocumentManager(textDocuments, fileSystem, documents)
|
|
|
114
114
|
getDocument(uri) {
|
|
115
115
|
return documents?.getDocument(UriUtils.toUri(uri));
|
|
116
116
|
},
|
|
117
|
-
|
|
118
|
-
return notSupported('
|
|
119
|
-
},
|
|
120
|
-
async readFile(uri) {
|
|
121
|
-
return notSupported(`readFile(${uri})`);
|
|
117
|
+
isTriggeringEdit() {
|
|
118
|
+
return notSupported('isTriggeringEdit');
|
|
122
119
|
}
|
|
123
120
|
};
|
|
124
121
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"stub-ast-document-manager.js","sourceRoot":"","sources":["../../src/testing/stub-ast-document-manager.ts"],"names":[],"mappings":"AAAA;;;;;;;kFAOkF;AAElF,OAAO,EAAsC,QAAQ,EAAE,MAAM,oBAAoB,CAAC;AAClF,OAAO,EAAE,UAAU,EAAE,MAAM,uBAAuB,CAAC;
|
|
1
|
+
{"version":3,"file":"stub-ast-document-manager.js","sourceRoot":"","sources":["../../src/testing/stub-ast-document-manager.ts"],"names":[],"mappings":"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"}
|
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
********************************************************************************/
|
|
9
9
|
import type { TransferDiagnostic, TransferElement } from '@hydranium/protocol';
|
|
10
10
|
import type { AstNode } from '@hydranium/langium';
|
|
11
|
-
import { ModelService, type ModelServiceOptions } from '../langium/model-service/model-service.js';
|
|
11
|
+
import { type ModelService, type ModelServiceOptions } from '../langium/model-service/model-service.js';
|
|
12
12
|
import type { ServerSharedServices } from '../langium/module.js';
|
|
13
13
|
/** The type of the model-service test double produced by {@link makeStubModelService}. */
|
|
14
14
|
export type StubModelService<TAst extends AstNode, TDiagnostic extends TransferDiagnostic = TransferDiagnostic, TTransfer extends TransferElement = TransferElement> = ModelService<TAst, TDiagnostic, TTransfer>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"stub-model-service.d.ts","sourceRoot":"","sources":["../../src/testing/stub-model-service.ts"],"names":[],"mappings":"AAAA;;;;;;;kFAOkF;AAElF,OAAO,KAAK,EAAE,kBAAkB,EAAE,eAAe,EAAE,MAAM,qBAAqB,CAAC;AAC/E,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,oBAAoB,CAAC;AAClD,OAAO,
|
|
1
|
+
{"version":3,"file":"stub-model-service.d.ts","sourceRoot":"","sources":["../../src/testing/stub-model-service.ts"],"names":[],"mappings":"AAAA;;;;;;;kFAOkF;AAElF,OAAO,KAAK,EAAE,kBAAkB,EAAE,eAAe,EAAE,MAAM,qBAAqB,CAAC;AAC/E,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,oBAAoB,CAAC;AAClD,OAAO,EAAuB,KAAK,YAAY,EAAE,KAAK,mBAAmB,EAAE,MAAM,2CAA2C,CAAC;AAC7H,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,sBAAsB,CAAC;AA2BjE,0FAA0F;AAC1F,MAAM,MAAM,gBAAgB,CACzB,IAAI,SAAS,OAAO,EACpB,WAAW,SAAS,kBAAkB,GAAG,kBAAkB,EAC3D,SAAS,SAAS,eAAe,GAAG,eAAe,IAClD,YAAY,CAAC,IAAI,EAAE,WAAW,EAAE,SAAS,CAAC,CAAC;AAE/C;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,oBAAoB,CACjC,IAAI,SAAS,OAAO,EACpB,WAAW,SAAS,kBAAkB,GAAG,kBAAkB,EAC3D,SAAS,SAAS,eAAe,GAAG,eAAe,EAEnD,QAAQ,EAAE,oBAAoB,EAC9B,SAAS,EAAE,CAAC,GAAG,EAAE,MAAM,EAAE,IAAI,EAAE,SAAS,KAAK,MAAM,EACnD,OAAO,CAAC,EAAE,mBAAmB,GAC7B,gBAAgB,CAAC,IAAI,EAAE,WAAW,EAAE,SAAS,CAAC,CAEhD"}
|
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
*
|
|
7
7
|
* SPDX-License-Identifier: MIT
|
|
8
8
|
********************************************************************************/
|
|
9
|
-
import {
|
|
9
|
+
import { DefaultModelService } from '../langium/model-service/model-service.js';
|
|
10
10
|
/**
|
|
11
11
|
* Implementation detail of {@link makeStubModelService}. A {@link ModelService}
|
|
12
12
|
* subclass that takes `serialize` as a constructor callback — the test stub
|
|
@@ -14,7 +14,7 @@ import { ModelService } from '../langium/model-service/model-service.js';
|
|
|
14
14
|
* path would fail. Construct it through the factory; the {@link StubModelService}
|
|
15
15
|
* type alias is the public type name.
|
|
16
16
|
*/
|
|
17
|
-
class StubModelServiceImpl extends
|
|
17
|
+
class StubModelServiceImpl extends DefaultModelService {
|
|
18
18
|
serializeFn;
|
|
19
19
|
constructor(services, serializeFn, options) {
|
|
20
20
|
super(services, options);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"stub-model-service.js","sourceRoot":"","sources":["../../src/testing/stub-model-service.ts"],"names":[],"mappings":"AAAA;;;;;;;kFAOkF;AAIlF,OAAO,EAAE,
|
|
1
|
+
{"version":3,"file":"stub-model-service.js","sourceRoot":"","sources":["../../src/testing/stub-model-service.ts"],"names":[],"mappings":"AAAA;;;;;;;kFAOkF;AAIlF,OAAO,EAAE,mBAAmB,EAA+C,MAAM,2CAA2C,CAAC;AAG7H;;;;;;GAMG;AACH,MAAM,oBAIJ,SAAQ,mBAAiD;IAGlC;IAFtB,YACG,QAA8B,EACX,WAAqD,EACxE,OAA6B;QAE7B,KAAK,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;QAHN,gBAAW,GAAX,WAAW,CAA0C;IAI3E,CAAC;IAEkB,SAAS,CAAC,GAAW,EAAE,IAAe;QACtD,OAAO,IAAI,CAAC,WAAW,CAAC,GAAG,EAAE,IAAI,CAAC,CAAC;IACtC,CAAC;CACH;AASD;;;;;;;;;;;;;;GAcG;AACH,MAAM,UAAU,oBAAoB,CAKjC,QAA8B,EAC9B,SAAmD,EACnD,OAA6B;IAE7B,OAAO,IAAI,oBAAoB,CAA+B,QAAQ,EAAE,SAAS,EAAE,OAAO,CAAC,CAAC;AAC/F,CAAC"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@hydranium/core",
|
|
3
|
-
"version": "1.0.0-next.
|
|
3
|
+
"version": "1.0.0-next.38",
|
|
4
4
|
"description": "Foundational runtime of the hydranium framework: AST coordination layer (services, integrity, AST extension, serialization, multi-client documents) plus the LSP textual head at the /lsp subpath. Consumed by protocol-head packages (@hydranium/data-server, @hydranium/glsp-server).",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"hydranium",
|
|
@@ -104,8 +104,8 @@
|
|
|
104
104
|
"diff": "^5.2.0"
|
|
105
105
|
},
|
|
106
106
|
"devDependencies": {
|
|
107
|
-
"@hydranium/langium": "1.0.0-next.
|
|
108
|
-
"@hydranium/protocol": "1.0.0-next.
|
|
107
|
+
"@hydranium/langium": "1.0.0-next.38",
|
|
108
|
+
"@hydranium/protocol": "1.0.0-next.38",
|
|
109
109
|
"@playwright/test": "^1.40.0",
|
|
110
110
|
"@types/diff": "^5.2.0",
|
|
111
111
|
"rimraf": "^5.0.0",
|
|
@@ -117,8 +117,8 @@
|
|
|
117
117
|
"vscode-languageserver-types": "^3.17.5"
|
|
118
118
|
},
|
|
119
119
|
"peerDependencies": {
|
|
120
|
-
"@hydranium/langium": "1.0.0-next.
|
|
121
|
-
"@hydranium/protocol": "1.0.0-next.
|
|
120
|
+
"@hydranium/langium": "1.0.0-next.38",
|
|
121
|
+
"@hydranium/protocol": "1.0.0-next.38",
|
|
122
122
|
"@playwright/test": "^1.40.0",
|
|
123
123
|
"vscode-jsonrpc": "9.0.1",
|
|
124
124
|
"vscode-languageserver": "~10.0.1",
|
|
@@ -166,6 +166,51 @@ export type AstDocumentSavedEvent<TAst extends AstNode, TDiagnostic> = TransferS
|
|
|
166
166
|
/** Construction options for {@link AstDocumentManager}. */
|
|
167
167
|
export type AstDocumentManagerOptions = LogNameOptions;
|
|
168
168
|
|
|
169
|
+
/**
|
|
170
|
+
* The document slot the model server and the integrity service talk to:
|
|
171
|
+
* open/close/update/save plus the AST-typed event streams, with the LSP
|
|
172
|
+
* plumbing hidden.
|
|
173
|
+
*
|
|
174
|
+
* Generic over `<TAst extends AstNode, TDiagnostic>` so each consumer projects
|
|
175
|
+
* its own AST root type and diagnostic shape into the emitted
|
|
176
|
+
* {@link AstDocument} envelopes.
|
|
177
|
+
*
|
|
178
|
+
* **URI contract.** Every URI-accepting member takes a URI in *any* spelling
|
|
179
|
+
* (canonical, symlinked, `..`/case-divergent) and canonicalizes internally
|
|
180
|
+
* through the {@link DocumentUriPolicy}, so a caller never has to canonicalize
|
|
181
|
+
* first and an implementation may not require it.
|
|
182
|
+
*/
|
|
183
|
+
export interface AstDocumentManager<TAst extends AstNode, TDiagnostic = unknown> {
|
|
184
|
+
open(args: OpenModelArgs): Promise<Disposable>;
|
|
185
|
+
close(args: CloseModelArgs): Promise<void>;
|
|
186
|
+
isOpen(uri: string): boolean;
|
|
187
|
+
|
|
188
|
+
/** Apply `text` as `clientId`'s edit. Resolves to the resulting text-document version. */
|
|
189
|
+
update(uri: string, text: string, clientId: string): Promise<number>;
|
|
190
|
+
save(uri: string, clientId: string): Promise<void>;
|
|
191
|
+
|
|
192
|
+
onUpdate(uri: string, listener: (event: AstDocumentUpdatedEvent<TAst, TDiagnostic>) => void): Disposable;
|
|
193
|
+
onSave(uri: string, listener: (event: AstDocumentSavedEvent<TAst, TDiagnostic>) => void | Promise<void>): Disposable;
|
|
194
|
+
onClientClosed(uri: string, clientId: string, listener: () => void): Disposable;
|
|
195
|
+
|
|
196
|
+
getDocument(uri: string): LangiumDocument | undefined;
|
|
197
|
+
|
|
198
|
+
/** Client id that authored the document's current version, or `undefined` for a framework-internal build. */
|
|
199
|
+
getAuthor(document: LangiumDocument): string | undefined;
|
|
200
|
+
|
|
201
|
+
/**
|
|
202
|
+
* Whether `uri` is one of the URIs the most recent build request named, as
|
|
203
|
+
* opposed to a document that build swept in as a dependent. Deletions are
|
|
204
|
+
* excluded: they never reach this layer, since a deleted document is
|
|
205
|
+
* removed before the build set is computed.
|
|
206
|
+
*
|
|
207
|
+
* The answer refers to the latest request, which may still be building, and
|
|
208
|
+
* it is retained between builds — so outside a build it describes whichever
|
|
209
|
+
* one ran last.
|
|
210
|
+
*/
|
|
211
|
+
isTriggeringEdit(uri: string): boolean;
|
|
212
|
+
}
|
|
213
|
+
|
|
169
214
|
/**
|
|
170
215
|
* Higher-level facade over {@link HydraniumTextDocuments} that speaks the
|
|
171
216
|
* model-server protocol (open/close/update/save with the transfer-model event
|
|
@@ -186,7 +231,7 @@ export type AstDocumentManagerOptions = LogNameOptions;
|
|
|
186
231
|
* resolution (the egress `applyEditToLanguageClient`) stay on
|
|
187
232
|
* {@link HydraniumTextDocuments}, their owner.
|
|
188
233
|
*/
|
|
189
|
-
export class
|
|
234
|
+
export class DefaultAstDocumentManager<TAst extends AstNode, TDiagnostic = unknown> implements AstDocumentManager<TAst, TDiagnostic> {
|
|
190
235
|
protected lastUpdate?: UpdateInfo;
|
|
191
236
|
|
|
192
237
|
protected readonly textDocuments: HydraniumTextDocuments<TextDocument>;
|
|
@@ -334,7 +379,7 @@ export class AstDocumentManager<TAst extends AstNode = AstNode, TDiagnostic = un
|
|
|
334
379
|
* concrete value (the `onUpdate` event's `sourceClientId`, the data-server's
|
|
335
380
|
* `resolveSourceClientId`).
|
|
336
381
|
*/
|
|
337
|
-
getAuthor(document: LangiumDocument
|
|
382
|
+
getAuthor(document: LangiumDocument): string | undefined {
|
|
338
383
|
return this.textDocuments.getAuthor(document.textDocument.uri, document.textDocument.version);
|
|
339
384
|
}
|
|
340
385
|
|
|
@@ -414,8 +459,7 @@ export class AstDocumentManager<TAst extends AstNode = AstNode, TDiagnostic = un
|
|
|
414
459
|
return !!this.textDocuments.get(uri);
|
|
415
460
|
}
|
|
416
461
|
|
|
417
|
-
|
|
418
|
-
isDirectChange(uri: string): boolean {
|
|
462
|
+
isTriggeringEdit(uri: string): boolean {
|
|
419
463
|
const canonical = this.uriPolicy.canonicalUri(uri);
|
|
420
464
|
return this.lastUpdate?.changed.some(changed => this.uriPolicy.canonicalUri(changed) === canonical) ?? false;
|
|
421
465
|
}
|
|
@@ -437,11 +481,7 @@ export class AstDocumentManager<TAst extends AstNode = AstNode, TDiagnostic = un
|
|
|
437
481
|
version = 0,
|
|
438
482
|
text?: string
|
|
439
483
|
): Promise<TextDocumentItem> {
|
|
440
|
-
return { uri, languageId, version, text: text ?? (await this.readFile(uri)) };
|
|
441
|
-
}
|
|
442
|
-
|
|
443
|
-
async readFile(uri: string): Promise<string> {
|
|
444
|
-
return this.fileSystemProvider.readFile(UriUtils.toUri(uri));
|
|
484
|
+
return { uri, languageId, version, text: text ?? (await this.fileSystemProvider.readFile(UriUtils.toUri(uri))) };
|
|
445
485
|
}
|
|
446
486
|
|
|
447
487
|
/**
|
|
@@ -644,18 +644,20 @@ export class HydraniumTextDocuments<T extends TextDocument = TextDocument> exten
|
|
|
644
644
|
if (this.isOpenInClient(uri, clientId)) {
|
|
645
645
|
// Already open for this client under this canonical identity. If this is a
|
|
646
646
|
// NEW client-facing URI for the same file (a second tab reached via a
|
|
647
|
-
// divergent path, e.g. a symlink and its real path), record it
|
|
648
|
-
//
|
|
649
|
-
//
|
|
647
|
+
// divergent path, e.g. a symlink and its real path), record it so outbound
|
|
648
|
+
// edits reach this tab too — but do NOT re-fire open/rebuild; the document
|
|
649
|
+
// is already live.
|
|
650
650
|
if (clientId === LANGUAGE_CLIENT_ID) {
|
|
651
651
|
const clientFacing = this.toLanguageClientUri(td.uri);
|
|
652
652
|
const record = this.__documents.get(uri);
|
|
653
653
|
if (record && !record.languageClientUris?.has(clientFacing)) {
|
|
654
654
|
(record.languageClientUris ??= new Set<LanguageClientUri>()).add(clientFacing);
|
|
655
|
-
|
|
656
|
-
|
|
657
|
-
|
|
658
|
-
|
|
655
|
+
// This tab's own buffer, NOT the synced text: a second tab is a second
|
|
656
|
+
// client model, read from disk, so a server-authored write already
|
|
657
|
+
// applied to the first tab leaves it BEHIND the synced document. Keying
|
|
658
|
+
// a diff to the synced text here addresses lines this tab does not have
|
|
659
|
+
// and drops content it does.
|
|
660
|
+
this.__shadow.setOpenedText(clientFacing, td.text);
|
|
659
661
|
}
|
|
660
662
|
}
|
|
661
663
|
return;
|
|
@@ -694,7 +696,18 @@ export class HydraniumTextDocuments<T extends TextDocument = TextDocument> exten
|
|
|
694
696
|
// Baseline the shadow to what Monaco just opened so the next outbound
|
|
695
697
|
// applyEditToLanguageClient diffs against the right starting point. Keyed by the
|
|
696
698
|
// language-client URI (what Monaco holds), not the canonical document key.
|
|
697
|
-
|
|
699
|
+
//
|
|
700
|
+
// The CLIENT's declared text, never the synced document: staged content
|
|
701
|
+
// consumed above leaves the two different, and a baseline asserting the
|
|
702
|
+
// client already holds the staged text suppresses the one sync that would
|
|
703
|
+
// deliver it. Skipped entirely when a push is already outstanding for this
|
|
704
|
+
// URI — an `applyEdit` to a closed file has the client open from disk and
|
|
705
|
+
// apply afterwards, so that shadow records what it is about to hold and
|
|
706
|
+
// disk text would key the next diff to a buffer nobody has.
|
|
707
|
+
const clientFacing = this.toLanguageClientUri(td.uri);
|
|
708
|
+
if (this.__shadow.get(clientFacing) === undefined) {
|
|
709
|
+
this.__shadow.set(clientFacing, td.text);
|
|
710
|
+
}
|
|
698
711
|
}
|
|
699
712
|
const toFire = Object.freeze({ document, clientId });
|
|
700
713
|
this.__onDidOpen.fire(toFire);
|
|
@@ -706,6 +719,14 @@ export class HydraniumTextDocuments<T extends TextDocument = TextDocument> exten
|
|
|
706
719
|
`Attach client: ${clientId} joined existing document (version ${document.version}, ` +
|
|
707
720
|
`now open in: ${[...existingClients, clientId].join(', ')})`
|
|
708
721
|
);
|
|
722
|
+
if (clientId === LANGUAGE_CLIENT_ID) {
|
|
723
|
+
// Monaco's own buffer, which on this path is NOT the synced text — another
|
|
724
|
+
// client opened the document and may already have changed it. Recorded as
|
|
725
|
+
// an equality-only baseline (never a diff one, see `setOpenedText`) so the
|
|
726
|
+
// refresh below does not push a full replace of content Monaco already
|
|
727
|
+
// holds, which would dirty the file on open.
|
|
728
|
+
this.__shadow.setOpenedText(this.toLanguageClientUri(td.uri), td.text);
|
|
729
|
+
}
|
|
709
730
|
this.refreshContent(uri, clientId);
|
|
710
731
|
}
|
|
711
732
|
}
|
|
@@ -57,12 +57,23 @@ export function isFullReplace(edits: readonly TextEdit[]): boolean {
|
|
|
57
57
|
* - {@link computeEdits} after each outgoing server→client sync (updates the shadow optimistically).
|
|
58
58
|
* - {@link set} when the server receives a `didChange` from the language client (the client now
|
|
59
59
|
* holds that text; we shouldn't resend it).
|
|
60
|
+
* - {@link setOpenedText} when the client opens a document the server did not baseline for it —
|
|
61
|
+
* an equality-only baseline, since that text is a snapshot rather than a tracked one.
|
|
60
62
|
* - {@link invalidate} when the client rejects an edit (`applied=false`) or a doc is closed —
|
|
61
63
|
* the shadow is now stale and the next sync must fall back to a full replace.
|
|
62
64
|
*/
|
|
63
65
|
export class LanguageClientTextShadow {
|
|
64
66
|
protected shadow = new Map<string, string>();
|
|
65
67
|
|
|
68
|
+
/**
|
|
69
|
+
* Per URI, the text the client declared it opened the document with, held
|
|
70
|
+
* only until a real baseline exists. Consulted by {@link computeEdits} when
|
|
71
|
+
* there is no shadow, and dropped on {@link invalidate}: a snapshot that
|
|
72
|
+
* outlived what the client holds would let the equality check skip an edit
|
|
73
|
+
* the client still needs.
|
|
74
|
+
*/
|
|
75
|
+
protected opened = new Map<string, string>();
|
|
76
|
+
|
|
66
77
|
/**
|
|
67
78
|
* @param onFallback invoked when {@link computeEdits} falls back to a full-range replace due to
|
|
68
79
|
* apply-verify mismatch. Useful for logging regressions.
|
|
@@ -84,6 +95,20 @@ export class LanguageClientTextShadow {
|
|
|
84
95
|
this.shadow.set(uri, text);
|
|
85
96
|
}
|
|
86
97
|
|
|
98
|
+
/**
|
|
99
|
+
* Record the buffer the language client declared at `didOpen`, for a URI
|
|
100
|
+
* with no baseline yet.
|
|
101
|
+
*
|
|
102
|
+
* Deliberately NOT a {@link set}: this text is only ever compared for
|
|
103
|
+
* EQUALITY, never diffed against. A line-keyed diff is position-dependent,
|
|
104
|
+
* so keying one to a `didOpen` snapshot the client may have moved past
|
|
105
|
+
* splices its buffer — the failure {@link computeEdits}'s full-replace
|
|
106
|
+
* fallback exists to avoid.
|
|
107
|
+
*/
|
|
108
|
+
setOpenedText(uri: string, text: string): void {
|
|
109
|
+
this.opened.set(uri, text);
|
|
110
|
+
}
|
|
111
|
+
|
|
87
112
|
/**
|
|
88
113
|
* The text the language client is believed to hold, or `undefined` when
|
|
89
114
|
* there is no baseline (first sync, or after an {@link invalidate}).
|
|
@@ -102,6 +127,11 @@ export class LanguageClientTextShadow {
|
|
|
102
127
|
/** Forget the shadow for a URI; next {@link computeEdits} falls back to a full-document replace. */
|
|
103
128
|
invalidate(uri: string): void {
|
|
104
129
|
this.shadow.delete(uri);
|
|
130
|
+
// Drops the opened snapshot too, and this is the only place that has to:
|
|
131
|
+
// `computeEdits` clears it whenever it consults it, so the sole way it can
|
|
132
|
+
// outlive what the client holds is surviving under a live shadow until that
|
|
133
|
+
// shadow is dropped here.
|
|
134
|
+
this.opened.delete(uri);
|
|
105
135
|
}
|
|
106
136
|
|
|
107
137
|
/**
|
|
@@ -109,7 +139,9 @@ export class LanguageClientTextShadow {
|
|
|
109
139
|
* the tracked shadow to `newText`. Updates the shadow to `newText` so subsequent calls diff
|
|
110
140
|
* against it.
|
|
111
141
|
*
|
|
112
|
-
* - Empty array when the shadow already equals `newText` (caller should skip the RPC)
|
|
142
|
+
* - Empty array when the shadow already equals `newText` (caller should skip the RPC),
|
|
143
|
+
* or when there is no shadow and the client opened the document with exactly `newText`
|
|
144
|
+
* (see {@link setOpenedText}) — pushing it anyway dirties the client's buffer on open.
|
|
113
145
|
* - Full-range replace when there is no shadow (first sync or post-{@link invalidate}).
|
|
114
146
|
* - Line-level diff otherwise. Before returning, we locally reconstruct `newText` by applying
|
|
115
147
|
* the diff to `old`; if that doesn't match, we fall back to a full-range replace and notify
|
|
@@ -124,7 +156,11 @@ export class LanguageClientTextShadow {
|
|
|
124
156
|
this.shadow.set(uri, newText);
|
|
125
157
|
const fullReplace: TextEdit = { range: FULL_RANGE, newText };
|
|
126
158
|
if (old === undefined) {
|
|
127
|
-
|
|
159
|
+
// The opened snapshot has served its purpose either way: the shadow above
|
|
160
|
+
// is now the baseline, so leaving it would only risk a later stale match.
|
|
161
|
+
const openedText = this.opened.get(uri);
|
|
162
|
+
this.opened.delete(uri);
|
|
163
|
+
return openedText === newText ? [] : [fullReplace];
|
|
128
164
|
}
|
|
129
165
|
const edits = diffToEdits(old, newText);
|
|
130
166
|
const verifyDoc = this.documents.create(uri, 'plaintext', 0, old);
|
|
@@ -22,10 +22,32 @@ export interface SelfSaveRegistryOptions {
|
|
|
22
22
|
/**
|
|
23
23
|
* Tracks `mtime` of files written by the server itself so the echo
|
|
24
24
|
* `didChangeWatchedFiles` event from the OS file watcher can be suppressed,
|
|
25
|
-
* avoiding redundant rebuilds after each save.
|
|
26
|
-
* (not by a time window) and expire after a TTL.
|
|
25
|
+
* avoiding redundant rebuilds after each save.
|
|
27
26
|
*/
|
|
28
|
-
export
|
|
27
|
+
export interface SelfSaveRegistry {
|
|
28
|
+
/**
|
|
29
|
+
* Record a self-write, and drop any registration already past its TTL.
|
|
30
|
+
*
|
|
31
|
+
* Keyed by `fsPath` rather than URI string, because the two sides of a
|
|
32
|
+
* suppression see different URI forms for one file.
|
|
33
|
+
*/
|
|
34
|
+
register(fsPath: string, mtimeMs: number): void;
|
|
35
|
+
|
|
36
|
+
/**
|
|
37
|
+
* Whether `fsPath` carries a live registration at exactly `mtimeMs`.
|
|
38
|
+
*
|
|
39
|
+
* A registration expires after the TTL, so a write recorded longer ago than
|
|
40
|
+
* that answers `false` — the caller's decision holds only while the echo it
|
|
41
|
+
* suppresses could still be in flight. A query never mutates the registry.
|
|
42
|
+
*/
|
|
43
|
+
isRegistered(fsPath: string, mtimeMs: number): boolean;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
/**
|
|
47
|
+
* Compares entries by mtime rather than by a time window, so the echo of a
|
|
48
|
+
* save whose content is unchanged is still recognised.
|
|
49
|
+
*/
|
|
50
|
+
export class DefaultSelfSaveRegistry implements SelfSaveRegistry {
|
|
29
51
|
protected readonly entries = new Map<string, { mtimeMs: number; registeredAt: number }>();
|
|
30
52
|
/**
|
|
31
53
|
* Read time through the shared {@link Clock} rather than `Date.now()`: the
|
|
@@ -59,23 +81,40 @@ export class SelfSaveRegistry {
|
|
|
59
81
|
return isCaseInsensitiveFileSystem() ? fsPath.toLowerCase() : fsPath;
|
|
60
82
|
}
|
|
61
83
|
|
|
62
|
-
/** Record a self-write. Key by `fsPath` (not URI string) to avoid URI-form mismatches. */
|
|
63
84
|
register(fsPath: string, mtimeMs: number): void {
|
|
85
|
+
this.evictExpired();
|
|
64
86
|
this.entries.set(this.key(fsPath), { mtimeMs, registeredAt: this.clock.now() });
|
|
65
87
|
}
|
|
66
88
|
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
const entry = this.entries.get(key);
|
|
71
|
-
if (!entry) {
|
|
72
|
-
return false;
|
|
73
|
-
}
|
|
74
|
-
if (this.clock.now() - entry.registeredAt > this.ttlMs) {
|
|
75
|
-
this.entries.delete(key);
|
|
89
|
+
isRegistered(fsPath: string, mtimeMs: number): boolean {
|
|
90
|
+
const entry = this.entries.get(this.key(fsPath));
|
|
91
|
+
if (!entry || this.isExpired(entry.registeredAt)) {
|
|
76
92
|
return false;
|
|
77
93
|
}
|
|
78
94
|
// Accept mtime equality (some filesystems have 1-second precision).
|
|
79
95
|
return entry.mtimeMs === mtimeMs;
|
|
80
96
|
}
|
|
97
|
+
|
|
98
|
+
/**
|
|
99
|
+
* Drop every expired registration.
|
|
100
|
+
*
|
|
101
|
+
* On the WRITE path, so the query stays free of side effects. Evicting from
|
|
102
|
+
* the query instead reaches only the keys something happens to ask about,
|
|
103
|
+
* and a path written once and never queried again is then retained for the
|
|
104
|
+
* life of the process. Bounded by the paths self-written inside one TTL
|
|
105
|
+
* window, so the sweep is over a handful of entries and sits behind a file
|
|
106
|
+
* write either way.
|
|
107
|
+
*/
|
|
108
|
+
protected evictExpired(): void {
|
|
109
|
+
for (const [key, entry] of this.entries) {
|
|
110
|
+
if (this.isExpired(entry.registeredAt)) {
|
|
111
|
+
this.entries.delete(key);
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
/** Strictly greater, so an entry aged exactly to the TTL is still eligible. */
|
|
117
|
+
protected isExpired(registeredAt: number): boolean {
|
|
118
|
+
return this.clock.now() - registeredAt > this.ttlMs;
|
|
119
|
+
}
|
|
81
120
|
}
|
package/src/index.ts
CHANGED
|
@@ -36,5 +36,9 @@ export * from './langium/service-registry.js';
|
|
|
36
36
|
export * from './langium/language-types.js';
|
|
37
37
|
export * from './launcher/index.js';
|
|
38
38
|
export * from './locale/index.js';
|
|
39
|
+
// The renderer only. The `./messages` subpath additionally enumerates this
|
|
40
|
+
// package's own declarations, which the root barrel already re-exports through
|
|
41
|
+
// the modules that raise them.
|
|
42
|
+
export * from './messages/renderer.js';
|
|
39
43
|
export * from './documents/index.js';
|
|
40
44
|
export * from './util/index.js';
|
package/src/langium/bootstrap.ts
CHANGED
|
@@ -12,15 +12,15 @@ import { type LangiumSharedCoreServices } from '@hydranium/langium';
|
|
|
12
12
|
import { type LangiumServices, type LangiumSharedServices } from '@hydranium/langium/lsp';
|
|
13
13
|
import type { ServerSharedServicesMinimal } from './shared-services.js';
|
|
14
14
|
import { collectProducibleTypes } from './language-types.js';
|
|
15
|
-
import {
|
|
15
|
+
import { DefaultAstDocumentManager } from '../documents/ast-document-manager.js';
|
|
16
16
|
import { HydraniumTextDocuments } from '../documents/hydranium-text-documents.js';
|
|
17
|
-
import {
|
|
17
|
+
import { DefaultBuildPipelineIntegration } from './document-builder/build-pipeline-integration.js';
|
|
18
18
|
import { HydraniumDocumentBuilder } from './document-builder/document-builder.js';
|
|
19
|
-
import {
|
|
19
|
+
import { DefaultModelService } from './model-service/model-service.js';
|
|
20
20
|
import { HydraniumScopeComputation } from './scope/hydranium-scope-computation.js';
|
|
21
21
|
import { HydraniumScopeProvider } from './scope/hydranium-scope-provider.js';
|
|
22
22
|
import { processEnv } from '../util/environment.js';
|
|
23
|
-
import {
|
|
23
|
+
import { DefaultTransferEncoder } from './transfer/transfer-encoder.js';
|
|
24
24
|
import { HydraniumWorkspaceManager } from './workspace/hydranium-workspace-manager.js';
|
|
25
25
|
|
|
26
26
|
/**
|
|
@@ -206,17 +206,17 @@ const STRICT_SHARED_SLOTS: readonly StrictSlot[] = [
|
|
|
206
206
|
{
|
|
207
207
|
side: 'shared',
|
|
208
208
|
path: 'workspace.AstDocumentManager',
|
|
209
|
-
base:
|
|
209
|
+
base: DefaultAstDocumentManager,
|
|
210
210
|
get: s => nested(s, 'workspace', 'AstDocumentManager')
|
|
211
211
|
},
|
|
212
212
|
{
|
|
213
213
|
side: 'shared',
|
|
214
214
|
path: 'workspace.BuildPipelineIntegration',
|
|
215
|
-
base:
|
|
215
|
+
base: DefaultBuildPipelineIntegration,
|
|
216
216
|
get: s => nested(s, 'workspace', 'BuildPipelineIntegration')
|
|
217
217
|
},
|
|
218
|
-
{ side: 'shared', path: 'model.TransferEncoder', base:
|
|
219
|
-
{ side: 'shared', path: 'model.ModelService', base:
|
|
218
|
+
{ side: 'shared', path: 'model.TransferEncoder', base: DefaultTransferEncoder, get: s => nested(s, 'model', 'TransferEncoder') },
|
|
219
|
+
{ side: 'shared', path: 'model.ModelService', base: DefaultModelService, get: s => nested(s, 'model', 'ModelService') }
|
|
220
220
|
];
|
|
221
221
|
|
|
222
222
|
const STRICT_LANGUAGE_SLOTS: readonly StrictSlot[] = [
|
|
@@ -65,6 +65,19 @@ export interface BuildPipelineIntegrationOptions {
|
|
|
65
65
|
readonly integrityPriority?: number;
|
|
66
66
|
}
|
|
67
67
|
|
|
68
|
+
/**
|
|
69
|
+
* The build-pipeline slot. Empty because nothing calls this service — it wires
|
|
70
|
+
* itself in its constructor and every seam it offers is `protected`.
|
|
71
|
+
*
|
|
72
|
+
* Typing the slot by the class instead would stop an adopter's subclass
|
|
73
|
+
* satisfying it, since a class carries its `protected` members into the check
|
|
74
|
+
* and they compare by declaration rather than by shape. The cost of the empty
|
|
75
|
+
* shape is that any non-null value satisfies it, so a mis-bound slot compiles
|
|
76
|
+
* and the framework's phase listeners are then never attached.
|
|
77
|
+
*/
|
|
78
|
+
// eslint-disable-next-line @typescript-eslint/no-empty-object-type -- the slot has no public member to name
|
|
79
|
+
export interface BuildPipelineIntegration {}
|
|
80
|
+
|
|
68
81
|
/**
|
|
69
82
|
* Wires the framework's build-time features (integrity rules, AST
|
|
70
83
|
* enrichment) into Langium's document-build pipeline. The single shared
|
|
@@ -90,7 +103,7 @@ export interface BuildPipelineIntegrationOptions {
|
|
|
90
103
|
* Eagerly constructed (via `DEFAULT_EAGER_SERVICES`) so the listeners are
|
|
91
104
|
* attached before the first build cycle.
|
|
92
105
|
*/
|
|
93
|
-
export class BuildPipelineIntegration {
|
|
106
|
+
export class DefaultBuildPipelineIntegration implements BuildPipelineIntegration {
|
|
94
107
|
constructor(
|
|
95
108
|
protected readonly services: ServerSharedServices,
|
|
96
109
|
options: BuildPipelineIntegrationOptions = {}
|
|
@@ -26,7 +26,7 @@ import {
|
|
|
26
26
|
// restating it.
|
|
27
27
|
import { CancellationToken, Diagnostic } from 'vscode-languageserver-protocol';
|
|
28
28
|
import { type LogNameOptions } from '../diagnostics/logger.js';
|
|
29
|
-
import type {
|
|
29
|
+
import type { MessageRenderer } from '../../messages/renderer.js';
|
|
30
30
|
import { CST_REHYDRATION_RESET_STATE, isCstShed } from '../residency/cst-residency-service.js';
|
|
31
31
|
import { type ExtendedServiceRegistry } from '../service-registry.js';
|
|
32
32
|
import { type ServerSharedServicesMinimal } from '../shared-services.js';
|
|
@@ -158,7 +158,7 @@ export class HydraniumDocumentBuilder extends DefaultDocumentBuilder {
|
|
|
158
158
|
protected readonly phaseDetailMs: ObservableValue<number>;
|
|
159
159
|
protected readonly uriPolicy: DocumentUriPolicy;
|
|
160
160
|
protected readonly clock: Clock;
|
|
161
|
-
protected readonly messageRenderer:
|
|
161
|
+
protected readonly messageRenderer: MessageRenderer;
|
|
162
162
|
/** Narrower handle on the same registry as the inherited `serviceRegistry`, for {@link ExtendedServiceRegistry.registrations}. */
|
|
163
163
|
protected readonly languageRegistry: ExtendedServiceRegistry;
|
|
164
164
|
protected languageFileExtensions: string[] = [];
|
|
@@ -104,7 +104,7 @@ export interface IntegrationServicesOptions<
|
|
|
104
104
|
*
|
|
105
105
|
* Both differences are the point, and neither is served by
|
|
106
106
|
* {@link extra}. Most framework shared services are constructed with
|
|
107
|
-
* no options (`ModelService: services => new
|
|
107
|
+
* no options (`ModelService: services => new DefaultModelService(services)`),
|
|
108
108
|
* so rebinding the slot is the only way to boot one configured
|
|
109
109
|
* differently; a caller that needs that is usually a test, and the slot
|
|
110
110
|
* it needs is as often a framework ADDITION (`Clock`, `Tracer`,
|