@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.
- package/README.md +80 -88
- package/lib/browser/start-glsp-server-in-worker.d.ts +43 -42
- package/lib/browser/start-glsp-server-in-worker.d.ts.map +1 -1
- package/lib/browser/start-glsp-server-in-worker.js +62 -13
- package/lib/browser/start-glsp-server-in-worker.js.map +1 -1
- package/lib/command/diagram-edit-dropped-error.d.ts +31 -0
- package/lib/command/diagram-edit-dropped-error.d.ts.map +1 -0
- package/lib/command/diagram-edit-dropped-error.js +48 -0
- package/lib/command/diagram-edit-dropped-error.js.map +1 -0
- package/lib/command/hydranium-glsp-command-stack.d.ts +33 -0
- package/lib/command/hydranium-glsp-command-stack.d.ts.map +1 -0
- package/lib/command/hydranium-glsp-command-stack.js +63 -0
- package/lib/command/hydranium-glsp-command-stack.js.map +1 -0
- package/lib/command/hydranium-glsp-operation-action-handler.d.ts +64 -0
- package/lib/command/hydranium-glsp-operation-action-handler.d.ts.map +1 -0
- package/lib/command/hydranium-glsp-operation-action-handler.js +142 -0
- package/lib/command/hydranium-glsp-operation-action-handler.js.map +1 -0
- package/lib/command/hydranium-glsp-operation-command.d.ts +250 -0
- package/lib/command/hydranium-glsp-operation-command.d.ts.map +1 -0
- package/lib/command/hydranium-glsp-operation-command.js +491 -0
- package/lib/command/hydranium-glsp-operation-command.js.map +1 -0
- package/lib/command/hydranium-glsp-recording-command.d.ts +26 -87
- package/lib/command/hydranium-glsp-recording-command.d.ts.map +1 -1
- package/lib/command/hydranium-glsp-recording-command.js +40 -117
- package/lib/command/hydranium-glsp-recording-command.js.map +1 -1
- package/lib/command/hydranium-glsp-undo-redo-action-handler.d.ts +23 -0
- package/lib/command/hydranium-glsp-undo-redo-action-handler.d.ts.map +1 -0
- package/lib/command/hydranium-glsp-undo-redo-action-handler.js +41 -0
- package/lib/command/hydranium-glsp-undo-redo-action-handler.js.map +1 -0
- package/lib/command/index.d.ts +5 -0
- package/lib/command/index.d.ts.map +1 -1
- package/lib/command/index.js +5 -0
- package/lib/command/index.js.map +1 -1
- package/lib/computed-bounds/hydranium-glsp-computed-bounds-action-handler.d.ts +1 -1
- package/lib/computed-bounds/hydranium-glsp-computed-bounds-action-handler.d.ts.map +1 -1
- package/lib/computed-bounds/hydranium-glsp-computed-bounds-action-handler.js +2 -2
- package/lib/computed-bounds/hydranium-glsp-computed-bounds-action-handler.js.map +1 -1
- package/lib/dispatcher/server-action-dispatcher.d.ts +25 -24
- package/lib/dispatcher/server-action-dispatcher.d.ts.map +1 -1
- package/lib/dispatcher/server-action-dispatcher.js +38 -26
- package/lib/dispatcher/server-action-dispatcher.js.map +1 -1
- package/lib/index.d.ts +1 -0
- package/lib/index.d.ts.map +1 -1
- package/lib/index.js +1 -0
- package/lib/index.js.map +1 -1
- package/lib/launcher/abstract-hydranium-glsp-diagram-module.d.ts +35 -59
- package/lib/launcher/abstract-hydranium-glsp-diagram-module.d.ts.map +1 -1
- package/lib/launcher/abstract-hydranium-glsp-diagram-module.js +60 -71
- package/lib/launcher/abstract-hydranium-glsp-diagram-module.js.map +1 -1
- package/lib/launcher/drop-notifications-to-gone-client.d.ts +23 -0
- package/lib/launcher/drop-notifications-to-gone-client.d.ts.map +1 -0
- package/lib/launcher/drop-notifications-to-gone-client.js +43 -0
- package/lib/launcher/drop-notifications-to-gone-client.js.map +1 -0
- package/lib/launcher/glsp-app-module.d.ts +1 -2
- package/lib/launcher/glsp-app-module.d.ts.map +1 -1
- package/lib/launcher/glsp-app-module.js.map +1 -1
- package/lib/launcher/glsp-connection-logger.d.ts +19 -0
- package/lib/launcher/glsp-connection-logger.d.ts.map +1 -0
- package/lib/launcher/glsp-connection-logger.js +24 -0
- package/lib/launcher/glsp-connection-logger.js.map +1 -0
- package/lib/launcher/glsp-server-overrides.d.ts +10 -8
- package/lib/launcher/glsp-server-overrides.d.ts.map +1 -1
- package/lib/launcher/glsp-server-overrides.js +25 -11
- package/lib/launcher/glsp-server-overrides.js.map +1 -1
- package/lib/launcher/hydranium-glsp-server.d.ts +60 -15
- package/lib/launcher/hydranium-glsp-server.d.ts.map +1 -1
- package/lib/launcher/hydranium-glsp-server.js +145 -22
- package/lib/launcher/hydranium-glsp-server.js.map +1 -1
- package/lib/launcher/index.d.ts +2 -0
- package/lib/launcher/index.d.ts.map +1 -1
- package/lib/launcher/index.js +5 -4
- package/lib/launcher/index.js.map +1 -1
- package/lib/logging/glsp-client-logger.d.ts +10 -6
- package/lib/logging/glsp-client-logger.d.ts.map +1 -1
- package/lib/logging/glsp-client-logger.js +14 -7
- package/lib/logging/glsp-client-logger.js.map +1 -1
- package/lib/messages/index.d.ts +11 -6
- package/lib/messages/index.d.ts.map +1 -1
- package/lib/messages/index.js +11 -6
- package/lib/messages/index.js.map +1 -1
- package/lib/node/start-glsp-server.d.ts +50 -15
- package/lib/node/start-glsp-server.d.ts.map +1 -1
- package/lib/node/start-glsp-server.js +97 -30
- package/lib/node/start-glsp-server.js.map +1 -1
- package/lib/state/abstract-hydranium-glsp-state.d.ts +326 -102
- package/lib/state/abstract-hydranium-glsp-state.d.ts.map +1 -1
- package/lib/state/abstract-hydranium-glsp-state.js +529 -139
- package/lib/state/abstract-hydranium-glsp-state.js.map +1 -1
- package/lib/state/diagram-status.d.ts +38 -0
- package/lib/state/diagram-status.d.ts.map +1 -0
- package/lib/state/diagram-status.js +27 -0
- package/lib/state/diagram-status.js.map +1 -0
- package/lib/state/full-text-hydranium-glsp-state.d.ts +22 -9
- package/lib/state/full-text-hydranium-glsp-state.d.ts.map +1 -1
- package/lib/state/full-text-hydranium-glsp-state.js +45 -18
- package/lib/state/full-text-hydranium-glsp-state.js.map +1 -1
- package/lib/state/hydranium-glsp-index.d.ts +40 -29
- package/lib/state/hydranium-glsp-index.d.ts.map +1 -1
- package/lib/state/hydranium-glsp-index.js +82 -45
- package/lib/state/hydranium-glsp-index.js.map +1 -1
- package/lib/state/hydranium-shared-core-services.d.ts +16 -29
- package/lib/state/hydranium-shared-core-services.d.ts.map +1 -1
- package/lib/state/hydranium-shared-core-services.js +15 -28
- package/lib/state/hydranium-shared-core-services.js.map +1 -1
- package/lib/state/index.d.ts +1 -0
- package/lib/state/index.d.ts.map +1 -1
- package/lib/state/index.js +1 -0
- package/lib/state/index.js.map +1 -1
- package/lib/state/model-ready-timeout-error.d.ts.map +1 -1
- package/lib/state/model-ready-timeout-error.js.map +1 -1
- package/lib/state/reconcile-source-model-write.d.ts +13 -27
- package/lib/state/reconcile-source-model-write.d.ts.map +1 -1
- package/lib/state/reconcile-source-model-write.js +44 -32
- package/lib/state/reconcile-source-model-write.js.map +1 -1
- package/lib/state/reconciling-multi-document-glsp-state.d.ts +125 -69
- package/lib/state/reconciling-multi-document-glsp-state.d.ts.map +1 -1
- package/lib/state/reconciling-multi-document-glsp-state.js +242 -100
- package/lib/state/reconciling-multi-document-glsp-state.js.map +1 -1
- package/lib/state/reconciling-transfer-hydranium-glsp-state.d.ts +36 -28
- package/lib/state/reconciling-transfer-hydranium-glsp-state.d.ts.map +1 -1
- package/lib/state/reconciling-transfer-hydranium-glsp-state.js +59 -42
- package/lib/state/reconciling-transfer-hydranium-glsp-state.js.map +1 -1
- package/lib/status/diagram-status-reporter.d.ts +44 -0
- package/lib/status/diagram-status-reporter.d.ts.map +1 -0
- package/lib/status/diagram-status-reporter.js +88 -0
- package/lib/status/diagram-status-reporter.js.map +1 -0
- package/lib/status/hydranium-glsp-request-model-action-handler.d.ts +27 -0
- package/lib/status/hydranium-glsp-request-model-action-handler.d.ts.map +1 -0
- package/lib/status/hydranium-glsp-request-model-action-handler.js +52 -0
- package/lib/status/hydranium-glsp-request-model-action-handler.js.map +1 -0
- package/lib/status/hydranium-glsp-set-edit-mode-action-handler.d.ts +27 -0
- package/lib/status/hydranium-glsp-set-edit-mode-action-handler.d.ts.map +1 -0
- package/lib/status/hydranium-glsp-set-edit-mode-action-handler.js +53 -0
- package/lib/status/hydranium-glsp-set-edit-mode-action-handler.js.map +1 -0
- package/lib/status/index.d.ts +12 -0
- package/lib/status/index.d.ts.map +1 -0
- package/lib/status/index.js +12 -0
- package/lib/status/index.js.map +1 -0
- package/lib/storage/hydranium-glsp-request-save-model-action-handler.d.ts +30 -0
- package/lib/storage/hydranium-glsp-request-save-model-action-handler.d.ts.map +1 -0
- package/lib/storage/hydranium-glsp-request-save-model-action-handler.js +47 -0
- package/lib/storage/hydranium-glsp-request-save-model-action-handler.js.map +1 -0
- package/lib/storage/hydranium-glsp-storage.d.ts +324 -143
- package/lib/storage/hydranium-glsp-storage.d.ts.map +1 -1
- package/lib/storage/hydranium-glsp-storage.js +569 -213
- package/lib/storage/hydranium-glsp-storage.js.map +1 -1
- package/lib/storage/index.d.ts +2 -1
- package/lib/storage/index.d.ts.map +1 -1
- package/lib/storage/index.js +2 -1
- package/lib/storage/index.js.map +1 -1
- package/lib/storage/save-delivery-policy.d.ts +51 -0
- package/lib/storage/save-delivery-policy.d.ts.map +1 -0
- package/lib/storage/{save-conflict-policy.js → save-delivery-policy.js} +7 -8
- package/lib/storage/save-delivery-policy.js.map +1 -0
- package/lib/submission/hydranium-glsp-submission-handler.d.ts +44 -4
- package/lib/submission/hydranium-glsp-submission-handler.d.ts.map +1 -1
- package/lib/submission/hydranium-glsp-submission-handler.js +82 -6
- package/lib/submission/hydranium-glsp-submission-handler.js.map +1 -1
- package/lib/testing/glsp-harness.d.ts +34 -7
- package/lib/testing/glsp-harness.d.ts.map +1 -1
- package/lib/testing/glsp-harness.js +47 -19
- package/lib/testing/glsp-harness.js.map +1 -1
- package/lib/validation/diagnostic-markers.d.ts +3 -3
- package/lib/validation/diagnostic-markers.d.ts.map +1 -1
- package/lib/validation/diagnostic-markers.js +1 -1
- package/lib/validation/diagnostic-markers.js.map +1 -1
- package/lib/validation/hydranium-glsp-model-validator.d.ts +1 -2
- package/lib/validation/hydranium-glsp-model-validator.d.ts.map +1 -1
- package/lib/validation/hydranium-glsp-model-validator.js +1 -1
- package/lib/validation/hydranium-glsp-model-validator.js.map +1 -1
- package/package.json +31 -52
- package/src/browser/start-glsp-server-in-worker.ts +79 -51
- package/src/command/diagram-edit-dropped-error.ts +51 -0
- package/src/command/hydranium-glsp-command-stack.ts +47 -0
- package/src/command/hydranium-glsp-operation-action-handler.ts +141 -0
- package/src/command/hydranium-glsp-operation-command.ts +602 -0
- package/src/command/hydranium-glsp-recording-command.ts +40 -121
- package/src/command/hydranium-glsp-undo-redo-action-handler.ts +29 -0
- package/src/command/index.ts +10 -0
- package/src/computed-bounds/hydranium-glsp-computed-bounds-action-handler.ts +2 -2
- package/src/dispatcher/server-action-dispatcher.ts +39 -31
- package/src/index.ts +1 -0
- package/src/launcher/abstract-hydranium-glsp-diagram-module.ts +79 -91
- package/src/launcher/drop-notifications-to-gone-client.ts +47 -0
- package/src/launcher/glsp-app-module.ts +1 -2
- package/src/launcher/glsp-connection-logger.ts +27 -0
- package/src/launcher/glsp-server-overrides.ts +27 -11
- package/src/launcher/hydranium-glsp-server.ts +153 -23
- package/src/launcher/index.ts +5 -4
- package/src/logging/glsp-client-logger.ts +16 -9
- package/src/messages/index.ts +16 -6
- package/src/node/start-glsp-server.ts +133 -40
- package/src/state/abstract-hydranium-glsp-state.ts +609 -154
- package/src/state/diagram-status.ts +41 -0
- package/src/state/full-text-hydranium-glsp-state.ts +46 -18
- package/src/state/hydranium-glsp-index.ts +85 -41
- package/src/state/hydranium-shared-core-services.ts +16 -29
- package/src/state/index.ts +1 -0
- package/src/state/reconcile-source-model-write.ts +51 -53
- package/src/state/reconciling-multi-document-glsp-state.ts +276 -102
- package/src/state/reconciling-transfer-hydranium-glsp-state.ts +67 -45
- package/src/status/diagram-status-reporter.ts +106 -0
- package/src/status/hydranium-glsp-request-model-action-handler.ts +43 -0
- package/src/status/hydranium-glsp-set-edit-mode-action-handler.ts +38 -0
- package/src/status/index.ts +12 -0
- package/src/storage/hydranium-glsp-request-save-model-action-handler.ts +40 -0
- package/src/storage/hydranium-glsp-storage.ts +647 -223
- package/src/storage/index.ts +2 -1
- package/src/storage/save-delivery-policy.ts +49 -0
- package/src/submission/hydranium-glsp-submission-handler.ts +91 -5
- package/src/testing/glsp-harness.ts +67 -25
- package/src/validation/diagnostic-markers.ts +3 -3
- package/src/validation/hydranium-glsp-model-validator.ts +4 -5
- package/lib/storage/save-conflict-policy.d.ts +0 -56
- package/lib/storage/save-conflict-policy.d.ts.map +0 -1
- package/lib/storage/save-conflict-policy.js.map +0 -1
- package/src/storage/save-conflict-policy.ts +0 -52
|
@@ -13,7 +13,9 @@ var __decorate = (this && this.__decorate) || function (decorators, target, key,
|
|
|
13
13
|
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
14
14
|
};
|
|
15
15
|
import { injectable } from 'inversify';
|
|
16
|
+
import { asModelVersion, describeErrorWithStack } from '@hydranium/protocol';
|
|
16
17
|
import { AbstractHydraniumGlspState } from './abstract-hydranium-glsp-state.js';
|
|
18
|
+
import { openOperationOf } from '../command/hydranium-glsp-operation-command.js';
|
|
17
19
|
import { reconcileSourceModelWrite } from './reconcile-source-model-write.js';
|
|
18
20
|
/**
|
|
19
21
|
* Editable GLSP state for a diagram whose edits span SEVERAL Langium documents —
|
|
@@ -28,43 +30,33 @@ import { reconcileSourceModelWrite } from './reconcile-source-model-write.js';
|
|
|
28
30
|
* defines them over the primary plus the secondary write set registered through
|
|
29
31
|
* {@link AbstractHydraniumGlspState.trackSecondaryDocument}.
|
|
30
32
|
*
|
|
31
|
-
* **
|
|
32
|
-
*
|
|
33
|
-
*
|
|
34
|
-
*
|
|
35
|
-
* back, and the document store commits per URI. An adopter that cannot accept the
|
|
36
|
-
* window should not span documents in one operation.
|
|
33
|
+
* **The write set is written all or none.** {@link persist} hands every
|
|
34
|
+
* changed document to one `ClientSession.updateAll` on the diagram's session,
|
|
35
|
+
* so a conflict on any document leaves every document of the set as it was,
|
|
36
|
+
* and write order carries no meaning.
|
|
37
37
|
*
|
|
38
|
-
* **
|
|
39
|
-
*
|
|
40
|
-
*
|
|
41
|
-
*
|
|
42
|
-
*
|
|
43
|
-
*
|
|
44
|
-
* secondaries-then-primary, which is correct for the common shape where the
|
|
45
|
-
* primary is the DIAGRAM and the semantics it references are secondaries: the
|
|
46
|
-
* user opened the diagram, so it is also the document the conflict gate should
|
|
47
|
-
* guard. **An adopter whose primary is the referenced document — a semantic file
|
|
48
|
-
* as the diagram source, with layout in a secondary — has the ordering backwards
|
|
49
|
-
* and must override {@link persist} to write the primary first.** Overriding it
|
|
50
|
-
* is the supported route; the base order is a default for the common case, not an
|
|
51
|
-
* invariant of the class.
|
|
38
|
+
* **Every document of the set is gated.** The primary on the caller's
|
|
39
|
+
* `baseVersion`, each secondary on {@link secondaryBaseVersion}, by default the version
|
|
40
|
+
* it had when the source root was last read. A conflict on any of them is
|
|
41
|
+
* reconciled against the whole write set, and the merged retry is gated on
|
|
42
|
+
* the versions its refetch read. A write based on `'any'` — an undo or redo
|
|
43
|
+
* applying a recorded patch — forces every document of the set.
|
|
52
44
|
*
|
|
53
|
-
*
|
|
54
|
-
*
|
|
55
|
-
*
|
|
56
|
-
*
|
|
57
|
-
*
|
|
58
|
-
* ARE available via {@link AbstractHydraniumGlspState.capturedVersionOf}, so an
|
|
59
|
-
* adopter that wants a coarser check can compare before writing.
|
|
45
|
+
* A secondary is written only while the diagram's session has it open. The
|
|
46
|
+
* storage opens it as it joins the write set, and {@link openForWrite} opens it
|
|
47
|
+
* again before each write; an adopter whose write set can name a document that
|
|
48
|
+
* does not exist yet overrides {@link openForWrite} to create it through
|
|
49
|
+
* {@link createSecondaryDocument}.
|
|
60
50
|
*/
|
|
61
51
|
let ReconcilingMultiDocumentGlspState = class ReconcilingMultiDocumentGlspState extends AbstractHydraniumGlspState {
|
|
62
52
|
/**
|
|
63
|
-
*
|
|
64
|
-
*
|
|
65
|
-
*
|
|
53
|
+
* The projection across the whole write set that a forward-write conflict
|
|
54
|
+
* reconciles the user's intent from, taken from the built roots on every
|
|
55
|
+
* capture.
|
|
66
56
|
*/
|
|
67
|
-
|
|
57
|
+
base;
|
|
58
|
+
/** The documents {@link createSecondaryDocument} created for the {@link persist} under way, with the version each was created at. */
|
|
59
|
+
createdForWrite = new Map();
|
|
68
60
|
/**
|
|
69
61
|
* Projection of the primary plus every registered secondary, in the framework
|
|
70
62
|
* encoder's `'grammar'` mode (authored state only — cross-references as
|
|
@@ -84,25 +76,85 @@ let ReconcilingMultiDocumentGlspState = class ReconcilingMultiDocumentGlspState
|
|
|
84
76
|
secondaries[uri] = projection;
|
|
85
77
|
}
|
|
86
78
|
}
|
|
87
|
-
return { primary: this.projectRoot(this.
|
|
79
|
+
return { primary: this.projectRoot(this.sourceRoot), secondaries };
|
|
88
80
|
}
|
|
89
|
-
|
|
90
|
-
super.
|
|
81
|
+
captureSourceRoot(uri, root) {
|
|
82
|
+
super.captureSourceRoot(uri, root);
|
|
91
83
|
this.trackWriteSet(uri);
|
|
92
|
-
this.
|
|
84
|
+
this.base = this.sourceModel;
|
|
85
|
+
}
|
|
86
|
+
/**
|
|
87
|
+
* Each document whose ends differ, either end serialized for its URI and
|
|
88
|
+
* parsed back; a document equal on both ends is left as it is, since it
|
|
89
|
+
* stays out of the transition's patch anyway.
|
|
90
|
+
*/
|
|
91
|
+
async normalizeTransition(transition) {
|
|
92
|
+
const from = { primary: transition.from.primary, secondaries: { ...transition.from.secondaries } };
|
|
93
|
+
const to = { primary: transition.to.primary, secondaries: { ...transition.to.secondaries } };
|
|
94
|
+
if (JSON.stringify(from.primary) !== JSON.stringify(to.primary)) {
|
|
95
|
+
from.primary = this.projectRoot(await this.roundTrip(this._sourceUri, from.primary));
|
|
96
|
+
to.primary = this.projectRoot(await this.roundTrip(this._sourceUri, to.primary));
|
|
97
|
+
}
|
|
98
|
+
for (const uri of new Set([...Object.keys(from.secondaries), ...Object.keys(to.secondaries)])) {
|
|
99
|
+
if (JSON.stringify(from.secondaries[uri]) === JSON.stringify(to.secondaries[uri])) {
|
|
100
|
+
continue;
|
|
101
|
+
}
|
|
102
|
+
for (const end of [from, to]) {
|
|
103
|
+
const secondary = end.secondaries[uri];
|
|
104
|
+
if (secondary !== undefined) {
|
|
105
|
+
end.secondaries[uri] = this.projectRoot(await this.roundTrip(uri, secondary));
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
return { from, to };
|
|
110
|
+
}
|
|
111
|
+
/**
|
|
112
|
+
* Also takes a secondary first tracked during an operation into the base
|
|
113
|
+
* and into the operation's projection from before its command, both from
|
|
114
|
+
* the root its version was read from: a conflict on it reconciles from the
|
|
115
|
+
* revision the operation's copy describes, and undoing the operation
|
|
116
|
+
* restores it. A document that does not exist yet has no projection to
|
|
117
|
+
* restore, so an undo leaves what the operation wrote into it.
|
|
118
|
+
*/
|
|
119
|
+
trackSecondaryDocument(uri) {
|
|
120
|
+
const added = uri !== this._sourceUri && !this.secondaryUris.includes(uri);
|
|
121
|
+
super.trackSecondaryDocument(uri);
|
|
122
|
+
const root = this.capturedRootOf(uri);
|
|
123
|
+
if (root === undefined) {
|
|
124
|
+
return;
|
|
125
|
+
}
|
|
126
|
+
const projection = this.projectRoot(root);
|
|
127
|
+
if (this.base !== undefined && !(uri in this.base.secondaries)) {
|
|
128
|
+
this.base = { ...this.base, secondaries: { ...this.base.secondaries, [uri]: projection } };
|
|
129
|
+
}
|
|
130
|
+
if (added) {
|
|
131
|
+
openOperationOf(this)?.amendBefore(before => isMultiDocumentModel(before) ? { ...before, secondaries: { ...before.secondaries, [uri]: projection } } : before);
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
/**
|
|
135
|
+
* During an operation, also drops the untracked documents from its
|
|
136
|
+
* projection from before its command: they are not written, so the
|
|
137
|
+
* operation's undo and redo leave them as they are.
|
|
138
|
+
*/
|
|
139
|
+
untrackSecondaryDocuments() {
|
|
140
|
+
const untracked = this.secondaryUris;
|
|
141
|
+
super.untrackSecondaryDocuments();
|
|
142
|
+
openOperationOf(this)?.amendBefore(before => isMultiDocumentModel(before)
|
|
143
|
+
? { ...before, secondaries: Object.fromEntries(Object.entries(before.secondaries).filter(([uri]) => !untracked.includes(uri))) }
|
|
144
|
+
: before);
|
|
93
145
|
}
|
|
94
146
|
/**
|
|
95
147
|
* Register the secondary documents that belong to the primary at `uri`, via
|
|
96
148
|
* {@link AbstractHydraniumGlspState.trackSecondaryDocument}. Called on every
|
|
97
|
-
*
|
|
98
|
-
*
|
|
149
|
+
* capture, after the primary is captured (so `sourceUri` is current) and
|
|
150
|
+
* BEFORE the base is taken (so the base includes them).
|
|
99
151
|
* Default: no secondaries.
|
|
100
152
|
*
|
|
101
153
|
* This hook exists because that ordering is a trap an adopter would otherwise
|
|
102
|
-
* hit silently. Registering from an overridden `
|
|
103
|
-
* `super.
|
|
154
|
+
* hit silently. Registering from an overridden `captureSourceRoot` *after*
|
|
155
|
+
* `super.captureSourceRoot(...)` runs too late — the base has already been
|
|
104
156
|
* captured without the secondaries, so the first conflict reconcile measures
|
|
105
|
-
* the user's intent against a
|
|
157
|
+
* the user's intent against a base missing half the write set and the
|
|
106
158
|
* secondary edits look like foreign changes. Registering *before* the super
|
|
107
159
|
* call is too early for a URI derived from the new primary. Overriding this
|
|
108
160
|
* instead removes the choice.
|
|
@@ -112,102 +164,189 @@ let ReconcilingMultiDocumentGlspState = class ReconcilingMultiDocumentGlspState
|
|
|
112
164
|
}
|
|
113
165
|
/**
|
|
114
166
|
* Persist the whole write set, then capture the resulting primary root. On a
|
|
115
|
-
* `ConflictError` from the
|
|
116
|
-
* as the single-document state does — the orchestration is
|
|
167
|
+
* `ConflictError` from any document of the set, reconcile via the injected
|
|
168
|
+
* policy exactly as the single-document state does — the orchestration is
|
|
169
|
+
* shared.
|
|
117
170
|
*/
|
|
118
|
-
async updateSourceModel(model,
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
this.
|
|
171
|
+
async updateSourceModel(model, baseVersion = this.baseVersion) {
|
|
172
|
+
let secondaryVersions;
|
|
173
|
+
return reconcileSourceModelWrite(model, baseVersion, {
|
|
174
|
+
persist: async (candidate, candidateBaseVersion) => {
|
|
175
|
+
const { root } = await this.persist(candidate, candidateBaseVersion, secondaryVersions);
|
|
176
|
+
this.captureWrittenRoot(root);
|
|
177
|
+
},
|
|
178
|
+
refetch: async () => {
|
|
179
|
+
const refetched = await this.refetch();
|
|
180
|
+
secondaryVersions = refetched?.secondaryVersions;
|
|
181
|
+
return refetched;
|
|
123
182
|
},
|
|
124
|
-
|
|
125
|
-
baseline: this.baseline,
|
|
183
|
+
base: this.base,
|
|
126
184
|
conflictResolver: this.conflictResolver,
|
|
127
185
|
logger: this.logger,
|
|
128
|
-
onConflictDropped: () => this.
|
|
186
|
+
onConflictDropped: () => this.writeDropped(),
|
|
187
|
+
onAlreadyApplied: () => this.captureBuiltRoot(),
|
|
188
|
+
maxWrites: this.maxSourceModelWrites
|
|
129
189
|
});
|
|
130
190
|
}
|
|
131
191
|
/**
|
|
132
|
-
* Write hook —
|
|
133
|
-
*
|
|
134
|
-
*
|
|
135
|
-
*
|
|
192
|
+
* Write hook — every document of `model` that changed, opened first through
|
|
193
|
+
* {@link openForWrite}, in one `updateAll` on the diagram's session: the
|
|
194
|
+
* primary gated on `baseVersion`, each secondary on its entry in
|
|
195
|
+
* `secondaryVersions` (a refetch's) or else {@link secondaryBaseVersion}, or
|
|
196
|
+
* every document on `'any'` when `baseVersion` is `'any'`. Resolves to
|
|
197
|
+
* the primary's root, the one already captured when the primary did not
|
|
198
|
+
* change. A write that bypasses `updateAll` gives up the all-or-none
|
|
199
|
+
* guarantee the class describes. Throws without a session
|
|
200
|
+
* ({@link requireModelSession}). An override that serializes otherwise than
|
|
201
|
+
* `ModelService.modelToText` overrides {@link normalizeTransition} alongside.
|
|
202
|
+
*
|
|
203
|
+
* A write that fails closes every document {@link createSecondaryDocument}
|
|
204
|
+
* created for it that {@link closesCreatedDocument} accepts.
|
|
136
205
|
*/
|
|
137
|
-
async persist(model, baseVersion) {
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
206
|
+
async persist(model, baseVersion, secondaryVersions) {
|
|
207
|
+
const primaryChanged = this.hasChanged(this.base.primary, model.primary);
|
|
208
|
+
const changedSecondaries = Object.entries(model.secondaries).filter(([uri, secondary]) => this.hasChanged(this.base.secondaries[uri], secondary));
|
|
209
|
+
if (!primaryChanged && changedSecondaries.length === 0) {
|
|
210
|
+
return { root: this._sourceRoot };
|
|
211
|
+
}
|
|
212
|
+
const session = this.requireModelSession();
|
|
213
|
+
this.createdForWrite.clear();
|
|
214
|
+
try {
|
|
215
|
+
if (primaryChanged) {
|
|
216
|
+
await this.openForWrite(session, this._sourceUri);
|
|
217
|
+
}
|
|
218
|
+
for (const [uri] of changedSecondaries) {
|
|
219
|
+
await this.openForWrite(session, uri);
|
|
220
|
+
}
|
|
221
|
+
// Based after the opens, so a secondary created there is gated on the version it was created at.
|
|
222
|
+
const updates = primaryChanged
|
|
223
|
+
? [{ uri: this._sourceUri, model: model.primary, baseVersion }]
|
|
224
|
+
: [];
|
|
225
|
+
for (const [uri, secondary] of changedSecondaries) {
|
|
226
|
+
updates.push({
|
|
227
|
+
uri,
|
|
228
|
+
model: secondary,
|
|
229
|
+
baseVersion: baseVersion === 'any' ? 'any' : (secondaryVersions?.[uri] ?? this.secondaryBaseVersion(uri))
|
|
230
|
+
});
|
|
141
231
|
}
|
|
232
|
+
const documents = await session.updateAll({ updates });
|
|
233
|
+
return { root: primaryChanged ? documents[0].root : this._sourceRoot };
|
|
142
234
|
}
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
235
|
+
catch (error) {
|
|
236
|
+
for (const [uri, created] of this.createdForWrite) {
|
|
237
|
+
try {
|
|
238
|
+
if (this.closesCreatedDocument(uri, created)) {
|
|
239
|
+
await session.close(uri);
|
|
240
|
+
}
|
|
241
|
+
}
|
|
242
|
+
catch (closeError) {
|
|
243
|
+
this.logger.warn(`Could not close ${uri}, created for a write that failed: ${describeErrorWithStack(closeError)}`);
|
|
244
|
+
}
|
|
245
|
+
}
|
|
246
|
+
throw error;
|
|
247
|
+
}
|
|
248
|
+
finally {
|
|
249
|
+
this.createdForWrite.clear();
|
|
147
250
|
}
|
|
148
|
-
return this.persistPrimary(model.primary, baseVersion);
|
|
149
251
|
}
|
|
150
252
|
/**
|
|
151
|
-
* Whether
|
|
253
|
+
* Whether a write that failed closes `uri`, which
|
|
254
|
+
* {@link createSecondaryDocument} created for it at `createdVersion`.
|
|
255
|
+
* Default: while it still holds the text it was created with. Left open, it
|
|
256
|
+
* would stay in the diagram's session, and the diagram's next save would
|
|
257
|
+
* write it to disk though no write landed in it. One whose text moved on,
|
|
258
|
+
* because the set failed after applying or another client wrote to it,
|
|
259
|
+
* stays open: closing it would drop that text.
|
|
260
|
+
*/
|
|
261
|
+
closesCreatedDocument(uri, createdVersion) {
|
|
262
|
+
return this.sharedServices.workspace.TextDocuments.version(uri) === createdVersion;
|
|
263
|
+
}
|
|
264
|
+
/**
|
|
265
|
+
* Whether `candidate` differs from the base projection of the same
|
|
152
266
|
* document, and therefore needs writing.
|
|
153
267
|
*
|
|
154
268
|
* **Skipping unchanged documents is correctness, not an optimisation.** A
|
|
155
|
-
* write
|
|
156
|
-
*
|
|
157
|
-
*
|
|
158
|
-
*
|
|
159
|
-
*
|
|
160
|
-
*
|
|
269
|
+
* write re-serializes from the AST, so writing a document that did not
|
|
270
|
+
* change still rewrites its text in the serializer's own layout. Persisting
|
|
271
|
+
* the whole write set unconditionally therefore means a pure layout drag
|
|
272
|
+
* reflows the semantic file, a change the user never asked for and would
|
|
273
|
+
* struggle to attribute. Comments survive that rewrite, but the
|
|
274
|
+
* hand-formatting around them does not.
|
|
161
275
|
*
|
|
162
276
|
* Compared by serialised form. Both sides come from the same encoder walking
|
|
163
277
|
* the same shape, so key order is stable and a string compare is sound here;
|
|
164
278
|
* it is also cheap enough to run per document per write.
|
|
165
279
|
*/
|
|
166
|
-
hasChanged(
|
|
167
|
-
return
|
|
168
|
-
}
|
|
169
|
-
/** Write the primary document, opting into the conflict gate when `baseVersion` is given. */
|
|
170
|
-
async persistPrimary(model, baseVersion) {
|
|
171
|
-
const document = await this.sharedServices.model.ModelService.update({
|
|
172
|
-
uri: this._sourceUri,
|
|
173
|
-
model,
|
|
174
|
-
clientId: this.clientId,
|
|
175
|
-
baseVersion
|
|
176
|
-
});
|
|
177
|
-
return document;
|
|
280
|
+
hasChanged(base, candidate) {
|
|
281
|
+
return base === undefined || JSON.stringify(base) !== JSON.stringify(candidate);
|
|
178
282
|
}
|
|
179
283
|
/**
|
|
180
|
-
*
|
|
181
|
-
*
|
|
182
|
-
*
|
|
284
|
+
* Make sure the diagram's session has `uri` open before the write set is
|
|
285
|
+
* written. Default: open it, a no-op for a document the session already
|
|
286
|
+
* has open. Override to create a document the write set names before it
|
|
287
|
+
* exists, through {@link createSecondaryDocument}: `updateAll` opens nothing.
|
|
183
288
|
*/
|
|
184
|
-
|
|
185
|
-
|
|
289
|
+
openForWrite(session, uri) {
|
|
290
|
+
return session.open(uri);
|
|
186
291
|
}
|
|
187
292
|
/**
|
|
188
|
-
*
|
|
189
|
-
*
|
|
190
|
-
*
|
|
191
|
-
*
|
|
192
|
-
*
|
|
293
|
+
* Create the secondary `uri` holding `text` through `session.create`, and
|
|
294
|
+
* base its write on the version the created document took. The version
|
|
295
|
+
* recorded while it did not exist matches no write, so the write conflicts.
|
|
296
|
+
* Make `text` with `ModelService.modelToText`, not the bare serializer,
|
|
297
|
+
* which leaves the file without the ending a write would give it.
|
|
298
|
+
*/
|
|
299
|
+
async createSecondaryDocument(session, uri, text) {
|
|
300
|
+
const created = await session.create(uri, text);
|
|
301
|
+
this.createdForWrite.set(uri, created);
|
|
302
|
+
if (this._secondaryVersions.has(uri)) {
|
|
303
|
+
this._secondaryVersions.set(uri, asModelVersion(created));
|
|
304
|
+
}
|
|
305
|
+
}
|
|
306
|
+
/**
|
|
307
|
+
* What a secondary write declares it was based on. Default: the version the
|
|
308
|
+
* secondary had when the source root was last read
|
|
309
|
+
* ({@link AbstractHydraniumGlspState.baseVersionOf}), so a foreign edit
|
|
310
|
+
* to it since is reported as a conflict and reconciled rather than
|
|
311
|
+
* overwritten; `'any'` for a secondary with no recorded version.
|
|
312
|
+
* Return `'any'` to force secondary writes.
|
|
313
|
+
*/
|
|
314
|
+
secondaryBaseVersion(uri) {
|
|
315
|
+
return this.baseVersionOf(uri) ?? 'any';
|
|
316
|
+
}
|
|
317
|
+
/**
|
|
318
|
+
* Refetch hook — the current projection across the write set, each document
|
|
319
|
+
* read through {@link AbstractHydraniumGlspState.readCurrentRoot}, with the
|
|
320
|
+
* versions read alongside: theirs, which the conflict resolver replays the
|
|
321
|
+
* user's intent onto. Returns `undefined` when the PRIMARY cannot be read,
|
|
322
|
+
* since a reconcile without it has nothing to merge into; an unreadable
|
|
323
|
+
* secondary is omitted the same way {@link sourceModel} omits one.
|
|
193
324
|
*/
|
|
194
325
|
async refetch() {
|
|
195
|
-
const
|
|
196
|
-
if (!
|
|
326
|
+
const theirs = await this.readCurrentRoot(this._sourceUri);
|
|
327
|
+
if (!theirs) {
|
|
197
328
|
return undefined;
|
|
198
329
|
}
|
|
199
330
|
const secondaries = {};
|
|
331
|
+
const secondaryVersions = {};
|
|
200
332
|
for (const uri of this.secondaryUris) {
|
|
201
|
-
const
|
|
202
|
-
if (
|
|
203
|
-
secondaries[uri] = this.projectRoot(
|
|
333
|
+
const read = await this.readCurrentRoot(uri);
|
|
334
|
+
if (read) {
|
|
335
|
+
secondaries[uri] = this.projectRoot(read.root);
|
|
336
|
+
secondaryVersions[uri] = read.version;
|
|
204
337
|
}
|
|
205
338
|
}
|
|
206
|
-
return { primary: this.projectRoot(
|
|
339
|
+
return { model: { primary: this.projectRoot(theirs.root), secondaries }, baseVersion: theirs.version, secondaryVersions };
|
|
207
340
|
}
|
|
208
|
-
/**
|
|
341
|
+
/**
|
|
342
|
+
* Project a currently-loaded document's root, or `undefined` when it is not
|
|
343
|
+
* loaded: the open operation's copy of it when there is one, which is where
|
|
344
|
+
* a handler's edit of it is, else the root its version was read from.
|
|
345
|
+
*/
|
|
209
346
|
projectDocument(uri) {
|
|
210
|
-
const root = this.
|
|
347
|
+
const root = this.existingWorkingRootOf(uri) ??
|
|
348
|
+
this.capturedRootOf(uri) ??
|
|
349
|
+
this.sharedServices.model.ModelService.getDocument(uri)?.parseResult?.value;
|
|
211
350
|
return root ? this.projectRoot(root) : undefined;
|
|
212
351
|
}
|
|
213
352
|
/** Grammar-mode transfer projection of one AST root. The single projection seam. */
|
|
@@ -219,4 +358,7 @@ ReconcilingMultiDocumentGlspState = __decorate([
|
|
|
219
358
|
injectable()
|
|
220
359
|
], ReconcilingMultiDocumentGlspState);
|
|
221
360
|
export { ReconcilingMultiDocumentGlspState };
|
|
361
|
+
function isMultiDocumentModel(value) {
|
|
362
|
+
return 'secondaries' in value && typeof value.secondaries === 'object' && value.secondaries !== null;
|
|
363
|
+
}
|
|
222
364
|
//# sourceMappingURL=reconciling-multi-document-glsp-state.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"reconciling-multi-document-glsp-state.js","sourceRoot":"","sources":["../../src/state/reconciling-multi-document-glsp-state.ts"],"names":[],"mappings":"AAAA;;;;;;;kFAOkF;;;;;;;AAGlF,OAAO,EAAE,UAAU,EAAE,MAAM,WAAW,CAAC;AAGvC,OAAO,EAAE,0BAA0B,EAAE,MAAM,oCAAoC,CAAC;AAChF,OAAO,EAAE,yBAAyB,EAAE,MAAM,mCAAmC,CAAC;
|
|
1
|
+
{"version":3,"file":"reconciling-multi-document-glsp-state.js","sourceRoot":"","sources":["../../src/state/reconciling-multi-document-glsp-state.ts"],"names":[],"mappings":"AAAA;;;;;;;kFAOkF;;;;;;;AAGlF,OAAO,EAAE,UAAU,EAAE,MAAM,WAAW,CAAC;AAGvC,OAAO,EACJ,cAAc,EAMd,sBAAsB,EACxB,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EAAE,0BAA0B,EAAE,MAAM,oCAAoC,CAAC;AAChF,OAAO,EAA4B,eAAe,EAAE,MAAM,gDAAgD,CAAC;AAC3G,OAAO,EAAE,yBAAyB,EAAE,MAAM,mCAAmC,CAAC;AA0B9E;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8BG;AAEI,IAAM,iCAAiC,GAAvC,MAAM,iCACV,SAAQ,0BAAqE;IAG7E;;;;OAIG;IACO,IAAI,CAAsC;IAEpD,qIAAqI;IAClH,eAAe,GAAG,IAAI,GAAG,EAAuB,CAAC;IAEpE;;;;;;;;;;OAUG;IACH,IAAI,WAAW;QACZ,MAAM,WAAW,GAAoC,EAAE,CAAC;QACxD,KAAK,MAAM,GAAG,IAAI,IAAI,CAAC,aAAa,EAAE,CAAC;YACpC,MAAM,UAAU,GAAG,IAAI,CAAC,eAAe,CAAC,GAAG,CAAC,CAAC;YAC7C,IAAI,UAAU,EAAE,CAAC;gBACd,WAAW,CAAC,GAAG,CAAC,GAAG,UAAU,CAAC;YACjC,CAAC;QACJ,CAAC;QACD,OAAO,EAAE,OAAO,EAAE,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,UAAU,CAAC,EAAE,WAAW,EAAE,CAAC;IACtE,CAAC;IAEkB,iBAAiB,CAAC,GAAW,EAAE,IAAW;QAC1D,KAAK,CAAC,iBAAiB,CAAC,GAAG,EAAE,IAAI,CAAC,CAAC;QACnC,IAAI,CAAC,aAAa,CAAC,GAAG,CAAC,CAAC;QACxB,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC,WAAW,CAAC;IAChC,CAAC;IAED;;;;OAIG;IACM,KAAK,CAAC,mBAAmB,CAC/B,UAAmE;QAEnE,MAAM,IAAI,GAAG,EAAE,OAAO,EAAE,UAAU,CAAC,IAAI,CAAC,OAAO,EAAE,WAAW,EAAE,EAAE,GAAG,UAAU,CAAC,IAAI,CAAC,WAAW,EAAE,EAAE,CAAC;QACnG,MAAM,EAAE,GAAG,EAAE,OAAO,EAAE,UAAU,CAAC,EAAE,CAAC,OAAO,EAAE,WAAW,EAAE,EAAE,GAAG,UAAU,CAAC,EAAE,CAAC,WAAW,EAAE,EAAE,CAAC;QAC7F,IAAI,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,OAAO,CAAC,KAAK,IAAI,CAAC,SAAS,CAAC,EAAE,CAAC,OAAO,CAAC,EAAE,CAAC;YAC/D,IAAI,CAAC,OAAO,GAAG,IAAI,CAAC,WAAW,CAAW,MAAM,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,UAAU,EAAE,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC;YAC/F,EAAE,CAAC,OAAO,GAAG,IAAI,CAAC,WAAW,CAAW,MAAM,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,UAAU,EAAE,EAAE,CAAC,OAAO,CAAC,CAAC,CAAC;QAC9F,CAAC;QACD,KAAK,MAAM,GAAG,IAAI,IAAI,GAAG,CAAC,CAAC,GAAG,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,WAAW,CAAC,EAAE,GAAG,MAAM,CAAC,IAAI,CAAC,EAAE,CAAC,WAAW,CAAC,CAAC,CAAC,EAAE,CAAC;YAC7F,IAAI,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,CAAC,KAAK,IAAI,CAAC,SAAS,CAAC,EAAE,CAAC,WAAW,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC;gBACjF,SAAS;YACZ,CAAC;YACD,KAAK,MAAM,GAAG,IAAI,CAAC,IAAI,EAAE,EAAE,CAAC,EAAE,CAAC;gBAC5B,MAAM,SAAS,GAAG,GAAG,CAAC,WAAW,CAAC,GAAG,CAAC,CAAC;gBACvC,IAAI,SAAS,KAAK,SAAS,EAAE,CAAC;oBAC3B,GAAG,CAAC,WAAW,CAAC,GAAG,CAAC,GAAG,IAAI,CAAC,WAAW,CAAC,MAAM,IAAI,CAAC,SAAS,CAAC,GAAG,EAAE,SAAS,CAAC,CAAC,CAAC;gBACjF,CAAC;YACJ,CAAC;QACJ,CAAC;QACD,OAAO,EAAE,IAAI,EAAE,EAAE,EAAE,CAAC;IACvB,CAAC;IAED;;;;;;;OAOG;IACM,sBAAsB,CAAC,GAAW;QACxC,MAAM,KAAK,GAAG,GAAG,KAAK,IAAI,CAAC,UAAU,IAAI,CAAC,IAAI,CAAC,aAAa,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC;QAC3E,KAAK,CAAC,sBAAsB,CAAC,GAAG,CAAC,CAAC;QAClC,MAAM,IAAI,GAAG,IAAI,CAAC,cAAc,CAAC,GAAG,CAAC,CAAC;QACtC,IAAI,IAAI,KAAK,SAAS,EAAE,CAAC;YACtB,OAAO;QACV,CAAC;QACD,MAAM,UAAU,GAAG,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,CAAC;QAC1C,IAAI,IAAI,CAAC,IAAI,KAAK,SAAS,IAAI,CAAC,CAAC,GAAG,IAAI,IAAI,CAAC,IAAI,CAAC,WAAW,CAAC,EAAE,CAAC;YAC9D,IAAI,CAAC,IAAI,GAAG,EAAE,GAAG,IAAI,CAAC,IAAI,EAAE,WAAW,EAAE,EAAE,GAAG,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,CAAC,GAAG,CAAC,EAAE,UAAU,EAAE,EAAE,CAAC;QAC9F,CAAC;QACD,IAAI,KAAK,EAAE,CAAC;YACT,eAAe,CAAC,IAAI,CAAC,EAAE,WAAW,CAAC,MAAM,CAAC,EAAE,CACzC,oBAAoB,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,EAAE,GAAG,MAAM,EAAE,WAAW,EAAE,EAAE,GAAG,MAAM,CAAC,WAAW,EAAE,CAAC,GAAG,CAAC,EAAE,UAAU,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,CAClH,CAAC;QACL,CAAC;IACJ,CAAC;IAED;;;;OAIG;IACM,yBAAyB;QAC/B,MAAM,SAAS,GAAG,IAAI,CAAC,aAAa,CAAC;QACrC,KAAK,CAAC,yBAAyB,EAAE,CAAC;QAClC,eAAe,CAAC,IAAI,CAAC,EAAE,WAAW,CAAC,MAAM,CAAC,EAAE,CACzC,oBAAoB,CAAC,MAAM,CAAC;YACzB,CAAC,CAAC,EAAE,GAAG,MAAM,EAAE,WAAW,EAAE,MAAM,CAAC,WAAW,CAAC,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,WAAW,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,EAAE,CAAC,CAAC,SAAS,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE;YAChI,CAAC,CAAC,MAAM,CACb,CAAC;IACL,CAAC;IAED;;;;;;;;;;;;;;;OAeG;IACO,aAAa,CAAC,IAAY;QACjC,wDAAwD;IAC3D,CAAC;IAED;;;;;OAKG;IACH,KAAK,CAAC,iBAAiB,CAAC,KAAyC,EAAE,WAAW,GAAgB,IAAI,CAAC,WAAW;QAC3G,IAAI,iBAAqE,CAAC;QAC1E,OAAO,yBAAyB,CAAqC,KAAK,EAAE,WAAW,EAAE;YACtF,OAAO,EAAE,KAAK,EAAE,SAAS,EAAE,oBAAoB,EAAE,EAAE;gBAChD,MAAM,EAAE,IAAI,EAAE,GAAG,MAAM,IAAI,CAAC,OAAO,CAAC,SAAS,EAAE,oBAAoB,EAAE,iBAAiB,CAAC,CAAC;gBACxF,IAAI,CAAC,kBAAkB,CAAC,IAAI,CAAC,CAAC;YACjC,CAAC;YACD,OAAO,EAAE,KAAK,IAAI,EAAE;gBACjB,MAAM,SAAS,GAAG,MAAM,IAAI,CAAC,OAAO,EAAE,CAAC;gBACvC,iBAAiB,GAAG,SAAS,EAAE,iBAAiB,CAAC;gBACjD,OAAO,SAAS,CAAC;YACpB,CAAC;YACD,IAAI,EAAE,IAAI,CAAC,IAAI;YACf,gBAAgB,EAAE,IAAI,CAAC,gBAAgB;YACvC,MAAM,EAAE,IAAI,CAAC,MAAM;YACnB,iBAAiB,EAAE,GAAG,EAAE,CAAC,IAAI,CAAC,YAAY,EAAE;YAC5C,gBAAgB,EAAE,GAAG,EAAE,CAAC,IAAI,CAAC,gBAAgB,EAAE;YAC/C,SAAS,EAAE,IAAI,CAAC,oBAAoB;SACtC,CAAC,CAAC;IACN,CAAC;IAED;;;;;;;;;;;;;;OAcG;IACO,KAAK,CAAC,OAAO,CACpB,KAAyC,EACzC,WAAwB,EACxB,iBAA0D;QAE1D,MAAM,cAAc,GAAG,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,KAAK,CAAC,OAAO,CAAC,CAAC;QACzE,MAAM,kBAAkB,GAAG,MAAM,CAAC,OAAO,CAAC,KAAK,CAAC,WAAW,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,GAAG,EAAE,SAAS,CAAC,EAAE,EAAE,CACtF,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,EAAE,SAAS,CAAC,CACxD,CAAC;QACF,IAAI,CAAC,cAAc,IAAI,kBAAkB,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YACtD,OAAO,EAAE,IAAI,EAAE,IAAI,CAAC,WAAW,EAAE,CAAC;QACrC,CAAC;QACD,MAAM,OAAO,GAAG,IAAI,CAAC,mBAAmB,EAAE,CAAC;QAC3C,IAAI,CAAC,eAAe,CAAC,KAAK,EAAE,CAAC;QAC7B,IAAI,CAAC;YACF,IAAI,cAAc,EAAE,CAAC;gBAClB,MAAM,IAAI,CAAC,YAAY,CAAC,OAAO,EAAE,IAAI,CAAC,UAAU,CAAC,CAAC;YACrD,CAAC;YACD,KAAK,MAAM,CAAC,GAAG,CAAC,IAAI,kBAAkB,EAAE,CAAC;gBACtC,MAAM,IAAI,CAAC,YAAY,CAAC,OAAO,EAAE,GAAG,CAAC,CAAC;YACzC,CAAC;YACD,iGAAiG;YACjG,MAAM,OAAO,GAA8C,cAAc;gBACtE,CAAC,CAAC,CAAC,EAAE,GAAG,EAAE,IAAI,CAAC,UAAU,EAAE,KAAK,EAAE,KAAK,CAAC,OAAO,EAAE,WAAW,EAAE,CAAC;gBAC/D,CAAC,CAAC,EAAE,CAAC;YACR,KAAK,MAAM,CAAC,GAAG,EAAE,SAAS,CAAC,IAAI,kBAAkB,EAAE,CAAC;gBACjD,OAAO,CAAC,IAAI,CAAC;oBACV,GAAG;oBACH,KAAK,EAAE,SAAS;oBAChB,WAAW,EAAE,WAAW,KAAK,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,iBAAiB,EAAE,CAAC,GAAG,CAAC,IAAI,IAAI,CAAC,oBAAoB,CAAC,GAAG,CAAC,CAAC;iBAC3G,CAAC,CAAC;YACN,CAAC;YACD,MAAM,SAAS,GAAG,MAAM,OAAO,CAAC,SAAS,CAAC,EAAE,OAAO,EAAE,CAAC,CAAC;YACvD,OAAO,EAAE,IAAI,EAAE,cAAc,CAAC,CAAC,CAAE,SAAS,CAAC,CAAC,CAAC,CAAC,IAAyB,CAAC,CAAC,CAAC,IAAI,CAAC,WAAW,EAAE,CAAC;QAChG,CAAC;QAAC,OAAO,KAAc,EAAE,CAAC;YACvB,KAAK,MAAM,CAAC,GAAG,EAAE,OAAO,CAAC,IAAI,IAAI,CAAC,eAAe,EAAE,CAAC;gBACjD,IAAI,CAAC;oBACF,IAAI,IAAI,CAAC,qBAAqB,CAAC,GAAG,EAAE,OAAO,CAAC,EAAE,CAAC;wBAC5C,MAAM,OAAO,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;oBAC5B,CAAC;gBACJ,CAAC;gBAAC,OAAO,UAAmB,EAAE,CAAC;oBAC5B,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,mBAAmB,GAAG,sCAAsC,sBAAsB,CAAC,UAAU,CAAC,EAAE,CAAC,CAAC;gBACtH,CAAC;YACJ,CAAC;YACD,MAAM,KAAK,CAAC;QACf,CAAC;gBAAS,CAAC;YACR,IAAI,CAAC,eAAe,CAAC,KAAK,EAAE,CAAC;QAChC,CAAC;IACJ,CAAC;IAED;;;;;;;;OAQG;IACO,qBAAqB,CAAC,GAAW,EAAE,cAA2B;QACrE,OAAO,IAAI,CAAC,cAAc,CAAC,SAAS,CAAC,aAAa,CAAC,OAAO,CAAC,GAAG,CAAC,KAAK,cAAc,CAAC;IACtF,CAAC;IAED;;;;;;;;;;;;;;;OAeG;IACO,UAAU,CAAC,IAAwB,EAAE,SAAiB;QAC7D,OAAO,IAAI,KAAK,SAAS,IAAI,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,KAAK,IAAI,CAAC,SAAS,CAAC,SAAS,CAAC,CAAC;IACnF,CAAC;IAED;;;;;OAKG;IACO,YAAY,CAAC,OAA+B,EAAE,GAAW;QAChE,OAAO,OAAO,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;IAC5B,CAAC;IAED;;;;;;OAMG;IACO,KAAK,CAAC,uBAAuB,CAAC,OAA+B,EAAE,GAAW,EAAE,IAAY;QAC/F,MAAM,OAAO,GAAG,MAAM,OAAO,CAAC,MAAM,CAAC,GAAG,EAAE,IAAI,CAAC,CAAC;QAChD,IAAI,CAAC,eAAe,CAAC,GAAG,CAAC,GAAG,EAAE,OAAO,CAAC,CAAC;QACvC,IAAI,IAAI,CAAC,kBAAkB,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,CAAC;YACpC,IAAI,CAAC,kBAAkB,CAAC,GAAG,CAAC,GAAG,EAAE,cAAc,CAAC,OAAO,CAAC,CAAC,CAAC;QAC7D,CAAC;IACJ,CAAC;IAED;;;;;;;OAOG;IACO,oBAAoB,CAAC,GAAW;QACvC,OAAO,IAAI,CAAC,aAAa,CAAC,GAAG,CAAC,IAAI,KAAK,CAAC;IAC3C,CAAC;IAED;;;;;;;OAOG;IACO,KAAK,CAAC,OAAO;QACpB,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,eAAe,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;QAC3D,IAAI,CAAC,MAAM,EAAE,CAAC;YACX,OAAO,SAAS,CAAC;QACpB,CAAC;QACD,MAAM,WAAW,GAAoC,EAAE,CAAC;QACxD,MAAM,iBAAiB,GAAiC,EAAE,CAAC;QAC3D,KAAK,MAAM,GAAG,IAAI,IAAI,CAAC,aAAa,EAAE,CAAC;YACpC,MAAM,IAAI,GAAG,MAAM,IAAI,CAAC,eAAe,CAAC,GAAG,CAAC,CAAC;YAC7C,IAAI,IAAI,EAAE,CAAC;gBACR,WAAW,CAAC,GAAG,CAAC,GAAG,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;gBAC/C,iBAAiB,CAAC,GAAG,CAAC,GAAG,IAAI,CAAC,OAAO,CAAC;YACzC,CAAC;QACJ,CAAC;QACD,OAAO,EAAE,KAAK,EAAE,EAAE,OAAO,EAAE,IAAI,CAAC,WAAW,CAAW,MAAM,CAAC,IAAI,CAAC,EAAE,WAAW,EAAE,EAAE,WAAW,EAAE,MAAM,CAAC,OAAO,EAAE,iBAAiB,EAAE,CAAC;IACvI,CAAC;IAED;;;;OAIG;IACO,eAAe,CAAC,GAAW;QAClC,MAAM,IAAI,GACP,IAAI,CAAC,qBAAqB,CAAC,GAAG,CAAC;YAC/B,IAAI,CAAC,cAAc,CAAC,GAAG,CAAC;YACxB,IAAI,CAAC,cAAc,CAAC,KAAK,CAAC,YAAY,CAAC,WAAW,CAAC,GAAG,CAAC,EAAE,WAAW,EAAE,KAAK,CAAC;QAC/E,OAAO,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;IACpD,CAAC;IAED,oFAAoF;IAC1E,WAAW,CAA8C,IAAa;QAC7E,OAAO,IAAI,CAAC,cAAc,CAAC,KAAK,CAAC,eAAe,CAAC,UAAU,CAAC,IAAI,EAAE,SAAS,CAAiB,CAAC;IAChG,CAAC;CACH,CAAA;AA/UY,iCAAiC;IAD7C,UAAU,EAAE;GACA,iCAAiC,CA+U7C;;AAED,SAAS,oBAAoB,CAAC,KAAa;IACxC,OAAO,aAAa,IAAI,KAAK,IAAI,OAAO,KAAK,CAAC,WAAW,KAAK,QAAQ,IAAI,KAAK,CAAC,WAAW,KAAK,IAAI,CAAC;AACxG,CAAC"}
|
|
@@ -8,7 +8,8 @@
|
|
|
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 BaseVersion, type TransferElement, type VersionedModel } from '@hydranium/protocol';
|
|
12
|
+
import { type OperationTransition } from '../command/hydranium-glsp-operation-command.js';
|
|
12
13
|
import { AbstractHydraniumGlspState } from './abstract-hydranium-glsp-state.js';
|
|
13
14
|
/**
|
|
14
15
|
* Editable GLSP state for adopters whose source model is a **structured
|
|
@@ -23,16 +24,16 @@ import { AbstractHydraniumGlspState } from './abstract-hydranium-glsp-state.js';
|
|
|
23
24
|
* field-level shape is what lets `fast-json-patch` diff per field, so undo /
|
|
24
25
|
* redo and forward-write reconcile act per field instead of clobbering the
|
|
25
26
|
* whole document.
|
|
26
|
-
* - {@link
|
|
27
|
-
*
|
|
28
|
-
* intent (
|
|
27
|
+
* - {@link base} — the last in-sync projection, taken on every capture of
|
|
28
|
+
* the built root. A forward-write conflict reconciles the user's
|
|
29
|
+
* intent (base → ours) against the server's current root (theirs).
|
|
29
30
|
* - {@link updateSourceModel} — the concrete reconcile template: persist,
|
|
30
31
|
* and on a `ConflictError` consult the injected `conflictResolver` and act
|
|
31
|
-
* on
|
|
32
|
+
* on its outcome.
|
|
32
33
|
* - {@link persist} / {@link refetch} — the only I/O seams. Defaults route
|
|
33
|
-
* through `
|
|
34
|
-
*
|
|
35
|
-
*
|
|
34
|
+
* through the diagram session's `update` and `ModelService.validated`;
|
|
35
|
+
* adopters whose document round-trip differs override these without
|
|
36
|
+
* touching the orchestration.
|
|
36
37
|
*
|
|
37
38
|
* Adopters whose source model is whole-document text (a bare `{ text }`
|
|
38
39
|
* source model) or that are read-only do NOT extend this class — they extend
|
|
@@ -43,13 +44,10 @@ import { AbstractHydraniumGlspState } from './abstract-hydranium-glsp-state.js';
|
|
|
43
44
|
*/
|
|
44
45
|
export declare class ReconcilingTransferHydraniumGlspState<TRoot extends AstNode, TSourceModel extends TransferElement> extends AbstractHydraniumGlspState<TRoot, TSourceModel> implements JsonModelState<TSourceModel> {
|
|
45
46
|
/**
|
|
46
|
-
*
|
|
47
|
-
*
|
|
48
|
-
* forward-write conflict reconciles against: it stays the pre-command
|
|
49
|
-
* state because operation handlers mutate `_sourceRoot` in place during
|
|
50
|
-
* `execute` while `setSourceRoot` only re-runs once the write commits.
|
|
47
|
+
* The projection a forward-write conflict reconciles the user's intent
|
|
48
|
+
* from, taken from the built root on every capture.
|
|
51
49
|
*/
|
|
52
|
-
protected
|
|
50
|
+
protected base: TSourceModel;
|
|
53
51
|
/**
|
|
54
52
|
* Persisted-shape projection of the current source root, consumed by GLSP's
|
|
55
53
|
* {@link JsonModelState} read side and recorded for field-level undo / redo.
|
|
@@ -59,33 +57,43 @@ export declare class ReconcilingTransferHydraniumGlspState<TRoot extends AstNode
|
|
|
59
57
|
* Synchronous — the encoder walks the in-memory AST without serialising.
|
|
60
58
|
*/
|
|
61
59
|
get sourceModel(): TSourceModel;
|
|
62
|
-
|
|
60
|
+
/**
|
|
61
|
+
* The source model of `root`. The single projection seam: the source
|
|
62
|
+
* model, the refetch and {@link normalizeTransition} all project through it.
|
|
63
|
+
*/
|
|
64
|
+
protected projectRoot(root: AstNode): TSourceModel;
|
|
65
|
+
/** Both ends serialized for the source document and parsed back, unless they are equal. */
|
|
66
|
+
normalizeTransition(transition: OperationTransition<TSourceModel>): Promise<OperationTransition<TSourceModel>>;
|
|
67
|
+
protected captureSourceRoot(uri: string, root: TRoot): void;
|
|
63
68
|
/**
|
|
64
69
|
* Persist `model` back to the document store, then capture the resulting
|
|
65
|
-
* AST root. On a `ConflictError` (the
|
|
66
|
-
* reconcile the user's intent against the
|
|
70
|
+
* AST root. On a `ConflictError` (the base version was superseded),
|
|
71
|
+
* reconcile the user's intent against the server's current root via the bound
|
|
67
72
|
* `conflictResolver` and act on the outcome — one declarative policy
|
|
68
73
|
* (force = last-writer-wins, reconciling = field-level merge) shared with
|
|
69
74
|
* undo / redo.
|
|
70
75
|
*/
|
|
71
|
-
updateSourceModel(model: TSourceModel,
|
|
76
|
+
updateSourceModel(model: TSourceModel, baseVersion?: BaseVersion): Promise<void>;
|
|
72
77
|
/**
|
|
73
78
|
* Persist hook — the only write-side I/O. Default routes the structured
|
|
74
|
-
* model through `
|
|
75
|
-
* the `ConflictError` gate
|
|
76
|
-
*
|
|
79
|
+
* model through the diagram session's `update` (serialize → reparse),
|
|
80
|
+
* opting into the `ConflictError` gate unless `baseVersion` is `'any'`,
|
|
81
|
+
* and throws without a session. Adopters whose document
|
|
82
|
+
* round-trip differs override this, and {@link normalizeTransition}
|
|
83
|
+
* alongside so undo compares what this writes; the orchestration in
|
|
77
84
|
* {@link updateSourceModel} is unchanged.
|
|
78
85
|
*/
|
|
79
|
-
protected persist(model: TSourceModel, baseVersion
|
|
86
|
+
protected persist(model: TSourceModel, baseVersion: BaseVersion): Promise<{
|
|
80
87
|
root: TRoot;
|
|
81
88
|
}>;
|
|
82
89
|
/**
|
|
83
|
-
* Refetch hook —
|
|
84
|
-
* projection (or `undefined` when
|
|
85
|
-
* replays the user's
|
|
86
|
-
*
|
|
87
|
-
* adopters override alongside
|
|
90
|
+
* Refetch hook — the stored text parsed afresh, as a persisted-shape
|
|
91
|
+
* projection with the version of that text (or `undefined` when
|
|
92
|
+
* unavailable): theirs, which the `conflictResolver` replays the user's
|
|
93
|
+
* intent onto. Default uses {@link AbstractHydraniumGlspState.readCurrentRoot}
|
|
94
|
+
* + the framework encoder's `'grammar'` mode; adopters override alongside
|
|
95
|
+
* {@link persist}.
|
|
88
96
|
*/
|
|
89
|
-
protected refetch(): Promise<TSourceModel | undefined>;
|
|
97
|
+
protected refetch(): Promise<VersionedModel<TSourceModel> | undefined>;
|
|
90
98
|
}
|
|
91
99
|
//# sourceMappingURL=reconciling-transfer-hydranium-glsp-state.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"reconciling-transfer-hydranium-glsp-state.d.ts","sourceRoot":"","sources":["../../src/state/reconciling-transfer-hydranium-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;
|
|
1
|
+
{"version":3,"file":"reconciling-transfer-hydranium-glsp-state.d.ts","sourceRoot":"","sources":["../../src/state/reconciling-transfer-hydranium-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,WAAW,EAAE,KAAK,eAAe,EAAE,KAAK,cAAc,EAAE,MAAM,qBAAqB,CAAC;AAClG,OAAO,EAAE,KAAK,mBAAmB,EAAE,MAAM,gDAAgD,CAAC;AAC1F,OAAO,EAAE,0BAA0B,EAAE,MAAM,oCAAoC,CAAC;AAGhF;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8BG;AACH,qBACa,qCAAqC,CAAC,KAAK,SAAS,OAAO,EAAE,YAAY,SAAS,eAAe,CAC3G,SAAQ,0BAA0B,CAAC,KAAK,EAAE,YAAY,CACtD,YAAW,cAAc,CAAC,YAAY,CAAC;IAEvC;;;OAGG;IACH,SAAS,CAAC,IAAI,EAAG,YAAY,CAAC;IAE9B;;;;;;;OAOG;IACH,IAAI,WAAW,IAAI,YAAY,CAE9B;IAED;;;OAGG;IACH,SAAS,CAAC,WAAW,CAAC,IAAI,EAAE,OAAO,GAAG,YAAY,CAEjD;IAED,2FAA2F;IAC5E,mBAAmB,CAAC,UAAU,EAAE,mBAAmB,CAAC,YAAY,CAAC,GAAG,OAAO,CAAC,mBAAmB,CAAC,YAAY,CAAC,CAAC,CAQ5H;IAED,UAAmB,iBAAiB,CAAC,GAAG,EAAE,MAAM,EAAE,IAAI,EAAE,KAAK,GAAG,IAAI,CAGnE;IAED;;;;;;;OAOG;IACG,iBAAiB,CAAC,KAAK,EAAE,YAAY,EAAE,WAAW,GAAE,WAA8B,GAAG,OAAO,CAAC,IAAI,CAAC,CAiBvG;IAED;;;;;;;;OAQG;IACH,UAAgB,OAAO,CAAC,KAAK,EAAE,YAAY,EAAE,WAAW,EAAE,WAAW,GAAG,OAAO,CAAC;QAAE,IAAI,EAAE,KAAK,CAAA;KAAE,CAAC,CAG/F;IAED;;;;;;;OAOG;IACH,UAAgB,OAAO,IAAI,OAAO,CAAC,cAAc,CAAC,YAAY,CAAC,GAAG,SAAS,CAAC,CAQ3E;CACH"}
|