@opensumi/ide-connection 2.27.3-rc-1708399099.0 → 2.27.3-rc-1710386185.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/README.md +1 -1
- package/lib/browser/ws-channel-handler.d.ts +1 -1
- package/lib/browser/ws-channel-handler.d.ts.map +1 -1
- package/lib/browser/ws-channel-handler.js +23 -33
- package/lib/browser/ws-channel-handler.js.map +1 -1
- package/lib/common/buffers/buffers.d.ts +1 -0
- package/lib/common/buffers/buffers.d.ts.map +1 -1
- package/lib/common/buffers/buffers.js +3 -3
- package/lib/common/buffers/buffers.js.map +1 -1
- package/lib/common/{utils.d.ts → capturer.d.ts} +1 -19
- package/lib/common/capturer.d.ts.map +1 -0
- package/lib/common/capturer.js +26 -0
- package/lib/common/capturer.js.map +1 -0
- package/lib/common/connection/drivers/frame-decoder.d.ts +40 -1
- package/lib/common/connection/drivers/frame-decoder.d.ts.map +1 -1
- package/lib/common/connection/drivers/frame-decoder.js +9 -10
- package/lib/common/connection/drivers/frame-decoder.js.map +1 -1
- package/lib/common/connection/drivers/index.d.ts +0 -1
- package/lib/common/connection/drivers/index.d.ts.map +1 -1
- package/lib/common/connection/drivers/index.js +0 -1
- package/lib/common/connection/drivers/index.js.map +1 -1
- package/lib/common/connection/drivers/message-port.d.ts.map +1 -1
- package/lib/common/connection/drivers/message-port.js +1 -4
- package/lib/common/connection/drivers/message-port.js.map +1 -1
- package/lib/common/connection/drivers/node-message-port.d.ts +1 -1
- package/lib/common/connection/drivers/node-message-port.d.ts.map +1 -1
- package/lib/common/connection/drivers/node-message-port.js.map +1 -1
- package/lib/common/connection/drivers/reconnecting-websocket.d.ts.map +1 -1
- package/lib/common/connection/drivers/reconnecting-websocket.js +1 -1
- package/lib/common/connection/drivers/reconnecting-websocket.js.map +1 -1
- package/lib/common/connection/drivers/socket.d.ts +3 -10
- package/lib/common/connection/drivers/socket.d.ts.map +1 -1
- package/lib/common/connection/drivers/socket.js +3 -36
- package/lib/common/connection/drivers/socket.js.map +1 -1
- package/lib/common/connection/drivers/stream.d.ts +17 -0
- package/lib/common/connection/drivers/stream.d.ts.map +1 -0
- package/lib/common/connection/drivers/stream.js +70 -0
- package/lib/common/connection/drivers/stream.js.map +1 -0
- package/lib/common/connection/drivers/ws-websocket.d.ts +1 -1
- package/lib/common/connection/drivers/ws-websocket.d.ts.map +1 -1
- package/lib/common/connection/drivers/ws-websocket.js.map +1 -1
- package/lib/common/fury-extends/any.d.ts +10 -7
- package/lib/common/fury-extends/any.d.ts.map +1 -1
- package/lib/common/fury-extends/any.js +126 -105
- package/lib/common/fury-extends/any.js.map +1 -1
- package/lib/common/fury-extends/one-of.d.ts +10 -5
- package/lib/common/fury-extends/one-of.d.ts.map +1 -1
- package/lib/common/fury-extends/one-of.js +65 -30
- package/lib/common/fury-extends/one-of.js.map +1 -1
- package/lib/common/fury-extends/shared.d.ts +2 -0
- package/lib/common/fury-extends/shared.d.ts.map +1 -1
- package/lib/common/fury-extends/shared.js.map +1 -1
- package/lib/common/index.d.ts +2 -2
- package/lib/common/index.d.ts.map +1 -1
- package/lib/common/index.js +2 -2
- package/lib/common/index.js.map +1 -1
- package/lib/common/message.d.ts +1 -1
- package/lib/common/message.d.ts.map +1 -1
- package/lib/common/rpc/connection.d.ts +31 -15
- package/lib/common/rpc/connection.d.ts.map +1 -1
- package/lib/common/rpc/connection.js +206 -138
- package/lib/common/rpc/connection.js.map +1 -1
- package/lib/common/rpc/index.d.ts +1 -1
- package/lib/common/rpc/index.d.ts.map +1 -1
- package/lib/common/rpc/index.js +1 -1
- package/lib/common/rpc/index.js.map +1 -1
- package/lib/common/rpc/message-io.d.ts +61 -0
- package/lib/common/rpc/message-io.d.ts.map +1 -0
- package/lib/common/rpc/message-io.js +159 -0
- package/lib/common/rpc/message-io.js.map +1 -0
- package/lib/common/rpc/multiplexer.d.ts +3 -0
- package/lib/common/rpc/multiplexer.d.ts.map +1 -1
- package/lib/common/rpc/multiplexer.js +3 -0
- package/lib/common/rpc/multiplexer.js.map +1 -1
- package/lib/common/rpc/types.d.ts +26 -5
- package/lib/common/rpc/types.d.ts.map +1 -1
- package/lib/common/rpc-service/center.d.ts +6 -3
- package/lib/common/rpc-service/center.d.ts.map +1 -1
- package/lib/common/rpc-service/center.js +39 -31
- package/lib/common/rpc-service/center.js.map +1 -1
- package/lib/common/rpc-service/proxy/base.d.ts +5 -3
- package/lib/common/rpc-service/proxy/base.d.ts.map +1 -1
- package/lib/common/rpc-service/proxy/base.js +56 -17
- package/lib/common/rpc-service/proxy/base.js.map +1 -1
- package/lib/common/rpc-service/proxy/index.d.ts +1 -3
- package/lib/common/rpc-service/proxy/index.d.ts.map +1 -1
- package/lib/common/rpc-service/proxy/index.js +1 -3
- package/lib/common/rpc-service/proxy/index.js.map +1 -1
- package/lib/common/rpc-service/proxy/{legacy.d.ts → json.d.ts} +5 -5
- package/lib/common/rpc-service/proxy/json.d.ts.map +1 -0
- package/lib/common/rpc-service/proxy/{legacy.js → json.js} +46 -56
- package/lib/common/rpc-service/proxy/json.js.map +1 -0
- package/lib/common/rpc-service/proxy/sumi.d.ts +1 -1
- package/lib/common/rpc-service/proxy/sumi.d.ts.map +1 -1
- package/lib/common/rpc-service/proxy/sumi.js +25 -37
- package/lib/common/rpc-service/proxy/sumi.js.map +1 -1
- package/lib/common/rpc-service/{proxy/registry.d.ts → registry.d.ts} +12 -1
- package/lib/common/rpc-service/registry.d.ts.map +1 -0
- package/lib/common/rpc-service/registry.js +99 -0
- package/lib/common/rpc-service/registry.js.map +1 -0
- package/lib/common/rpc-service/stub.js +4 -6
- package/lib/common/rpc-service/stub.js.map +1 -1
- package/lib/common/{ext-rpc-protocol.d.ts → rpcProtocol.d.ts} +2 -2
- package/lib/common/rpcProtocol.d.ts.map +1 -0
- package/lib/common/{ext-rpc-protocol.js → rpcProtocol.js} +5 -6
- package/lib/common/rpcProtocol.js.map +1 -0
- package/lib/common/server-handler.d.ts +35 -0
- package/lib/common/server-handler.d.ts.map +1 -0
- package/lib/common/server-handler.js +165 -0
- package/lib/common/server-handler.js.map +1 -0
- package/lib/common/types.d.ts +14 -0
- package/lib/common/types.d.ts.map +1 -1
- package/lib/common/ws-channel.d.ts +6 -10
- package/lib/common/ws-channel.d.ts.map +1 -1
- package/lib/common/ws-channel.js +16 -15
- package/lib/common/ws-channel.js.map +1 -1
- package/lib/electron/channel-handler.d.ts +14 -0
- package/lib/electron/channel-handler.d.ts.map +1 -0
- package/lib/electron/channel-handler.js +26 -0
- package/lib/electron/channel-handler.js.map +1 -0
- package/lib/electron/index.d.ts +2 -0
- package/lib/electron/index.d.ts.map +1 -0
- package/lib/electron/index.js +5 -0
- package/lib/electron/index.js.map +1 -0
- package/lib/node/common-channel-handler.d.ts +6 -25
- package/lib/node/common-channel-handler.d.ts.map +1 -1
- package/lib/node/common-channel-handler.js +9 -151
- package/lib/node/common-channel-handler.js.map +1 -1
- package/package.json +5 -5
- package/src/browser/ws-channel-handler.ts +26 -40
- package/src/common/buffers/buffers.ts +1 -1
- package/src/common/capturer.ts +36 -0
- package/src/common/connection/drivers/frame-decoder.ts +11 -11
- package/src/common/connection/drivers/index.ts +0 -1
- package/src/common/connection/drivers/message-port.ts +1 -4
- package/src/common/connection/drivers/node-message-port.ts +2 -2
- package/src/common/connection/drivers/reconnecting-websocket.ts +3 -2
- package/src/common/connection/drivers/socket.ts +4 -42
- package/src/common/connection/drivers/stream.ts +76 -0
- package/src/common/connection/drivers/ws-websocket.ts +2 -2
- package/src/common/fury-extends/any.ts +122 -102
- package/src/common/fury-extends/one-of.ts +79 -31
- package/src/common/fury-extends/shared.ts +3 -0
- package/src/common/index.ts +2 -2
- package/src/common/message.ts +1 -1
- package/src/common/rpc/connection.ts +228 -166
- package/src/common/rpc/index.ts +1 -1
- package/src/common/rpc/message-io.ts +223 -0
- package/src/common/rpc/multiplexer.ts +3 -0
- package/src/common/rpc/types.ts +30 -5
- package/src/common/rpc-service/center.ts +37 -31
- package/src/common/rpc-service/proxy/base.ts +59 -12
- package/src/common/rpc-service/proxy/index.ts +1 -3
- package/src/common/rpc-service/proxy/{legacy.ts → json.ts} +47 -57
- package/src/common/rpc-service/proxy/sumi.ts +23 -35
- package/src/common/rpc-service/registry.ts +125 -0
- package/src/common/rpc-service/stub.ts +6 -6
- package/src/common/{ext-rpc-protocol.ts → rpcProtocol.ts} +2 -2
- package/src/common/server-handler.ts +183 -0
- package/src/common/types.ts +13 -0
- package/src/common/ws-channel.ts +21 -23
- package/src/electron/channel-handler.ts +26 -0
- package/src/electron/index.ts +1 -0
- package/src/node/common-channel-handler.ts +10 -165
- package/lib/common/connection/drivers/utils.d.ts +0 -12
- package/lib/common/connection/drivers/utils.d.ts.map +0 -1
- package/lib/common/connection/drivers/utils.js +0 -49
- package/lib/common/connection/drivers/utils.js.map +0 -1
- package/lib/common/ext-rpc-protocol.d.ts.map +0 -1
- package/lib/common/ext-rpc-protocol.js.map +0 -1
- package/lib/common/rpc/packet.d.ts +0 -65
- package/lib/common/rpc/packet.d.ts.map +0 -1
- package/lib/common/rpc/packet.js +0 -82
- package/lib/common/rpc/packet.js.map +0 -1
- package/lib/common/rpc/protocol-repository.d.ts +0 -32
- package/lib/common/rpc/protocol-repository.d.ts.map +0 -1
- package/lib/common/rpc/protocol-repository.js +0 -118
- package/lib/common/rpc/protocol-repository.js.map +0 -1
- package/lib/common/rpc/utils.d.ts +0 -2
- package/lib/common/rpc/utils.d.ts.map +0 -1
- package/lib/common/rpc/utils.js +0 -10
- package/lib/common/rpc/utils.js.map +0 -1
- package/lib/common/rpc-service/proxy/invoker.d.ts +0 -14
- package/lib/common/rpc-service/proxy/invoker.d.ts.map +0 -1
- package/lib/common/rpc-service/proxy/invoker.js +0 -34
- package/lib/common/rpc-service/proxy/invoker.js.map +0 -1
- package/lib/common/rpc-service/proxy/legacy.d.ts.map +0 -1
- package/lib/common/rpc-service/proxy/legacy.js.map +0 -1
- package/lib/common/rpc-service/proxy/registry.d.ts.map +0 -1
- package/lib/common/rpc-service/proxy/registry.js +0 -46
- package/lib/common/rpc-service/proxy/registry.js.map +0 -1
- package/lib/common/utils.d.ts.map +0 -1
- package/lib/common/utils.js +0 -57
- package/lib/common/utils.js.map +0 -1
- package/src/common/connection/drivers/utils.ts +0 -52
- package/src/common/rpc/packet.ts +0 -104
- package/src/common/rpc/protocol-repository.ts +0 -180
- package/src/common/rpc/utils.ts +0 -5
- package/src/common/rpc-service/proxy/invoker.ts +0 -45
- package/src/common/rpc-service/proxy/registry.ts +0 -56
- package/src/common/utils.ts +0 -80
|
@@ -1,45 +1,35 @@
|
|
|
1
|
-
import
|
|
2
|
-
|
|
3
|
-
import type { WebSocket } from 'ws';
|
|
4
|
-
|
|
5
|
-
import { EventEmitter } from '@opensumi/events';
|
|
1
|
+
import { getDebugLogger } from '@opensumi/ide-core-common';
|
|
6
2
|
import {
|
|
3
|
+
CancellationToken,
|
|
4
|
+
CancellationTokenSource,
|
|
7
5
|
DisposableCollection,
|
|
6
|
+
EventQueue,
|
|
8
7
|
IDisposable,
|
|
9
|
-
parseError,
|
|
10
|
-
CancellationToken,
|
|
11
8
|
canceled,
|
|
12
|
-
|
|
13
|
-
isPromise,
|
|
9
|
+
parseError,
|
|
14
10
|
} from '@opensumi/ide-utils';
|
|
11
|
+
import { IReadableStream, isReadableStream, listenReadable } from '@opensumi/ide-utils/lib/stream';
|
|
15
12
|
|
|
16
13
|
import { BaseConnection, NetSocketConnection, WSWebSocketConnection } from '../connection';
|
|
17
14
|
import { METHOD_NOT_REGISTERED } from '../constants';
|
|
18
15
|
import { ILogger } from '../types';
|
|
19
16
|
|
|
20
17
|
import { MethodTimeoutError } from './errors';
|
|
18
|
+
import { MessageIO, OperationType, Status } from './message-io';
|
|
21
19
|
import {
|
|
22
|
-
BodyCodec,
|
|
23
|
-
ErrorCode,
|
|
24
|
-
OperationType,
|
|
25
|
-
MessageIO,
|
|
26
|
-
requestHeadersSerializer,
|
|
27
|
-
reader,
|
|
28
20
|
IRequestHeaders,
|
|
29
|
-
|
|
30
|
-
import { ProtocolRepository } from './protocol-repository';
|
|
31
|
-
import {
|
|
21
|
+
IResponseHeaders,
|
|
32
22
|
TGenericNotificationHandler,
|
|
33
23
|
TGenericRequestHandler,
|
|
34
|
-
|
|
35
|
-
TOnRequestNotFoundHandler,
|
|
24
|
+
TNotificationNotFoundHandler,
|
|
36
25
|
TRequestCallback,
|
|
26
|
+
TRequestNotFoundHandler,
|
|
37
27
|
} from './types';
|
|
38
|
-
import { assert } from './utils';
|
|
39
28
|
|
|
40
|
-
|
|
29
|
+
import type net from 'net';
|
|
30
|
+
import type { WebSocket } from 'ws';
|
|
41
31
|
|
|
42
|
-
const
|
|
32
|
+
const nullHeaders = {};
|
|
43
33
|
|
|
44
34
|
export interface ISumiConnectionOptions {
|
|
45
35
|
timeout?: number;
|
|
@@ -49,12 +39,10 @@ export interface ISumiConnectionOptions {
|
|
|
49
39
|
export class SumiConnection implements IDisposable {
|
|
50
40
|
protected disposable = new DisposableCollection();
|
|
51
41
|
|
|
52
|
-
private
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
private
|
|
56
|
-
[key: string]: [requestId: number, method: string, headers: Record<string, any>, args: any[]];
|
|
57
|
-
}>();
|
|
42
|
+
private _requestHandlers = new Map<string, TGenericRequestHandler<any>>();
|
|
43
|
+
private _starRequestHandler: TRequestNotFoundHandler | undefined;
|
|
44
|
+
private _notificationHandlers = new Map<string, TGenericNotificationHandler>();
|
|
45
|
+
private _starNotificationHandler: TNotificationNotFoundHandler | undefined;
|
|
58
46
|
|
|
59
47
|
private _requestId = 0;
|
|
60
48
|
private _callbacks = new Map<number, TRequestCallback>();
|
|
@@ -63,39 +51,41 @@ export class SumiConnection implements IDisposable {
|
|
|
63
51
|
private readonly _cancellationTokenSources = new Map<number, CancellationTokenSource>();
|
|
64
52
|
private readonly _knownCanceledRequests = new Set<number>();
|
|
65
53
|
|
|
66
|
-
|
|
67
|
-
|
|
54
|
+
protected activeRequestPool = new Map<number, ActiveRequest>();
|
|
55
|
+
|
|
56
|
+
public io = new MessageIO();
|
|
57
|
+
protected logger: ILogger;
|
|
68
58
|
|
|
69
59
|
constructor(protected socket: BaseConnection<Uint8Array>, protected options: ISumiConnectionOptions = {}) {
|
|
70
60
|
if (options.logger) {
|
|
71
61
|
this.logger = options.logger;
|
|
62
|
+
} else {
|
|
63
|
+
this.logger = getDebugLogger();
|
|
72
64
|
}
|
|
73
65
|
}
|
|
74
66
|
|
|
75
67
|
sendNotification(method: string, ...args: any[]) {
|
|
76
|
-
|
|
77
|
-
const payload = processor.serializeRequest(args);
|
|
78
|
-
this.socket.send(MessageIO.Request(this._requestId++, OperationType.Notification, method, nullHeaders, payload));
|
|
68
|
+
this.socket.send(this.io.Notification(this._requestId++, method, nullHeaders, args));
|
|
79
69
|
}
|
|
80
70
|
|
|
81
71
|
sendRequest(method: string, ...args: any[]) {
|
|
82
72
|
return new Promise<any>((resolve, reject) => {
|
|
83
73
|
const requestId = this._requestId++;
|
|
84
74
|
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
this._callbacks.set(requestId, (headers, error, buffer) => {
|
|
75
|
+
this._callbacks.set(requestId, (headers, error, result) => {
|
|
88
76
|
if (error) {
|
|
89
77
|
if (error === METHOD_NOT_REGISTERED) {
|
|
78
|
+
// we should not treat `METHOD_NOT_REGISTERED` as an error.
|
|
79
|
+
// it is a special case, it means the method is not registered on the other side.
|
|
90
80
|
resolve(error);
|
|
91
81
|
return;
|
|
92
82
|
}
|
|
93
83
|
|
|
84
|
+
this.traceRequestError(method, args, error);
|
|
94
85
|
reject(error);
|
|
95
86
|
return;
|
|
96
87
|
}
|
|
97
88
|
|
|
98
|
-
const result = processor.deserializeResult(buffer);
|
|
99
89
|
resolve(result);
|
|
100
90
|
});
|
|
101
91
|
|
|
@@ -117,37 +107,21 @@ export class SumiConnection implements IDisposable {
|
|
|
117
107
|
cancellationToken.onCancellationRequested(() => this.cancelRequest(requestId));
|
|
118
108
|
}
|
|
119
109
|
|
|
120
|
-
const payload = processor.serializeRequest(args);
|
|
121
110
|
this.socket.send(
|
|
122
|
-
|
|
111
|
+
this.io.Request(
|
|
123
112
|
requestId,
|
|
124
|
-
OperationType.Request,
|
|
125
113
|
method,
|
|
126
114
|
{
|
|
127
|
-
cancelable: cancellationToken
|
|
115
|
+
cancelable: Boolean(cancellationToken) || undefined,
|
|
128
116
|
},
|
|
129
|
-
|
|
117
|
+
args,
|
|
130
118
|
),
|
|
131
119
|
);
|
|
132
120
|
});
|
|
133
121
|
}
|
|
134
122
|
|
|
135
|
-
onNotification(method: string, handler: TGenericNotificationHandler): IDisposable {
|
|
136
|
-
const handlerWrapper = (requestId: number, method: string, headers: Record<string, any>, args: any[]) => {
|
|
137
|
-
handler(...args);
|
|
138
|
-
};
|
|
139
|
-
return this._notificationEmitter.on(method, handlerWrapper);
|
|
140
|
-
}
|
|
141
|
-
|
|
142
|
-
onNotificationNotFound(handler: TOnNotificationNotFoundHandler): IDisposable {
|
|
143
|
-
const handlerWrapper = (requestId: number, method: string, headers: Record<string, any>, args: any[]) => {
|
|
144
|
-
handler(method, args);
|
|
145
|
-
};
|
|
146
|
-
return this._notificationEmitter.on(star, handlerWrapper);
|
|
147
|
-
}
|
|
148
|
-
|
|
149
123
|
cancelRequest(requestId: number) {
|
|
150
|
-
this.socket.send(
|
|
124
|
+
this.socket.send(this.io.Cancel(requestId));
|
|
151
125
|
}
|
|
152
126
|
|
|
153
127
|
private _handleTimeout(method: string, requestId: number) {
|
|
@@ -161,72 +135,52 @@ export class SumiConnection implements IDisposable {
|
|
|
161
135
|
callback(nullHeaders, new MethodTimeoutError(method));
|
|
162
136
|
}
|
|
163
137
|
|
|
164
|
-
private runRequestHandler<T extends (...args: any[]) => any>(
|
|
165
|
-
requestId: number,
|
|
166
|
-
method: string,
|
|
167
|
-
args: any[],
|
|
168
|
-
handler: T,
|
|
169
|
-
) {
|
|
170
|
-
let result: any;
|
|
171
|
-
let error: Error | undefined;
|
|
172
|
-
const processor = this.protocolRepository.getProcessor(method);
|
|
173
|
-
|
|
174
|
-
try {
|
|
175
|
-
result = handler(...args);
|
|
176
|
-
} catch (err) {
|
|
177
|
-
error = err;
|
|
178
|
-
}
|
|
179
|
-
|
|
180
|
-
if (error) {
|
|
181
|
-
this.socket.send(MessageIO.Error(requestId, ErrorCode.Err, nullHeaders, error));
|
|
182
|
-
this._cancellationTokenSources.delete(requestId);
|
|
183
|
-
} else if (isPromise(result)) {
|
|
184
|
-
result
|
|
185
|
-
.then((result) => {
|
|
186
|
-
const payload = processor.serializeResult(result);
|
|
187
|
-
this.socket.send(MessageIO.Response(requestId, nullHeaders, payload));
|
|
188
|
-
this._cancellationTokenSources.delete(requestId);
|
|
189
|
-
})
|
|
190
|
-
.catch((err) => {
|
|
191
|
-
this.socket.send(MessageIO.Error(requestId, ErrorCode.Err, nullHeaders, err));
|
|
192
|
-
this._cancellationTokenSources.delete(requestId);
|
|
193
|
-
});
|
|
194
|
-
} else {
|
|
195
|
-
const payload = processor.serializeResult(result);
|
|
196
|
-
this.socket.send(MessageIO.Response(requestId, nullHeaders, payload));
|
|
197
|
-
this._cancellationTokenSources.delete(requestId);
|
|
198
|
-
}
|
|
199
|
-
}
|
|
200
|
-
|
|
201
138
|
onRequest<T = any>(method: string, handler: TGenericRequestHandler<T>): IDisposable {
|
|
202
|
-
|
|
203
|
-
|
|
139
|
+
this._requestHandlers.set(method, handler);
|
|
140
|
+
return {
|
|
141
|
+
dispose: () => {
|
|
142
|
+
this._requestHandlers.delete(method);
|
|
143
|
+
},
|
|
204
144
|
};
|
|
205
|
-
return this._requestEmitter.on(method, handlerWrapper);
|
|
206
145
|
}
|
|
207
146
|
|
|
208
|
-
onRequestNotFound(handler:
|
|
209
|
-
|
|
210
|
-
|
|
147
|
+
onRequestNotFound(handler: TRequestNotFoundHandler): IDisposable {
|
|
148
|
+
this._starRequestHandler = handler;
|
|
149
|
+
return {
|
|
150
|
+
dispose: () => {
|
|
151
|
+
this._starRequestHandler = undefined;
|
|
152
|
+
},
|
|
211
153
|
};
|
|
154
|
+
}
|
|
212
155
|
|
|
213
|
-
|
|
156
|
+
onNotification(method: string, handler: TGenericNotificationHandler): IDisposable {
|
|
157
|
+
this._notificationHandlers.set(method, handler);
|
|
158
|
+
return {
|
|
159
|
+
dispose: () => {
|
|
160
|
+
this._notificationHandlers.delete(method);
|
|
161
|
+
},
|
|
162
|
+
};
|
|
214
163
|
}
|
|
215
164
|
|
|
216
|
-
|
|
217
|
-
this.
|
|
165
|
+
onNotificationNotFound(handler: TNotificationNotFoundHandler): IDisposable {
|
|
166
|
+
this._starNotificationHandler = handler;
|
|
167
|
+
return {
|
|
168
|
+
dispose: () => {
|
|
169
|
+
this._starNotificationHandler = undefined;
|
|
170
|
+
},
|
|
171
|
+
};
|
|
218
172
|
}
|
|
219
173
|
|
|
220
174
|
listen() {
|
|
175
|
+
const { reader } = this.io;
|
|
176
|
+
|
|
221
177
|
const toDispose = this.socket.onMessage((data) => {
|
|
222
178
|
reader.reset(data);
|
|
223
179
|
// skip version, currently only have version 1
|
|
224
180
|
reader.skip(1);
|
|
225
181
|
|
|
226
|
-
const
|
|
227
|
-
|
|
182
|
+
const opType = reader.uint8() as OperationType;
|
|
228
183
|
const requestId = reader.uint32();
|
|
229
|
-
const codec = reader.uint8();
|
|
230
184
|
|
|
231
185
|
if (this._timeoutHandles.has(requestId)) {
|
|
232
186
|
// Ignore some jest test scenarios where clearTimeout is not defined.
|
|
@@ -237,41 +191,59 @@ export class SumiConnection implements IDisposable {
|
|
|
237
191
|
this._timeoutHandles.delete(requestId);
|
|
238
192
|
}
|
|
239
193
|
|
|
240
|
-
switch (
|
|
194
|
+
switch (opType) {
|
|
241
195
|
case OperationType.Response: {
|
|
242
|
-
const
|
|
243
|
-
if (!callback) {
|
|
244
|
-
this.logger.error(`Cannot find callback for request ${requestId}`);
|
|
245
|
-
return;
|
|
246
|
-
}
|
|
247
|
-
|
|
248
|
-
this._callbacks.delete(requestId);
|
|
249
|
-
|
|
196
|
+
const method = reader.stringOfVarUInt32();
|
|
250
197
|
const status = reader.uint16();
|
|
251
|
-
// const headers = headerSerializer.read();
|
|
252
|
-
|
|
253
|
-
// if error code is not 0, it's an error
|
|
254
|
-
if (status === ErrorCode.Err) {
|
|
255
|
-
// TODO: use binary codec
|
|
256
|
-
assert(codec === BodyCodec.JSON, 'Error response should be JSON encoded');
|
|
257
|
-
const content = reader.stringOfVarUInt32();
|
|
258
|
-
const error = parseError(content);
|
|
259
|
-
callback(nullHeaders, error);
|
|
260
|
-
return;
|
|
261
|
-
}
|
|
262
198
|
|
|
263
|
-
|
|
264
|
-
const
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
callback(
|
|
273
|
-
}
|
|
274
|
-
|
|
199
|
+
const runCallback = (headers: IResponseHeaders, error?: any, result?: any) => {
|
|
200
|
+
const callback = this._callbacks.get(requestId);
|
|
201
|
+
if (!callback) {
|
|
202
|
+
this.logger.error(`Cannot find callback for request ${requestId}`);
|
|
203
|
+
return;
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
this._callbacks.delete(requestId);
|
|
207
|
+
|
|
208
|
+
callback(headers, error, result);
|
|
209
|
+
};
|
|
210
|
+
|
|
211
|
+
const headers = this.io.responseHeadersSerializer.read();
|
|
212
|
+
|
|
213
|
+
switch (status) {
|
|
214
|
+
case Status.Err: {
|
|
215
|
+
// TODO: use binary codec
|
|
216
|
+
const content = reader.stringOfVarUInt32();
|
|
217
|
+
const error = parseError(content);
|
|
218
|
+
runCallback(nullHeaders, error);
|
|
219
|
+
break;
|
|
220
|
+
}
|
|
221
|
+
default: {
|
|
222
|
+
if (headers && headers.chunked) {
|
|
223
|
+
let activeReq: ActiveRequest;
|
|
224
|
+
if (this.activeRequestPool.has(requestId)) {
|
|
225
|
+
activeReq = this.activeRequestPool.get(requestId)!;
|
|
226
|
+
} else {
|
|
227
|
+
activeReq = new ActiveRequest(requestId, headers);
|
|
228
|
+
this.activeRequestPool.set(requestId, activeReq);
|
|
229
|
+
runCallback(headers, undefined, activeReq);
|
|
230
|
+
}
|
|
231
|
+
|
|
232
|
+
const result = this.io.getProcessor(method).readResponse() as Uint8Array;
|
|
233
|
+
|
|
234
|
+
// when result is null, it means the stream is ended.
|
|
235
|
+
if (result) {
|
|
236
|
+
activeReq.emit(result);
|
|
237
|
+
break;
|
|
238
|
+
}
|
|
239
|
+
|
|
240
|
+
activeReq.end();
|
|
241
|
+
this.activeRequestPool.delete(requestId);
|
|
242
|
+
} else {
|
|
243
|
+
const result = this.io.getProcessor(method).readResponse();
|
|
244
|
+
runCallback(headers, undefined, result);
|
|
245
|
+
}
|
|
246
|
+
}
|
|
275
247
|
}
|
|
276
248
|
break;
|
|
277
249
|
}
|
|
@@ -279,15 +251,79 @@ export class SumiConnection implements IDisposable {
|
|
|
279
251
|
// fall through
|
|
280
252
|
case OperationType.Request: {
|
|
281
253
|
const method = reader.stringOfVarUInt32();
|
|
282
|
-
const headers = requestHeadersSerializer.read() as IRequestHeaders;
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
254
|
+
const headers = this.io.requestHeadersSerializer.read() as IRequestHeaders;
|
|
255
|
+
const args = this.io.getProcessor(method).readRequest();
|
|
256
|
+
|
|
257
|
+
if (headers.cancelable) {
|
|
258
|
+
const tokenSource = new CancellationTokenSource();
|
|
259
|
+
this._cancellationTokenSources.set(requestId, tokenSource);
|
|
260
|
+
args.push(tokenSource.token);
|
|
261
|
+
|
|
262
|
+
if (this._knownCanceledRequests.has(requestId)) {
|
|
263
|
+
tokenSource.cancel();
|
|
264
|
+
this._knownCanceledRequests.delete(requestId);
|
|
265
|
+
}
|
|
266
|
+
}
|
|
287
267
|
|
|
288
|
-
|
|
268
|
+
switch (opType) {
|
|
269
|
+
case OperationType.Request: {
|
|
270
|
+
let promise: Promise<any>;
|
|
271
|
+
|
|
272
|
+
try {
|
|
273
|
+
let result: any;
|
|
274
|
+
|
|
275
|
+
const handler = this._requestHandlers.get(method);
|
|
276
|
+
if (handler) {
|
|
277
|
+
result = handler(...args);
|
|
278
|
+
} else if (this._starRequestHandler) {
|
|
279
|
+
result = this._starRequestHandler(method, args);
|
|
280
|
+
}
|
|
281
|
+
|
|
282
|
+
promise = Promise.resolve(result);
|
|
283
|
+
} catch (err) {
|
|
284
|
+
promise = Promise.reject(err);
|
|
285
|
+
}
|
|
286
|
+
|
|
287
|
+
const onSuccess = (result: any) => {
|
|
288
|
+
if (isReadableStream(result)) {
|
|
289
|
+
const responseHeaders: IResponseHeaders = {
|
|
290
|
+
chunked: true,
|
|
291
|
+
};
|
|
292
|
+
listenReadable(result, {
|
|
293
|
+
onData: (data) => {
|
|
294
|
+
this.socket.send(this.io.Response(requestId, method, responseHeaders, data));
|
|
295
|
+
},
|
|
296
|
+
onEnd: () => {
|
|
297
|
+
this.socket.send(this.io.Response(requestId, method, responseHeaders, null));
|
|
298
|
+
},
|
|
299
|
+
});
|
|
300
|
+
} else {
|
|
301
|
+
this.socket.send(this.io.Response(requestId, method, nullHeaders, result));
|
|
302
|
+
}
|
|
303
|
+
|
|
304
|
+
this._cancellationTokenSources.delete(requestId);
|
|
305
|
+
};
|
|
306
|
+
|
|
307
|
+
const onError = (err: Error) => {
|
|
308
|
+
this.traceRequestError(method, args, err);
|
|
309
|
+
this.socket.send(this.io.Error(requestId, method, nullHeaders, err));
|
|
310
|
+
this._cancellationTokenSources.delete(requestId);
|
|
311
|
+
};
|
|
312
|
+
|
|
313
|
+
promise.then(onSuccess).catch(onError);
|
|
314
|
+
break;
|
|
315
|
+
}
|
|
316
|
+
case OperationType.Notification: {
|
|
317
|
+
const handler = this._notificationHandlers.get(method);
|
|
318
|
+
if (handler) {
|
|
319
|
+
handler(...args);
|
|
320
|
+
} else if (this._starNotificationHandler) {
|
|
321
|
+
this._starNotificationHandler(method, args);
|
|
322
|
+
}
|
|
323
|
+
break;
|
|
324
|
+
}
|
|
325
|
+
}
|
|
289
326
|
|
|
290
|
-
this._receiveRequest(rpcType, requestId, method, headers, args);
|
|
291
327
|
break;
|
|
292
328
|
}
|
|
293
329
|
case OperationType.Cancel: {
|
|
@@ -313,33 +349,59 @@ export class SumiConnection implements IDisposable {
|
|
|
313
349
|
this.disposable.dispose();
|
|
314
350
|
}
|
|
315
351
|
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
const tokenSource = new CancellationTokenSource();
|
|
320
|
-
this._cancellationTokenSources.set(requestId, tokenSource);
|
|
321
|
-
args.push(tokenSource.token);
|
|
352
|
+
static forWSWebSocket(socket: WebSocket, options: ISumiConnectionOptions = {}) {
|
|
353
|
+
return new SumiConnection(new WSWebSocketConnection(socket), options);
|
|
354
|
+
}
|
|
322
355
|
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
356
|
+
static forNetSocket(socket: net.Socket, options: ISumiConnectionOptions = {}) {
|
|
357
|
+
return new SumiConnection(new NetSocketConnection(socket), options);
|
|
358
|
+
}
|
|
359
|
+
|
|
360
|
+
private traceRequestError(method: string, args: any[], error: any) {
|
|
361
|
+
this.logger.error(`Error handling request ${method} with args `, args, error);
|
|
362
|
+
}
|
|
363
|
+
}
|
|
364
|
+
|
|
365
|
+
class ActiveRequest implements IReadableStream<Uint8Array> {
|
|
366
|
+
protected dataQ = new EventQueue<Uint8Array>();
|
|
367
|
+
protected endQ = new EventQueue<void>();
|
|
368
|
+
|
|
369
|
+
on(event: 'data', listener: (chunk: Uint8Array) => void): this;
|
|
370
|
+
on(event: 'end', listener: () => void): this;
|
|
371
|
+
on(event: string, listener: (...args: any[]) => void): this;
|
|
372
|
+
on(event: unknown, listener: unknown): this {
|
|
373
|
+
if (typeof event === 'string') {
|
|
374
|
+
switch (event) {
|
|
375
|
+
case 'data':
|
|
376
|
+
this.onData(listener as (chunk: Uint8Array) => void);
|
|
377
|
+
break;
|
|
378
|
+
case 'end':
|
|
379
|
+
this.onEnd(listener as () => void);
|
|
380
|
+
break;
|
|
381
|
+
default:
|
|
382
|
+
break;
|
|
326
383
|
}
|
|
327
384
|
}
|
|
385
|
+
return this;
|
|
386
|
+
}
|
|
328
387
|
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
this._requestEmitter.emit(eventName, requestId, method, headers, args);
|
|
332
|
-
} else {
|
|
333
|
-
const eventName = this._notificationEmitter.hasListener(method) ? method : star;
|
|
334
|
-
this._notificationEmitter.emit(eventName, requestId, method, headers, args);
|
|
335
|
-
}
|
|
388
|
+
onData(cb: (data: Uint8Array) => void): IDisposable {
|
|
389
|
+
return this.dataQ.on(cb);
|
|
336
390
|
}
|
|
337
391
|
|
|
338
|
-
|
|
339
|
-
return
|
|
392
|
+
onEnd(cb: () => void): IDisposable {
|
|
393
|
+
return this.endQ.on(cb);
|
|
340
394
|
}
|
|
341
395
|
|
|
342
|
-
|
|
343
|
-
|
|
396
|
+
constructor(protected requestId: number, protected responseHeaders: IResponseHeaders) {}
|
|
397
|
+
|
|
398
|
+
emit(buffer: Uint8Array) {
|
|
399
|
+
this.dataQ.push(buffer);
|
|
400
|
+
}
|
|
401
|
+
|
|
402
|
+
end() {
|
|
403
|
+
this.dataQ.dispose();
|
|
404
|
+
this.endQ.push(undefined);
|
|
405
|
+
this.endQ.dispose();
|
|
344
406
|
}
|
|
345
407
|
}
|
package/src/common/rpc/index.ts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
export * from './types';
|
|
2
|
-
export * from './
|
|
2
|
+
export * from './message-io';
|