UNPKG

@cloudbase/app

Version:
117 lines (107 loc) 3.45 kB
import { KV } from '@cloudbase/types' import { ICloudbaseComponent, ICloudbaseHook } from '@cloudbase/types/component' import { constants } from '@cloudbase/utilities' const { ERRORS } = constants const components: KV<ICloudbaseComponent> = {} export function registerComponent(app: any, component: ICloudbaseComponent) { const { name, namespace, entity, injectEvents, IIFE = false } = component // 不允许重复注册或命名空间重名 if (components[name] || (namespace && app[namespace])) { throw new Error(JSON.stringify({ code: ERRORS.INVALID_OPERATION, msg: `Duplicate component ${name}`, })) } // IIFE类型的组件以app为scope执行entity函数,不挂载到app.prototype上 if (IIFE) { if (!entity || typeof entity !== 'function') { throw new Error(JSON.stringify({ code: ERRORS.INVALID_PARAMS, msg: 'IIFE component\'s entity must be a function', })) } entity.call(app) } components[name] = component if (namespace) { (app as any).prototype[namespace] = entity } else { deepExtend((app as any).prototype, entity) } if (injectEvents) { const { bus, events } = injectEvents if (!bus || !events || events.length === 0) { return } const originCallback = (app as any).prototype.fire || function () {} if (!(app as any).prototype.events) { (app as any).prototype.events = {} } const originEvents: KV<any> = (app as any).prototype.events || {} if (originEvents[name]) { (app as any).prototype.events[name].events = [...(app as any).prototype.events[name].events, ...events] } else { (app as any).prototype.events[name] = { bus, events } } (app as any).prototype.fire = function (eventName: string, data?: any) { originCallback(eventName, data) const eventNames = Object.keys(this.events) for (const name of eventNames) { const { bus, events: eventList } = this.events[name] if (eventList.includes(eventName)) { bus.fire(eventName, data) break } } } } } function deepExtend(target: any, source: any): KV<any> { if (!(source instanceof Object)) { return source } switch (source.constructor) { case Date: { const dateValue = source as Date return new Date(dateValue.getTime()) } case Object: if (target === undefined) { target = {} } break case Array: target = [] break default: return source } const sourceKeys = Object.keys(source) for (const key of sourceKeys) { if (!Object.prototype.hasOwnProperty.call(source, key)) { continue } target[key] = deepExtend(target[key], source[key]) } return target } export function registerHook(app: any, hook: ICloudbaseHook) { const { entity, target } = hook if (Object.prototype.hasOwnProperty.call(app, target)) { throw new Error(JSON.stringify({ code: ERRORS.INVALID_OPERATION, msg: `target:${target} is not exist`, })) } const originMethod = app.prototype[target] if (typeof originMethod !== 'function') { throw new Error(JSON.stringify({ code: ERRORS.INVALID_OPERATION, msg: `target:${target} is not a function which is the only type supports hook`, })) } app.prototype[target] = function (...args: any) { entity.call(this, ...args) return originMethod.call(this, ...args) } }