@hydranium/glsp-server 1.0.0-next.31 → 1.0.0-next.313
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
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
/********************************************************************************
|
|
2
|
+
* Copyright (c) 2026 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 { DefaultCommandStack, ModelState } from '@eclipse-glsp/server';
|
|
19
|
+
import { inject, injectable } from 'inversify';
|
|
20
|
+
import { HydraniumTypes } from '../state/hydranium-shared-core-services.js';
|
|
21
|
+
/**
|
|
22
|
+
* GLSP's command stack with the diagram's dirty state read from the text store:
|
|
23
|
+
* dirty while any document the diagram's client session has open differs from
|
|
24
|
+
* its file, as the store last knew the file. Undo and redo are GLSP's.
|
|
25
|
+
*
|
|
26
|
+
* GLSP's own answer counts the diagram's commands since its last save, so it
|
|
27
|
+
* misses every change the diagram did not make: another client's unsaved edit
|
|
28
|
+
* leaves it clean, and a save it did not make of a document other than the
|
|
29
|
+
* diagram's own leaves it dirty. Every `SetDirtyStateAction` GLSP sends reads
|
|
30
|
+
* this answer.
|
|
31
|
+
*/
|
|
32
|
+
let HydraniumGlspCommandStack = class HydraniumGlspCommandStack extends DefaultCommandStack {
|
|
33
|
+
modelState;
|
|
34
|
+
sharedServices;
|
|
35
|
+
get isDirty() {
|
|
36
|
+
const textDocuments = this.sharedServices.workspace.TextDocuments;
|
|
37
|
+
const clientId = this.modelState.clientId;
|
|
38
|
+
return textDocuments.openDocuments().some(open => open.clients.includes(clientId) && textDocuments.isDirty(open.uri));
|
|
39
|
+
}
|
|
40
|
+
/**
|
|
41
|
+
* Lifted from `@eclipse-glsp/server` 2.7.0's `DefaultCommandStack.handleError`
|
|
42
|
+
* without its `error` line: the failure is rethrown, and whoever ends it
|
|
43
|
+
* logs it. The accompanying test pins upstream's source.
|
|
44
|
+
*/
|
|
45
|
+
handleError(error) {
|
|
46
|
+
this.flush();
|
|
47
|
+
this.logger.debug('A command failed; the command stack was flushed');
|
|
48
|
+
throw error;
|
|
49
|
+
}
|
|
50
|
+
};
|
|
51
|
+
__decorate([
|
|
52
|
+
inject(ModelState),
|
|
53
|
+
__metadata("design:type", Object)
|
|
54
|
+
], HydraniumGlspCommandStack.prototype, "modelState", void 0);
|
|
55
|
+
__decorate([
|
|
56
|
+
inject(HydraniumTypes.SharedCoreServices),
|
|
57
|
+
__metadata("design:type", Object)
|
|
58
|
+
], HydraniumGlspCommandStack.prototype, "sharedServices", void 0);
|
|
59
|
+
HydraniumGlspCommandStack = __decorate([
|
|
60
|
+
injectable()
|
|
61
|
+
], HydraniumGlspCommandStack);
|
|
62
|
+
export { HydraniumGlspCommandStack };
|
|
63
|
+
//# sourceMappingURL=hydranium-glsp-command-stack.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"hydranium-glsp-command-stack.js","sourceRoot":"","sources":["../../src/command/hydranium-glsp-command-stack.ts"],"names":[],"mappings":"AAAA;;;;;;;kFAOkF;;;;;;;;;;AAElF,OAAO,EAAE,mBAAmB,EAAE,UAAU,EAAE,MAAM,sBAAsB,CAAC;AAEvE,OAAO,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,WAAW,CAAC;AAC/C,OAAO,EAAE,cAAc,EAAE,MAAM,4CAA4C,CAAC;AAE5E;;;;;;;;;;GAUG;AAEI,IAAM,yBAAyB,GAA/B,MAAM,yBAA0B,SAAQ,mBAAmB;IACxB,UAAU,CAAc;IACD,cAAc,CAAwB;IAEpG,IAAa,OAAO;QACjB,MAAM,aAAa,GAAG,IAAI,CAAC,cAAc,CAAC,SAAS,CAAC,aAAa,CAAC;QAClE,MAAM,QAAQ,GAAG,IAAI,CAAC,UAAU,CAAC,QAAQ,CAAC;QAC1C,OAAO,aAAa,CAAC,aAAa,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAC,IAAI,aAAa,CAAC,OAAO,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC;IACzH,CAAC;IAED;;;;OAIG;IACgB,WAAW,CAAC,KAAc;QAC1C,IAAI,CAAC,KAAK,EAAE,CAAC;QACb,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,iDAAiD,CAAC,CAAC;QACrE,MAAM,KAAK,CAAC;IACf,CAAC;CACH,CAAA;AAnByC;IAAtC,MAAM,CAAC,UAAU,CAAC;;6DAA4C;AACD;IAA7D,MAAM,CAAC,cAAc,CAAC,kBAAkB,CAAC;;iEAA0D;AAF1F,yBAAyB;IADrC,UAAU,EAAE;GACA,yBAAyB,CAoBrC"}
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
/********************************************************************************
|
|
2
|
+
* Copyright (c) 2026 EclipseSource and others.
|
|
3
|
+
*
|
|
4
|
+
* This program and the accompanying materials are made available under the
|
|
5
|
+
* terms of the MIT License which is available in the project root.
|
|
6
|
+
*
|
|
7
|
+
* SPDX-License-Identifier: MIT
|
|
8
|
+
********************************************************************************/
|
|
9
|
+
import { type Action, ActionDispatcher, type AnyObject, GLSPClientProxy, Logger, type Operation, OperationActionHandler, type OperationHandler } from '@eclipse-glsp/server';
|
|
10
|
+
import { type HydraniumGlspRecordingState } from './hydranium-glsp-recording-command.js';
|
|
11
|
+
/**
|
|
12
|
+
* GLSP's operation action handler, running each operation as a
|
|
13
|
+
* {@link HydraniumGlspOperationCommand} inside the state's `runExclusive`,
|
|
14
|
+
* which covers the operation, its write, the command-stack push and the
|
|
15
|
+
* submit, so neither another operation, an undo nor the storage's capture
|
|
16
|
+
* lands between them.
|
|
17
|
+
*
|
|
18
|
+
* An operation dispatched while another is open, as a handler's plain
|
|
19
|
+
* `dispatch` does, is queued behind it and its dispatch resolves at once;
|
|
20
|
+
* awaited inside the open operation, it would wait for the operation awaiting
|
|
21
|
+
* it. It writes, pushes and submits on its own, and a failure is reported to
|
|
22
|
+
* the client as GLSP reports a failed client action.
|
|
23
|
+
*
|
|
24
|
+
* Only operations are queued that way, and only while one is open, its undo's
|
|
25
|
+
* side effects included. Code running inside the boundary otherwise must not
|
|
26
|
+
* dispatch an operation and await it: a GModel factory or a submit after an
|
|
27
|
+
* operation, an undo's write and submit, the storage's render. Nor may any code
|
|
28
|
+
* inside the boundary await a dispatched undo, redo or model request, which
|
|
29
|
+
* take the boundary themselves. Each waits for the section awaiting it.
|
|
30
|
+
*/
|
|
31
|
+
export declare class HydraniumGlspOperationActionHandler extends OperationActionHandler {
|
|
32
|
+
protected modelState: HydraniumGlspRecordingState<AnyObject>;
|
|
33
|
+
protected readonly actionDispatcher: ActionDispatcher;
|
|
34
|
+
protected readonly logger: Logger;
|
|
35
|
+
protected readonly clientProxy: GLSPClientProxy;
|
|
36
|
+
protected executeHandler(operation: Operation, handler: OperationHandler): Promise<Action[]>;
|
|
37
|
+
/**
|
|
38
|
+
* Run `operation`; push it when its command was written, and submit the
|
|
39
|
+
* model when it executed one, written or dropped.
|
|
40
|
+
*/
|
|
41
|
+
protected runOperation(operation: Operation, handler: OperationHandler): Promise<Action[]>;
|
|
42
|
+
/**
|
|
43
|
+
* Deliver what a queued operation answered: a message straight to the
|
|
44
|
+
* client, as {@link reportFailure} sends one, the rest through the
|
|
45
|
+
* dispatcher. A failure to deliver is logged, not reported as the
|
|
46
|
+
* operation's.
|
|
47
|
+
*/
|
|
48
|
+
protected deliverQueued(actions: Action[]): void;
|
|
49
|
+
/**
|
|
50
|
+
* Log `error` with {@link logActionFailure}, as the server logs a failed
|
|
51
|
+
* action, and send the client the error message GLSP sends for one. A
|
|
52
|
+
* queued operation that fails once its diagram has closed, which the
|
|
53
|
+
* storage's dispose marks by clearing the state's session, is logged at
|
|
54
|
+
* `debug` and told to no client, as the server treats an ended session.
|
|
55
|
+
*/
|
|
56
|
+
protected reportFailure(operation: Operation, error: unknown): void;
|
|
57
|
+
/**
|
|
58
|
+
* Send `action` straight to the client, as GLSP's server sends a failed
|
|
59
|
+
* action's message. Sent through the dispatcher instead, an action of a
|
|
60
|
+
* kind the client registered no handler for is rejected.
|
|
61
|
+
*/
|
|
62
|
+
protected sendToClient(action: Action): void;
|
|
63
|
+
}
|
|
64
|
+
//# sourceMappingURL=hydranium-glsp-operation-action-handler.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"hydranium-glsp-operation-action-handler.d.ts","sourceRoot":"","sources":["../../src/command/hydranium-glsp-operation-action-handler.ts"],"names":[],"mappings":"AAAA;;;;;;;kFAOkF;AAElF,OAAO,EACJ,KAAK,MAAM,EACX,gBAAgB,EAChB,KAAK,SAAS,EACd,eAAe,EAEf,MAAM,EAEN,KAAK,SAAS,EACd,sBAAsB,EACtB,KAAK,gBAAgB,EACvB,MAAM,sBAAsB,CAAC;AAK9B,OAAO,EAAE,KAAK,2BAA2B,EAAE,MAAM,uCAAuC,CAAC;AAEzF;;;;;;;;;;;;;;;;;;;GAmBG;AACH,qBACa,mCAAoC,SAAQ,sBAAsB;IAC5E,UAAkB,UAAU,EAAE,2BAA2B,CAAC,SAAS,CAAC,CAAC;IAC3C,SAAS,CAAC,QAAQ,CAAC,gBAAgB,EAAG,gBAAgB,CAAC;IACjE,SAAS,CAAC,QAAQ,CAAC,MAAM,EAAG,MAAM,CAAC;IAC1B,SAAS,CAAC,QAAQ,CAAC,WAAW,EAAG,eAAe,CAAC;IAE1E,UAAmB,cAAc,CAAC,SAAS,EAAE,SAAS,EAAE,OAAO,EAAE,gBAAgB,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC,CAWpG;IAED;;;OAGG;IACH,UAAgB,YAAY,CAAC,SAAS,EAAE,SAAS,EAAE,OAAO,EAAE,gBAAgB,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC,CAgB/F;IAED;;;;;OAKG;IACH,SAAS,CAAC,aAAa,CAAC,OAAO,EAAE,MAAM,EAAE,GAAG,IAAI,CAQ/C;IAED;;;;;;OAMG;IACH,SAAS,CAAC,aAAa,CAAC,SAAS,EAAE,SAAS,EAAE,KAAK,EAAE,OAAO,GAAG,IAAI,CAclE;IAED;;;;OAIG;IACH,SAAS,CAAC,YAAY,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI,CAM3C;CACH"}
|
|
@@ -0,0 +1,142 @@
|
|
|
1
|
+
/********************************************************************************
|
|
2
|
+
* Copyright (c) 2026 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 { ActionDispatcher, GLSPClientProxy, GLSPServerError, Logger, MessageAction, OperationActionHandler } from '@eclipse-glsp/server';
|
|
19
|
+
import { describeErrorWithStack } from '@hydranium/protocol';
|
|
20
|
+
import { inject, injectable } from 'inversify';
|
|
21
|
+
import { logActionFailure } from './diagram-edit-dropped-error.js';
|
|
22
|
+
import { HydraniumGlspOperationCommand, openOperationOf, runOperation } from './hydranium-glsp-operation-command.js';
|
|
23
|
+
/**
|
|
24
|
+
* GLSP's operation action handler, running each operation as a
|
|
25
|
+
* {@link HydraniumGlspOperationCommand} inside the state's `runExclusive`,
|
|
26
|
+
* which covers the operation, its write, the command-stack push and the
|
|
27
|
+
* submit, so neither another operation, an undo nor the storage's capture
|
|
28
|
+
* lands between them.
|
|
29
|
+
*
|
|
30
|
+
* An operation dispatched while another is open, as a handler's plain
|
|
31
|
+
* `dispatch` does, is queued behind it and its dispatch resolves at once;
|
|
32
|
+
* awaited inside the open operation, it would wait for the operation awaiting
|
|
33
|
+
* it. It writes, pushes and submits on its own, and a failure is reported to
|
|
34
|
+
* the client as GLSP reports a failed client action.
|
|
35
|
+
*
|
|
36
|
+
* Only operations are queued that way, and only while one is open, its undo's
|
|
37
|
+
* side effects included. Code running inside the boundary otherwise must not
|
|
38
|
+
* dispatch an operation and await it: a GModel factory or a submit after an
|
|
39
|
+
* operation, an undo's write and submit, the storage's render. Nor may any code
|
|
40
|
+
* inside the boundary await a dispatched undo, redo or model request, which
|
|
41
|
+
* take the boundary themselves. Each waits for the section awaiting it.
|
|
42
|
+
*/
|
|
43
|
+
let HydraniumGlspOperationActionHandler = class HydraniumGlspOperationActionHandler extends OperationActionHandler {
|
|
44
|
+
actionDispatcher;
|
|
45
|
+
logger;
|
|
46
|
+
clientProxy;
|
|
47
|
+
executeHandler(operation, handler) {
|
|
48
|
+
const queued = openOperationOf(this.modelState) !== undefined;
|
|
49
|
+
const run = this.modelState.runExclusive(() => this.runOperation(operation, handler));
|
|
50
|
+
if (!queued) {
|
|
51
|
+
return run;
|
|
52
|
+
}
|
|
53
|
+
run.then(actions => this.deliverQueued(actions), (error) => this.reportFailure(operation, error));
|
|
54
|
+
return Promise.resolve([]);
|
|
55
|
+
}
|
|
56
|
+
/**
|
|
57
|
+
* Run `operation`; push it when its command was written, and submit the
|
|
58
|
+
* model when it executed one, written or dropped.
|
|
59
|
+
*/
|
|
60
|
+
async runOperation(operation, handler) {
|
|
61
|
+
// A queued operation can find the diagram read-only by the time it runs.
|
|
62
|
+
if (this.modelState.isReadonly) {
|
|
63
|
+
return [
|
|
64
|
+
MessageAction.create(`Server is in readonly-mode! Could not execute operation: ${operation.kind}`, { severity: 'WARNING' })
|
|
65
|
+
];
|
|
66
|
+
}
|
|
67
|
+
const command = new HydraniumGlspOperationCommand(this.modelState);
|
|
68
|
+
const outcome = await runOperation(command, () => handler.execute(operation));
|
|
69
|
+
if (outcome === 'none') {
|
|
70
|
+
return [];
|
|
71
|
+
}
|
|
72
|
+
if (outcome === 'executed') {
|
|
73
|
+
await this.executeCommand(command);
|
|
74
|
+
}
|
|
75
|
+
return this.submitModel();
|
|
76
|
+
}
|
|
77
|
+
/**
|
|
78
|
+
* Deliver what a queued operation answered: a message straight to the
|
|
79
|
+
* client, as {@link reportFailure} sends one, the rest through the
|
|
80
|
+
* dispatcher. A failure to deliver is logged, not reported as the
|
|
81
|
+
* operation's.
|
|
82
|
+
*/
|
|
83
|
+
deliverQueued(actions) {
|
|
84
|
+
const messages = actions.filter(action => MessageAction.is(action));
|
|
85
|
+
messages.forEach(message => this.sendToClient(message));
|
|
86
|
+
this.actionDispatcher
|
|
87
|
+
.dispatchAll(actions.filter(action => !MessageAction.is(action)))
|
|
88
|
+
.catch((error) => this.logger.warn(`Could not deliver the result of a queued operation: ${describeErrorWithStack(error)}`));
|
|
89
|
+
}
|
|
90
|
+
/**
|
|
91
|
+
* Log `error` with {@link logActionFailure}, as the server logs a failed
|
|
92
|
+
* action, and send the client the error message GLSP sends for one. A
|
|
93
|
+
* queued operation that fails once its diagram has closed, which the
|
|
94
|
+
* storage's dispose marks by clearing the state's session, is logged at
|
|
95
|
+
* `debug` and told to no client, as the server treats an ended session.
|
|
96
|
+
*/
|
|
97
|
+
reportFailure(operation, error) {
|
|
98
|
+
// Queued only after a load registered the session, so none now means the diagram has closed.
|
|
99
|
+
if (this.modelState.modelSession === undefined) {
|
|
100
|
+
this.logger.debug(`Operation '${operation.kind}' ended with its diagram: ${describeErrorWithStack(error)}`);
|
|
101
|
+
return;
|
|
102
|
+
}
|
|
103
|
+
logActionFailure(this.logger, operation, error);
|
|
104
|
+
let message = `Could not process action: '${operation.kind}`;
|
|
105
|
+
let details = error instanceof Error ? error.toString() : String(error);
|
|
106
|
+
if (error instanceof GLSPServerError) {
|
|
107
|
+
details = String(error.cause);
|
|
108
|
+
message = error.message;
|
|
109
|
+
}
|
|
110
|
+
this.sendToClient(MessageAction.create(message, { severity: 'ERROR', details }));
|
|
111
|
+
}
|
|
112
|
+
/**
|
|
113
|
+
* Send `action` straight to the client, as GLSP's server sends a failed
|
|
114
|
+
* action's message. Sent through the dispatcher instead, an action of a
|
|
115
|
+
* kind the client registered no handler for is rejected.
|
|
116
|
+
*/
|
|
117
|
+
sendToClient(action) {
|
|
118
|
+
try {
|
|
119
|
+
this.clientProxy.process({ clientId: this.modelState.clientId, action });
|
|
120
|
+
}
|
|
121
|
+
catch (error) {
|
|
122
|
+
this.logger.warn(`Could not send '${action.kind}' to the client: ${describeErrorWithStack(error)}`);
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
};
|
|
126
|
+
__decorate([
|
|
127
|
+
inject(ActionDispatcher),
|
|
128
|
+
__metadata("design:type", Object)
|
|
129
|
+
], HydraniumGlspOperationActionHandler.prototype, "actionDispatcher", void 0);
|
|
130
|
+
__decorate([
|
|
131
|
+
inject(Logger),
|
|
132
|
+
__metadata("design:type", Logger)
|
|
133
|
+
], HydraniumGlspOperationActionHandler.prototype, "logger", void 0);
|
|
134
|
+
__decorate([
|
|
135
|
+
inject(GLSPClientProxy),
|
|
136
|
+
__metadata("design:type", Object)
|
|
137
|
+
], HydraniumGlspOperationActionHandler.prototype, "clientProxy", void 0);
|
|
138
|
+
HydraniumGlspOperationActionHandler = __decorate([
|
|
139
|
+
injectable()
|
|
140
|
+
], HydraniumGlspOperationActionHandler);
|
|
141
|
+
export { HydraniumGlspOperationActionHandler };
|
|
142
|
+
//# sourceMappingURL=hydranium-glsp-operation-action-handler.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"hydranium-glsp-operation-action-handler.js","sourceRoot":"","sources":["../../src/command/hydranium-glsp-operation-action-handler.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,250 @@
|
|
|
1
|
+
/********************************************************************************
|
|
2
|
+
* Copyright (c) 2026 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 AnyObject, Command, type MaybePromise } from '@eclipse-glsp/server';
|
|
10
|
+
import { type AstNode, type MultiReference, type Reference } from '@hydranium/langium';
|
|
11
|
+
import { type ModelVersion } from '@hydranium/protocol';
|
|
12
|
+
import { type HydraniumGlspRecordingState } from './hydranium-glsp-recording-command.js';
|
|
13
|
+
/**
|
|
14
|
+
* What becomes of an operation {@link HydraniumGlspOperationCommand} ran: its
|
|
15
|
+
* command written, its write dropped, or no command.
|
|
16
|
+
*/
|
|
17
|
+
export type OperationOutcome = 'executed' | 'dropped' | 'none';
|
|
18
|
+
/**
|
|
19
|
+
* One executed side effect the operation undoes and redoes: a recording
|
|
20
|
+
* command's bridge, or a command that does not record.
|
|
21
|
+
*/
|
|
22
|
+
export interface OperationSideEffect {
|
|
23
|
+
undo(): MaybePromise<void>;
|
|
24
|
+
redo(): MaybePromise<void>;
|
|
25
|
+
}
|
|
26
|
+
/** The source model an operation changed, before and after it; a redo applies `from → to`, an undo the reverse. */
|
|
27
|
+
export interface OperationTransition<TSourceModel> {
|
|
28
|
+
readonly from: TSourceModel;
|
|
29
|
+
readonly to: TSourceModel;
|
|
30
|
+
}
|
|
31
|
+
/** Whether an undo or a redo of an operation runs. */
|
|
32
|
+
export type UndoRedoDirection = 'undo' | 'redo';
|
|
33
|
+
/**
|
|
34
|
+
* The members of an operation the framework's state, recording command and
|
|
35
|
+
* operation action handler call; reached through {@link openOperationOf} and
|
|
36
|
+
* {@link runOperation}, not through the operation itself.
|
|
37
|
+
*/
|
|
38
|
+
export interface OperationInternals {
|
|
39
|
+
run(create: () => MaybePromise<Command | undefined>): Promise<OperationOutcome>;
|
|
40
|
+
workingRootOf(key: string, built: AstNode): AstNode;
|
|
41
|
+
existingWorkingRootOf(key: string): AstNode | undefined;
|
|
42
|
+
workingUriOf(node: AstNode): string | undefined;
|
|
43
|
+
builtNodeOf<T extends AstNode>(node: T): T;
|
|
44
|
+
recordWrittenRoot(root: AstNode): void;
|
|
45
|
+
recordDropped(current: AstNode | undefined): void;
|
|
46
|
+
recordExecuted(step: OperationSideEffect): void;
|
|
47
|
+
assertNotDuringUndoRedo(label: string): void;
|
|
48
|
+
amendBefore(update: (before: AnyObject) => AnyObject): void;
|
|
49
|
+
}
|
|
50
|
+
/**
|
|
51
|
+
* The canonical URI of the document whose working copy `node` belongs to;
|
|
52
|
+
* `undefined` for a node of no copy. A copy has no `$document`, so a lookup
|
|
53
|
+
* that routes by a node's document routes a copy node through this instead.
|
|
54
|
+
*/
|
|
55
|
+
export declare function workingUriOfCopy(node: AstNode): string | undefined;
|
|
56
|
+
/** The operation open on `state`, executing, undoing or redoing its side effects; `undefined` between operations. */
|
|
57
|
+
export declare function openOperationOf(state: object): OperationInternals | undefined;
|
|
58
|
+
/** Run `operation` as {@link HydraniumGlspOperationCommand} describes. */
|
|
59
|
+
export declare function runOperation<TSourceModel extends AnyObject>(operation: HydraniumGlspOperationCommand<TSourceModel>, create: () => MaybePromise<Command | undefined>): Promise<OperationOutcome>;
|
|
60
|
+
/**
|
|
61
|
+
* One GLSP operation as a transaction, and the command-stack entry that undoes
|
|
62
|
+
* and redoes it.
|
|
63
|
+
*
|
|
64
|
+
* {@link runOperation} executes the operation's command against copies of the
|
|
65
|
+
* built roots and writes their projection once; a reader of a built root never
|
|
66
|
+
* sees an edit its write has not committed, and an edit the write drops stays
|
|
67
|
+
* out of every built root. Call it inside `runExclusive`: the copies, the write
|
|
68
|
+
* and the capture that follows assume no other operation, undo or storage
|
|
69
|
+
* capture runs meanwhile.
|
|
70
|
+
*
|
|
71
|
+
* The entry holds one model transition, from the copies' projection before the
|
|
72
|
+
* command to their projection after it, both as the documents hold them after
|
|
73
|
+
* a write (see `normalizeTransition`), and the side effects that executed, in
|
|
74
|
+
* order: each command that does not record, a `CompoundCommand`'s children
|
|
75
|
+
* counted one by one, and the bridge of each recording command at any depth.
|
|
76
|
+
* Rollback and undo run them in reverse, redo in order. A recording command
|
|
77
|
+
* executed inside an open operation writes nothing, and its own undo and redo
|
|
78
|
+
* do nothing there.
|
|
79
|
+
*/
|
|
80
|
+
export declare class HydraniumGlspOperationCommand<TSourceModel extends AnyObject = AnyObject> implements Command {
|
|
81
|
+
protected readonly modelState: HydraniumGlspRecordingState<TSourceModel>;
|
|
82
|
+
/** Working copies by canonical URI. */
|
|
83
|
+
protected readonly workingRoots: Map<string, AstNode>;
|
|
84
|
+
/** Built node to copy and copy to built node, across every working root, as `AstUtils.copyAstNode` records it. */
|
|
85
|
+
protected readonly trace: Map<AstNode, AstNode>;
|
|
86
|
+
/** The source root captured when the operation opened. */
|
|
87
|
+
protected sourceRootAtOpen?: AstNode;
|
|
88
|
+
/** The version of {@link sourceRootAtOpen}, which the write is gated on. */
|
|
89
|
+
protected baseVersionAtOpen?: ModelVersion;
|
|
90
|
+
/**
|
|
91
|
+
* The primary root to capture when the operation closes: the one its write
|
|
92
|
+
* produced, or the document's built one after a dropped write or one the
|
|
93
|
+
* document already held.
|
|
94
|
+
*/
|
|
95
|
+
protected writtenRoot?: AstNode;
|
|
96
|
+
/** Whether the write's reconcile dropped the edit. */
|
|
97
|
+
protected dropped: boolean;
|
|
98
|
+
/** The command the operation executed. */
|
|
99
|
+
protected command?: Command;
|
|
100
|
+
/** The side effects that executed, in execution order. */
|
|
101
|
+
protected readonly steps: OperationSideEffect[];
|
|
102
|
+
/**
|
|
103
|
+
* The copies' projection when the operation opened, amended as documents
|
|
104
|
+
* join or leave the write set during it.
|
|
105
|
+
*/
|
|
106
|
+
protected before?: TSourceModel;
|
|
107
|
+
protected transition?: OperationTransition<TSourceModel>;
|
|
108
|
+
/** Whether an undo or redo is running the side effects, on copies it discards. */
|
|
109
|
+
protected undoingOrRedoing: boolean;
|
|
110
|
+
constructor(modelState: HydraniumGlspRecordingState<TSourceModel>);
|
|
111
|
+
/**
|
|
112
|
+
* Open the operation, execute the command `create` makes, write the result
|
|
113
|
+
* once, and close the operation.
|
|
114
|
+
*
|
|
115
|
+
* `create` runs inside the operation, because handlers resolve their
|
|
116
|
+
* targets there. On any failure, `create`, the command or the write, the
|
|
117
|
+
* executed commands' side effects are undone, nothing is written, and the
|
|
118
|
+
* error is rethrown; after a write whose reconcile dropped the edit, the
|
|
119
|
+
* side effects are undone the same way and this answers `'dropped'`. The
|
|
120
|
+
* operation closes either way: the copies are dropped and the source root
|
|
121
|
+
* is captured again, with the base version, every tracked version and the
|
|
122
|
+
* index.
|
|
123
|
+
*/
|
|
124
|
+
protected run(create: () => MaybePromise<Command | undefined>): Promise<'executed' | 'dropped' | 'none'>;
|
|
125
|
+
/**
|
|
126
|
+
* Awaited where the operation, or an undo or redo of it, yields to code it
|
|
127
|
+
* does not control: before creating the command, before each side effect
|
|
128
|
+
* executes, is undone or redone, rolls back or is compensated, before
|
|
129
|
+
* projecting the copies, before resolving an undo or redo. Does nothing; a
|
|
130
|
+
* test overrides it to land a foreign edit or a failure there.
|
|
131
|
+
*/
|
|
132
|
+
protected checkpoint(_point: 'create' | 'execute' | 'project' | 'resolve' | UndoRedoDirection | 'rollback' | 'compensate'): Promise<void>;
|
|
133
|
+
/**
|
|
134
|
+
* Does nothing: {@link runOperation} executed the command; the command stack
|
|
135
|
+
* calls this when it pushes the entry.
|
|
136
|
+
*/
|
|
137
|
+
execute(): Promise<void>;
|
|
138
|
+
undo(): Promise<void>;
|
|
139
|
+
redo(): Promise<void>;
|
|
140
|
+
canUndo(): boolean;
|
|
141
|
+
/** The working copy of `built`, the root of the document whose canonical URI is `key`, made on the first request. */
|
|
142
|
+
protected workingRootOf(key: string, built: AstNode): AstNode;
|
|
143
|
+
/** The canonical URI of the working root `node` belongs to; `undefined` for a node of no copy. */
|
|
144
|
+
protected workingUriOf(node: AstNode): string | undefined;
|
|
145
|
+
/**
|
|
146
|
+
* The built node `node` was copied from; `node` itself for a node of no copy
|
|
147
|
+
* and for a node the operation created.
|
|
148
|
+
*/
|
|
149
|
+
protected builtNodeOf<T extends AstNode>(node: T): T;
|
|
150
|
+
/**
|
|
151
|
+
* Copy the source root, and point the index at the copy, so the nodes a
|
|
152
|
+
* handler resolves by id are the nodes it edits.
|
|
153
|
+
*/
|
|
154
|
+
protected open(): void;
|
|
155
|
+
/**
|
|
156
|
+
* Drop the copies, move every id added through `indexSemanticElement` from
|
|
157
|
+
* a copy back to the built node it was copied from, and capture the source
|
|
158
|
+
* root again, whether or not the write changed it.
|
|
159
|
+
*/
|
|
160
|
+
protected close(): void;
|
|
161
|
+
/**
|
|
162
|
+
* Undo the side effects of the executed commands, newest first, each step
|
|
163
|
+
* on its own: a step that fails is logged and the rest are still undone.
|
|
164
|
+
* The operation's own error is the one thrown.
|
|
165
|
+
*/
|
|
166
|
+
protected rollback(): Promise<void>;
|
|
167
|
+
/**
|
|
168
|
+
* Run each of `actions`, each reverting a side effect of its own: a failure
|
|
169
|
+
* is logged as `what` failing and the rest still run, so one step that
|
|
170
|
+
* cannot be reverted leaves no other step applied. The caller reports its
|
|
171
|
+
* own failure, not these.
|
|
172
|
+
*/
|
|
173
|
+
protected runEach(actions: ReadonlyArray<() => MaybePromise<void>>, what: string, point: 'rollback' | 'compensate'): Promise<void>;
|
|
174
|
+
/**
|
|
175
|
+
* `command` with every side effect it executes recorded as a step: the
|
|
176
|
+
* command itself, or for a `CompoundCommand` each child, at any depth. A
|
|
177
|
+
* tracked command's own undo and redo do nothing, so a `CompoundCommand`
|
|
178
|
+
* reverting its children when a later one throws leaves that to the steps.
|
|
179
|
+
*
|
|
180
|
+
* The children are read from GLSP's protected `CompoundCommand.commands`;
|
|
181
|
+
* should that field stop being readable, a compound becomes one step and
|
|
182
|
+
* its children's side effects no longer interleave with the bridges.
|
|
183
|
+
*/
|
|
184
|
+
protected tracked(command: Command): Command;
|
|
185
|
+
/** The model projected from the working copies, cloned; `undefined` for a state that projects none. */
|
|
186
|
+
protected project(): Promise<TSourceModel | undefined>;
|
|
187
|
+
/**
|
|
188
|
+
* Resolve the transition onto the current model, run the commands' side
|
|
189
|
+
* effects, then write once, gated on the versions the model was read at. A
|
|
190
|
+
* collision does nothing but warn; a transition with nothing left to apply,
|
|
191
|
+
* or one the model already holds, still runs the side effects.
|
|
192
|
+
*
|
|
193
|
+
* The caller holds `runExclusive`, which nothing here takes again.
|
|
194
|
+
*/
|
|
195
|
+
protected undoOrRedo(direction: UndoRedoDirection): Promise<void>;
|
|
196
|
+
/**
|
|
197
|
+
* Write `model` once through the state's write path, gated on the versions
|
|
198
|
+
* read when the operation opened, a conflict reconciled as for any write of
|
|
199
|
+
* the state; `false` when the reconcile dropped it.
|
|
200
|
+
*/
|
|
201
|
+
protected write(model: TSourceModel): Promise<boolean>;
|
|
202
|
+
/**
|
|
203
|
+
* Run the recorded steps of an undo or redo against fresh copies of the
|
|
204
|
+
* built roots, made on demand as in an operation and discarded unwritten,
|
|
205
|
+
* then write `merged`, the resolved transition, through {@link write}: that
|
|
206
|
+
* write is what changes the model, and a step that edits `sourceRoot` must
|
|
207
|
+
* not reach the root every reader shares. A recording command executed here
|
|
208
|
+
* throws.
|
|
209
|
+
*
|
|
210
|
+
* When a step or the write throws, or the write's reconcile drops it, the
|
|
211
|
+
* steps already run are run the other way, newest first, and the error is
|
|
212
|
+
* rethrown with nothing written; GLSP's command stack then flushes, as it
|
|
213
|
+
* does for any undo or redo that fails.
|
|
214
|
+
*/
|
|
215
|
+
protected undoOrRedoSideEffects(direction: UndoRedoDirection, merged?: TSourceModel): Promise<void>;
|
|
216
|
+
/**
|
|
217
|
+
* Run `steps`, which a failed undo or redo already ran, the other way, each
|
|
218
|
+
* on its own as {@link rollback} does; the undo or redo's own error is the
|
|
219
|
+
* one thrown.
|
|
220
|
+
*/
|
|
221
|
+
protected compensate(steps: readonly OperationSideEffect[], direction: UndoRedoDirection): Promise<void>;
|
|
222
|
+
/**
|
|
223
|
+
* The transition and the recorded steps as `direction` runs them: an undo
|
|
224
|
+
* runs the transition backwards and each step's undo, newest first, and is
|
|
225
|
+
* reverted by each step's redo; a redo the other way round.
|
|
226
|
+
*/
|
|
227
|
+
protected inDirection(direction: UndoRedoDirection): {
|
|
228
|
+
readonly transition?: OperationTransition<TSourceModel>;
|
|
229
|
+
readonly steps: readonly OperationSideEffect[];
|
|
230
|
+
run(step: OperationSideEffect): MaybePromise<void>;
|
|
231
|
+
revert(step: OperationSideEffect): MaybePromise<void>;
|
|
232
|
+
};
|
|
233
|
+
/**
|
|
234
|
+
* The copy's stand-in for `original`: its target is the copy of
|
|
235
|
+
* `original`'s target once one exists, read when asked so a copy made later
|
|
236
|
+
* in the operation is found, else that target itself. A handler compares a
|
|
237
|
+
* target by identity with nodes it resolved from a copy.
|
|
238
|
+
*/
|
|
239
|
+
protected buildWorkingReference(original: Reference): Reference;
|
|
240
|
+
/** {@link buildWorkingReference} for a reference with several targets. */
|
|
241
|
+
protected buildWorkingMultiReference(original: MultiReference): MultiReference;
|
|
242
|
+
/**
|
|
243
|
+
* Replace every multi-reference under `working` with a working one.
|
|
244
|
+
* `AstUtils.copyAstNode` rebuilds single references only and leaves a
|
|
245
|
+
* multi-reference object shared with the built root, whose targets are
|
|
246
|
+
* built nodes.
|
|
247
|
+
*/
|
|
248
|
+
protected rebuildWorkingMultiReferences(working: AstNode): void;
|
|
249
|
+
}
|
|
250
|
+
//# sourceMappingURL=hydranium-glsp-operation-command.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"hydranium-glsp-operation-command.d.ts","sourceRoot":"","sources":["../../src/command/hydranium-glsp-operation-command.ts"],"names":[],"mappings":"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"}
|