@hydranium/glsp-server 1.0.0-next.10
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/LICENSE +21 -0
- package/README.md +97 -0
- package/lib/browser/index.d.ts +10 -0
- package/lib/browser/index.d.ts.map +1 -0
- package/lib/browser/index.js +15 -0
- package/lib/browser/index.js.map +1 -0
- package/lib/browser/start-glsp-server-in-worker.d.ts +121 -0
- package/lib/browser/start-glsp-server-in-worker.d.ts.map +1 -0
- package/lib/browser/start-glsp-server-in-worker.js +102 -0
- package/lib/browser/start-glsp-server-in-worker.js.map +1 -0
- package/lib/command/hydranium-glsp-recording-command.d.ts +132 -0
- package/lib/command/hydranium-glsp-recording-command.d.ts.map +1 -0
- package/lib/command/hydranium-glsp-recording-command.js +159 -0
- package/lib/command/hydranium-glsp-recording-command.js.map +1 -0
- package/lib/command/index.d.ts +10 -0
- package/lib/command/index.d.ts.map +1 -0
- package/lib/command/index.js +10 -0
- package/lib/command/index.js.map +1 -0
- package/lib/computed-bounds/hydranium-glsp-computed-bounds-action-handler.d.ts +61 -0
- package/lib/computed-bounds/hydranium-glsp-computed-bounds-action-handler.d.ts.map +1 -0
- package/lib/computed-bounds/hydranium-glsp-computed-bounds-action-handler.js +93 -0
- package/lib/computed-bounds/hydranium-glsp-computed-bounds-action-handler.js.map +1 -0
- package/lib/computed-bounds/index.d.ts +10 -0
- package/lib/computed-bounds/index.d.ts.map +1 -0
- package/lib/computed-bounds/index.js +10 -0
- package/lib/computed-bounds/index.js.map +1 -0
- package/lib/dispatcher/index.d.ts +10 -0
- package/lib/dispatcher/index.d.ts.map +1 -0
- package/lib/dispatcher/index.js +10 -0
- package/lib/dispatcher/index.js.map +1 -0
- package/lib/dispatcher/server-action-dispatcher.d.ts +52 -0
- package/lib/dispatcher/server-action-dispatcher.d.ts.map +1 -0
- package/lib/dispatcher/server-action-dispatcher.js +79 -0
- package/lib/dispatcher/server-action-dispatcher.js.map +1 -0
- package/lib/index.d.ts +19 -0
- package/lib/index.d.ts.map +1 -0
- package/lib/index.js +20 -0
- package/lib/index.js.map +1 -0
- package/lib/launcher/abstract-hydranium-glsp-diagram-module.d.ts +75 -0
- package/lib/launcher/abstract-hydranium-glsp-diagram-module.d.ts.map +1 -0
- package/lib/launcher/abstract-hydranium-glsp-diagram-module.js +100 -0
- package/lib/launcher/abstract-hydranium-glsp-diagram-module.js.map +1 -0
- package/lib/launcher/glsp-app-module.d.ts +87 -0
- package/lib/launcher/glsp-app-module.d.ts.map +1 -0
- package/lib/launcher/glsp-app-module.js +71 -0
- package/lib/launcher/glsp-app-module.js.map +1 -0
- package/lib/launcher/glsp-framework-overrides.d.ts +32 -0
- package/lib/launcher/glsp-framework-overrides.d.ts.map +1 -0
- package/lib/launcher/glsp-framework-overrides.js +49 -0
- package/lib/launcher/glsp-framework-overrides.js.map +1 -0
- package/lib/launcher/glsp-server-overrides.d.ts +39 -0
- package/lib/launcher/glsp-server-overrides.d.ts.map +1 -0
- package/lib/launcher/glsp-server-overrides.js +45 -0
- package/lib/launcher/glsp-server-overrides.js.map +1 -0
- package/lib/launcher/hydranium-glsp-server.d.ts +62 -0
- package/lib/launcher/hydranium-glsp-server.d.ts.map +1 -0
- package/lib/launcher/hydranium-glsp-server.js +101 -0
- package/lib/launcher/hydranium-glsp-server.js.map +1 -0
- package/lib/launcher/index.d.ts +12 -0
- package/lib/launcher/index.d.ts.map +1 -0
- package/lib/launcher/index.js +22 -0
- package/lib/launcher/index.js.map +1 -0
- package/lib/logging/glsp-client-logger.d.ts +110 -0
- package/lib/logging/glsp-client-logger.d.ts.map +1 -0
- package/lib/logging/glsp-client-logger.js +151 -0
- package/lib/logging/glsp-client-logger.js.map +1 -0
- package/lib/logging/index.d.ts +10 -0
- package/lib/logging/index.d.ts.map +1 -0
- package/lib/logging/index.js +10 -0
- package/lib/logging/index.js.map +1 -0
- package/lib/node/index.d.ts +10 -0
- package/lib/node/index.d.ts.map +1 -0
- package/lib/node/index.js +13 -0
- package/lib/node/index.js.map +1 -0
- package/lib/node/start-glsp-server.d.ts +122 -0
- package/lib/node/start-glsp-server.d.ts.map +1 -0
- package/lib/node/start-glsp-server.js +103 -0
- package/lib/node/start-glsp-server.js.map +1 -0
- package/lib/state/abstract-hydranium-glsp-state.d.ts +333 -0
- package/lib/state/abstract-hydranium-glsp-state.d.ts.map +1 -0
- package/lib/state/abstract-hydranium-glsp-state.js +451 -0
- package/lib/state/abstract-hydranium-glsp-state.js.map +1 -0
- package/lib/state/full-text-hydranium-glsp-state.d.ts +43 -0
- package/lib/state/full-text-hydranium-glsp-state.d.ts.map +1 -0
- package/lib/state/full-text-hydranium-glsp-state.js +60 -0
- package/lib/state/full-text-hydranium-glsp-state.js.map +1 -0
- package/lib/state/hydranium-glsp-index.d.ts +220 -0
- package/lib/state/hydranium-glsp-index.d.ts.map +1 -0
- package/lib/state/hydranium-glsp-index.js +320 -0
- package/lib/state/hydranium-glsp-index.js.map +1 -0
- package/lib/state/hydranium-shared-core-services.d.ts +90 -0
- package/lib/state/hydranium-shared-core-services.d.ts.map +1 -0
- package/lib/state/hydranium-shared-core-services.js +89 -0
- package/lib/state/hydranium-shared-core-services.js.map +1 -0
- package/lib/state/index.d.ts +17 -0
- package/lib/state/index.d.ts.map +1 -0
- package/lib/state/index.js +17 -0
- package/lib/state/index.js.map +1 -0
- package/lib/state/model-ready-timeout-error.d.ts +28 -0
- package/lib/state/model-ready-timeout-error.d.ts.map +1 -0
- package/lib/state/model-ready-timeout-error.js +36 -0
- package/lib/state/model-ready-timeout-error.js.map +1 -0
- package/lib/state/reconcile-source-model-write.d.ts +43 -0
- package/lib/state/reconcile-source-model-write.d.ts.map +1 -0
- package/lib/state/reconcile-source-model-write.js +47 -0
- package/lib/state/reconcile-source-model-write.js.map +1 -0
- package/lib/state/reconciling-multi-document-glsp-state.d.ts +164 -0
- package/lib/state/reconciling-multi-document-glsp-state.d.ts.map +1 -0
- package/lib/state/reconciling-multi-document-glsp-state.js +222 -0
- package/lib/state/reconciling-multi-document-glsp-state.js.map +1 -0
- package/lib/state/reconciling-transfer-hydranium-glsp-state.d.ts +91 -0
- package/lib/state/reconciling-transfer-hydranium-glsp-state.d.ts.map +1 -0
- package/lib/state/reconciling-transfer-hydranium-glsp-state.js +129 -0
- package/lib/state/reconciling-transfer-hydranium-glsp-state.js.map +1 -0
- package/lib/storage/hydranium-glsp-storage.d.ts +348 -0
- package/lib/storage/hydranium-glsp-storage.d.ts.map +1 -0
- package/lib/storage/hydranium-glsp-storage.js +634 -0
- package/lib/storage/hydranium-glsp-storage.js.map +1 -0
- package/lib/storage/index.d.ts +11 -0
- package/lib/storage/index.d.ts.map +1 -0
- package/lib/storage/index.js +11 -0
- package/lib/storage/index.js.map +1 -0
- package/lib/storage/save-conflict-policy.d.ts +56 -0
- package/lib/storage/save-conflict-policy.d.ts.map +1 -0
- package/lib/storage/save-conflict-policy.js +19 -0
- package/lib/storage/save-conflict-policy.js.map +1 -0
- package/lib/submission/hydranium-glsp-submission-handler.d.ts +109 -0
- package/lib/submission/hydranium-glsp-submission-handler.d.ts.map +1 -0
- package/lib/submission/hydranium-glsp-submission-handler.js +157 -0
- package/lib/submission/hydranium-glsp-submission-handler.js.map +1 -0
- package/lib/submission/index.d.ts +10 -0
- package/lib/submission/index.d.ts.map +1 -0
- package/lib/submission/index.js +10 -0
- package/lib/submission/index.js.map +1 -0
- package/lib/testing/glsp-harness.d.ts +170 -0
- package/lib/testing/glsp-harness.d.ts.map +1 -0
- package/lib/testing/glsp-harness.js +231 -0
- package/lib/testing/glsp-harness.js.map +1 -0
- package/lib/testing/index.d.ts +11 -0
- package/lib/testing/index.d.ts.map +1 -0
- package/lib/testing/index.js +13 -0
- package/lib/testing/index.js.map +1 -0
- package/lib/testing/make-noop-glsp-logger.d.ts +42 -0
- package/lib/testing/make-noop-glsp-logger.d.ts.map +1 -0
- package/lib/testing/make-noop-glsp-logger.js +47 -0
- package/lib/testing/make-noop-glsp-logger.js.map +1 -0
- package/lib/util/index.d.ts +10 -0
- package/lib/util/index.d.ts.map +1 -0
- package/lib/util/index.js +10 -0
- package/lib/util/index.js.map +1 -0
- package/lib/util/service-identifier.d.ts +46 -0
- package/lib/util/service-identifier.d.ts.map +1 -0
- package/lib/util/service-identifier.js +47 -0
- package/lib/util/service-identifier.js.map +1 -0
- package/lib/validation/diagnostic-markers.d.ts +48 -0
- package/lib/validation/diagnostic-markers.d.ts.map +1 -0
- package/lib/validation/diagnostic-markers.js +68 -0
- package/lib/validation/diagnostic-markers.js.map +1 -0
- package/lib/validation/hydranium-glsp-model-validator.d.ts +51 -0
- package/lib/validation/hydranium-glsp-model-validator.d.ts.map +1 -0
- package/lib/validation/hydranium-glsp-model-validator.js +118 -0
- package/lib/validation/hydranium-glsp-model-validator.js.map +1 -0
- package/lib/validation/index.d.ts +11 -0
- package/lib/validation/index.d.ts.map +1 -0
- package/lib/validation/index.js +11 -0
- package/lib/validation/index.js.map +1 -0
- package/package.json +111 -0
- package/src/browser/index.ts +15 -0
- package/src/browser/start-glsp-server-in-worker.ts +202 -0
- package/src/command/hydranium-glsp-recording-command.ts +183 -0
- package/src/command/index.ts +10 -0
- package/src/computed-bounds/hydranium-glsp-computed-bounds-action-handler.ts +103 -0
- package/src/computed-bounds/index.ts +10 -0
- package/src/dispatcher/index.ts +10 -0
- package/src/dispatcher/server-action-dispatcher.ts +72 -0
- package/src/index.ts +20 -0
- package/src/launcher/abstract-hydranium-glsp-diagram-module.ts +117 -0
- package/src/launcher/glsp-app-module.ts +106 -0
- package/src/launcher/glsp-framework-overrides.ts +51 -0
- package/src/launcher/glsp-server-overrides.ts +46 -0
- package/src/launcher/hydranium-glsp-server.ts +104 -0
- package/src/launcher/index.ts +22 -0
- package/src/logging/glsp-client-logger.ts +184 -0
- package/src/logging/index.ts +10 -0
- package/src/node/index.ts +13 -0
- package/src/node/start-glsp-server.ts +214 -0
- package/src/state/abstract-hydranium-glsp-state.ts +503 -0
- package/src/state/full-text-hydranium-glsp-state.ts +63 -0
- package/src/state/hydranium-glsp-index.ts +337 -0
- package/src/state/hydranium-shared-core-services.ts +92 -0
- package/src/state/index.ts +17 -0
- package/src/state/model-ready-timeout-error.ts +33 -0
- package/src/state/reconcile-source-model-write.ts +77 -0
- package/src/state/reconciling-multi-document-glsp-state.ts +248 -0
- package/src/state/reconciling-transfer-hydranium-glsp-state.ts +132 -0
- package/src/storage/hydranium-glsp-storage.ts +660 -0
- package/src/storage/index.ts +11 -0
- package/src/storage/save-conflict-policy.ts +52 -0
- package/src/submission/hydranium-glsp-submission-handler.ts +170 -0
- package/src/submission/index.ts +10 -0
- package/src/testing/glsp-harness.ts +422 -0
- package/src/testing/index.ts +14 -0
- package/src/testing/make-noop-glsp-logger.ts +66 -0
- package/src/util/index.ts +10 -0
- package/src/util/service-identifier.ts +49 -0
- package/src/validation/diagnostic-markers.ts +93 -0
- package/src/validation/hydranium-glsp-model-validator.ts +105 -0
- package/src/validation/index.ts +11 -0
|
@@ -0,0 +1,348 @@
|
|
|
1
|
+
/********************************************************************************
|
|
2
|
+
* Copyright (c) 2023-2026 CrossBreeze, EclipseSource and others.
|
|
3
|
+
*
|
|
4
|
+
* This program and the accompanying materials are made available under the
|
|
5
|
+
* terms of the MIT License which is available in the project root.
|
|
6
|
+
*
|
|
7
|
+
* SPDX-License-Identifier: MIT
|
|
8
|
+
********************************************************************************/
|
|
9
|
+
import { type Action, ActionDispatcher, type ClientSession, type ClientSessionListener, ClientSessionManager, type DefaultCommandStack, type Disposable, Logger as GlspLogger, type MaybePromise, ModelValidator, type RequestModelAction, type SaveModelAction, type SourceModelStorage } from '@eclipse-glsp/server';
|
|
10
|
+
import { Debouncer, DisposableCollection } from '@hydranium/protocol';
|
|
11
|
+
import { type AstNode } from '@hydranium/langium';
|
|
12
|
+
import { AstDocument, type AstDocumentSavedEvent, type AstDocumentUpdatedEvent, type ServerSharedServices } from '@hydranium/core';
|
|
13
|
+
import { type AbstractHydraniumGlspState } from '../state/abstract-hydranium-glsp-state.js';
|
|
14
|
+
import { type HydraniumGlspSubmissionHandler } from '../submission/hydranium-glsp-submission-handler.js';
|
|
15
|
+
import { SaveConflictPolicy } from './save-conflict-policy.js';
|
|
16
|
+
/**
|
|
17
|
+
* GLSP source-model storage base shared by all hydranium adopters.
|
|
18
|
+
* Provides the DI signature, the {@link ClientSessionListener} +
|
|
19
|
+
* {@link Disposable} lifecycle plumbing (including the
|
|
20
|
+
* {@link DisposableCollection} drain on session disposal), the
|
|
21
|
+
* {@link RequestModelAction} / {@link SaveModelAction} URI-extraction
|
|
22
|
+
* helpers, and the live load/rebuild/resubmit flow with a settled-root
|
|
23
|
+
* invariant.
|
|
24
|
+
*
|
|
25
|
+
* **The settled-root invariant.** Every {@link AbstractHydraniumGlspState.setSourceRoot}
|
|
26
|
+
* the framework performs captures a root that has reached
|
|
27
|
+
* `IntegrityService.SettledState` (post-`Linked`, references indexed, on-build
|
|
28
|
+
* integrity rules applied). The GModel factory therefore always walks a fully
|
|
29
|
+
* linked + reprojected AST. The flow never captures off a transient mid-rebuild
|
|
30
|
+
* snapshot — notably it re-`settled()`s in the resubmit path rather than trusting
|
|
31
|
+
* the `onModelUpdated` event's document, which can arrive while a re-entered
|
|
32
|
+
* document is still being rebuilt.
|
|
33
|
+
*
|
|
34
|
+
* Adopters with richer needs override the seams ({@link isStructurallyBroken},
|
|
35
|
+
* {@link onParseErrorChanged}, {@link onSourceModelSettled}) rather than the
|
|
36
|
+
* whole flow, and select a {@link SaveConflictPolicy} via the bound option to
|
|
37
|
+
* tune how {@link saveSourceModel} reacts to a concurrent edit.
|
|
38
|
+
*
|
|
39
|
+
* **Default `saveSourceModel` flow.** Delegates to `ModelService.save`, which
|
|
40
|
+
* serialises through the language-specific `Serializer` bound at
|
|
41
|
+
* `services.serializer.Serializer` (resolved per-URI via `ServiceRegistry`),
|
|
42
|
+
* updates the multi-client text-document store, drives a rebuild, and writes the
|
|
43
|
+
* result via the `WritableFileSystemProvider`. The bound
|
|
44
|
+
* {@link SaveConflictPolicy} (default {@link DEFAULT_SAVE_CONFLICT_POLICY},
|
|
45
|
+
* `overwrite`) decides the based-on-version guard, await-vs-fire-and-forget, and
|
|
46
|
+
* failure handling.
|
|
47
|
+
*
|
|
48
|
+
* **tempId filter.** GLSP's `DefaultGlobalActionProvider` spins up a
|
|
49
|
+
* throwaway per-diagram-type container with upstream's {@link TEMPORARY_CLIENT_ID}
|
|
50
|
+
* placeholder purely to enumerate action kinds, then calls `unbindAll()`.
|
|
51
|
+
* The {@link postConstruct} hook skips registration for that placeholder so
|
|
52
|
+
* it doesn't linger in {@link ClientSessionManager}.
|
|
53
|
+
*
|
|
54
|
+
* **Lifecycle ordering.** `init` runs after DI resolution and parks the
|
|
55
|
+
* secondary-write-set watch, which outlives any single load.
|
|
56
|
+
* {@link sessionDisposed} calls {@link dispose}, which drains
|
|
57
|
+
* {@link toDispose} idempotently. Every transient subscription created in
|
|
58
|
+
* {@link doLoadSourceModel} is parked on {@link toDispose} so the drain catches
|
|
59
|
+
* them on client-detach.
|
|
60
|
+
*/
|
|
61
|
+
export declare class HydraniumGlspStorage<TRoot extends AstNode, TSourceModel = string> implements SourceModelStorage, ClientSessionListener, Disposable {
|
|
62
|
+
protected readonly logger: GlspLogger;
|
|
63
|
+
protected readonly sharedServices: ServerSharedServices;
|
|
64
|
+
protected readonly state: AbstractHydraniumGlspState<TRoot, TSourceModel>;
|
|
65
|
+
protected readonly sessionManager: ClientSessionManager;
|
|
66
|
+
protected readonly actionDispatcher: ActionDispatcher;
|
|
67
|
+
protected readonly submissionHandler: HydraniumGlspSubmissionHandler<TRoot, TSourceModel>;
|
|
68
|
+
protected readonly commandStack: DefaultCommandStack;
|
|
69
|
+
/**
|
|
70
|
+
* Optional {@link ModelValidator} whose markers are pushed to the client by
|
|
71
|
+
* {@link refreshDiagnosticMarkers}. Bound per diagram via
|
|
72
|
+
* `DiagramModule.bindModelValidator()`; absent (no push) when the head binds
|
|
73
|
+
* no validator. The framework default is `HydraniumGlspModelValidator`
|
|
74
|
+
* (LSP diagnostics → markers).
|
|
75
|
+
*/
|
|
76
|
+
protected readonly modelValidator?: ModelValidator;
|
|
77
|
+
/**
|
|
78
|
+
* Selected {@link SaveConflictPolicy} for {@link saveSourceModel}. Bind the
|
|
79
|
+
* {@link SaveConflictPolicy} token in a `DiagramModule` to choose a policy;
|
|
80
|
+
* left unbound it resolves to {@link DEFAULT_SAVE_CONFLICT_POLICY}
|
|
81
|
+
* (`overwrite`, last-write-wins). Read via {@link saveConflictPolicy} so the
|
|
82
|
+
* fallback is applied even when inversify injects `undefined` for an unbound
|
|
83
|
+
* `@optional()` member.
|
|
84
|
+
*/
|
|
85
|
+
protected readonly boundSaveConflictPolicy?: SaveConflictPolicy;
|
|
86
|
+
/** Disposables created during {@link doLoadSourceModel}; drained on session disposal. */
|
|
87
|
+
protected toDispose: DisposableCollection;
|
|
88
|
+
/**
|
|
89
|
+
* Live update subscriptions for the state's SECONDARY documents, keyed by URI.
|
|
90
|
+
* Reconciled by {@link reconcileSecondarySubscriptions} after every capture.
|
|
91
|
+
*
|
|
92
|
+
* Held apart from {@link toDispose} because this set is not fixed for the
|
|
93
|
+
* session: a document can leave the write set, and its subscription has to go
|
|
94
|
+
* with it rather than linger until the client detaches.
|
|
95
|
+
*/
|
|
96
|
+
protected readonly secondarySubscriptions: Map<string, Disposable>;
|
|
97
|
+
/**
|
|
98
|
+
* Whether an external resubmit has ever been dispatched. Gates the
|
|
99
|
+
* keep-the-last-valid-GModel branch, which needs to know a canvas is already
|
|
100
|
+
* standing — not what is on it. The content comparison that decides whether a
|
|
101
|
+
* resubmit is worth dispatching lives on the submission handler, which is the
|
|
102
|
+
* only place that sees operation submits too.
|
|
103
|
+
*/
|
|
104
|
+
protected hasSubmittedExternally: boolean;
|
|
105
|
+
/**
|
|
106
|
+
* Trailing-edge debounce for the external resubmit. Rescheduled on each
|
|
107
|
+
* {@link handleModelUpdated} so back-to-back rebuilds (cascade relinks,
|
|
108
|
+
* referenced-document edits) collapse into one {@link doUpdateAndSubmit}.
|
|
109
|
+
* Constructed in {@link init} (the injected {@link ServerSharedServices} —
|
|
110
|
+
* hence its `Clock` — is available by then); disposed on session teardown.
|
|
111
|
+
*/
|
|
112
|
+
protected resubmitDebouncer: Debouncer;
|
|
113
|
+
/** Latest event document awaiting the debounced resubmit; read by {@link flushResubmit} (last write wins). */
|
|
114
|
+
protected pendingResubmitDocument?: AstDocument<AstNode, unknown>;
|
|
115
|
+
protected init(): void;
|
|
116
|
+
/**
|
|
117
|
+
* Default load flow — {@link doLoadSourceModel}. Adopters whose load flow
|
|
118
|
+
* needs more than the seams allow override this method.
|
|
119
|
+
*/
|
|
120
|
+
loadSourceModel(action: RequestModelAction): MaybePromise<void>;
|
|
121
|
+
protected doLoadSourceModel(action: RequestModelAction): Promise<void>;
|
|
122
|
+
/**
|
|
123
|
+
* Capture the initial settled root and apply the initial edit mode. `settled()`
|
|
124
|
+
* strips diagnostics by phase contract, so the first edit mode is `EDITABLE`;
|
|
125
|
+
* the first {@link handleModelUpdated} (at `Validated`, with diagnostics) flips
|
|
126
|
+
* it READONLY if the document has structural parse errors. Edit-mode +
|
|
127
|
+
* settle-hook actions are dispatched on a macrotask so the initial
|
|
128
|
+
* `requestModel → setModel` handshake isn't perturbed.
|
|
129
|
+
*/
|
|
130
|
+
protected captureSettledRoot(rootUri: string, document: AstDocument<AstNode, never>): Promise<void>;
|
|
131
|
+
/**
|
|
132
|
+
* Reconcile {@link secondarySubscriptions} against the state's current
|
|
133
|
+
* secondary write set: dispose what left it, subscribe what arrived. Driven by
|
|
134
|
+
* {@link AbstractHydraniumGlspState.onSecondaryUrisChanged}, so it runs when
|
|
135
|
+
* the set actually changes rather than at points a caller guessed it might.
|
|
136
|
+
*
|
|
137
|
+
* **Secondaries need a subscription of their own because nothing else
|
|
138
|
+
* notifies for them.** The state records a secondary's version for the
|
|
139
|
+
* write-side conflict gate and adopter GModel factories re-read secondary
|
|
140
|
+
* content on every build, but no rebuild of a secondary reaches the primary's
|
|
141
|
+
* subscription: Langium's affected-documents walk runs from the referenced
|
|
142
|
+
* document to the referencing one, so a document that references the primary
|
|
143
|
+
* is downstream of it and editing it correctly affects nothing upstream.
|
|
144
|
+
* Manufacturing that invalidation to obtain a notification would cost a real
|
|
145
|
+
* rebuild per edit and make the affected set mean two things — the missing
|
|
146
|
+
* piece is a subscription, not an invalidation.
|
|
147
|
+
*/
|
|
148
|
+
protected reconcileSecondarySubscriptions(): void;
|
|
149
|
+
/**
|
|
150
|
+
* React to a rebuild of a SECONDARY document by resubmitting the diagram, so
|
|
151
|
+
* an external edit to (say) a layout file reaches the canvas.
|
|
152
|
+
*
|
|
153
|
+
* Reuses {@link handleModelUpdated}'s authorship guard, and that is the load-
|
|
154
|
+
* bearing half rather than the resubmit: a diagram interaction that writes a
|
|
155
|
+
* secondary — a drag persisting bounds to a layout file — comes back through
|
|
156
|
+
* this listener as the client's own `changed` edit, and resubmitting on it
|
|
157
|
+
* fights the optimistic client-side move the user is still holding.
|
|
158
|
+
*
|
|
159
|
+
* Schedules the PRIMARY's current document, never the secondary's.
|
|
160
|
+
* {@link doUpdateAndSubmit} reads its event document only for the edit-mode
|
|
161
|
+
* and structurally-broken decisions, both of which are statements about the
|
|
162
|
+
* document the canvas edits: passing the secondary's would let a typo in a
|
|
163
|
+
* layout file flip the canvas READONLY and take the keep-the-last-valid-GModel
|
|
164
|
+
* branch off an unrelated document's parse state. The pending-document field
|
|
165
|
+
* is shared with the primary path, so it would poison a concurrently
|
|
166
|
+
* scheduled primary resubmit too.
|
|
167
|
+
*
|
|
168
|
+
* No marker refresh, unlike the primary path: a secondary's diagnostics reach
|
|
169
|
+
* the client only if an adopter's index registers elements as rendering that
|
|
170
|
+
* document, and refreshing here unconditionally would add a dispatch to every
|
|
171
|
+
* drag this client authors — the guard above gates the resubmit, not the
|
|
172
|
+
* markers.
|
|
173
|
+
*/
|
|
174
|
+
protected handleSecondaryUpdated(uri: string, event: AstDocumentUpdatedEvent<AstNode, unknown>): void;
|
|
175
|
+
/**
|
|
176
|
+
* The primary document's current state, or `undefined` when it is not
|
|
177
|
+
* registered.
|
|
178
|
+
*
|
|
179
|
+
* Synchronous by construction — the phase-agnostic lookup door plus the shared
|
|
180
|
+
* projection — so reacting to a secondary neither waits nor can force a build.
|
|
181
|
+
* `settled()` is not an alternative: it strips diagnostics by phase contract,
|
|
182
|
+
* and diagnostics are the reason {@link doUpdateAndSubmit} takes a separate
|
|
183
|
+
* event document at all.
|
|
184
|
+
*/
|
|
185
|
+
protected currentPrimaryDocument(): AstDocument<AstNode, unknown> | undefined;
|
|
186
|
+
/**
|
|
187
|
+
* React to an external rebuild reaching `Validated`. Self-cleans if the
|
|
188
|
+
* session has vanished but this listener leaked (neither `sessionDisposed`
|
|
189
|
+
* nor `onClientClosed` fired on tab close). Resubmits for any change not
|
|
190
|
+
* authored by this client's own optimistic `changed` edit, then refreshes
|
|
191
|
+
* diagnostic markers for every update — including own edits, which skip
|
|
192
|
+
* the resubmit but can still change diagnostics.
|
|
193
|
+
*/
|
|
194
|
+
protected handleModelUpdated(rootUri: string, event: AstDocumentUpdatedEvent<AstNode, unknown>): Promise<void>;
|
|
195
|
+
/**
|
|
196
|
+
* Whether this storage has outlived its session — disposing it as a side
|
|
197
|
+
* effect when so. Checked from every subscription entry point because GLSP's
|
|
198
|
+
* `sessionDisposed` is unreliable on Theia tab-close and `onClientClosed` can
|
|
199
|
+
* miss it as well; a listener that survives its session otherwise keeps firing
|
|
200
|
+
* for the life of the process. `context` names the document whose event
|
|
201
|
+
* surfaced the leak.
|
|
202
|
+
*/
|
|
203
|
+
protected disposeIfStale(context: string): boolean;
|
|
204
|
+
/**
|
|
205
|
+
* Record the latest document and (re)arm the trailing-edge
|
|
206
|
+
* {@link resubmitDebouncer}, so a burst of rebuilds runs
|
|
207
|
+
* {@link doUpdateAndSubmit} once with the most recent document.
|
|
208
|
+
*/
|
|
209
|
+
protected scheduleUpdateAndSubmit(document: AstDocument<AstNode, unknown>): void;
|
|
210
|
+
/**
|
|
211
|
+
* Debouncer callback: run the resubmit for the latest pending document
|
|
212
|
+
* against this storage's (invariant) source URI and dispatch the result.
|
|
213
|
+
* Fire-and-forget — failures are logged, not surfaced to the timer caller.
|
|
214
|
+
*/
|
|
215
|
+
protected flushResubmit(): void;
|
|
216
|
+
/**
|
|
217
|
+
* Coordinate the command stack when another client persists the document:
|
|
218
|
+
* mark our stack clean so the editor doesn't prompt to re-save identical
|
|
219
|
+
* content. Our own saves already settle the stack through the save flow.
|
|
220
|
+
*/
|
|
221
|
+
protected handleModelSaved(event: AstDocumentSavedEvent<AstNode, unknown>): void;
|
|
222
|
+
/**
|
|
223
|
+
* Re-settle to a guaranteed fully-linked + reprojected root, capture it, and
|
|
224
|
+
* (unless suppressed) resubmit a deduped external GModel. Diagnostics for the
|
|
225
|
+
* edit-mode decision come from the event document (`settled()` strips them by
|
|
226
|
+
* phase contract).
|
|
227
|
+
*/
|
|
228
|
+
protected doUpdateAndSubmit(rootUri: string, eventDocument: AstDocument<AstNode, unknown>): Promise<Action[]>;
|
|
229
|
+
/**
|
|
230
|
+
* Recompute the desired edit mode from the document's structural-error state,
|
|
231
|
+
* flip {@link AbstractHydraniumGlspState.editMode}, and — only on a transition —
|
|
232
|
+
* return the {@link onParseErrorChanged} actions. No transition → no actions.
|
|
233
|
+
*/
|
|
234
|
+
protected refreshEditMode(document: AstDocument<AstNode, unknown>): Action[];
|
|
235
|
+
/**
|
|
236
|
+
* Seam: is the AST structurally broken (lexing/parsing errors)? Drives both
|
|
237
|
+
* READONLY mode and the GModel resubmit skip — keeping the last valid canvas
|
|
238
|
+
* instead of blanking it mid-typing. Default: any error-severity diagnostic
|
|
239
|
+
* carrying a Langium `lexing-error` / `parsing-error` code. Adopters override
|
|
240
|
+
* to compose additional break reasons.
|
|
241
|
+
*/
|
|
242
|
+
protected isStructurallyBroken(document: AstDocument<AstNode, unknown>): boolean;
|
|
243
|
+
/**
|
|
244
|
+
* Seam: actions to emit when the structural-broken state transitions. Default:
|
|
245
|
+
* a single {@link SetEditModeAction} toggling READONLY ↔ EDITABLE — editing is
|
|
246
|
+
* disabled while the syntax is broken but re-enabled once it parses, a sound
|
|
247
|
+
* generic for any Langium-backed diagram. Adopters override to add or replace
|
|
248
|
+
* the transition feedback. The {@link AbstractHydraniumGlspState.editMode}
|
|
249
|
+
* flip itself is owned by {@link refreshEditMode}.
|
|
250
|
+
*/
|
|
251
|
+
protected onParseErrorChanged(_document: AstDocument<AstNode, unknown>, broken: boolean): Action[];
|
|
252
|
+
/**
|
|
253
|
+
* Seam: extra actions to dispatch right after the initial settled root is
|
|
254
|
+
* captured (e.g. an adopter-specific status or palette refresh). Default: none.
|
|
255
|
+
*/
|
|
256
|
+
protected onSourceModelSettled(_document: AstDocument<AstNode, never>): Action[];
|
|
257
|
+
/** The effective {@link SaveConflictPolicy}: the bound option, or {@link DEFAULT_SAVE_CONFLICT_POLICY} when unbound. */
|
|
258
|
+
protected get saveConflictPolicy(): SaveConflictPolicy;
|
|
259
|
+
/**
|
|
260
|
+
* Default save flow: route through `ModelService.save`. The framework
|
|
261
|
+
* serialise-and-persist machinery handles serialisation (via the
|
|
262
|
+
* language-specific `Serializer` bound at `services.serializer.Serializer`),
|
|
263
|
+
* the multi-client text-document update, the rebuild, and the eventual
|
|
264
|
+
* `WritableFileSystemProvider.writeFile`.
|
|
265
|
+
*
|
|
266
|
+
* The configured {@link SaveConflictPolicy} (see {@link saveConflictPolicy})
|
|
267
|
+
* decides how a concurrent edit that advanced the document is handled:
|
|
268
|
+
* - `overwrite` (default): no based-on guard, await, propagate failures —
|
|
269
|
+
* last-write-wins, correct for a single-editor head.
|
|
270
|
+
* - `reject`: guard on the captured `state.version`, await, surface a
|
|
271
|
+
* `ConflictError` (and any other failure) to the GLSP save action.
|
|
272
|
+
* - `drop-and-log`: guard, fire-and-forget, log + swallow failures — a stale
|
|
273
|
+
* diagram save is dropped because a concurrent form/code edit already wrote
|
|
274
|
+
* the truth, and GLSP exposes no save-failure back-channel.
|
|
275
|
+
*
|
|
276
|
+
* Returns `MaybePromise<void>` to match upstream `SourceModelStorage`:
|
|
277
|
+
* resolves with the persist under `overwrite`/`reject`, returns synchronously
|
|
278
|
+
* under `drop-and-log`. Adopters that bypass `ModelService` (writing through
|
|
279
|
+
* `WritableFileSystemProvider` directly) still override the whole method.
|
|
280
|
+
*/
|
|
281
|
+
saveSourceModel(action: SaveModelAction): MaybePromise<void>;
|
|
282
|
+
/**
|
|
283
|
+
* Normalise GLSP's `sourceUri` — which may be a filesystem PATH or a URI
|
|
284
|
+
* string — to the URI string the workspace keys documents by.
|
|
285
|
+
*
|
|
286
|
+
* **The protocol does not pin which form a client sends, and the clients in
|
|
287
|
+
* play disagree.** GLSP's VS Code integration sends `document.uri.toString()`;
|
|
288
|
+
* a headless caller passes the path it already has. Committing to either one
|
|
289
|
+
* alone is what this method exists to avoid.
|
|
290
|
+
*
|
|
291
|
+
* **Getting it wrong does not throw where the mistake is.** `URI.file` given
|
|
292
|
+
* a URI string treats the whole thing as a path, percent-encodes the scheme,
|
|
293
|
+
* and yields an `fsPath` with that scheme buried in the middle. Nothing
|
|
294
|
+
* rejects it; it travels down to the filesystem and surfaces as an ENOENT
|
|
295
|
+
* several layers from the coercion that produced it.
|
|
296
|
+
*
|
|
297
|
+
* Adopters whose client sends a third form override this.
|
|
298
|
+
*/
|
|
299
|
+
protected toSourceModelUri(sourceUri: string): string;
|
|
300
|
+
/**
|
|
301
|
+
* Extract the source URI from a {@link RequestModelAction}. Throws
|
|
302
|
+
* {@link GLSPServerError} if the option is missing or non-string —
|
|
303
|
+
* GLSP's protocol contract requires the client to pass `sourceUri`
|
|
304
|
+
* when initiating a model request.
|
|
305
|
+
*
|
|
306
|
+
* Returns it VERBATIM, in whatever form the client sent;
|
|
307
|
+
* {@link toSourceModelUri} is what normalises it.
|
|
308
|
+
*/
|
|
309
|
+
protected getSourceUri(action: RequestModelAction): string;
|
|
310
|
+
/**
|
|
311
|
+
* Resolve the URI to save to: prefer the {@link SaveModelAction.fileUri}
|
|
312
|
+
* (set when the user chose "Save As"), fall back to the
|
|
313
|
+
* {@link SOURCE_URI_ARG} mirrored into the inherited properties map by
|
|
314
|
+
* {@link AbstractHydraniumGlspState.setSourceRoot}.
|
|
315
|
+
*
|
|
316
|
+
* A save action carries no request id, so a throw here reaches the user as a
|
|
317
|
+
* toast built from `message`, with `cause` behind its details control. The
|
|
318
|
+
* two therefore address different readers and must not be collapsed: the
|
|
319
|
+
* message names what failed in the user's terms, and the cause names which
|
|
320
|
+
* lookups came back empty for whom. Neither can name the URI — not having
|
|
321
|
+
* one IS the failure, and both sources are written together, so the typed
|
|
322
|
+
* `sourceUri` is equally empty whenever this fires.
|
|
323
|
+
*/
|
|
324
|
+
protected getFileUri(action: SaveModelAction): string;
|
|
325
|
+
/**
|
|
326
|
+
* Recompute the bound {@link ModelValidator}'s markers and push them to the
|
|
327
|
+
* client as a `SetMarkersAction` — asynchronously and independently of model
|
|
328
|
+
* rendering. Called from {@link handleModelUpdated} (which fires at `Validated`),
|
|
329
|
+
* so diagram markers refresh without gating the diagram submit on validation.
|
|
330
|
+
* No-op when no validator is bound.
|
|
331
|
+
*
|
|
332
|
+
* Always dispatched under {@link MarkersReason.BATCH}: the GLSP client's
|
|
333
|
+
* `ValidationFeedbackEmitter` keys feedback by reason and replaces the prior
|
|
334
|
+
* set, so re-pushing the full set clears stale markers (an empty set clears
|
|
335
|
+
* all once the model is valid), and sharing the tool-palette validate
|
|
336
|
+
* command's `BATCH` reason means the two paths replace rather than duplicate.
|
|
337
|
+
*/
|
|
338
|
+
refreshDiagnosticMarkers(): Promise<void>;
|
|
339
|
+
sessionDisposed(_clientSession: ClientSession): void;
|
|
340
|
+
/**
|
|
341
|
+
* Cancel any pending resubmit and drain every subscription — those registered
|
|
342
|
+
* during {@link doLoadSourceModel} and the per-secondary ones, which live
|
|
343
|
+
* outside {@link toDispose} because they come and go with the write set.
|
|
344
|
+
* Idempotent.
|
|
345
|
+
*/
|
|
346
|
+
dispose(): void;
|
|
347
|
+
}
|
|
348
|
+
//# sourceMappingURL=hydranium-glsp-storage.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"hydranium-glsp-storage.d.ts","sourceRoot":"","sources":["../../src/storage/hydranium-glsp-storage.ts"],"names":[],"mappings":"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"}
|