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.
- package/dist/bean/beanBaseSimple.d.ts.map +1 -1
- package/dist/bean/beanBaseSimple.js +10 -2
- package/dist/bean/beanBaseSimple.js.map +1 -1
- package/dist/core/resource.d.ts +6 -6
- package/dist/core/resource.d.ts.map +1 -1
- package/dist/core/resource.js +2 -6
- package/dist/core/resource.js.map +1 -1
- package/dist/decorator/class/use.js +8 -5
- package/dist/decorator/class/use.js.map +1 -1
- package/package.json +4 -3
- package/src/bean/beanBase.ts +53 -0
- package/src/bean/beanBaseSimple.ts +38 -0
- package/src/bean/beanContainer.ts +963 -0
- package/src/bean/beanControllerBase.ts +58 -0
- package/src/bean/beanControllerLike.ts +29 -0
- package/src/bean/beanControllerPageBase.ts +18 -0
- package/src/bean/beanRenderBase.ts +7 -0
- package/src/bean/beanRenderLike.ts +33 -0
- package/src/bean/beanSimple.ts +11 -0
- package/src/bean/beanStyleBase.ts +3 -0
- package/src/bean/index.ts +13 -0
- package/src/bean/resource/component/index.ts +1 -0
- package/src/bean/resource/component/type.ts +5 -0
- package/src/bean/resource/config/index.ts +1 -0
- package/src/bean/resource/config/type.ts +32 -0
- package/src/bean/resource/constant/index.ts +1 -0
- package/src/bean/resource/constant/type.ts +1 -0
- package/src/bean/resource/error/beanScopeError.ts +21 -0
- package/src/bean/resource/error/errorClass.ts +57 -0
- package/src/bean/resource/error/errorGlobal.ts +7 -0
- package/src/bean/resource/error/errorInternal.ts +66 -0
- package/src/bean/resource/error/errorObject.ts +4 -0
- package/src/bean/resource/error/index.ts +6 -0
- package/src/bean/resource/error/type.ts +10 -0
- package/src/bean/resource/icon/icon.ts +161 -0
- package/src/bean/resource/icon/iconGroup.ts +10 -0
- package/src/bean/resource/icon/index.ts +4 -0
- package/src/bean/resource/icon/types.ts +21 -0
- package/src/bean/resource/icon/useZovaIcon.ts +20 -0
- package/src/bean/resource/icon/utils.ts +20 -0
- package/src/bean/resource/icon/zovaIcon.ts +52 -0
- package/src/bean/resource/index.ts +8 -0
- package/src/bean/resource/locale/beanScopeLocale.ts +22 -0
- package/src/bean/resource/locale/index.ts +2 -0
- package/src/bean/resource/locale/type.ts +21 -0
- package/src/bean/resource/page/index.ts +1 -0
- package/src/bean/resource/page/type.ts +12 -0
- package/src/bean/resource/service/beanScopeService.ts +24 -0
- package/src/bean/resource/service/index.ts +2 -0
- package/src/bean/resource/service/type.ts +8 -0
- package/src/bean/scope/beanScopeBase.ts +74 -0
- package/src/bean/scope/index.ts +4 -0
- package/src/bean/scope/type.ts +23 -0
- package/src/bean/type.ts +31 -0
- package/src/composables/index.ts +4 -0
- package/src/composables/onControllerMounted.ts +12 -0
- package/src/composables/useApp.ts +7 -0
- package/src/composables/useContext.ts +7 -0
- package/src/composables/useController.ts +125 -0
- package/src/core/app/application.ts +76 -0
- package/src/core/app/config.ts +68 -0
- package/src/core/app/constant.ts +11 -0
- package/src/core/app/index.ts +6 -0
- package/src/core/app/locale.ts +12 -0
- package/src/core/app/meta.ts +44 -0
- package/src/core/app/util.ts +31 -0
- package/src/core/component/component.ts +44 -0
- package/src/core/component/cookie.ts +16 -0
- package/src/core/component/error.ts +18 -0
- package/src/core/component/event.ts +87 -0
- package/src/core/component/index.ts +3 -0
- package/src/core/component/locale.ts +97 -0
- package/src/core/component/module.ts +281 -0
- package/src/core/context/component.ts +34 -0
- package/src/core/context/context.ts +38 -0
- package/src/core/context/index.ts +4 -0
- package/src/core/context/meta.ts +26 -0
- package/src/core/context/state.ts +28 -0
- package/src/core/context/util.ts +20 -0
- package/src/core/index.ts +5 -0
- package/src/core/metadata.ts +54 -0
- package/src/core/resource.ts +186 -0
- package/src/decorator/class/bean.ts +19 -0
- package/src/decorator/class/index.ts +12 -0
- package/src/decorator/class/local.ts +18 -0
- package/src/decorator/class/model.ts +18 -0
- package/src/decorator/class/scope.ts +18 -0
- package/src/decorator/class/store.ts +18 -0
- package/src/decorator/class/style.ts +18 -0
- package/src/decorator/class/theme.ts +18 -0
- package/src/decorator/class/tool.ts +18 -0
- package/src/decorator/class/use.ts +37 -0
- package/src/decorator/class/useComposable.ts +16 -0
- package/src/decorator/class/useScope.ts +21 -0
- package/src/decorator/class/virtual.ts +20 -0
- package/src/decorator/index.ts +7 -0
- package/src/decorator/interface/beanOptions.ts +80 -0
- package/src/decorator/interface/useOptions.ts +37 -0
- package/src/decorator/type/constructable.ts +1 -0
- package/src/decorator/type/containerScope.ts +1 -0
- package/src/decorator/type/functionable.ts +1 -0
- package/src/decorator/type/injectionScope.ts +1 -0
- package/src/index.ts +9 -0
- package/src/plugins/bean.ts +16 -0
- package/src/plugins/index.ts +2 -0
- package/src/plugins/zova.ts +28 -0
- package/src/types/index.ts +2 -0
- package/src/types/interface/component.ts +36 -0
- package/src/types/interface/event.ts +28 -0
- package/src/types/interface/index.ts +6 -0
- package/src/types/interface/inject.ts +2 -0
- package/src/types/interface/module.ts +38 -0
- package/src/types/interface/monkey.ts +38 -0
- package/src/types/interface/pluginZova.ts +17 -0
- package/src/types/utils/cast.ts +8 -0
- package/src/types/utils/env.ts +35 -0
- package/src/types/utils/index.ts +3 -0
- package/src/types/utils/powerPartial.ts +3 -0
- package/src/utils/index.ts +1 -0
- package/src/utils/isClass.ts +17 -0
- package/src/utils/stateLock.ts +47 -0
- package/src/utils/uuid.ts +84 -0
- package/src/vue/composable.ts +10 -0
- package/src/vue/computed.ts +7 -0
- package/src/vue/customRef.ts +5 -0
- package/src/vue/index.ts +4 -0
- package/src/vue/ref.ts +12 -0
- package/src/zod/index.ts +2 -0
- package/src/zod/zz.ts +77 -0
- package/dist/decorator/class/data.d.ts +0 -3
- package/dist/decorator/class/data.d.ts.map +0 -1
- package/dist/decorator/class/data.js +0 -18
- 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,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
|
+
}
|