UNPKG

@ch1/rpc

Version:

JavaScript Remote Procedure Call (RPC)

83 lines 2.89 kB
/** * Functions related to creating and using remote objects */ import * as rpc from './remote-procedure'; import { createTypeError, isFunction, isDictionary, isObject, isRPCDefaultAsync, safeInvoke, } from './utils'; export function getFinalFunction(remote, fnName) { const names = fnName.split('.').filter(Boolean); // invalid function name case if (names.length === 0) { return createTypeError(`getFinalFunction: ${fnName} not found on remote`); } // "first level" case if (names.length === 1) { if (isFunction(remote[names[0]])) { return remote[names[0]]; } return createTypeError(`getFinalFunction: ${fnName} is not a function: ` + typeof remote[names[0]]); } // invalid sub object case if (!remote[names[0]]) { return createTypeError(`getFinalFunction: ${names[0]} is not a ` + 'namespace (sub-object) on remote'); } // sub object case if (names.length === 2) { return getFinalFunction(remote[names[0]], names[1]); } // deeper object case return getFinalFunction(remote[names.shift()], names.join('.')); } /** * Safely finds and executes a proxy for a remote procedure */ export function safeCall(c, fnName, args) { const fn = getFinalFunction(c.remote, fnName); if (!Array.isArray(args)) { args = []; } if (fn instanceof Error) { return fn; } return safeInvoke(fn, args); } export function create(c, callbacks, remoteDesc, remote, prefix) { remoteDesc = remoteDesc || Object.create(null); remote = remote || Object.create(null); return Object.keys(remoteDesc).reduce((state, prop) => { const desc = remoteDesc[prop]; prefix = prefix || ''; if (isDictionary(desc)) { state[prop] = create(c, callbacks, desc, remote[prop], prop + '.'); } else if (isRPCDefaultAsync(desc)) { state[prop] = rpc.create(c, callbacks, prefix + prop, desc); } return state; }, remote); } export function createRemoteDescFrom(c, remote, remoteDesc) { remote = remote || Object.create(null); remoteDesc = remoteDesc || Object.create(null); const newRemoteDesc = Object.create(null); /* tslint:disable forin */ for (let prop in remote) { if (isObject(remote[prop])) { let newDesc; if (isDictionary(remoteDesc[prop])) { newDesc = remoteDesc[prop]; } else { newDesc = Object.create(null); } newRemoteDesc[prop] = createRemoteDescFrom(c, remote[prop], newDesc); } if (isFunction(remote[prop])) { const type = remoteDesc[prop] || c.defaultAsyncType; newRemoteDesc[prop] = type; } } return newRemoteDesc; } //# sourceMappingURL=remote.js.map