(#56) Add Core Data. #57

Merged
MrKBear merged 1 commits from dev-mrkbear into master 2022-01-21 17:33:11 +08:00
Showing only changes of commit ec635b9ae6 - Show all commits

250
miniprogram/core/Data.ts Normal file
View File

@ -0,0 +1,250 @@
/**
*
*/
interface IDataParamSettingItem {
/**
*
*/
type: any;
/**
*
*/
isGet: boolean;
/**
*
*/
isSet: boolean;
/**
*
*/
isGetAsync?: boolean;
/**
*
*/
isSetAsync?: boolean;
}
/**
*
*/
interface IDataParamSetting {
[x: string]: IDataParamSettingItem
}
type IGet<T> = () => T;
type IGetAsync<T> = () => Promise<T>;
type ISet<T> = (data: T) => INone;
type ISetAsync<T> = (data: T) => Promise<INone>;
type INone = undefined | void | unknown;
/**
*
*/
type IRegistryItem<S extends IDataParamSettingItem> = {
/**
*
*/
get: S["isGetAsync"] extends true ? INone : S["isGet"] extends true ? IGet<S["type"]> : INone;
/**
*
*/
getAsync: S["isGet"] extends true ? IGetAsync<S["type"]> : INone;
/**
*
*/
set: S["isSetAsync"] extends true ? INone : S["isSet"] extends true ? ISet<S["type"]> : INone;
/**
*
*/
setAsync: S["isSet"] extends true ? ISetAsync<S["type"]> : INone;
}
/**
*
*/
type IRegistry<D extends IDataParamSetting> = {
[P in keyof D]: IRegistryItem<D[P]>;
}
type IRegistryPartial<D extends IDataParamSetting> = {
[P in keyof D]?: Partial<IRegistryItem<D[P]>>;
}
type IAutoSelect<IF extends boolean, A, B> = IF extends true ? A : B;
/**
* Core
*
* 使
* ```typescript
* class TestData extends Data<{
* test: {
* type: number,
* isGet: true,
* isSet: true,
* isGetAsync: true
* }
* }> {
* public onLoad() {
* let dataObject = {key: 1}
* this.getter("test", () => 1);
* this.registerKeyFromObject("test", "key", dataObject);
* }
* }
* ```
*/
class Data<D extends IDataParamSetting> {
/**
* getter setter
*/
private registryList: IRegistryPartial<D> = {};
/**
*
*/
public onLoad(): any {};
/**
* Setter
* @param key
* @param setter Setter
* @param isAsync
*/
protected setter<KEY extends keyof D> (key: KEY, setter: IRegistryItem<D[KEY]>["set"]): this
protected setter<KEY extends keyof D> (key: KEY, setter: IRegistryItem<D[KEY]>["setAsync"], isAsync: true): this
protected setter<
KEY extends keyof D,
ASYNC extends boolean
> (
key: KEY,
setter: IAutoSelect<ASYNC, IRegistryItem<D[KEY]>["setAsync"], IRegistryItem<D[KEY]>["set"]>,
isAsync?: ASYNC
): this {
// 如果此键值不存在,新建
if (!this.registryList[key]) this.registryList[key] = {};
// 设置异步 setter
if (isAsync) this.registryList[key]!.setAsync = setter as IRegistryItem<D[KEY]>["setAsync"];
// 设置同步 setter
else this.registryList[key]!.set = setter as IRegistryItem<D[KEY]>["set"];
return this;
}
/**
* Getter
* @param key
* @param getter Getter
* @param isAsync
*/
protected getter<KEY extends keyof D> (key: KEY, getter: IRegistryItem<D[KEY]>["get"]): this
protected getter<KEY extends keyof D> (key: KEY, getter: IRegistryItem<D[KEY]>["getAsync"], isAsync: true): this
protected getter<
KEY extends keyof D,
ASYNC extends boolean
> (
key: KEY,
getter: IAutoSelect<ASYNC, IRegistryItem<D[KEY]>["getAsync"], IRegistryItem<D[KEY]>["get"]>,
isAsync?: ASYNC
): this {
// 如果此键值不存在,新建
if (!this.registryList[key]) this.registryList[key] = {};
// 设置异步 getter
if (isAsync) this.registryList[key]!.getAsync = getter as IRegistryItem<D[KEY]>["getAsync"];
// 设置同步 getter
else this.registryList[key]!.get = getter as IRegistryItem<D[KEY]>["get"];
return this;
}
/**
* Data
* @param key Data
* @param keyFromObject
* @param object
*/
protected registerKeyFromObject<
KEY extends keyof D,
F extends keyof O,
O extends {[K in F]: D[KEY]["type"]}
> (key: KEY, keyFromObject: F, object: O) {
// 注册同步获取
this.getter(key, () => {
return object[keyFromObject]
});
// 注册同步设置
this.setter(key, (data: any) => {
object[keyFromObject] = data
})
}
/**
*
* @returns
*/
public export(): IRegistry<D> {
this.autoFillFunction();
return this.registryList as IRegistry<D>;
}
/**
*
*
*
* export
*/
protected autoFillFunction(): void {
// 填充函数
const fillFunction = <KEY extends keyof D>(key: KEY): void => {
const item = this.registryList[key] as IRegistryItem<D[KEY]>;
if (!item) return;
// 检验 getter
if (item.get && !item.getAsync) {
item.getAsync = this.syncFn2AsyncFn(item.get as IGet<D[KEY]["type"]>);
}
// 检验 setter
if (item.set && !item.setAsync) {
item.setAsync = this.syncFn2AsyncFn(item.set as ISet<D[KEY]["type"]>);
}
}
// 在注册表中查找
for (const key in this.registryList) fillFunction(key);
}
/**
*
* @param fn
*/
protected syncFn2AsyncFn<D, H extends (IGet<D> | ISet<D>)> (fn: H):
IAutoSelect<H extends IGet<D> ? true : false, IGetAsync<D>, ISetAsync<D>> {
const asyncFn = async (...param: [D]) => {
return fn(...param);
};
return asyncFn as any;
}
}