@eclipse-glsp/client 2.6.0-next.14 → 2.6.0-next.16
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/lib/base/action-dispatcher.d.ts +6 -2
- package/lib/base/action-dispatcher.d.ts.map +1 -1
- package/lib/base/action-dispatcher.js +58 -16
- package/lib/base/action-dispatcher.js.map +1 -1
- package/package.json +4 -4
- package/src/base/action-dispatcher.spec.ts +180 -2
- package/src/base/action-dispatcher.ts +64 -18
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/********************************************************************************
|
|
2
|
-
* Copyright (c) 2019-
|
|
2
|
+
* Copyright (c) 2019-2026 EclipseSource and others.
|
|
3
3
|
*
|
|
4
4
|
* This program and the accompanying materials are made available under the
|
|
5
5
|
* terms of the Eclipse Public License v. 2.0 which is available at
|
|
@@ -13,7 +13,7 @@
|
|
|
13
13
|
*
|
|
14
14
|
* SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
|
|
15
15
|
********************************************************************************/
|
|
16
|
-
import { Action, ActionDispatcher, ActionHandlerRegistry, Deferred, GModelRoot, IActionDispatcher, RequestAction, ResponseAction } from '@eclipse-glsp/sprotty';
|
|
16
|
+
import { Action, ActionDispatcher, ActionHandler, ActionHandlerRegistry, Deferred, GModelRoot, IActionDispatcher, RequestAction, ResponseAction } from '@eclipse-glsp/sprotty';
|
|
17
17
|
import { IGModelRootListener } from './editor-context-service';
|
|
18
18
|
import { ModelInitializationConstraint } from './model/model-initialization-constraint';
|
|
19
19
|
export declare class GLSPActionDispatcher extends ActionDispatcher implements IGModelRootListener, IActionDispatcher {
|
|
@@ -47,6 +47,10 @@ export declare class GLSPActionDispatcher extends ActionDispatcher implements IG
|
|
|
47
47
|
modelRootChanged(_root: Readonly<GModelRoot>): void;
|
|
48
48
|
dispatch(action: Action): Promise<void>;
|
|
49
49
|
protected handleAction(action: Action): Promise<void>;
|
|
50
|
+
protected handleResponseAction(action: ResponseAction): Promise<void>;
|
|
51
|
+
protected doHandleAction(action: Action): Promise<void>;
|
|
52
|
+
protected handleActionWithoutHandler(action: Action): Promise<void>;
|
|
53
|
+
protected handleActionWithHandler(action: Action, handlers: ActionHandler[]): Promise<void>;
|
|
50
54
|
request<Res extends ResponseAction>(action: RequestAction<Res>): Promise<Res>;
|
|
51
55
|
/**
|
|
52
56
|
* Dispatch a request and waits for a response until the timeout given in `timeoutMs` has
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"action-dispatcher.d.ts","sourceRoot":"","sources":["../../src/base/action-dispatcher.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;kFAckF;AAClF,OAAO,EACH,MAAM,EACN,gBAAgB,EAChB,qBAAqB,EACrB,QAAQ,EAER,UAAU,EACV,iBAAiB,
|
|
1
|
+
{"version":3,"file":"action-dispatcher.d.ts","sourceRoot":"","sources":["../../src/base/action-dispatcher.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;kFAckF;AAClF,OAAO,EACH,MAAM,EACN,gBAAgB,EAChB,aAAa,EACb,qBAAqB,EACrB,QAAQ,EAER,UAAU,EACV,iBAAiB,EAEjB,aAAa,EACb,cAAc,EAGjB,MAAM,uBAAuB,CAAC;AAG/B,OAAO,EAAE,mBAAmB,EAAE,MAAM,0BAA0B,CAAC;AAE/D,OAAO,EAAE,6BAA6B,EAAE,MAAM,yCAAyC,CAAC;AAExF,qBACa,oBAAqB,SAAQ,gBAAiB,YAAW,mBAAmB,EAAE,iBAAiB;IACxG,SAAS,CAAC,QAAQ,CAAC,QAAQ,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,OAAO,CAAC,CAAa;IACrE,SAAS,CAAC,qBAAqB,UAAS;IAGxC,SAAS,CAAC,wBAAwB,EAAE,6BAA6B,CAAC;IAElE,UACmB,qBAAqB,EAAE,qBAAqB,CAAC;IAEhE,gGAAgG;IAEhG,UAAgE,6BAA6B,EAAE,MAAM,OAAO,CAAC,qBAAqB,CAAC,CAAC;IACpI,SAAS,CAAC,eAAe,EAAE,MAAM,EAAE,CAAM;IAEzC,SAAS,CAAC,kBAAkB,iBAAwB;IAE3C,UAAU,IAAI,OAAO,CAAC,IAAI,CAAC;cAQpB,YAAY,IAAI,OAAO,CAAC,IAAI,CAAC;IAe7C,SAAS,CAAC,wBAAwB,IAAI,IAAI;IAQ1C,oBAAoB,IAAI,OAAO,CAAC,IAAI,CAAC;IAIrC,UAAU,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO;IAInC;;;;OAIG;IACH,4BAA4B,CAAC,GAAG,OAAO,EAAE,MAAM,EAAE,GAAG,IAAI;IAIxD;;;;;;OAMG;IACH,uBAAuB,CAAC,GAAG,OAAO,EAAE,MAAM,EAAE,GAAG,IAAI;IAInD,gBAAgB,CAAC,KAAK,EAAE,QAAQ,CAAC,UAAU,CAAC,GAAG,IAAI;IAUpC,QAAQ,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;cAMnC,YAAY,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;cAI9C,oBAAoB,CAAC,MAAM,EAAE,cAAc,GAAG,OAAO,CAAC,IAAI,CAAC;IA2B3E,SAAS,CAAC,cAAc,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;cAKvC,0BAA0B,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;cAgBzD,uBAAuB,CAAC,MAAM,EAAE,MAAM,EAAE,QAAQ,EAAE,aAAa,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC;IAexF,OAAO,CAAC,GAAG,SAAS,cAAc,EAAE,MAAM,EAAE,aAAa,CAAC,GAAG,CAAC,GAAG,OAAO,CAAC,GAAG,CAAC;IAQtF;;;;;;;;;OASG;IACH,YAAY,CAAC,GAAG,SAAS,cAAc,EACnC,MAAM,EAAE,aAAa,CAAC,GAAG,CAAC,EAC1B,SAAS,SAAO,EAChB,eAAe,UAAQ,GACxB,OAAO,CAAC,GAAG,GAAG,SAAS,CAAC;CA0B9B"}
|
|
@@ -11,7 +11,7 @@ var __metadata = (this && this.__metadata) || function (k, v) {
|
|
|
11
11
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
12
|
exports.GLSPActionDispatcher = void 0;
|
|
13
13
|
/********************************************************************************
|
|
14
|
-
* Copyright (c) 2019-
|
|
14
|
+
* Copyright (c) 2019-2026 EclipseSource and others.
|
|
15
15
|
*
|
|
16
16
|
* This program and the accompanying materials are made available under the
|
|
17
17
|
* terms of the Eclipse Public License v. 2.0 which is available at
|
|
@@ -105,24 +105,66 @@ let GLSPActionDispatcher = class GLSPActionDispatcher extends sprotty_1.ActionDi
|
|
|
105
105
|
return result;
|
|
106
106
|
}
|
|
107
107
|
handleAction(action) {
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
108
|
+
return sprotty_1.ResponseAction.hasValidResponseId(action) ? this.handleResponseAction(action) : this.doHandleAction(action);
|
|
109
|
+
}
|
|
110
|
+
async handleResponseAction(action) {
|
|
111
|
+
// clear any pending timeout
|
|
112
|
+
const timeout = this.timeouts.get(action.responseId);
|
|
113
|
+
if (timeout !== undefined) {
|
|
114
|
+
clearTimeout(timeout);
|
|
115
|
+
this.timeouts.delete(action.responseId);
|
|
116
|
+
}
|
|
117
|
+
// check for matching request
|
|
118
|
+
const request = this.requests.get(action.responseId);
|
|
119
|
+
if (!request) {
|
|
120
|
+
// treat no matching request by dispatching action normally
|
|
121
|
+
this.logger.log(this, 'No matching request for response, dispatch normally', action);
|
|
122
|
+
action.responseId = '';
|
|
123
|
+
return this.handleAction(action);
|
|
124
|
+
}
|
|
125
|
+
this.requests.delete(action.responseId);
|
|
126
|
+
if (sprotty_1.RejectAction.is(action)) {
|
|
127
|
+
// translation reject action to request rejection
|
|
128
|
+
request.reject(new Error(action.message));
|
|
129
|
+
this.logger.warn(this, `Request with id ${action.responseId} failed.`, action.message, action.detail);
|
|
130
|
+
}
|
|
131
|
+
else {
|
|
132
|
+
request.resolve(action);
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
doHandleAction(action) {
|
|
136
|
+
const handlers = this.actionHandlerRegistry.get(action.kind);
|
|
137
|
+
return handlers.length === 0 ? this.handleActionWithoutHandler(action) : this.handleActionWithHandler(action, handlers);
|
|
138
|
+
}
|
|
139
|
+
async handleActionWithoutHandler(action) {
|
|
140
|
+
if (glsp_model_source_1.OptionalAction.is(action) && !this.hasHandler(action)) {
|
|
141
|
+
return;
|
|
142
|
+
}
|
|
143
|
+
this.logger.warn(this, 'Missing handler for action', action);
|
|
144
|
+
const error = new Error(`Missing handler for action '${action.kind}'`);
|
|
145
|
+
if (!sprotty_1.RequestAction.is(action)) {
|
|
146
|
+
throw error;
|
|
147
|
+
}
|
|
148
|
+
const request = this.requests.get(action.requestId);
|
|
149
|
+
if (request !== undefined) {
|
|
150
|
+
this.requests.delete(action.requestId);
|
|
151
|
+
request.reject(error);
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
async handleActionWithHandler(action, handlers) {
|
|
155
|
+
this.logger.log(this, 'Handle', action);
|
|
156
|
+
const handlerResults = [];
|
|
157
|
+
for (const handler of handlers) {
|
|
158
|
+
const result = await handler.handle(action);
|
|
159
|
+
if (sprotty_1.Action.is(result)) {
|
|
160
|
+
handlerResults.push(this.dispatch(result));
|
|
114
161
|
}
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
if (deferred === undefined) {
|
|
119
|
-
action.responseId = '';
|
|
162
|
+
else if (result !== undefined) {
|
|
163
|
+
this.blockUntil = result.blockUntil;
|
|
164
|
+
handlerResults.push(this.commandStack.execute(result));
|
|
120
165
|
}
|
|
121
166
|
}
|
|
122
|
-
|
|
123
|
-
return Promise.resolve();
|
|
124
|
-
}
|
|
125
|
-
return super.handleAction(action);
|
|
167
|
+
await Promise.all(handlerResults);
|
|
126
168
|
}
|
|
127
169
|
request(action) {
|
|
128
170
|
if (!action.requestId && action.requestId === '') {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"action-dispatcher.js","sourceRoot":"","sources":["../../src/base/action-dispatcher.ts"],"names":[],"mappings":";;;;;;;;;;;;AAAA;;;;;;;;;;;;;;kFAckF;AAClF,
|
|
1
|
+
{"version":3,"file":"action-dispatcher.js","sourceRoot":"","sources":["../../src/base/action-dispatcher.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@eclipse-glsp/client",
|
|
3
|
-
"version": "2.6.0-next.
|
|
3
|
+
"version": "2.6.0-next.16+33c27e5",
|
|
4
4
|
"description": "A sprotty-based client for GLSP",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"eclipse",
|
|
@@ -46,10 +46,10 @@
|
|
|
46
46
|
"watch": "tsc -w"
|
|
47
47
|
},
|
|
48
48
|
"dependencies": {
|
|
49
|
-
"@eclipse-glsp/sprotty": "2.6.0-next.
|
|
49
|
+
"@eclipse-glsp/sprotty": "2.6.0-next.16+33c27e5",
|
|
50
50
|
"autocompleter": "^9.1.2",
|
|
51
51
|
"file-saver": "^2.0.5",
|
|
52
|
-
"lodash": "4.17.
|
|
52
|
+
"lodash": "4.17.23",
|
|
53
53
|
"snabbdom": "~3.5.1",
|
|
54
54
|
"vscode-jsonrpc": "8.2.0"
|
|
55
55
|
},
|
|
@@ -63,5 +63,5 @@
|
|
|
63
63
|
"publishConfig": {
|
|
64
64
|
"access": "public"
|
|
65
65
|
},
|
|
66
|
-
"gitHead": "
|
|
66
|
+
"gitHead": "33c27e5f2e0034522dd8bc11cde82b411fe3f8ff"
|
|
67
67
|
}
|
|
@@ -36,10 +36,10 @@ const testHandler: IActionHandler = {
|
|
|
36
36
|
handle: action => {
|
|
37
37
|
const request = action as RequestAction<ResponseAction>;
|
|
38
38
|
new Promise(resolve => setTimeout(resolve, testHandlerDelay)).then(() =>
|
|
39
|
-
actionDispatcher.dispatch(
|
|
39
|
+
actionDispatcher.dispatch({
|
|
40
40
|
kind: 'response',
|
|
41
41
|
responseId: request.requestId
|
|
42
|
-
})
|
|
42
|
+
} as ResponseAction)
|
|
43
43
|
);
|
|
44
44
|
}
|
|
45
45
|
};
|
|
@@ -85,4 +85,182 @@ describe('GLSPActionDispatcher', () => {
|
|
|
85
85
|
expect(dispatchSuccessful, 'Promise of re-dispatch should resolve successfully').to.be.true;
|
|
86
86
|
});
|
|
87
87
|
});
|
|
88
|
+
describe('async action handlers', () => {
|
|
89
|
+
it('should handle async action handlers correctly', async () => {
|
|
90
|
+
let handlerExecuted = false;
|
|
91
|
+
const asyncHandler: IActionHandler = {
|
|
92
|
+
handle: async () => {
|
|
93
|
+
await new Promise(resolve => setTimeout(resolve, 10));
|
|
94
|
+
handlerExecuted = true;
|
|
95
|
+
}
|
|
96
|
+
};
|
|
97
|
+
|
|
98
|
+
registry.register('asyncTest1', asyncHandler);
|
|
99
|
+
await actionDispatcher.dispatch({ kind: 'asyncTest1' });
|
|
100
|
+
|
|
101
|
+
expect(handlerExecuted).to.be.true;
|
|
102
|
+
});
|
|
103
|
+
|
|
104
|
+
it('should execute multiple async handlers sequentially', async () => {
|
|
105
|
+
const executionOrder: number[] = [];
|
|
106
|
+
const asyncHandler1: IActionHandler = {
|
|
107
|
+
handle: async () => {
|
|
108
|
+
await new Promise(resolve => setTimeout(resolve, 20));
|
|
109
|
+
executionOrder.push(1);
|
|
110
|
+
}
|
|
111
|
+
};
|
|
112
|
+
const asyncHandler2: IActionHandler = {
|
|
113
|
+
handle: async () => {
|
|
114
|
+
await new Promise(resolve => setTimeout(resolve, 10));
|
|
115
|
+
executionOrder.push(2);
|
|
116
|
+
}
|
|
117
|
+
};
|
|
118
|
+
|
|
119
|
+
registry.register('multiAsyncTest', asyncHandler1);
|
|
120
|
+
registry.register('multiAsyncTest', asyncHandler2);
|
|
121
|
+
await actionDispatcher.dispatch({ kind: 'multiAsyncTest' });
|
|
122
|
+
|
|
123
|
+
expect(executionOrder).to.deep.equal([1, 2]);
|
|
124
|
+
});
|
|
125
|
+
|
|
126
|
+
it('should handle mixed sync and async handlers correctly', async () => {
|
|
127
|
+
const executionOrder: number[] = [];
|
|
128
|
+
const syncHandler: IActionHandler = {
|
|
129
|
+
handle: () => {
|
|
130
|
+
executionOrder.push(1);
|
|
131
|
+
}
|
|
132
|
+
};
|
|
133
|
+
const asyncHandler: IActionHandler = {
|
|
134
|
+
handle: async () => {
|
|
135
|
+
await new Promise(resolve => setTimeout(resolve, 10));
|
|
136
|
+
executionOrder.push(2);
|
|
137
|
+
}
|
|
138
|
+
};
|
|
139
|
+
|
|
140
|
+
registry.register('mixedTest', syncHandler);
|
|
141
|
+
registry.register('mixedTest', asyncHandler);
|
|
142
|
+
await actionDispatcher.dispatch({ kind: 'mixedTest' });
|
|
143
|
+
|
|
144
|
+
expect(executionOrder).to.deep.equal([1, 2]);
|
|
145
|
+
});
|
|
146
|
+
|
|
147
|
+
it('should propagate errors from async handlers', async () => {
|
|
148
|
+
const errorMessage = 'Async handler error';
|
|
149
|
+
const errorHandler: IActionHandler = {
|
|
150
|
+
handle: async () => {
|
|
151
|
+
await new Promise(resolve => setTimeout(resolve, 5));
|
|
152
|
+
throw new Error(errorMessage);
|
|
153
|
+
}
|
|
154
|
+
};
|
|
155
|
+
|
|
156
|
+
registry.register('errorTest1', errorHandler);
|
|
157
|
+
let caughtError: Error | undefined;
|
|
158
|
+
try {
|
|
159
|
+
await actionDispatcher.dispatch({ kind: 'errorTest1' });
|
|
160
|
+
} catch (error) {
|
|
161
|
+
caughtError = error as Error;
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
expect(caughtError).to.not.be.undefined;
|
|
165
|
+
expect(caughtError?.message).to.equal(errorMessage);
|
|
166
|
+
});
|
|
167
|
+
|
|
168
|
+
it('should handle errors in one handler without affecting others when multiple handlers are registered', async () => {
|
|
169
|
+
const executionOrder: number[] = [];
|
|
170
|
+
const successHandler: IActionHandler = {
|
|
171
|
+
handle: async () => {
|
|
172
|
+
await new Promise(resolve => setTimeout(resolve, 5));
|
|
173
|
+
executionOrder.push(1);
|
|
174
|
+
}
|
|
175
|
+
};
|
|
176
|
+
const errorHandler: IActionHandler = {
|
|
177
|
+
handle: async () => {
|
|
178
|
+
await new Promise(resolve => setTimeout(resolve, 5));
|
|
179
|
+
throw new Error('Handler 2 error');
|
|
180
|
+
}
|
|
181
|
+
};
|
|
182
|
+
|
|
183
|
+
registry.register('multiHandlerErrorTest', successHandler);
|
|
184
|
+
registry.register('multiHandlerErrorTest', errorHandler);
|
|
185
|
+
|
|
186
|
+
let caughtError: Error | undefined;
|
|
187
|
+
try {
|
|
188
|
+
await actionDispatcher.dispatch({ kind: 'multiHandlerErrorTest' });
|
|
189
|
+
} catch (error) {
|
|
190
|
+
caughtError = error as Error;
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
// First handler should have executed successfully
|
|
194
|
+
expect(executionOrder).to.deep.equal([1]);
|
|
195
|
+
// Error should have been thrown
|
|
196
|
+
expect(caughtError).to.not.be.undefined;
|
|
197
|
+
expect(caughtError?.message).to.equal('Handler 2 error');
|
|
198
|
+
});
|
|
199
|
+
|
|
200
|
+
it('should handle synchronous errors in handlers', async () => {
|
|
201
|
+
const errorMessage = 'Sync handler error';
|
|
202
|
+
const syncErrorHandler: IActionHandler = {
|
|
203
|
+
handle: () => {
|
|
204
|
+
throw new Error(errorMessage);
|
|
205
|
+
}
|
|
206
|
+
};
|
|
207
|
+
|
|
208
|
+
registry.register('syncErrorTest', syncErrorHandler);
|
|
209
|
+
let caughtError: Error | undefined;
|
|
210
|
+
try {
|
|
211
|
+
await actionDispatcher.dispatch({ kind: 'syncErrorTest' });
|
|
212
|
+
} catch (error) {
|
|
213
|
+
caughtError = error as Error;
|
|
214
|
+
}
|
|
215
|
+
|
|
216
|
+
expect(caughtError).to.not.be.undefined;
|
|
217
|
+
expect(caughtError?.message).to.equal(errorMessage);
|
|
218
|
+
});
|
|
219
|
+
|
|
220
|
+
it('should handle async handlers that return actions', async () => {
|
|
221
|
+
const dispatchedActions: string[] = [];
|
|
222
|
+
const returningHandler: IActionHandler = {
|
|
223
|
+
handle: async () => {
|
|
224
|
+
await new Promise(resolve => setTimeout(resolve, 5));
|
|
225
|
+
return { kind: 'returnedAction1' };
|
|
226
|
+
}
|
|
227
|
+
};
|
|
228
|
+
const receivingHandler: IActionHandler = {
|
|
229
|
+
handle: action => {
|
|
230
|
+
dispatchedActions.push(action.kind);
|
|
231
|
+
}
|
|
232
|
+
};
|
|
233
|
+
|
|
234
|
+
registry.register('asyncReturnTest', returningHandler);
|
|
235
|
+
registry.register('returnedAction1', receivingHandler);
|
|
236
|
+
await actionDispatcher.dispatch({ kind: 'asyncReturnTest' });
|
|
237
|
+
|
|
238
|
+
expect(dispatchedActions).to.include('returnedAction1');
|
|
239
|
+
});
|
|
240
|
+
|
|
241
|
+
it('should wait for all async handlers to complete before resolving dispatch promise', async () => {
|
|
242
|
+
let handler1Completed = false;
|
|
243
|
+
let handler2Completed = false;
|
|
244
|
+
const asyncHandler1: IActionHandler = {
|
|
245
|
+
handle: async () => {
|
|
246
|
+
await new Promise(resolve => setTimeout(resolve, 30));
|
|
247
|
+
handler1Completed = true;
|
|
248
|
+
}
|
|
249
|
+
};
|
|
250
|
+
const asyncHandler2: IActionHandler = {
|
|
251
|
+
handle: async () => {
|
|
252
|
+
await new Promise(resolve => setTimeout(resolve, 20));
|
|
253
|
+
handler2Completed = true;
|
|
254
|
+
}
|
|
255
|
+
};
|
|
256
|
+
|
|
257
|
+
registry.register('completionTest', asyncHandler1);
|
|
258
|
+
registry.register('completionTest', asyncHandler2);
|
|
259
|
+
await actionDispatcher.dispatch({ kind: 'completionTest' });
|
|
260
|
+
|
|
261
|
+
// Both handlers should be completed when dispatch resolves
|
|
262
|
+
expect(handler1Completed).to.be.true;
|
|
263
|
+
expect(handler2Completed).to.be.true;
|
|
264
|
+
});
|
|
265
|
+
});
|
|
88
266
|
});
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/********************************************************************************
|
|
2
|
-
* Copyright (c) 2019-
|
|
2
|
+
* Copyright (c) 2019-2026 EclipseSource and others.
|
|
3
3
|
*
|
|
4
4
|
* This program and the accompanying materials are made available under the
|
|
5
5
|
* terms of the Eclipse Public License v. 2.0 which is available at
|
|
@@ -16,11 +16,13 @@
|
|
|
16
16
|
import {
|
|
17
17
|
Action,
|
|
18
18
|
ActionDispatcher,
|
|
19
|
+
ActionHandler,
|
|
19
20
|
ActionHandlerRegistry,
|
|
20
21
|
Deferred,
|
|
21
22
|
EMPTY_ROOT,
|
|
22
23
|
GModelRoot,
|
|
23
24
|
IActionDispatcher,
|
|
25
|
+
RejectAction,
|
|
24
26
|
RequestAction,
|
|
25
27
|
ResponseAction,
|
|
26
28
|
SetModelAction,
|
|
@@ -126,25 +128,70 @@ export class GLSPActionDispatcher extends ActionDispatcher implements IGModelRoo
|
|
|
126
128
|
}
|
|
127
129
|
|
|
128
130
|
protected override handleAction(action: Action): Promise<void> {
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
const timeout = this.timeouts.get(action.responseId);
|
|
132
|
-
if (timeout !== undefined) {
|
|
133
|
-
clearTimeout(timeout);
|
|
134
|
-
this.timeouts.delete(action.responseId);
|
|
135
|
-
}
|
|
131
|
+
return ResponseAction.hasValidResponseId(action) ? this.handleResponseAction(action) : this.doHandleAction(action);
|
|
132
|
+
}
|
|
136
133
|
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
134
|
+
protected async handleResponseAction(action: ResponseAction): Promise<void> {
|
|
135
|
+
// clear any pending timeout
|
|
136
|
+
const timeout = this.timeouts.get(action.responseId);
|
|
137
|
+
if (timeout !== undefined) {
|
|
138
|
+
clearTimeout(timeout);
|
|
139
|
+
this.timeouts.delete(action.responseId);
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
// check for matching request
|
|
143
|
+
const request = this.requests.get(action.responseId);
|
|
144
|
+
if (!request) {
|
|
145
|
+
// treat no matching request by dispatching action normally
|
|
146
|
+
this.logger.log(this, 'No matching request for response, dispatch normally', action);
|
|
147
|
+
action.responseId = '';
|
|
148
|
+
return this.handleAction(action);
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
this.requests.delete(action.responseId);
|
|
152
|
+
if (RejectAction.is(action)) {
|
|
153
|
+
// translation reject action to request rejection
|
|
154
|
+
request.reject(new Error(action.message));
|
|
155
|
+
this.logger.warn(this, `Request with id ${action.responseId} failed.`, action.message, action.detail);
|
|
156
|
+
} else {
|
|
157
|
+
request.resolve(action);
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
protected doHandleAction(action: Action): Promise<void> {
|
|
162
|
+
const handlers = this.actionHandlerRegistry.get(action.kind);
|
|
163
|
+
return handlers.length === 0 ? this.handleActionWithoutHandler(action) : this.handleActionWithHandler(action, handlers);
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
protected async handleActionWithoutHandler(action: Action): Promise<void> {
|
|
167
|
+
if (OptionalAction.is(action) && !this.hasHandler(action)) {
|
|
168
|
+
return;
|
|
169
|
+
}
|
|
170
|
+
this.logger.warn(this, 'Missing handler for action', action);
|
|
171
|
+
const error = new Error(`Missing handler for action '${action.kind}'`);
|
|
172
|
+
if (!RequestAction.is(action)) {
|
|
173
|
+
throw error;
|
|
143
174
|
}
|
|
144
|
-
|
|
145
|
-
|
|
175
|
+
const request = this.requests.get(action.requestId);
|
|
176
|
+
if (request !== undefined) {
|
|
177
|
+
this.requests.delete(action.requestId);
|
|
178
|
+
request.reject(error);
|
|
146
179
|
}
|
|
147
|
-
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
protected async handleActionWithHandler(action: Action, handlers: ActionHandler[]): Promise<void> {
|
|
183
|
+
this.logger.log(this, 'Handle', action);
|
|
184
|
+
const handlerResults: Promise<any>[] = [];
|
|
185
|
+
for (const handler of handlers) {
|
|
186
|
+
const result = await handler.handle(action);
|
|
187
|
+
if (Action.is(result)) {
|
|
188
|
+
handlerResults.push(this.dispatch(result));
|
|
189
|
+
} else if (result !== undefined) {
|
|
190
|
+
this.blockUntil = result.blockUntil;
|
|
191
|
+
handlerResults.push(this.commandStack.execute(result));
|
|
192
|
+
}
|
|
193
|
+
}
|
|
194
|
+
await Promise.all(handlerResults);
|
|
148
195
|
}
|
|
149
196
|
|
|
150
197
|
override request<Res extends ResponseAction>(action: RequestAction<Res>): Promise<Res> {
|
|
@@ -193,7 +240,6 @@ export class GLSPActionDispatcher extends ActionDispatcher implements IGModelRoo
|
|
|
193
240
|
}
|
|
194
241
|
}, timeoutMs);
|
|
195
242
|
this.timeouts.set(requestId, timeout);
|
|
196
|
-
|
|
197
243
|
return super.request<Res>(action);
|
|
198
244
|
}
|
|
199
245
|
}
|