Support nested methods.
This commit is contained in:
parent
e46c929761
commit
e7622c8558
@ -21,10 +21,37 @@ function tryJSON(type, destination, id, data) {
|
||||
}
|
||||
}
|
||||
|
||||
function getPaths(obj, prefix = '') {
|
||||
return Object.keys(obj)
|
||||
.map(key => {
|
||||
const prop = obj[key];
|
||||
const path = `${prefix}${key}`;
|
||||
if (typeof prop === 'function') {
|
||||
return path;
|
||||
}
|
||||
return getPaths(prop, path + '.');
|
||||
})
|
||||
.reduce((a, b) => a.concat(b), []);
|
||||
}
|
||||
|
||||
function traverseObj(obj, pathStr, assignValue) {
|
||||
const path = pathStr.split('.');
|
||||
const last = path.pop();
|
||||
const ptr = path.reduce(
|
||||
(acc, next) => (acc[next] === undefined ? (acc[next] = {}) : acc[next]),
|
||||
obj
|
||||
);
|
||||
if (assignValue) {
|
||||
return (ptr[last] = assignValue);
|
||||
}
|
||||
return ptr[last];
|
||||
}
|
||||
|
||||
export function WorkerPortal(context, worker, isSlave, serialize) {
|
||||
const responseMap = new Map();
|
||||
const _worker = worker || self;
|
||||
const contextIndex = Object.keys(context);
|
||||
const contextIndex = getPaths(context);
|
||||
const methods = contextIndex.map(path => traverseObj(context, path));
|
||||
const _serialize = serialize
|
||||
? (type, destination, id, params) => serialize(type, destination, id, params, tryJSON)
|
||||
: tryJSON;
|
||||
@ -66,7 +93,7 @@ export function WorkerPortal(context, worker, isSlave, serialize) {
|
||||
// If we have received an RPC call, execute and respond.
|
||||
let thennable;
|
||||
try {
|
||||
thennable = context[contextIndex[destination]].apply(null, params);
|
||||
thennable = methods[destination].apply(null, params);
|
||||
} catch (e) {
|
||||
_reject(e);
|
||||
}
|
||||
@ -94,8 +121,8 @@ export function WorkerPortal(context, worker, isSlave, serialize) {
|
||||
function resolveExternalInterfaceFactory(resolve) {
|
||||
return (linkedFunctionNames, ...rest) => {
|
||||
const externalInterface = {};
|
||||
linkedFunctionNames.forEach((fnName, index) => {
|
||||
externalInterface[fnName] = injectionPointFactory(index);
|
||||
linkedFunctionNames.forEach((pathStr, index) => {
|
||||
traverseObj(externalInterface, pathStr, injectionPointFactory(index));
|
||||
});
|
||||
enabled = true;
|
||||
resolve(externalInterface);
|
||||
@ -118,8 +145,7 @@ export function WorkerPortal(context, worker, isSlave, serialize) {
|
||||
if (isSlave) {
|
||||
return new Promise(resolve => {
|
||||
contextIndex.splice(0, 0, '__init', '__cleanupSlave');
|
||||
context.__init = resolveExternalInterfaceFactory(resolve);
|
||||
context.__cleanupSlave = cleanup;
|
||||
methods.splice(0, 0, resolveExternalInterfaceFactory(resolve), cleanup);
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@ -42,7 +42,13 @@ test('Workers can call and respond equally', async t => {
|
||||
|
||||
const slave = WorkerPortal(
|
||||
{
|
||||
slaveAdd: (a, b) => a + b
|
||||
slaveAdd: (a, b) => a + b,
|
||||
math: {
|
||||
multiply: (a, b) => a * b,
|
||||
lib: {
|
||||
pow: (a, b) => Math.pow(a, b)
|
||||
}
|
||||
}
|
||||
},
|
||||
a,
|
||||
true
|
||||
@ -58,11 +64,14 @@ test('Workers can call and respond equally', async t => {
|
||||
const masterApi = await master;
|
||||
const slaveApi = await slave;
|
||||
|
||||
t.deepEqual(Object.keys(masterApi), ['__init', '__cleanupSlave', 'slaveAdd', '_cleanup']);
|
||||
t.deepEqual(Object.keys(masterApi), ['__init', '__cleanupSlave', 'slaveAdd', 'math', '_cleanup']);
|
||||
t.deepEqual(Object.keys(masterApi.math), ['multiply', 'lib']);
|
||||
t.deepEqual(Object.keys(slaveApi), ['masterSubtract']);
|
||||
|
||||
t.is(await slaveApi.masterSubtract(9, 2), 7);
|
||||
t.is(await masterApi.slaveAdd(9, 2), 11);
|
||||
t.is(await masterApi.math.multiply(9, 2), 18);
|
||||
t.is(await masterApi.math.lib.pow(9, 2), 81);
|
||||
|
||||
t.is(await masterApi.slaveAdd(5, 2), 7);
|
||||
t.is(await slaveApi.masterSubtract(2, 2), 0);
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user