surrogate
Version:
Object method hooks made easy
59 lines • 2.6 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.SurrogateClassWrapper = void 0;
const identifier_1 = require("../identifier");
const defaults_1 = require("@status/defaults");
const which_1 = require("../which");
const proxy_1 = require("../proxy");
class SurrogateClassWrapper {
constructor(options) {
this.options = options;
}
construct(Klass, args, Target) {
const { locateWith = Klass } = this.options;
const decoratorMap = SurrogateClassWrapper.retrieveTargetDecoratorMap(locateWith);
const wrappedInstance = proxy_1.SurrogateProxy.wrap(Reflect.construct(Klass, args, Target), this.options);
const eventManager = wrappedInstance.getSurrogate();
const identifier = new identifier_1.MethodIdentifier(wrappedInstance);
this.applyDecorators(eventManager, decoratorMap, identifier);
return wrappedInstance;
}
applyDecorators(eventManager, decoratorMap, identifier) {
const methods = identifier.instanceMethodNames();
Object.entries(decoratorMap).forEach(([action, options]) => {
const events = identifier.getApplicableMethods(action, methods);
Object.entries(options).forEach(([which, handlerOptions]) => {
events.forEach((event) => {
this.registerHandlers(eventManager, handlerOptions, which, event);
});
});
});
}
registerHandlers(eventManager, handlerOptions, hook, event) {
handlerOptions.forEach(({ handler, options }) => {
eventManager.registerHook(event, hook, handler, options);
});
}
static wrap(klass, options) {
return new Proxy(klass, new SurrogateClassWrapper(options));
}
static addDecorators(klass, type, event, surrogateDecoratorOptions) {
const decoratorMap = this.retrieveTargetDecoratorMap(klass);
decoratorMap[event][type].push(...surrogateDecoratorOptions);
return this.decoratorMap.set(klass, decoratorMap);
}
static retrieveTargetDecoratorMap(klass) {
var _a;
return ((_a = this.decoratorMap.get(klass)) !== null && _a !== void 0 ? _a : (0, defaults_1.wrapDefaults)({
defaultValue: {
[which_1.HookType.PRE]: [],
[which_1.HookType.POST]: [],
},
setUndefined: true,
shallowCopy: false,
}));
}
}
SurrogateClassWrapper.decoratorMap = new Map();
exports.SurrogateClassWrapper = SurrogateClassWrapper;
//# sourceMappingURL=surrogateClassWrapper.js.map