@opensumi/ide-connection 2.27.3-next-1706520813.0 → 2.27.3-rc-1706687185.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 (158) hide show
  1. package/lib/browser/ws-channel-handler.d.ts +9 -7
  2. package/lib/browser/ws-channel-handler.d.ts.map +1 -1
  3. package/lib/browser/ws-channel-handler.js +65 -64
  4. package/lib/browser/ws-channel-handler.js.map +1 -1
  5. package/lib/common/connect.d.ts +6 -57
  6. package/lib/common/connect.d.ts.map +1 -1
  7. package/lib/common/connect.js +9 -168
  8. package/lib/common/connect.js.map +1 -1
  9. package/lib/common/connection/buffers.d.ts +55 -0
  10. package/lib/common/connection/buffers.d.ts.map +1 -0
  11. package/lib/common/connection/buffers.js +244 -0
  12. package/lib/common/connection/buffers.js.map +1 -0
  13. package/lib/common/connection/drivers/base.d.ts +9 -0
  14. package/lib/common/connection/drivers/base.d.ts.map +1 -0
  15. package/lib/common/connection/drivers/base.js +11 -0
  16. package/lib/common/connection/drivers/base.js.map +1 -0
  17. package/lib/common/connection/drivers/empty.d.ts +8 -0
  18. package/lib/common/connection/drivers/empty.d.ts.map +1 -0
  19. package/lib/common/connection/drivers/empty.js +21 -0
  20. package/lib/common/connection/drivers/empty.js.map +1 -0
  21. package/lib/common/connection/drivers/index.d.ts +6 -0
  22. package/lib/common/connection/drivers/index.d.ts.map +1 -0
  23. package/lib/common/connection/drivers/index.js +9 -0
  24. package/lib/common/connection/drivers/index.js.map +1 -0
  25. package/lib/common/connection/drivers/node-message-port.d.ts +12 -0
  26. package/lib/common/connection/drivers/node-message-port.d.ts.map +1 -0
  27. package/lib/common/connection/drivers/node-message-port.js +31 -0
  28. package/lib/common/connection/drivers/node-message-port.js.map +1 -0
  29. package/lib/common/connection/drivers/reconnecting-websocket.d.ts +15 -0
  30. package/lib/common/connection/drivers/reconnecting-websocket.d.ts.map +1 -0
  31. package/lib/common/connection/drivers/reconnecting-websocket.js +83 -0
  32. package/lib/common/connection/drivers/reconnecting-websocket.js.map +1 -0
  33. package/lib/common/connection/drivers/socket.d.ts +17 -0
  34. package/lib/common/connection/drivers/socket.d.ts.map +1 -0
  35. package/lib/common/connection/drivers/socket.js +56 -0
  36. package/lib/common/connection/drivers/socket.js.map +1 -0
  37. package/lib/common/connection/drivers/stream-decoder.d.ts +67 -0
  38. package/lib/common/connection/drivers/stream-decoder.d.ts.map +1 -0
  39. package/lib/common/connection/drivers/stream-decoder.js +171 -0
  40. package/lib/common/connection/drivers/stream-decoder.js.map +1 -0
  41. package/lib/common/connection/drivers/utils.d.ts +12 -0
  42. package/lib/common/connection/drivers/utils.d.ts.map +1 -0
  43. package/lib/common/connection/drivers/utils.js +49 -0
  44. package/lib/common/connection/drivers/utils.js.map +1 -0
  45. package/lib/common/connection/drivers/ws-websocket.d.ts +11 -0
  46. package/lib/common/connection/drivers/ws-websocket.d.ts.map +1 -0
  47. package/lib/common/connection/drivers/ws-websocket.js +31 -0
  48. package/lib/common/connection/drivers/ws-websocket.js.map +1 -0
  49. package/lib/common/connection/index.d.ts +2 -0
  50. package/lib/common/connection/index.d.ts.map +1 -0
  51. package/lib/common/connection/index.js +5 -0
  52. package/lib/common/connection/index.js.map +1 -0
  53. package/lib/common/connection/types.d.ts +7 -0
  54. package/lib/common/connection/types.d.ts.map +1 -0
  55. package/lib/common/connection/types.js +3 -0
  56. package/lib/common/connection/types.js.map +1 -0
  57. package/lib/common/constants.d.ts +2 -0
  58. package/lib/common/constants.d.ts.map +1 -0
  59. package/lib/common/constants.js +5 -0
  60. package/lib/common/constants.js.map +1 -0
  61. package/lib/common/{rpcProtocol.d.ts → ext-rpc-protocol.d.ts} +10 -11
  62. package/lib/common/ext-rpc-protocol.d.ts.map +1 -0
  63. package/lib/common/{rpcProtocol.js → ext-rpc-protocol.js} +22 -19
  64. package/lib/common/ext-rpc-protocol.js.map +1 -0
  65. package/lib/common/index.d.ts +2 -1
  66. package/lib/common/index.d.ts.map +1 -1
  67. package/lib/common/index.js +2 -1
  68. package/lib/common/index.js.map +1 -1
  69. package/lib/common/proxy/base.d.ts +22 -0
  70. package/lib/common/proxy/base.d.ts.map +1 -0
  71. package/lib/common/proxy/base.js +47 -0
  72. package/lib/common/proxy/base.js.map +1 -0
  73. package/lib/common/proxy/index.d.ts +8 -0
  74. package/lib/common/proxy/index.d.ts.map +1 -0
  75. package/lib/common/proxy/index.js +12 -0
  76. package/lib/common/proxy/index.js.map +1 -0
  77. package/lib/common/proxy/legacy.d.ts +23 -0
  78. package/lib/common/proxy/legacy.d.ts.map +1 -0
  79. package/lib/common/proxy/legacy.js +183 -0
  80. package/lib/common/proxy/legacy.js.map +1 -0
  81. package/lib/common/rpc-service/center.d.ts +20 -0
  82. package/lib/common/rpc-service/center.d.ts.map +1 -0
  83. package/lib/common/rpc-service/center.js +100 -0
  84. package/lib/common/rpc-service/center.js.map +1 -0
  85. package/lib/common/rpc-service/index.d.ts +3 -0
  86. package/lib/common/rpc-service/index.d.ts.map +1 -0
  87. package/lib/common/rpc-service/index.js +6 -0
  88. package/lib/common/rpc-service/index.js.map +1 -0
  89. package/lib/common/rpc-service/stub.d.ts +15 -0
  90. package/lib/common/rpc-service/stub.d.ts.map +1 -0
  91. package/lib/common/rpc-service/stub.js +48 -0
  92. package/lib/common/rpc-service/stub.js.map +1 -0
  93. package/lib/common/types.d.ts +15 -0
  94. package/lib/common/types.d.ts.map +1 -0
  95. package/lib/common/types.js +9 -0
  96. package/lib/common/types.js.map +1 -0
  97. package/lib/common/utils.d.ts +4 -2
  98. package/lib/common/utils.d.ts.map +1 -1
  99. package/lib/common/utils.js +32 -9
  100. package/lib/common/utils.js.map +1 -1
  101. package/lib/common/ws-channel.d.ts +104 -27
  102. package/lib/common/ws-channel.d.ts.map +1 -1
  103. package/lib/common/ws-channel.js +96 -27
  104. package/lib/common/ws-channel.js.map +1 -1
  105. package/lib/node/common-channel-handler.d.ts +18 -16
  106. package/lib/node/common-channel-handler.d.ts.map +1 -1
  107. package/lib/node/common-channel-handler.js +42 -59
  108. package/lib/node/common-channel-handler.js.map +1 -1
  109. package/lib/node/index.d.ts +0 -3
  110. package/lib/node/index.d.ts.map +1 -1
  111. package/lib/node/index.js +0 -5
  112. package/lib/node/index.js.map +1 -1
  113. package/lib/node/ws.d.ts +1 -1
  114. package/lib/node/ws.d.ts.map +1 -1
  115. package/lib/node/ws.js +2 -0
  116. package/lib/node/ws.js.map +1 -1
  117. package/package.json +9 -7
  118. package/src/browser/ws-channel-handler.ts +82 -70
  119. package/src/common/connect.ts +7 -193
  120. package/src/common/connection/buffers.ts +284 -0
  121. package/src/common/connection/drivers/base.ts +15 -0
  122. package/src/common/connection/drivers/empty.ts +19 -0
  123. package/src/common/connection/drivers/index.ts +5 -0
  124. package/src/common/connection/drivers/node-message-port.ts +33 -0
  125. package/src/common/connection/drivers/reconnecting-websocket.ts +86 -0
  126. package/src/common/connection/drivers/socket.ts +62 -0
  127. package/src/common/connection/drivers/stream-decoder.ts +196 -0
  128. package/src/common/connection/drivers/utils.ts +52 -0
  129. package/src/common/connection/drivers/ws-websocket.ts +31 -0
  130. package/src/common/connection/index.ts +1 -0
  131. package/src/common/connection/types.ts +7 -0
  132. package/src/common/constants.ts +1 -0
  133. package/src/common/{rpcProtocol.ts → ext-rpc-protocol.ts} +43 -31
  134. package/src/common/index.ts +2 -1
  135. package/src/common/proxy/base.ts +67 -0
  136. package/src/common/proxy/index.ts +10 -0
  137. package/src/common/proxy/legacy.ts +200 -0
  138. package/src/common/rpc-service/center.ts +124 -0
  139. package/src/common/rpc-service/index.ts +2 -0
  140. package/src/common/rpc-service/stub.ts +49 -0
  141. package/src/common/types.ts +17 -0
  142. package/src/common/utils.ts +31 -8
  143. package/src/common/ws-channel.ts +175 -48
  144. package/src/node/common-channel-handler.ts +68 -80
  145. package/src/node/index.ts +0 -5
  146. package/src/node/ws.ts +3 -1
  147. package/lib/common/proxy.d.ts +0 -47
  148. package/lib/common/proxy.d.ts.map +0 -1
  149. package/lib/common/proxy.js +0 -272
  150. package/lib/common/proxy.js.map +0 -1
  151. package/lib/common/rpcProtocol.d.ts.map +0 -1
  152. package/lib/common/rpcProtocol.js.map +0 -1
  153. package/lib/node/connect.d.ts +0 -4
  154. package/lib/node/connect.d.ts.map +0 -1
  155. package/lib/node/connect.js +0 -9
  156. package/lib/node/connect.js.map +0 -1
  157. package/src/common/proxy.ts +0 -303
  158. package/src/node/connect.ts +0 -11
@@ -0,0 +1,62 @@
1
+ import type net from 'net';
2
+
3
+ import { IDisposable } from '@opensumi/ide-core-common';
4
+
5
+ import { BaseConnection } from './base';
6
+ import { StreamPacketDecoder, createStreamPacket } from './stream-decoder';
7
+
8
+ export class NetSocketConnection extends BaseConnection<Uint8Array> {
9
+ protected decoder = new StreamPacketDecoder();
10
+
11
+ constructor(private socket: net.Socket) {
12
+ super();
13
+ this.socket.on('data', (chunk) => {
14
+ this.decoder.push(chunk);
15
+ });
16
+ this.socket.once('close', () => {
17
+ this.decoder.dispose();
18
+ });
19
+ }
20
+
21
+ isOpen(): boolean {
22
+ return this.socket.readyState === 'open';
23
+ }
24
+
25
+ send(data: Uint8Array): void {
26
+ this.socket.write(createStreamPacket(data));
27
+ }
28
+
29
+ onMessage(cb: (data: Uint8Array) => void): IDisposable {
30
+ const dispose = this.decoder.onData(cb);
31
+ return {
32
+ dispose,
33
+ };
34
+ }
35
+
36
+ onceClose(cb: () => void): IDisposable {
37
+ this.socket.once('close', cb);
38
+ return {
39
+ dispose: () => {
40
+ this.socket.off('close', cb);
41
+ },
42
+ };
43
+ }
44
+
45
+ onOpen(cb: () => void): IDisposable {
46
+ this.socket.on('connect', cb);
47
+ return {
48
+ dispose: () => {
49
+ this.socket.off('connect', cb);
50
+ },
51
+ };
52
+ }
53
+
54
+ onError(cb: (err: Error) => void): IDisposable {
55
+ this.socket.on('error', cb);
56
+ return {
57
+ dispose: () => {
58
+ this.socket.off('error', cb);
59
+ },
60
+ };
61
+ }
62
+ }
@@ -0,0 +1,196 @@
1
+ import { BinaryReader } from '@furyjs/fury/dist/lib/reader';
2
+ import { BinaryWriter } from '@furyjs/fury/dist/lib/writer';
3
+
4
+ import { EventEmitter } from '@opensumi/events';
5
+
6
+ import { Buffers } from '../buffers';
7
+
8
+ /**
9
+ * You can use `Buffer.from('Sumi')` to get this magic number
10
+ */
11
+ export const kMagicNumber = 0x53756d69;
12
+
13
+ const writer = BinaryWriter({});
14
+
15
+ /**
16
+ * When we send data through net.Socket, the data is not guaranteed to be sent as a whole.
17
+ *
18
+ * So we need to add a header to the data, so that the receiver can know the length of the data,
19
+ * The header is 4 bytes, the first 4 bytes is a magic number, which is `Sumi` in little endian.
20
+ * use magic number can help us to detect the start of the packet in the stream.
21
+ *
22
+ * The next 4 bytes is a varUInt32, which means the length of the following data, and
23
+ * the following data is the content.
24
+ */
25
+ export function createStreamPacket(content: Uint8Array) {
26
+ writer.reset();
27
+ writer.uint32(kMagicNumber);
28
+ writer.varUInt32(content.byteLength);
29
+ writer.buffer(content);
30
+ return writer.dump();
31
+ }
32
+
33
+ export class StreamPacketDecoder {
34
+ protected emitter = new EventEmitter<{
35
+ data: [Uint8Array];
36
+ }>();
37
+
38
+ protected buffers = new Buffers();
39
+ protected cursor = this.buffers.cursor();
40
+
41
+ protected reader = BinaryReader({});
42
+
43
+ protected state = 0;
44
+ protected contentLength = 0;
45
+
46
+ reset() {
47
+ this.state = 0;
48
+ this.contentLength = 0;
49
+
50
+ this.cursor.reset();
51
+ }
52
+
53
+ push(chunk: Uint8Array): void {
54
+ this.buffers.push(chunk);
55
+ let done = false;
56
+
57
+ while (!done) {
58
+ done = this.readPacket();
59
+ }
60
+ }
61
+
62
+ protected readPacket(): boolean {
63
+ const found = this.readHeader();
64
+
65
+ if (found) {
66
+ const start = this.cursor.offset;
67
+ const end = start + this.contentLength;
68
+
69
+ const binary = this.buffers.slice(start, end);
70
+
71
+ this.emitter.emit('data', binary);
72
+
73
+ if (this.buffers.byteLength > end) {
74
+ this.cursor.moveTo(end);
75
+ this.state = 0;
76
+ this.contentLength = 0;
77
+ // has more data, continue to parse
78
+ return false;
79
+ }
80
+
81
+ // delete used buffers
82
+ this.buffers.splice(0, end);
83
+ this.reset();
84
+ }
85
+
86
+ return true;
87
+ }
88
+
89
+ /**
90
+ * First we read the first 4 bytes, if it is not magic 4 bytes
91
+ * discard it and continue to read the next byte until we get magic 4 bytes
92
+ * Then read the next byte, this is a varUint32, which means the length of the following data
93
+ * Then read the following data, until we get the length of varUint32, then return this data and continue to read the next packet
94
+ */
95
+ protected readHeader() {
96
+ if (this.buffers.byteLength === 0) {
97
+ return false;
98
+ }
99
+
100
+ if (this.state !== 4) {
101
+ this.readMagicNumber();
102
+ }
103
+
104
+ if (this.state !== 4) {
105
+ // Not enough data yet, wait for more data
106
+ return false;
107
+ }
108
+
109
+ if (this.cursor.offset + 4 > this.buffers.byteLength) {
110
+ // Not enough data yet, wait for more data
111
+ return false;
112
+ }
113
+
114
+ if (!this.contentLength) {
115
+ // read the content length
116
+ const buffers = this.buffers.slice(this.cursor.offset, this.cursor.offset + 4);
117
+ this.reader.reset(buffers);
118
+ this.contentLength = this.reader.varUInt32();
119
+ this.cursor.move(this.reader.getCursor());
120
+ }
121
+
122
+ if (this.cursor.offset + this.contentLength > this.buffers.byteLength) {
123
+ // Not enough data yet, wait for more data
124
+ return false;
125
+ }
126
+
127
+ return true;
128
+ }
129
+
130
+ protected readMagicNumber() {
131
+ const iter = this.cursor.iterator();
132
+
133
+ let result = iter.next();
134
+ while (!result.done) {
135
+ // Fury use little endian to store data
136
+ switch (result.value) {
137
+ case 0x69:
138
+ switch (this.state) {
139
+ case 0:
140
+ this.state = 1;
141
+ break;
142
+ default:
143
+ this.state = 0;
144
+ break;
145
+ }
146
+ break;
147
+ case 0x6d:
148
+ switch (this.state) {
149
+ case 1:
150
+ this.state = 2;
151
+ break;
152
+ default:
153
+ this.state = 0;
154
+ break;
155
+ }
156
+ break;
157
+ case 0x75:
158
+ switch (this.state) {
159
+ case 2:
160
+ this.state = 3;
161
+ break;
162
+ default:
163
+ this.state = 0;
164
+ break;
165
+ }
166
+ break;
167
+ case 0x53:
168
+ switch (this.state) {
169
+ case 3:
170
+ this.state = 4;
171
+ iter.return();
172
+ break;
173
+ default:
174
+ this.state = 0;
175
+ break;
176
+ }
177
+ break;
178
+ default:
179
+ this.state = 0;
180
+ break;
181
+ }
182
+ result = iter.next();
183
+ }
184
+ }
185
+
186
+ onData(cb: (data: Uint8Array) => void) {
187
+ return this.emitter.on('data', cb);
188
+ }
189
+
190
+ dispose() {
191
+ this.reader = BinaryReader({});
192
+ this.emitter.dispose();
193
+ this.buffers.dispose();
194
+ this.cursor.dispose();
195
+ }
196
+ }
@@ -0,0 +1,52 @@
1
+ import { Emitter } from '@opensumi/ide-core-common';
2
+
3
+ import { IConnectionShape } from '../types';
4
+
5
+ export class EventQueue<T> {
6
+ emitter = new Emitter<T>();
7
+
8
+ queue: T[] = [];
9
+
10
+ isOpened = false;
11
+ open() {
12
+ this.isOpened = true;
13
+ this.queue.forEach((data) => {
14
+ this.emitter.fire(data);
15
+ });
16
+ this.queue = [];
17
+ }
18
+
19
+ push(data: T) {
20
+ if (this.isOpened) {
21
+ this.emitter.fire(data);
22
+ } else {
23
+ this.queue.push(data);
24
+ }
25
+ }
26
+
27
+ on(cb: (data: T) => void) {
28
+ const disposable = this.emitter.event(cb);
29
+
30
+ if (!this.isOpened) {
31
+ this.open();
32
+ }
33
+
34
+ return disposable;
35
+ }
36
+ }
37
+
38
+ export const createQueue = <T>(socket: IConnectionShape<T>): IConnectionShape<T> => {
39
+ const queue = new EventQueue<T>();
40
+
41
+ socket.onMessage((data) => {
42
+ queue.push(data);
43
+ });
44
+
45
+ return {
46
+ send: (data) => {
47
+ socket.send(data);
48
+ },
49
+ onMessage: (cb) => queue.on(cb),
50
+ onceClose: (cb) => socket.onceClose(cb),
51
+ };
52
+ };
@@ -0,0 +1,31 @@
1
+ import type WebSocket from 'ws';
2
+
3
+ import { IDisposable } from '@opensumi/ide-core-common';
4
+
5
+ import { BaseConnection } from './base';
6
+
7
+ export class WSWebSocketConnection extends BaseConnection<Uint8Array> {
8
+ constructor(public socket: WebSocket) {
9
+ super();
10
+ }
11
+ send(data: Uint8Array): void {
12
+ this.socket.send(data);
13
+ }
14
+
15
+ onMessage(cb: (data: Uint8Array) => void): IDisposable {
16
+ this.socket.on('message', cb);
17
+ return {
18
+ dispose: () => {
19
+ this.socket.off('message', cb);
20
+ },
21
+ };
22
+ }
23
+ onceClose(cb: () => void): IDisposable {
24
+ this.socket.once('close', cb);
25
+ return {
26
+ dispose: () => {
27
+ this.socket.off('close', cb);
28
+ },
29
+ };
30
+ }
31
+ }
@@ -0,0 +1 @@
1
+ export * from './drivers';
@@ -0,0 +1,7 @@
1
+ import { IDisposable } from '@opensumi/ide-core-common';
2
+
3
+ export interface IConnectionShape<T> {
4
+ send(data: T): void;
5
+ onMessage: (cb: (data: T) => void) => IDisposable;
6
+ onceClose: (cb: () => void) => IDisposable;
7
+ }
@@ -0,0 +1 @@
1
+ export const METHOD_NOT_REGISTERED = '$$METHOD_NOT_REGISTERED';
@@ -1,4 +1,17 @@
1
- import { CancellationToken, CancellationTokenSource, Deferred, Event, Uri } from '@opensumi/ide-core-common';
1
+ import {
2
+ CancellationToken,
3
+ CancellationTokenSource,
4
+ Deferred,
5
+ Emitter,
6
+ Event,
7
+ SerializedError,
8
+ Uri,
9
+ transformErrorForSerialization,
10
+ } from '@opensumi/ide-core-common';
11
+
12
+ import { ILogger } from './types';
13
+ import { WSChannel } from './ws-channel';
14
+
2
15
  // Uri: vscode 中的 uri
3
16
  // URI: 在 vscode 中的 uri 基础上包装了一些基础方法
4
17
 
@@ -7,30 +20,6 @@ export enum RPCProtocolEnv {
7
20
  EXT,
8
21
  }
9
22
 
10
- export interface SerializedError {
11
- readonly $isError: true;
12
- readonly name: string;
13
- readonly message: string;
14
- readonly stack: string;
15
- }
16
-
17
- export function transformErrorForSerialization(error: Error): SerializedError;
18
- export function transformErrorForSerialization(error: any): any;
19
- export function transformErrorForSerialization(error: any): any {
20
- if (error instanceof Error) {
21
- const { name, message } = error;
22
- const stack: string = (error as any).stacktrace || (error as any).stack;
23
- return {
24
- $isError: true,
25
- name,
26
- message,
27
- stack,
28
- };
29
- }
30
-
31
- return error;
32
- }
33
-
34
23
  export interface IProxyIdentifier {
35
24
  serviceId: string;
36
25
  countId: number;
@@ -56,7 +45,7 @@ export function createMainContextProxyIdentifier<T>(identifier: string): ProxyId
56
45
  return result;
57
46
  }
58
47
  export interface IMessagePassingProtocol {
59
- send(msg): void;
48
+ send(msg: string): void;
60
49
  onMessage: Event<string>;
61
50
  timeout?: number;
62
51
  }
@@ -212,9 +201,9 @@ export class RPCProtocol implements IRPCProtocol {
212
201
  private readonly _timeoutHandles: Map<string, NodeJS.Timeout | number>;
213
202
  private _lastMessageId: number;
214
203
  private _pendingRPCReplies: Map<string, Deferred<any>>;
215
- private logger;
204
+ private logger: ILogger;
216
205
 
217
- constructor(connection: IMessagePassingProtocol, logger?: any) {
206
+ constructor(connection: IMessagePassingProtocol, logger?: ILogger) {
218
207
  this._protocol = connection;
219
208
  this._locals = new Map();
220
209
  this._proxies = new Map();
@@ -290,8 +279,8 @@ export class RPCProtocol implements IRPCProtocol {
290
279
  return result.promise;
291
280
  }
292
281
 
293
- private _receiveOneMessage(rawmsg: string): void {
294
- const msg = JSON.parse(rawmsg, ObjectTransfer.reviver);
282
+ private _receiveOneMessage(rawMsg: string): void {
283
+ const msg = JSON.parse(rawMsg, ObjectTransfer.reviver);
295
284
 
296
285
  if (this._timeoutHandles.has(msg.id)) {
297
286
  // 忽略一些 jest 测试场景 clearTimeout not defined 的问题
@@ -410,6 +399,29 @@ export class RPCProtocol implements IRPCProtocol {
410
399
  this._pendingRPCReplies.delete(callId);
411
400
  this._timeoutHandles.delete(callId);
412
401
 
413
- pendingReply.reject(new Error('RPC Timeout: '+ callId));
402
+ pendingReply.reject(new Error('RPC Timeout: ' + callId));
414
403
  }
415
404
  }
405
+
406
+ interface RPCProtocolCreateOptions {
407
+ timeout?: number;
408
+ }
409
+
410
+ export function createRPCProtocol(channel: WSChannel, options: RPCProtocolCreateOptions = {}): RPCProtocol {
411
+ const onMessageEmitter = new Emitter<string>();
412
+ channel.onMessage((msg: string) => {
413
+ onMessageEmitter.fire(msg);
414
+ });
415
+
416
+ const onMessage = onMessageEmitter.event;
417
+ const send = (msg: string) => {
418
+ channel.send(msg);
419
+ };
420
+
421
+ const mainThreadProtocol = new RPCProtocol({
422
+ onMessage,
423
+ send,
424
+ timeout: options.timeout,
425
+ });
426
+ return mainThreadProtocol;
427
+ }
@@ -1,6 +1,7 @@
1
1
  export * from './message';
2
2
  export * from './proxy';
3
- export * from './rpcProtocol';
3
+ export * from './ext-rpc-protocol';
4
4
  export * from './utils';
5
5
  export * from './ws-channel';
6
6
  export * from './connect';
7
+ export * from './types';
@@ -0,0 +1,67 @@
1
+ import { Deferred, isDefined } from '@opensumi/ide-core-common';
2
+
3
+ import { ILogger, IRPCServiceMap } from '../types';
4
+ import { ICapturedMessage, getCapturer, getServiceMethods } from '../utils';
5
+
6
+ interface IBaseConnection {
7
+ listen(): void;
8
+ }
9
+
10
+ export abstract class ProxyBase<T extends IBaseConnection> {
11
+ protected proxyService: any = {};
12
+
13
+ protected logger: ILogger;
14
+ protected connection: T;
15
+
16
+ protected connectionPromise: Deferred<void> = new Deferred<void>();
17
+
18
+ protected abstract engine: 'legacy';
19
+
20
+ constructor(public target?: IRPCServiceMap, logger?: ILogger) {
21
+ this.logger = logger || console;
22
+ }
23
+
24
+ // capture messages for opensumi devtools
25
+ protected capture(message: ICapturedMessage): void {
26
+ const capturer = getCapturer();
27
+ if (isDefined(capturer)) {
28
+ capturer({
29
+ ...message,
30
+ engine: this.engine,
31
+ });
32
+ }
33
+ }
34
+
35
+ listen(connection: T): void {
36
+ this.connection = connection;
37
+
38
+ if (this.target) {
39
+ this.listenService(this.target);
40
+ }
41
+
42
+ connection.listen();
43
+ this.connectionPromise.resolve();
44
+ }
45
+
46
+ public listenService(service: IRPCServiceMap) {
47
+ if (this.connection) {
48
+ this.bindOnRequest(service, (service, prop) => {
49
+ this.proxyService[prop] = service[prop].bind(service);
50
+ });
51
+ } else {
52
+ if (!this.target) {
53
+ this.target = {} as any;
54
+ }
55
+
56
+ const methods = getServiceMethods(service);
57
+ for (const method of methods) {
58
+ // `getServiceMethods` ensure that method is a function
59
+ (this.target as any)[method] = service[method]!.bind(service);
60
+ }
61
+ }
62
+ }
63
+
64
+ abstract getInvokeProxy(): any;
65
+
66
+ protected abstract bindOnRequest(service: IRPCServiceMap, cb: (service: IRPCServiceMap, prop: string) => void): void;
67
+ }
@@ -0,0 +1,10 @@
1
+ export * from './legacy';
2
+
3
+ export abstract class RPCService<T = any> {
4
+ rpcClient?: T[];
5
+ rpcRegistered?: boolean;
6
+ register?(): () => Promise<T>;
7
+ get client() {
8
+ return this.rpcClient ? this.rpcClient[0] : undefined;
9
+ }
10
+ }