UNPKG

@teambit/harmony

Version:
109 lines 3.92 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.HookRegistry = void 0; exports.ExtensionDecorator = ExtensionDecorator; exports.provider = provider; exports.register = register; exports.createHook = createHook; exports.hook = hook; const map = {}; /** * decorator for an Harmony extension. */ function ExtensionDecorator({ name, dependencies } = {}) { function classDecorator(constructor) { Reflect.defineMetadata('harmony:name', name || constructor.name, constructor); Reflect.defineMetadata('harmony:dependencies', calculateDependnecies(constructor, dependencies), constructor); } return classDecorator; } function provider() { return function (target, propertyKey, descriptor) { const keys = Reflect.getMetadata('design:paramtypes', descriptor); }; } // @hack todo: must be defined and assigned from a single location function providerFn(classExtension) { return classExtension.provide ? classExtension.provide : classExtension.provider; } function calculateDependnecies(classExtension, deps) { function fromMetadata() { const provider = providerFn(classExtension); if (provider) { // // TODO: check why Reflect.getMetadataKeys(provider) is empty and how to access method param types. // console.log(Reflect.getMetadataKeys(classExtension.provide)) return []; } return Reflect.getMetadata('design:paramtypes', classExtension); } const dependnecies = deps ? deps : fromMetadata() || []; const hookDeps = classExtension.__hookDeps ? classExtension.__hookDeps : []; return dependnecies.concat(hookDeps) || []; } // :TODO refactor this asap to handle harmony objects properly function register(extension, name) { return function (target, propertyKey, descriptor) { // if (!target.constructor.__hookDeps) Reflect.defineMetadata('harmony:subscriptions', [extension], target.constructor); // else target.constructor.__hookDeps.push(extension); const extensionName = Reflect.getMetadata('harmony:name', extension); if (!map[extensionName]) { map[extensionName] = {}; } const hook = map[extensionName][name || propertyKey]; // if (!hook) throw new HookNotFound(); if (!hook) return; hook.register(target[propertyKey]); }; } function createHook() { const randomId = Math.random().toString(36).substring(2); map[randomId] = HookRegistry.create(); const decorator = function (target, propertyKey, descriptor) { const registry = map[randomId]; registry.register(descriptor.value); }; decorator.hash = randomId; return decorator; } function hook(name) { return function (target, propertyKey) { let instance = HookRegistry.create(); const extensionName = Reflect.getMetadata('harmony:name', target.constructor); const hookName = name || propertyKey; if (!map[extensionName]) map[extensionName] = { [hookName]: instance }; else map[extensionName][hookName] = instance; Object.defineProperty(target, propertyKey, { get: () => { return instance; }, set: (value) => { instance = value; } }); }; } class HookRegistry { constructor(fillers, hash) { this.fillers = fillers; this.hash = hash; } register(filler) { this.fillers.push(filler); } list() { // return map[this.name][name] || []; return this.fillers; } static of(hook) { return map[hook.hash]; } // hack due to https://github.com/microsoft/TypeScript/issues/4881 static create() { return new HookRegistry([]); } } exports.HookRegistry = HookRegistry; //# sourceMappingURL=decorator.js.map