zova-core 5.0.110 → 5.0.113

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (133) hide show
  1. package/dist/bean/beanBaseSimple.d.ts.map +1 -1
  2. package/dist/bean/beanBaseSimple.js +10 -2
  3. package/dist/bean/beanBaseSimple.js.map +1 -1
  4. package/dist/core/resource.d.ts +6 -6
  5. package/dist/core/resource.d.ts.map +1 -1
  6. package/dist/core/resource.js +2 -6
  7. package/dist/core/resource.js.map +1 -1
  8. package/dist/decorator/class/use.js +8 -5
  9. package/dist/decorator/class/use.js.map +1 -1
  10. package/package.json +4 -3
  11. package/src/bean/beanBase.ts +53 -0
  12. package/src/bean/beanBaseSimple.ts +38 -0
  13. package/src/bean/beanContainer.ts +963 -0
  14. package/src/bean/beanControllerBase.ts +58 -0
  15. package/src/bean/beanControllerLike.ts +29 -0
  16. package/src/bean/beanControllerPageBase.ts +18 -0
  17. package/src/bean/beanRenderBase.ts +7 -0
  18. package/src/bean/beanRenderLike.ts +33 -0
  19. package/src/bean/beanSimple.ts +11 -0
  20. package/src/bean/beanStyleBase.ts +3 -0
  21. package/src/bean/index.ts +13 -0
  22. package/src/bean/resource/component/index.ts +1 -0
  23. package/src/bean/resource/component/type.ts +5 -0
  24. package/src/bean/resource/config/index.ts +1 -0
  25. package/src/bean/resource/config/type.ts +32 -0
  26. package/src/bean/resource/constant/index.ts +1 -0
  27. package/src/bean/resource/constant/type.ts +1 -0
  28. package/src/bean/resource/error/beanScopeError.ts +21 -0
  29. package/src/bean/resource/error/errorClass.ts +57 -0
  30. package/src/bean/resource/error/errorGlobal.ts +7 -0
  31. package/src/bean/resource/error/errorInternal.ts +66 -0
  32. package/src/bean/resource/error/errorObject.ts +4 -0
  33. package/src/bean/resource/error/index.ts +6 -0
  34. package/src/bean/resource/error/type.ts +10 -0
  35. package/src/bean/resource/icon/icon.ts +161 -0
  36. package/src/bean/resource/icon/iconGroup.ts +10 -0
  37. package/src/bean/resource/icon/index.ts +4 -0
  38. package/src/bean/resource/icon/types.ts +21 -0
  39. package/src/bean/resource/icon/useZovaIcon.ts +20 -0
  40. package/src/bean/resource/icon/utils.ts +20 -0
  41. package/src/bean/resource/icon/zovaIcon.ts +52 -0
  42. package/src/bean/resource/index.ts +8 -0
  43. package/src/bean/resource/locale/beanScopeLocale.ts +22 -0
  44. package/src/bean/resource/locale/index.ts +2 -0
  45. package/src/bean/resource/locale/type.ts +21 -0
  46. package/src/bean/resource/page/index.ts +1 -0
  47. package/src/bean/resource/page/type.ts +12 -0
  48. package/src/bean/resource/service/beanScopeService.ts +24 -0
  49. package/src/bean/resource/service/index.ts +2 -0
  50. package/src/bean/resource/service/type.ts +8 -0
  51. package/src/bean/scope/beanScopeBase.ts +74 -0
  52. package/src/bean/scope/index.ts +4 -0
  53. package/src/bean/scope/type.ts +23 -0
  54. package/src/bean/type.ts +31 -0
  55. package/src/composables/index.ts +4 -0
  56. package/src/composables/onControllerMounted.ts +12 -0
  57. package/src/composables/useApp.ts +7 -0
  58. package/src/composables/useContext.ts +7 -0
  59. package/src/composables/useController.ts +125 -0
  60. package/src/core/app/application.ts +76 -0
  61. package/src/core/app/config.ts +68 -0
  62. package/src/core/app/constant.ts +11 -0
  63. package/src/core/app/index.ts +6 -0
  64. package/src/core/app/locale.ts +12 -0
  65. package/src/core/app/meta.ts +44 -0
  66. package/src/core/app/util.ts +31 -0
  67. package/src/core/component/component.ts +44 -0
  68. package/src/core/component/cookie.ts +16 -0
  69. package/src/core/component/error.ts +18 -0
  70. package/src/core/component/event.ts +87 -0
  71. package/src/core/component/index.ts +3 -0
  72. package/src/core/component/locale.ts +97 -0
  73. package/src/core/component/module.ts +281 -0
  74. package/src/core/context/component.ts +34 -0
  75. package/src/core/context/context.ts +38 -0
  76. package/src/core/context/index.ts +4 -0
  77. package/src/core/context/meta.ts +26 -0
  78. package/src/core/context/state.ts +28 -0
  79. package/src/core/context/util.ts +20 -0
  80. package/src/core/index.ts +5 -0
  81. package/src/core/metadata.ts +54 -0
  82. package/src/core/resource.ts +186 -0
  83. package/src/decorator/class/bean.ts +19 -0
  84. package/src/decorator/class/index.ts +12 -0
  85. package/src/decorator/class/local.ts +18 -0
  86. package/src/decorator/class/model.ts +18 -0
  87. package/src/decorator/class/scope.ts +18 -0
  88. package/src/decorator/class/store.ts +18 -0
  89. package/src/decorator/class/style.ts +18 -0
  90. package/src/decorator/class/theme.ts +18 -0
  91. package/src/decorator/class/tool.ts +18 -0
  92. package/src/decorator/class/use.ts +37 -0
  93. package/src/decorator/class/useComposable.ts +16 -0
  94. package/src/decorator/class/useScope.ts +21 -0
  95. package/src/decorator/class/virtual.ts +20 -0
  96. package/src/decorator/index.ts +7 -0
  97. package/src/decorator/interface/beanOptions.ts +80 -0
  98. package/src/decorator/interface/useOptions.ts +37 -0
  99. package/src/decorator/type/constructable.ts +1 -0
  100. package/src/decorator/type/containerScope.ts +1 -0
  101. package/src/decorator/type/functionable.ts +1 -0
  102. package/src/decorator/type/injectionScope.ts +1 -0
  103. package/src/index.ts +9 -0
  104. package/src/plugins/bean.ts +16 -0
  105. package/src/plugins/index.ts +2 -0
  106. package/src/plugins/zova.ts +28 -0
  107. package/src/types/index.ts +2 -0
  108. package/src/types/interface/component.ts +36 -0
  109. package/src/types/interface/event.ts +28 -0
  110. package/src/types/interface/index.ts +6 -0
  111. package/src/types/interface/inject.ts +2 -0
  112. package/src/types/interface/module.ts +38 -0
  113. package/src/types/interface/monkey.ts +38 -0
  114. package/src/types/interface/pluginZova.ts +17 -0
  115. package/src/types/utils/cast.ts +8 -0
  116. package/src/types/utils/env.ts +35 -0
  117. package/src/types/utils/index.ts +3 -0
  118. package/src/types/utils/powerPartial.ts +3 -0
  119. package/src/utils/index.ts +1 -0
  120. package/src/utils/isClass.ts +17 -0
  121. package/src/utils/stateLock.ts +47 -0
  122. package/src/utils/uuid.ts +84 -0
  123. package/src/vue/composable.ts +10 -0
  124. package/src/vue/computed.ts +7 -0
  125. package/src/vue/customRef.ts +5 -0
  126. package/src/vue/index.ts +4 -0
  127. package/src/vue/ref.ts +12 -0
  128. package/src/zod/index.ts +2 -0
  129. package/src/zod/zz.ts +77 -0
  130. package/dist/decorator/class/data.d.ts +0 -3
  131. package/dist/decorator/class/data.d.ts.map +0 -1
  132. package/dist/decorator/class/data.js +0 -18
  133. package/dist/decorator/class/data.js.map +0 -1
@@ -0,0 +1,44 @@
1
+ import { BeanSimple } from '../../bean/beanSimple.js';
2
+ import { AppIcon } from '../../bean/resource/icon/icon.js';
3
+ import { IModuleLocaleText } from '../../bean/resource/locale/type.js';
4
+ import { Constructable } from '../../decorator/type/constructable.js';
5
+ import { IMonkeyApp, IMonkeyController, IMonkeySystem } from '../../types/interface/monkey.js';
6
+ import { AppError } from '../component/error.js';
7
+ import { AppEvent } from '../component/event.js';
8
+ import { AppComponent } from '../component/component.js';
9
+ import { AppLocale } from '../component/locale.js';
10
+ import { AppModule } from '../component/module.js';
11
+ import { AppUtil } from './util.js';
12
+ import { AppCookie } from '../component/cookie.js';
13
+
14
+ export class AppMeta extends BeanSimple {
15
+ module: AppModule;
16
+ util: AppUtil;
17
+ component: AppComponent;
18
+ locale: AppLocale;
19
+ error: AppError;
20
+ event: AppEvent;
21
+ icon: AppIcon;
22
+ cookie: AppCookie;
23
+ text: IModuleLocaleText;
24
+
25
+ /** @internal */
26
+ public appMonkey?: IMonkeyApp & IMonkeySystem & IMonkeyController;
27
+
28
+ protected __init__() {
29
+ this.module = this.app.bean._newBeanSimple(AppModule, false);
30
+ this.util = this.app.bean._newBeanSimple(AppUtil, false);
31
+ this.component = this.app.bean._newBeanSimple(AppComponent, false);
32
+ this.locale = this.app.bean._newBeanSimple(AppLocale, false);
33
+ this.error = this.app.bean._newBeanSimple(AppError, false);
34
+ this.event = this.app.bean._newBeanSimple(AppEvent, false);
35
+ this.icon = this.app.bean._newBeanSimple(AppIcon, false);
36
+ this.cookie = this.app.bean._newBeanSimple(AppCookie, false);
37
+ this.text = this.locale.createLocaleText();
38
+ }
39
+
40
+ /** @internal */
41
+ public async initialize(AppMonkey: Constructable<IMonkeyApp & IMonkeySystem & IMonkeyController>) {
42
+ this.appMonkey = this.bean._newBeanSimple(AppMonkey, false);
43
+ }
44
+ }
@@ -0,0 +1,31 @@
1
+ import { extend } from '@cabloy/extend';
2
+ import { BeanSimple } from '../../bean/beanSimple.js';
3
+ import { uuid } from '../../utils/uuid.js';
4
+
5
+ export class AppUtil extends BeanSimple {
6
+ uuid(): string {
7
+ return uuid();
8
+ }
9
+
10
+ isUuid(str: string): boolean {
11
+ if (!str) return false;
12
+ const length = str.length;
13
+ return length === 36 || length === 32;
14
+ }
15
+
16
+ isNullOrEmptyString(str?: string | undefined | null): boolean {
17
+ return str === undefined || str === null || str === '';
18
+ }
19
+
20
+ async sleep(ms: number) {
21
+ return new Promise(reslove => {
22
+ window.setTimeout(() => {
23
+ reslove(null);
24
+ }, ms);
25
+ });
26
+ }
27
+
28
+ extend(...args) {
29
+ return extend(true, ...args);
30
+ }
31
+ }
@@ -0,0 +1,44 @@
1
+ import { BeanSimple } from '../../bean/beanSimple.js';
2
+ import { TypeModuleResourceComponents } from '../../types/interface/module.js';
3
+ import { Component, ComponentCustomOptions } from 'vue';
4
+
5
+ export class AppComponent extends BeanSimple {
6
+ /** @internal */
7
+ public async initialize() {}
8
+
9
+ public createAsyncComponent(componentName: string) {
10
+ return () => {
11
+ return this.use(componentName);
12
+ };
13
+ // should not use defineAsyncComponent
14
+ // return defineAsyncComponent(() => {
15
+ // return this.use(componentName);
16
+ // });
17
+ }
18
+
19
+ public async use(componentName: string): Promise<Component> {
20
+ const [moduleName, componentName2] = componentName.split(':');
21
+ const module = await this.app.meta.module.use(moduleName);
22
+ return module.resource.components[componentName2];
23
+ }
24
+
25
+ /** @internal */
26
+ public _registerComponents(_moduleName: string, components: TypeModuleResourceComponents) {
27
+ if (!components) return;
28
+ for (const key in components) {
29
+ const component = components[key];
30
+ this._setComponentGlobal(component);
31
+ }
32
+ }
33
+
34
+ private _setComponentGlobal(component: Component) {
35
+ // register
36
+ const options = component as ComponentCustomOptions;
37
+ if (component.name && options.meta?.global === true) {
38
+ if (!this.app.vue.component(component.name)) {
39
+ this.app.vue.component(component.name, component);
40
+ }
41
+ }
42
+ return component;
43
+ }
44
+ }
@@ -0,0 +1,16 @@
1
+ import Cookies from 'js-cookie';
2
+ import { BeanSimple } from '../../bean/beanSimple.js';
3
+
4
+ export class AppCookie extends BeanSimple {
5
+ getItem(key: string): string | undefined {
6
+ return Cookies.get(key);
7
+ }
8
+
9
+ setItem(key: string, value: string): void {
10
+ Cookies.set(key, value);
11
+ }
12
+
13
+ removeItem(key: string): void {
14
+ Cookies.remove(key);
15
+ }
16
+ }
@@ -0,0 +1,18 @@
1
+ import { ErrorClass } from '../../bean/resource/error/errorClass.js';
2
+ import { IErrorObject } from '../../bean/resource/error/errorObject.js';
3
+ import { IModuleError } from '../../bean/resource/error/type.js';
4
+
5
+ export class AppError extends ErrorClass {
6
+ /** @internal */
7
+ public createScopeError(moduleScope: string, errorCode: number | string): IModuleError {
8
+ const self = this;
9
+ return {
10
+ throw: (...args: any[]): never => {
11
+ return self.throw(moduleScope, errorCode, ...args);
12
+ },
13
+ parseFail: (...args: any[]): IErrorObject => {
14
+ return self.parseFail(moduleScope, errorCode, ...args);
15
+ },
16
+ };
17
+ }
18
+ }
@@ -0,0 +1,87 @@
1
+ import { composeAsync } from '@cabloy/compose';
2
+ import { BeanSimple } from '../../bean/beanSimple.js';
3
+ import {
4
+ IEventRecord,
5
+ IEventResultRecord,
6
+ TypeEventContext,
7
+ TypeEventHandler,
8
+ TypeEventHandlers,
9
+ TypeEventHandlersMap,
10
+ TypeEventOff,
11
+ } from '../../types/interface/event.js';
12
+
13
+ const __adapter = (_context, chain) => {
14
+ const eventHandlerWrapper = chain;
15
+ if (eventHandlerWrapper.fn === null) return;
16
+ return {
17
+ receiver: undefined,
18
+ fn: eventHandlerWrapper.fn,
19
+ };
20
+ };
21
+
22
+ export class AppEvent extends BeanSimple {
23
+ private eventHandlersMap = {} as TypeEventHandlersMap<keyof IEventRecord>;
24
+
25
+ /** @internal */
26
+ public async initialize() {}
27
+
28
+ public getEventHandlers<K extends keyof IEventRecord>(
29
+ eventName: K,
30
+ ): TypeEventHandlers<IEventRecord[K], IEventResultRecord[K]> {
31
+ let eventHandlers = this.eventHandlersMap[eventName];
32
+ if (!eventHandlers) {
33
+ eventHandlers = this.eventHandlersMap[eventName] = [] as any;
34
+ }
35
+ return eventHandlers;
36
+ }
37
+
38
+ async emit<K extends keyof IEventRecord>(
39
+ eventName: K,
40
+ data?: IEventRecord[K],
41
+ initialValue?: IEventResultRecord[K],
42
+ fallback?: TypeEventHandler<IEventRecord[K], IEventResultRecord[K]>,
43
+ ): Promise<IEventResultRecord[K]> {
44
+ const eventHandlers = this.getEventHandlers(eventName);
45
+ // context
46
+ const context = {
47
+ data,
48
+ result: initialValue,
49
+ } as TypeEventContext<IEventRecord[K], IEventResultRecord[K]>;
50
+ // invoke
51
+ await composeAsync(eventHandlers.concat(), __adapter)(context, async (context, next) => {
52
+ if (fallback) {
53
+ await fallback(context, next);
54
+ } else {
55
+ await next();
56
+ }
57
+ });
58
+ // ok
59
+ return context.result;
60
+ }
61
+
62
+ on<K extends keyof IEventRecord>(
63
+ eventName: K,
64
+ fn: TypeEventHandler<IEventRecord[K], IEventResultRecord[K]>,
65
+ ): TypeEventOff {
66
+ const eventHandlers = this.getEventHandlers(eventName);
67
+ eventHandlers.push({ fn });
68
+ return () => {
69
+ const index = eventHandlers.findIndex(item => item.fn === fn);
70
+ if (index > -1) {
71
+ eventHandlers[index].fn = null;
72
+ eventHandlers.splice(index, 1);
73
+ }
74
+ };
75
+ }
76
+
77
+ once<K extends keyof IEventRecord>(
78
+ eventName: K,
79
+ fn: TypeEventHandler<IEventRecord[K], IEventResultRecord[K]>,
80
+ ): TypeEventOff {
81
+ const off = this.on(eventName, async (context, next) => {
82
+ await fn(context, next);
83
+ off();
84
+ });
85
+ return off;
86
+ }
87
+ }
@@ -0,0 +1,3 @@
1
+ export * from './error.js';
2
+ export * from './locale.js';
3
+ export * from './module.js';
@@ -0,0 +1,97 @@
1
+ import * as localeutil from '@cabloy/localeutil';
2
+ import { BeanSimple } from '../../bean/beanSimple.js';
3
+ import { TypeModuleResourceLocaleModules, TypeModuleResourceLocales } from '../../types/interface/module.js';
4
+ import { ILocalInfos, IModuleLocale, IModuleLocaleText } from '../../bean/resource/locale/type.js';
5
+ import { ZovaLocaleOptionalMap } from '../app/locale.js';
6
+ import { ref, Ref } from 'vue';
7
+
8
+ const SymbolLocaleCurrent = Symbol('SymbolLocaleCurrent');
9
+
10
+ export class AppLocale extends BeanSimple {
11
+ private [SymbolLocaleCurrent]: Ref<string | undefined> = ref();
12
+ /** @internal */
13
+ public locales: TypeModuleResourceLocales = {};
14
+ public localeModules: TypeModuleResourceLocaleModules = {};
15
+
16
+ get current(): keyof ILocalInfos {
17
+ let locale = this[SymbolLocaleCurrent].value;
18
+ if (!locale) locale = this.app.meta.cookie.getItem(this.app.config.locale.storeKey);
19
+ if (!locale) locale = this.app.config.locale.default;
20
+ return locale as keyof ILocalInfos;
21
+ }
22
+
23
+ set current(value: keyof ILocalInfos) {
24
+ if (this[SymbolLocaleCurrent].value === value) return;
25
+ this[SymbolLocaleCurrent].value = value;
26
+ this.app.meta.cookie.setItem(this.app.config.locale.storeKey, value);
27
+ }
28
+
29
+ /** @internal */
30
+ public async initialize(locales: ZovaLocaleOptionalMap) {
31
+ for (const locale in locales) {
32
+ const moduleMap = locales[locale].modules;
33
+ for (const moduleName in moduleMap) {
34
+ this._registerLocale(moduleName, locale, moduleMap[moduleName]);
35
+ }
36
+ }
37
+ }
38
+
39
+ /** @internal */
40
+ public _registerLocales(moduleName: string, locales: TypeModuleResourceLocales) {
41
+ if (!locales) return;
42
+ for (const locale in locales) {
43
+ this._registerLocale(moduleName, locale, locales[locale]);
44
+ }
45
+ }
46
+
47
+ private _registerLocale(moduleName: string, locale: string, moduleLocales: object) {
48
+ // locales
49
+ this.locales[locale] = Object.assign({}, moduleLocales, this.locales[locale]);
50
+ // localeModules
51
+ if (!this.localeModules[moduleName]) this.localeModules[moduleName] = {};
52
+ this.localeModules[moduleName][locale] = Object.assign({}, moduleLocales, this.localeModules[moduleName][locale]);
53
+ }
54
+
55
+ /** @internal */
56
+ public createLocaleText(moduleScope?: string): IModuleLocaleText {
57
+ const self = this;
58
+ const getText = function (text: string, ...args: any[]): string {
59
+ return self.getText(moduleScope, undefined, text, ...args);
60
+ };
61
+ getText.locale = function <T extends keyof ILocalInfos>(
62
+ locale: T | undefined,
63
+ text: string,
64
+ ...args: any[]
65
+ ): string {
66
+ return self.getText(moduleScope, locale, text, ...args);
67
+ };
68
+ return getText;
69
+ }
70
+
71
+ /** @internal */
72
+ public createScopeLocaleText(moduleScope: string, text: string): IModuleLocale {
73
+ const self = this;
74
+ const getText = function (...args: any[]): string {
75
+ return self.getText(moduleScope, undefined, text, ...args);
76
+ };
77
+ getText.locale = function <T extends keyof ILocalInfos>(locale: T | undefined, ...args: any[]): string {
78
+ return self.getText(moduleScope, locale, text, ...args);
79
+ };
80
+ return getText;
81
+ }
82
+
83
+ public getText<T extends keyof ILocalInfos>(
84
+ moduleScope: string | undefined,
85
+ locale: T | undefined,
86
+ key: string,
87
+ ...args: any[]
88
+ ): string {
89
+ return localeutil.getLocaleText(
90
+ moduleScope ? this.localeModules[moduleScope] : undefined,
91
+ this.locales,
92
+ locale || this.current,
93
+ key,
94
+ ...args,
95
+ );
96
+ }
97
+ }
@@ -0,0 +1,281 @@
1
+ import { IModule, IModuleInfo } from '@cabloy/module-info';
2
+ import * as ModuleInfo from '@cabloy/module-info';
3
+ import { BeanSimple } from '../../bean/beanSimple.js';
4
+ import { shallowReactive } from 'vue';
5
+ import { IModuleResource, PluginZovaModulesMeta, SymbolInstalled, TypeMonkeyName } from '../../types/index.js';
6
+ import { StateLock } from '../../utils/stateLock.js';
7
+ import { TypeBeanScopeRecordKeys } from '../../bean/type.js';
8
+
9
+ export class AppModule extends BeanSimple {
10
+ private modulesMeta: PluginZovaModulesMeta;
11
+ private modules: Record<string, IModule> = shallowReactive({});
12
+
13
+ /** @internal */
14
+ public async initialize(modulesMeta: PluginZovaModulesMeta) {
15
+ this.modulesMeta = modulesMeta;
16
+ await this._loadAllMonkeysAndSyncs();
17
+ await this._requireAllMonkeys();
18
+ await this._requireAllSyncs();
19
+ }
20
+
21
+ get<K extends TypeBeanScopeRecordKeys>(moduleName: K, forceLoad?: boolean): IModule | undefined;
22
+ get(moduleName: string, forceLoad?: boolean): IModule | undefined;
23
+ get(moduleName: IModuleInfo, forceLoad?: boolean): IModule | undefined;
24
+ get(moduleName: string | IModuleInfo, forceLoad?: boolean): IModule | undefined {
25
+ // module info
26
+ if (!moduleName) return undefined;
27
+ const moduleInfo = typeof moduleName === 'string' ? ModuleInfo.parseInfo(moduleName) : moduleName;
28
+ if (!moduleInfo) throw new Error(`invalid module name: ${moduleName}`);
29
+ // get
30
+ const module = this.modules[moduleInfo.relativeName];
31
+ if (!module) {
32
+ // module not loaded, so async use to raise the next call
33
+ if (forceLoad !== false) {
34
+ this.use(moduleInfo.relativeName);
35
+ }
36
+ return undefined;
37
+ }
38
+ if (!module[SymbolInstalled] || !module[SymbolInstalled].state) {
39
+ return undefined;
40
+ }
41
+ return module;
42
+ }
43
+
44
+ async use<K extends TypeBeanScopeRecordKeys>(moduleName: K): Promise<IModule>;
45
+ async use(moduleName: string): Promise<IModule>;
46
+ async use(moduleName: IModuleInfo): Promise<IModule>;
47
+ async use(moduleName?: string | IModuleInfo): Promise<IModule> {
48
+ // module info
49
+ if (!moduleName) throw new Error('should specify the module name');
50
+ const moduleInfo = typeof moduleName === 'string' ? ModuleInfo.parseInfo(moduleName) : moduleName;
51
+ if (!moduleInfo) throw new Error(`invalid module name: ${moduleName}`);
52
+ const relativeName = moduleInfo.relativeName;
53
+ // should not try check get directly
54
+ // const module = this.getOnly(relativeName);
55
+ // if (module) return module;
56
+ // module
57
+ const moduleRepo = this.modulesMeta.modules[relativeName];
58
+ if (!moduleRepo) throw new Error(`module not exists: ${relativeName}`);
59
+ // install
60
+ await this._install(relativeName, moduleRepo);
61
+ // ok
62
+ return moduleRepo;
63
+ }
64
+
65
+ exists<K extends TypeBeanScopeRecordKeys>(moduleName: K): boolean;
66
+ exists(moduleName: string): boolean;
67
+ exists(moduleName: IModuleInfo): boolean;
68
+ exists(moduleName: string | IModuleInfo): boolean {
69
+ // module info
70
+ if (!moduleName) return false;
71
+ const moduleInfo = typeof moduleName === 'string' ? ModuleInfo.parseInfo(moduleName) : moduleName;
72
+ if (!moduleInfo) throw new Error(`invalid module name: ${moduleName}`);
73
+ const moduleRepo = this.modulesMeta.modules[moduleInfo.relativeName];
74
+ return !!moduleRepo;
75
+ }
76
+
77
+ private async _loadAllMonkeysAndSyncs() {
78
+ const promises: Promise<IModuleResource>[] = [];
79
+ const moduleNames: string[] = [];
80
+ for (const moduleName of this.modulesMeta.moduleNames) {
81
+ const module = this.modulesMeta.modules[moduleName];
82
+ const info = module.info;
83
+ if (info.capabilities?.monkey || info.capabilities?.sync) {
84
+ const moduleResource = module.resource as any;
85
+ promises.push(moduleResource());
86
+ moduleNames.push(moduleName);
87
+ }
88
+ }
89
+ const modulesResource = await Promise.all(promises);
90
+ for (let i = 0; i < modulesResource.length; i++) {
91
+ const moduleName = moduleNames[i];
92
+ this.modulesMeta.modules[moduleName].resource = modulesResource[i];
93
+ }
94
+ }
95
+
96
+ private async _requireAllMonkeys() {
97
+ for (const moduleName of this.modulesMeta.moduleNames) {
98
+ const module = this.modulesMeta.modules[moduleName];
99
+ if (module.info.capabilities?.monkey) {
100
+ await this._install(moduleName, module);
101
+ }
102
+ }
103
+ }
104
+
105
+ private async _requireAllSyncs() {
106
+ for (const moduleName of this.modulesMeta.moduleNames) {
107
+ const module = this.modulesMeta.modules[moduleName];
108
+ if (module.info.capabilities?.sync) {
109
+ await this._install(moduleName, module);
110
+ }
111
+ }
112
+ }
113
+
114
+ private async _install(moduleName: string, module: IModule) {
115
+ if (!module[SymbolInstalled]) {
116
+ module[SymbolInstalled] = StateLock.create();
117
+ }
118
+ // check
119
+ if (this.modules[moduleName]) {
120
+ await module[SymbolInstalled].wait();
121
+ return;
122
+ }
123
+ // record
124
+ this.modules[moduleName] = module;
125
+ // install
126
+ await this._installInner(moduleName, module);
127
+ // installed
128
+ module[SymbolInstalled].touch();
129
+ // scope: should after [SymbolInstalled].touch
130
+ await this.app.bean._getBean(`${moduleName}.scope.module` as any, false);
131
+ }
132
+
133
+ private async _installInner(_moduleName: string, module: IModule) {
134
+ // load
135
+ if (typeof module.resource === 'function') {
136
+ const moduleResource = module.resource as any;
137
+ module.resource = await moduleResource();
138
+ }
139
+ // main / monkey
140
+ if (module.resource.Main) {
141
+ module.mainInstance = this.app.bean._newBeanSimple(module.resource.Main, false, module);
142
+ }
143
+ if (module.resource.Monkey) {
144
+ module.monkeyInstance = this.app.bean._newBeanSimple(module.resource.Monkey, false, module);
145
+ }
146
+ // monkey: moduleLoading
147
+ await this._monkeyModule('moduleLoading', module);
148
+ // register resources
149
+ await this._registerResources(module);
150
+ // monkey: moduleLoaded
151
+ await this._monkeyModule('moduleLoaded', module);
152
+ }
153
+
154
+ private async _registerResources(module: IModule) {
155
+ this._registerComponents(module);
156
+ this._registerLocales(module);
157
+ this._registerErrors(module);
158
+ this._registerConstants(module);
159
+ await this._registerConfig(module);
160
+ }
161
+
162
+ private _registerComponents(module: IModule) {
163
+ this.app.meta.component._registerComponents(module.info.relativeName, module.resource.components);
164
+ }
165
+
166
+ private _registerErrors(module: IModule) {
167
+ if (!module.resource.Errors) return;
168
+ this.app.meta.error.errors[module.info.relativeName] = module.resource.Errors;
169
+ }
170
+
171
+ private _registerLocales(module: IModule) {
172
+ this.app.meta.locale._registerLocales(module.info.relativeName, module.resource.locales);
173
+ }
174
+
175
+ private _registerConstants(module: IModule) {
176
+ if (!module.resource.constants) return;
177
+ const relativeName = module.info.relativeName;
178
+ this.app.constant.modules[relativeName] = this.app.meta.util.extend(
179
+ {},
180
+ module.resource.constants,
181
+ this.app.constant.modules[relativeName],
182
+ );
183
+ }
184
+
185
+ private async _registerConfig(module: IModule) {
186
+ if (!module.resource.config) return;
187
+ // config
188
+ const config = await module.resource.config(this.app);
189
+ // monkey
190
+ await this._monkeyModule('configLoaded', module, config);
191
+ // extend
192
+ const relativeName = module.info.relativeName;
193
+ this.app.config.modules[relativeName] = this.app.meta.util.extend(
194
+ {},
195
+ config,
196
+ this.app.config.modules[relativeName],
197
+ );
198
+ }
199
+
200
+ /** @internal */
201
+ public async _monkeyModule(monkeyName: TypeMonkeyName, moduleTarget?: IModule, ...monkeyData: any[]) {
202
+ // self: main
203
+ if (moduleTarget && moduleTarget.mainInstance && moduleTarget.mainInstance[monkeyName]) {
204
+ // @ts-ignore ignore
205
+ await this.app.vue.runWithContext(async () => {
206
+ await moduleTarget.mainInstance[monkeyName](...monkeyData);
207
+ });
208
+ }
209
+ // module monkey
210
+ for (const key of this.modulesMeta.moduleNames) {
211
+ const moduleMonkey: IModule = this.modulesMeta.modules[key];
212
+ if (moduleMonkey.info.capabilities?.monkey) {
213
+ if (moduleMonkey.monkeyInstance && moduleMonkey.monkeyInstance[monkeyName]) {
214
+ await this.app.vue.runWithContext(async () => {
215
+ if (moduleTarget === undefined) {
216
+ // @ts-ignore ignore
217
+ await moduleMonkey.monkeyInstance[monkeyName](...monkeyData);
218
+ } else {
219
+ // @ts-ignore ignore
220
+ await moduleMonkey.monkeyInstance[monkeyName](moduleTarget, ...monkeyData);
221
+ }
222
+ });
223
+ }
224
+ }
225
+ }
226
+ // app monkey
227
+ const appMonkey = this.app.meta.appMonkey;
228
+ if (appMonkey && appMonkey[monkeyName]) {
229
+ await this.app.vue.runWithContext(async () => {
230
+ if (moduleTarget === undefined) {
231
+ // @ts-ignore ignore
232
+ await appMonkey[monkeyName](...monkeyData);
233
+ } else {
234
+ // @ts-ignore ignore
235
+ await appMonkey[monkeyName](moduleTarget, ...monkeyData);
236
+ }
237
+ });
238
+ }
239
+ }
240
+
241
+ /** @internal */
242
+ public _monkeyModuleSync(monkeyName: TypeMonkeyName, moduleTarget?: IModule, ...monkeyData: any[]) {
243
+ // self: main
244
+ if (moduleTarget && moduleTarget.mainInstance && moduleTarget.mainInstance[monkeyName]) {
245
+ // @ts-ignore ignore
246
+ this.app.vue.runWithContext(() => {
247
+ moduleTarget.mainInstance[monkeyName](...monkeyData);
248
+ });
249
+ }
250
+ // module monkey
251
+ for (const key of this.modulesMeta.moduleNames) {
252
+ const moduleMonkey: IModule = this.modulesMeta.modules[key];
253
+ if (moduleMonkey.info.capabilities?.monkey) {
254
+ if (moduleMonkey.monkeyInstance && moduleMonkey.monkeyInstance[monkeyName]) {
255
+ this.app.vue.runWithContext(() => {
256
+ if (moduleTarget === undefined) {
257
+ // @ts-ignore ignore
258
+ moduleMonkey.monkeyInstance[monkeyName](...monkeyData);
259
+ } else {
260
+ // @ts-ignore ignore
261
+ moduleMonkey.monkeyInstance[monkeyName](moduleTarget, ...monkeyData);
262
+ }
263
+ });
264
+ }
265
+ }
266
+ }
267
+ // app monkey
268
+ const appMonkey = this.app.meta.appMonkey;
269
+ if (appMonkey && appMonkey[monkeyName]) {
270
+ this.app.vue.runWithContext(() => {
271
+ if (moduleTarget === undefined) {
272
+ // @ts-ignore ignore
273
+ appMonkey[monkeyName](...monkeyData);
274
+ } else {
275
+ // @ts-ignore ignore
276
+ appMonkey[monkeyName](moduleTarget, ...monkeyData);
277
+ }
278
+ });
279
+ }
280
+ }
281
+ }
@@ -0,0 +1,34 @@
1
+ import { BeanRenderBase } from '../../bean/beanRenderBase.js';
2
+ import { BeanSimple } from '../../bean/beanSimple.js';
3
+ import { BeanRenderIdentifier } from '../../bean/type.js';
4
+ import { Cast } from '../../types/utils/cast.js';
5
+
6
+ export class CtxComponent extends BeanSimple {
7
+ private _bean_render_original: any;
8
+
9
+ activate() {
10
+ const self = this;
11
+ const instance = Cast(this.ctx.instance);
12
+ this._bean_render_original = instance.render;
13
+ instance.render = function (this, ...args) {
14
+ if (instance.isUnmounted) return;
15
+ if (!self.ctx.meta.state.inited.state) {
16
+ return self._bean_render_original.call(this, ...args);
17
+ }
18
+ const render: BeanRenderBase = self.ctx.bean._getBeanSyncOnly(BeanRenderIdentifier);
19
+ if (!render) {
20
+ return self._bean_render_original.call(this, ...args);
21
+ // throw new Error('render bean not found');
22
+ }
23
+ // need not use ctx.meta.util.instanceScope, since ctx.instance = getCurrentInstance()
24
+ return render.render();
25
+ };
26
+ }
27
+
28
+ /** @internal */
29
+ public dispose() {
30
+ const instance = Cast(this.ctx.instance);
31
+ instance.render = this._bean_render_original;
32
+ this._bean_render_original = null;
33
+ }
34
+ }