Add support for wrapping generators
Opened this issue · 0 comments
ruipin commented
Because generator functions are synctactic sugar around a Generator
factory, trying to wrap a generator the naive way will trigger a libWrapper exception:
game.generatorFn = function*(...args) {
yield args[0];
yield args[1];
yield args[2];
};
libWrapper.register('package_id', 'game.generatorFn', function*(wrapped, ...args) {
const gen = wrapped(...args);
yield gen.next().value+1;
yield gen.next().value+1;
yield gen.next().value+1;
}, "WRAPPER");
console.log(game.generatorFn(1).next());
// <- The wrapper for 'game.generatorFn' registered by module 'package_id' with type WRAPPER did not chain the call to the next wrapper, which breaks a libWrapper API requirement. This wrapper will be unregistered.
A workaround is to divide the wrapper into two parts, a factory, and a generator:
game.generatorFn = function*(...args) {
yield args[0];
yield args[1];
yield args[2];
};
function* generatorFn_wrapped(wrapped, ...args) {
yield wrapped.next().value+1;
yield wrapped.next().value+1;
yield wrapped.next().value+1;
}
libWrapper.register('package_id', 'game.generatorFn', function(wrapped, ...args) {
return generatorFn_wrapped(wrapped(...args), ...args);
}, "WRAPPER");
console.log(game.generatorFn(1,2,3).next().value);
// <- 2
It might be a good idea to have libWrapper do this automatically when it detects the wrapper function is a generator. When libWrapper.register
detects that the wrapper function is a generator, it should automatically create a corresponding factory, and register that instead, similar to above.
To detect whether a function is a generator, the following StackOverflow thread is useful:
https://stackoverflow.com/questions/21559365/how-to-identify-an-es6-generator