@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,200 @@
1
+ import { uuid } from '@opensumi/ide-core-common';
2
+ import { MessageConnection } from '@opensumi/vscode-jsonrpc';
3
+
4
+ import { METHOD_NOT_REGISTERED } from '../constants';
5
+ import { IRPCServiceMap } from '../types';
6
+ import { MessageType, ResponseStatus, getServiceMethods } from '../utils';
7
+
8
+ import { ProxyBase } from './base';
9
+
10
+ interface IRPCResult {
11
+ error: boolean;
12
+ data: any;
13
+ }
14
+
15
+ export class ProxyLegacy extends ProxyBase<MessageConnection> {
16
+ engine = 'legacy' as const;
17
+
18
+ public getInvokeProxy(): any {
19
+ return new Proxy(this, this);
20
+ }
21
+
22
+ public get(target: any, p: PropertyKey) {
23
+ const prop = p.toString();
24
+ return async (...args: any[]) => {
25
+ await this.connectionPromise.promise;
26
+
27
+ let isSingleArray = false;
28
+ if (args.length === 1 && Array.isArray(args[0])) {
29
+ isSingleArray = true;
30
+ }
31
+
32
+ // 调用方法为 on 开头时,作为单项通知
33
+ if (prop.startsWith('on')) {
34
+ if (isSingleArray) {
35
+ this.connection.sendNotification(prop, [...args]);
36
+ } else {
37
+ this.connection.sendNotification(prop, ...args);
38
+ }
39
+ this.capture({ type: MessageType.SendNotification, serviceMethod: prop, arguments: args });
40
+ } else {
41
+ let requestResult: Promise<any>;
42
+ // generate a unique requestId to associate request and requestResult
43
+ const requestId = uuid();
44
+
45
+ if (isSingleArray) {
46
+ requestResult = this.connection.sendRequest(prop, [...args]) as Promise<any>;
47
+ } else {
48
+ requestResult = this.connection.sendRequest(prop, ...args) as Promise<any>;
49
+ }
50
+
51
+ this.capture({ type: MessageType.SendRequest, requestId, serviceMethod: prop, arguments: args });
52
+
53
+ const result: IRPCResult = await requestResult;
54
+
55
+ if (result.error) {
56
+ const error = new Error(result.data.message);
57
+ if (result.data.stack) {
58
+ error.stack = result.data.stack;
59
+ }
60
+ this.capture({
61
+ type: MessageType.RequestResult,
62
+ status: ResponseStatus.Fail,
63
+ requestId,
64
+ serviceMethod: prop,
65
+ error: result.data,
66
+ });
67
+ throw error;
68
+ } else {
69
+ this.capture({
70
+ type: MessageType.RequestResult,
71
+ status: ResponseStatus.Success,
72
+ requestId,
73
+ serviceMethod: prop,
74
+ data: result.data,
75
+ });
76
+ return result.data;
77
+ }
78
+ }
79
+ };
80
+ }
81
+
82
+ protected bindOnRequest(service: IRPCServiceMap, cb?: ((service: IRPCServiceMap, prop: string) => void) | undefined) {
83
+ if (this.connection) {
84
+ const connection = this.connection;
85
+
86
+ const methods = getServiceMethods(service);
87
+
88
+ methods.forEach((method) => {
89
+ if (method.startsWith('on')) {
90
+ connection.onNotification(method, (...args) => {
91
+ this.onNotification(method, ...args);
92
+ this.capture({ type: MessageType.OnNotification, serviceMethod: method, arguments: args });
93
+ });
94
+ } else {
95
+ connection.onRequest(method, (...args) => {
96
+ const requestId = uuid();
97
+ const result = this.onRequest(method, ...args);
98
+ this.capture({ type: MessageType.OnRequest, requestId, serviceMethod: method, arguments: args });
99
+
100
+ result
101
+ .then((result) => {
102
+ this.capture({
103
+ type: MessageType.OnRequestResult,
104
+ status: ResponseStatus.Success,
105
+ requestId,
106
+ serviceMethod: method,
107
+ data: result.data,
108
+ });
109
+ })
110
+ .catch((err) => {
111
+ this.capture({
112
+ type: MessageType.OnRequestResult,
113
+ status: ResponseStatus.Fail,
114
+ requestId,
115
+ serviceMethod: method,
116
+ error: err.data,
117
+ });
118
+ });
119
+
120
+ return result;
121
+ });
122
+ }
123
+
124
+ if (cb) {
125
+ cb(service, method);
126
+ }
127
+ });
128
+ }
129
+ }
130
+
131
+ /**
132
+ * 对于纯数组参数的情况,收到请求/通知后做展开操作
133
+ * 因为在通信层会为每个 rpc 调用添加一个 CancellationToken 参数
134
+ * 如果参数本身是数组, 在方法中如果使用 spread 运算符获取参数(...args),则会出现 [...args, MutableToken] 这种情况
135
+ * 所以发送请求时将这类参数统一再用数组包了一层,形如 [[...args]], 参考 {@link ProxyLegacy.get get} 方法
136
+ * 此时接收到的数组类参数固定长度为 2,且最后一项一定是 MutableToken
137
+ * @param args
138
+ * @returns args
139
+ */
140
+ private serializeArguments(args: any[]): any[] {
141
+ const maybeCancellationToken = args[args.length - 1];
142
+ if (
143
+ args.length === 2 &&
144
+ Array.isArray(args[0]) &&
145
+ Object.prototype.hasOwnProperty.call(maybeCancellationToken, '_isCancelled')
146
+ ) {
147
+ return [...args[0], maybeCancellationToken];
148
+ }
149
+
150
+ return args;
151
+ }
152
+
153
+ private async onRequest(prop: PropertyKey, ...args: any[]) {
154
+ try {
155
+ const result = await this.proxyService[prop](...this.serializeArguments(args));
156
+
157
+ return {
158
+ error: false,
159
+ data: result,
160
+ };
161
+ } catch (e) {
162
+ return {
163
+ error: true,
164
+ data: {
165
+ message: e.message,
166
+ stack: e.stack,
167
+ },
168
+ };
169
+ }
170
+ }
171
+
172
+ private onNotification(prop: PropertyKey, ...args: any[]) {
173
+ try {
174
+ this.proxyService[prop](...this.serializeArguments(args));
175
+ } catch (e) {
176
+ this.logger.warn('notification', e);
177
+ }
178
+ }
179
+
180
+ listen(connection: MessageConnection): void {
181
+ super.listen(connection);
182
+ connection.onRequest((method) => {
183
+ if (!this.proxyService[method]) {
184
+ const requestId = uuid();
185
+ this.capture({ type: MessageType.OnRequest, requestId, serviceMethod: method });
186
+ const result = {
187
+ data: METHOD_NOT_REGISTERED,
188
+ };
189
+ this.capture({
190
+ type: MessageType.OnRequestResult,
191
+ status: ResponseStatus.Fail,
192
+ requestId,
193
+ serviceMethod: method,
194
+ error: result.data,
195
+ });
196
+ return result;
197
+ }
198
+ });
199
+ }
200
+ }
@@ -0,0 +1,124 @@
1
+ import { Deferred } from '@opensumi/ide-core-common';
2
+
3
+ import { METHOD_NOT_REGISTERED } from '../constants';
4
+ import { ProxyLegacy } from '../proxy';
5
+ import { IBench, ILogger, IRPCServiceMap, RPCServiceMethod, ServiceType } from '../types';
6
+ import { getMethodName } from '../utils';
7
+ import { WSChannel } from '../ws-channel';
8
+
9
+ const safeProcess: { pid: string } = typeof process === 'undefined' ? { pid: 'mock' } : (process as any);
10
+
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
+ }
31
+
32
+ export class RPCServiceCenter {
33
+ public uid: string;
34
+
35
+ private invokers: Invoker[] = [];
36
+ private connection: Array<WSChannel> = [];
37
+
38
+ private serviceMethodMap = { client: undefined } as unknown as IRPCServiceMap;
39
+
40
+ private connectionDeferred = new Deferred<void>();
41
+ private logger: ILogger;
42
+
43
+ constructor(private bench?: IBench, logger?: ILogger) {
44
+ this.uid = 'RPCServiceCenter:' + safeProcess.pid;
45
+ this.logger = logger || console;
46
+ }
47
+
48
+ registerService(serviceName: string, type: ServiceType): void {
49
+ if (type === ServiceType.Service) {
50
+ if (this.bench) {
51
+ this.bench.registerService(serviceName);
52
+ }
53
+ }
54
+ }
55
+
56
+ ready() {
57
+ return this.connectionDeferred.promise;
58
+ }
59
+
60
+ setChannel(channel: WSChannel) {
61
+ if (!this.connection.length) {
62
+ this.connectionDeferred.resolve();
63
+ }
64
+ this.connection.push(channel);
65
+ const index = this.connection.length - 1;
66
+
67
+ const rpcProxy = new ProxyLegacy(this.serviceMethodMap, this.logger);
68
+ const connection = channel.createMessageConnection();
69
+ rpcProxy.listen(connection);
70
+
71
+ const invoker = new Invoker();
72
+
73
+ invoker.setLegacyProxy(rpcProxy);
74
+
75
+ this.invokers.push(invoker);
76
+
77
+ return {
78
+ dispose: () => {
79
+ this.connection.splice(index, 1);
80
+ this.invokers.splice(index, 1);
81
+ connection.dispose();
82
+ },
83
+ };
84
+ }
85
+
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
+ });
94
+ }
95
+ }
96
+
97
+ async broadcast(serviceName: string, _name: string, ...args: any[]): Promise<any> {
98
+ const name = getMethodName(serviceName, _name);
99
+ const broadcastResult = await Promise.all(this.invokers.map((proxy) => proxy.invoke(name, ...args)));
100
+
101
+ const doubtfulResult = [] as any[];
102
+ const result = [] as any[];
103
+ for (const i of broadcastResult) {
104
+ if (i === METHOD_NOT_REGISTERED) {
105
+ doubtfulResult.push(i);
106
+ } else {
107
+ result.push(i);
108
+ }
109
+ }
110
+
111
+ if (doubtfulResult.length > 0) {
112
+ this.logger.warn(`broadcast rpc \`${name}\` getting doubtful responses: ${doubtfulResult.join(',')}`);
113
+ }
114
+
115
+ if (result.length === 0) {
116
+ throw new Error(`broadcast rpc \`${name}\` error: no remote service can handle this call`);
117
+ }
118
+
119
+ // 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`.
122
+ return result.length === 1 ? result[0] : result;
123
+ }
124
+ }
@@ -0,0 +1,2 @@
1
+ export * from './stub';
2
+ export * from './center';
@@ -0,0 +1,49 @@
1
+ import { RPCServiceMethod, ServiceType } from '../types';
2
+ import { getServiceMethods } from '../utils';
3
+
4
+ import { RPCServiceCenter } from './center';
5
+
6
+ export class RPCServiceStub {
7
+ constructor(private serviceName: string, private center: RPCServiceCenter, private type: ServiceType) {
8
+ this.center.registerService(serviceName, this.type);
9
+ }
10
+
11
+ async ready() {
12
+ return this.center.ready();
13
+ }
14
+
15
+ on(name: string, method: RPCServiceMethod) {
16
+ this.onRequest(name, method);
17
+ }
18
+
19
+ onRequestService(service: any) {
20
+ const methods = getServiceMethods(service);
21
+ for (const method of methods) {
22
+ this.onRequest(method, service[method].bind(service));
23
+ }
24
+ }
25
+
26
+ onRequest(name: string, method: RPCServiceMethod) {
27
+ this.center.onRequest(this.serviceName, name, method);
28
+ }
29
+
30
+ broadcast(name: string, ...args: any[]): Promise<any> {
31
+ return this.center.broadcast(this.serviceName, name, ...args);
32
+ }
33
+
34
+ getProxy = <T>() =>
35
+ new Proxy<T extends void ? RPCServiceStub : RPCServiceStub & T>(this as any, {
36
+ // 调用方
37
+ get: (target, prop: string) => {
38
+ if (!target[prop]) {
39
+ if (typeof prop === 'symbol') {
40
+ return Promise.resolve();
41
+ } else {
42
+ return (...args: any[]) => this.ready().then(() => this.broadcast(prop, ...args));
43
+ }
44
+ } else {
45
+ return target[prop];
46
+ }
47
+ },
48
+ });
49
+ }
@@ -0,0 +1,17 @@
1
+ export interface ILogger {
2
+ log(...args: any[]): void;
3
+ warn(...args: any[]): void;
4
+ error(...args: any[]): void;
5
+ }
6
+
7
+ export type RPCServiceMethod = (...args: any[]) => any;
8
+ export type IRPCServiceMap = Record<string, RPCServiceMethod>;
9
+
10
+ export enum ServiceType {
11
+ Service,
12
+ Stub,
13
+ }
14
+
15
+ export interface IBench {
16
+ registerService: (service: string) => void;
17
+ }
@@ -41,17 +41,40 @@ export interface WSCloseInfo {
41
41
  connectInfo: ConnectionInfo;
42
42
  }
43
43
 
44
- export function stringify(obj: any): string {
45
- return JSON.stringify(obj);
46
- }
47
-
48
- export function parse(input: string, reviver?: (this: any, key: string, value: any) => any): any {
49
- return JSON.parse(input, reviver);
50
- }
51
-
52
44
  export function getCapturer() {
53
45
  if (typeof window !== 'undefined' && window.__OPENSUMI_DEVTOOLS_GLOBAL_HOOK__?.captureRPC) {
54
46
  return window.__OPENSUMI_DEVTOOLS_GLOBAL_HOOK__.captureRPC;
55
47
  }
56
48
  return;
57
49
  }
50
+
51
+ export function getServiceMethods(service: any): string[] {
52
+ let props: any[] = [];
53
+
54
+ if (/^\s*class/.test(service.constructor.toString())) {
55
+ let obj = service;
56
+ do {
57
+ props = props.concat(Object.getOwnPropertyNames(obj));
58
+ } while ((obj = Object.getPrototypeOf(obj)));
59
+ props = props.sort().filter((e, i, arr) => e !== arr[i + 1] && typeof service[e] === 'function');
60
+ } else {
61
+ for (const prop in service) {
62
+ if (service[prop] && typeof service[prop] === 'function') {
63
+ props.push(prop);
64
+ }
65
+ }
66
+ }
67
+
68
+ return props;
69
+ }
70
+
71
+ export function getNotificationName(serviceName: string, name: string) {
72
+ return `on:${serviceName}:${name}`;
73
+ }
74
+ export function getRequestName(serviceName: string, name: string) {
75
+ return `${serviceName}:${name}`;
76
+ }
77
+
78
+ export function getMethodName(serviceName: string, name: string) {
79
+ return name.startsWith('on') ? getNotificationName(serviceName, name) : getRequestName(serviceName, name);
80
+ }