@cybermp/rpc-core 0.1.0-rc.1 → 0.1.0-rc.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/definitions/index.cjs +25 -0
- package/dist/definitions/index.d.cts +97 -0
- package/dist/definitions/index.d.mts +97 -0
- package/dist/definitions/index.d.ts +97 -0
- package/dist/index.cjs +390 -0
- package/dist/index.d.cts +147 -0
- package/dist/index.d.mts +147 -0
- package/dist/index.d.ts +147 -0
- package/dist/shared/rpc-core.Dn7eTH9H.cjs +46 -0
- package/dist/shared/rpc-core.T_c3MAf6.cjs +154 -0
- package/dist/shared/rpc-core.tDMABvlQ.d.cts +7 -0
- package/dist/shared/rpc-core.tDMABvlQ.d.mts +7 -0
- package/dist/shared/rpc-core.tDMABvlQ.d.ts +7 -0
- package/dist/utils/index.cjs +9 -0
- package/dist/utils/index.d.cts +8 -0
- package/dist/utils/index.d.mts +8 -0
- package/dist/utils/index.d.ts +8 -0
- package/package.json +16 -4
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
const utils_index = require('../shared/rpc-core.Dn7eTH9H.cjs');
|
|
4
|
+
const rpcPacket = require('../shared/rpc-core.T_c3MAf6.cjs');
|
|
5
|
+
|
|
6
|
+
class RpcContext {
|
|
7
|
+
data;
|
|
8
|
+
meta;
|
|
9
|
+
packet;
|
|
10
|
+
constructor({ data, meta, packet }) {
|
|
11
|
+
this.data = data;
|
|
12
|
+
this.meta = meta;
|
|
13
|
+
this.packet = packet;
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
exports.MpEnv = utils_index.MpEnv;
|
|
18
|
+
exports.CommonRpcErrorCode = rpcPacket.CommonRpcErrorCode;
|
|
19
|
+
exports.RpcApplyType = rpcPacket.RpcApplyType;
|
|
20
|
+
exports.RpcEnv = rpcPacket.RpcEnv;
|
|
21
|
+
exports.RpcError = rpcPacket.RpcError;
|
|
22
|
+
exports.RpcPacket = rpcPacket.RpcPacket;
|
|
23
|
+
exports.RpcPacketType = rpcPacket.RpcPacketType;
|
|
24
|
+
exports.getRpcError = rpcPacket.getRpcError;
|
|
25
|
+
exports.RpcContext = RpcContext;
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
import { M as MpEnv } from '../shared/rpc-core.tDMABvlQ.cjs';
|
|
2
|
+
|
|
3
|
+
type RpcEnvOptions = {
|
|
4
|
+
source?: MpEnv;
|
|
5
|
+
target: MpEnv;
|
|
6
|
+
};
|
|
7
|
+
declare class RpcEnv {
|
|
8
|
+
source: MpEnv;
|
|
9
|
+
target: MpEnv;
|
|
10
|
+
constructor(opts: RpcEnvOptions);
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
declare const enum CommonRpcErrorCode {
|
|
14
|
+
UNKNOWN = "UNKNOWN",
|
|
15
|
+
UNAUTHORIZED = "UNAUTHORIZED",
|
|
16
|
+
FORBIDDEN = "FORBIDDEN",
|
|
17
|
+
NOT_FOUND = "NOT_FOUND",
|
|
18
|
+
METHOD_NOT_FOUND = "METHOD_NOT_FOUND",
|
|
19
|
+
INTERNAL_ERROR = "INTERNAL_ERROR",
|
|
20
|
+
TIMEOUT = "TIMEOUT",
|
|
21
|
+
INVALID_DATA = "INVALID_DATA",
|
|
22
|
+
TOO_MANY_PENDING_REQUESTS = "TOO_MANY_PENDING_REQUESTS"
|
|
23
|
+
}
|
|
24
|
+
interface RpcErrorOptions {
|
|
25
|
+
message?: string;
|
|
26
|
+
code?: string;
|
|
27
|
+
data?: any;
|
|
28
|
+
method?: string;
|
|
29
|
+
}
|
|
30
|
+
declare class RpcError<D = any> extends Error {
|
|
31
|
+
code: string;
|
|
32
|
+
data?: D;
|
|
33
|
+
method?: string;
|
|
34
|
+
constructor(options?: RpcErrorOptions);
|
|
35
|
+
static unknown(options?: RpcErrorOptions): RpcError<any>;
|
|
36
|
+
static tooManyPendingRequests(options?: RpcErrorOptions): RpcError<any>;
|
|
37
|
+
static unauthorized(options?: RpcErrorOptions): RpcError<any>;
|
|
38
|
+
static forbidden(options?: RpcErrorOptions): RpcError<any>;
|
|
39
|
+
static notFound(options?: RpcErrorOptions): RpcError<any>;
|
|
40
|
+
static methodNotFound(options?: RpcErrorOptions): RpcError<any>;
|
|
41
|
+
static internalError(options?: RpcErrorOptions): RpcError<any>;
|
|
42
|
+
static timeout(options?: RpcErrorOptions): RpcError<any>;
|
|
43
|
+
static invalidData(options?: RpcErrorOptions): RpcError<any>;
|
|
44
|
+
}
|
|
45
|
+
declare const getRpcError: (err: any, method?: string) => RpcError<any>;
|
|
46
|
+
|
|
47
|
+
declare enum RpcPacketType {
|
|
48
|
+
CALL = "call",
|
|
49
|
+
TRIGGER = "trigger",
|
|
50
|
+
RESPONSE = "response"
|
|
51
|
+
}
|
|
52
|
+
type RpcPacketOptions<D = any, M extends Record<string, any> = Record<string, any>> = {
|
|
53
|
+
id?: string | null;
|
|
54
|
+
type: RpcPacketType;
|
|
55
|
+
method: string;
|
|
56
|
+
data?: D;
|
|
57
|
+
meta?: M;
|
|
58
|
+
error?: RpcError;
|
|
59
|
+
};
|
|
60
|
+
declare class RpcPacket<D = any, M extends Record<string, any> = Record<string, any>> {
|
|
61
|
+
readonly id?: string | null;
|
|
62
|
+
type: RpcPacketType;
|
|
63
|
+
method: string;
|
|
64
|
+
data: D;
|
|
65
|
+
meta: M;
|
|
66
|
+
error?: RpcError;
|
|
67
|
+
env: RpcEnv;
|
|
68
|
+
constructor({ id, type, data, method, error, meta, }: RpcPacketOptions<D, M>, env: RpcEnvOptions);
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
interface RpcSerializer {
|
|
72
|
+
serialize<O = any>(obj: O): any;
|
|
73
|
+
deserialize<R = any>(obj: any): R;
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
declare enum RpcApplyType {
|
|
77
|
+
ON = "on",
|
|
78
|
+
REGISTER = "register"
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
type RpcContextConstructor<D = any, M extends Record<string, any> = Record<string, any>> = {
|
|
82
|
+
data: D;
|
|
83
|
+
meta: M;
|
|
84
|
+
packet: RpcPacket<D, M>;
|
|
85
|
+
};
|
|
86
|
+
declare abstract class RpcContext<D = any, M extends Record<string, any> = Record<string, any>> {
|
|
87
|
+
data: D;
|
|
88
|
+
meta: M;
|
|
89
|
+
packet: RpcPacket<D, M>;
|
|
90
|
+
constructor({ data, meta, packet }: RpcContextConstructor<D, M>);
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
type RpcNext = () => Promise<any>;
|
|
94
|
+
type RpcHandler<C extends RpcContext = RpcContext> = (ctx: C, next: RpcNext) => any;
|
|
95
|
+
|
|
96
|
+
export { CommonRpcErrorCode, MpEnv, RpcApplyType, RpcContext, RpcEnv, RpcError, RpcPacket, RpcPacketType, getRpcError };
|
|
97
|
+
export type { RpcContextConstructor, RpcEnvOptions, RpcErrorOptions, RpcHandler, RpcNext, RpcPacketOptions, RpcSerializer };
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
import { M as MpEnv } from '../shared/rpc-core.tDMABvlQ.mjs';
|
|
2
|
+
|
|
3
|
+
type RpcEnvOptions = {
|
|
4
|
+
source?: MpEnv;
|
|
5
|
+
target: MpEnv;
|
|
6
|
+
};
|
|
7
|
+
declare class RpcEnv {
|
|
8
|
+
source: MpEnv;
|
|
9
|
+
target: MpEnv;
|
|
10
|
+
constructor(opts: RpcEnvOptions);
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
declare const enum CommonRpcErrorCode {
|
|
14
|
+
UNKNOWN = "UNKNOWN",
|
|
15
|
+
UNAUTHORIZED = "UNAUTHORIZED",
|
|
16
|
+
FORBIDDEN = "FORBIDDEN",
|
|
17
|
+
NOT_FOUND = "NOT_FOUND",
|
|
18
|
+
METHOD_NOT_FOUND = "METHOD_NOT_FOUND",
|
|
19
|
+
INTERNAL_ERROR = "INTERNAL_ERROR",
|
|
20
|
+
TIMEOUT = "TIMEOUT",
|
|
21
|
+
INVALID_DATA = "INVALID_DATA",
|
|
22
|
+
TOO_MANY_PENDING_REQUESTS = "TOO_MANY_PENDING_REQUESTS"
|
|
23
|
+
}
|
|
24
|
+
interface RpcErrorOptions {
|
|
25
|
+
message?: string;
|
|
26
|
+
code?: string;
|
|
27
|
+
data?: any;
|
|
28
|
+
method?: string;
|
|
29
|
+
}
|
|
30
|
+
declare class RpcError<D = any> extends Error {
|
|
31
|
+
code: string;
|
|
32
|
+
data?: D;
|
|
33
|
+
method?: string;
|
|
34
|
+
constructor(options?: RpcErrorOptions);
|
|
35
|
+
static unknown(options?: RpcErrorOptions): RpcError<any>;
|
|
36
|
+
static tooManyPendingRequests(options?: RpcErrorOptions): RpcError<any>;
|
|
37
|
+
static unauthorized(options?: RpcErrorOptions): RpcError<any>;
|
|
38
|
+
static forbidden(options?: RpcErrorOptions): RpcError<any>;
|
|
39
|
+
static notFound(options?: RpcErrorOptions): RpcError<any>;
|
|
40
|
+
static methodNotFound(options?: RpcErrorOptions): RpcError<any>;
|
|
41
|
+
static internalError(options?: RpcErrorOptions): RpcError<any>;
|
|
42
|
+
static timeout(options?: RpcErrorOptions): RpcError<any>;
|
|
43
|
+
static invalidData(options?: RpcErrorOptions): RpcError<any>;
|
|
44
|
+
}
|
|
45
|
+
declare const getRpcError: (err: any, method?: string) => RpcError<any>;
|
|
46
|
+
|
|
47
|
+
declare enum RpcPacketType {
|
|
48
|
+
CALL = "call",
|
|
49
|
+
TRIGGER = "trigger",
|
|
50
|
+
RESPONSE = "response"
|
|
51
|
+
}
|
|
52
|
+
type RpcPacketOptions<D = any, M extends Record<string, any> = Record<string, any>> = {
|
|
53
|
+
id?: string | null;
|
|
54
|
+
type: RpcPacketType;
|
|
55
|
+
method: string;
|
|
56
|
+
data?: D;
|
|
57
|
+
meta?: M;
|
|
58
|
+
error?: RpcError;
|
|
59
|
+
};
|
|
60
|
+
declare class RpcPacket<D = any, M extends Record<string, any> = Record<string, any>> {
|
|
61
|
+
readonly id?: string | null;
|
|
62
|
+
type: RpcPacketType;
|
|
63
|
+
method: string;
|
|
64
|
+
data: D;
|
|
65
|
+
meta: M;
|
|
66
|
+
error?: RpcError;
|
|
67
|
+
env: RpcEnv;
|
|
68
|
+
constructor({ id, type, data, method, error, meta, }: RpcPacketOptions<D, M>, env: RpcEnvOptions);
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
interface RpcSerializer {
|
|
72
|
+
serialize<O = any>(obj: O): any;
|
|
73
|
+
deserialize<R = any>(obj: any): R;
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
declare enum RpcApplyType {
|
|
77
|
+
ON = "on",
|
|
78
|
+
REGISTER = "register"
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
type RpcContextConstructor<D = any, M extends Record<string, any> = Record<string, any>> = {
|
|
82
|
+
data: D;
|
|
83
|
+
meta: M;
|
|
84
|
+
packet: RpcPacket<D, M>;
|
|
85
|
+
};
|
|
86
|
+
declare abstract class RpcContext<D = any, M extends Record<string, any> = Record<string, any>> {
|
|
87
|
+
data: D;
|
|
88
|
+
meta: M;
|
|
89
|
+
packet: RpcPacket<D, M>;
|
|
90
|
+
constructor({ data, meta, packet }: RpcContextConstructor<D, M>);
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
type RpcNext = () => Promise<any>;
|
|
94
|
+
type RpcHandler<C extends RpcContext = RpcContext> = (ctx: C, next: RpcNext) => any;
|
|
95
|
+
|
|
96
|
+
export { CommonRpcErrorCode, MpEnv, RpcApplyType, RpcContext, RpcEnv, RpcError, RpcPacket, RpcPacketType, getRpcError };
|
|
97
|
+
export type { RpcContextConstructor, RpcEnvOptions, RpcErrorOptions, RpcHandler, RpcNext, RpcPacketOptions, RpcSerializer };
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
import { M as MpEnv } from '../shared/rpc-core.tDMABvlQ.js';
|
|
2
|
+
|
|
3
|
+
type RpcEnvOptions = {
|
|
4
|
+
source?: MpEnv;
|
|
5
|
+
target: MpEnv;
|
|
6
|
+
};
|
|
7
|
+
declare class RpcEnv {
|
|
8
|
+
source: MpEnv;
|
|
9
|
+
target: MpEnv;
|
|
10
|
+
constructor(opts: RpcEnvOptions);
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
declare const enum CommonRpcErrorCode {
|
|
14
|
+
UNKNOWN = "UNKNOWN",
|
|
15
|
+
UNAUTHORIZED = "UNAUTHORIZED",
|
|
16
|
+
FORBIDDEN = "FORBIDDEN",
|
|
17
|
+
NOT_FOUND = "NOT_FOUND",
|
|
18
|
+
METHOD_NOT_FOUND = "METHOD_NOT_FOUND",
|
|
19
|
+
INTERNAL_ERROR = "INTERNAL_ERROR",
|
|
20
|
+
TIMEOUT = "TIMEOUT",
|
|
21
|
+
INVALID_DATA = "INVALID_DATA",
|
|
22
|
+
TOO_MANY_PENDING_REQUESTS = "TOO_MANY_PENDING_REQUESTS"
|
|
23
|
+
}
|
|
24
|
+
interface RpcErrorOptions {
|
|
25
|
+
message?: string;
|
|
26
|
+
code?: string;
|
|
27
|
+
data?: any;
|
|
28
|
+
method?: string;
|
|
29
|
+
}
|
|
30
|
+
declare class RpcError<D = any> extends Error {
|
|
31
|
+
code: string;
|
|
32
|
+
data?: D;
|
|
33
|
+
method?: string;
|
|
34
|
+
constructor(options?: RpcErrorOptions);
|
|
35
|
+
static unknown(options?: RpcErrorOptions): RpcError<any>;
|
|
36
|
+
static tooManyPendingRequests(options?: RpcErrorOptions): RpcError<any>;
|
|
37
|
+
static unauthorized(options?: RpcErrorOptions): RpcError<any>;
|
|
38
|
+
static forbidden(options?: RpcErrorOptions): RpcError<any>;
|
|
39
|
+
static notFound(options?: RpcErrorOptions): RpcError<any>;
|
|
40
|
+
static methodNotFound(options?: RpcErrorOptions): RpcError<any>;
|
|
41
|
+
static internalError(options?: RpcErrorOptions): RpcError<any>;
|
|
42
|
+
static timeout(options?: RpcErrorOptions): RpcError<any>;
|
|
43
|
+
static invalidData(options?: RpcErrorOptions): RpcError<any>;
|
|
44
|
+
}
|
|
45
|
+
declare const getRpcError: (err: any, method?: string) => RpcError<any>;
|
|
46
|
+
|
|
47
|
+
declare enum RpcPacketType {
|
|
48
|
+
CALL = "call",
|
|
49
|
+
TRIGGER = "trigger",
|
|
50
|
+
RESPONSE = "response"
|
|
51
|
+
}
|
|
52
|
+
type RpcPacketOptions<D = any, M extends Record<string, any> = Record<string, any>> = {
|
|
53
|
+
id?: string | null;
|
|
54
|
+
type: RpcPacketType;
|
|
55
|
+
method: string;
|
|
56
|
+
data?: D;
|
|
57
|
+
meta?: M;
|
|
58
|
+
error?: RpcError;
|
|
59
|
+
};
|
|
60
|
+
declare class RpcPacket<D = any, M extends Record<string, any> = Record<string, any>> {
|
|
61
|
+
readonly id?: string | null;
|
|
62
|
+
type: RpcPacketType;
|
|
63
|
+
method: string;
|
|
64
|
+
data: D;
|
|
65
|
+
meta: M;
|
|
66
|
+
error?: RpcError;
|
|
67
|
+
env: RpcEnv;
|
|
68
|
+
constructor({ id, type, data, method, error, meta, }: RpcPacketOptions<D, M>, env: RpcEnvOptions);
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
interface RpcSerializer {
|
|
72
|
+
serialize<O = any>(obj: O): any;
|
|
73
|
+
deserialize<R = any>(obj: any): R;
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
declare enum RpcApplyType {
|
|
77
|
+
ON = "on",
|
|
78
|
+
REGISTER = "register"
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
type RpcContextConstructor<D = any, M extends Record<string, any> = Record<string, any>> = {
|
|
82
|
+
data: D;
|
|
83
|
+
meta: M;
|
|
84
|
+
packet: RpcPacket<D, M>;
|
|
85
|
+
};
|
|
86
|
+
declare abstract class RpcContext<D = any, M extends Record<string, any> = Record<string, any>> {
|
|
87
|
+
data: D;
|
|
88
|
+
meta: M;
|
|
89
|
+
packet: RpcPacket<D, M>;
|
|
90
|
+
constructor({ data, meta, packet }: RpcContextConstructor<D, M>);
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
type RpcNext = () => Promise<any>;
|
|
94
|
+
type RpcHandler<C extends RpcContext = RpcContext> = (ctx: C, next: RpcNext) => any;
|
|
95
|
+
|
|
96
|
+
export { CommonRpcErrorCode, MpEnv, RpcApplyType, RpcContext, RpcEnv, RpcError, RpcPacket, RpcPacketType, getRpcError };
|
|
97
|
+
export type { RpcContextConstructor, RpcEnvOptions, RpcErrorOptions, RpcHandler, RpcNext, RpcPacketOptions, RpcSerializer };
|
package/dist/index.cjs
ADDED
|
@@ -0,0 +1,390 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
const utils_index = require('./shared/rpc-core.Dn7eTH9H.cjs');
|
|
4
|
+
const rpcPacket = require('./shared/rpc-core.T_c3MAf6.cjs');
|
|
5
|
+
|
|
6
|
+
class RpcInterceptorManager {
|
|
7
|
+
handlers = [];
|
|
8
|
+
use(handler) {
|
|
9
|
+
this.handlers.push(handler);
|
|
10
|
+
return this.handlers.length - 1;
|
|
11
|
+
}
|
|
12
|
+
eject(id) {
|
|
13
|
+
if (this.handlers[id]) {
|
|
14
|
+
this.handlers[id] = null;
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
getHandlers() {
|
|
18
|
+
return this.handlers.filter((h) => h !== null);
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
class RpcOptions {
|
|
23
|
+
throwUnknownMethods = true;
|
|
24
|
+
maxPending = 1e3;
|
|
25
|
+
pendingTimeout = 1e4;
|
|
26
|
+
prefix = "";
|
|
27
|
+
serializer;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
const anyAbortSignal = (iterable) => {
|
|
31
|
+
const controller = new AbortController();
|
|
32
|
+
function abort() {
|
|
33
|
+
controller.abort(this.reason);
|
|
34
|
+
clean();
|
|
35
|
+
}
|
|
36
|
+
function clean() {
|
|
37
|
+
for (const signal of iterable) {
|
|
38
|
+
signal.removeEventListener("abort", abort);
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
for (const signal of iterable) {
|
|
42
|
+
if (signal.aborted) {
|
|
43
|
+
controller.abort(signal.reason);
|
|
44
|
+
break;
|
|
45
|
+
} else {
|
|
46
|
+
signal.addEventListener("abort", abort);
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
return controller.signal;
|
|
50
|
+
};
|
|
51
|
+
const timeoutAbortSignal = (ms) => {
|
|
52
|
+
const controller = new AbortController();
|
|
53
|
+
setTimeout(() => {
|
|
54
|
+
controller.abort("TimeoutError");
|
|
55
|
+
}, ms);
|
|
56
|
+
return controller.signal;
|
|
57
|
+
};
|
|
58
|
+
|
|
59
|
+
class RpcPendingStore {
|
|
60
|
+
constructor(options) {
|
|
61
|
+
this.options = options;
|
|
62
|
+
}
|
|
63
|
+
pendingRequests = /* @__PURE__ */ new Map();
|
|
64
|
+
processPending({ resolve, reject, packet }) {
|
|
65
|
+
if (!packet) {
|
|
66
|
+
return;
|
|
67
|
+
}
|
|
68
|
+
if (packet.error) {
|
|
69
|
+
reject(packet.error);
|
|
70
|
+
} else {
|
|
71
|
+
resolve(packet.data);
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
addPending({
|
|
75
|
+
packet,
|
|
76
|
+
reject,
|
|
77
|
+
resolve,
|
|
78
|
+
// TODO: sync abort signals both ways, so if request was aborted from client, it execution would also abort in registry
|
|
79
|
+
signal: externalSignal,
|
|
80
|
+
timeout
|
|
81
|
+
}) {
|
|
82
|
+
const { id, method } = packet;
|
|
83
|
+
if (!id) {
|
|
84
|
+
return;
|
|
85
|
+
}
|
|
86
|
+
const timeoutValue = timeout || this.options.pendingTimeout;
|
|
87
|
+
const combinedSignal = anyAbortSignal([
|
|
88
|
+
...externalSignal ? [externalSignal] : [],
|
|
89
|
+
...timeoutValue ? [timeoutAbortSignal(timeoutValue)] : []
|
|
90
|
+
]);
|
|
91
|
+
const onAbort = () => {
|
|
92
|
+
this.pendingRequests.delete(id);
|
|
93
|
+
const isTimeout = combinedSignal.reason?.name === "TimeoutError" || combinedSignal.reason === "TimeoutError";
|
|
94
|
+
const error = isTimeout ? rpcPacket.RpcError.timeout({
|
|
95
|
+
message: `RPC call ${method}:${id} timed out after ${timeoutValue}ms`,
|
|
96
|
+
method,
|
|
97
|
+
data: combinedSignal.reason
|
|
98
|
+
}) : new rpcPacket.RpcError({
|
|
99
|
+
method,
|
|
100
|
+
data: combinedSignal.reason,
|
|
101
|
+
message: combinedSignal.reason
|
|
102
|
+
});
|
|
103
|
+
this.processPending({
|
|
104
|
+
reject,
|
|
105
|
+
resolve,
|
|
106
|
+
packet: new rpcPacket.RpcPacket(
|
|
107
|
+
{ id, method, error, type: rpcPacket.RpcPacketType.RESPONSE },
|
|
108
|
+
{ target: utils_index.CURRENT_ENVIRONMENT }
|
|
109
|
+
)
|
|
110
|
+
});
|
|
111
|
+
};
|
|
112
|
+
if (combinedSignal.aborted) {
|
|
113
|
+
onAbort();
|
|
114
|
+
return;
|
|
115
|
+
}
|
|
116
|
+
if (this.options.maxPending && this.pendingRequests.size >= this.options.maxPending) {
|
|
117
|
+
const error = rpcPacket.RpcError.tooManyPendingRequests();
|
|
118
|
+
this.processPending({
|
|
119
|
+
reject,
|
|
120
|
+
resolve,
|
|
121
|
+
packet: new rpcPacket.RpcPacket(
|
|
122
|
+
{ id, method, error, type: rpcPacket.RpcPacketType.RESPONSE },
|
|
123
|
+
{ target: utils_index.CURRENT_ENVIRONMENT }
|
|
124
|
+
)
|
|
125
|
+
});
|
|
126
|
+
return;
|
|
127
|
+
}
|
|
128
|
+
combinedSignal.addEventListener("abort", onAbort, { once: true });
|
|
129
|
+
this.pendingRequests.set(id, async (packet2) => {
|
|
130
|
+
combinedSignal.removeEventListener("abort", onAbort);
|
|
131
|
+
this.pendingRequests.delete(id);
|
|
132
|
+
this.processPending({ reject, resolve, packet: packet2 });
|
|
133
|
+
});
|
|
134
|
+
}
|
|
135
|
+
resolvePending(packet) {
|
|
136
|
+
if (!packet.id || packet.type !== rpcPacket.RpcPacketType.RESPONSE) {
|
|
137
|
+
return;
|
|
138
|
+
}
|
|
139
|
+
const handler = this.pendingRequests.get(packet.id);
|
|
140
|
+
if (!handler) {
|
|
141
|
+
return;
|
|
142
|
+
}
|
|
143
|
+
handler(packet);
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
class RpcRegistry {
|
|
148
|
+
constructor(options) {
|
|
149
|
+
this.options = options;
|
|
150
|
+
}
|
|
151
|
+
globalMiddlewares = [];
|
|
152
|
+
callHandlers = /* @__PURE__ */ new Map();
|
|
153
|
+
triggerHandlers = /* @__PURE__ */ new Map();
|
|
154
|
+
use(...middlewares) {
|
|
155
|
+
this.globalMiddlewares.push(...middlewares);
|
|
156
|
+
}
|
|
157
|
+
isApplied(method, type) {
|
|
158
|
+
if (type === rpcPacket.RpcApplyType.ON) {
|
|
159
|
+
return this.triggerHandlers.has(method);
|
|
160
|
+
} else if (type === rpcPacket.RpcApplyType.REGISTER) {
|
|
161
|
+
return this.callHandlers.has(method);
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
register(method, ...stack) {
|
|
165
|
+
this.callHandlers.set(method, stack);
|
|
166
|
+
}
|
|
167
|
+
unregister(method) {
|
|
168
|
+
this.callHandlers.delete(method);
|
|
169
|
+
}
|
|
170
|
+
on(eventName, ...stack) {
|
|
171
|
+
if (!this.triggerHandlers.has(eventName)) {
|
|
172
|
+
this.triggerHandlers.set(eventName, []);
|
|
173
|
+
}
|
|
174
|
+
this.triggerHandlers.get(eventName).push(stack);
|
|
175
|
+
}
|
|
176
|
+
off(eventName, handler) {
|
|
177
|
+
const containers = this.triggerHandlers.get(eventName);
|
|
178
|
+
if (!containers) {
|
|
179
|
+
return;
|
|
180
|
+
}
|
|
181
|
+
const index = containers.findIndex(
|
|
182
|
+
(c) => c[c.length - 1] === handler
|
|
183
|
+
);
|
|
184
|
+
if (index !== -1) {
|
|
185
|
+
containers.splice(index, 1);
|
|
186
|
+
}
|
|
187
|
+
if (containers.length === 0) {
|
|
188
|
+
this.triggerHandlers.delete(eventName);
|
|
189
|
+
}
|
|
190
|
+
}
|
|
191
|
+
offAll(eventName) {
|
|
192
|
+
this.triggerHandlers.delete(eventName);
|
|
193
|
+
}
|
|
194
|
+
async execute(ctx) {
|
|
195
|
+
const { type, method } = ctx.packet;
|
|
196
|
+
if (type === rpcPacket.RpcPacketType.CALL) {
|
|
197
|
+
const stack = this.callHandlers.get(method);
|
|
198
|
+
if (!stack) {
|
|
199
|
+
if (this.options.throwUnknownMethods) {
|
|
200
|
+
throw rpcPacket.RpcError.methodNotFound({ method });
|
|
201
|
+
}
|
|
202
|
+
return;
|
|
203
|
+
}
|
|
204
|
+
return this.runStack(ctx, stack);
|
|
205
|
+
}
|
|
206
|
+
if (type === rpcPacket.RpcPacketType.TRIGGER) {
|
|
207
|
+
const listenerStacks = this.triggerHandlers.get(method);
|
|
208
|
+
if (!listenerStacks) {
|
|
209
|
+
return;
|
|
210
|
+
}
|
|
211
|
+
for (const stack of listenerStacks) {
|
|
212
|
+
this.runStack(ctx, stack).catch((err) => {
|
|
213
|
+
console.error("RPC UNHANDLDED REJECTION", err);
|
|
214
|
+
});
|
|
215
|
+
}
|
|
216
|
+
}
|
|
217
|
+
}
|
|
218
|
+
async runStack(ctx, handlers) {
|
|
219
|
+
const fullStack = [...this.globalMiddlewares, ...handlers];
|
|
220
|
+
let index = 0;
|
|
221
|
+
const next = async () => {
|
|
222
|
+
if (index >= fullStack.length) {
|
|
223
|
+
return;
|
|
224
|
+
}
|
|
225
|
+
const current = fullStack[index++];
|
|
226
|
+
try {
|
|
227
|
+
return await current?.(ctx, next);
|
|
228
|
+
} catch (err) {
|
|
229
|
+
throw rpcPacket.getRpcError(err, ctx.packet.method);
|
|
230
|
+
}
|
|
231
|
+
};
|
|
232
|
+
return next();
|
|
233
|
+
}
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
class RpcBase {
|
|
237
|
+
options;
|
|
238
|
+
registry;
|
|
239
|
+
pendingStore;
|
|
240
|
+
interceptors = {
|
|
241
|
+
request: new RpcInterceptorManager(),
|
|
242
|
+
response: new RpcInterceptorManager()
|
|
243
|
+
};
|
|
244
|
+
constructor(options = {}) {
|
|
245
|
+
this.options = Object.assign(new RpcOptions(), options);
|
|
246
|
+
this.registry = new RpcRegistry(this.options);
|
|
247
|
+
this.pendingStore = new RpcPendingStore(this.options);
|
|
248
|
+
}
|
|
249
|
+
async call(packet, options, remoteInfo) {
|
|
250
|
+
const interceptedPacket = await this.runRequestInterceptors(packet);
|
|
251
|
+
return this.internalCall(interceptedPacket, options, remoteInfo);
|
|
252
|
+
}
|
|
253
|
+
async trigger(packet, remoteInfo) {
|
|
254
|
+
const interceptedPacket = await this.runRequestInterceptors(packet);
|
|
255
|
+
this.internalTrigger(interceptedPacket, remoteInfo);
|
|
256
|
+
}
|
|
257
|
+
init() {
|
|
258
|
+
this.databus.listen(
|
|
259
|
+
(packet, remoteInfo) => this.handleIncoming(packet, remoteInfo)
|
|
260
|
+
);
|
|
261
|
+
}
|
|
262
|
+
async runRequestInterceptors(request) {
|
|
263
|
+
let req = { ...request };
|
|
264
|
+
for (const handler of this.interceptors.request.getHandlers()) {
|
|
265
|
+
req = await handler(req);
|
|
266
|
+
}
|
|
267
|
+
return req;
|
|
268
|
+
}
|
|
269
|
+
async runResponseInterceptors(response) {
|
|
270
|
+
let res = { ...response };
|
|
271
|
+
if (res.error) {
|
|
272
|
+
let error = res.error;
|
|
273
|
+
for (const handler of this.interceptors.response.getHandlers()) {
|
|
274
|
+
if (handler.onRejected) {
|
|
275
|
+
error = await handler.onRejected(error);
|
|
276
|
+
}
|
|
277
|
+
}
|
|
278
|
+
res.error = error;
|
|
279
|
+
return res;
|
|
280
|
+
}
|
|
281
|
+
for (const handler of this.interceptors.response.getHandlers()) {
|
|
282
|
+
if (handler.onFulfilled) {
|
|
283
|
+
res = await handler.onFulfilled(res);
|
|
284
|
+
}
|
|
285
|
+
}
|
|
286
|
+
return res;
|
|
287
|
+
}
|
|
288
|
+
async handleIncoming(packet, remoteInfo) {
|
|
289
|
+
if (packet.env.target !== utils_index.CURRENT_ENVIRONMENT) {
|
|
290
|
+
return this.forward(packet, remoteInfo);
|
|
291
|
+
}
|
|
292
|
+
if (packet.type === rpcPacket.RpcPacketType.RESPONSE) {
|
|
293
|
+
this.pendingStore.resolvePending(
|
|
294
|
+
await this.runResponseInterceptors(packet)
|
|
295
|
+
);
|
|
296
|
+
return;
|
|
297
|
+
}
|
|
298
|
+
const ctx = this.createContext(packet, remoteInfo);
|
|
299
|
+
try {
|
|
300
|
+
const result = await this.registry.execute(ctx);
|
|
301
|
+
if (packet.type === rpcPacket.RpcPacketType.CALL && packet.id) {
|
|
302
|
+
this.sendResponse(packet, result, remoteInfo);
|
|
303
|
+
}
|
|
304
|
+
} catch (err) {
|
|
305
|
+
if (packet.type === rpcPacket.RpcPacketType.CALL && packet.id) {
|
|
306
|
+
this.sendResponse(packet, null, remoteInfo, err);
|
|
307
|
+
}
|
|
308
|
+
}
|
|
309
|
+
}
|
|
310
|
+
sendResponse(original, data, remoteInfo, error) {
|
|
311
|
+
const response = new rpcPacket.RpcPacket(
|
|
312
|
+
{
|
|
313
|
+
id: original.id,
|
|
314
|
+
method: original.method,
|
|
315
|
+
type: rpcPacket.RpcPacketType.RESPONSE,
|
|
316
|
+
data,
|
|
317
|
+
error: error ? rpcPacket.getRpcError(error, original.method) : void 0
|
|
318
|
+
},
|
|
319
|
+
{ target: original.env.source }
|
|
320
|
+
);
|
|
321
|
+
this.databus.send(response, remoteInfo);
|
|
322
|
+
}
|
|
323
|
+
parseCallArgs(args) {
|
|
324
|
+
const [first, second, third] = args;
|
|
325
|
+
const isConfig = (obj) => {
|
|
326
|
+
return obj && typeof obj === "object" && ("timeout" in obj || "signal" in obj || "data" in obj || "meta" in obj);
|
|
327
|
+
};
|
|
328
|
+
if (args.length === 1 && isConfig(first)) {
|
|
329
|
+
return {
|
|
330
|
+
data: first.data,
|
|
331
|
+
meta: first.meta,
|
|
332
|
+
options: first
|
|
333
|
+
};
|
|
334
|
+
}
|
|
335
|
+
return {
|
|
336
|
+
data: first,
|
|
337
|
+
meta: second,
|
|
338
|
+
options: third
|
|
339
|
+
};
|
|
340
|
+
}
|
|
341
|
+
on(eventName, ...stack) {
|
|
342
|
+
this.registry.on(eventName, ...stack);
|
|
343
|
+
}
|
|
344
|
+
register(method, ...stack) {
|
|
345
|
+
this.registry.register(method, ...stack);
|
|
346
|
+
}
|
|
347
|
+
unregister(method) {
|
|
348
|
+
this.registry.unregister(method);
|
|
349
|
+
}
|
|
350
|
+
isApplied(method, type) {
|
|
351
|
+
return this.registry.isApplied(method, type);
|
|
352
|
+
}
|
|
353
|
+
off(eventName, handler) {
|
|
354
|
+
this.registry.off(eventName, handler);
|
|
355
|
+
}
|
|
356
|
+
offAll(eventName) {
|
|
357
|
+
this.registry.offAll(eventName);
|
|
358
|
+
}
|
|
359
|
+
use(...middlewares) {
|
|
360
|
+
this.registry.use(...middlewares);
|
|
361
|
+
}
|
|
362
|
+
}
|
|
363
|
+
|
|
364
|
+
class RpcDatabus {
|
|
365
|
+
constructor(options) {
|
|
366
|
+
this.options = options;
|
|
367
|
+
}
|
|
368
|
+
get RPC_INVOKE_EVENT() {
|
|
369
|
+
return `${this.options.prefix}__rpc:invoke`;
|
|
370
|
+
}
|
|
371
|
+
get RPC_RESPONSE_EVENT() {
|
|
372
|
+
return `${this.options.prefix}__rpc:response`;
|
|
373
|
+
}
|
|
374
|
+
serialize(obj) {
|
|
375
|
+
return this.options.serializer?.serialize(obj) ?? obj;
|
|
376
|
+
}
|
|
377
|
+
deserialize(obj) {
|
|
378
|
+
return this.options.serializer?.deserialize(obj) ?? obj;
|
|
379
|
+
}
|
|
380
|
+
onPacketReceived;
|
|
381
|
+
listen(cb) {
|
|
382
|
+
this.onPacketReceived = cb;
|
|
383
|
+
}
|
|
384
|
+
}
|
|
385
|
+
|
|
386
|
+
exports.RpcBase = RpcBase;
|
|
387
|
+
exports.RpcDatabus = RpcDatabus;
|
|
388
|
+
exports.RpcOptions = RpcOptions;
|
|
389
|
+
exports.RpcPendingStore = RpcPendingStore;
|
|
390
|
+
exports.RpcRegistry = RpcRegistry;
|