@hydranium/glsp-server 1.0.0-next.31 → 1.0.0-next.315

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 (217) hide show
  1. package/README.md +80 -88
  2. package/lib/browser/start-glsp-server-in-worker.d.ts +43 -42
  3. package/lib/browser/start-glsp-server-in-worker.d.ts.map +1 -1
  4. package/lib/browser/start-glsp-server-in-worker.js +62 -13
  5. package/lib/browser/start-glsp-server-in-worker.js.map +1 -1
  6. package/lib/command/diagram-edit-dropped-error.d.ts +31 -0
  7. package/lib/command/diagram-edit-dropped-error.d.ts.map +1 -0
  8. package/lib/command/diagram-edit-dropped-error.js +48 -0
  9. package/lib/command/diagram-edit-dropped-error.js.map +1 -0
  10. package/lib/command/hydranium-glsp-command-stack.d.ts +33 -0
  11. package/lib/command/hydranium-glsp-command-stack.d.ts.map +1 -0
  12. package/lib/command/hydranium-glsp-command-stack.js +63 -0
  13. package/lib/command/hydranium-glsp-command-stack.js.map +1 -0
  14. package/lib/command/hydranium-glsp-operation-action-handler.d.ts +64 -0
  15. package/lib/command/hydranium-glsp-operation-action-handler.d.ts.map +1 -0
  16. package/lib/command/hydranium-glsp-operation-action-handler.js +142 -0
  17. package/lib/command/hydranium-glsp-operation-action-handler.js.map +1 -0
  18. package/lib/command/hydranium-glsp-operation-command.d.ts +250 -0
  19. package/lib/command/hydranium-glsp-operation-command.d.ts.map +1 -0
  20. package/lib/command/hydranium-glsp-operation-command.js +491 -0
  21. package/lib/command/hydranium-glsp-operation-command.js.map +1 -0
  22. package/lib/command/hydranium-glsp-recording-command.d.ts +26 -87
  23. package/lib/command/hydranium-glsp-recording-command.d.ts.map +1 -1
  24. package/lib/command/hydranium-glsp-recording-command.js +40 -117
  25. package/lib/command/hydranium-glsp-recording-command.js.map +1 -1
  26. package/lib/command/hydranium-glsp-undo-redo-action-handler.d.ts +23 -0
  27. package/lib/command/hydranium-glsp-undo-redo-action-handler.d.ts.map +1 -0
  28. package/lib/command/hydranium-glsp-undo-redo-action-handler.js +41 -0
  29. package/lib/command/hydranium-glsp-undo-redo-action-handler.js.map +1 -0
  30. package/lib/command/index.d.ts +5 -0
  31. package/lib/command/index.d.ts.map +1 -1
  32. package/lib/command/index.js +5 -0
  33. package/lib/command/index.js.map +1 -1
  34. package/lib/computed-bounds/hydranium-glsp-computed-bounds-action-handler.d.ts +1 -1
  35. package/lib/computed-bounds/hydranium-glsp-computed-bounds-action-handler.d.ts.map +1 -1
  36. package/lib/computed-bounds/hydranium-glsp-computed-bounds-action-handler.js +2 -2
  37. package/lib/computed-bounds/hydranium-glsp-computed-bounds-action-handler.js.map +1 -1
  38. package/lib/dispatcher/server-action-dispatcher.d.ts +25 -24
  39. package/lib/dispatcher/server-action-dispatcher.d.ts.map +1 -1
  40. package/lib/dispatcher/server-action-dispatcher.js +38 -26
  41. package/lib/dispatcher/server-action-dispatcher.js.map +1 -1
  42. package/lib/index.d.ts +1 -0
  43. package/lib/index.d.ts.map +1 -1
  44. package/lib/index.js +1 -0
  45. package/lib/index.js.map +1 -1
  46. package/lib/launcher/abstract-hydranium-glsp-diagram-module.d.ts +35 -59
  47. package/lib/launcher/abstract-hydranium-glsp-diagram-module.d.ts.map +1 -1
  48. package/lib/launcher/abstract-hydranium-glsp-diagram-module.js +60 -71
  49. package/lib/launcher/abstract-hydranium-glsp-diagram-module.js.map +1 -1
  50. package/lib/launcher/drop-notifications-to-gone-client.d.ts +23 -0
  51. package/lib/launcher/drop-notifications-to-gone-client.d.ts.map +1 -0
  52. package/lib/launcher/drop-notifications-to-gone-client.js +43 -0
  53. package/lib/launcher/drop-notifications-to-gone-client.js.map +1 -0
  54. package/lib/launcher/glsp-app-module.d.ts +1 -2
  55. package/lib/launcher/glsp-app-module.d.ts.map +1 -1
  56. package/lib/launcher/glsp-app-module.js.map +1 -1
  57. package/lib/launcher/glsp-connection-logger.d.ts +19 -0
  58. package/lib/launcher/glsp-connection-logger.d.ts.map +1 -0
  59. package/lib/launcher/glsp-connection-logger.js +24 -0
  60. package/lib/launcher/glsp-connection-logger.js.map +1 -0
  61. package/lib/launcher/glsp-server-overrides.d.ts +10 -8
  62. package/lib/launcher/glsp-server-overrides.d.ts.map +1 -1
  63. package/lib/launcher/glsp-server-overrides.js +25 -11
  64. package/lib/launcher/glsp-server-overrides.js.map +1 -1
  65. package/lib/launcher/hydranium-glsp-server.d.ts +60 -15
  66. package/lib/launcher/hydranium-glsp-server.d.ts.map +1 -1
  67. package/lib/launcher/hydranium-glsp-server.js +145 -22
  68. package/lib/launcher/hydranium-glsp-server.js.map +1 -1
  69. package/lib/launcher/index.d.ts +2 -0
  70. package/lib/launcher/index.d.ts.map +1 -1
  71. package/lib/launcher/index.js +5 -4
  72. package/lib/launcher/index.js.map +1 -1
  73. package/lib/logging/glsp-client-logger.d.ts +10 -6
  74. package/lib/logging/glsp-client-logger.d.ts.map +1 -1
  75. package/lib/logging/glsp-client-logger.js +14 -7
  76. package/lib/logging/glsp-client-logger.js.map +1 -1
  77. package/lib/messages/index.d.ts +11 -6
  78. package/lib/messages/index.d.ts.map +1 -1
  79. package/lib/messages/index.js +11 -6
  80. package/lib/messages/index.js.map +1 -1
  81. package/lib/node/start-glsp-server.d.ts +50 -15
  82. package/lib/node/start-glsp-server.d.ts.map +1 -1
  83. package/lib/node/start-glsp-server.js +97 -30
  84. package/lib/node/start-glsp-server.js.map +1 -1
  85. package/lib/state/abstract-hydranium-glsp-state.d.ts +326 -102
  86. package/lib/state/abstract-hydranium-glsp-state.d.ts.map +1 -1
  87. package/lib/state/abstract-hydranium-glsp-state.js +529 -139
  88. package/lib/state/abstract-hydranium-glsp-state.js.map +1 -1
  89. package/lib/state/diagram-status.d.ts +38 -0
  90. package/lib/state/diagram-status.d.ts.map +1 -0
  91. package/lib/state/diagram-status.js +27 -0
  92. package/lib/state/diagram-status.js.map +1 -0
  93. package/lib/state/full-text-hydranium-glsp-state.d.ts +22 -9
  94. package/lib/state/full-text-hydranium-glsp-state.d.ts.map +1 -1
  95. package/lib/state/full-text-hydranium-glsp-state.js +45 -18
  96. package/lib/state/full-text-hydranium-glsp-state.js.map +1 -1
  97. package/lib/state/hydranium-glsp-index.d.ts +40 -29
  98. package/lib/state/hydranium-glsp-index.d.ts.map +1 -1
  99. package/lib/state/hydranium-glsp-index.js +82 -45
  100. package/lib/state/hydranium-glsp-index.js.map +1 -1
  101. package/lib/state/hydranium-shared-core-services.d.ts +16 -29
  102. package/lib/state/hydranium-shared-core-services.d.ts.map +1 -1
  103. package/lib/state/hydranium-shared-core-services.js +15 -28
  104. package/lib/state/hydranium-shared-core-services.js.map +1 -1
  105. package/lib/state/index.d.ts +1 -0
  106. package/lib/state/index.d.ts.map +1 -1
  107. package/lib/state/index.js +1 -0
  108. package/lib/state/index.js.map +1 -1
  109. package/lib/state/model-ready-timeout-error.d.ts.map +1 -1
  110. package/lib/state/model-ready-timeout-error.js.map +1 -1
  111. package/lib/state/reconcile-source-model-write.d.ts +13 -27
  112. package/lib/state/reconcile-source-model-write.d.ts.map +1 -1
  113. package/lib/state/reconcile-source-model-write.js +44 -32
  114. package/lib/state/reconcile-source-model-write.js.map +1 -1
  115. package/lib/state/reconciling-multi-document-glsp-state.d.ts +125 -69
  116. package/lib/state/reconciling-multi-document-glsp-state.d.ts.map +1 -1
  117. package/lib/state/reconciling-multi-document-glsp-state.js +242 -100
  118. package/lib/state/reconciling-multi-document-glsp-state.js.map +1 -1
  119. package/lib/state/reconciling-transfer-hydranium-glsp-state.d.ts +36 -28
  120. package/lib/state/reconciling-transfer-hydranium-glsp-state.d.ts.map +1 -1
  121. package/lib/state/reconciling-transfer-hydranium-glsp-state.js +59 -42
  122. package/lib/state/reconciling-transfer-hydranium-glsp-state.js.map +1 -1
  123. package/lib/status/diagram-status-reporter.d.ts +44 -0
  124. package/lib/status/diagram-status-reporter.d.ts.map +1 -0
  125. package/lib/status/diagram-status-reporter.js +88 -0
  126. package/lib/status/diagram-status-reporter.js.map +1 -0
  127. package/lib/status/hydranium-glsp-request-model-action-handler.d.ts +27 -0
  128. package/lib/status/hydranium-glsp-request-model-action-handler.d.ts.map +1 -0
  129. package/lib/status/hydranium-glsp-request-model-action-handler.js +52 -0
  130. package/lib/status/hydranium-glsp-request-model-action-handler.js.map +1 -0
  131. package/lib/status/hydranium-glsp-set-edit-mode-action-handler.d.ts +27 -0
  132. package/lib/status/hydranium-glsp-set-edit-mode-action-handler.d.ts.map +1 -0
  133. package/lib/status/hydranium-glsp-set-edit-mode-action-handler.js +53 -0
  134. package/lib/status/hydranium-glsp-set-edit-mode-action-handler.js.map +1 -0
  135. package/lib/status/index.d.ts +12 -0
  136. package/lib/status/index.d.ts.map +1 -0
  137. package/lib/status/index.js +12 -0
  138. package/lib/status/index.js.map +1 -0
  139. package/lib/storage/hydranium-glsp-request-save-model-action-handler.d.ts +30 -0
  140. package/lib/storage/hydranium-glsp-request-save-model-action-handler.d.ts.map +1 -0
  141. package/lib/storage/hydranium-glsp-request-save-model-action-handler.js +47 -0
  142. package/lib/storage/hydranium-glsp-request-save-model-action-handler.js.map +1 -0
  143. package/lib/storage/hydranium-glsp-storage.d.ts +324 -143
  144. package/lib/storage/hydranium-glsp-storage.d.ts.map +1 -1
  145. package/lib/storage/hydranium-glsp-storage.js +569 -213
  146. package/lib/storage/hydranium-glsp-storage.js.map +1 -1
  147. package/lib/storage/index.d.ts +2 -1
  148. package/lib/storage/index.d.ts.map +1 -1
  149. package/lib/storage/index.js +2 -1
  150. package/lib/storage/index.js.map +1 -1
  151. package/lib/storage/save-delivery-policy.d.ts +51 -0
  152. package/lib/storage/save-delivery-policy.d.ts.map +1 -0
  153. package/lib/storage/{save-conflict-policy.js → save-delivery-policy.js} +7 -8
  154. package/lib/storage/save-delivery-policy.js.map +1 -0
  155. package/lib/submission/hydranium-glsp-submission-handler.d.ts +44 -4
  156. package/lib/submission/hydranium-glsp-submission-handler.d.ts.map +1 -1
  157. package/lib/submission/hydranium-glsp-submission-handler.js +82 -6
  158. package/lib/submission/hydranium-glsp-submission-handler.js.map +1 -1
  159. package/lib/testing/glsp-harness.d.ts +34 -7
  160. package/lib/testing/glsp-harness.d.ts.map +1 -1
  161. package/lib/testing/glsp-harness.js +47 -19
  162. package/lib/testing/glsp-harness.js.map +1 -1
  163. package/lib/validation/diagnostic-markers.d.ts +3 -3
  164. package/lib/validation/diagnostic-markers.d.ts.map +1 -1
  165. package/lib/validation/diagnostic-markers.js +1 -1
  166. package/lib/validation/diagnostic-markers.js.map +1 -1
  167. package/lib/validation/hydranium-glsp-model-validator.d.ts +1 -2
  168. package/lib/validation/hydranium-glsp-model-validator.d.ts.map +1 -1
  169. package/lib/validation/hydranium-glsp-model-validator.js +1 -1
  170. package/lib/validation/hydranium-glsp-model-validator.js.map +1 -1
  171. package/package.json +31 -52
  172. package/src/browser/start-glsp-server-in-worker.ts +79 -51
  173. package/src/command/diagram-edit-dropped-error.ts +51 -0
  174. package/src/command/hydranium-glsp-command-stack.ts +47 -0
  175. package/src/command/hydranium-glsp-operation-action-handler.ts +141 -0
  176. package/src/command/hydranium-glsp-operation-command.ts +602 -0
  177. package/src/command/hydranium-glsp-recording-command.ts +40 -121
  178. package/src/command/hydranium-glsp-undo-redo-action-handler.ts +29 -0
  179. package/src/command/index.ts +10 -0
  180. package/src/computed-bounds/hydranium-glsp-computed-bounds-action-handler.ts +2 -2
  181. package/src/dispatcher/server-action-dispatcher.ts +39 -31
  182. package/src/index.ts +1 -0
  183. package/src/launcher/abstract-hydranium-glsp-diagram-module.ts +79 -91
  184. package/src/launcher/drop-notifications-to-gone-client.ts +47 -0
  185. package/src/launcher/glsp-app-module.ts +1 -2
  186. package/src/launcher/glsp-connection-logger.ts +27 -0
  187. package/src/launcher/glsp-server-overrides.ts +27 -11
  188. package/src/launcher/hydranium-glsp-server.ts +153 -23
  189. package/src/launcher/index.ts +5 -4
  190. package/src/logging/glsp-client-logger.ts +16 -9
  191. package/src/messages/index.ts +16 -6
  192. package/src/node/start-glsp-server.ts +133 -40
  193. package/src/state/abstract-hydranium-glsp-state.ts +609 -154
  194. package/src/state/diagram-status.ts +41 -0
  195. package/src/state/full-text-hydranium-glsp-state.ts +46 -18
  196. package/src/state/hydranium-glsp-index.ts +85 -41
  197. package/src/state/hydranium-shared-core-services.ts +16 -29
  198. package/src/state/index.ts +1 -0
  199. package/src/state/reconcile-source-model-write.ts +51 -53
  200. package/src/state/reconciling-multi-document-glsp-state.ts +276 -102
  201. package/src/state/reconciling-transfer-hydranium-glsp-state.ts +67 -45
  202. package/src/status/diagram-status-reporter.ts +106 -0
  203. package/src/status/hydranium-glsp-request-model-action-handler.ts +43 -0
  204. package/src/status/hydranium-glsp-set-edit-mode-action-handler.ts +38 -0
  205. package/src/status/index.ts +12 -0
  206. package/src/storage/hydranium-glsp-request-save-model-action-handler.ts +40 -0
  207. package/src/storage/hydranium-glsp-storage.ts +647 -223
  208. package/src/storage/index.ts +2 -1
  209. package/src/storage/save-delivery-policy.ts +49 -0
  210. package/src/submission/hydranium-glsp-submission-handler.ts +91 -5
  211. package/src/testing/glsp-harness.ts +67 -25
  212. package/src/validation/diagnostic-markers.ts +3 -3
  213. package/src/validation/hydranium-glsp-model-validator.ts +4 -5
  214. package/lib/storage/save-conflict-policy.d.ts +0 -56
  215. package/lib/storage/save-conflict-policy.d.ts.map +0 -1
  216. package/lib/storage/save-conflict-policy.js.map +0 -1
  217. package/src/storage/save-conflict-policy.ts +0 -52
@@ -8,8 +8,10 @@
8
8
  ********************************************************************************/
9
9
  import { type JsonModelState } from '@eclipse-glsp/server';
10
10
  import { type AstNode } from '@hydranium/langium';
11
- import { type TransferElement } from '@hydranium/protocol';
11
+ import { type ClientSession } from '@hydranium/core';
12
+ import { type BaseVersion, type ModelVersion, type TextVersion, type TransferElement, type VersionedModel } from '@hydranium/protocol';
12
13
  import { AbstractHydraniumGlspState } from './abstract-hydranium-glsp-state.js';
14
+ import { type OperationTransition } from '../command/hydranium-glsp-operation-command.js';
13
15
  /**
14
16
  * Source model spanning more than one document: the primary document's
15
17
  * projection plus one per registered secondary, keyed by URI.
@@ -26,6 +28,10 @@ export interface MultiDocumentSourceModel<TPrimary extends TransferElement = Tra
26
28
  /** Projection of each registered secondary document, keyed by its URI. */
27
29
  secondaries: Record<string, TransferElement>;
28
30
  }
31
+ /** A write set, with the version of each secondary's text it was projected from, keyed by URI. */
32
+ export interface VersionedMultiDocumentSourceModel<TPrimary extends TransferElement = TransferElement> extends VersionedModel<MultiDocumentSourceModel<TPrimary>> {
33
+ readonly secondaryVersions: Readonly<Record<string, ModelVersion>>;
34
+ }
29
35
  /**
30
36
  * Editable GLSP state for a diagram whose edits span SEVERAL Langium documents —
31
37
  * a diagram file plus the semantic file it references, say, where creating a node
@@ -39,43 +45,33 @@ export interface MultiDocumentSourceModel<TPrimary extends TransferElement = Tra
39
45
  * defines them over the primary plus the secondary write set registered through
40
46
  * {@link AbstractHydraniumGlspState.trackSecondaryDocument}.
41
47
  *
42
- * **Writes are NOT atomic, deliberately, and the window is real.** Each document
43
- * goes through its own `ModelService.update`, so a failure after the first write
44
- * has landed leaves the set inconsistent on disk. There is no multi-document
45
- * transaction to lean on: `WorkspaceLock` serialises builds but does not roll
46
- * back, and the document store commits per URI. An adopter that cannot accept the
47
- * window should not span documents in one operation.
48
+ * **The write set is written all or none.** {@link persist} hands every
49
+ * changed document to one `ClientSession.updateAll` on the diagram's session,
50
+ * so a conflict on any document leaves every document of the set as it was,
51
+ * and write order carries no meaning.
48
52
  *
49
- * **What makes the window tolerable is write ORDER, and the rule is
50
- * referenced-before-referencing** — not "secondaries first" as such. Write the
51
- * document whose content the others point AT before the documents that point at
52
- * it, so a partial write leaves an unreferenced element (inert, and the direction
53
- * an integrity rule can repair) rather than a reference to something that does
54
- * not exist (a linking error). {@link persist} implements that as
55
- * secondaries-then-primary, which is correct for the common shape where the
56
- * primary is the DIAGRAM and the semantics it references are secondaries: the
57
- * user opened the diagram, so it is also the document the conflict gate should
58
- * guard. **An adopter whose primary is the referenced document — a semantic file
59
- * as the diagram source, with layout in a secondary — has the ordering backwards
60
- * and must override {@link persist} to write the primary first.** Overriding it
61
- * is the supported route; the base order is a default for the common case, not an
62
- * invariant of the class.
53
+ * **Every document of the set is gated.** The primary on the caller's
54
+ * `baseVersion`, each secondary on {@link secondaryBaseVersion}, by default the version
55
+ * it had when the source root was last read. A conflict on any of them is
56
+ * reconciled against the whole write set, and the merged retry is gated on
57
+ * the versions its refetch read. A write based on `'any'` — an undo or redo
58
+ * applying a recorded patch — forces every document of the set.
63
59
  *
64
- * **The conflict gate covers the primary only.** Secondaries are written without
65
- * a based-on version, so a concurrent foreign edit to one is overwritten rather
66
- * than reconciled. Gating them too would need a per-document reconcile whose
67
- * outcomes can disagree (merge one, conflict another) with no way to un-write the
68
- * merged one — the atomicity problem again, one layer up. The captured versions
69
- * ARE available via {@link AbstractHydraniumGlspState.capturedVersionOf}, so an
70
- * adopter that wants a coarser check can compare before writing.
60
+ * A secondary is written only while the diagram's session has it open. The
61
+ * storage opens it as it joins the write set, and {@link openForWrite} opens it
62
+ * again before each write; an adopter whose write set can name a document that
63
+ * does not exist yet overrides {@link openForWrite} to create it through
64
+ * {@link createSecondaryDocument}.
71
65
  */
72
66
  export declare class ReconcilingMultiDocumentGlspState<TRoot extends AstNode, TPrimary extends TransferElement = TransferElement> extends AbstractHydraniumGlspState<TRoot, MultiDocumentSourceModel<TPrimary>> implements JsonModelState<MultiDocumentSourceModel<TPrimary>> {
73
67
  /**
74
- * Last in-sync projection across the whole write set, captured on every
75
- * {@link setSourceRoot}. Same role as the single-document baseline: the state a
76
- * forward-write conflict reconciles the user's intent against.
68
+ * The projection across the whole write set that a forward-write conflict
69
+ * reconciles the user's intent from, taken from the built roots on every
70
+ * capture.
77
71
  */
78
- protected baseline?: MultiDocumentSourceModel<TPrimary>;
72
+ protected base: MultiDocumentSourceModel<TPrimary>;
73
+ /** The documents {@link createSecondaryDocument} created for the {@link persist} under way, with the version each was created at. */
74
+ protected readonly createdForWrite: Map<string, number>;
79
75
  /**
80
76
  * Projection of the primary plus every registered secondary, in the framework
81
77
  * encoder's `'grammar'` mode (authored state only — cross-references as
@@ -88,19 +84,40 @@ export declare class ReconcilingMultiDocumentGlspState<TRoot extends AstNode, TP
88
84
  * persist as a deletion of content the state simply could not see.
89
85
  */
90
86
  get sourceModel(): MultiDocumentSourceModel<TPrimary>;
91
- setSourceRoot(uri: string, root: TRoot): void;
87
+ protected captureSourceRoot(uri: string, root: TRoot): void;
88
+ /**
89
+ * Each document whose ends differ, either end serialized for its URI and
90
+ * parsed back; a document equal on both ends is left as it is, since it
91
+ * stays out of the transition's patch anyway.
92
+ */
93
+ normalizeTransition(transition: OperationTransition<MultiDocumentSourceModel<TPrimary>>): Promise<OperationTransition<MultiDocumentSourceModel<TPrimary>>>;
94
+ /**
95
+ * Also takes a secondary first tracked during an operation into the base
96
+ * and into the operation's projection from before its command, both from
97
+ * the root its version was read from: a conflict on it reconciles from the
98
+ * revision the operation's copy describes, and undoing the operation
99
+ * restores it. A document that does not exist yet has no projection to
100
+ * restore, so an undo leaves what the operation wrote into it.
101
+ */
102
+ trackSecondaryDocument(uri: string): void;
103
+ /**
104
+ * During an operation, also drops the untracked documents from its
105
+ * projection from before its command: they are not written, so the
106
+ * operation's undo and redo leave them as they are.
107
+ */
108
+ untrackSecondaryDocuments(): void;
92
109
  /**
93
110
  * Register the secondary documents that belong to the primary at `uri`, via
94
111
  * {@link AbstractHydraniumGlspState.trackSecondaryDocument}. Called on every
95
- * {@link setSourceRoot}, after the primary is captured (so `sourceUri` is
96
- * current) and BEFORE the baseline is taken (so the baseline includes them).
112
+ * capture, after the primary is captured (so `sourceUri` is current) and
113
+ * BEFORE the base is taken (so the base includes them).
97
114
  * Default: no secondaries.
98
115
  *
99
116
  * This hook exists because that ordering is a trap an adopter would otherwise
100
- * hit silently. Registering from an overridden `setSourceRoot` *after*
101
- * `super.setSourceRoot(...)` runs too late — the baseline has already been
117
+ * hit silently. Registering from an overridden `captureSourceRoot` *after*
118
+ * `super.captureSourceRoot(...)` runs too late — the base has already been
102
119
  * captured without the secondaries, so the first conflict reconcile measures
103
- * the user's intent against a baseline missing half the write set and the
120
+ * the user's intent against a base missing half the write set and the
104
121
  * secondary edits look like foreign changes. Registering *before* the super
105
122
  * call is too early for a URI derived from the new primary. Overriding this
106
123
  * instead removes the choice.
@@ -108,55 +125,94 @@ export declare class ReconcilingMultiDocumentGlspState<TRoot extends AstNode, TP
108
125
  protected trackWriteSet(_uri: string): void;
109
126
  /**
110
127
  * Persist the whole write set, then capture the resulting primary root. On a
111
- * `ConflictError` from the primary, reconcile via the injected policy exactly
112
- * as the single-document state does — the orchestration is shared.
128
+ * `ConflictError` from any document of the set, reconcile via the injected
129
+ * policy exactly as the single-document state does — the orchestration is
130
+ * shared.
113
131
  */
114
- updateSourceModel(model: MultiDocumentSourceModel<TPrimary>, version?: number): Promise<void>;
132
+ updateSourceModel(model: MultiDocumentSourceModel<TPrimary>, baseVersion?: BaseVersion): Promise<void>;
115
133
  /**
116
- * Write hook — secondaries first (ungated), primary last (gated on
117
- * `baseVersion`). The order is the failure-mode choice documented on the
118
- * class, not incidental: override this when the primary is the document the
119
- * others REFERENCE, since then this order writes the references first.
134
+ * Write hook — every document of `model` that changed, opened first through
135
+ * {@link openForWrite}, in one `updateAll` on the diagram's session: the
136
+ * primary gated on `baseVersion`, each secondary on its entry in
137
+ * `secondaryVersions` (a refetch's) or else {@link secondaryBaseVersion}, or
138
+ * every document on `'any'` when `baseVersion` is `'any'`. Resolves to
139
+ * the primary's root, the one already captured when the primary did not
140
+ * change. A write that bypasses `updateAll` gives up the all-or-none
141
+ * guarantee the class describes. Throws without a session
142
+ * ({@link requireModelSession}). An override that serializes otherwise than
143
+ * `ModelService.modelToText` overrides {@link normalizeTransition} alongside.
144
+ *
145
+ * A write that fails closes every document {@link createSecondaryDocument}
146
+ * created for it that {@link closesCreatedDocument} accepts.
120
147
  */
121
- protected persist(model: MultiDocumentSourceModel<TPrimary>, baseVersion?: number): Promise<{
148
+ protected persist(model: MultiDocumentSourceModel<TPrimary>, baseVersion: BaseVersion, secondaryVersions?: Readonly<Record<string, ModelVersion>>): Promise<{
122
149
  root: TRoot;
123
150
  }>;
124
151
  /**
125
- * Whether `candidate` differs from the baseline projection of the same
152
+ * Whether a write that failed closes `uri`, which
153
+ * {@link createSecondaryDocument} created for it at `createdVersion`.
154
+ * Default: while it still holds the text it was created with. Left open, it
155
+ * would stay in the diagram's session, and the diagram's next save would
156
+ * write it to disk though no write landed in it. One whose text moved on,
157
+ * because the set failed after applying or another client wrote to it,
158
+ * stays open: closing it would drop that text.
159
+ */
160
+ protected closesCreatedDocument(uri: string, createdVersion: TextVersion): boolean;
161
+ /**
162
+ * Whether `candidate` differs from the base projection of the same
126
163
  * document, and therefore needs writing.
127
164
  *
128
165
  * **Skipping unchanged documents is correctness, not an optimisation.** A
129
- * write goes through `ModelService.update`, which re-serializes from the AST —
130
- * so writing a document that did not change still rewrites its text, and a
131
- * serializer is free to normalise formatting and cannot preserve comments.
132
- * Persisting the whole write set unconditionally therefore means a pure layout
133
- * drag reflows the semantic file and strips its comments, which is a data
134
- * loss the user never asked for and would struggle to attribute.
166
+ * write re-serializes from the AST, so writing a document that did not
167
+ * change still rewrites its text in the serializer's own layout. Persisting
168
+ * the whole write set unconditionally therefore means a pure layout drag
169
+ * reflows the semantic file, a change the user never asked for and would
170
+ * struggle to attribute. Comments survive that rewrite, but the
171
+ * hand-formatting around them does not.
135
172
  *
136
173
  * Compared by serialised form. Both sides come from the same encoder walking
137
174
  * the same shape, so key order is stable and a string compare is sound here;
138
175
  * it is also cheap enough to run per document per write.
139
176
  */
140
- protected hasChanged(baseline: object | undefined, candidate: object): boolean;
141
- /** Write the primary document, opting into the conflict gate when `baseVersion` is given. */
142
- protected persistPrimary(model: TPrimary, baseVersion?: number): Promise<{
143
- root: TRoot;
144
- }>;
177
+ protected hasChanged(base: object | undefined, candidate: object): boolean;
178
+ /**
179
+ * Make sure the diagram's session has `uri` open before the write set is
180
+ * written. Default: open it, a no-op for a document the session already
181
+ * has open. Override to create a document the write set names before it
182
+ * exists, through {@link createSecondaryDocument}: `updateAll` opens nothing.
183
+ */
184
+ protected openForWrite(session: ClientSession<AstNode>, uri: string): Promise<void>;
185
+ /**
186
+ * Create the secondary `uri` holding `text` through `session.create`, and
187
+ * base its write on the version the created document took. The version
188
+ * recorded while it did not exist matches no write, so the write conflicts.
189
+ * Make `text` with `ModelService.modelToText`, not the bare serializer,
190
+ * which leaves the file without the ending a write would give it.
191
+ */
192
+ protected createSecondaryDocument(session: ClientSession<AstNode>, uri: string, text: string): Promise<void>;
193
+ /**
194
+ * What a secondary write declares it was based on. Default: the version the
195
+ * secondary had when the source root was last read
196
+ * ({@link AbstractHydraniumGlspState.baseVersionOf}), so a foreign edit
197
+ * to it since is reported as a conflict and reconciled rather than
198
+ * overwritten; `'any'` for a secondary with no recorded version.
199
+ * Return `'any'` to force secondary writes.
200
+ */
201
+ protected secondaryBaseVersion(uri: string): BaseVersion;
145
202
  /**
146
- * Write one secondary document. Ungated by design (see the class doc); override
147
- * alongside {@link persistPrimary} when the round-trip differs per document
148
- * role — a layout file and a semantic file need not share a serializer.
203
+ * Refetch hook — the current projection across the write set, each document
204
+ * read through {@link AbstractHydraniumGlspState.readCurrentRoot}, with the
205
+ * versions read alongside: theirs, which the conflict resolver replays the
206
+ * user's intent onto. Returns `undefined` when the PRIMARY cannot be read,
207
+ * since a reconcile without it has nothing to merge into; an unreadable
208
+ * secondary is omitted the same way {@link sourceModel} omits one.
149
209
  */
150
- protected persistSecondary(uri: string, model: TransferElement): Promise<void>;
210
+ protected refetch(): Promise<VersionedMultiDocumentSourceModel<TPrimary> | undefined>;
151
211
  /**
152
- * Refetch hook — the current settled projection across the write set, used by
153
- * the conflict resolver to replay the user's intent against fresh state.
154
- * Returns `undefined` when the PRIMARY cannot be read, since a reconcile
155
- * without it has nothing to merge into; an unreadable secondary is omitted the
156
- * same way {@link sourceModel} omits one.
212
+ * Project a currently-loaded document's root, or `undefined` when it is not
213
+ * loaded: the open operation's copy of it when there is one, which is where
214
+ * a handler's edit of it is, else the root its version was read from.
157
215
  */
158
- protected refetch(): Promise<MultiDocumentSourceModel<TPrimary> | undefined>;
159
- /** Project a currently-loaded document's root, or `undefined` when it is not loaded. */
160
216
  protected projectDocument(uri: string): TransferElement | undefined;
161
217
  /** Grammar-mode transfer projection of one AST root. The single projection seam. */
162
218
  protected projectRoot<T extends TransferElement = TransferElement>(root: AstNode): T;
@@ -1 +1 @@
1
- {"version":3,"file":"reconciling-multi-document-glsp-state.d.ts","sourceRoot":"","sources":["../../src/state/reconciling-multi-document-glsp-state.ts"],"names":[],"mappings":"AAAA;;;;;;;kFAOkF;AAElF,OAAO,EAAE,KAAK,cAAc,EAAE,MAAM,sBAAsB,CAAC;AAE3D,OAAO,EAAE,KAAK,OAAO,EAAE,MAAM,oBAAoB,CAAC;AAClD,OAAO,EAAE,KAAK,eAAe,EAAE,MAAM,qBAAqB,CAAC;AAC3D,OAAO,EAAE,0BAA0B,EAAE,MAAM,oCAAoC,CAAC;AAGhF;;;;;;;;;GASG;AACH,MAAM,WAAW,wBAAwB,CAAC,QAAQ,SAAS,eAAe,GAAG,eAAe;IACzF,gFAAgF;IAChF,OAAO,EAAE,QAAQ,CAAC;IAClB,0EAA0E;IAC1E,WAAW,EAAE,MAAM,CAAC,MAAM,EAAE,eAAe,CAAC,CAAC;CAC/C;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA0CG;AACH,qBACa,iCAAiC,CAAC,KAAK,SAAS,OAAO,EAAE,QAAQ,SAAS,eAAe,GAAG,eAAe,CACrH,SAAQ,0BAA0B,CAAC,KAAK,EAAE,wBAAwB,CAAC,QAAQ,CAAC,CAC5E,YAAW,cAAc,CAAC,wBAAwB,CAAC,QAAQ,CAAC,CAAC;IAE7D;;;;OAIG;IACH,SAAS,CAAC,QAAQ,CAAC,EAAE,wBAAwB,CAAC,QAAQ,CAAC,CAAC;IAExD;;;;;;;;;;OAUG;IACH,IAAI,WAAW,IAAI,wBAAwB,CAAC,QAAQ,CAAC,CASpD;IAEQ,aAAa,CAAC,GAAG,EAAE,MAAM,EAAE,IAAI,EAAE,KAAK,GAAG,IAAI;IAMtD;;;;;;;;;;;;;;;OAeG;IACH,SAAS,CAAC,aAAa,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI;IAI3C;;;;OAIG;IACG,iBAAiB,CAAC,KAAK,EAAE,wBAAwB,CAAC,QAAQ,CAAC,EAAE,OAAO,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAcnG;;;;;OAKG;cACa,OAAO,CAAC,KAAK,EAAE,wBAAwB,CAAC,QAAQ,CAAC,EAAE,WAAW,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC;QAAE,IAAI,EAAE,KAAK,CAAA;KAAE,CAAC;IAclH;;;;;;;;;;;;;;;OAeG;IACH,SAAS,CAAC,UAAU,CAAC,QAAQ,EAAE,MAAM,GAAG,SAAS,EAAE,SAAS,EAAE,MAAM,GAAG,OAAO;IAI9E,6FAA6F;cAC7E,cAAc,CAAC,KAAK,EAAE,QAAQ,EAAE,WAAW,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC;QAAE,IAAI,EAAE,KAAK,CAAA;KAAE,CAAC;IAU/F;;;;OAIG;cACa,gBAAgB,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,eAAe,GAAG,OAAO,CAAC,IAAI,CAAC;IAIpF;;;;;;OAMG;cACa,OAAO,IAAI,OAAO,CAAC,wBAAwB,CAAC,QAAQ,CAAC,GAAG,SAAS,CAAC;IAelF,wFAAwF;IACxF,SAAS,CAAC,eAAe,CAAC,GAAG,EAAE,MAAM,GAAG,eAAe,GAAG,SAAS;IAKnE,oFAAoF;IACpF,SAAS,CAAC,WAAW,CAAC,CAAC,SAAS,eAAe,GAAG,eAAe,EAAE,IAAI,EAAE,OAAO,GAAG,CAAC;CAGtF"}
1
+ {"version":3,"file":"reconciling-multi-document-glsp-state.d.ts","sourceRoot":"","sources":["../../src/state/reconciling-multi-document-glsp-state.ts"],"names":[],"mappings":"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"}