dev: add Invoker

This commit is contained in:
KernelDeimos 2024-07-25 15:32:16 -04:00 committed by Eric Dubé
parent 9e38e048c1
commit 20b58ddcb5
2 changed files with 91 additions and 0 deletions

View File

@ -0,0 +1,53 @@
const { AdvancedBase } = require("../..");
class Invoker extends AdvancedBase {
static create ({
decorators,
delegate,
}) {
const invoker = new Invoker();
invoker.decorators = decorators;
invoker.delegate = delegate;
return invoker;
}
async run (args) {
let fn = this.delegate;
const decorators = this.decorators;
for ( let i = decorators.length-1 ; i >= 0 ; i-- ) {
const dec = decorators[i];
fn = this.add_dec_(dec, fn);
}
return await fn(args);
}
add_dec_ (dec, fn) {
return async (args) => {
try {
if ( dec.on_call ) {
args = await dec.on_call(args);
}
let result = await fn(args);
if ( dec.on_return ) {
result = await dec.on_return(result);
}
return result;
} catch (e) {
if ( ! dec.on_error ) throw e;
let cancel = false;
const a = {
error () { return e },
cancel_error () { cancel = true; },
};
const result = await dec.on_error(a);
if ( cancel ) {
return result;
}
throw result ?? e;
}
}
}
}
module.exports = {
Invoker,
};

View File

@ -19,6 +19,7 @@
const { expect } = require('chai');
const { BasicBase } = require('../src/bases/BasicBase');
const { AdvancedBase } = require('../src/AdvancedBase');
const { Invoker } = require('../src/libs/invoker');
class ClassA extends BasicBase {
static STATIC_OBJ = {
@ -70,3 +71,40 @@ describe('AdvancedBase', () => {
});
});
describe('lib:invoker', () => {
it('works', async () => {
const invoker = Invoker.create({
decorators: [
{
name: 'uphill both ways',
on_call: (args) => {
return {
...args,
n: args.n + 1,
};
},
on_return: (result) => {
return {
n: result.n + 1,
};
},
},
{
name: 'error number five',
on_error: a => {
a.cancel_error();
return { n: 5 };
},
}
],
async delegate (args) {
const { n } = args;
if ( n === 3 ) {
throw new Error('test error');
}
return { n: 'oops' };
}
});
expect(await invoker.run({ n: 2 })).to.deep.equal({ n: 6 });
});
});