UNPKG

reactant-share

Version:

A framework for building shared web applications with Reactant

68 lines (66 loc) 2.33 kB
import { containerKey, identifierKey, Service } from 'reactant'; import { proxyServerActionName } from './constants'; import { ProxyExec } from './interfaces'; import { PortDetector } from './modules/portDetector'; /** * Proxy execute On the client side. * * ## Description * * `fork()` is very similar to the actor model, * which transfers the corresponding module method to all client threads for execution and returns the result from the first client's response. * * Note: It does not create new threads, it always runs on all client thread that have already been created. * * reference: https://en.wikipedia.org/wiki/Actor_model */ export const fork = ((module, key, _args, _options) => { const args = _args ?? []; const { clientIds, portName, ...options } = _options ?? {}; const method = module[key]; if (typeof key !== 'string') { throw new Error(`'fork()' is valid only for method name with string type.`); } if (typeof method !== 'function') { throw new Error( `The property '${key}'' must be a method in class '${module.constructor.name}'.` ); } if (!Array.isArray(args)) { throw new Error(`The parameters of the method '${key}' must be an array.`); } const target: Service = module; if (target[containerKey]!.isBound(PortDetector)) { const portDetector = target[containerKey]!.get(PortDetector); if (!portDetector.isServer) { throw new Error(`'fork()' should be running in server port.`); } if (__DEV__) { const moduleName = target.constructor.name; if (/^@@reactant/.test(target[identifierKey]!)) { throw new Error( `The identifier '${target[identifierKey]}' is a temporary string, please set 'provide' for the module '${moduleName}' or the 'name' field of the module '${moduleName}'.` ); } } if (!portDetector.transports.server) { return Promise.reject( new Error(`Detected that the current server transport does not exist.`) ); } return portDetector.transports.server.emit( { ...options, name: proxyServerActionName, }, { module: target[identifierKey]!, method: key, args, clientIds, portName, } ); } return (method as Function).apply(target, args); }) as ProxyExec;