@x-oasis/async-call-rpc 0.1.38

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 (104) hide show
  1. package/README.md +48 -0
  2. package/dist/async-call-rpc.cjs.development.js +1275 -0
  3. package/dist/async-call-rpc.cjs.development.js.map +1 -0
  4. package/dist/async-call-rpc.cjs.production.min.js +2 -0
  5. package/dist/async-call-rpc.cjs.production.min.js.map +1 -0
  6. package/dist/async-call-rpc.esm.js +1559 -0
  7. package/dist/async-call-rpc.esm.js.map +1 -0
  8. package/dist/buffer/BufferFactory.d.ts +12 -0
  9. package/dist/buffer/DataBuffer.d.ts +2 -0
  10. package/dist/buffer/MessagePackBuffer.d.ts +10 -0
  11. package/dist/buffer/ReadBaseBuffer.d.ts +5 -0
  12. package/dist/buffer/ReadBuffer.d.ts +14 -0
  13. package/dist/buffer/SerializationFormat.d.ts +16 -0
  14. package/dist/buffer/WriteBaseBuffer.d.ts +5 -0
  15. package/dist/buffer/WriteBuffer.d.ts +5 -0
  16. package/dist/buffer/examples.d.ts +10 -0
  17. package/dist/buffer/index.d.ts +8 -0
  18. package/dist/common.d.ts +4 -0
  19. package/dist/endpoint/ProxyRPCClient.d.ts +12 -0
  20. package/dist/endpoint/RPCClientHost.d.ts +12 -0
  21. package/dist/endpoint/RPCService.d.ts +20 -0
  22. package/dist/endpoint/RPCServiceHost.d.ts +10 -0
  23. package/dist/error.d.ts +21 -0
  24. package/dist/index.d.ts +11 -0
  25. package/dist/index.js +8 -0
  26. package/dist/middlewares/buffer.d.ts +18 -0
  27. package/dist/middlewares/handleDisconnectedRequest.d.ts +7 -0
  28. package/dist/middlewares/handlePortRequest.d.ts +3 -0
  29. package/dist/middlewares/handleRequest.d.ts +3 -0
  30. package/dist/middlewares/handleRequestUtils.d.ts +10 -0
  31. package/dist/middlewares/handleResponse.d.ts +3 -0
  32. package/dist/middlewares/index.d.ts +7 -0
  33. package/dist/middlewares/logger.d.ts +4 -0
  34. package/dist/middlewares/normalize.d.ts +14 -0
  35. package/dist/middlewares/prepareRequestData.d.ts +28 -0
  36. package/dist/middlewares/sendRequest.d.ts +6 -0
  37. package/dist/middlewares/updateSeqInfo.d.ts +6 -0
  38. package/dist/middlewares/utils.d.ts +3 -0
  39. package/dist/protocol/AbstractChannelProtocol.d.ts +55 -0
  40. package/dist/protocol/MessageChannel.d.ts +18 -0
  41. package/dist/protocol/WebSocketChannel.d.ts +23 -0
  42. package/dist/protocol/WorkerChannel.d.ts +11 -0
  43. package/dist/types/buffer.d.ts +4 -0
  44. package/dist/types/channel.d.ts +27 -0
  45. package/dist/types/index.d.ts +7 -0
  46. package/dist/types/middleware.d.ts +44 -0
  47. package/dist/types/proxyChannel.d.ts +3 -0
  48. package/dist/types/proxyService.d.ts +11 -0
  49. package/dist/types/rpc.d.ts +25 -0
  50. package/dist/types/rpcProtocol.d.ts +22 -0
  51. package/dist/utils/constants.d.ts +5 -0
  52. package/dist/utils/index.d.ts +2 -0
  53. package/dist/utils/jsonrpc.d.ts +36 -0
  54. package/package.json +36 -0
  55. package/src/buffer/ARCHITECTURE.md +298 -0
  56. package/src/buffer/BufferFactory.ts +124 -0
  57. package/src/buffer/CHANGELOG.md +207 -0
  58. package/src/buffer/DataBuffer.ts +1 -0
  59. package/src/buffer/MessagePackBuffer.ts +79 -0
  60. package/src/buffer/OPTIMIZATION.md +258 -0
  61. package/src/buffer/README.md +147 -0
  62. package/src/buffer/ReadBaseBuffer.ts +20 -0
  63. package/src/buffer/ReadBuffer.ts +58 -0
  64. package/src/buffer/SerializationFormat.ts +81 -0
  65. package/src/buffer/WriteBaseBuffer.ts +20 -0
  66. package/src/buffer/WriteBuffer.ts +15 -0
  67. package/src/buffer/examples.ts +242 -0
  68. package/src/buffer/index.ts +15 -0
  69. package/src/common.ts +20 -0
  70. package/src/endpoint/ProxyRPCClient.ts +64 -0
  71. package/src/endpoint/RPCClientHost.ts +45 -0
  72. package/src/endpoint/RPCService.ts +54 -0
  73. package/src/endpoint/RPCServiceHost.ts +18 -0
  74. package/src/error.ts +98 -0
  75. package/src/index.ts +16 -0
  76. package/src/middlewares/buffer.ts +33 -0
  77. package/src/middlewares/handleDisconnectedRequest.ts +30 -0
  78. package/src/middlewares/handlePortRequest.ts +141 -0
  79. package/src/middlewares/handleRequest.ts +128 -0
  80. package/src/middlewares/handleRequestUtils.ts +43 -0
  81. package/src/middlewares/handleResponse.ts +36 -0
  82. package/src/middlewares/index.ts +11 -0
  83. package/src/middlewares/logger.ts +22 -0
  84. package/src/middlewares/normalize.ts +167 -0
  85. package/src/middlewares/prepareRequestData.ts +137 -0
  86. package/src/middlewares/sendRequest.ts +15 -0
  87. package/src/middlewares/updateSeqInfo.ts +34 -0
  88. package/src/middlewares/utils.ts +67 -0
  89. package/src/protocol/AbstractChannelProtocol.ts +343 -0
  90. package/src/protocol/MessageChannel.ts +80 -0
  91. package/src/protocol/WebSocketChannel.ts +179 -0
  92. package/src/protocol/WorkerChannel.ts +36 -0
  93. package/src/types/buffer.ts +5 -0
  94. package/src/types/channel.ts +50 -0
  95. package/src/types/index.ts +9 -0
  96. package/src/types/messageChannel.ts +133 -0
  97. package/src/types/middleware.ts +54 -0
  98. package/src/types/proxyChannel.ts +3 -0
  99. package/src/types/proxyService.ts +18 -0
  100. package/src/types/rpc.ts +61 -0
  101. package/src/types/rpcProtocol.ts +24 -0
  102. package/src/utils/constants.ts +17 -0
  103. package/src/utils/index.ts +5 -0
  104. package/src/utils/jsonrpc.ts +242 -0
@@ -0,0 +1,45 @@
1
+ import ProxyRPCClient from './ProxyRPCClient';
2
+ import AbstractChannelProtocol from '../protocol/AbstractChannelProtocol';
3
+
4
+ class RPCClientHost {
5
+ protected readonly hostPath: string;
6
+
7
+ private hostMap = new Map<string, ProxyRPCClient>();
8
+
9
+ // handlersMap = new Map<ServiceHandlerPath, IService>();
10
+
11
+ registerClient(
12
+ requestPath: string,
13
+ options?: {
14
+ channel?: AbstractChannelProtocol;
15
+ }
16
+ ) {
17
+ const client = new ProxyRPCClient(requestPath, options);
18
+ this.hostMap.set(requestPath, client);
19
+ return client;
20
+ }
21
+
22
+ // registerServiceHandler(handlerPath: ServiceHandlerPath, service: IService) {
23
+ // this.handlersMap.set(handlerPath, service);
24
+ // }
25
+
26
+ // getHandlers(handlerPath: ServiceHandlerPath) {
27
+ // const handlers = this.handlersMap.get(handlerPath);
28
+ // return handlers;
29
+ // }
30
+
31
+ // getHandler(handlerPath: ServiceHandlerPath, fnName: string) {
32
+ // const handlers = this.handlersMap.get(handlerPath);
33
+ // // should bind to current service object
34
+ // if (handlers && handlers[fnName]) return handlers[fnName].bind(handlers);
35
+ // return null;
36
+ // }
37
+
38
+ // merge(serviceHost: RPCClientHost) {
39
+ // for (const [key, value] of serviceHost.handlersMap) {
40
+ // this.registerServiceHandler(key, value);
41
+ // }
42
+ // }
43
+ }
44
+ export { RPCClientHost };
45
+ export default new RPCClientHost();
@@ -0,0 +1,54 @@
1
+ import AbstractChannelProtocol from '../protocol/AbstractChannelProtocol';
2
+ import { RPCServiceHost } from './RPCServiceHost';
3
+ import { ServiceHandlers } from '../types/proxyService';
4
+
5
+ class RPCService {
6
+ private channel: AbstractChannelProtocol;
7
+ readonly serviceHost: RPCServiceHost;
8
+ readonly servicePath: string;
9
+ readonly handlersMap = new Map<string, (...args: any[]) => any>();
10
+
11
+ constructor(
12
+ servicePath: string,
13
+ options?: {
14
+ channel?: AbstractChannelProtocol;
15
+ handlers: ServiceHandlers;
16
+ serviceHost?: RPCServiceHost;
17
+ }
18
+ ) {
19
+ const { channel, handlers, serviceHost } = options || {};
20
+ this.servicePath = servicePath;
21
+ this.serviceHost = serviceHost;
22
+ if (channel) {
23
+ this.setChannel(channel);
24
+ }
25
+ this.registerHandlers(handlers);
26
+ }
27
+
28
+ setChannel(channel: AbstractChannelProtocol) {
29
+ this.channel = channel;
30
+ this.channel.setService(this);
31
+ this.channel.on(this.handleMessage.bind(this));
32
+ }
33
+
34
+ registerHandlers(handlers: Record<string, (...args: any[]) => any>) {
35
+ if (!handlers) return;
36
+ for (const [methodName, handler] of Object.entries(handlers)) {
37
+ this.registerHandler(methodName, handler);
38
+ }
39
+ }
40
+
41
+ handleMessage(...args: any[]) {
42
+ this.channel.onMessage(...args);
43
+ }
44
+
45
+ registerHandler(methodName: string, handler: (...args: any[]) => any) {
46
+ this.handlersMap.set(methodName, handler);
47
+ }
48
+
49
+ getHandler(methodName: string) {
50
+ return this.handlersMap.get(methodName);
51
+ }
52
+ }
53
+
54
+ export default RPCService;
@@ -0,0 +1,18 @@
1
+ import { ServiceHandlers } from '../types/proxyService';
2
+ import RPCService from './RPCService';
3
+
4
+ class RPCServiceHost {
5
+ protected readonly hostPath: string;
6
+
7
+ private hostMap = new Map<string, RPCService>();
8
+
9
+ // handlersMap = new Map<ServiceHandlerPath, IService>();
10
+
11
+ registerService(servicePath: string, serviceHandlers: ServiceHandlers) {
12
+ const service = new RPCService(servicePath, { handlers: serviceHandlers });
13
+ this.hostMap.set(servicePath, service);
14
+ return service;
15
+ }
16
+ }
17
+ export { RPCServiceHost };
18
+ export default new RPCServiceHost();
package/src/error.ts ADDED
@@ -0,0 +1,98 @@
1
+ /* eslint-disable no-param-reassign */
2
+
3
+ /**
4
+ * JSONRPC Error Response Detail
5
+ * Based on JSONRPC 2.0 specification
6
+ */
7
+ export interface ErrorResponseDetail<Error = unknown> {
8
+ readonly code: number;
9
+ readonly message: string;
10
+ readonly data?: Error;
11
+ }
12
+
13
+ /**
14
+ * JSONRPC Request/Response ID type
15
+ * Can be string, number, null, or undefined (for notifications)
16
+ */
17
+ export type ID = string | number | null | undefined;
18
+
19
+ /**
20
+ * JSONRPC Error Response
21
+ * Based on JSONRPC 2.0 specification
22
+ */
23
+ export interface ErrorResponse<Error = unknown> {
24
+ readonly jsonrpc: '2.0';
25
+ readonly id?: ID;
26
+ readonly error: ErrorResponseDetail<Error>;
27
+ }
28
+
29
+ /**
30
+ * Standard JSONRPC 2.0 Error Codes
31
+ * Based on JSONRPC 2.0 specification section 5.1
32
+ */
33
+ export enum JSONRPCErrorCode {
34
+ /**
35
+ * Parse error (-32700)
36
+ * Invalid JSON was received by the server.
37
+ * An error occurred on the server while parsing the JSON text.
38
+ */
39
+ ParseError = -32700,
40
+
41
+ /**
42
+ * Invalid Request (-32600)
43
+ * The JSON sent is not a valid Request object.
44
+ */
45
+ InvalidRequest = -32600,
46
+
47
+ /**
48
+ * Method not found (-32601)
49
+ * The method does not exist / is not available.
50
+ */
51
+ MethodNotFound = -32601,
52
+
53
+ /**
54
+ * Invalid params (-32602)
55
+ * Invalid method parameter(s).
56
+ */
57
+ InvalidParams = -32602,
58
+
59
+ /**
60
+ * Internal error (-32603)
61
+ * Internal JSON-RPC error.
62
+ */
63
+ InternalError = -32603,
64
+
65
+ /**
66
+ * Server error (-32000 to -32099)
67
+ * Reserved for implementation-defined server-errors.
68
+ * The remainder of the space is available for application defined errors.
69
+ */
70
+ ServerErrorStart = -32000,
71
+ ServerErrorEnd = -32099,
72
+ }
73
+
74
+ /**
75
+ * Create a JSONRPC error response object
76
+ * This function is kept for backward compatibility.
77
+ * For new code, prefer using functions from utils/jsonrpc.ts
78
+ */
79
+ export const makeErrorResponse = <T>(
80
+ id: ID,
81
+ code: number,
82
+ message: string,
83
+ data?: T
84
+ ): ErrorResponse<T> => {
85
+ if (id === undefined) id = null;
86
+ code = Math.floor(code);
87
+ if (Number.isNaN(code)) code = -1;
88
+ const x: ErrorResponse<T> = {
89
+ jsonrpc: '2.0',
90
+ id,
91
+ error: { code, message, data },
92
+ };
93
+ // Remove undefined data field
94
+ if (x.error.data === undefined) {
95
+ delete (x.error as any).data;
96
+ }
97
+ return x;
98
+ };
package/src/index.ts ADDED
@@ -0,0 +1,16 @@
1
+ import clientHost from './endpoint/RPCClientHost';
2
+ import ProxyRPCClient from './endpoint/ProxyRPCClient';
3
+ import RPCService from './endpoint/RPCService';
4
+ import serviceHost from './endpoint/RPCServiceHost';
5
+
6
+ export { default as MessageChannel } from './protocol/MessageChannel';
7
+ export { default as WorkerChannel } from './protocol/WorkerChannel';
8
+ export { default as WebSocketChannel } from './protocol/WebSocketChannel';
9
+
10
+ export { ProxyRPCClient, RPCService, clientHost, serviceHost };
11
+
12
+ // Export JSONRPC utilities and types
13
+ export * from './utils';
14
+ // Export error types but not makeErrorResponse to avoid conflict (it's in utils/jsonrpc.ts)
15
+ export type { ErrorResponse, ErrorResponseDetail, ID } from './error';
16
+ export { JSONRPCErrorCode } from './error';
@@ -0,0 +1,33 @@
1
+ import {
2
+ NormalizedRawMessageOutput,
3
+ SenderMiddlewareOutput,
4
+ SendMiddlewareLifecycle,
5
+ } from '../types';
6
+ import AbstractChannelProtocol from '../protocol/AbstractChannelProtocol';
7
+
8
+ export const serialize = (channel: AbstractChannelProtocol) => {
9
+ const fn = (value: SenderMiddlewareOutput) => ({
10
+ ...value,
11
+ data: channel.writeBuffer.encode(value.data),
12
+ });
13
+
14
+ fn.lifecycle = SendMiddlewareLifecycle.DataOperation;
15
+ return fn;
16
+ };
17
+
18
+ export const deserialize =
19
+ (channel: AbstractChannelProtocol) => (value: NormalizedRawMessageOutput) => {
20
+ const { data } = value;
21
+ let decoded = data;
22
+
23
+ try {
24
+ decoded = channel.readBuffer.decode(data);
25
+ } catch (err) {
26
+ console.error('[decode error]', data, err);
27
+ }
28
+
29
+ return {
30
+ ...value,
31
+ data: decoded,
32
+ };
33
+ };
@@ -0,0 +1,30 @@
1
+ import { SenderMiddlewareOutput, SendMiddlewareLifecycle } from '../types';
2
+ import AbstractChannelProtocol from '../protocol/AbstractChannelProtocol';
3
+
4
+ export const handleDisconnectedRequest = (
5
+ protocol: AbstractChannelProtocol
6
+ ) => {
7
+ const fn = (value: SenderMiddlewareOutput) => {
8
+ const isConnected = protocol.isConnected();
9
+
10
+ if (!isConnected && !value.isOptionsRequest) {
11
+ protocol.addPendingSendEntry({
12
+ methodName: fn.displayName,
13
+ lifecycle: SendMiddlewareLifecycle.Prepare,
14
+ ...value,
15
+ middlewareContext: {
16
+ ...value.middlewareContext,
17
+ },
18
+ });
19
+
20
+ value.middlewareContext.minLifecycle = SendMiddlewareLifecycle.Aborted;
21
+ }
22
+
23
+ return value;
24
+ };
25
+
26
+ fn.displayName = 'handleDisconnectedRequest';
27
+ fn.lifecycle = SendMiddlewareLifecycle.Prepare;
28
+
29
+ return fn;
30
+ };
@@ -0,0 +1,141 @@
1
+ import isPromise from '@x-oasis/is-promise';
2
+ import { ResponseType, DeserializedMessageOutput } from '../types';
3
+ import AbstractChannelProtocol from '../protocol/AbstractChannelProtocol';
4
+ import { isEventMethod } from '../common';
5
+ import {
6
+ defaultErrorMapper,
7
+ ErrorResponseMapped,
8
+ makeRequest,
9
+ } from '../utils/jsonrpc';
10
+ import { JSONRPCErrorCode } from '../error';
11
+
12
+ export const handlePortRequest =
13
+ (protocol: AbstractChannelProtocol) =>
14
+ (message: DeserializedMessageOutput) => {
15
+ const serviceHost = protocol.service;
16
+
17
+ const { data, event: messageEvent } = message;
18
+ const header = data[0];
19
+ const channelName = header[4];
20
+
21
+ const body = data[1];
22
+ const type = header[0] as any;
23
+
24
+ if (Object.values(ResponseType).includes(type)) {
25
+ return message;
26
+ }
27
+
28
+ const seqId = header[1];
29
+ const requestPath = header[2];
30
+ const methodName = header[3];
31
+ const args = body[0];
32
+
33
+ if (serviceHost) {
34
+ if (isEventMethod(methodName)) {
35
+ // const event = serviceHost.getHandler(requestPath, methodName)
36
+ // const fn = (...args: any[]) => {
37
+ // const responseHeader = [ResponseType.ReturnSuccess, seqId]
38
+ // let responseBody = []
39
+ // let sendData = null
40
+ // try {
41
+ // responseBody = args
42
+ // sendData = protocol.writeBuffer.encode([responseHeader, responseBody])
43
+ // } catch (err) {
44
+ // sendData = protocol.writeBuffer.encode([responseHeader, []])
45
+ // console.error(`[handleRequest sendReply encode error ] ${requestPath} ${methodName}`, err)
46
+ // }
47
+
48
+ // // TODO: temp; main <=> project renderer...
49
+ // if (messageEvent?.sender) {
50
+ // messageEvent.sender.send(channelName, sendData)
51
+ // return
52
+ // }
53
+
54
+ // protocol.sendReply(sendData)
55
+ // }
56
+
57
+ // event(fn)
58
+ return message;
59
+ }
60
+
61
+ const handler = serviceHost.getHandler(methodName);
62
+
63
+ // Create JSONRPC request object for error context
64
+ const jsonrpcRequest = makeRequest(seqId, methodName, args);
65
+
66
+ // todo
67
+ const result = Promise.resolve(handler?.(args));
68
+
69
+ if (handler && isPromise(result)) {
70
+ result.then(
71
+ (port: any) => {
72
+ const responseHeader = [ResponseType.PortSuccess, seqId];
73
+ let responseBody: any[] = [];
74
+ let sendData = null;
75
+ try {
76
+ responseBody = [];
77
+ sendData = protocol.writeBuffer.encode([
78
+ responseHeader,
79
+ responseBody,
80
+ ]);
81
+ } catch (err) {
82
+ // Encoding error - use standardized error format
83
+ const mapper = defaultErrorMapper(
84
+ err instanceof Error ? err.stack : '',
85
+ JSONRPCErrorCode.InternalError
86
+ );
87
+ const errorResponse = ErrorResponseMapped(
88
+ jsonrpcRequest,
89
+ err,
90
+ mapper
91
+ );
92
+ responseBody = [errorResponse.error];
93
+ sendData = protocol.writeBuffer.encode([
94
+ responseHeader,
95
+ responseBody,
96
+ ]);
97
+ console.error(
98
+ `[handleRequest sendReply encode error ] ${requestPath} ${methodName}`,
99
+ err
100
+ );
101
+ }
102
+
103
+ // TODO: temp; main <=> project renderer...
104
+ if (messageEvent?.sender) {
105
+ messageEvent.sender.postMessage(channelName, sendData, [port]);
106
+ return;
107
+ }
108
+
109
+ protocol.sendReply(sendData);
110
+ },
111
+ (err: unknown) => {
112
+ // Use standardized JSONRPC error format
113
+ const mapper = defaultErrorMapper(
114
+ err instanceof Error ? err.stack : '',
115
+ JSONRPCErrorCode.InternalError
116
+ );
117
+ const errorResponse = ErrorResponseMapped(
118
+ jsonrpcRequest,
119
+ err,
120
+ mapper
121
+ );
122
+ const responseHeader = [ResponseType.ReturnFail, seqId];
123
+ const responseBody = [errorResponse.error];
124
+
125
+ if (messageEvent?.sender) {
126
+ messageEvent.sender.send(
127
+ (protocol as any).channelName,
128
+ protocol.writeBuffer.encode([responseHeader, responseBody])
129
+ );
130
+ return;
131
+ }
132
+
133
+ protocol.sendReply(
134
+ protocol.writeBuffer.encode([responseHeader, responseBody])
135
+ );
136
+ }
137
+ );
138
+ }
139
+ }
140
+ return message;
141
+ };
@@ -0,0 +1,128 @@
1
+ import isPromise from '@x-oasis/is-promise';
2
+ import { ResponseType, DeserializedMessageOutput } from '../types';
3
+ import AbstractChannelProtocol from '../protocol/AbstractChannelProtocol';
4
+ import {
5
+ ErrorResponseMethodNotFound,
6
+ defaultErrorMapper,
7
+ ErrorResponseMapped,
8
+ makeRequest,
9
+ Request,
10
+ AsyncCallErrorDetail,
11
+ } from '../utils/jsonrpc';
12
+ import { JSONRPCErrorCode } from '../error';
13
+
14
+ /**
15
+ * Create standardized error response body
16
+ */
17
+ const createErrorResponseBody = (
18
+ error: unknown,
19
+ request?: Request
20
+ ): {
21
+ code: number;
22
+ message: string;
23
+ data?: AsyncCallErrorDetail;
24
+ } => {
25
+ const mapper = defaultErrorMapper(
26
+ error instanceof Error ? error.stack : '',
27
+ JSONRPCErrorCode.InternalError
28
+ );
29
+
30
+ if (request) {
31
+ const errorResponse = ErrorResponseMapped(request, error, mapper);
32
+ return errorResponse.error;
33
+ }
34
+
35
+ // Fallback when no request context is available
36
+ const { code, message, data } = mapper(error, {} as Request);
37
+ return { code, message, data };
38
+ };
39
+
40
+ export const handleRequest =
41
+ (protocol: AbstractChannelProtocol) =>
42
+ (message: DeserializedMessageOutput) => {
43
+ const service = protocol.service;
44
+
45
+ const { data } = message;
46
+ const header = data[0];
47
+
48
+ const body = data[1];
49
+ const type = header[0] as any;
50
+
51
+ /**
52
+ * if the message is a response, do nothing and return the message
53
+ */
54
+ if (Object.values(ResponseType).includes(type)) {
55
+ return message;
56
+ }
57
+
58
+ const seqId = header[1];
59
+ const requestPath = header[2];
60
+ const methodName = header[3];
61
+ const args = body[0];
62
+
63
+ // Create JSONRPC request object for error context
64
+ const jsonrpcRequest = makeRequest(seqId, methodName, args);
65
+
66
+ const handler = service.getHandler(methodName);
67
+
68
+ // Check if method exists
69
+ if (!handler) {
70
+ const errorResponse = ErrorResponseMethodNotFound(seqId);
71
+ const responseHeader = [ResponseType.ReturnFail, seqId];
72
+ const responseBody = [errorResponse.error];
73
+
74
+ protocol.sendReply(
75
+ protocol.writeBuffer.encode([responseHeader, responseBody])
76
+ );
77
+ return message;
78
+ }
79
+
80
+ const _result = handler(args);
81
+
82
+ // todo
83
+ const result = Promise.resolve(_result);
84
+
85
+ if (isPromise(result)) {
86
+ result.then(
87
+ (response: any) => {
88
+ const responseHeader = [ResponseType.ReturnSuccess, seqId];
89
+ let responseBody = [];
90
+ let sendData = null;
91
+ try {
92
+ responseBody = [response];
93
+ sendData = protocol.writeBuffer.encode([
94
+ responseHeader,
95
+ responseBody,
96
+ ]);
97
+ } catch (err) {
98
+ // Encoding error - use standardized error format
99
+ const errorBody = createErrorResponseBody(err, jsonrpcRequest);
100
+ responseBody = [errorBody];
101
+ sendData = protocol.writeBuffer.encode([
102
+ responseHeader,
103
+ responseBody,
104
+ ]);
105
+ console.error(
106
+ `[handleRequest sendReply encode error ] ${requestPath} ${methodName}`,
107
+ err
108
+ );
109
+ }
110
+
111
+ protocol.sendReply(sendData);
112
+ },
113
+ (err: unknown) => {
114
+ // Use standardized JSONRPC error format
115
+ const errorBody = createErrorResponseBody(err, jsonrpcRequest);
116
+ const responseHeader = [ResponseType.ReturnFail, seqId];
117
+ const responseBody = [errorBody];
118
+
119
+ protocol.sendReply(
120
+ protocol.writeBuffer.encode([responseHeader, responseBody])
121
+ );
122
+ }
123
+ );
124
+ }
125
+ // 其实这儿不应该这么处理,应该返回一个空值,但是为了方便,还是返回原来的消息
126
+ // 因为假如说是一个request的话,到这一步就算处理完了
127
+ return message;
128
+ };
@@ -0,0 +1,43 @@
1
+ import AbstractChannelProtocol from '../protocol/AbstractChannelProtocol';
2
+ import { ResponseType } from '../types';
3
+ import RPCService from '../endpoint/RPCService';
4
+
5
+ export const handleAcquirePort = (props: {
6
+ protocol: AbstractChannelProtocol;
7
+ // serviceHost: RPCServiceHost;
8
+ service: RPCService;
9
+ requestPath: string;
10
+ methodName: string;
11
+ seqId: string;
12
+ args: any[];
13
+ }) => {
14
+ const { service, requestPath, methodName, protocol, seqId, args } = props;
15
+
16
+ // const handler = serviceHost.getHandler(requestPath, methodName);
17
+ const handler = service.getHandler(methodName);
18
+ const port = handler?.(args);
19
+
20
+ // 比如port process它监听的是message;你用process创建一个ProcessChannelProtocol
21
+ // 都会触发监听,这个时候并不一定有值返回,其实正常是否考虑将on message这种
22
+ // emitter收敛了,即使你new了,但其实是一个实例
23
+ if (!port) {
24
+ // console.error('may trigger message listener', protocol)
25
+ }
26
+
27
+ let responseHeader = [ResponseType.PortSuccess, seqId];
28
+ let responseBody: any[] = [];
29
+ let sendData = null;
30
+ try {
31
+ responseBody = [];
32
+ sendData = protocol.writeBuffer.encode([responseHeader, responseBody]);
33
+ } catch (err) {
34
+ responseHeader = [ResponseType.PortFail, seqId];
35
+ sendData = protocol.writeBuffer.encode([responseHeader, []]);
36
+ console.error(
37
+ `[handleRequest sendReply encode error ] ${requestPath} ${methodName}`,
38
+ err
39
+ );
40
+ }
41
+
42
+ return port ? [sendData, [port]] : null;
43
+ };
@@ -0,0 +1,36 @@
1
+ import { RequestType, ResponseType, DeserializedMessageOutput } from '../types';
2
+ import AbstractChannelProtocol from '../protocol/AbstractChannelProtocol';
3
+
4
+ export const handleResponse =
5
+ (protocol: AbstractChannelProtocol) =>
6
+ (message: DeserializedMessageOutput) => {
7
+ if (!message) return message;
8
+ const { data } = message;
9
+ const header = data[0];
10
+ const body = data[1];
11
+ const type = header[0] as any;
12
+
13
+ if (Object.values(RequestType).includes(type)) {
14
+ return message;
15
+ }
16
+
17
+ const seqId = header[1];
18
+
19
+ const findDefer = protocol.ongoingRequests.get(`${seqId}`);
20
+
21
+ if (findDefer) {
22
+ protocol.ongoingRequests.delete(`${seqId}`);
23
+ if (type === ResponseType.PortSuccess) {
24
+ findDefer.resolve(message.ports[0]);
25
+ } else if (type === ResponseType.ReturnFail) {
26
+ findDefer.reject(body[0]);
27
+ } else findDefer.resolve(body[0]);
28
+ } else {
29
+ const findListener = protocol.requestEvents.get(`${seqId}`);
30
+
31
+ if (findListener) {
32
+ findListener(...body);
33
+ }
34
+ }
35
+ return null;
36
+ };
@@ -0,0 +1,11 @@
1
+ export * from './buffer';
2
+ // export * from './handleRequest';
3
+ export * from './normalize';
4
+ export * from './handleResponse';
5
+ export * from './prepareRequestData';
6
+ export * from './updateSeqInfo';
7
+ // export * from './handlePortRequest';
8
+ export * from './sendRequest';
9
+ // export * from './handleDisconnectedRequest';
10
+
11
+ export { runMiddlewares } from './utils';
@@ -0,0 +1,22 @@
1
+ import AbstractChannelProtocol from '../protocol/AbstractChannelProtocol';
2
+ import { NormalizedRawMessageOutput } from '../types';
3
+
4
+ export const createSenderLogger =
5
+ (logService: any) =>
6
+ (channel: AbstractChannelProtocol) =>
7
+ (value: NormalizedRawMessageOutput) => {
8
+ logService.info(`${channel.masterProcessName} send message`, value.data);
9
+ return value;
10
+ };
11
+
12
+ export const createClientLogger =
13
+ (logService: any) =>
14
+ (channel: AbstractChannelProtocol) =>
15
+ (value: NormalizedRawMessageOutput) => {
16
+ const { data } = value;
17
+ logService.info(
18
+ `${channel.masterProcessName} receive message from ${channel.description}`,
19
+ data
20
+ );
21
+ return value;
22
+ };