@hydranium/core 1.0.0-next.117 → 1.0.0-next.123
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 +8 -44
- package/lib/documents/ast-document-manager.d.ts.map +1 -1
- package/lib/documents/ast-document-manager.js +22 -41
- package/lib/documents/ast-document-manager.js.map +1 -1
- package/lib/documents/client-session-errors.d.ts +4 -33
- package/lib/documents/client-session-errors.d.ts.map +1 -1
- package/lib/documents/client-session-errors.js +4 -46
- package/lib/documents/client-session-errors.js.map +1 -1
- package/lib/documents/client-session-registry.d.ts +40 -20
- package/lib/documents/client-session-registry.d.ts.map +1 -1
- package/lib/documents/client-session-registry.js +33 -20
- package/lib/documents/client-session-registry.js.map +1 -1
- package/lib/documents/file-system-task-queue.d.ts +49 -0
- package/lib/documents/file-system-task-queue.d.ts.map +1 -0
- package/lib/documents/file-system-task-queue.js +34 -0
- package/lib/documents/file-system-task-queue.js.map +1 -0
- package/lib/documents/hydranium-text-documents.d.ts +138 -13
- package/lib/documents/hydranium-text-documents.d.ts.map +1 -1
- package/lib/documents/hydranium-text-documents.js +283 -40
- package/lib/documents/hydranium-text-documents.js.map +1 -1
- package/lib/documents/index.d.ts +1 -0
- package/lib/documents/index.d.ts.map +1 -1
- package/lib/documents/index.js +1 -0
- package/lib/documents/index.js.map +1 -1
- package/lib/langium/document-builder/document-builder.d.ts +15 -2
- package/lib/langium/document-builder/document-builder.d.ts.map +1 -1
- package/lib/langium/document-builder/document-builder.js +15 -2
- package/lib/langium/document-builder/document-builder.js.map +1 -1
- package/lib/langium/integrity/integrity-service.d.ts +3 -2
- package/lib/langium/integrity/integrity-service.d.ts.map +1 -1
- package/lib/langium/integrity/integrity-service.js +9 -6
- package/lib/langium/integrity/integrity-service.js.map +1 -1
- package/lib/langium/language-module.d.ts +2 -2
- package/lib/langium/language-module.js +2 -2
- package/lib/langium/language-module.js.map +1 -1
- package/lib/langium/model-service/client-session.d.ts +203 -24
- package/lib/langium/model-service/client-session.d.ts.map +1 -1
- package/lib/langium/model-service/client-session.js +233 -29
- package/lib/langium/model-service/client-session.js.map +1 -1
- package/lib/langium/model-service/model-service.d.ts +62 -217
- package/lib/langium/model-service/model-service.d.ts.map +1 -1
- package/lib/langium/model-service/model-service.js +54 -357
- package/lib/langium/model-service/model-service.js.map +1 -1
- package/lib/langium/module.d.ts +11 -1
- package/lib/langium/module.d.ts.map +1 -1
- package/lib/langium/module.js +5 -1
- package/lib/langium/module.js.map +1 -1
- package/lib/langium/update-rewrite/update-rewrite.d.ts +1 -1
- package/lib/langium/workspace/in-memory-file-system-provider.d.ts.map +1 -1
- package/lib/langium/workspace/in-memory-file-system-provider.js +10 -2
- package/lib/langium/workspace/in-memory-file-system-provider.js.map +1 -1
- package/lib/langium/workspace/write-lock-scope.d.ts +1 -1
- package/lib/langium/workspace/write-lock-scope.js +1 -1
- package/lib/lsp/hydranium-document-update-handler.d.ts +69 -67
- package/lib/lsp/hydranium-document-update-handler.d.ts.map +1 -1
- package/lib/lsp/hydranium-document-update-handler.js +111 -89
- package/lib/lsp/hydranium-document-update-handler.js.map +1 -1
- package/lib/lsp/shared-module.d.ts +4 -8
- package/lib/lsp/shared-module.d.ts.map +1 -1
- package/lib/lsp/shared-module.js.map +1 -1
- package/lib/lsp/start-language-server.d.ts +3 -4
- package/lib/lsp/start-language-server.d.ts.map +1 -1
- package/lib/lsp/start-language-server.js +3 -4
- package/lib/lsp/start-language-server.js.map +1 -1
- package/lib/testing/make-test-services.d.ts +16 -4
- package/lib/testing/make-test-services.d.ts.map +1 -1
- package/lib/testing/make-test-services.js +6 -2
- package/lib/testing/make-test-services.js.map +1 -1
- package/lib/testing/node/lsp-server-connection.d.ts +1 -1
- package/lib/testing/node/scratch-workspace.js +1 -1
- package/lib/testing/run-update-pipeline.d.ts +4 -4
- package/lib/testing/run-update-pipeline.d.ts.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 +6 -8
- package/lib/testing/stub-ast-document-manager.js.map +1 -1
- package/lib/testing/stub-hydranium-text-documents.d.ts +10 -5
- package/lib/testing/stub-hydranium-text-documents.d.ts.map +1 -1
- package/lib/testing/stub-hydranium-text-documents.js +16 -9
- package/lib/testing/stub-hydranium-text-documents.js.map +1 -1
- package/lib/testing/stub-model-service.d.ts +2 -2
- package/lib/testing/stub-model-service.js +2 -2
- package/package.json +5 -5
- package/src/documents/ast-document-manager.ts +27 -78
- package/src/documents/client-session-errors.ts +11 -43
- package/src/documents/client-session-registry.ts +54 -28
- package/src/documents/file-system-task-queue.ts +68 -0
- package/src/documents/hydranium-text-documents.ts +348 -44
- package/src/documents/index.ts +1 -0
- package/src/langium/document-builder/document-builder.ts +16 -2
- package/src/langium/integrity/integrity-service.ts +9 -6
- package/src/langium/language-module.ts +4 -4
- package/src/langium/model-service/client-session.ts +363 -39
- package/src/langium/model-service/model-service.ts +91 -420
- package/src/langium/module.ts +14 -2
- package/src/langium/update-rewrite/update-rewrite.ts +1 -1
- package/src/langium/workspace/in-memory-file-system-provider.ts +11 -2
- package/src/langium/workspace/write-lock-scope.ts +1 -1
- package/src/lsp/hydranium-document-update-handler.ts +138 -92
- package/src/lsp/shared-module.ts +4 -8
- package/src/lsp/start-language-server.ts +3 -4
- package/src/testing/make-test-services.ts +25 -6
- package/src/testing/node/lsp-server-connection.ts +1 -1
- package/src/testing/node/scratch-workspace.ts +1 -1
- package/src/testing/run-update-pipeline.ts +4 -4
- package/src/testing/stub-ast-document-manager.ts +10 -24
- package/src/testing/stub-hydranium-text-documents.ts +29 -16
- package/src/testing/stub-model-service.ts +2 -2
|
@@ -22,14 +22,14 @@ import type { StubLangiumDocuments } from './stub-langium-documents.js';
|
|
|
22
22
|
|
|
23
23
|
/**
|
|
24
24
|
* Minimal stub of {@link AstDocumentManager} for use in test
|
|
25
|
-
* harnesses. Implements just the methods the
|
|
26
|
-
*
|
|
27
|
-
* `
|
|
25
|
+
* harnesses. Implements just the methods the model service and client
|
|
26
|
+
* sessions call (`open` / `close` / `update` / `save` / `isOpen` /
|
|
27
|
+
* `getDocument`);
|
|
28
28
|
* `onSave` / `onClientClosed` forward to the underlying stub text store,
|
|
29
29
|
* `onUpdate` is driven explicitly
|
|
30
30
|
* through {@link StubAstDocumentManager.emitUpdate} because the stub tree runs
|
|
31
31
|
* no build phases to emit from, and the remaining read helpers
|
|
32
|
-
* (`
|
|
32
|
+
* (`getAuthor`) throw if invoked — tests that need them
|
|
33
33
|
* should wire a richer stub or use the real {@link AstDocumentManager}.
|
|
34
34
|
*
|
|
35
35
|
* Open state is tracked per URI as the set of holding client ids, so a
|
|
@@ -48,18 +48,7 @@ import type { StubLangiumDocuments } from './stub-langium-documents.js';
|
|
|
48
48
|
*/
|
|
49
49
|
export interface StubAstDocumentManager<TAst extends AstNode, TDiagnostic extends AstDiagnostic = AstDiagnostic> extends Pick<
|
|
50
50
|
AstDocumentManager<TAst, TDiagnostic>,
|
|
51
|
-
| '
|
|
52
|
-
| 'close'
|
|
53
|
-
| 'isOpen'
|
|
54
|
-
| 'update'
|
|
55
|
-
| 'save'
|
|
56
|
-
| 'queueDiskTask'
|
|
57
|
-
| 'onUpdate'
|
|
58
|
-
| 'onSave'
|
|
59
|
-
| 'onClientClosed'
|
|
60
|
-
| 'getAuthor'
|
|
61
|
-
| 'getDocument'
|
|
62
|
-
| 'isTriggeringEdit'
|
|
51
|
+
'open' | 'close' | 'isOpen' | 'update' | 'save' | 'onUpdate' | 'onSave' | 'onClientClosed' | 'getAuthor' | 'getDocument'
|
|
63
52
|
> {
|
|
64
53
|
readonly openClients: Map<string, Set<string>>;
|
|
65
54
|
|
|
@@ -132,10 +121,13 @@ export function makeStubAstDocumentManager<TAst extends AstNode, TDiagnostic ext
|
|
|
132
121
|
clients.add(args.clientId);
|
|
133
122
|
openClients.set(args.uri, clients);
|
|
134
123
|
// The real `open` materialises the synced document (from the payload
|
|
135
|
-
// text or the filesystem)
|
|
136
|
-
//
|
|
124
|
+
// text or the filesystem), or attaches the client to the one that is
|
|
125
|
+
// there; mirror both so a subsequent `update` finds the document open
|
|
126
|
+
// for this client.
|
|
137
127
|
if (!textDocuments.get(args.uri)) {
|
|
138
128
|
textDocuments.seedOpen(args.uri, args.text ?? '', args.clientId);
|
|
129
|
+
} else {
|
|
130
|
+
textDocuments.attachClient(args.uri, args.clientId);
|
|
139
131
|
}
|
|
140
132
|
return Disposable.create(() => close({ uri: args.uri, clientId: args.clientId }));
|
|
141
133
|
},
|
|
@@ -153,9 +145,6 @@ export function makeStubAstDocumentManager<TAst extends AstNode, TDiagnostic ext
|
|
|
153
145
|
await fileSystem.writeFile(UriUtils.toUri(uri), text);
|
|
154
146
|
textDocuments.notifyDidSaveTextDocument({ textDocument: { uri }, text }, clientId);
|
|
155
147
|
},
|
|
156
|
-
queueDiskTask<T>(_uri: string, task: () => Promise<T>): Promise<T> {
|
|
157
|
-
return task();
|
|
158
|
-
},
|
|
159
148
|
// Registers the listener but never calls it by itself — the real manager
|
|
160
149
|
// emits from a `DocumentBuilder.onDocumentPhase(Validated)` hook and the
|
|
161
150
|
// stub tree runs no phases. `emitUpdate` is the only thing that fires it;
|
|
@@ -217,9 +206,6 @@ export function makeStubAstDocumentManager<TAst extends AstNode, TDiagnostic ext
|
|
|
217
206
|
// that need real symlink canonicalization wire the real AstDocumentManager).
|
|
218
207
|
getDocument(uri: string): LangiumDocument | undefined {
|
|
219
208
|
return documents?.getDocument(UriUtils.toUri(uri));
|
|
220
|
-
},
|
|
221
|
-
isTriggeringEdit(): boolean {
|
|
222
|
-
return notSupported('isTriggeringEdit');
|
|
223
209
|
}
|
|
224
210
|
};
|
|
225
211
|
}
|
|
@@ -9,11 +9,11 @@
|
|
|
9
9
|
|
|
10
10
|
import type { CanonicalUri } from '@hydranium/protocol';
|
|
11
11
|
import type { ApplyWorkspaceEditResult } from 'vscode-languageserver';
|
|
12
|
-
import { Disposable } from 'vscode-languageserver';
|
|
12
|
+
import { Disposable, Emitter } from 'vscode-languageserver';
|
|
13
13
|
import type { TextDocument } from 'vscode-languageserver-textdocument';
|
|
14
14
|
import { LANGUAGE_CLIENT_ID } from '../documents/client-ids.js';
|
|
15
15
|
import { ClientSessionRegistry } from '../documents/client-session-registry.js';
|
|
16
|
-
import type { ClientTextDocumentChangeEvent, HydraniumTextDocuments } from '../documents/hydranium-text-documents.js';
|
|
16
|
+
import type { ClientTextDocumentChangeEvent, HydraniumTextDocuments, LastOpenClosedEvent } from '../documents/hydranium-text-documents.js';
|
|
17
17
|
|
|
18
18
|
/** Snapshot of an open document tracked by the stub. */
|
|
19
19
|
export interface StubTextDocumentEntry {
|
|
@@ -28,11 +28,12 @@ export interface StubTextDocumentEntry {
|
|
|
28
28
|
* reads from on test paths — the content channel
|
|
29
29
|
* (`notifyDidChangeTextDocument` / `applyContentChange` / `version` /
|
|
30
30
|
* `getAuthor`), the open-state probes (`isOpenInLanguageClient` /
|
|
31
|
-
* `isOpenInAnyClient` / `isOpenInClient` / `
|
|
31
|
+
* `isOpenInAnyClient` / `isOpenInClient` / `isRevertPending` /
|
|
32
|
+
* `openDocuments`), the push channel
|
|
32
33
|
* to the language client (`applyEditToLanguageClient` / `stagePendingContent`),
|
|
33
34
|
* the save / close notifications, and the client-session table
|
|
34
|
-
* (`registerSession` / `closeSession` / `onDidCloseSession`
|
|
35
|
-
*
|
|
35
|
+
* (`registerSession` / `closeSession` / `onDidCloseSession`), which is a real
|
|
36
|
+
* `ClientSessionRegistry` — plus test-only helpers:
|
|
36
37
|
*
|
|
37
38
|
* - {@link seedOpen} — pre-populate an open document without firing change
|
|
38
39
|
* events. Use to set up a baseline version before exercising an `update`.
|
|
@@ -69,15 +70,16 @@ export interface StubHydraniumTextDocuments extends Pick<
|
|
|
69
70
|
| 'getAuthor'
|
|
70
71
|
| 'isOpenInLanguageClient'
|
|
71
72
|
| 'isOpenInAnyClient'
|
|
73
|
+
| 'isRevertPending'
|
|
72
74
|
| 'applyEditToLanguageClient'
|
|
73
75
|
| 'stagePendingContent'
|
|
74
76
|
| 'openDocuments'
|
|
75
77
|
| 'isOpenInClient'
|
|
78
|
+
| 'attachClient'
|
|
76
79
|
| 'registerSession'
|
|
77
80
|
| 'closeSession'
|
|
78
81
|
| 'onDidCloseSession'
|
|
79
|
-
| '
|
|
80
|
-
| 'setOpenOptions'
|
|
82
|
+
| 'onDidCloseLastOpen'
|
|
81
83
|
> {
|
|
82
84
|
/**
|
|
83
85
|
* Stub-tailored read accessor. Returns just the surface the framework's
|
|
@@ -100,7 +102,11 @@ export interface StubHydraniumTextDocuments extends Pick<
|
|
|
100
102
|
seedOpen(uri: string, text: string, clientId: string): void;
|
|
101
103
|
/** Mark `uri` as open in the LSP textual language client (drives {@link isOpenInLanguageClient}). */
|
|
102
104
|
seedOpenInLanguageClient(uri: string): void;
|
|
103
|
-
/**
|
|
105
|
+
/**
|
|
106
|
+
* Synchronously deliver `onDidClose` to subscribers, then `onDidCloseLastOpen`
|
|
107
|
+
* when no client has `uri` open any more. The stub keeps no revert grace, so
|
|
108
|
+
* a last close is announced at once.
|
|
109
|
+
*/
|
|
104
110
|
fireClose(uri: string, clientId: string): void;
|
|
105
111
|
/**
|
|
106
112
|
* Drop recorded state. Useful for `beforeEach` resets.
|
|
@@ -140,11 +146,12 @@ export function makeStubHydraniumTextDocuments(): StubHydraniumTextDocuments {
|
|
|
140
146
|
let applyEditHandler: (uri: string, text: string) => ApplyWorkspaceEditResult | undefined = () => ({ applied: true });
|
|
141
147
|
const saveListeners: Array<(event: { document: { uri: string }; clientId: string }) => void> = [];
|
|
142
148
|
const closeListeners: Array<(event: ClientTextDocumentChangeEvent<TextDocument>) => void> = [];
|
|
143
|
-
// The real registry, so the session table, the opens
|
|
144
|
-
//
|
|
149
|
+
// The real registry, so the session table, the opens and the closing state
|
|
150
|
+
// behave as the store's do. The stub's plain-string keys
|
|
145
151
|
// stand in for canonical URIs (one stub-boundary cast, like `fireClose`).
|
|
146
152
|
const sessions = new ClientSessionRegistry();
|
|
147
153
|
const key = (uri: string): CanonicalUri => uri as CanonicalUri;
|
|
154
|
+
const lastOpenClosed = new Emitter<LastOpenClosedEvent>();
|
|
148
155
|
|
|
149
156
|
const stub: StubHydraniumTextDocuments = {
|
|
150
157
|
get changes() {
|
|
@@ -230,6 +237,12 @@ export function makeStubHydraniumTextDocuments(): StubHydraniumTextDocuments {
|
|
|
230
237
|
isOpenInClient(uri, clientId) {
|
|
231
238
|
return sessions.isOpenIn(key(uri), clientId);
|
|
232
239
|
},
|
|
240
|
+
isRevertPending(uri) {
|
|
241
|
+
return sessions.isRevertPending(key(uri));
|
|
242
|
+
},
|
|
243
|
+
attachClient(uri, clientId) {
|
|
244
|
+
return docs.has(uri) && sessions.addOpen(key(uri), clientId);
|
|
245
|
+
},
|
|
233
246
|
registerSession(clientId) {
|
|
234
247
|
sessions.register(clientId);
|
|
235
248
|
},
|
|
@@ -248,11 +261,8 @@ export function makeStubHydraniumTextDocuments(): StubHydraniumTextDocuments {
|
|
|
248
261
|
get onDidCloseSession() {
|
|
249
262
|
return sessions.onDidCloseSession;
|
|
250
263
|
},
|
|
251
|
-
|
|
252
|
-
return
|
|
253
|
-
},
|
|
254
|
-
setOpenOptions(uri, clientId, options) {
|
|
255
|
-
sessions.setOpenOptions(key(uri), clientId, options);
|
|
264
|
+
get onDidCloseLastOpen() {
|
|
265
|
+
return lastOpenClosed.event;
|
|
256
266
|
},
|
|
257
267
|
openDocuments() {
|
|
258
268
|
// From the registry that also answers `isOpenInClient`, which both
|
|
@@ -285,7 +295,7 @@ export function makeStubHydraniumTextDocuments(): StubHydraniumTextDocuments {
|
|
|
285
295
|
if (holder && holder.clientId === clientId) {
|
|
286
296
|
docs.delete(uri);
|
|
287
297
|
}
|
|
288
|
-
sessions.removeOpen(key(uri), clientId);
|
|
298
|
+
const removed = sessions.removeOpen(key(uri), clientId);
|
|
289
299
|
if (clientId === LANGUAGE_CLIENT_ID) {
|
|
290
300
|
languageClientOpen.delete(uri);
|
|
291
301
|
}
|
|
@@ -293,6 +303,9 @@ export function makeStubHydraniumTextDocuments(): StubHydraniumTextDocuments {
|
|
|
293
303
|
for (const listener of closeListeners.slice()) {
|
|
294
304
|
listener(event);
|
|
295
305
|
}
|
|
306
|
+
if (removed && !sessions.isOpen(key(uri))) {
|
|
307
|
+
lastOpenClosed.fire({ uri: key(uri) });
|
|
308
|
+
}
|
|
296
309
|
},
|
|
297
310
|
reset() {
|
|
298
311
|
docs.clear();
|
|
@@ -53,8 +53,8 @@ export type StubModelService<
|
|
|
53
53
|
* `makeTestServices` wires this stub automatically.
|
|
54
54
|
*
|
|
55
55
|
* `options` are the framework {@link ModelServiceOptions}, forwarded verbatim, so
|
|
56
|
-
* a test can exercise an option-gated code path (`serializeBuilds
|
|
57
|
-
*
|
|
56
|
+
* a test can exercise an option-gated code path (`serializeBuilds`) without
|
|
57
|
+
* hand-rolling a subclass just to reach the constructor.
|
|
58
58
|
*
|
|
59
59
|
* Adopters that need richer override behaviour — the framework's own extension
|
|
60
60
|
* surface is {@link ModelService.rewriteModel} alongside `serialize` — should
|