@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.
Files changed (209) hide show
  1. package/lib/browser/ws-channel-handler.d.ts.map +1 -1
  2. package/lib/browser/ws-channel-handler.js +2 -6
  3. package/lib/browser/ws-channel-handler.js.map +1 -1
  4. package/lib/common/{connection → buffers}/buffers.d.ts +2 -1
  5. package/lib/common/buffers/buffers.d.ts.map +1 -0
  6. package/lib/common/{connection → buffers}/buffers.js +21 -3
  7. package/lib/common/buffers/buffers.js.map +1 -0
  8. package/lib/common/connection/drivers/base.d.ts +2 -2
  9. package/lib/common/connection/drivers/base.d.ts.map +1 -1
  10. package/lib/common/connection/drivers/base.js +0 -4
  11. package/lib/common/connection/drivers/base.js.map +1 -1
  12. package/lib/common/connection/drivers/frame-decoder.d.ts +34 -0
  13. package/lib/common/connection/drivers/frame-decoder.d.ts.map +1 -0
  14. package/lib/common/connection/drivers/frame-decoder.js +147 -0
  15. package/lib/common/connection/drivers/frame-decoder.js.map +1 -0
  16. package/lib/common/connection/drivers/{empty.d.ts → message-port.d.ts} +5 -2
  17. package/lib/common/connection/drivers/message-port.d.ts.map +1 -0
  18. package/lib/common/connection/drivers/message-port.js +41 -0
  19. package/lib/common/connection/drivers/message-port.js.map +1 -0
  20. package/lib/common/connection/drivers/node-message-port.d.ts +1 -0
  21. package/lib/common/connection/drivers/node-message-port.d.ts.map +1 -1
  22. package/lib/common/connection/drivers/node-message-port.js +3 -0
  23. package/lib/common/connection/drivers/node-message-port.js.map +1 -1
  24. package/lib/common/connection/drivers/reconnecting-websocket.d.ts +1 -0
  25. package/lib/common/connection/drivers/reconnecting-websocket.d.ts.map +1 -1
  26. package/lib/common/connection/drivers/reconnecting-websocket.js +3 -0
  27. package/lib/common/connection/drivers/reconnecting-websocket.js.map +1 -1
  28. package/lib/common/connection/drivers/simple.d.ts +17 -0
  29. package/lib/common/connection/drivers/simple.d.ts.map +1 -0
  30. package/lib/common/connection/drivers/simple.js +32 -0
  31. package/lib/common/connection/drivers/simple.js.map +1 -0
  32. package/lib/common/connection/drivers/socket.d.ts +4 -2
  33. package/lib/common/connection/drivers/socket.d.ts.map +1 -1
  34. package/lib/common/connection/drivers/socket.js +10 -7
  35. package/lib/common/connection/drivers/socket.js.map +1 -1
  36. package/lib/common/connection/drivers/ws-websocket.d.ts +2 -0
  37. package/lib/common/connection/drivers/ws-websocket.d.ts.map +1 -1
  38. package/lib/common/connection/drivers/ws-websocket.js +6 -0
  39. package/lib/common/connection/drivers/ws-websocket.js.map +1 -1
  40. package/lib/common/connection/types.d.ts +1 -1
  41. package/lib/common/connection/types.d.ts.map +1 -1
  42. package/lib/common/ext-rpc-protocol.d.ts +7 -21
  43. package/lib/common/ext-rpc-protocol.d.ts.map +1 -1
  44. package/lib/common/ext-rpc-protocol.js +13 -33
  45. package/lib/common/ext-rpc-protocol.js.map +1 -1
  46. package/lib/common/fury-extends/any.d.ts +22 -0
  47. package/lib/common/fury-extends/any.d.ts.map +1 -0
  48. package/lib/common/fury-extends/any.js +143 -0
  49. package/lib/common/fury-extends/any.js.map +1 -0
  50. package/lib/common/fury-extends/one-of.d.ts +14 -0
  51. package/lib/common/fury-extends/one-of.d.ts.map +1 -0
  52. package/lib/common/fury-extends/one-of.js +50 -0
  53. package/lib/common/fury-extends/one-of.js.map +1 -0
  54. package/lib/common/fury-extends/shared.d.ts +142 -0
  55. package/lib/common/fury-extends/shared.d.ts.map +1 -0
  56. package/lib/common/fury-extends/shared.js +17 -0
  57. package/lib/common/fury-extends/shared.js.map +1 -0
  58. package/lib/common/index.d.ts +2 -1
  59. package/lib/common/index.d.ts.map +1 -1
  60. package/lib/common/index.js +2 -1
  61. package/lib/common/index.js.map +1 -1
  62. package/lib/common/protocols/common-server.d.ts +3 -0
  63. package/lib/common/protocols/common-server.d.ts.map +1 -0
  64. package/lib/common/protocols/common-server.js +18 -0
  65. package/lib/common/protocols/common-server.js.map +1 -0
  66. package/lib/common/protocols/common.d.ts +24 -0
  67. package/lib/common/protocols/common.d.ts.map +1 -0
  68. package/lib/common/protocols/common.js +12 -0
  69. package/lib/common/protocols/common.js.map +1 -0
  70. package/lib/common/rpc/connection.d.ts +44 -0
  71. package/lib/common/rpc/connection.d.ts.map +1 -0
  72. package/lib/common/rpc/connection.js +256 -0
  73. package/lib/common/rpc/connection.js.map +1 -0
  74. package/lib/common/rpc/errors.d.ts +4 -0
  75. package/lib/common/rpc/errors.d.ts.map +1 -0
  76. package/lib/common/rpc/errors.js +10 -0
  77. package/lib/common/rpc/errors.js.map +1 -0
  78. package/lib/common/rpc/index.d.ts +3 -0
  79. package/lib/common/rpc/index.d.ts.map +1 -0
  80. package/lib/common/rpc/index.js +6 -0
  81. package/lib/common/rpc/index.js.map +1 -0
  82. package/lib/common/rpc/multiplexer.d.ts +28 -0
  83. package/lib/common/rpc/multiplexer.d.ts.map +1 -0
  84. package/lib/common/rpc/multiplexer.js +82 -0
  85. package/lib/common/rpc/multiplexer.js.map +1 -0
  86. package/lib/common/rpc/packet.d.ts +65 -0
  87. package/lib/common/rpc/packet.d.ts.map +1 -0
  88. package/lib/common/rpc/packet.js +82 -0
  89. package/lib/common/rpc/packet.js.map +1 -0
  90. package/lib/common/rpc/protocol-repository.d.ts +32 -0
  91. package/lib/common/rpc/protocol-repository.d.ts.map +1 -0
  92. package/lib/common/rpc/protocol-repository.js +118 -0
  93. package/lib/common/rpc/protocol-repository.js.map +1 -0
  94. package/lib/common/rpc/types.d.ts +13 -0
  95. package/lib/common/rpc/types.d.ts.map +1 -0
  96. package/lib/common/rpc/types.js +3 -0
  97. package/lib/common/rpc/types.js.map +1 -0
  98. package/lib/common/rpc/utils.d.ts +2 -0
  99. package/lib/common/rpc/utils.d.ts.map +1 -0
  100. package/lib/common/rpc/utils.js +10 -0
  101. package/lib/common/rpc/utils.js.map +1 -0
  102. package/lib/common/rpc-service/center.d.ts +12 -5
  103. package/lib/common/rpc-service/center.d.ts.map +1 -1
  104. package/lib/common/rpc-service/center.js +47 -42
  105. package/lib/common/rpc-service/center.js.map +1 -1
  106. package/lib/common/rpc-service/index.d.ts +6 -0
  107. package/lib/common/rpc-service/index.d.ts.map +1 -1
  108. package/lib/common/rpc-service/index.js +7 -0
  109. package/lib/common/rpc-service/index.js.map +1 -1
  110. package/lib/common/rpc-service/proxy/base.d.ts +32 -0
  111. package/lib/common/rpc-service/proxy/base.d.ts.map +1 -0
  112. package/lib/common/rpc-service/proxy/base.js +93 -0
  113. package/lib/common/rpc-service/proxy/base.js.map +1 -0
  114. package/lib/common/rpc-service/proxy/index.d.ts +5 -0
  115. package/lib/common/rpc-service/proxy/index.d.ts.map +1 -0
  116. package/lib/common/rpc-service/proxy/index.js +8 -0
  117. package/lib/common/rpc-service/proxy/index.js.map +1 -0
  118. package/lib/common/rpc-service/proxy/invoker.d.ts +14 -0
  119. package/lib/common/rpc-service/proxy/invoker.d.ts.map +1 -0
  120. package/lib/common/rpc-service/proxy/invoker.js +34 -0
  121. package/lib/common/rpc-service/proxy/invoker.js.map +1 -0
  122. package/lib/common/{proxy → rpc-service/proxy}/legacy.d.ts +3 -7
  123. package/lib/common/rpc-service/proxy/legacy.d.ts.map +1 -0
  124. package/lib/common/rpc-service/proxy/legacy.js +136 -0
  125. package/lib/common/rpc-service/proxy/legacy.js.map +1 -0
  126. package/lib/common/rpc-service/proxy/registry.d.ts +18 -0
  127. package/lib/common/rpc-service/proxy/registry.d.ts.map +1 -0
  128. package/lib/common/rpc-service/proxy/registry.js +46 -0
  129. package/lib/common/rpc-service/proxy/registry.js.map +1 -0
  130. package/lib/common/rpc-service/proxy/sumi.d.ts +9 -0
  131. package/lib/common/rpc-service/proxy/sumi.d.ts.map +1 -0
  132. package/lib/common/rpc-service/proxy/sumi.js +86 -0
  133. package/lib/common/rpc-service/proxy/sumi.js.map +1 -0
  134. package/lib/common/rpc-service/stub.d.ts +0 -1
  135. package/lib/common/rpc-service/stub.d.ts.map +1 -1
  136. package/lib/common/rpc-service/stub.js +3 -11
  137. package/lib/common/rpc-service/stub.js.map +1 -1
  138. package/lib/common/types.d.ts +1 -1
  139. package/lib/common/types.d.ts.map +1 -1
  140. package/lib/common/ws-channel.d.ts +97 -32
  141. package/lib/common/ws-channel.d.ts.map +1 -1
  142. package/lib/common/ws-channel.js +75 -51
  143. package/lib/common/ws-channel.js.map +1 -1
  144. package/lib/node/common-channel-handler.js +1 -1
  145. package/lib/node/common-channel-handler.js.map +1 -1
  146. package/package.json +5 -5
  147. package/src/browser/ws-channel-handler.ts +2 -6
  148. package/src/common/{connection → buffers}/buffers.ts +24 -3
  149. package/src/common/connection/drivers/base.ts +2 -6
  150. package/src/common/connection/drivers/frame-decoder.ts +170 -0
  151. package/src/common/connection/drivers/message-port.ts +42 -0
  152. package/src/common/connection/drivers/node-message-port.ts +3 -0
  153. package/src/common/connection/drivers/reconnecting-websocket.ts +4 -0
  154. package/src/common/connection/drivers/simple.ts +33 -0
  155. package/src/common/connection/drivers/socket.ts +11 -7
  156. package/src/common/connection/drivers/ws-websocket.ts +8 -0
  157. package/src/common/connection/types.ts +1 -1
  158. package/src/common/ext-rpc-protocol.ts +16 -51
  159. package/src/common/fury-extends/any.ts +144 -0
  160. package/src/common/fury-extends/one-of.ts +61 -0
  161. package/src/common/fury-extends/shared.ts +15 -0
  162. package/src/common/index.ts +2 -1
  163. package/src/common/protocols/common-server.ts +18 -0
  164. package/src/common/protocols/common.ts +9 -0
  165. package/src/common/rpc/connection.ts +345 -0
  166. package/src/common/rpc/errors.ts +5 -0
  167. package/src/common/rpc/index.ts +2 -0
  168. package/src/common/rpc/multiplexer.ts +105 -0
  169. package/src/common/rpc/packet.ts +104 -0
  170. package/src/common/rpc/protocol-repository.ts +180 -0
  171. package/src/common/rpc/types.ts +23 -0
  172. package/src/common/rpc/utils.ts +5 -0
  173. package/src/common/rpc-service/center.ts +59 -49
  174. package/src/common/rpc-service/index.ts +9 -0
  175. package/src/common/rpc-service/proxy/base.ts +126 -0
  176. package/src/common/rpc-service/proxy/index.ts +4 -0
  177. package/src/common/rpc-service/proxy/invoker.ts +45 -0
  178. package/src/common/rpc-service/proxy/legacy.ts +150 -0
  179. package/src/common/rpc-service/proxy/registry.ts +56 -0
  180. package/src/common/rpc-service/proxy/sumi.ts +81 -0
  181. package/src/common/rpc-service/stub.ts +4 -11
  182. package/src/common/types.ts +1 -1
  183. package/src/common/ws-channel.ts +100 -61
  184. package/src/node/common-channel-handler.ts +1 -1
  185. package/lib/common/connection/buffers.d.ts.map +0 -1
  186. package/lib/common/connection/buffers.js.map +0 -1
  187. package/lib/common/connection/drivers/empty.d.ts.map +0 -1
  188. package/lib/common/connection/drivers/empty.js +0 -21
  189. package/lib/common/connection/drivers/empty.js.map +0 -1
  190. package/lib/common/connection/drivers/stream-decoder.d.ts +0 -67
  191. package/lib/common/connection/drivers/stream-decoder.d.ts.map +0 -1
  192. package/lib/common/connection/drivers/stream-decoder.js +0 -171
  193. package/lib/common/connection/drivers/stream-decoder.js.map +0 -1
  194. package/lib/common/proxy/base.d.ts +0 -22
  195. package/lib/common/proxy/base.d.ts.map +0 -1
  196. package/lib/common/proxy/base.js +0 -47
  197. package/lib/common/proxy/base.js.map +0 -1
  198. package/lib/common/proxy/index.d.ts +0 -8
  199. package/lib/common/proxy/index.d.ts.map +0 -1
  200. package/lib/common/proxy/index.js +0 -12
  201. package/lib/common/proxy/index.js.map +0 -1
  202. package/lib/common/proxy/legacy.d.ts.map +0 -1
  203. package/lib/common/proxy/legacy.js +0 -183
  204. package/lib/common/proxy/legacy.js.map +0 -1
  205. package/src/common/connection/drivers/empty.ts +0 -19
  206. package/src/common/connection/drivers/stream-decoder.ts +0 -196
  207. package/src/common/proxy/base.ts +0 -67
  208. package/src/common/proxy/index.ts +0 -10
  209. package/src/common/proxy/legacy.ts +0 -200
@@ -0,0 +1,105 @@
1
+ import { BaseConnection } from '../connection';
2
+
3
+ import { ISumiConnectionOptions, SumiConnection } from './connection';
4
+
5
+ export class ProxyIdentifier<T = any> {
6
+ public static count = 0;
7
+
8
+ public readonly serviceId: string;
9
+ public readonly countId: number;
10
+ constructor(serviceId: string) {
11
+ this.serviceId = serviceId;
12
+ this.countId = ++ProxyIdentifier.count;
13
+ }
14
+
15
+ static for(serviceId: string) {
16
+ return new ProxyIdentifier(serviceId);
17
+ }
18
+ }
19
+
20
+ export const IRPCProtocol = Symbol('IRPCProtocol');
21
+ export interface IRPCProtocol {
22
+ getProxy<T>(proxyId: ProxyIdentifier<T>): T;
23
+ set<T>(identifier: ProxyIdentifier<T>, instance: T): T;
24
+ get<T>(identifier: ProxyIdentifier<T>): T;
25
+ }
26
+
27
+ const SEP = '/';
28
+
29
+ function getRPCName(serviceId: string, methodName: string) {
30
+ return `${serviceId}${SEP}${methodName}`;
31
+ }
32
+
33
+ function extractServiceAndMethod(rpcId: string): [string, string] {
34
+ const idx = rpcId.indexOf(SEP);
35
+ return [rpcId.substring(0, idx), rpcId.substring(idx + 1)];
36
+ }
37
+
38
+ export class SumiConnectionMultiplexer extends SumiConnection implements IRPCProtocol {
39
+ private readonly _locals: Map<string, any>;
40
+ private readonly _proxies: Map<string, any>;
41
+
42
+ constructor(protected socket: BaseConnection<Uint8Array>, protected options: ISumiConnectionOptions = {}) {
43
+ super(socket, options);
44
+ this._locals = new Map();
45
+ this._proxies = new Map();
46
+
47
+ this.onRequestNotFound((rpcName: string, args: any[]) => {
48
+ const [rpcId, methodName] = extractServiceAndMethod(rpcName);
49
+ return this._doInvokeHandler(rpcId, methodName, args);
50
+ });
51
+
52
+ // call `listen` implicitly
53
+ // compatible behavior with the RPCProtocol
54
+ this.listen();
55
+ }
56
+
57
+ public set<T>(identifier: ProxyIdentifier<T>, instance: any) {
58
+ this._locals.set(identifier.serviceId, instance);
59
+ return instance;
60
+ }
61
+
62
+ public get<T>(identifier: ProxyIdentifier<T>) {
63
+ return this._locals.get(identifier.serviceId);
64
+ }
65
+
66
+ public getProxy<T>(proxyId: ProxyIdentifier<T>) {
67
+ if (!this._proxies.has(proxyId.serviceId)) {
68
+ this._proxies.set(proxyId.serviceId, this._createProxy(proxyId.serviceId));
69
+ }
70
+
71
+ return this._proxies.get(proxyId.serviceId);
72
+ }
73
+
74
+ private _createProxy(rpcId: string) {
75
+ const handler = {
76
+ get: (target: any, name: string) => {
77
+ if (typeof name === 'symbol') {
78
+ return null;
79
+ }
80
+ // charCodeAt(0) === 36 means starts with $
81
+ if (!target[name] && name.charCodeAt(0) === 36) {
82
+ const rpcName = getRPCName(rpcId, name);
83
+ target[name] = (...args: any[]) => this.sendRequest(rpcName, ...args);
84
+ }
85
+
86
+ return target[name];
87
+ },
88
+ };
89
+
90
+ return new Proxy(Object.create(null), handler);
91
+ }
92
+
93
+ private async _doInvokeHandler(rpcId: string, methodName: string, args: any[]): Promise<any> {
94
+ const actor = this._locals.get(rpcId);
95
+ if (!actor) {
96
+ throw new Error('Unknown actor ' + rpcId);
97
+ }
98
+ const method = await actor[methodName];
99
+ if (typeof method !== 'function') {
100
+ throw new Error('Unknown method ' + methodName + ' on actor ' + rpcId);
101
+ }
102
+
103
+ return method.apply(actor, args);
104
+ }
105
+ }
@@ -0,0 +1,104 @@
1
+ import { Serializer, Type } from '@furyjs/fury';
2
+ import { generateSerializer } from '@furyjs/fury/dist/lib/gen';
3
+
4
+ import { stringifyError } from '@opensumi/ide-core-common/lib/utils';
5
+
6
+ import { furyFactory } from '../fury-extends/shared';
7
+
8
+ const ProtoVersionV1 = 1;
9
+
10
+ export enum OperationType {
11
+ Request,
12
+ Notification,
13
+ Response,
14
+ Heartbeat,
15
+ Cancel,
16
+ }
17
+
18
+ export enum BodyCodec {
19
+ /**
20
+ * Means no body
21
+ */
22
+ None,
23
+ Text,
24
+ Binary,
25
+ JSON,
26
+ }
27
+
28
+ export enum ErrorCode {
29
+ OK,
30
+ Err,
31
+ }
32
+
33
+ const { fury, reader, writer } = furyFactory();
34
+ export { reader };
35
+
36
+ const requestHeadersProto = Type.object('headers', {
37
+ cancelable: Type.bool(),
38
+ });
39
+
40
+ export interface IRequestHeaders {
41
+ /**
42
+ * If set to true, the request can be canceled.
43
+ *
44
+ * the server will push a `CancellationToken` to the request arguments.
45
+ */
46
+ cancelable?: boolean;
47
+ }
48
+
49
+ export const requestHeadersSerializer = generateSerializer(fury, requestHeadersProto) as Serializer;
50
+
51
+ export class MessageIO {
52
+ static Request(requestId: number, rpcType: number, method: string, headers: IRequestHeaders, payload: Uint8Array) {
53
+ writer.reset();
54
+
55
+ writer.uint8(ProtoVersionV1);
56
+ writer.uint8(rpcType);
57
+ writer.uint32(requestId);
58
+ writer.uint8(BodyCodec.Binary);
59
+ writer.stringOfVarUInt32(method);
60
+ requestHeadersSerializer.write(headers);
61
+ writer.varUInt32(payload.length);
62
+ writer.buffer(payload);
63
+
64
+ return writer.dump();
65
+ }
66
+
67
+ static Cancel(requestId: number) {
68
+ writer.reset();
69
+
70
+ writer.uint8(ProtoVersionV1);
71
+ writer.uint8(OperationType.Cancel);
72
+ writer.uint32(requestId);
73
+ writer.uint8(BodyCodec.None);
74
+
75
+ return writer.dump();
76
+ }
77
+
78
+ static Response(requestId: number, headers: Record<string, any>, payload: Uint8Array) {
79
+ writer.reset();
80
+
81
+ writer.uint8(ProtoVersionV1);
82
+ writer.uint8(OperationType.Response);
83
+ writer.uint32(requestId);
84
+ writer.uint8(BodyCodec.Binary);
85
+ writer.uint16(ErrorCode.OK);
86
+ writer.varUInt32(payload.length);
87
+ writer.buffer(payload);
88
+
89
+ return writer.dump();
90
+ }
91
+
92
+ static Error(requestId: number, status: number, headers: Record<string, any>, error: any) {
93
+ writer.reset();
94
+
95
+ writer.uint8(ProtoVersionV1);
96
+ writer.uint8(OperationType.Response);
97
+ writer.uint32(requestId);
98
+ writer.uint8(BodyCodec.JSON);
99
+ writer.uint16(status);
100
+ writer.stringOfVarUInt32(stringifyError(error));
101
+
102
+ return writer.dump();
103
+ }
104
+ }
@@ -0,0 +1,180 @@
1
+ import Fury, { Type, TypeDescription } from '@furyjs/fury';
2
+
3
+ import { anySerializer } from '../fury-extends/any';
4
+
5
+ import { TSumiProtocol, TSumiProtocolMethod } from './types';
6
+
7
+ export type TRequestTransferable = ITransferable[];
8
+
9
+ export interface ITransferable {
10
+ /**
11
+ * transfer raw value
12
+ */
13
+ r: any;
14
+
15
+ /**
16
+ * value that cannot be transferred, use string instead
17
+ */
18
+ $?: string;
19
+ }
20
+
21
+ type TSerializer = ReturnType<Fury['registerSerializer']>;
22
+
23
+ interface IProtocolProcessor {
24
+ serializeRequest(args: any[]): Uint8Array;
25
+ deserializeRequest(buffer: Uint8Array): any[];
26
+ serializeResult<T = any>(result: T): Uint8Array;
27
+ deserializeResult<T = any>(buffer: Uint8Array): T;
28
+ }
29
+
30
+ const createTransferable = (name: string, type?: TypeDescription) => {
31
+ const props = {
32
+ $: Type.string(),
33
+ } as Record<string, TypeDescription>;
34
+ if (type) {
35
+ props.r = type;
36
+ }
37
+ return Type.object(name, props);
38
+ };
39
+
40
+ class SumiProtocolProcessor implements IProtocolProcessor {
41
+ request: TSerializer;
42
+ result: TSerializer;
43
+ requestArgsLength: number;
44
+
45
+ constructor(methodProtocol: TSumiProtocolMethod, public fury: Fury) {
46
+ const methodName = methodProtocol.method;
47
+
48
+ const argsTuple = [] as TypeDescription[];
49
+
50
+ for (const element of methodProtocol.request) {
51
+ argsTuple.push(createTransferable(methodName + '^' + element.name, element.type));
52
+ }
53
+
54
+ const requestProto = Type.tuple(argsTuple);
55
+ const resultProto = createTransferable(methodName + 'v', methodProtocol.response.type);
56
+
57
+ this.requestArgsLength = argsTuple.length;
58
+
59
+ this.request = this.fury.registerSerializer(requestProto);
60
+ this.result = this.fury.registerSerializer(resultProto);
61
+ }
62
+
63
+ serializeRequest(args: any[]): Uint8Array {
64
+ const newArray: TRequestTransferable = new Array(args.length);
65
+ for (let i = 0; i < args.length; i++) {
66
+ newArray[i] = ObjectTransfer.replacer(args[i]);
67
+ }
68
+
69
+ return this.request.serialize(newArray);
70
+ }
71
+
72
+ deserializeRequest(buffer: Uint8Array): any[] {
73
+ const result = new Array(this.requestArgsLength);
74
+ const argsArray = this.request.deserialize(buffer) as TRequestTransferable;
75
+ for (let i = 0; i < this.requestArgsLength; i++) {
76
+ result[i] = ObjectTransfer.reviver(argsArray[i]);
77
+ }
78
+ return result;
79
+ }
80
+
81
+ serializeResult<T = any>(result: T): Uint8Array {
82
+ return this.result.serialize(ObjectTransfer.replacer(result));
83
+ }
84
+
85
+ deserializeResult<T = any>(buffer: Uint8Array): T {
86
+ const payload = this.result.deserialize(buffer) as ITransferable;
87
+ return ObjectTransfer.reviver(payload);
88
+ }
89
+ }
90
+
91
+ class AnyProtocolProcessor implements IProtocolProcessor {
92
+ serializeRequest(args: any[]): Uint8Array {
93
+ return anySerializer.serialize(args);
94
+ }
95
+
96
+ deserializeRequest(buffer: Uint8Array): any[] {
97
+ return anySerializer.deserialize(buffer);
98
+ }
99
+
100
+ serializeResult<T = any>(result: T): Uint8Array {
101
+ return anySerializer.serialize(result);
102
+ }
103
+
104
+ deserializeResult<T = any>(buffer: Uint8Array): T {
105
+ return anySerializer.deserialize(buffer);
106
+ }
107
+ }
108
+
109
+ export class ProtocolRepository {
110
+ fury = new Fury();
111
+
112
+ private processorMap = new Map<string, SumiProtocolProcessor>();
113
+
114
+ private anyProcessor = new AnyProtocolProcessor();
115
+
116
+ has(name: string) {
117
+ return this.processorMap.has(name);
118
+ }
119
+
120
+ loadProtocol(
121
+ protocol: TSumiProtocol,
122
+ options?: {
123
+ nameConverter?: (str: string) => string;
124
+ },
125
+ ) {
126
+ const { methods } = protocol;
127
+
128
+ for (const proto of methods) {
129
+ let method = proto.method;
130
+ if (options?.nameConverter) {
131
+ method = options.nameConverter(method);
132
+ }
133
+
134
+ const copy = {
135
+ ...proto,
136
+ method,
137
+ };
138
+
139
+ this.loadProtocolMethod(copy);
140
+ }
141
+ }
142
+
143
+ loadProtocolMethod(methodProtocol: TSumiProtocolMethod) {
144
+ this.processorMap.set(methodProtocol.method, new SumiProtocolProcessor(methodProtocol, this.fury));
145
+ }
146
+
147
+ getProcessor(method: string): IProtocolProcessor {
148
+ const processor = this.processorMap.get(method);
149
+ if (processor) {
150
+ return processor;
151
+ }
152
+ return this.anyProcessor;
153
+ }
154
+ }
155
+
156
+ class ObjectTransfer {
157
+ static TypeUndefined = '$undefined';
158
+
159
+ static replacer(value: any) {
160
+ const payload = {} as ITransferable;
161
+
162
+ if (typeof value === 'undefined') {
163
+ payload.$ = ObjectTransfer.TypeUndefined;
164
+ }
165
+
166
+ if (!payload.$) {
167
+ payload.r = value;
168
+ }
169
+
170
+ return payload;
171
+ }
172
+
173
+ static reviver(transferable: ITransferable): any {
174
+ if (transferable.$ === ObjectTransfer.TypeUndefined) {
175
+ return undefined;
176
+ }
177
+
178
+ return transferable.r;
179
+ }
180
+ }
@@ -0,0 +1,23 @@
1
+ import { TypeDescription } from '@furyjs/fury';
2
+
3
+ import {
4
+ RPCProtocol as _RPCProtocol,
5
+ RPCProtocolMethod as _RPCProtocolMethod,
6
+ Request as _Request,
7
+ Response as _Response,
8
+ } from '@opensumi/ide-core-common/lib/types/rpc';
9
+
10
+ export type TSumiProtocol = _RPCProtocol<TypeDescription>;
11
+ export type TSumiProtocolMethod = _RPCProtocolMethod<TypeDescription>;
12
+ export type TSumiRequest = _Request<TypeDescription>;
13
+ export type TSumiResponse = _Response<TypeDescription>;
14
+
15
+ export type TRequestCallback = (headers: Record<string, any>, error?: any, payload?: Uint8Array | string | any) => void;
16
+
17
+ export type THandlerResult<R> = R | Promise<R>;
18
+
19
+ export type TGenericNotificationHandler = (...args: any[]) => void | Promise<void>;
20
+ export type TGenericRequestHandler<R> = (...args: any[]) => THandlerResult<R>;
21
+
22
+ export type TOnRequestNotFoundHandler = (method: string, args: any[]) => THandlerResult<any>;
23
+ export type TOnNotificationNotFoundHandler = (method: string, args: any[]) => THandlerResult<void>;
@@ -0,0 +1,5 @@
1
+ export const assert = (condition: any, message: string) => {
2
+ if (!condition) {
3
+ throw new Error(message);
4
+ }
5
+ };
@@ -1,43 +1,25 @@
1
1
  import { Deferred } from '@opensumi/ide-core-common';
2
+ import { MessageConnection } from '@opensumi/vscode-jsonrpc';
2
3
 
3
4
  import { METHOD_NOT_REGISTERED } from '../constants';
4
- import { ProxyLegacy } from '../proxy';
5
- import { IBench, ILogger, IRPCServiceMap, RPCServiceMethod, ServiceType } from '../types';
5
+ import { TSumiProtocol, ProtocolRepository } from '../rpc';
6
+ import { SumiConnection } from '../rpc/connection';
7
+ import { IBench, ILogger, RPCServiceMethod, ServiceType } from '../types';
6
8
  import { getMethodName } from '../utils';
7
- import { WSChannel } from '../ws-channel';
8
9
 
9
- const safeProcess: { pid: string } = typeof process === 'undefined' ? { pid: 'mock' } : (process as any);
10
+ import { ServiceRegistry, Invoker, ProxyLegacy, ProxySumi } from './proxy';
10
11
 
11
- const defaultReservedWordSet = new Set(['then']);
12
-
13
- class Invoker {
14
- legacyProxy: ProxyLegacy;
15
-
16
- private legacyInvokeProxy: any;
17
-
18
- setLegacyProxy(proxy: ProxyLegacy) {
19
- this.legacyProxy = proxy;
20
- this.legacyInvokeProxy = proxy.getInvokeProxy();
21
- }
22
-
23
- invoke(name: string, ...args: any[]) {
24
- if (defaultReservedWordSet.has(name) || typeof name === 'symbol') {
25
- return Promise.resolve();
26
- }
27
-
28
- return this.legacyInvokeProxy[name](...args);
29
- }
30
- }
12
+ const safeProcess: { pid: string } = typeof process === 'undefined' ? { pid: 'unknown' } : (process as any);
31
13
 
32
14
  export class RPCServiceCenter {
33
15
  public uid: string;
34
16
 
35
17
  private invokers: Invoker[] = [];
36
- private connection: Array<WSChannel> = [];
37
18
 
38
- private serviceMethodMap = { client: undefined } as unknown as IRPCServiceMap;
19
+ private protocolRepository = new ProtocolRepository();
20
+ private registry = new ServiceRegistry();
39
21
 
40
- private connectionDeferred = new Deferred<void>();
22
+ private deferred = new Deferred<void>();
41
23
  private logger: ILogger;
42
24
 
43
25
  constructor(private bench?: IBench, logger?: ILogger) {
@@ -54,47 +36,75 @@ export class RPCServiceCenter {
54
36
  }
55
37
 
56
38
  ready() {
57
- return this.connectionDeferred.promise;
39
+ return this.deferred.promise;
40
+ }
41
+
42
+ loadProtocol(protocol: TSumiProtocol) {
43
+ this.protocolRepository.loadProtocol(protocol, {
44
+ nameConverter: (name) => getMethodName(protocol.name, name),
45
+ });
58
46
  }
59
47
 
60
- setChannel(channel: WSChannel) {
61
- if (!this.connection.length) {
62
- this.connectionDeferred.resolve();
48
+ setSumiConnection(connection: SumiConnection) {
49
+ if (this.invokers.length === 0) {
50
+ this.deferred.resolve();
63
51
  }
64
- this.connection.push(channel);
65
- const index = this.connection.length - 1;
66
52
 
67
- const rpcProxy = new ProxyLegacy(this.serviceMethodMap, this.logger);
68
- const connection = channel.createMessageConnection();
69
- rpcProxy.listen(connection);
53
+ const index = this.invokers.length - 1;
70
54
 
71
55
  const invoker = new Invoker();
72
56
 
73
- invoker.setLegacyProxy(rpcProxy);
57
+ const sumiProxy = new ProxySumi(this.registry, this.logger);
58
+ invoker.attachSumi(sumiProxy);
59
+ sumiProxy.listen(connection);
74
60
 
75
61
  this.invokers.push(invoker);
76
62
 
77
63
  return {
78
64
  dispose: () => {
79
- this.connection.splice(index, 1);
80
65
  this.invokers.splice(index, 1);
81
- connection.dispose();
66
+ invoker.dispose();
82
67
  },
83
68
  };
84
69
  }
85
70
 
86
- onRequest(serviceName: string, _name: string, method: RPCServiceMethod) {
87
- const name = getMethodName(serviceName, _name);
88
- if (!this.connection.length) {
89
- this.serviceMethodMap[name] = method;
90
- } else {
91
- this.invokers.forEach((proxy) => {
92
- proxy.legacyProxy.listenService({ [name]: method });
93
- });
71
+ setConnection(connection: MessageConnection) {
72
+ if (this.invokers.length === 0) {
73
+ this.deferred.resolve();
94
74
  }
75
+
76
+ const index = this.invokers.length - 1;
77
+
78
+ const invoker = new Invoker();
79
+
80
+ const legacyProxy = new ProxyLegacy(this.registry, this.logger);
81
+ legacyProxy.listen(connection);
82
+
83
+ invoker.attachLegacy(legacyProxy);
84
+
85
+ this.invokers.push(invoker);
86
+
87
+ return {
88
+ dispose: () => {
89
+ this.invokers.splice(index, 1);
90
+ invoker.dispose();
91
+ },
92
+ };
93
+ }
94
+
95
+ onRequest(serviceName: string, _name: string, method: RPCServiceMethod) {
96
+ this.registry.register(getMethodName(serviceName, _name), method);
97
+ }
98
+
99
+ onRequestService(serviceName: string, service: any) {
100
+ this.registry.registerService(service, {
101
+ nameConverter: (name) => getMethodName(serviceName, name),
102
+ });
95
103
  }
96
104
 
97
105
  async broadcast(serviceName: string, _name: string, ...args: any[]): Promise<any> {
106
+ await this.ready();
107
+
98
108
  const name = getMethodName(serviceName, _name);
99
109
  const broadcastResult = await Promise.all(this.invokers.map((proxy) => proxy.invoke(name, ...args)));
100
110
 
@@ -117,8 +127,8 @@ export class RPCServiceCenter {
117
127
  }
118
128
 
119
129
  // FIXME: this is an unreasonable design, if remote service only returned doubtful result, we will return an empty array.
120
- // but actually we should throw an error to tell user that no remote service can handle this call.
121
- // or just return `undefined`.
130
+ // but actually we should throw an error to tell user that no remote service can handle this call.
131
+ // or just return `undefined`.
122
132
  return result.length === 1 ? result[0] : result;
123
133
  }
124
134
  }
@@ -1,2 +1,11 @@
1
1
  export * from './stub';
2
2
  export * from './center';
3
+
4
+ export abstract class RPCService<T = any> {
5
+ rpcClient?: T[];
6
+ rpcRegistered?: boolean;
7
+ register?(): () => Promise<T>;
8
+ get client() {
9
+ return this.rpcClient ? this.rpcClient[0] : undefined;
10
+ }
11
+ }