@hydranium/core 1.0.0-next.289 → 1.0.0-next.298
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/README.md +1 -0
- package/lib/browser/index.d.ts +10 -0
- package/lib/browser/index.d.ts.map +1 -0
- package/lib/browser/index.js +14 -0
- package/lib/browser/index.js.map +1 -0
- package/lib/browser/indexeddb-file-system-store.d.ts +82 -0
- package/lib/browser/indexeddb-file-system-store.d.ts.map +1 -0
- package/lib/browser/indexeddb-file-system-store.js +181 -0
- package/lib/browser/indexeddb-file-system-store.js.map +1 -0
- package/lib/langium/ast-extension/ast-extension-service.d.ts +39 -31
- package/lib/langium/ast-extension/ast-extension-service.d.ts.map +1 -1
- package/lib/langium/ast-extension/ast-extension-service.js +45 -19
- package/lib/langium/ast-extension/ast-extension-service.js.map +1 -1
- package/lib/langium/build-phase-pass/build-phase-pass-service.d.ts +8 -8
- package/lib/langium/build-phase-pass/build-phase-pass-service.d.ts.map +1 -1
- package/lib/langium/build-phase-pass/build-phase-pass-service.js +25 -16
- package/lib/langium/build-phase-pass/build-phase-pass-service.js.map +1 -1
- package/lib/langium/build-phase-pass/build-phase-pass.d.ts +19 -7
- package/lib/langium/build-phase-pass/build-phase-pass.d.ts.map +1 -1
- package/lib/langium/build-phase-pass/build-phase-pass.js +20 -0
- package/lib/langium/build-phase-pass/build-phase-pass.js.map +1 -1
- package/lib/langium/document-builder/build-pipeline-integration.d.ts.map +1 -1
- package/lib/langium/document-builder/build-pipeline-integration.js +11 -40
- package/lib/langium/document-builder/build-pipeline-integration.js.map +1 -1
- package/lib/langium/residency/cst-residency-service.js +1 -1
- package/lib/langium/workspace/persistent-file-system-provider.d.ts +8 -0
- package/lib/langium/workspace/persistent-file-system-provider.d.ts.map +1 -1
- package/lib/langium/workspace/persistent-file-system-provider.js +11 -0
- package/lib/langium/workspace/persistent-file-system-provider.js.map +1 -1
- package/package.json +14 -9
- package/src/browser/index.ts +14 -0
- package/src/browser/indexeddb-file-system-store.ts +192 -0
- package/src/langium/ast-extension/ast-extension-service.ts +74 -41
- package/src/langium/build-phase-pass/build-phase-pass-service.ts +28 -18
- package/src/langium/build-phase-pass/build-phase-pass.ts +36 -7
- package/src/langium/document-builder/build-pipeline-integration.ts +11 -42
- package/src/langium/residency/cst-residency-service.ts +1 -1
- package/src/langium/workspace/persistent-file-system-provider.ts +11 -0
|
@@ -10,46 +10,11 @@
|
|
|
10
10
|
import { type LangiumDocument, DocumentState } from '@hydranium/langium';
|
|
11
11
|
import { type CancellationToken } from 'vscode-languageserver';
|
|
12
12
|
import { IntegrityPhase } from '../integrity/integrity-rule.js';
|
|
13
|
-
import {
|
|
13
|
+
import { AstExtensionPhase } from '../ast-extension/ast-extension-service.js';
|
|
14
|
+
import { BuildPassPhase, groupDocumentsByLanguage } from '../build-phase-pass/build-phase-pass.js';
|
|
14
15
|
import { type ServerSharedServices } from '../module.js';
|
|
15
16
|
import { labelPhaseListener } from './labeled-phase-listener.js';
|
|
16
17
|
|
|
17
|
-
/**
|
|
18
|
-
* AST extension wiring covers every "useful" `DocumentState` an extension can
|
|
19
|
-
* target. `Changed` has no AST yet; `IndexedContent` carries the same
|
|
20
|
-
* per-document information as `Parsed`. No-op fires for documents with no
|
|
21
|
-
* extension at a given state are negligible (`notifyDocumentPhase` is a plain
|
|
22
|
-
* listener loop), so the framework wires the full set unconditionally rather
|
|
23
|
-
* than collecting declared states from per-language registrations.
|
|
24
|
-
*/
|
|
25
|
-
const AST_EXTENSION_PHASES: readonly DocumentState[] = [
|
|
26
|
-
DocumentState.Parsed,
|
|
27
|
-
DocumentState.ComputedScopes,
|
|
28
|
-
DocumentState.Linked,
|
|
29
|
-
DocumentState.IndexedReferences,
|
|
30
|
-
DocumentState.Validated
|
|
31
|
-
];
|
|
32
|
-
|
|
33
|
-
/**
|
|
34
|
-
* Build phases at which the `BuildPhasePassService` is driven. A pass
|
|
35
|
-
* registered at any other state never fires (the listener is not wired), and
|
|
36
|
-
* `runPasses` no-ops at a phase with no registered pass, so wiring the full set
|
|
37
|
-
* unconditionally costs only an empty-bucket check per phase.
|
|
38
|
-
*
|
|
39
|
-
* `IndexedContent` belongs here and NOT in {@link AST_EXTENSION_PHASES}, so the
|
|
40
|
-
* two cannot be collapsed. Per document it carries nothing `Parsed` does; per
|
|
41
|
-
* BATCH it is the only phase meaning the global index is whole again, which
|
|
42
|
-
* batch work keyed on a complete index has nowhere else to run.
|
|
43
|
-
*/
|
|
44
|
-
const BUILD_PHASE_PASS_STATES: readonly DocumentState[] = [
|
|
45
|
-
DocumentState.Parsed,
|
|
46
|
-
DocumentState.IndexedContent,
|
|
47
|
-
DocumentState.ComputedScopes,
|
|
48
|
-
DocumentState.Linked,
|
|
49
|
-
DocumentState.IndexedReferences,
|
|
50
|
-
DocumentState.Validated
|
|
51
|
-
];
|
|
52
|
-
|
|
53
18
|
/**
|
|
54
19
|
* Default priority of the framework integrity passes. Integrity mutates / cleans
|
|
55
20
|
* the AST that every derived-state pass reads, so it is *foundational* and must
|
|
@@ -132,17 +97,19 @@ export class DefaultBuildPipelineIntegration implements BuildPipelineIntegration
|
|
|
132
97
|
for (const phase of IntegrityPhase.all()) {
|
|
133
98
|
passes.register({
|
|
134
99
|
id: `framework:integrity:${IntegrityPhase.toString(phase).toLowerCase()}`,
|
|
135
|
-
|
|
100
|
+
phase,
|
|
136
101
|
priority: integrityPriority,
|
|
137
102
|
run: (documents, cancelToken) => this.callIntegrity(documents, phase, cancelToken)
|
|
138
103
|
});
|
|
139
104
|
}
|
|
140
105
|
|
|
141
|
-
// One onBuildPhase listener per pass
|
|
106
|
+
// One onBuildPhase listener per pass phase, routed through the overridable
|
|
142
107
|
// `runBuildPhase` seam → priority-ordered, sequential, cancel-aware pass
|
|
143
108
|
// dispatch. The returned promise is awaited by the build pipeline, so a
|
|
144
|
-
// mutating pass (integrity) reparses before the build advances.
|
|
145
|
-
|
|
109
|
+
// mutating pass (integrity) reparses before the build advances. The full
|
|
110
|
+
// set is wired unconditionally: `runPasses` no-ops at a phase with no
|
|
111
|
+
// pass, so an unused listener costs one empty-bucket check.
|
|
112
|
+
for (const phase of BuildPassPhase.all()) {
|
|
146
113
|
builder.onBuildPhase(
|
|
147
114
|
phase,
|
|
148
115
|
labelPhaseListener(
|
|
@@ -164,7 +131,9 @@ export class DefaultBuildPipelineIntegration implements BuildPipelineIntegration
|
|
|
164
131
|
// unchanged by the build-phase-pass registry, which is batch-granular. The
|
|
165
132
|
// listener calls the `extendAst` seam directly (the document-phase analog of
|
|
166
133
|
// `runBuildPhase`); there is no per-phase handler tier — one parameterized seam.
|
|
167
|
-
for
|
|
134
|
+
// Wired for every phase unconditionally rather than for the phases the
|
|
135
|
+
// per-language registrations declare: a no-op fire is a plain listener loop.
|
|
136
|
+
for (const phase of AstExtensionPhase.all()) {
|
|
168
137
|
builder.onDocumentPhase(
|
|
169
138
|
phase,
|
|
170
139
|
labelPhaseListener(
|
|
@@ -282,7 +282,7 @@ export class DefaultCstResidencyService implements CstResidencyService {
|
|
|
282
282
|
this.langiumDocs = services.workspace.LangiumDocuments;
|
|
283
283
|
services.workspace.BuildPhasePassService.register({
|
|
284
284
|
id: 'framework:cst-residency:shed',
|
|
285
|
-
|
|
285
|
+
phase: DocumentState.Validated,
|
|
286
286
|
priority: options.priority ?? CST_RESIDENCY_PASS_PRIORITY,
|
|
287
287
|
run: documents => this.onBuild(documents)
|
|
288
288
|
});
|
|
@@ -150,12 +150,21 @@ export class PersistentFileSystemProvider extends InMemoryFileSystemProvider {
|
|
|
150
150
|
* of marking it — a deletion that quietly undoes itself on the next load.
|
|
151
151
|
*/
|
|
152
152
|
protected readonly seededPaths: ReadonlySet<string>;
|
|
153
|
+
/**
|
|
154
|
+
* The store keys restored as CONTENT, in the store's order.
|
|
155
|
+
*
|
|
156
|
+
* A deletion marker is not listed: the store holds a key for a deleted seeded
|
|
157
|
+
* file, so a host counting stored keys would report that deletion as a
|
|
158
|
+
* restored file, and only this class can tell the two apart.
|
|
159
|
+
*/
|
|
160
|
+
readonly restoredPaths: readonly string[];
|
|
153
161
|
|
|
154
162
|
constructor(services: ServerSharedServicesMinimal, options: PersistentFileSystemOptions) {
|
|
155
163
|
super(services, options);
|
|
156
164
|
this.store = options.store;
|
|
157
165
|
this.storeRoot = options.rootUri === undefined ? undefined : `${this.fileKey(options.rootUri)}/`;
|
|
158
166
|
this.seededPaths = new Set(Object.keys(options.seed ?? {}).map(path => this.storeKey(this.storeUri(path))));
|
|
167
|
+
const restoredPaths: string[] = [];
|
|
159
168
|
for (const [path, content] of Object.entries(options.restored ?? {})) {
|
|
160
169
|
// `super.*`, so restoring does not mirror straight back into the store
|
|
161
170
|
// it just came from — a write-back on every start, and one that would
|
|
@@ -170,8 +179,10 @@ export class PersistentFileSystemProvider extends InMemoryFileSystemProvider {
|
|
|
170
179
|
this.files.delete(this.fileKey(uri));
|
|
171
180
|
} else {
|
|
172
181
|
super.setFile(uri, content);
|
|
182
|
+
restoredPaths.push(path);
|
|
173
183
|
}
|
|
174
184
|
}
|
|
185
|
+
this.restoredPaths = restoredPaths;
|
|
175
186
|
}
|
|
176
187
|
|
|
177
188
|
/**
|