@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 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/storage/index.ts"],"names":[],"mappings":"AAAA;;;;;;;kFAOkF;AAElF,cAAc,6BAA6B,CAAC;AAC5C,cAAc,2BAA2B,CAAC"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
/********************************************************************************
|
|
2
|
+
* Copyright (c) 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
|
+
export * from './hydranium-glsp-storage.js';
|
|
10
|
+
export * from './save-conflict-policy.js';
|
|
11
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/storage/index.ts"],"names":[],"mappings":"AAAA;;;;;;;kFAOkF;AAElF,cAAc,6BAA6B,CAAC;AAC5C,cAAc,2BAA2B,CAAC"}
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
/********************************************************************************
|
|
2
|
+
* Copyright (c) 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
|
+
/**
|
|
10
|
+
* How `HydraniumGlspStorage.saveSourceModel` reacts when a concurrent edit has
|
|
11
|
+
* advanced the document past the version this diagram was last captured at.
|
|
12
|
+
*
|
|
13
|
+
* A save spans otherwise-independent choices — whether to guard on the captured
|
|
14
|
+
* based-on version, whether the GLSP save action awaits the persist, and what
|
|
15
|
+
* happens on failure. Each arm bundles those into one coherent, nameable policy
|
|
16
|
+
* so an adopter selects a whole behaviour rather than assembling an incoherent
|
|
17
|
+
* mix: fire-and-forget plus rethrow would leave an unhandled rejection. It is a
|
|
18
|
+
* *selection of configuration*, delivered as a bound option (see the
|
|
19
|
+
* {@link SaveConflictPolicy} symbol) rather than a behaviour hook.
|
|
20
|
+
*/
|
|
21
|
+
export type SaveConflictPolicy =
|
|
22
|
+
/**
|
|
23
|
+
* Last-write-wins: no based-on guard, await the persist, propagate any
|
|
24
|
+
* failure to the GLSP save action. The default; correct for a single-editor
|
|
25
|
+
* head where nothing races the save.
|
|
26
|
+
*/
|
|
27
|
+
{
|
|
28
|
+
kind: 'overwrite';
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* Guard on the captured version, await the persist, and surface a
|
|
32
|
+
* `ConflictError` (and any other failure) to the GLSP save action.
|
|
33
|
+
*/
|
|
34
|
+
| {
|
|
35
|
+
kind: 'reject';
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* Guard on the captured version, fire-and-forget, and log + swallow every
|
|
39
|
+
* failure. Correct when another editor of the same document may already have
|
|
40
|
+
* written the truth, so a stale diagram save is benign and must neither
|
|
41
|
+
* block the action nor surface as an error.
|
|
42
|
+
*/
|
|
43
|
+
| {
|
|
44
|
+
kind: 'drop-and-log';
|
|
45
|
+
};
|
|
46
|
+
/** The policy applied when no {@link SaveConflictPolicy} option is bound. */
|
|
47
|
+
export declare const DEFAULT_SAVE_CONFLICT_POLICY: SaveConflictPolicy;
|
|
48
|
+
/**
|
|
49
|
+
* DI token for the {@link SaveConflictPolicy} option. Bind a constant value in a
|
|
50
|
+
* `DiagramModule` to select a non-default policy; left unbound,
|
|
51
|
+
* `HydraniumGlspStorage` falls back to
|
|
52
|
+
* {@link DEFAULT_SAVE_CONFLICT_POLICY}. Shares its name with the type, the way a
|
|
53
|
+
* `class` is both a value and a type.
|
|
54
|
+
*/
|
|
55
|
+
export declare const SaveConflictPolicy: unique symbol;
|
|
56
|
+
//# sourceMappingURL=save-conflict-policy.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"save-conflict-policy.d.ts","sourceRoot":"","sources":["../../src/storage/save-conflict-policy.ts"],"names":[],"mappings":"AAAA;;;;;;;kFAOkF;AAElF;;;;;;;;;;;GAWG;AACH,MAAM,MAAM,kBAAkB;AAC3B;;;;GAIG;AACD;IAAE,IAAI,EAAE,WAAW,CAAA;CAAE;AACvB;;;GAGG;GACD;IAAE,IAAI,EAAE,QAAQ,CAAA;CAAE;AACpB;;;;;GAKG;GACD;IAAE,IAAI,EAAE,cAAc,CAAA;CAAE,CAAC;AAE9B,6EAA6E;AAC7E,eAAO,MAAM,4BAA4B,EAAE,kBAA0C,CAAC;AAEtF;;;;;;GAMG;AACH,eAAO,MAAM,kBAAkB,eAA+B,CAAC"}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
/********************************************************************************
|
|
2
|
+
* Copyright (c) 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
|
+
/** The policy applied when no {@link SaveConflictPolicy} option is bound. */
|
|
10
|
+
export const DEFAULT_SAVE_CONFLICT_POLICY = { kind: 'overwrite' };
|
|
11
|
+
/**
|
|
12
|
+
* DI token for the {@link SaveConflictPolicy} option. Bind a constant value in a
|
|
13
|
+
* `DiagramModule` to select a non-default policy; left unbound,
|
|
14
|
+
* `HydraniumGlspStorage` falls back to
|
|
15
|
+
* {@link DEFAULT_SAVE_CONFLICT_POLICY}. Shares its name with the type, the way a
|
|
16
|
+
* `class` is both a value and a type.
|
|
17
|
+
*/
|
|
18
|
+
export const SaveConflictPolicy = Symbol('SaveConflictPolicy');
|
|
19
|
+
//# sourceMappingURL=save-conflict-policy.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"save-conflict-policy.js","sourceRoot":"","sources":["../../src/storage/save-conflict-policy.ts"],"names":[],"mappings":"AAAA;;;;;;;kFAOkF;AAkClF,6EAA6E;AAC7E,MAAM,CAAC,MAAM,4BAA4B,GAAuB,EAAE,IAAI,EAAE,WAAW,EAAE,CAAC;AAEtF;;;;;;GAMG;AACH,MAAM,CAAC,MAAM,kBAAkB,GAAG,MAAM,CAAC,oBAAoB,CAAC,CAAC"}
|
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
/********************************************************************************
|
|
2
|
+
* Copyright (c) 2024-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, type DirtyStateChangeReason, type GModelRootSchema, type LayoutOperation, ModelSubmissionHandler, type SetModelAction } from '@eclipse-glsp/server';
|
|
10
|
+
import { type AstNode, type DocumentState } from '@hydranium/langium';
|
|
11
|
+
import { type AbstractHydraniumGlspState } from '../state/abstract-hydranium-glsp-state.js';
|
|
12
|
+
/**
|
|
13
|
+
* GLSP {@link ModelSubmissionHandler} base shared by all hydranium adopters.
|
|
14
|
+
* Wraps {@link submitModel} with an optional document-state ready-gate and
|
|
15
|
+
* post-action observability logging; preserves the {@link createSetModeAction}
|
|
16
|
+
* handshake log; exposes a {@link hasPendingInitialRequest} guard adopters
|
|
17
|
+
* use to suppress external rebuild reactions while the initial-load
|
|
18
|
+
* `RequestModelAction` is still in flight.
|
|
19
|
+
*
|
|
20
|
+
* **What stays adopter-side.** Translation of the source AST to a GModel is
|
|
21
|
+
* owned by GLSP's existing `GModelFactory` interface, bound separately
|
|
22
|
+
* per `DiagramModule`. The submission handler is strictly orchestration —
|
|
23
|
+
* deliberately no `translateToGModel` hook here; adopters wire their per-
|
|
24
|
+
* diagram-type `GModelFactory` subclass via `bindGModelFactory()`.
|
|
25
|
+
*
|
|
26
|
+
* **Hooks.**
|
|
27
|
+
* - {@link readyEvent} — {@link DocumentState} the {@link submitModel} flow
|
|
28
|
+
* awaits via {@link AbstractHydraniumGlspState.ready} before delegating to
|
|
29
|
+
* `super.submitModel`. Default {@link IntegrityService.SettledState}
|
|
30
|
+
* (`IndexedReferences`) — the GModel-factory walk sees a fully linked AST
|
|
31
|
+
* with cross-document references resolved AND post-build integrity rules
|
|
32
|
+
* applied. Adopters that need a different phase (earlier `Linked` for
|
|
33
|
+
* simpler models, later `Validated` to consume diagnostics, or `undefined`
|
|
34
|
+
* to opt out entirely) override this field.
|
|
35
|
+
* - {@link formatSourceRoot} — adopter-specific AST description used in
|
|
36
|
+
* the submit-log line. Default returns `root.$type`.
|
|
37
|
+
*
|
|
38
|
+
* Logs through {@link AbstractHydraniumGlspState.logger} (the state's
|
|
39
|
+
* URI-tagged tracer), so it carries no log-label field of its own.
|
|
40
|
+
*/
|
|
41
|
+
export declare class HydraniumGlspSubmissionHandler<TRoot extends AstNode, TSourceModel = string> extends ModelSubmissionHandler {
|
|
42
|
+
protected modelState: AbstractHydraniumGlspState<TRoot, TSourceModel>;
|
|
43
|
+
/**
|
|
44
|
+
* Document-state gate awaited before {@link submitModel} delegates to
|
|
45
|
+
* `super.submitModel`. Default {@link IntegrityService.SettledState} so the
|
|
46
|
+
* GModel factory walks a fully-linked, integrity-settled AST out of the
|
|
47
|
+
* box. Adopters override (including to `undefined` to opt out entirely)
|
|
48
|
+
* when their submission flow doesn't need to wait.
|
|
49
|
+
*/
|
|
50
|
+
protected readyEvent: DocumentState | undefined;
|
|
51
|
+
/**
|
|
52
|
+
* True when a `RequestModelAction` has been accepted but the
|
|
53
|
+
* corresponding {@link SetModelAction} response has not yet been
|
|
54
|
+
* dispatched. Adopter storage uses this to suppress the "external
|
|
55
|
+
* submit" rebuild reaction during the initial-load handshake: that
|
|
56
|
+
* rebuild reaction would call `submitModel('external')`, which rebuilds
|
|
57
|
+
* the GModel and bumps its revision; once the revision changes, the
|
|
58
|
+
* client's first `computedBounds` (still carrying the old revision) is
|
|
59
|
+
* dropped and the initial `SetModelAction` never fires.
|
|
60
|
+
*/
|
|
61
|
+
hasPendingInitialRequest(): boolean;
|
|
62
|
+
submitModel(reason?: DirtyStateChangeReason, layout?: LayoutOperation): Promise<Action[]>;
|
|
63
|
+
/**
|
|
64
|
+
* Content signature of the last submission, whatever its reason.
|
|
65
|
+
*
|
|
66
|
+
* **Tracked across every reason because the CLIENT cannot tell them apart.**
|
|
67
|
+
* An operation submit and a later external rebuild that produce the same
|
|
68
|
+
* graph are the same delivery as far as the canvas is concerned, so a
|
|
69
|
+
* comparison scoped to one reason reports "changed" for a model the client
|
|
70
|
+
* already has. `undefined` until the first submit.
|
|
71
|
+
*/
|
|
72
|
+
get lastSubmittedSignature(): string | undefined;
|
|
73
|
+
protected _lastSubmittedSignature?: string;
|
|
74
|
+
/**
|
|
75
|
+
* Serialise the model-bearing actions of a submission into a comparable
|
|
76
|
+
* signature.
|
|
77
|
+
*
|
|
78
|
+
* `requestId` is fresh per action and `revision` is a monotonic `GModelRoot`
|
|
79
|
+
* counter bumped on every rebuild, so neither reflects content.
|
|
80
|
+
*
|
|
81
|
+
* **`SetDirtyStateAction` is dropped whole rather than having its `reason`
|
|
82
|
+
* stripped by key, and the distinction is load-bearing.** Measured: an
|
|
83
|
+
* operation submit and the external rebuild echoing it are byte-identical
|
|
84
|
+
* across the entire GModel and differ only in that action's `reason`, so
|
|
85
|
+
* leaving it in defeats the comparison outright. Stripping the KEY instead
|
|
86
|
+
* would reach further than intended — `reason` carries meaning on other
|
|
87
|
+
* actions, `SetMarkersAction` among them — and would quietly weaken any
|
|
88
|
+
* later comparison that includes one. Dropping the action also keeps
|
|
89
|
+
* `isDirty` out, which is correct: dirty state is not part of "is this the
|
|
90
|
+
* same model", and a genuine dirty-to-clean change must not be suppressed as
|
|
91
|
+
* a duplicate model.
|
|
92
|
+
*/
|
|
93
|
+
protected signatureOf(actions: Action[]): string;
|
|
94
|
+
/**
|
|
95
|
+
* Logs the {@link SetModelAction} dispatch so the initial
|
|
96
|
+
* `requestModel → setModel` handshake is observable in the server log
|
|
97
|
+
* alongside `Submit model` and `ComputedBounds accepted`.
|
|
98
|
+
*/
|
|
99
|
+
protected createSetModeAction(newRoot: GModelRootSchema): SetModelAction;
|
|
100
|
+
protected logSubmit(reason: DirtyStateChangeReason | undefined, actions: Action[]): void;
|
|
101
|
+
/**
|
|
102
|
+
* Hook for adopter-specific AST description in the submit-log line.
|
|
103
|
+
* Default returns `root.$type` (or `'none'` when the source root is
|
|
104
|
+
* undefined). Adopters with multi-shape source roots override to add
|
|
105
|
+
* per-shape detail.
|
|
106
|
+
*/
|
|
107
|
+
protected formatSourceRoot(root: TRoot | undefined): string;
|
|
108
|
+
}
|
|
109
|
+
//# sourceMappingURL=hydranium-glsp-submission-handler.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"hydranium-glsp-submission-handler.d.ts","sourceRoot":"","sources":["../../src/submission/hydranium-glsp-submission-handler.ts"],"names":[],"mappings":"AAAA;;;;;;;kFAOkF;AAElF,OAAO,EACJ,KAAK,MAAM,EACX,KAAK,sBAAsB,EAC3B,KAAK,gBAAgB,EACrB,KAAK,eAAe,EAEpB,sBAAsB,EAEtB,KAAK,cAAc,EACrB,MAAM,sBAAsB,CAAC;AAG9B,OAAO,EAAE,KAAK,OAAO,EAAE,KAAK,aAAa,EAAE,MAAM,oBAAoB,CAAC;AACtE,OAAO,EAAE,KAAK,0BAA0B,EAAE,MAAM,2CAA2C,CAAC;AAE5F;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG;AACH,qBACa,8BAA8B,CAAC,KAAK,SAAS,OAAO,EAAE,YAAY,GAAG,MAAM,CAAE,SAAQ,sBAAsB;IACrH,UAAsC,UAAU,EAAE,0BAA0B,CAAC,KAAK,EAAE,YAAY,CAAC,CAAC;IAElG;;;;;;OAMG;IACH,SAAS,CAAC,UAAU,EAAE,aAAa,GAAG,SAAS,CAAiC;IAEhF;;;;;;;;;OASG;IACH,wBAAwB,IAAI,OAAO;IAIpB,WAAW,CAAC,MAAM,CAAC,EAAE,sBAAsB,EAAE,MAAM,CAAC,EAAE,eAAe,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC;IAcxG;;;;;;;;OAQG;IACH,IAAI,sBAAsB,IAAI,MAAM,GAAG,SAAS,CAE/C;IAED,SAAS,CAAC,uBAAuB,CAAC,EAAE,MAAM,CAAC;IAE3C;;;;;;;;;;;;;;;;;;OAkBG;IACH,SAAS,CAAC,WAAW,CAAC,OAAO,EAAE,MAAM,EAAE,GAAG,MAAM;IAOhD;;;;OAIG;cACgB,mBAAmB,CAAC,OAAO,EAAE,gBAAgB,GAAG,cAAc;IAQjF,SAAS,CAAC,SAAS,CAAC,MAAM,EAAE,sBAAsB,GAAG,SAAS,EAAE,OAAO,EAAE,MAAM,EAAE,GAAG,IAAI;IAYxF;;;;;OAKG;IACH,SAAS,CAAC,gBAAgB,CAAC,IAAI,EAAE,KAAK,GAAG,SAAS,GAAG,MAAM;CAG7D"}
|
|
@@ -0,0 +1,157 @@
|
|
|
1
|
+
/********************************************************************************
|
|
2
|
+
* Copyright (c) 2024-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
|
+
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
|
10
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
11
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
12
|
+
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
13
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
14
|
+
};
|
|
15
|
+
var __metadata = (this && this.__metadata) || function (k, v) {
|
|
16
|
+
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
|
17
|
+
};
|
|
18
|
+
import { ModelState, ModelSubmissionHandler, SetDirtyStateAction } from '@eclipse-glsp/server';
|
|
19
|
+
import { IntegrityService } from '@hydranium/core';
|
|
20
|
+
import { inject, injectable } from 'inversify';
|
|
21
|
+
/**
|
|
22
|
+
* GLSP {@link ModelSubmissionHandler} base shared by all hydranium adopters.
|
|
23
|
+
* Wraps {@link submitModel} with an optional document-state ready-gate and
|
|
24
|
+
* post-action observability logging; preserves the {@link createSetModeAction}
|
|
25
|
+
* handshake log; exposes a {@link hasPendingInitialRequest} guard adopters
|
|
26
|
+
* use to suppress external rebuild reactions while the initial-load
|
|
27
|
+
* `RequestModelAction` is still in flight.
|
|
28
|
+
*
|
|
29
|
+
* **What stays adopter-side.** Translation of the source AST to a GModel is
|
|
30
|
+
* owned by GLSP's existing `GModelFactory` interface, bound separately
|
|
31
|
+
* per `DiagramModule`. The submission handler is strictly orchestration —
|
|
32
|
+
* deliberately no `translateToGModel` hook here; adopters wire their per-
|
|
33
|
+
* diagram-type `GModelFactory` subclass via `bindGModelFactory()`.
|
|
34
|
+
*
|
|
35
|
+
* **Hooks.**
|
|
36
|
+
* - {@link readyEvent} — {@link DocumentState} the {@link submitModel} flow
|
|
37
|
+
* awaits via {@link AbstractHydraniumGlspState.ready} before delegating to
|
|
38
|
+
* `super.submitModel`. Default {@link IntegrityService.SettledState}
|
|
39
|
+
* (`IndexedReferences`) — the GModel-factory walk sees a fully linked AST
|
|
40
|
+
* with cross-document references resolved AND post-build integrity rules
|
|
41
|
+
* applied. Adopters that need a different phase (earlier `Linked` for
|
|
42
|
+
* simpler models, later `Validated` to consume diagnostics, or `undefined`
|
|
43
|
+
* to opt out entirely) override this field.
|
|
44
|
+
* - {@link formatSourceRoot} — adopter-specific AST description used in
|
|
45
|
+
* the submit-log line. Default returns `root.$type`.
|
|
46
|
+
*
|
|
47
|
+
* Logs through {@link AbstractHydraniumGlspState.logger} (the state's
|
|
48
|
+
* URI-tagged tracer), so it carries no log-label field of its own.
|
|
49
|
+
*/
|
|
50
|
+
let HydraniumGlspSubmissionHandler = class HydraniumGlspSubmissionHandler extends ModelSubmissionHandler {
|
|
51
|
+
/**
|
|
52
|
+
* Document-state gate awaited before {@link submitModel} delegates to
|
|
53
|
+
* `super.submitModel`. Default {@link IntegrityService.SettledState} so the
|
|
54
|
+
* GModel factory walks a fully-linked, integrity-settled AST out of the
|
|
55
|
+
* box. Adopters override (including to `undefined` to opt out entirely)
|
|
56
|
+
* when their submission flow doesn't need to wait.
|
|
57
|
+
*/
|
|
58
|
+
readyEvent = IntegrityService.SettledState;
|
|
59
|
+
/**
|
|
60
|
+
* True when a `RequestModelAction` has been accepted but the
|
|
61
|
+
* corresponding {@link SetModelAction} response has not yet been
|
|
62
|
+
* dispatched. Adopter storage uses this to suppress the "external
|
|
63
|
+
* submit" rebuild reaction during the initial-load handshake: that
|
|
64
|
+
* rebuild reaction would call `submitModel('external')`, which rebuilds
|
|
65
|
+
* the GModel and bumps its revision; once the revision changes, the
|
|
66
|
+
* client's first `computedBounds` (still carrying the old revision) is
|
|
67
|
+
* dropped and the initial `SetModelAction` never fires.
|
|
68
|
+
*/
|
|
69
|
+
hasPendingInitialRequest() {
|
|
70
|
+
return this.requestModelAction !== undefined;
|
|
71
|
+
}
|
|
72
|
+
async submitModel(reason, layout) {
|
|
73
|
+
if (this.readyEvent !== undefined) {
|
|
74
|
+
// Adopters with on-build integrity rules wait so the GModel-factory walk sees
|
|
75
|
+
// a settled AST; otherwise the GModel could include elements the build pass is
|
|
76
|
+
// about to rewrite or remove. ready() also refreshes the captured source root
|
|
77
|
+
// via onReadyRefreshed.
|
|
78
|
+
await this.modelState.ready(this.readyEvent);
|
|
79
|
+
}
|
|
80
|
+
const actions = await super.submitModel(reason, layout);
|
|
81
|
+
this._lastSubmittedSignature = this.signatureOf(actions);
|
|
82
|
+
this.logSubmit(reason, actions);
|
|
83
|
+
return actions;
|
|
84
|
+
}
|
|
85
|
+
/**
|
|
86
|
+
* Content signature of the last submission, whatever its reason.
|
|
87
|
+
*
|
|
88
|
+
* **Tracked across every reason because the CLIENT cannot tell them apart.**
|
|
89
|
+
* An operation submit and a later external rebuild that produce the same
|
|
90
|
+
* graph are the same delivery as far as the canvas is concerned, so a
|
|
91
|
+
* comparison scoped to one reason reports "changed" for a model the client
|
|
92
|
+
* already has. `undefined` until the first submit.
|
|
93
|
+
*/
|
|
94
|
+
get lastSubmittedSignature() {
|
|
95
|
+
return this._lastSubmittedSignature;
|
|
96
|
+
}
|
|
97
|
+
_lastSubmittedSignature;
|
|
98
|
+
/**
|
|
99
|
+
* Serialise the model-bearing actions of a submission into a comparable
|
|
100
|
+
* signature.
|
|
101
|
+
*
|
|
102
|
+
* `requestId` is fresh per action and `revision` is a monotonic `GModelRoot`
|
|
103
|
+
* counter bumped on every rebuild, so neither reflects content.
|
|
104
|
+
*
|
|
105
|
+
* **`SetDirtyStateAction` is dropped whole rather than having its `reason`
|
|
106
|
+
* stripped by key, and the distinction is load-bearing.** Measured: an
|
|
107
|
+
* operation submit and the external rebuild echoing it are byte-identical
|
|
108
|
+
* across the entire GModel and differ only in that action's `reason`, so
|
|
109
|
+
* leaving it in defeats the comparison outright. Stripping the KEY instead
|
|
110
|
+
* would reach further than intended — `reason` carries meaning on other
|
|
111
|
+
* actions, `SetMarkersAction` among them — and would quietly weaken any
|
|
112
|
+
* later comparison that includes one. Dropping the action also keeps
|
|
113
|
+
* `isDirty` out, which is correct: dirty state is not part of "is this the
|
|
114
|
+
* same model", and a genuine dirty-to-clean change must not be suppressed as
|
|
115
|
+
* a duplicate model.
|
|
116
|
+
*/
|
|
117
|
+
signatureOf(actions) {
|
|
118
|
+
return JSON.stringify(actions.filter(action => !SetDirtyStateAction.is(action)), (key, value) => (key === 'requestId' || key === 'revision' ? undefined : value));
|
|
119
|
+
}
|
|
120
|
+
/**
|
|
121
|
+
* Logs the {@link SetModelAction} dispatch so the initial
|
|
122
|
+
* `requestModel → setModel` handshake is observable in the server log
|
|
123
|
+
* alongside `Submit model` and `ComputedBounds accepted`.
|
|
124
|
+
*/
|
|
125
|
+
createSetModeAction(newRoot) {
|
|
126
|
+
const action = super.createSetModeAction(newRoot);
|
|
127
|
+
this.modelState.logger.info(`Dispatching SetModelAction (response to requestModel #${action.responseId || '?'}) — initial model handshake complete`);
|
|
128
|
+
return action;
|
|
129
|
+
}
|
|
130
|
+
logSubmit(reason, actions) {
|
|
131
|
+
const root = this.modelState.root;
|
|
132
|
+
const gChildren = root?.children?.length ?? 0;
|
|
133
|
+
const sourceRoot = this.modelState.sourceRoot;
|
|
134
|
+
const kinds = actions.map(a => a.kind).join(',');
|
|
135
|
+
this.modelState.logger.info(`Submit model [reason=${reason ?? 'initial'}, actions=[${kinds}], ` +
|
|
136
|
+
`gmodel={type=${root?.type ?? 'none'}, children=${gChildren}}, ` +
|
|
137
|
+
`ast={${this.formatSourceRoot(sourceRoot)}}]`);
|
|
138
|
+
}
|
|
139
|
+
/**
|
|
140
|
+
* Hook for adopter-specific AST description in the submit-log line.
|
|
141
|
+
* Default returns `root.$type` (or `'none'` when the source root is
|
|
142
|
+
* undefined). Adopters with multi-shape source roots override to add
|
|
143
|
+
* per-shape detail.
|
|
144
|
+
*/
|
|
145
|
+
formatSourceRoot(root) {
|
|
146
|
+
return root?.$type ?? 'none';
|
|
147
|
+
}
|
|
148
|
+
};
|
|
149
|
+
__decorate([
|
|
150
|
+
inject(ModelState),
|
|
151
|
+
__metadata("design:type", Function)
|
|
152
|
+
], HydraniumGlspSubmissionHandler.prototype, "modelState", void 0);
|
|
153
|
+
HydraniumGlspSubmissionHandler = __decorate([
|
|
154
|
+
injectable()
|
|
155
|
+
], HydraniumGlspSubmissionHandler);
|
|
156
|
+
export { HydraniumGlspSubmissionHandler };
|
|
157
|
+
//# sourceMappingURL=hydranium-glsp-submission-handler.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"hydranium-glsp-submission-handler.js","sourceRoot":"","sources":["../../src/submission/hydranium-glsp-submission-handler.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
/********************************************************************************
|
|
2
|
+
* Copyright (c) 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
|
+
export * from './hydranium-glsp-submission-handler.js';
|
|
10
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/submission/index.ts"],"names":[],"mappings":"AAAA;;;;;;;kFAOkF;AAElF,cAAc,wCAAwC,CAAC"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
/********************************************************************************
|
|
2
|
+
* Copyright (c) 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
|
+
export * from './hydranium-glsp-submission-handler.js';
|
|
10
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/submission/index.ts"],"names":[],"mappings":"AAAA;;;;;;;kFAOkF;AAElF,cAAc,wCAAwC,CAAC"}
|
|
@@ -0,0 +1,170 @@
|
|
|
1
|
+
/********************************************************************************
|
|
2
|
+
* Copyright (c) 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 'reflect-metadata';
|
|
10
|
+
import { type Action, GLSPServer } from '@eclipse-glsp/server';
|
|
11
|
+
import { Logger as GlspLogger, type ServerModule } from '@eclipse-glsp/server/node.js';
|
|
12
|
+
import { ContainerModule, type interfaces } from 'inversify';
|
|
13
|
+
import type { AstNode } from '@hydranium/langium';
|
|
14
|
+
import type { Harness } from '@hydranium/protocol/testing';
|
|
15
|
+
import type { AbstractHydraniumGlspState } from '../state/abstract-hydranium-glsp-state.js';
|
|
16
|
+
/**
|
|
17
|
+
* Options for {@link makeGlspHarness}.
|
|
18
|
+
*
|
|
19
|
+
* The harness drives a REAL {@link GLSPServer} in-process: it composes the
|
|
20
|
+
* server container the way `startGlspServer` does (framework default app
|
|
21
|
+
* module + adopter `appModules` + the adopter `serverModule`), but binds
|
|
22
|
+
* {@link GLSPClientProxy} to a capturing stub instead of a socket-backed
|
|
23
|
+
* proxy, so every action the server pushes to the client lands in the
|
|
24
|
+
* harness's `actions` capture. There is no OS socket and no JSON
|
|
25
|
+
* serialization, so nothing here covers the wire layer.
|
|
26
|
+
*
|
|
27
|
+
* `serverModule` + `diagramType` are required; everything else has a
|
|
28
|
+
* test-friendly default. The adopter's shared services / id provider /
|
|
29
|
+
* conflict resolver come from `appModules` (typically an
|
|
30
|
+
* `HydraniumGlspAppModule` subclass) — exactly as in production, so
|
|
31
|
+
* the harness binds none of them itself.
|
|
32
|
+
*/
|
|
33
|
+
export interface MakeGlspHarnessOptions {
|
|
34
|
+
/** Adopter {@link ServerModule} with its diagram module(s) pre-configured via `configureDiagramModule`. */
|
|
35
|
+
readonly serverModule: ServerModule;
|
|
36
|
+
/** Diagram type id passed to `initializeClientSession`; must match the configured diagram module. */
|
|
37
|
+
readonly diagramType: string;
|
|
38
|
+
/**
|
|
39
|
+
* Adopter Inversify modules loaded AFTER the framework default module
|
|
40
|
+
* (which binds `InjectionContainer`, GLSP's `Logger`, `LoggerFactory` and
|
|
41
|
+
* `ActionDispatchScope`). Carries the adopter's
|
|
42
|
+
* `HydraniumTypes.SharedCoreServices` / `HydraniumTypes.ConflictResolver` /
|
|
43
|
+
* language-services bindings. Per-language providers come from the diagram
|
|
44
|
+
* module instead — see `AbstractHydraniumGlspDiagramModule`.
|
|
45
|
+
*/
|
|
46
|
+
readonly appModules?: ReadonlyArray<ContainerModule>;
|
|
47
|
+
/**
|
|
48
|
+
* GLSP logger factory. Default: a silent logger (the harness keeps the
|
|
49
|
+
* test output clean). Override to capture GLSP framework log lines.
|
|
50
|
+
*/
|
|
51
|
+
readonly createLogger?: (caller?: string) => GlspLogger;
|
|
52
|
+
/** `applicationId` for the `initialize` handshake. Default `'test-app'`. */
|
|
53
|
+
readonly applicationId?: string;
|
|
54
|
+
/** Client session id used for `initializeClientSession` + every dispatched `ActionMessage`. Default `'test-session'`. */
|
|
55
|
+
readonly clientSessionId?: string;
|
|
56
|
+
/**
|
|
57
|
+
* Adopter-specific client action kinds to forward IN ADDITION to
|
|
58
|
+
* {@link DEFAULT_CLIENT_ACTION_KINDS}. The server's
|
|
59
|
+
* `ClientActionForwarder` only forwards declared kinds to the capturing
|
|
60
|
+
* `GLSPClientProxy`, so list any custom server→client action a test needs
|
|
61
|
+
* to observe. The standard set covers ordinary round-trips, so most tests
|
|
62
|
+
* leave this unset.
|
|
63
|
+
*/
|
|
64
|
+
readonly additionalClientActionKinds?: ReadonlyArray<string>;
|
|
65
|
+
}
|
|
66
|
+
/** Options for {@link GlspHarness.nextModelSubmission}. */
|
|
67
|
+
export interface NextModelSubmissionOptions {
|
|
68
|
+
/** How long to wait. Defaults to 2000ms. */
|
|
69
|
+
readonly timeoutMs?: number;
|
|
70
|
+
/**
|
|
71
|
+
* Reject on timeout (default `true`) or resolve `undefined` (`false`). Pair
|
|
72
|
+
* `false` with a short `timeoutMs` — the wait runs to completion in the
|
|
73
|
+
* passing case.
|
|
74
|
+
*/
|
|
75
|
+
readonly rejectOnTimeout?: boolean;
|
|
76
|
+
}
|
|
77
|
+
/**
|
|
78
|
+
* Bundle returned by {@link makeGlspHarness}. Satisfies the uniform
|
|
79
|
+
* {@link Harness} contract — `state` is the **subject** (the resolved adopter
|
|
80
|
+
* state under test), `server` + `dispatch`/`nextAction` are the **seam** tests
|
|
81
|
+
* drive the action round-trip through, `actions` is the **capture** of every
|
|
82
|
+
* outbound action in arrival order, and `dispose()` is the uniform teardown
|
|
83
|
+
* hook. `state` / `sessionContainer` are only valid after {@link start} (the
|
|
84
|
+
* `ModelState` lives in GLSP's per-session child container, created by
|
|
85
|
+
* `initializeClientSession`).
|
|
86
|
+
*/
|
|
87
|
+
export interface GlspHarness<TState extends AbstractHydraniumGlspState<AstNode, unknown>> extends Harness {
|
|
88
|
+
/** The real GLSP server under test. */
|
|
89
|
+
readonly server: GLSPServer;
|
|
90
|
+
/** The main (app + server) container. */
|
|
91
|
+
readonly container: interfaces.Container;
|
|
92
|
+
/** The per-session child container `initializeClientSession` created. Throws if read before {@link start}. */
|
|
93
|
+
readonly sessionContainer: interfaces.Container;
|
|
94
|
+
/** The adopter `ModelState` resolved from {@link sessionContainer}. Throws if read before {@link start}. */
|
|
95
|
+
readonly state: TState;
|
|
96
|
+
/** Every action the server pushed to the client, in arrival order. Never cleared by the harness. */
|
|
97
|
+
readonly actions: ReadonlyArray<Action>;
|
|
98
|
+
/** Drive `initialize` then `initializeClientSession`; resolve once the session container exists. */
|
|
99
|
+
start(): Promise<void>;
|
|
100
|
+
/** Drive `server.shutdown()` (disposes client sessions). */
|
|
101
|
+
shutdown(): Promise<void>;
|
|
102
|
+
/** Send an action to the server as `{ clientId, action }`. Fire-and-forget (GLSP `process` is `void`). */
|
|
103
|
+
dispatch(action: Action): void;
|
|
104
|
+
/**
|
|
105
|
+
* Resolve with the next captured action whose `kind` matches — an
|
|
106
|
+
* already-captured-but-unconsumed match resolves immediately, otherwise
|
|
107
|
+
* waits for the next arrival. Rejects after `timeoutMs` (default 2000) so
|
|
108
|
+
* a missing action fails fast instead of hanging.
|
|
109
|
+
*/
|
|
110
|
+
nextAction<T extends Action = Action>(kind: string, timeoutMs?: number): Promise<T>;
|
|
111
|
+
/**
|
|
112
|
+
* FAITHFUL fidelity: open `sourceUri` the way a client does — dispatch
|
|
113
|
+
* `RequestModelAction` with `SOURCE_URI_ARG` — and resolve with the model
|
|
114
|
+
* the server publishes in response.
|
|
115
|
+
*
|
|
116
|
+
* Resolves on **whichever** submission action the diagram produces, because
|
|
117
|
+
* that depends on its `DiagramConfiguration` rather than on the test:
|
|
118
|
+
* `SetModelAction` for a server-laid-out diagram, `RequestBoundsAction` for
|
|
119
|
+
* a client-laid-out one. Awaiting the wrong one is a 2s timeout that names
|
|
120
|
+
* the wrong subsystem, and a test should not have to know which applies.
|
|
121
|
+
*
|
|
122
|
+
* Rejects if nothing is published within `timeoutMs`. Valid only after
|
|
123
|
+
* {@link start}.
|
|
124
|
+
*/
|
|
125
|
+
openDocument(sourceUri: string, timeoutMs?: number): Promise<Action>;
|
|
126
|
+
/**
|
|
127
|
+
* Resolve with the next action that publishes a model — the settling point
|
|
128
|
+
* after an operation, since a successful operation re-submits.
|
|
129
|
+
*
|
|
130
|
+
* Kind-agnostic for the same reason as {@link openDocument}. Set
|
|
131
|
+
* `rejectOnTimeout: false` to ask whether a submission happened *at all*.
|
|
132
|
+
*/
|
|
133
|
+
nextModelSubmission(options?: NextModelSubmissionOptions): Promise<Action | undefined>;
|
|
134
|
+
/**
|
|
135
|
+
* LIGHT fidelity: seed the state's source root directly via
|
|
136
|
+
* `setSourceRoot`, bypassing source-model storage. Valid only after
|
|
137
|
+
* {@link start}.
|
|
138
|
+
*/
|
|
139
|
+
seedSourceRoot(uri: string, root: Parameters<TState['setSourceRoot']>[1]): void;
|
|
140
|
+
/** Idempotent teardown: `server.shutdown()` then `container.unbindAll()`. */
|
|
141
|
+
dispose(): void;
|
|
142
|
+
}
|
|
143
|
+
/**
|
|
144
|
+
* The actions that mean "the server published a model".
|
|
145
|
+
*
|
|
146
|
+
* Which one arrives depends on the diagram's `DiagramConfiguration`, not on
|
|
147
|
+
* what the test did: a server-laid-out diagram gets `SetModelAction`, a
|
|
148
|
+
* client-laid-out one (`needsClientLayout`) gets `RequestBoundsAction`, and a
|
|
149
|
+
* re-submit after an operation may be `UpdateModelAction`. Tests that only care
|
|
150
|
+
* *that* the model was published should not have to encode that choice — see
|
|
151
|
+
* {@link GlspHarness.nextModelSubmission}.
|
|
152
|
+
*
|
|
153
|
+
* Exported for the tests that must COUNT submissions rather than await the next
|
|
154
|
+
* one (asserting that nothing further was published, say). Re-listing the kinds
|
|
155
|
+
* in such a test is a false-green shape: a kind added here would leave the copy
|
|
156
|
+
* silently under-counting.
|
|
157
|
+
*/
|
|
158
|
+
export declare const MODEL_SUBMISSION_KINDS: ReadonlyArray<string>;
|
|
159
|
+
/**
|
|
160
|
+
* Wire a real {@link GLSPServer} in-process and drive a GLSP action
|
|
161
|
+
* round-trip against it — dispatch an action → operation/request handler →
|
|
162
|
+
* GModel mutation → response action, captured via a stub
|
|
163
|
+
* {@link GLSPClientProxy}.
|
|
164
|
+
*
|
|
165
|
+
* The harness composes ONE container, collapsing production's parent
|
|
166
|
+
* app-container / per-connection child split, which exists only to share the
|
|
167
|
+
* app container across socket connections.
|
|
168
|
+
*/
|
|
169
|
+
export declare function makeGlspHarness<TState extends AbstractHydraniumGlspState<AstNode, unknown>>(options: MakeGlspHarnessOptions): GlspHarness<TState>;
|
|
170
|
+
//# sourceMappingURL=glsp-harness.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"glsp-harness.d.ts","sourceRoot":"","sources":["../../src/testing/glsp-harness.ts"],"names":[],"mappings":"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"}
|