@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.
Files changed (208) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +97 -0
  3. package/lib/browser/index.d.ts +10 -0
  4. package/lib/browser/index.d.ts.map +1 -0
  5. package/lib/browser/index.js +15 -0
  6. package/lib/browser/index.js.map +1 -0
  7. package/lib/browser/start-glsp-server-in-worker.d.ts +121 -0
  8. package/lib/browser/start-glsp-server-in-worker.d.ts.map +1 -0
  9. package/lib/browser/start-glsp-server-in-worker.js +102 -0
  10. package/lib/browser/start-glsp-server-in-worker.js.map +1 -0
  11. package/lib/command/hydranium-glsp-recording-command.d.ts +132 -0
  12. package/lib/command/hydranium-glsp-recording-command.d.ts.map +1 -0
  13. package/lib/command/hydranium-glsp-recording-command.js +159 -0
  14. package/lib/command/hydranium-glsp-recording-command.js.map +1 -0
  15. package/lib/command/index.d.ts +10 -0
  16. package/lib/command/index.d.ts.map +1 -0
  17. package/lib/command/index.js +10 -0
  18. package/lib/command/index.js.map +1 -0
  19. package/lib/computed-bounds/hydranium-glsp-computed-bounds-action-handler.d.ts +61 -0
  20. package/lib/computed-bounds/hydranium-glsp-computed-bounds-action-handler.d.ts.map +1 -0
  21. package/lib/computed-bounds/hydranium-glsp-computed-bounds-action-handler.js +93 -0
  22. package/lib/computed-bounds/hydranium-glsp-computed-bounds-action-handler.js.map +1 -0
  23. package/lib/computed-bounds/index.d.ts +10 -0
  24. package/lib/computed-bounds/index.d.ts.map +1 -0
  25. package/lib/computed-bounds/index.js +10 -0
  26. package/lib/computed-bounds/index.js.map +1 -0
  27. package/lib/dispatcher/index.d.ts +10 -0
  28. package/lib/dispatcher/index.d.ts.map +1 -0
  29. package/lib/dispatcher/index.js +10 -0
  30. package/lib/dispatcher/index.js.map +1 -0
  31. package/lib/dispatcher/server-action-dispatcher.d.ts +52 -0
  32. package/lib/dispatcher/server-action-dispatcher.d.ts.map +1 -0
  33. package/lib/dispatcher/server-action-dispatcher.js +79 -0
  34. package/lib/dispatcher/server-action-dispatcher.js.map +1 -0
  35. package/lib/index.d.ts +19 -0
  36. package/lib/index.d.ts.map +1 -0
  37. package/lib/index.js +20 -0
  38. package/lib/index.js.map +1 -0
  39. package/lib/launcher/abstract-hydranium-glsp-diagram-module.d.ts +75 -0
  40. package/lib/launcher/abstract-hydranium-glsp-diagram-module.d.ts.map +1 -0
  41. package/lib/launcher/abstract-hydranium-glsp-diagram-module.js +100 -0
  42. package/lib/launcher/abstract-hydranium-glsp-diagram-module.js.map +1 -0
  43. package/lib/launcher/glsp-app-module.d.ts +87 -0
  44. package/lib/launcher/glsp-app-module.d.ts.map +1 -0
  45. package/lib/launcher/glsp-app-module.js +71 -0
  46. package/lib/launcher/glsp-app-module.js.map +1 -0
  47. package/lib/launcher/glsp-framework-overrides.d.ts +32 -0
  48. package/lib/launcher/glsp-framework-overrides.d.ts.map +1 -0
  49. package/lib/launcher/glsp-framework-overrides.js +49 -0
  50. package/lib/launcher/glsp-framework-overrides.js.map +1 -0
  51. package/lib/launcher/glsp-server-overrides.d.ts +39 -0
  52. package/lib/launcher/glsp-server-overrides.d.ts.map +1 -0
  53. package/lib/launcher/glsp-server-overrides.js +45 -0
  54. package/lib/launcher/glsp-server-overrides.js.map +1 -0
  55. package/lib/launcher/hydranium-glsp-server.d.ts +62 -0
  56. package/lib/launcher/hydranium-glsp-server.d.ts.map +1 -0
  57. package/lib/launcher/hydranium-glsp-server.js +101 -0
  58. package/lib/launcher/hydranium-glsp-server.js.map +1 -0
  59. package/lib/launcher/index.d.ts +12 -0
  60. package/lib/launcher/index.d.ts.map +1 -0
  61. package/lib/launcher/index.js +22 -0
  62. package/lib/launcher/index.js.map +1 -0
  63. package/lib/logging/glsp-client-logger.d.ts +110 -0
  64. package/lib/logging/glsp-client-logger.d.ts.map +1 -0
  65. package/lib/logging/glsp-client-logger.js +151 -0
  66. package/lib/logging/glsp-client-logger.js.map +1 -0
  67. package/lib/logging/index.d.ts +10 -0
  68. package/lib/logging/index.d.ts.map +1 -0
  69. package/lib/logging/index.js +10 -0
  70. package/lib/logging/index.js.map +1 -0
  71. package/lib/node/index.d.ts +10 -0
  72. package/lib/node/index.d.ts.map +1 -0
  73. package/lib/node/index.js +13 -0
  74. package/lib/node/index.js.map +1 -0
  75. package/lib/node/start-glsp-server.d.ts +122 -0
  76. package/lib/node/start-glsp-server.d.ts.map +1 -0
  77. package/lib/node/start-glsp-server.js +103 -0
  78. package/lib/node/start-glsp-server.js.map +1 -0
  79. package/lib/state/abstract-hydranium-glsp-state.d.ts +333 -0
  80. package/lib/state/abstract-hydranium-glsp-state.d.ts.map +1 -0
  81. package/lib/state/abstract-hydranium-glsp-state.js +451 -0
  82. package/lib/state/abstract-hydranium-glsp-state.js.map +1 -0
  83. package/lib/state/full-text-hydranium-glsp-state.d.ts +43 -0
  84. package/lib/state/full-text-hydranium-glsp-state.d.ts.map +1 -0
  85. package/lib/state/full-text-hydranium-glsp-state.js +60 -0
  86. package/lib/state/full-text-hydranium-glsp-state.js.map +1 -0
  87. package/lib/state/hydranium-glsp-index.d.ts +220 -0
  88. package/lib/state/hydranium-glsp-index.d.ts.map +1 -0
  89. package/lib/state/hydranium-glsp-index.js +320 -0
  90. package/lib/state/hydranium-glsp-index.js.map +1 -0
  91. package/lib/state/hydranium-shared-core-services.d.ts +90 -0
  92. package/lib/state/hydranium-shared-core-services.d.ts.map +1 -0
  93. package/lib/state/hydranium-shared-core-services.js +89 -0
  94. package/lib/state/hydranium-shared-core-services.js.map +1 -0
  95. package/lib/state/index.d.ts +17 -0
  96. package/lib/state/index.d.ts.map +1 -0
  97. package/lib/state/index.js +17 -0
  98. package/lib/state/index.js.map +1 -0
  99. package/lib/state/model-ready-timeout-error.d.ts +28 -0
  100. package/lib/state/model-ready-timeout-error.d.ts.map +1 -0
  101. package/lib/state/model-ready-timeout-error.js +36 -0
  102. package/lib/state/model-ready-timeout-error.js.map +1 -0
  103. package/lib/state/reconcile-source-model-write.d.ts +43 -0
  104. package/lib/state/reconcile-source-model-write.d.ts.map +1 -0
  105. package/lib/state/reconcile-source-model-write.js +47 -0
  106. package/lib/state/reconcile-source-model-write.js.map +1 -0
  107. package/lib/state/reconciling-multi-document-glsp-state.d.ts +164 -0
  108. package/lib/state/reconciling-multi-document-glsp-state.d.ts.map +1 -0
  109. package/lib/state/reconciling-multi-document-glsp-state.js +222 -0
  110. package/lib/state/reconciling-multi-document-glsp-state.js.map +1 -0
  111. package/lib/state/reconciling-transfer-hydranium-glsp-state.d.ts +91 -0
  112. package/lib/state/reconciling-transfer-hydranium-glsp-state.d.ts.map +1 -0
  113. package/lib/state/reconciling-transfer-hydranium-glsp-state.js +129 -0
  114. package/lib/state/reconciling-transfer-hydranium-glsp-state.js.map +1 -0
  115. package/lib/storage/hydranium-glsp-storage.d.ts +348 -0
  116. package/lib/storage/hydranium-glsp-storage.d.ts.map +1 -0
  117. package/lib/storage/hydranium-glsp-storage.js +634 -0
  118. package/lib/storage/hydranium-glsp-storage.js.map +1 -0
  119. package/lib/storage/index.d.ts +11 -0
  120. package/lib/storage/index.d.ts.map +1 -0
  121. package/lib/storage/index.js +11 -0
  122. package/lib/storage/index.js.map +1 -0
  123. package/lib/storage/save-conflict-policy.d.ts +56 -0
  124. package/lib/storage/save-conflict-policy.d.ts.map +1 -0
  125. package/lib/storage/save-conflict-policy.js +19 -0
  126. package/lib/storage/save-conflict-policy.js.map +1 -0
  127. package/lib/submission/hydranium-glsp-submission-handler.d.ts +109 -0
  128. package/lib/submission/hydranium-glsp-submission-handler.d.ts.map +1 -0
  129. package/lib/submission/hydranium-glsp-submission-handler.js +157 -0
  130. package/lib/submission/hydranium-glsp-submission-handler.js.map +1 -0
  131. package/lib/submission/index.d.ts +10 -0
  132. package/lib/submission/index.d.ts.map +1 -0
  133. package/lib/submission/index.js +10 -0
  134. package/lib/submission/index.js.map +1 -0
  135. package/lib/testing/glsp-harness.d.ts +170 -0
  136. package/lib/testing/glsp-harness.d.ts.map +1 -0
  137. package/lib/testing/glsp-harness.js +231 -0
  138. package/lib/testing/glsp-harness.js.map +1 -0
  139. package/lib/testing/index.d.ts +11 -0
  140. package/lib/testing/index.d.ts.map +1 -0
  141. package/lib/testing/index.js +13 -0
  142. package/lib/testing/index.js.map +1 -0
  143. package/lib/testing/make-noop-glsp-logger.d.ts +42 -0
  144. package/lib/testing/make-noop-glsp-logger.d.ts.map +1 -0
  145. package/lib/testing/make-noop-glsp-logger.js +47 -0
  146. package/lib/testing/make-noop-glsp-logger.js.map +1 -0
  147. package/lib/util/index.d.ts +10 -0
  148. package/lib/util/index.d.ts.map +1 -0
  149. package/lib/util/index.js +10 -0
  150. package/lib/util/index.js.map +1 -0
  151. package/lib/util/service-identifier.d.ts +46 -0
  152. package/lib/util/service-identifier.d.ts.map +1 -0
  153. package/lib/util/service-identifier.js +47 -0
  154. package/lib/util/service-identifier.js.map +1 -0
  155. package/lib/validation/diagnostic-markers.d.ts +48 -0
  156. package/lib/validation/diagnostic-markers.d.ts.map +1 -0
  157. package/lib/validation/diagnostic-markers.js +68 -0
  158. package/lib/validation/diagnostic-markers.js.map +1 -0
  159. package/lib/validation/hydranium-glsp-model-validator.d.ts +51 -0
  160. package/lib/validation/hydranium-glsp-model-validator.d.ts.map +1 -0
  161. package/lib/validation/hydranium-glsp-model-validator.js +118 -0
  162. package/lib/validation/hydranium-glsp-model-validator.js.map +1 -0
  163. package/lib/validation/index.d.ts +11 -0
  164. package/lib/validation/index.d.ts.map +1 -0
  165. package/lib/validation/index.js +11 -0
  166. package/lib/validation/index.js.map +1 -0
  167. package/package.json +111 -0
  168. package/src/browser/index.ts +15 -0
  169. package/src/browser/start-glsp-server-in-worker.ts +202 -0
  170. package/src/command/hydranium-glsp-recording-command.ts +183 -0
  171. package/src/command/index.ts +10 -0
  172. package/src/computed-bounds/hydranium-glsp-computed-bounds-action-handler.ts +103 -0
  173. package/src/computed-bounds/index.ts +10 -0
  174. package/src/dispatcher/index.ts +10 -0
  175. package/src/dispatcher/server-action-dispatcher.ts +72 -0
  176. package/src/index.ts +20 -0
  177. package/src/launcher/abstract-hydranium-glsp-diagram-module.ts +117 -0
  178. package/src/launcher/glsp-app-module.ts +106 -0
  179. package/src/launcher/glsp-framework-overrides.ts +51 -0
  180. package/src/launcher/glsp-server-overrides.ts +46 -0
  181. package/src/launcher/hydranium-glsp-server.ts +104 -0
  182. package/src/launcher/index.ts +22 -0
  183. package/src/logging/glsp-client-logger.ts +184 -0
  184. package/src/logging/index.ts +10 -0
  185. package/src/node/index.ts +13 -0
  186. package/src/node/start-glsp-server.ts +214 -0
  187. package/src/state/abstract-hydranium-glsp-state.ts +503 -0
  188. package/src/state/full-text-hydranium-glsp-state.ts +63 -0
  189. package/src/state/hydranium-glsp-index.ts +337 -0
  190. package/src/state/hydranium-shared-core-services.ts +92 -0
  191. package/src/state/index.ts +17 -0
  192. package/src/state/model-ready-timeout-error.ts +33 -0
  193. package/src/state/reconcile-source-model-write.ts +77 -0
  194. package/src/state/reconciling-multi-document-glsp-state.ts +248 -0
  195. package/src/state/reconciling-transfer-hydranium-glsp-state.ts +132 -0
  196. package/src/storage/hydranium-glsp-storage.ts +660 -0
  197. package/src/storage/index.ts +11 -0
  198. package/src/storage/save-conflict-policy.ts +52 -0
  199. package/src/submission/hydranium-glsp-submission-handler.ts +170 -0
  200. package/src/submission/index.ts +10 -0
  201. package/src/testing/glsp-harness.ts +422 -0
  202. package/src/testing/index.ts +14 -0
  203. package/src/testing/make-noop-glsp-logger.ts +66 -0
  204. package/src/util/index.ts +10 -0
  205. package/src/util/service-identifier.ts +49 -0
  206. package/src/validation/diagnostic-markers.ts +93 -0
  207. package/src/validation/hydranium-glsp-model-validator.ts +105 -0
  208. 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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"}