@hydranium/core 1.0.0-next.160 → 1.0.0-next.169
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/hydranium-text-documents.d.ts +60 -25
- package/lib/documents/hydranium-text-documents.d.ts.map +1 -1
- package/lib/documents/hydranium-text-documents.js +91 -34
- package/lib/documents/hydranium-text-documents.js.map +1 -1
- package/lib/langium/model-service/model-service.d.ts.map +1 -1
- package/lib/langium/model-service/model-service.js +5 -8
- package/lib/langium/model-service/model-service.js.map +1 -1
- package/lib/langium/workspace/hydranium-workspace-manager.d.ts +4 -0
- package/lib/langium/workspace/hydranium-workspace-manager.d.ts.map +1 -1
- package/lib/langium/workspace/hydranium-workspace-manager.js +13 -1
- package/lib/langium/workspace/hydranium-workspace-manager.js.map +1 -1
- package/package.json +5 -5
- package/src/documents/hydranium-text-documents.ts +125 -46
- package/src/langium/model-service/model-service.ts +5 -8
- package/src/langium/workspace/hydranium-workspace-manager.ts +21 -2
|
@@ -358,13 +358,10 @@ export class DefaultModelService<
|
|
|
358
358
|
// Deliberately NO fallback to Langium's `ready`: it resolves pre-build,
|
|
359
359
|
// so falling back to it would silently reinstate the very gap this gate
|
|
360
360
|
// exists to close.
|
|
361
|
-
// Captured rather than read off `this` inside the closure, which TS cannot
|
|
362
|
-
// prove runs after the field is assigned.
|
|
363
|
-
const tracer = this.tracer;
|
|
364
361
|
this.ready = (async () => {
|
|
365
362
|
try {
|
|
366
363
|
await services.workspace.WorkspaceManager?.workspaceInitialized;
|
|
367
|
-
} catch
|
|
364
|
+
} catch {
|
|
368
365
|
// NEVER rejects, deliberately. This gate is about TIMING — "the
|
|
369
366
|
// initial build has finished" — not about whether it succeeded, and
|
|
370
367
|
// Langium's `ready` (what it replaced) could not reject at all.
|
|
@@ -372,8 +369,8 @@ export class DefaultModelService<
|
|
|
372
369
|
// build (routine — any write preempts one) and on a failed one
|
|
373
370
|
// (e.g. a disposed connection at teardown). Propagating either would
|
|
374
371
|
// fail every `waitForReady` for the rest of the process lifetime,
|
|
375
|
-
// a far worse failure than the late gate this exists to fix.
|
|
376
|
-
|
|
372
|
+
// a far worse failure than the late gate this exists to fix. The
|
|
373
|
+
// workspace manager logs the outcome.
|
|
377
374
|
}
|
|
378
375
|
})();
|
|
379
376
|
// One persistent listener mirroring non-LSP-client changes back to the LSP
|
|
@@ -922,7 +919,7 @@ export class DefaultModelService<
|
|
|
922
919
|
try {
|
|
923
920
|
let result = await this.services.workspace.TextDocuments.applyEditToLanguageClient(uri, text, { label: this.editLabel() });
|
|
924
921
|
if (result?.applied === false && !this.pendingSync.has(uri)) {
|
|
925
|
-
// The push is addressed at the client's
|
|
922
|
+
// The push is addressed at the client's last known version, so a
|
|
926
923
|
// rejection normally means the client's buffer moved while the
|
|
927
924
|
// line-keyed diff was in flight — exactly the case where applying it
|
|
928
925
|
// would splice the file. Dropping the push there would leave the
|
|
@@ -940,7 +937,7 @@ export class DefaultModelService<
|
|
|
940
937
|
// `pendingSync` check skips the retry when a newer settle has already
|
|
941
938
|
// queued — best-effort, since a settle arriving later simply pushes
|
|
942
939
|
// after this and still wins.
|
|
943
|
-
uriLogger.
|
|
940
|
+
uriLogger.debug(`Re-pushing a full replace after the language client refused applyEdit`);
|
|
944
941
|
result = await this.services.workspace.TextDocuments.applyEditToLanguageClient(uri, text, { label: this.editLabel() });
|
|
945
942
|
if (result?.applied === false) {
|
|
946
943
|
uriLogger.warn(`Language client rejected the full-replace retry too — client content is stale`);
|
|
@@ -8,7 +8,15 @@
|
|
|
8
8
|
********************************************************************************/
|
|
9
9
|
|
|
10
10
|
import { Deferred, type Logger, type Tracer } from '@hydranium/protocol';
|
|
11
|
-
import {
|
|
11
|
+
import {
|
|
12
|
+
DefaultWorkspaceManager,
|
|
13
|
+
DocumentState,
|
|
14
|
+
isOperationCancelled,
|
|
15
|
+
type LangiumDocument,
|
|
16
|
+
type Stream,
|
|
17
|
+
UriUtils,
|
|
18
|
+
type URI
|
|
19
|
+
} from '@hydranium/langium';
|
|
12
20
|
import { type CancellationToken, type InitializeParams } from 'vscode-languageserver';
|
|
13
21
|
import type { WorkspaceFolder } from 'vscode-languageserver-types';
|
|
14
22
|
import { type LogNameOptions, resolveLogFilePlaceholder, toLogFileWorkspaceToken } from '../diagnostics/logger.js';
|
|
@@ -20,6 +28,7 @@ import type { WritableFileSystemProvider } from '../../documents/ast-document-ma
|
|
|
20
28
|
import { type DocumentUriPolicy, findRealpathDivergence } from './document-uri-policy.js';
|
|
21
29
|
import { type AdditionalDocumentContribution, collectAdditionalDocuments } from './additional-document-contribution.js';
|
|
22
30
|
import { onProcessEvent } from '../../util/environment.js';
|
|
31
|
+
import { isConnectionGoneError } from '../../util/connection-liveness.js';
|
|
23
32
|
|
|
24
33
|
/**
|
|
25
34
|
* Module-level guard so repeated workspace-manager construction (e.g.
|
|
@@ -488,12 +497,22 @@ export class HydraniumWorkspaceManager extends DefaultWorkspaceManager {
|
|
|
488
497
|
* and either delegate to `super.initializeWorkspace(...)` (preserving the
|
|
489
498
|
* default resolve) or call `this.workspaceInitializedDeferred.resolve(...)`
|
|
490
499
|
* themselves after the additional work finishes.
|
|
500
|
+
*
|
|
501
|
+
* A failed setup is logged here, since every framework waiter on
|
|
502
|
+
* {@link workspaceInitialized} discards the rejection; an override that
|
|
503
|
+
* rejects the deferred itself logs its own failure.
|
|
491
504
|
*/
|
|
492
505
|
override async initializeWorkspace(folders: WorkspaceFolder[], cancelToken?: CancellationToken): Promise<void> {
|
|
493
506
|
try {
|
|
494
507
|
await super.initializeWorkspace(folders, cancelToken);
|
|
495
508
|
this.workspaceInitializedDeferred.resolve(undefined);
|
|
496
|
-
} catch (error) {
|
|
509
|
+
} catch (error: unknown) {
|
|
510
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
511
|
+
if (isOperationCancelled(error) || isConnectionGoneError(error)) {
|
|
512
|
+
this.tracer.debug(`Initial workspace build did not complete: ${message}`);
|
|
513
|
+
} else {
|
|
514
|
+
this.tracer.error(`Initial workspace build failed: ${message}`);
|
|
515
|
+
}
|
|
497
516
|
this.workspaceInitializedDeferred.reject(error);
|
|
498
517
|
throw error;
|
|
499
518
|
}
|