代码拉取完成,页面将自动刷新
import { EventEmitter } from 'node:events'
import { AsyncLocalStorage } from 'node:async_hooks'
import { genKVMethods } from './utils'
// import { wrappedActions, actionMiddlewares, middlewares } from './middleware'
export interface ReturnsBody {
traceId: string,
success: boolean,
body?: any,
error?: {
message: string,
stack: string,
}
}
export class Context {
// 请求溯源ID
traceId? = ''
}
export const asyncStore = new AsyncLocalStorage<Context> ( )
export const eventHub = new EventEmitter ( )
/**
* sourceMethods => methods
*/
let sourceMethods: any = { }
/**
* the kvMethods is all actions refs [has bind this]
*/
export const kvMethods: Map<string, Function> = new Map ( )
export const sourceKVMethods: Map<string, Function> = new Map ( )
export function setMethods ( methods: any ) {
sourceMethods = methods
kvMethods.clear ( )
sourceKVMethods.clear ( )
genKVMethods ( methods, kvMethods, sourceKVMethods )
}
export function getMethods ( ) {
return sourceMethods
}
export function on ( event: 'request', listener: ( action: string, params: any[], context: Context ) => void ): void
export function on ( event: 'success', listener: ( action: string, params: any[], context: Context, result: ReturnsBody ) => void ): void
export function on ( event: 'fail', listener: ( action: string, params: any[], context: Context, error: Error ) => void ): void
export function on ( event: string, listener: ( ...args: any[] ) => void ) {
return eventHub.on ( event, listener )
}
/**
* Call an Function on RPC server
* @param action
* @param params
* @param context
* @returns
*/
export async function call ( action: string, params: any[]=[], context: Context ): Promise<ReturnsBody> {
if ( !Array.isArray ( params ) ) params = [ params ]
const { traceId } = context
eventHub.emit ( 'request', action, params, context )
const returns: ReturnsBody = {
traceId,
success: false
}
try {
const result = await execute ( action, [ ...params ], context )
returns.body = result
returns.success = true
eventHub.emit ( 'success', action, params, context, result )
} catch ( error ) {
returns.error = {
message: error.message,
stack: error.stack
}
eventHub.emit ( 'fail', action, params, context, error )
} finally {
return returns
}
}
export async function execute ( action: string, params: Array<any>, context: Context ) {
const __proxy = '__proxy', _proxy = '_proxy'
if ( __proxy === action || _proxy === action || action.endsWith ( _proxy ) ) throw new Error ( 'Invalid Action[' + action + ']' )
const methods = kvMethods
// 目标函数
const target = methods.get ( action )
// 目标代理函数
const targetProxy = methods.get ( action + _proxy )
// 即不存在目标也不存在目标代理时, 报错函数不存在
if ( !target && !targetProxy ) throw new Error ( 'Unknown Action [' + action + ']' )
asyncStore.enterWith ( context )
// ============================ PROXY BEGIN ============================
// 最顶层代理
const topProxy = methods.get ( __proxy )
if ( topProxy ) {
const proxyReturns = await topProxy ( action, params, context )
if ( proxyReturns !== undefined ) return proxyReturns
}
// 'x.y.z' => [ 'x', 'y', 'z' ]
const nameStack = action.split ( '.' ), size = nameStack.length - 1
let index = -1, proxyPrefix = ''
// 根代理遍历
while ( ++index < size ) {
// x.
// x.y.
proxyPrefix += nameStack [ index ] + '.'
// x.__proxy
// x.y.__proxy
const rootProxy = methods.get ( proxyPrefix + __proxy )
// x.__proxy ( 'y.z', ... )
// x.y.__proxy ( 'z', ... )
if ( rootProxy ) {
const proxyReturns = await rootProxy ( nameStack.slice ( index ).join ( '.' ), params, context )
if ( proxyReturns !== undefined ) return proxyReturns
}
}
// 同级代理
const layerProxy = methods.get ( proxyPrefix + _proxy )
if ( layerProxy ) {
const proxyReturns = await layerProxy ( nameStack [ index ], params, context )
if ( proxyReturns !== undefined ) return proxyReturns
}
if ( targetProxy ) {
const proxyReturns = await targetProxy ( params, context )
if ( proxyReturns !== undefined ) return proxyReturns
}
// ============================= PROXY END =============================
// make sure target action execute after all proxies
if ( target ) {
/*
const sourceMethod = wrappedActions.get ( action )
const middlewareNames = actionMiddlewares.get ( sourceMethod )
if ( middlewareNames && middlewareNames.length ) for ( const name of middlewareNames ) {
const middleware = middlewares.get ( name )
await middleware ( action, params, context )
}
*/
return await target ( ...params )
}
}
此处可能存在不合适展示的内容,页面不予展示。您可通过相关编辑功能自查并修改。
如您确认内容无涉及 不当用语 / 纯广告导流 / 暴力 / 低俗色情 / 侵权 / 盗版 / 虚假 / 无价值内容或违法国家有关法律法规的内容,可点击提交进行申诉,我们将尽快为您处理。