UNPKG

@v4fire/client

Version:

V4Fire client core library

264 lines (208 loc) • 5.26 kB
/*! * V4Fire Client Core * https://github.com/V4Fire/Client * * Released under the MIT license * https://github.com/V4Fire/Client/blob/master/LICENSE */ import { metaPointers, PARENT } from 'core/component/const'; import type { ComponentMeta, StrictModDeclVal } from 'core/component/interface'; /** * Inherits the specified meta object from another meta object. * The function modifies the original object and returns it. * * @param meta * @param parentMeta */ export function inheritMeta( meta: ComponentMeta, parentMeta: ComponentMeta ): ComponentMeta { const metaPointer = metaPointers[meta.componentName]; const { params: pParams, props: pProps, mods: pMods, fields: pFields, tiedFields: pTiedFields, computedFields: pComputedFields, systemFields: pSystemFields, accessors: pAccessors, methods: pMethods, watchDependencies: pWatchDependencies } = parentMeta; // Component parameters inheritance meta.params = { ...pParams, ...meta.params, name: meta.params.name, model: (meta.params.model || pParams.model) && {...pParams.model, ...meta.params.model}, deprecatedProps: {...pParams.deprecatedProps, ...meta.params.deprecatedProps} }; // Watcher dependencies inheritance if (meta.watchDependencies.size > 0) { for (let o = pWatchDependencies.entries(), el = o.next(); !el.done; el = o.next()) { const [key, pVal] = el.value; meta.watchDependencies.set(key, (meta.watchDependencies.get(key) ?? []).concat(pVal)); } } else { meta.watchDependencies = new Map(pWatchDependencies.entries()); } // Props/fields inheritance { const list = [ [meta.props, pProps], [meta.fields, pFields], [meta.systemFields, pSystemFields] ]; for (let i = 0; i < list.length; i++) { const [o, parentObj] = list[i]; for (let keys = Object.keys(parentObj), i = 0; i < keys.length; i++) { const key = keys[i], parent = parentObj[key]; if (!parent) { continue; } if (!metaPointer || !metaPointer[key]) { o[key] = parent; continue; } let after, watchers; if (parent.watchers) { for (let w = parent.watchers.values(), el = w.next(); !el.done; el = w.next()) { const val = el.value; watchers ??= new Map(); watchers.set(val.handler, {...el.value}); } } if ('after' in parent && parent.after) { for (let a = parent.after.values(), el = a.next(); !el.done; el = a.next()) { after ??= new Set(); after.add(el.value); } } o[key] = {...parent, after, watchers}; } } } // Tied fields inheritance Object.assign(meta.tiedFields, pTiedFields); // Accessors inheritance { const list = [ [meta.computedFields, pComputedFields], [meta.accessors, pAccessors] ]; for (let i = 0; i < list.length; i++) { const [o, parentObj] = list[i]; for (let keys = Object.keys(parentObj), i = 0; i < keys.length; i++) { const key = keys[i]; o[key] = {...parentObj[key]!}; } } } // Methods inheritance for (let o = meta.methods, keys = Object.keys(pMethods), i = 0; i < keys.length; i++) { const key = keys[i], parent = pMethods[key]; if (!parent) { continue; } if (!metaPointer || !metaPointer[key]) { o[key] = {...parent}; continue; } const watchers = {}, hooks = {}; if (parent.watchers) { const o = parent.watchers, w = Object.keys(o); for (let i = 0; i < w.length; i++) { const key = w[i]; watchers[key] = {...o[key]}; } } if (parent.hooks) { const o = parent.hooks, w = Object.keys(o); for (let i = 0; i < w.length; i++) { const key = w[i], el = o[key]; hooks[key] = { ...el, after: Object.size(el.after) > 0 ? new Set(el.after) : undefined }; } } o[key] = {...parent, watchers, hooks}; } // Modifiers inheritance for (let o = meta.mods, keys = Object.keys(pMods), i = 0; i < keys.length; i++) { const key = keys[i], current = o[key], parent = (pMods[key] ?? []).slice(); if (current) { const values = Object.createDict<StrictModDeclVal>(); for (let o = current.slice(), i = 0; i < o.length; i++) { const el = o[i]; if (el !== PARENT) { if (Object.isArray(el) || !(<string>el in values)) { values[String(el)] = <StrictModDeclVal>el; } continue; } let hasDefault = false; for (let i = 0; i < o.length; i++) { const el = o[i]; if (Object.isArray(el)) { hasDefault = true; break; } } let parentDef = !hasDefault; for (let i = 0; i < parent.length; i++) { const el = parent[i]; if (!(<string>el in values)) { values[String(el)] = <StrictModDeclVal>el; } if (!parentDef && Object.isArray(el)) { parent[i] = el[0]; parentDef = true; } } current.splice(i, 1, ...parent); } const valuesList = <StrictModDeclVal[]>[]; for (let keys = Object.keys(values), i = 0; i < keys.length; i++) { const el = values[keys[i]]; if (el !== undefined) { valuesList.push(el); } } o[key] = valuesList; } else if (!(key in o)) { o[key] = parent; } } return meta; }