@hydranium/core 1.0.0-next.199 → 1.0.0-next.201

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.
Files changed (92) hide show
  1. package/README.md +8 -7
  2. package/lib/documents/ast-document-manager.d.ts +2 -52
  3. package/lib/documents/ast-document-manager.d.ts.map +1 -1
  4. package/lib/documents/ast-document-manager.js.map +1 -1
  5. package/lib/documents/index.d.ts +0 -1
  6. package/lib/documents/index.d.ts.map +1 -1
  7. package/lib/documents/index.js +0 -1
  8. package/lib/documents/index.js.map +1 -1
  9. package/lib/langium/document-builder/document-builder.d.ts +10 -0
  10. package/lib/langium/document-builder/document-builder.d.ts.map +1 -1
  11. package/lib/langium/document-builder/document-builder.js +13 -0
  12. package/lib/langium/document-builder/document-builder.js.map +1 -1
  13. package/lib/langium/integrity/integrity-service.d.ts +1 -1
  14. package/lib/langium/integrity/integrity-service.d.ts.map +1 -1
  15. package/lib/langium/language-module.d.ts +2 -2
  16. package/lib/langium/language-module.d.ts.map +1 -1
  17. package/lib/langium/language-module.js +2 -2
  18. package/lib/langium/language-module.js.map +1 -1
  19. package/lib/langium/model-service/client-session.d.ts +21 -16
  20. package/lib/langium/model-service/client-session.d.ts.map +1 -1
  21. package/lib/langium/model-service/client-session.js +23 -37
  22. package/lib/langium/model-service/client-session.js.map +1 -1
  23. package/lib/langium/module.d.ts +3 -3
  24. package/lib/langium/module.d.ts.map +1 -1
  25. package/lib/langium/module.js +1 -1
  26. package/lib/langium/module.js.map +1 -1
  27. package/lib/langium/shared-services.d.ts +2 -2
  28. package/lib/langium/shared-services.d.ts.map +1 -1
  29. package/lib/langium/validation/validation-contribution-collector.d.ts +9 -1
  30. package/lib/langium/validation/validation-contribution-collector.d.ts.map +1 -1
  31. package/lib/langium/validation/validation-contribution-collector.js +1 -1
  32. package/lib/langium/validation/validation-contribution-collector.js.map +1 -1
  33. package/lib/langium/workspace/file-system-provider.d.ts +52 -2
  34. package/lib/langium/workspace/file-system-provider.d.ts.map +1 -1
  35. package/lib/langium/workspace/file-system-provider.js.map +1 -1
  36. package/lib/langium/workspace/hydranium-workspace-manager.d.ts +1 -1
  37. package/lib/langium/workspace/hydranium-workspace-manager.d.ts.map +1 -1
  38. package/lib/langium/workspace/in-memory-file-system-provider.d.ts +1 -1
  39. package/lib/langium/workspace/in-memory-file-system-provider.d.ts.map +1 -1
  40. package/lib/langium/workspace/index.d.ts +1 -0
  41. package/lib/langium/workspace/index.d.ts.map +1 -1
  42. package/lib/langium/workspace/index.js +1 -0
  43. package/lib/langium/workspace/index.js.map +1 -1
  44. package/lib/langium/workspace/persistent-file-system-provider.d.ts +1 -1
  45. package/lib/langium/workspace/persistent-file-system-provider.d.ts.map +1 -1
  46. package/lib/{documents → langium/workspace}/self-save-registry.d.ts +1 -1
  47. package/lib/langium/workspace/self-save-registry.d.ts.map +1 -0
  48. package/lib/{documents → langium/workspace}/self-save-registry.js +1 -1
  49. package/lib/langium/workspace/self-save-registry.js.map +1 -0
  50. package/lib/langium/workspace/virtual-document.d.ts +1 -1
  51. package/lib/langium/workspace/virtual-document.d.ts.map +1 -1
  52. package/lib/lsp/hydranium-document-update-handler.d.ts +2 -2
  53. package/lib/lsp/hydranium-document-update-handler.d.ts.map +1 -1
  54. package/lib/node/node-file-system-provider.d.ts +2 -2
  55. package/lib/node/node-file-system-provider.d.ts.map +1 -1
  56. package/lib/testing/stub-ast-document-manager.d.ts +2 -1
  57. package/lib/testing/stub-ast-document-manager.d.ts.map +1 -1
  58. package/lib/testing/stub-ast-document-manager.js.map +1 -1
  59. package/lib/testing/stub-document-builder.d.ts +2 -2
  60. package/lib/testing/stub-document-builder.d.ts.map +1 -1
  61. package/lib/testing/stub-document-builder.js +3 -0
  62. package/lib/testing/stub-document-builder.js.map +1 -1
  63. package/lib/testing/stub-self-save-registry.d.ts +1 -1
  64. package/lib/testing/stub-self-save-registry.d.ts.map +1 -1
  65. package/lib/testing/stub-writable-file-system.d.ts +1 -1
  66. package/lib/testing/stub-writable-file-system.d.ts.map +1 -1
  67. package/package.json +5 -5
  68. package/src/documents/ast-document-manager.ts +2 -61
  69. package/src/documents/index.ts +0 -1
  70. package/src/langium/document-builder/document-builder.ts +14 -0
  71. package/src/langium/integrity/integrity-service.ts +1 -1
  72. package/src/langium/language-module.ts +6 -3
  73. package/src/langium/model-service/client-session.ts +27 -45
  74. package/src/langium/module.ts +4 -3
  75. package/src/langium/shared-services.ts +2 -2
  76. package/src/langium/validation/validation-contribution-collector.ts +10 -1
  77. package/src/langium/workspace/file-system-provider.ts +53 -2
  78. package/src/langium/workspace/hydranium-workspace-manager.ts +1 -1
  79. package/src/langium/workspace/in-memory-file-system-provider.ts +1 -1
  80. package/src/langium/workspace/index.ts +1 -0
  81. package/src/langium/workspace/persistent-file-system-provider.ts +1 -1
  82. package/src/{documents → langium/workspace}/self-save-registry.ts +2 -2
  83. package/src/langium/workspace/virtual-document.ts +1 -1
  84. package/src/lsp/hydranium-document-update-handler.ts +2 -2
  85. package/src/node/node-file-system-provider.ts +2 -2
  86. package/src/testing/parse-semantic-root.ts +1 -1
  87. package/src/testing/stub-ast-document-manager.ts +2 -2
  88. package/src/testing/stub-document-builder.ts +4 -2
  89. package/src/testing/stub-self-save-registry.ts +1 -1
  90. package/src/testing/stub-writable-file-system.ts +1 -1
  91. package/lib/documents/self-save-registry.d.ts.map +0 -1
  92. package/lib/documents/self-save-registry.js.map +0 -1
@@ -19,13 +19,12 @@ import {
19
19
  type Tracer,
20
20
  type TransferElement
21
21
  } from '@hydranium/protocol';
22
- import { type AstNode, type DocumentBuilder, DocumentState, UriUtils } from '@hydranium/langium';
22
+ import { type AstNode, UriUtils } from '@hydranium/langium';
23
23
  import { type CancellationToken, type Disposable } from 'vscode-languageserver';
24
24
  import { type AstDocument, type SavedAstDocument } from '../../documents/ast-document-manager.js';
25
25
  import { DocumentNotOpenError, SessionClosedError } from '../../documents/client-session-errors.js';
26
26
  import { type OpenOptions, type SessionEndCause } from '../../documents/client-session-registry.js';
27
27
  import { type LogNameOptions } from '../diagnostics/logger.js';
28
- import { IntegrityService } from '../integrity/integrity-service.js';
29
28
  import { type ServerSharedServices } from '../module.js';
30
29
  import { type AstDiagnostic } from '../validation/document-validator.js';
31
30
  import { type ModelService } from './model-service.js';
@@ -118,11 +117,11 @@ export interface ClientSession<
118
117
  save(args: ClientSessionWriteArgs<TTransfer>, cancelToken?: CancellationToken): Promise<SavedAstDocument<TAst, TDiagnostic>>;
119
118
  /**
120
119
  * Persist the text the store holds for `args.uri` as it is, with no update
121
- * and no serialisation, and resolve to the document as {@link save} does.
122
- * The saved event names this session, also when another client wrote the
123
- * text.
120
+ * and no serialisation. Resolves with the version of the text written, once
121
+ * it is on disk, without waiting for a build. The saved event names this
122
+ * session, also when another client wrote the text.
124
123
  */
125
- persist(args: ClientSessionPersistArgs, cancelToken?: CancellationToken): Promise<SavedAstDocument<TAst, TDiagnostic>>;
124
+ persist(args: ClientSessionPersistArgs): Promise<TextVersion>;
126
125
  /** Close this session's open of `uri`, at once. A no-op when it does not have `uri` open. */
127
126
  close(uri: string): Promise<void>;
128
127
  /**
@@ -144,21 +143,6 @@ export interface ClientSession<
144
143
  dispose(cause?: SessionEndCause): void;
145
144
  }
146
145
 
147
- /**
148
- * The phase a session write waits for before it answers: `Validated`, or
149
- * {@link IntegrityService.SettledState} when rebuilds do not validate, since
150
- * no build then reaches `Validated` and the wait would never end. Read from
151
- * `updateBuildOptions`, which every rebuild takes; a document a
152
- * `shouldValidate` override skips is the builder's to resolve.
153
- *
154
- * Waiting for the write's own build is not enough: a later write cancels it,
155
- * and the build that takes over validates the document after the answer was
156
- * taken.
157
- */
158
- function answerState(builder: DocumentBuilder): DocumentState {
159
- return builder.updateBuildOptions.validation ? DocumentState.Validated : IntegrityService.SettledState;
160
- }
161
-
162
146
  /**
163
147
  * The framework's {@link ClientSession}, built by
164
148
  * {@link DefaultClientSessionFactory}.
@@ -256,9 +240,9 @@ export class DefaultClientSession<
256
240
  return this.saveDocument(args, cancelToken);
257
241
  }
258
242
 
259
- persist(args: ClientSessionPersistArgs, cancelToken?: CancellationToken): Promise<SavedAstDocument<TAst, TDiagnostic>> {
243
+ persist(args: ClientSessionPersistArgs): Promise<TextVersion> {
260
244
  this.assertLive();
261
- return this.persistDocument(args, cancelToken);
245
+ return this.persistDocument(args);
262
246
  }
263
247
 
264
248
  close(uri: string): Promise<void> {
@@ -328,7 +312,10 @@ export class DefaultClientSession<
328
312
  *
329
313
  * Resolves with the latest build of the document, which may already carry
330
314
  * a newer write; that is logged at debug, and a slow update at warn when
331
- * `ClientSessionFactoryOptions.slowUpdateWarnMs` is set.
315
+ * `ClientSessionFactoryOptions.slowUpdateWarnMs` is set. It waits for the
316
+ * builder's final phase rather than the write's own build: a later write
317
+ * cancels that build, and the one that takes over validates the document
318
+ * after the answer was taken.
332
319
  */
333
320
  protected async updateDocument(
334
321
  args: ClientSessionWriteArgs<TTransfer>,
@@ -353,7 +340,7 @@ export class DefaultClientSession<
353
340
  // An override that awaits before calling the base can outlast the build
354
341
  // this write already has, and then builds it twice; see
355
342
  // `ModelService.rebuild`.
356
- const doc = await run('rebuild', () => service.rebuild(uri, answerState(this.services.workspace.DocumentBuilder), cancelToken));
343
+ const doc = await run('rebuild', () => service.rebuild(uri, this.services.workspace.DocumentBuilder.finalBuildState(), cancelToken));
357
344
  const finalVersion = textDocuments.version(uri);
358
345
  if (finalVersion > appliedVersion) {
359
346
  this.tracer.debug(`Update to v${appliedVersion} ready at v${finalVersion} (changed again before it settled)`);
@@ -409,50 +396,45 @@ export class DefaultClientSession<
409
396
  check();
410
397
  const applied = uris.map((uri, i) => this.services.workspace.AstDocumentManager.update(uri, texts[i], this.clientId));
411
398
  await Promise.all(applied);
412
- const state = answerState(this.services.workspace.DocumentBuilder);
399
+ const state = this.services.workspace.DocumentBuilder.finalBuildState();
413
400
  return Promise.all(uris.map(uri => service.rebuild(uri, state, cancelToken)));
414
401
  }
415
402
 
416
403
  /**
417
- * Write `args.model` through {@link updateDocument}, so an override of it
418
- * applies to saves too, then persist the document.
404
+ * Write `args.model` through {@link updateDocument}, then persist it through
405
+ * {@link persistDocument}, so an override of either applies to saves too.
419
406
  *
420
407
  * Fails with `DocumentNotOpenError` and writes nothing when this session
421
- * closes the URI while the text is being built: the check sits in the same
422
- * synchronous step as the manager taking the text. Checked any earlier, a
423
- * session that closes the URI during the rebuild still has the shared
424
- * text, other clients' edits included, written in its name. Once taken,
425
- * the write completes whatever the session does next.
408
+ * closes the URI while the text is being built. Persisted at `'any'`: the
409
+ * update already gated on `args.baseVersion` and moved the text past it.
426
410
  */
427
411
  protected async saveDocument(
428
412
  args: ClientSessionWriteArgs<TTransfer>,
429
413
  cancelToken?: CancellationToken
430
414
  ): Promise<SavedAstDocument<TAst, TDiagnostic>> {
431
415
  const doc = await this.updateDocument(args, cancelToken);
432
- const uri = this.canonicalKey(args.uri);
433
- this.assertOpen(uri);
434
- const version = await this.services.workspace.AstDocumentManager.save(uri, this.clientId);
416
+ const version = await this.persistDocument({ uri: args.uri, baseVersion: 'any' });
435
417
  return { ...doc, persisted: { version } };
436
418
  }
437
419
 
438
420
  /**
439
- * Persist the store's text for `args.uri` under this session's id.
421
+ * Persist the store's text for `args.uri` under this session's id. Every
422
+ * write to disk a session makes goes through here, so an override sees each
423
+ * of them.
440
424
  *
441
425
  * The open check and the `baseVersion` gate sit in the same synchronous step
442
426
  * as the manager taking the text: an await between them lets another
443
427
  * client's write land after the gate, and its text is then persisted under
444
- * this session's id without this session ever having seen it.
428
+ * this session's id without this session ever having seen it. An override
429
+ * that awaits before calling the base lets a diagram save take its
430
+ * documents' texts at different moments, and a diagram that ends during the
431
+ * await fails the documents not yet taken with `DocumentNotOpenError`.
445
432
  */
446
- protected async persistDocument(
447
- args: ClientSessionPersistArgs,
448
- cancelToken?: CancellationToken
449
- ): Promise<SavedAstDocument<TAst, TDiagnostic>> {
433
+ protected async persistDocument(args: ClientSessionPersistArgs): Promise<TextVersion> {
450
434
  const uri = this.canonicalKey(args.uri);
451
435
  this.assertOpen(uri);
452
436
  this.assertBaseVersion(uri, args.baseVersion, this.services.workspace.TextDocuments.version(uri));
453
- const version = await this.services.workspace.AstDocumentManager.save(uri, this.clientId);
454
- const doc = await this.modelService.ensureDocumentState(uri, answerState(this.services.workspace.DocumentBuilder), cancelToken);
455
- return { ...doc, persisted: { version } };
437
+ return this.services.workspace.AstDocumentManager.save(uri, this.clientId);
456
438
  }
457
439
 
458
440
  protected async closeDocument(uri: string): Promise<void> {
@@ -34,15 +34,16 @@ import { type HydraniumDocumentRegistry, HydraniumLangiumDocuments } from './wor
34
34
  import { type AdditionalDocumentContribution } from './workspace/additional-document-contribution.js';
35
35
  import { DefaultDocumentUriPolicy, type DocumentUriPolicy } from './workspace/document-uri-policy.js';
36
36
  import { HydraniumTextDocuments } from '../documents/hydranium-text-documents.js';
37
- import { DefaultAstDocumentManager, type AstDocumentManager, type WritableFileSystemProvider } from '../documents/ast-document-manager.js';
38
- import { DefaultSelfSaveRegistry, type SelfSaveRegistry } from '../documents/self-save-registry.js';
37
+ import { DefaultAstDocumentManager, type AstDocumentManager } from '../documents/ast-document-manager.js';
38
+ import { DefaultSelfSaveRegistry, type SelfSaveRegistry } from './workspace/self-save-registry.js';
39
39
  import { DefaultFileSystemTaskQueue, type FileSystemTaskQueue } from '../documents/file-system-task-queue.js';
40
40
  import { DefaultModelLedger, type ModelLedger } from '../documents/model-ledger.js';
41
41
  import { DefaultVersionSyncService, type VersionSyncService } from '../documents/version-sync-service.js';
42
42
  import {
43
43
  DefaultEmptyFileSystemProvider,
44
44
  DefaultFileSystemProviderRegistry,
45
- type FileSystemProviderRegistry
45
+ type FileSystemProviderRegistry,
46
+ type WritableFileSystemProvider
46
47
  } from './workspace/file-system-provider.js';
47
48
  import { VIRTUAL_SCHEME, VirtualFileSystemProvider } from './workspace/virtual-document.js';
48
49
  import { type ServerLanguageServices } from './language-module.js';
@@ -11,10 +11,10 @@ import type { Clock, Logger, Project, Tracer } from '@hydranium/protocol';
11
11
  import type { LangiumSharedCoreServices } from '@hydranium/langium';
12
12
  import type { ServerLocale } from '../locale/server-locale.js';
13
13
  import type { MessageRenderer } from '../messages/renderer.js';
14
- import type { SelfSaveRegistry } from '../documents/self-save-registry.js';
14
+ import type { SelfSaveRegistry } from './workspace/self-save-registry.js';
15
15
  import type { ModelLedger } from '../documents/model-ledger.js';
16
16
  import type { VersionSyncService } from '../documents/version-sync-service.js';
17
- import type { WritableFileSystemProvider } from '../documents/ast-document-manager.js';
17
+ import type { WritableFileSystemProvider } from './workspace/file-system-provider.js';
18
18
  import type { HydraniumDocumentRegistry } from './workspace/langium-documents.js';
19
19
  import type { BuildPhasePassService } from './build-phase-pass/build-phase-pass-service.js';
20
20
  import type { CstResidencyService } from './residency/cst-residency-service.js';
@@ -15,6 +15,15 @@ import { type ValidationCheckRegistry } from './validation-contribution.js';
15
15
 
16
16
  export type ValidationContributionCollectorOptions = LogNameOptions;
17
17
 
18
+ /**
19
+ * The validation-collector slot. Empty because the service registers checks in
20
+ * its constructor and nothing calls it; typing the slot by the class would stop
21
+ * an adopter's subclass from a second package copy satisfying it. The cost: any
22
+ * non-null value satisfies it, so a mis-bound slot compiles and registers no check.
23
+ */
24
+ // eslint-disable-next-line @typescript-eslint/no-empty-object-type -- the slot has no public member to name
25
+ export interface ValidationContributionCollector {}
26
+
18
27
  /**
19
28
  * Per-language eager collector that wires `ValidationCheckContribution`s
20
29
  * declared under `services.validation.checks` into Langium's native
@@ -32,7 +41,7 @@ export type ValidationContributionCollectorOptions = LogNameOptions;
32
41
  * DI proxy. That is what gets the checks into the registry before Langium
33
42
  * reaches the `Validated` phase — nothing else constructs this service.
34
43
  */
35
- export class ValidationContributionCollector {
44
+ export class DefaultValidationContributionCollector implements ValidationContributionCollector {
36
45
  protected readonly tracer: Tracer;
37
46
 
38
47
  constructor(services: ServerLanguageServices, options: ValidationContributionCollectorOptions = {}) {
@@ -9,11 +9,62 @@
9
9
 
10
10
  import { type Tracer } from '@hydranium/protocol';
11
11
  import { EmptyFileSystemProvider } from '@hydranium/langium';
12
- import type { FileSystemNode, URI } from '@hydranium/langium';
13
- import { type WritableFileSystemProvider } from '../../documents/ast-document-manager.js';
12
+ import type { FileSystemNode, FileSystemProvider, URI } from '@hydranium/langium';
13
+ import { type SelfSaveRegistry } from './self-save-registry.js';
14
14
  import { type LogNameOptions } from '../diagnostics/logger.js';
15
15
  import { type ServerSharedServicesMinimal } from '../shared-services.js';
16
16
 
17
+ /**
18
+ * File-system provider extension that supports writes. Langium's standard
19
+ * {@link FileSystemProvider} is read-only; `AstDocumentManager` needs to persist
20
+ * saves, so consumers wire in a provider that implements this superset.
21
+ *
22
+ * Implementations may optionally hold a reference to a
23
+ * {@link SelfSaveRegistry} so they can record their own write mtimes and
24
+ * help downstream file-watchers suppress echo events for those writes.
25
+ * The framework's `DefaultFileSystemProvider` reads it from
26
+ * `services.workspace.SelfSaveRegistry`; alternative implementations can do
27
+ * the same or leave the field unset.
28
+ */
29
+ export interface WritableFileSystemProvider extends FileSystemProvider {
30
+ writeFile(uri: URI, content: string): Promise<void>;
31
+ /**
32
+ * Last-modified time (ms) of the file at `uri`, or `undefined` if it can't
33
+ * be determined (missing file, or a provider with no disk — in-memory /
34
+ * browser). Optional: the only consumer is self-save echo suppression
35
+ * (`didChangeWatchedFiles`), which simply lets a change through when the
36
+ * mtime is unavailable. Distinct from Langium's `stat` (whose
37
+ * `FileSystemNode` carries no mtime). Keeping disk access on the provider
38
+ * seam is what lets the LSP update handler avoid a direct `node:fs` import.
39
+ */
40
+ mtimeMs?(uri: URI): Promise<number | undefined>;
41
+ /**
42
+ * Resolve `uri` to its real on-disk identity (symlinks collapsed, `..`/`.`
43
+ * walked, case-folded on case-insensitive filesystems), or `undefined` *iff
44
+ * the filesystem knows the path is absent*. The single source of the
45
+ * "nothing loadable here" signal `RealpathDocumentUriPolicy` turns into
46
+ * the synthetic-placeholder branch of `getOrCreateDocument`.
47
+ *
48
+ * Contract for implementers:
49
+ * - A `file:`-backed provider returns the resolved URI when the file exists,
50
+ * and `undefined` when it cannot resolve the path (missing / unreadable).
51
+ * - A non-`file:` URI (or any URI the provider cannot stat) passes through
52
+ * **unchanged** — it is treated as present, never reported absent.
53
+ * - A provider with no disk to check (in-memory / browser / empty) simply
54
+ * omits this method; the framework's `FileSystemProviderRegistry` then
55
+ * returns the URI unchanged, and `RealpathDocumentUriPolicy` answers as
56
+ * the syntactic `DefaultDocumentUriPolicy` does.
57
+ *
58
+ * Synchronous (a `realpath` is a kernel-cached syscall) and optional — the
59
+ * only consumers are the document-identity policy's `canonicalUri`/`loadUri`.
60
+ * Keeping the syscall on the provider seam is what lets the policy stay
61
+ * browser-neutral (no `node:fs` import).
62
+ */
63
+ realpath?(uri: URI): URI | undefined;
64
+ /** Registry the provider records its own writes against. Optional — providers without watcher integration may omit. */
65
+ readonly selfSaveRegistry?: SelfSaveRegistry;
66
+ }
67
+
17
68
  /**
18
69
  * Empty-filesystem {@link WritableFileSystemProvider}. For browser / test / CLI
19
70
  * hosts that don't have a real filesystem. All writes are no-ops. On the
@@ -24,7 +24,7 @@ import type { ServerLocale } from '../../locale/server-locale.js';
24
24
  import type { ProjectChangeEvent } from '../project/project-change-event.js';
25
25
  import type { ProjectManager } from '../project/project-manager.js';
26
26
  import type { ServerSharedServicesMinimal } from '../shared-services.js';
27
- import type { WritableFileSystemProvider } from '../../documents/ast-document-manager.js';
27
+ import type { WritableFileSystemProvider } from './file-system-provider.js';
28
28
  import { type DocumentUriPolicy, findRealpathDivergence } from './document-uri-policy.js';
29
29
  import { type AdditionalDocumentContribution, collectAdditionalDocuments } from './additional-document-contribution.js';
30
30
  import { onProcessEvent } from '../../util/environment.js';
@@ -9,7 +9,7 @@
9
9
 
10
10
  import { type FileSystemNode, URI } from '@hydranium/langium';
11
11
  import { defineMessage, type Tracer } from '@hydranium/protocol';
12
- import { type WritableFileSystemProvider } from '../../documents/ast-document-manager.js';
12
+ import { type WritableFileSystemProvider } from './file-system-provider.js';
13
13
  import { type LogNameOptions } from '../diagnostics/logger.js';
14
14
  import { serverSharedFactory, type ServerSharedServicesMinimal } from '../shared-services.js';
15
15
  import { notFound } from './file-not-found.js';
@@ -11,6 +11,7 @@ export * from './document-uri-policy.js';
11
11
  export * from './file-system-provider.js';
12
12
  export * from './in-memory-file-system-provider.js';
13
13
  export * from './persistent-file-system-provider.js';
14
+ export * from './self-save-registry.js';
14
15
  export * from './index-manager.js';
15
16
  export * from './initialize-workspace.js';
16
17
  export * from './langium-documents.js';
@@ -8,7 +8,7 @@
8
8
  ********************************************************************************/
9
9
 
10
10
  import { URI } from '@hydranium/langium';
11
- import { type WritableFileSystemProvider } from '../../documents/ast-document-manager.js';
11
+ import { type WritableFileSystemProvider } from './file-system-provider.js';
12
12
  import { serverSharedFactory, type ServerSharedServicesMinimal } from '../shared-services.js';
13
13
  import { type FileSystemSeed, InMemoryFileSystemProvider, type InMemoryFileSystemOptions } from './in-memory-file-system-provider.js';
14
14
 
@@ -8,8 +8,8 @@
8
8
  ********************************************************************************/
9
9
 
10
10
  import { type Clock } from '@hydranium/protocol';
11
- import { isCaseInsensitiveFileSystem } from '../util/environment.js';
12
- import { type ServerSharedServicesMinimal } from '../langium/shared-services.js';
11
+ import { isCaseInsensitiveFileSystem } from '../../util/environment.js';
12
+ import { type ServerSharedServicesMinimal } from '../shared-services.js';
13
13
 
14
14
  /** Default eligibility window for a self-save entry. */
15
15
  const DEFAULT_TTL_MS = 30_000;
@@ -9,7 +9,7 @@
9
9
 
10
10
  import { type FileSystemNode, URI } from '@hydranium/langium';
11
11
  import { type Tracer } from '@hydranium/protocol';
12
- import { type WritableFileSystemProvider } from '../../documents/ast-document-manager.js';
12
+ import { type WritableFileSystemProvider } from './file-system-provider.js';
13
13
  import { type LogNameOptions } from '../diagnostics/logger.js';
14
14
  import { type ServerSharedServicesMinimal } from '../shared-services.js';
15
15
  import { NO_SUCH_FILE, NO_SUCH_PATH, UNSUPPORTED_WRITE } from './in-memory-file-system-provider.js';
@@ -13,8 +13,8 @@ import { DefaultDocumentUpdateHandler } from '@hydranium/langium/lsp';
13
13
  import { HYDRANIUM_BUILD_REASONS, type HydraniumDocumentBuilder } from '../langium/document-builder/document-builder.js';
14
14
  import { type ServerSharedServices } from '../langium/module.js';
15
15
  import { LANGUAGE_CLIENT_ID } from '../documents/client-ids.js';
16
- import { type SelfSaveRegistry } from '../documents/self-save-registry.js';
17
- import { type WritableFileSystemProvider } from '../documents/ast-document-manager.js';
16
+ import { type SelfSaveRegistry } from '../langium/workspace/self-save-registry.js';
17
+ import { type WritableFileSystemProvider } from '../langium/workspace/file-system-provider.js';
18
18
  import { type HydraniumTextDocuments } from '../documents/hydranium-text-documents.js';
19
19
  import { isConnectionGoneError } from '../util/connection-liveness.js';
20
20
  import {
@@ -13,8 +13,8 @@ import { NodeFileSystemProvider } from '@hydranium/langium/node';
13
13
  import { randomUUID } from 'node:crypto';
14
14
  import { realpathSync } from 'node:fs';
15
15
  import * as fsp from 'node:fs/promises';
16
- import { type WritableFileSystemProvider } from '../documents/ast-document-manager.js';
17
- import { type SelfSaveRegistry } from '../documents/self-save-registry.js';
16
+ import { type WritableFileSystemProvider } from '../langium/workspace/file-system-provider.js';
17
+ import { type SelfSaveRegistry } from '../langium/workspace/self-save-registry.js';
18
18
  import { renameOverOpenReaders } from './rename-over-open-readers.js';
19
19
  import { type LogNameOptions } from '../langium/diagnostics/logger.js';
20
20
  import { serverSharedFactory, type ServerSharedServicesMinimal } from '../langium/shared-services.js';
@@ -55,7 +55,7 @@
55
55
 
56
56
  import { type AstNode, AstUtils, type LangiumCoreServices, URI } from '@hydranium/langium';
57
57
  import { type ParseHelperOptions, parseHelper } from '@hydranium/langium/test';
58
- import type { WritableFileSystemProvider } from '../documents/ast-document-manager.js';
58
+ import type { WritableFileSystemProvider } from '../langium/workspace/file-system-provider.js';
59
59
 
60
60
  /** The one field this module reads off a lexer or parser error. */
61
61
  interface ParseErrorMessage {
@@ -14,9 +14,9 @@ import {
14
14
  AstDocument,
15
15
  type AstDocumentManager,
16
16
  type AstDocumentUpdatedEvent,
17
- type UpdateAttribution,
18
- type WritableFileSystemProvider
17
+ type UpdateAttribution
19
18
  } from '../documents/ast-document-manager.js';
19
+ import { type WritableFileSystemProvider } from '../langium/workspace/file-system-provider.js';
20
20
  import { UNKNOWN_CLIENT_ID } from '../documents/client-ids.js';
21
21
  import { DefaultModelLedger, type ModelLedger } from '../documents/model-ledger.js';
22
22
  import { type CloseModelArgs, type OpenModelArgs } from '@hydranium/protocol';
@@ -18,7 +18,7 @@ import {
18
18
  type WorkspaceLock
19
19
  } from '@hydranium/langium';
20
20
  import { type CancellationToken, Disposable } from 'vscode-languageserver';
21
- import { type HydraniumDocumentBuilder } from '../langium/document-builder/document-builder.js';
21
+ import { HydraniumDocumentBuilder } from '../langium/document-builder/document-builder.js';
22
22
 
23
23
  /** Recorded call to a stubbed {@link DocumentBuilder} method. */
24
24
  export interface RecordedBuilderCall<TArgs extends unknown[]> {
@@ -76,7 +76,7 @@ export interface StubWaitUntilGate {
76
76
  export interface StubDocumentBuilder
77
77
  extends
78
78
  Pick<DocumentBuilder, 'update' | 'onDocumentPhase' | 'onUpdate' | 'build' | 'onBuildPhase' | 'resetToState' | 'updateBuildOptions'>,
79
- Pick<HydraniumDocumentBuilder, 'onDocumentPhaseDelivered' | 'scheduleUpdate'> {
79
+ Pick<HydraniumDocumentBuilder, 'onDocumentPhaseDelivered' | 'scheduleUpdate' | 'finalBuildState'> {
80
80
  /**
81
81
  * Single-overload stub of {@link DocumentBuilder.waitUntil}. Real has
82
82
  * two overloads (`(state, cancelToken?): Promise<void>` and
@@ -162,6 +162,8 @@ export function makeStubDocumentBuilder(workspaceLock?: WorkspaceLock): StubDocu
162
162
  // Langium's own default, so a session write waits for `Validated` here
163
163
  // as it does against the real builder.
164
164
  updateBuildOptions: { validation: { categories: ['built-in', 'fast'] } },
165
+ // The real rule, read off this stub's options, so the two cannot drift.
166
+ finalBuildState: () => HydraniumDocumentBuilder.prototype.finalBuildState.call(stub),
165
167
  get updateCalls() {
166
168
  return updateCalls;
167
169
  },
@@ -7,7 +7,7 @@
7
7
  * SPDX-License-Identifier: MIT
8
8
  ********************************************************************************/
9
9
 
10
- import type { SelfSaveRegistry } from '../documents/self-save-registry.js';
10
+ import type { SelfSaveRegistry } from '../langium/workspace/self-save-registry.js';
11
11
 
12
12
  /**
13
13
  * Stub for the framework's {@link SelfSaveRegistry}. Records `register` calls
@@ -8,7 +8,7 @@
8
8
  ********************************************************************************/
9
9
 
10
10
  import type { URI } from '@hydranium/langium';
11
- import type { WritableFileSystemProvider } from '../documents/ast-document-manager.js';
11
+ import type { WritableFileSystemProvider } from '../langium/workspace/file-system-provider.js';
12
12
  import type { StubSelfSaveRegistry } from './stub-self-save-registry.js';
13
13
 
14
14
  /**
@@ -1 +0,0 @@
1
- {"version":3,"file":"self-save-registry.d.ts","sourceRoot":"","sources":["../../src/documents/self-save-registry.ts"],"names":[],"mappings":"AAAA;;;;;;;kFAOkF;AAElF,OAAO,EAAE,KAAK,KAAK,EAAE,MAAM,qBAAqB,CAAC;AAEjD,OAAO,EAAE,KAAK,2BAA2B,EAAE,MAAM,+BAA+B,CAAC;AAKjF,MAAM,WAAW,uBAAuB;IACrC,0GAA0G;IAC1G,KAAK,CAAC,EAAE,MAAM,CAAC;CACjB;AAED;;;;GAIG;AACH,MAAM,WAAW,gBAAgB;IAC9B;;;;;OAKG;IACH,QAAQ,CAAC,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;IAEhD;;;;;;OAMG;IACH,YAAY,CAAC,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC;CACzD;AAED;;;GAGG;AACH,qBAAa,uBAAwB,YAAW,gBAAgB;IAC7D,SAAS,CAAC,QAAQ,CAAC,OAAO;iBAA8B,MAAM;sBAAgB,MAAM;OAAM;IAC1F;;;;;;OAMG;IACH,SAAS,CAAC,QAAQ,CAAC,KAAK,EAAE,KAAK,CAAC;IAChC,SAAS,CAAC,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IAEjC,YAAY,QAAQ,EAAE,IAAI,CAAC,2BAA2B,EAAE,OAAO,CAAC,EAAE,OAAO,GAAE,uBAA4B,EAGtG;IAED;;;;;;;;;;;;OAYG;IACH,SAAS,CAAC,GAAG,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAEpC;IAED,QAAQ,CAAC,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,IAAI,CAG9C;IAED,YAAY,CAAC,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,OAAO,CAOrD;IAED;;;;;;;;;OASG;IACH,SAAS,CAAC,YAAY,IAAI,IAAI,CAM7B;IAED,+EAA+E;IAC/E,SAAS,CAAC,SAAS,CAAC,YAAY,EAAE,MAAM,GAAG,OAAO,CAEjD;CACH"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"self-save-registry.js","sourceRoot":"","sources":["../../src/documents/self-save-registry.ts"],"names":[],"mappings":"AAAA;;;;;;;kFAOkF;AAGlF,OAAO,EAAE,2BAA2B,EAAE,MAAM,wBAAwB,CAAC;AAGrE,wDAAwD;AACxD,MAAM,cAAc,GAAG,MAAM,CAAC;AA+B9B;;;GAGG;AACH,MAAM,OAAO,uBAAuB;IACd,OAAO,GAAG,IAAI,GAAG,EAAqD,CAAC;IAC1F;;;;;;OAMG;IACgB,KAAK,CAAQ;IACb,KAAK,CAAS;IAEjC,YAAY,QAAoD,EAAE,OAAO,GAA4B,EAAE;QACpG,IAAI,CAAC,KAAK,GAAG,QAAQ,CAAC,KAAK,CAAC;QAC5B,IAAI,CAAC,KAAK,GAAG,OAAO,CAAC,KAAK,IAAI,cAAc,CAAC;IAChD,CAAC;IAED;;;;;;;;;;;;OAYG;IACO,GAAG,CAAC,MAAc;QACzB,OAAO,2BAA2B,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,WAAW,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC;IACxE,CAAC;IAED,QAAQ,CAAC,MAAc,EAAE,OAAe;QACrC,IAAI,CAAC,YAAY,EAAE,CAAC;QACpB,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,EAAE,OAAO,EAAE,YAAY,EAAE,IAAI,CAAC,KAAK,CAAC,GAAG,EAAE,EAAE,CAAC,CAAC;IACnF,CAAC;IAED,YAAY,CAAC,MAAc,EAAE,OAAe;QACzC,MAAM,KAAK,GAAG,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC;QACjD,IAAI,CAAC,KAAK,IAAI,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,YAAY,CAAC,EAAE,CAAC;YAChD,OAAO,KAAK,CAAC;QAChB,CAAC;QACD,oEAAoE;QACpE,OAAO,KAAK,CAAC,OAAO,KAAK,OAAO,CAAC;IACpC,CAAC;IAED;;;;;;;;;OASG;IACO,YAAY;QACnB,KAAK,MAAM,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,IAAI,CAAC,OAAO,EAAE,CAAC;YACvC,IAAI,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,YAAY,CAAC,EAAE,CAAC;gBACtC,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;YAC5B,CAAC;QACJ,CAAC;IACJ,CAAC;IAED,+EAA+E;IACrE,SAAS,CAAC,YAAoB;QACrC,OAAO,IAAI,CAAC,KAAK,CAAC,GAAG,EAAE,GAAG,YAAY,GAAG,IAAI,CAAC,KAAK,CAAC;IACvD,CAAC;CACH"}