UNPKG

@v4fire/client

Version:

V4Fire client core library

145 lines (119 loc) 2.99 kB
/*! * V4Fire Client Core * https://github.com/V4Fire/Client * * Released under the MIT license * https://github.com/V4Fire/Client/blob/master/LICENSE */ import { defProp } from 'core/const/props'; import type { ComponentMeta } from 'core/component/interface'; /** * Iterates over a prototype of a component constructor and adds methods/accessors to the specified meta object * * @param meta * @param [constructor] */ export function addMethodsToMeta(meta: ComponentMeta, constructor: Function = meta.constructor): void { const proto = constructor.prototype, ownProps = Object.getOwnPropertyNames(proto), replace = !meta.params.flyweight; const { componentName: src, props, fields, computedFields, systemFields, accessors, methods } = meta; for (let i = 0; i < ownProps.length; i++) { const key = ownProps[i]; if (key === 'constructor') { continue; } const desc = <PropertyDescriptor>Object.getOwnPropertyDescriptor(proto, key); // Methods if ('value' in desc) { const fn = desc.value; if (!Object.isFunction(fn)) { continue; } methods[key] = Object.assign(methods[key] ?? {replace, watchers: {}, hooks: {}}, {src, fn}); // Accessors } else { const propKey = `${key}Prop`, storeKey = `${key}Store`; let metaKey; // Computed fields are cached by default if ( key in computedFields || !(key in accessors) && (props[propKey] || fields[storeKey] || systemFields[storeKey]) ) { metaKey = 'computedFields'; } else { metaKey = 'accessors'; } let field; if (props[key] != null) { field = props; } else if (fields[key] != null) { field = fields; } else { field = systemFields; } const obj = meta[metaKey]; // If we already have a property by this key, like a prop or a field, // we need to delete it to correct override if (field[key] != null) { Object.defineProperty(proto, key, defProp); delete field[key]; } const old = obj[key], // eslint-disable-next-line @typescript-eslint/unbound-method set = desc.set ?? old?.set, // eslint-disable-next-line @typescript-eslint/unbound-method get = desc.get ?? old?.get; // For using "super" within a setter we also create a method with a name of form `${key}Setter` if (set != null) { const k = `${key}Setter`; proto[k] = set; meta.methods[k] = { src, replace, fn: set, watchers: {}, hooks: {} }; } // For using "super" within a getter we also create a method with a name of form `${key}Getter` if (get != null) { const k = `${key}Getter`; proto[k] = get; meta.methods[k] = { src, replace, fn: get, watchers: {}, hooks: {} }; } obj[key] = Object.assign(obj[key] ?? {replace}, { src, // eslint-disable-next-line @typescript-eslint/unbound-method get: desc.get ?? old?.get, set }); } } }