@opensumi/ide-connection 2.27.3-rc-1706687185.0 → 2.27.3-rc-1708222409.0
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/browser/ws-channel-handler.d.ts.map +1 -1
- package/lib/browser/ws-channel-handler.js +2 -6
- package/lib/browser/ws-channel-handler.js.map +1 -1
- package/lib/common/{connection → buffers}/buffers.d.ts +2 -1
- package/lib/common/buffers/buffers.d.ts.map +1 -0
- package/lib/common/{connection → buffers}/buffers.js +21 -3
- package/lib/common/buffers/buffers.js.map +1 -0
- package/lib/common/connection/drivers/base.d.ts +2 -2
- package/lib/common/connection/drivers/base.d.ts.map +1 -1
- package/lib/common/connection/drivers/base.js +0 -4
- package/lib/common/connection/drivers/base.js.map +1 -1
- package/lib/common/connection/drivers/frame-decoder.d.ts +34 -0
- package/lib/common/connection/drivers/frame-decoder.d.ts.map +1 -0
- package/lib/common/connection/drivers/frame-decoder.js +147 -0
- package/lib/common/connection/drivers/frame-decoder.js.map +1 -0
- package/lib/common/connection/drivers/{empty.d.ts → message-port.d.ts} +5 -2
- package/lib/common/connection/drivers/message-port.d.ts.map +1 -0
- package/lib/common/connection/drivers/message-port.js +41 -0
- package/lib/common/connection/drivers/message-port.js.map +1 -0
- package/lib/common/connection/drivers/node-message-port.d.ts +1 -0
- package/lib/common/connection/drivers/node-message-port.d.ts.map +1 -1
- package/lib/common/connection/drivers/node-message-port.js +3 -0
- package/lib/common/connection/drivers/node-message-port.js.map +1 -1
- package/lib/common/connection/drivers/reconnecting-websocket.d.ts +1 -0
- package/lib/common/connection/drivers/reconnecting-websocket.d.ts.map +1 -1
- package/lib/common/connection/drivers/reconnecting-websocket.js +3 -0
- package/lib/common/connection/drivers/reconnecting-websocket.js.map +1 -1
- package/lib/common/connection/drivers/simple.d.ts +17 -0
- package/lib/common/connection/drivers/simple.d.ts.map +1 -0
- package/lib/common/connection/drivers/simple.js +32 -0
- package/lib/common/connection/drivers/simple.js.map +1 -0
- package/lib/common/connection/drivers/socket.d.ts +4 -2
- package/lib/common/connection/drivers/socket.d.ts.map +1 -1
- package/lib/common/connection/drivers/socket.js +10 -7
- package/lib/common/connection/drivers/socket.js.map +1 -1
- package/lib/common/connection/drivers/ws-websocket.d.ts +2 -0
- package/lib/common/connection/drivers/ws-websocket.d.ts.map +1 -1
- package/lib/common/connection/drivers/ws-websocket.js +6 -0
- package/lib/common/connection/drivers/ws-websocket.js.map +1 -1
- package/lib/common/connection/types.d.ts +1 -1
- package/lib/common/connection/types.d.ts.map +1 -1
- package/lib/common/ext-rpc-protocol.d.ts +7 -21
- package/lib/common/ext-rpc-protocol.d.ts.map +1 -1
- package/lib/common/ext-rpc-protocol.js +13 -33
- package/lib/common/ext-rpc-protocol.js.map +1 -1
- package/lib/common/fury-extends/any.d.ts +22 -0
- package/lib/common/fury-extends/any.d.ts.map +1 -0
- package/lib/common/fury-extends/any.js +143 -0
- package/lib/common/fury-extends/any.js.map +1 -0
- package/lib/common/fury-extends/one-of.d.ts +14 -0
- package/lib/common/fury-extends/one-of.d.ts.map +1 -0
- package/lib/common/fury-extends/one-of.js +50 -0
- package/lib/common/fury-extends/one-of.js.map +1 -0
- package/lib/common/fury-extends/shared.d.ts +142 -0
- package/lib/common/fury-extends/shared.d.ts.map +1 -0
- package/lib/common/fury-extends/shared.js +17 -0
- package/lib/common/fury-extends/shared.js.map +1 -0
- package/lib/common/index.d.ts +2 -1
- package/lib/common/index.d.ts.map +1 -1
- package/lib/common/index.js +2 -1
- package/lib/common/index.js.map +1 -1
- package/lib/common/protocols/common-server.d.ts +3 -0
- package/lib/common/protocols/common-server.d.ts.map +1 -0
- package/lib/common/protocols/common-server.js +18 -0
- package/lib/common/protocols/common-server.js.map +1 -0
- package/lib/common/protocols/common.d.ts +24 -0
- package/lib/common/protocols/common.d.ts.map +1 -0
- package/lib/common/protocols/common.js +12 -0
- package/lib/common/protocols/common.js.map +1 -0
- package/lib/common/rpc/connection.d.ts +44 -0
- package/lib/common/rpc/connection.d.ts.map +1 -0
- package/lib/common/rpc/connection.js +256 -0
- package/lib/common/rpc/connection.js.map +1 -0
- package/lib/common/rpc/errors.d.ts +4 -0
- package/lib/common/rpc/errors.d.ts.map +1 -0
- package/lib/common/rpc/errors.js +10 -0
- package/lib/common/rpc/errors.js.map +1 -0
- package/lib/common/rpc/index.d.ts +3 -0
- package/lib/common/rpc/index.d.ts.map +1 -0
- package/lib/common/rpc/index.js +6 -0
- package/lib/common/rpc/index.js.map +1 -0
- package/lib/common/rpc/multiplexer.d.ts +28 -0
- package/lib/common/rpc/multiplexer.d.ts.map +1 -0
- package/lib/common/rpc/multiplexer.js +82 -0
- package/lib/common/rpc/multiplexer.js.map +1 -0
- package/lib/common/rpc/packet.d.ts +65 -0
- package/lib/common/rpc/packet.d.ts.map +1 -0
- package/lib/common/rpc/packet.js +82 -0
- package/lib/common/rpc/packet.js.map +1 -0
- package/lib/common/rpc/protocol-repository.d.ts +32 -0
- package/lib/common/rpc/protocol-repository.d.ts.map +1 -0
- package/lib/common/rpc/protocol-repository.js +118 -0
- package/lib/common/rpc/protocol-repository.js.map +1 -0
- package/lib/common/rpc/types.d.ts +13 -0
- package/lib/common/rpc/types.d.ts.map +1 -0
- package/lib/common/rpc/types.js +3 -0
- package/lib/common/rpc/types.js.map +1 -0
- package/lib/common/rpc/utils.d.ts +2 -0
- package/lib/common/rpc/utils.d.ts.map +1 -0
- package/lib/common/rpc/utils.js +10 -0
- package/lib/common/rpc/utils.js.map +1 -0
- package/lib/common/rpc-service/center.d.ts +12 -5
- package/lib/common/rpc-service/center.d.ts.map +1 -1
- package/lib/common/rpc-service/center.js +47 -42
- package/lib/common/rpc-service/center.js.map +1 -1
- package/lib/common/rpc-service/index.d.ts +6 -0
- package/lib/common/rpc-service/index.d.ts.map +1 -1
- package/lib/common/rpc-service/index.js +7 -0
- package/lib/common/rpc-service/index.js.map +1 -1
- package/lib/common/rpc-service/proxy/base.d.ts +32 -0
- package/lib/common/rpc-service/proxy/base.d.ts.map +1 -0
- package/lib/common/rpc-service/proxy/base.js +93 -0
- package/lib/common/rpc-service/proxy/base.js.map +1 -0
- package/lib/common/rpc-service/proxy/index.d.ts +5 -0
- package/lib/common/rpc-service/proxy/index.d.ts.map +1 -0
- package/lib/common/rpc-service/proxy/index.js +8 -0
- package/lib/common/rpc-service/proxy/index.js.map +1 -0
- package/lib/common/rpc-service/proxy/invoker.d.ts +14 -0
- package/lib/common/rpc-service/proxy/invoker.d.ts.map +1 -0
- package/lib/common/rpc-service/proxy/invoker.js +34 -0
- package/lib/common/rpc-service/proxy/invoker.js.map +1 -0
- package/lib/common/{proxy → rpc-service/proxy}/legacy.d.ts +3 -7
- package/lib/common/rpc-service/proxy/legacy.d.ts.map +1 -0
- package/lib/common/rpc-service/proxy/legacy.js +136 -0
- package/lib/common/rpc-service/proxy/legacy.js.map +1 -0
- package/lib/common/rpc-service/proxy/registry.d.ts +18 -0
- package/lib/common/rpc-service/proxy/registry.d.ts.map +1 -0
- package/lib/common/rpc-service/proxy/registry.js +46 -0
- package/lib/common/rpc-service/proxy/registry.js.map +1 -0
- package/lib/common/rpc-service/proxy/sumi.d.ts +9 -0
- package/lib/common/rpc-service/proxy/sumi.d.ts.map +1 -0
- package/lib/common/rpc-service/proxy/sumi.js +86 -0
- package/lib/common/rpc-service/proxy/sumi.js.map +1 -0
- package/lib/common/rpc-service/stub.d.ts +0 -1
- package/lib/common/rpc-service/stub.d.ts.map +1 -1
- package/lib/common/rpc-service/stub.js +3 -11
- package/lib/common/rpc-service/stub.js.map +1 -1
- package/lib/common/types.d.ts +1 -1
- package/lib/common/types.d.ts.map +1 -1
- package/lib/common/ws-channel.d.ts +97 -32
- package/lib/common/ws-channel.d.ts.map +1 -1
- package/lib/common/ws-channel.js +75 -51
- package/lib/common/ws-channel.js.map +1 -1
- package/lib/node/common-channel-handler.js +1 -1
- package/lib/node/common-channel-handler.js.map +1 -1
- package/package.json +5 -5
- package/src/browser/ws-channel-handler.ts +2 -6
- package/src/common/{connection → buffers}/buffers.ts +24 -3
- package/src/common/connection/drivers/base.ts +2 -6
- package/src/common/connection/drivers/frame-decoder.ts +170 -0
- package/src/common/connection/drivers/message-port.ts +42 -0
- package/src/common/connection/drivers/node-message-port.ts +3 -0
- package/src/common/connection/drivers/reconnecting-websocket.ts +4 -0
- package/src/common/connection/drivers/simple.ts +33 -0
- package/src/common/connection/drivers/socket.ts +11 -7
- package/src/common/connection/drivers/ws-websocket.ts +8 -0
- package/src/common/connection/types.ts +1 -1
- package/src/common/ext-rpc-protocol.ts +16 -51
- package/src/common/fury-extends/any.ts +144 -0
- package/src/common/fury-extends/one-of.ts +61 -0
- package/src/common/fury-extends/shared.ts +15 -0
- package/src/common/index.ts +2 -1
- package/src/common/protocols/common-server.ts +18 -0
- package/src/common/protocols/common.ts +9 -0
- package/src/common/rpc/connection.ts +345 -0
- package/src/common/rpc/errors.ts +5 -0
- package/src/common/rpc/index.ts +2 -0
- package/src/common/rpc/multiplexer.ts +105 -0
- package/src/common/rpc/packet.ts +104 -0
- package/src/common/rpc/protocol-repository.ts +180 -0
- package/src/common/rpc/types.ts +23 -0
- package/src/common/rpc/utils.ts +5 -0
- package/src/common/rpc-service/center.ts +59 -49
- package/src/common/rpc-service/index.ts +9 -0
- package/src/common/rpc-service/proxy/base.ts +126 -0
- package/src/common/rpc-service/proxy/index.ts +4 -0
- package/src/common/rpc-service/proxy/invoker.ts +45 -0
- package/src/common/rpc-service/proxy/legacy.ts +150 -0
- package/src/common/rpc-service/proxy/registry.ts +56 -0
- package/src/common/rpc-service/proxy/sumi.ts +81 -0
- package/src/common/rpc-service/stub.ts +4 -11
- package/src/common/types.ts +1 -1
- package/src/common/ws-channel.ts +100 -61
- package/src/node/common-channel-handler.ts +1 -1
- package/lib/common/connection/buffers.d.ts.map +0 -1
- package/lib/common/connection/buffers.js.map +0 -1
- package/lib/common/connection/drivers/empty.d.ts.map +0 -1
- package/lib/common/connection/drivers/empty.js +0 -21
- package/lib/common/connection/drivers/empty.js.map +0 -1
- package/lib/common/connection/drivers/stream-decoder.d.ts +0 -67
- package/lib/common/connection/drivers/stream-decoder.d.ts.map +0 -1
- package/lib/common/connection/drivers/stream-decoder.js +0 -171
- package/lib/common/connection/drivers/stream-decoder.js.map +0 -1
- package/lib/common/proxy/base.d.ts +0 -22
- package/lib/common/proxy/base.d.ts.map +0 -1
- package/lib/common/proxy/base.js +0 -47
- package/lib/common/proxy/base.js.map +0 -1
- package/lib/common/proxy/index.d.ts +0 -8
- package/lib/common/proxy/index.d.ts.map +0 -1
- package/lib/common/proxy/index.js +0 -12
- package/lib/common/proxy/index.js.map +0 -1
- package/lib/common/proxy/legacy.d.ts.map +0 -1
- package/lib/common/proxy/legacy.js +0 -183
- package/lib/common/proxy/legacy.js.map +0 -1
- package/src/common/connection/drivers/empty.ts +0 -19
- package/src/common/connection/drivers/stream-decoder.ts +0 -196
- package/src/common/proxy/base.ts +0 -67
- package/src/common/proxy/index.ts +0 -10
- package/src/common/proxy/legacy.ts +0 -200
|
@@ -0,0 +1,126 @@
|
|
|
1
|
+
import { Deferred, isDefined } from '@opensumi/ide-core-common';
|
|
2
|
+
|
|
3
|
+
import { ILogger, IRPCServiceMap } from '../../types';
|
|
4
|
+
import { ICapturedMessage, MessageType, ResponseStatus, getCapturer } from '../../utils';
|
|
5
|
+
|
|
6
|
+
import type { ServiceRegistry } from './registry';
|
|
7
|
+
|
|
8
|
+
interface IBaseConnection {
|
|
9
|
+
listen(): void;
|
|
10
|
+
dispose(): void;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
let requestId = 0;
|
|
14
|
+
|
|
15
|
+
export abstract class ProxyBase<T extends IBaseConnection> {
|
|
16
|
+
protected logger: ILogger;
|
|
17
|
+
protected connection: T;
|
|
18
|
+
|
|
19
|
+
protected connectionPromise: Deferred<void> = new Deferred<void>();
|
|
20
|
+
|
|
21
|
+
protected abstract engine: 'legacy' | 'sumi';
|
|
22
|
+
|
|
23
|
+
constructor(public registry: ServiceRegistry, logger?: ILogger) {
|
|
24
|
+
this.logger = logger || console;
|
|
25
|
+
|
|
26
|
+
this.registry.onServicesUpdate((services) => {
|
|
27
|
+
if (this.connection) {
|
|
28
|
+
this.bindMethods(services);
|
|
29
|
+
}
|
|
30
|
+
});
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
// capture messages for opensumi devtools
|
|
34
|
+
private capture(message: ICapturedMessage): void {
|
|
35
|
+
const capturer = getCapturer();
|
|
36
|
+
if (isDefined(capturer)) {
|
|
37
|
+
capturer({
|
|
38
|
+
...message,
|
|
39
|
+
engine: this.engine,
|
|
40
|
+
});
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
protected nextRequestId() {
|
|
45
|
+
return String(requestId++);
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
protected captureOnRequest(requestId: string, serviceMethod: string, args: any[]): void {
|
|
49
|
+
this.capture({ type: MessageType.OnRequest, requestId, serviceMethod, arguments: args });
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
protected captureOnRequestResult(requestId: string, serviceMethod: string, data: any): void {
|
|
53
|
+
this.capture({
|
|
54
|
+
type: MessageType.OnRequestResult,
|
|
55
|
+
status: ResponseStatus.Success,
|
|
56
|
+
requestId,
|
|
57
|
+
serviceMethod,
|
|
58
|
+
data,
|
|
59
|
+
});
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
protected captureOnRequestFail(requestId: string, serviceMethod: string, error: any): void {
|
|
63
|
+
this.logger.warn(`request exec ${serviceMethod} error`, error);
|
|
64
|
+
|
|
65
|
+
this.capture({
|
|
66
|
+
type: MessageType.OnRequestResult,
|
|
67
|
+
status: ResponseStatus.Fail,
|
|
68
|
+
requestId,
|
|
69
|
+
serviceMethod,
|
|
70
|
+
error,
|
|
71
|
+
});
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
protected captureOnNotification(serviceMethod: string, args: any[]): void {
|
|
75
|
+
this.capture({ type: MessageType.OnNotification, serviceMethod, arguments: args });
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
protected captureSendRequest(requestId: string, serviceMethod: string, args: any[]): void {
|
|
79
|
+
this.capture({ type: MessageType.SendRequest, requestId, serviceMethod, arguments: args });
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
protected captureSendRequestResult(requestId: string, serviceMethod: string, data: any): void {
|
|
83
|
+
this.capture({
|
|
84
|
+
type: MessageType.RequestResult,
|
|
85
|
+
status: ResponseStatus.Success,
|
|
86
|
+
requestId,
|
|
87
|
+
serviceMethod,
|
|
88
|
+
data,
|
|
89
|
+
});
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
protected captureSendRequestFail(requestId: string, serviceMethod: string, error: any): void {
|
|
93
|
+
this.capture({
|
|
94
|
+
type: MessageType.RequestResult,
|
|
95
|
+
status: ResponseStatus.Fail,
|
|
96
|
+
requestId,
|
|
97
|
+
serviceMethod,
|
|
98
|
+
error,
|
|
99
|
+
});
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
protected captureSendNotification(serviceMethod: string, args: any[]): void {
|
|
103
|
+
this.capture({ type: MessageType.SendNotification, serviceMethod, arguments: args });
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
listen(connection: T): void {
|
|
107
|
+
this.connection = connection;
|
|
108
|
+
this.bindMethods(this.registry.methods());
|
|
109
|
+
|
|
110
|
+
connection.listen();
|
|
111
|
+
this.connectionPromise.resolve();
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
public listenService(service: IRPCServiceMap) {
|
|
115
|
+
this.registry.registerService(service);
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
dispose(): void {
|
|
119
|
+
if (this.connection) {
|
|
120
|
+
this.connection.dispose();
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
abstract getInvokeProxy<T = any>(): T;
|
|
125
|
+
protected abstract bindMethods(services: PropertyKey[]): void;
|
|
126
|
+
}
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import { ProxyLegacy } from './legacy';
|
|
2
|
+
import { ProxySumi } from './sumi';
|
|
3
|
+
|
|
4
|
+
const defaultReservedWordSet = new Set(['then', 'finally']);
|
|
5
|
+
|
|
6
|
+
export class Invoker {
|
|
7
|
+
legacyProxy: ProxyLegacy;
|
|
8
|
+
sumiProxy: ProxySumi;
|
|
9
|
+
|
|
10
|
+
private legacyInvokeProxy: any;
|
|
11
|
+
private sumiInvokeProxy: any;
|
|
12
|
+
|
|
13
|
+
constructor() {}
|
|
14
|
+
|
|
15
|
+
attachLegacy(legacyProxy: ProxyLegacy) {
|
|
16
|
+
this.legacyProxy = legacyProxy;
|
|
17
|
+
this.legacyInvokeProxy = this.legacyProxy.getInvokeProxy();
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
attachSumi(sumiProxy: ProxySumi) {
|
|
21
|
+
this.sumiProxy = sumiProxy;
|
|
22
|
+
this.sumiInvokeProxy = this.sumiProxy.getInvokeProxy();
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
invoke(name: string, ...args: any[]) {
|
|
26
|
+
if (defaultReservedWordSet.has(name)) {
|
|
27
|
+
return Promise.resolve();
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
if (this.sumiInvokeProxy) {
|
|
31
|
+
return this.sumiInvokeProxy[name](...args);
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
return this.legacyInvokeProxy[name](...args);
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
dispose() {
|
|
38
|
+
if (this.legacyProxy) {
|
|
39
|
+
this.legacyProxy.dispose();
|
|
40
|
+
}
|
|
41
|
+
if (this.sumiProxy) {
|
|
42
|
+
this.sumiProxy.dispose();
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
}
|
|
@@ -0,0 +1,150 @@
|
|
|
1
|
+
import { MessageConnection } from '@opensumi/vscode-jsonrpc';
|
|
2
|
+
|
|
3
|
+
import { METHOD_NOT_REGISTERED } from '../../constants';
|
|
4
|
+
|
|
5
|
+
import { ProxyBase } from './base';
|
|
6
|
+
|
|
7
|
+
interface IRPCResult {
|
|
8
|
+
error: boolean;
|
|
9
|
+
data: any;
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
export class ProxyLegacy extends ProxyBase<MessageConnection> {
|
|
13
|
+
protected engine = 'legacy' as const;
|
|
14
|
+
|
|
15
|
+
protected bindMethods(methods: string[]): void {
|
|
16
|
+
for (const method of methods) {
|
|
17
|
+
if (method.startsWith('on')) {
|
|
18
|
+
this.connection.onNotification(method, async (...args: any[]) => {
|
|
19
|
+
this.captureOnNotification(method, args);
|
|
20
|
+
try {
|
|
21
|
+
await this.registry.invoke(method, ...this.serializeArguments(args));
|
|
22
|
+
} catch (e) {
|
|
23
|
+
this.logger.warn(`notification exec ${method} error`, e);
|
|
24
|
+
}
|
|
25
|
+
});
|
|
26
|
+
} else {
|
|
27
|
+
this.connection.onRequest(method, async (...args: any[]) => {
|
|
28
|
+
const requestId = this.nextRequestId();
|
|
29
|
+
this.captureOnRequest(requestId, method, args);
|
|
30
|
+
|
|
31
|
+
try {
|
|
32
|
+
const result = await this.registry.invoke(method, ...this.serializeArguments(args));
|
|
33
|
+
|
|
34
|
+
this.captureOnRequestResult(requestId, method, result);
|
|
35
|
+
|
|
36
|
+
return {
|
|
37
|
+
error: false,
|
|
38
|
+
data: result,
|
|
39
|
+
};
|
|
40
|
+
} catch (e) {
|
|
41
|
+
this.captureOnRequestFail(requestId, method, e);
|
|
42
|
+
|
|
43
|
+
return {
|
|
44
|
+
error: true,
|
|
45
|
+
data: {
|
|
46
|
+
message: e.message,
|
|
47
|
+
stack: e.stack,
|
|
48
|
+
},
|
|
49
|
+
};
|
|
50
|
+
}
|
|
51
|
+
});
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
public getInvokeProxy<T = any>(): T {
|
|
57
|
+
return new Proxy(Object.create(null), {
|
|
58
|
+
get: (target: any, p: PropertyKey) => {
|
|
59
|
+
if (!target[p]) {
|
|
60
|
+
target[p] = async (...args: any[]) => {
|
|
61
|
+
await this.connectionPromise.promise;
|
|
62
|
+
|
|
63
|
+
let isSingleArray = false;
|
|
64
|
+
if (args.length === 1 && Array.isArray(args[0])) {
|
|
65
|
+
isSingleArray = true;
|
|
66
|
+
}
|
|
67
|
+
const prop = p.toString();
|
|
68
|
+
|
|
69
|
+
// 调用方法为 on 开头时,作为单项通知
|
|
70
|
+
if (prop.startsWith('on')) {
|
|
71
|
+
this.captureSendNotification(prop, args);
|
|
72
|
+
if (isSingleArray) {
|
|
73
|
+
this.connection.sendNotification(prop, [...args]);
|
|
74
|
+
} else {
|
|
75
|
+
this.connection.sendNotification(prop, ...args);
|
|
76
|
+
}
|
|
77
|
+
} else {
|
|
78
|
+
// generate a unique requestId to associate request and requestResult
|
|
79
|
+
const requestId = this.nextRequestId();
|
|
80
|
+
|
|
81
|
+
let requestResult: Promise<any>;
|
|
82
|
+
|
|
83
|
+
if (isSingleArray) {
|
|
84
|
+
requestResult = this.connection.sendRequest(prop, [...args]) as Promise<any>;
|
|
85
|
+
} else {
|
|
86
|
+
requestResult = this.connection.sendRequest(prop, ...args) as Promise<any>;
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
this.captureSendRequest(requestId, prop, args);
|
|
90
|
+
|
|
91
|
+
const result: IRPCResult = await requestResult;
|
|
92
|
+
|
|
93
|
+
if (result.error) {
|
|
94
|
+
const error = new Error(result.data.message);
|
|
95
|
+
if (result.data.stack) {
|
|
96
|
+
error.stack = result.data.stack;
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
this.captureSendRequestFail(requestId, prop, result.data);
|
|
100
|
+
throw error;
|
|
101
|
+
} else {
|
|
102
|
+
this.captureSendRequestResult(requestId, prop, result.data);
|
|
103
|
+
return result.data;
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
};
|
|
107
|
+
}
|
|
108
|
+
return target[p];
|
|
109
|
+
},
|
|
110
|
+
});
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
/**
|
|
114
|
+
* 对于纯数组参数的情况,收到请求/通知后做展开操作
|
|
115
|
+
* 因为在通信层会为每个 rpc 调用添加一个 CancellationToken 参数
|
|
116
|
+
* 如果参数本身是数组, 在方法中如果使用 spread 运算符获取参数(...args),则会出现 [...args, MutableToken] 这种情况
|
|
117
|
+
* 所以发送请求时将这类参数统一再用数组包了一层,形如 [[...args]], 参考 {@link ProxyLegacy.get get} 方法
|
|
118
|
+
* 此时接收到的数组类参数固定长度为 2,且最后一项一定是 MutableToken
|
|
119
|
+
* @param args
|
|
120
|
+
* @returns args
|
|
121
|
+
*/
|
|
122
|
+
private serializeArguments(args: any[]): any[] {
|
|
123
|
+
const maybeCancellationToken = args[args.length - 1];
|
|
124
|
+
if (
|
|
125
|
+
args.length === 2 &&
|
|
126
|
+
Array.isArray(args[0]) &&
|
|
127
|
+
Object.prototype.hasOwnProperty.call(maybeCancellationToken, '_isCancelled')
|
|
128
|
+
) {
|
|
129
|
+
return [...args[0], maybeCancellationToken];
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
return args;
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
listen(connection: MessageConnection): void {
|
|
136
|
+
super.listen(connection);
|
|
137
|
+
|
|
138
|
+
connection.onRequest((method) => {
|
|
139
|
+
if (!this.registry.has(method)) {
|
|
140
|
+
const requestId = this.nextRequestId();
|
|
141
|
+
this.captureOnRequest(requestId, method, []);
|
|
142
|
+
const result = {
|
|
143
|
+
data: METHOD_NOT_REGISTERED,
|
|
144
|
+
};
|
|
145
|
+
this.captureOnRequestFail(requestId, method, result.data);
|
|
146
|
+
return result;
|
|
147
|
+
}
|
|
148
|
+
});
|
|
149
|
+
}
|
|
150
|
+
}
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
import { Emitter } from '@opensumi/ide-core-common';
|
|
2
|
+
|
|
3
|
+
import { RPCServiceMethod } from '../../types';
|
|
4
|
+
import { getServiceMethods } from '../../utils';
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Store all executable services
|
|
8
|
+
*/
|
|
9
|
+
export class ServiceRegistry {
|
|
10
|
+
protected emitter = new Emitter<string[]>();
|
|
11
|
+
|
|
12
|
+
private serviceMethodMap = new Map<PropertyKey, RPCServiceMethod>();
|
|
13
|
+
|
|
14
|
+
onServicesUpdate = this.emitter.event;
|
|
15
|
+
|
|
16
|
+
register(name: string, methodFn: RPCServiceMethod) {
|
|
17
|
+
this.serviceMethodMap.set(name, methodFn);
|
|
18
|
+
this.emitter.fire([name]);
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
registerService(
|
|
22
|
+
service: any,
|
|
23
|
+
options?: {
|
|
24
|
+
nameConverter?: (str: string) => string;
|
|
25
|
+
},
|
|
26
|
+
) {
|
|
27
|
+
const serviceNames = [] as string[];
|
|
28
|
+
const { nameConverter } = options || {};
|
|
29
|
+
const methods = getServiceMethods(service);
|
|
30
|
+
for (const method of methods) {
|
|
31
|
+
let methodName = method;
|
|
32
|
+
if (nameConverter) {
|
|
33
|
+
methodName = nameConverter(method);
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
this.serviceMethodMap.set(methodName, service[method].bind(service));
|
|
37
|
+
serviceNames.push(methodName);
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
this.emitter.fire(serviceNames);
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
has(name: PropertyKey) {
|
|
44
|
+
return this.serviceMethodMap.has(name);
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
invoke(name: PropertyKey, ...args: any[]): any {
|
|
48
|
+
// here because we have checked the existence of the method
|
|
49
|
+
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
|
|
50
|
+
return this.serviceMethodMap.get(name)!(...args);
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
methods() {
|
|
54
|
+
return Array.from(this.serviceMethodMap.keys());
|
|
55
|
+
}
|
|
56
|
+
}
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
import { METHOD_NOT_REGISTERED } from '../../constants';
|
|
2
|
+
import { SumiConnection } from '../../rpc/connection';
|
|
3
|
+
|
|
4
|
+
import { ProxyBase } from './base';
|
|
5
|
+
|
|
6
|
+
export class ProxySumi extends ProxyBase<SumiConnection> {
|
|
7
|
+
protected engine = 'sumi' as const;
|
|
8
|
+
|
|
9
|
+
protected bindMethods(methods: string[]): void {
|
|
10
|
+
for (const method of methods) {
|
|
11
|
+
if (method.startsWith('on')) {
|
|
12
|
+
this.connection.onNotification(method, async (...args: any[]) => {
|
|
13
|
+
this.captureOnNotification(method, args);
|
|
14
|
+
try {
|
|
15
|
+
await this.registry.invoke(method, ...args);
|
|
16
|
+
} catch (e) {
|
|
17
|
+
this.logger.warn(`notification exec ${method} error`, e);
|
|
18
|
+
}
|
|
19
|
+
});
|
|
20
|
+
} else {
|
|
21
|
+
this.connection.onRequest(method, async (...args: any[]) => {
|
|
22
|
+
const requestId = this.nextRequestId();
|
|
23
|
+
this.captureOnRequest(requestId, method, args);
|
|
24
|
+
|
|
25
|
+
try {
|
|
26
|
+
const result = await this.registry.invoke(method, ...args);
|
|
27
|
+
this.captureOnRequestResult(requestId, method, result);
|
|
28
|
+
return result;
|
|
29
|
+
} catch (e) {
|
|
30
|
+
this.captureOnRequestFail(requestId, method, e);
|
|
31
|
+
throw e;
|
|
32
|
+
}
|
|
33
|
+
});
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
public getInvokeProxy<T = any>(): T {
|
|
39
|
+
return new Proxy(Object.create(null), {
|
|
40
|
+
get: (target: any, p: PropertyKey) => {
|
|
41
|
+
if (!target[p]) {
|
|
42
|
+
target[p] = async (...args: any[]) => {
|
|
43
|
+
await this.connectionPromise.promise;
|
|
44
|
+
const prop = p.toString();
|
|
45
|
+
|
|
46
|
+
// 调用方法为 on 开头时,作为单项通知
|
|
47
|
+
if (prop.startsWith('on')) {
|
|
48
|
+
this.captureSendNotification(prop, args);
|
|
49
|
+
this.connection.sendNotification(prop, ...args);
|
|
50
|
+
} else {
|
|
51
|
+
// generate a unique requestId to associate request and requestResult
|
|
52
|
+
const requestId = this.nextRequestId();
|
|
53
|
+
this.captureSendRequest(requestId, prop, args);
|
|
54
|
+
try {
|
|
55
|
+
const result = await this.connection.sendRequest(prop, ...args);
|
|
56
|
+
this.captureSendRequestResult(requestId, prop, result);
|
|
57
|
+
return result;
|
|
58
|
+
} catch (error) {
|
|
59
|
+
this.captureSendRequestFail(requestId, prop, error);
|
|
60
|
+
throw error;
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
};
|
|
64
|
+
}
|
|
65
|
+
return target[p];
|
|
66
|
+
},
|
|
67
|
+
});
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
listen(connection: SumiConnection): void {
|
|
71
|
+
super.listen(connection);
|
|
72
|
+
connection.onRequestNotFound((method) => {
|
|
73
|
+
if (!this.registry.has(method)) {
|
|
74
|
+
const requestId = this.nextRequestId();
|
|
75
|
+
this.captureOnRequest(requestId, method, []);
|
|
76
|
+
this.captureOnRequestFail(requestId, method, METHOD_NOT_REGISTERED);
|
|
77
|
+
throw METHOD_NOT_REGISTERED;
|
|
78
|
+
}
|
|
79
|
+
});
|
|
80
|
+
}
|
|
81
|
+
}
|
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
import { RPCServiceMethod, ServiceType } from '../types';
|
|
2
|
-
import { getServiceMethods } from '../utils';
|
|
3
2
|
|
|
4
3
|
import { RPCServiceCenter } from './center';
|
|
5
4
|
|
|
@@ -8,19 +7,12 @@ export class RPCServiceStub {
|
|
|
8
7
|
this.center.registerService(serviceName, this.type);
|
|
9
8
|
}
|
|
10
9
|
|
|
11
|
-
async ready() {
|
|
12
|
-
return this.center.ready();
|
|
13
|
-
}
|
|
14
|
-
|
|
15
10
|
on(name: string, method: RPCServiceMethod) {
|
|
16
11
|
this.onRequest(name, method);
|
|
17
12
|
}
|
|
18
13
|
|
|
19
14
|
onRequestService(service: any) {
|
|
20
|
-
|
|
21
|
-
for (const method of methods) {
|
|
22
|
-
this.onRequest(method, service[method].bind(service));
|
|
23
|
-
}
|
|
15
|
+
this.center.onRequestService(this.serviceName, service);
|
|
24
16
|
}
|
|
25
17
|
|
|
26
18
|
onRequest(name: string, method: RPCServiceMethod) {
|
|
@@ -38,9 +30,10 @@ export class RPCServiceStub {
|
|
|
38
30
|
if (!target[prop]) {
|
|
39
31
|
if (typeof prop === 'symbol') {
|
|
40
32
|
return Promise.resolve();
|
|
41
|
-
} else {
|
|
42
|
-
return (...args: any[]) => this.ready().then(() => this.broadcast(prop, ...args));
|
|
43
33
|
}
|
|
34
|
+
|
|
35
|
+
target[prop] = (...args: any[]) => this.broadcast(prop, ...args);
|
|
36
|
+
return target[prop];
|
|
44
37
|
} else {
|
|
45
38
|
return target[prop];
|
|
46
39
|
}
|
package/src/common/types.ts
CHANGED
|
@@ -5,7 +5,7 @@ export interface ILogger {
|
|
|
5
5
|
}
|
|
6
6
|
|
|
7
7
|
export type RPCServiceMethod = (...args: any[]) => any;
|
|
8
|
-
export type IRPCServiceMap = Record<
|
|
8
|
+
export type IRPCServiceMap = Record<PropertyKey, RPCServiceMethod>;
|
|
9
9
|
|
|
10
10
|
export enum ServiceType {
|
|
11
11
|
Service,
|