Compare commits
3 Commits
809a3759d9
...
ebb9ed21ad
| Author | SHA1 | Date | |
|---|---|---|---|
| ebb9ed21ad | |||
| 720a79ca7a | |||
| 500e7c8fa6 |
@@ -11,15 +11,13 @@ export interface BaseHookCtx {
|
||||
|
||||
export interface CallOutgoingBeforeCtx extends BaseHookCtx {
|
||||
session: RPCSession;
|
||||
options: {
|
||||
fnPath: string;
|
||||
args: any[];
|
||||
};
|
||||
options: unknown;
|
||||
setOptions: (opt: unknown) => void;
|
||||
}
|
||||
|
||||
export interface CallOutgoingCtx extends CallOutgoingBeforeCtx {
|
||||
result: any;
|
||||
setResult: (data: any) => void;
|
||||
result: unknown;
|
||||
setResult: (res: unknown) => void;
|
||||
}
|
||||
|
||||
export interface CallIncomingBeforeCtx extends BaseHookCtx {
|
||||
@@ -51,8 +49,8 @@ export interface RPCPlugin extends RPCPluginHooks {
|
||||
}
|
||||
|
||||
export abstract class AbstractRPCPlugin implements RPCPlugin {
|
||||
abstract onInit?(): void;
|
||||
abstract onDestroy?(): void;
|
||||
// abstract onInit?(): void;
|
||||
// abstract onDestroy?(): void;
|
||||
abstract onCallOutgoingBefore?(ctx: CallOutgoingBeforeCtx): NormalMethodReturn;
|
||||
abstract onCallOutgoing?(ctx: CallOutgoingCtx): NormalMethodReturn;
|
||||
abstract onCallIncomingBefore?(ctx: CallIncomingBeforeCtx): NormalMethodReturn;
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { isPublicMethod, ToDeepPromise } from "@/utils/utils";
|
||||
import { isArray, isObject, isPublicMethod, ToDeepPromise } from "@/utils/utils";
|
||||
import { RPCConnection } from "./RPCConnection";
|
||||
import { RPCHandler } from "./RPCHandler";
|
||||
import { RPCProvider } from "./RPCProvider";
|
||||
@@ -8,6 +8,7 @@ import { RPCError, RPCErrorCode } from "./RPCError";
|
||||
import { makeCallPacket, makeCallResponsePacket, parseCallPacket, parseCallResponsePacket } from "./RPCCommon";
|
||||
import { RPCPacket } from "./RPCPacket";
|
||||
import { EventEmitter } from "@/utils/EventEmitter";
|
||||
import { createHookRunner } from "./RPCPlugin";
|
||||
|
||||
function getProviderFunction(provider: RPCProvider, fnPath: string):
|
||||
[(...args: any[]) => Promise<any>, object] | null {
|
||||
@@ -111,6 +112,45 @@ export class RPCSession {
|
||||
});
|
||||
}
|
||||
|
||||
function setOptions(opt: unknown) {
|
||||
if (!isObject(opt)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if ('fnPath' in opt && 'args' in opt && 'timeout' in opt) {
|
||||
const { fnPath, args, timeout } = opt;
|
||||
if (typeof fnPath !== 'string') {
|
||||
return;
|
||||
}
|
||||
if (!isArray(args)) {
|
||||
return;
|
||||
}
|
||||
if (typeof timeout !== 'number') {
|
||||
return;
|
||||
}
|
||||
options = {
|
||||
...options,
|
||||
fnPath,
|
||||
args,
|
||||
timeout,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const hookRunner = createHookRunner(this.rpcHandler.getPlugins(), 'onCallOutgoingBefore');
|
||||
await hookRunner({
|
||||
session: this,
|
||||
options: { ...options },
|
||||
setOptions,
|
||||
});
|
||||
|
||||
/** due to `await hookRunner` */
|
||||
if (this.connection.closed) {
|
||||
throw new RPCError({
|
||||
errorCode: RPCErrorCode.CONNECTION_DISCONNECTED,
|
||||
});
|
||||
}
|
||||
|
||||
const { fnPath, args } = options;
|
||||
const packet = makeCallPacket({
|
||||
fnPath,
|
||||
@@ -135,28 +175,75 @@ export class RPCSession {
|
||||
})();
|
||||
|
||||
const handleCallResponsePacket = (packet: RPCPacket) => {
|
||||
const result = parseCallResponsePacket(packet);
|
||||
if (result === null) {
|
||||
return reject(new RPCError({
|
||||
let result = parseCallResponsePacket(packet);
|
||||
function setResult(res: unknown) {
|
||||
if (!isObject(res)) {
|
||||
return;
|
||||
}
|
||||
|
||||
const { success, error } = res;
|
||||
|
||||
if (typeof success === 'object' && typeof error === 'object') {
|
||||
if (success && !error) {
|
||||
if ('data' in success) {
|
||||
result = {
|
||||
success: { data: success.data },
|
||||
error: null,
|
||||
}
|
||||
}
|
||||
} else if (!success && error) {
|
||||
const { errorCode, reason } = error;
|
||||
if (typeof errorCode === 'number' && typeof reason === 'string') {
|
||||
result = {
|
||||
success: null,
|
||||
error: {
|
||||
errorCode,
|
||||
reason,
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const hookRunner = createHookRunner(this.rpcHandler.getPlugins(), 'onCallOutgoing');
|
||||
hookRunner({
|
||||
session: this,
|
||||
options: { ...options },
|
||||
setOptions,
|
||||
result,
|
||||
setResult,
|
||||
}).then(() => {
|
||||
if (result === null) {
|
||||
return reject(new RPCError({
|
||||
errorCode: RPCErrorCode.UNKNOWN_ERROR,
|
||||
}));;
|
||||
}
|
||||
|
||||
const { success, error } = result;
|
||||
if (success) {
|
||||
return resolve(success.data);
|
||||
}
|
||||
|
||||
if (error) {
|
||||
return reject(new RPCError({
|
||||
errorCode: error.errorCode,
|
||||
reason: error.reason
|
||||
}));
|
||||
}
|
||||
|
||||
reject(new RPCError({
|
||||
errorCode: RPCErrorCode.UNKNOWN_ERROR,
|
||||
}));;
|
||||
}
|
||||
}).catch((e) => {
|
||||
if (e instanceof RPCError) {
|
||||
return reject(e);
|
||||
}
|
||||
|
||||
const { success, error } = result;
|
||||
if (success) {
|
||||
return resolve(success.data);
|
||||
}
|
||||
|
||||
if (error) {
|
||||
return reject(new RPCError({
|
||||
errorCode: error.errorCode,
|
||||
reason: error.reason
|
||||
}));
|
||||
}
|
||||
|
||||
return reject(new RPCError({
|
||||
errorCode: RPCErrorCode.UNKNOWN_ERROR,
|
||||
}));;
|
||||
reject(new RPCError({
|
||||
errorCode: RPCErrorCode.UNKNOWN_ERROR,
|
||||
}))
|
||||
})
|
||||
}
|
||||
this.callResponseEmitter.once(packet.id, handleCallResponsePacket);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user