module的相关代码

This commit is contained in:
Xu Chang 2024-04-02 19:40:37 +08:00
parent 4c78de2233
commit fd540fe96f
26 changed files with 492 additions and 17 deletions

View File

@ -5,7 +5,6 @@ import { SyncConfig } from "./Sync";
import { AttrUpdateMatrix } from './EntityDesc';
import { ActionDefDict } from './Action';
import { StyleDict } from './Style';
import { Exportation, Importation } from './Port';
/**
*
*/
@ -14,7 +13,7 @@ export type ServerConfiguration<ED extends BaseEntityDict & EntityDict, Cxt exte
type: 'mysql';
host: string;
database: string;
port: number;
port?: number;
user: string;
password?: string;
connectionLimit: number;
@ -37,7 +36,8 @@ export type AccessConfiguration = {
bridge?: string;
};
http: {
port: number;
hostname: string;
port?: number;
ssl?: boolean;
path?: string;
};
@ -45,12 +45,10 @@ export type AccessConfiguration = {
/**
*
*/
export type CommonConfiguration<ED extends BaseEntityDict & EntityDict, Cxt extends AsyncContext<ED>> = {
export type CommonConfiguration<ED extends BaseEntityDict & EntityDict> = {
attrUpdateMatrix: AttrUpdateMatrix<ED>;
actionDefDict: ActionDefDict<ED>;
authDeduceRelationMap: AuthDeduceRelationMap<ED>;
importations?: Importation<ED, keyof ED, any, Cxt>[];
exportations?: Exportation<ED, keyof ED, any, Cxt>[];
selectFreeEntities?: (keyof ED)[];
updateFreeDict?: {
[A in keyof ED]?: string[];
@ -58,6 +56,7 @@ export type CommonConfiguration<ED extends BaseEntityDict & EntityDict, Cxt exte
cacheSavedEntities?: (keyof ED)[];
cacheKeepFreshPeriod?: number;
};
export type DependencyConfiguration = string[];
/**
*
*/

View File

@ -36,4 +36,7 @@ export interface Connector<ED extends EntityDict, FrontCxt extends SyncContext<E
url: string;
headers?: Record<string, string>;
};
getFullData: (keys?: (keyof ED)[]) => Promise<{
[T in keyof ED]?: ED[T]['OpSchema'][];
}>;
}

View File

@ -77,5 +77,6 @@ export declare class SimpleConnector<ED extends EntityDict, FrontCxt extends Syn
url: string;
headers?: Record<string, string> | undefined;
};
getFullData(): Promise<{}>;
}
export {};

View File

@ -213,5 +213,9 @@ class SimpleConnector {
headers: headers && JSON.parse(headers),
};
}
async getFullData() {
console.error('前后台模式下暂时不支持此操作,请到数据库查看数据');
return {};
}
}
exports.SimpleConnector = SimpleConnector;

10
lib/utils/lodash.d.ts vendored
View File

@ -12,6 +12,7 @@ import intersection from 'lodash/intersection';
import intersectionBy from 'lodash/intersectionBy';
import omit from 'lodash/omit';
import merge from 'lodash/merge';
import mergeWith from 'lodash/mergeWith';
import cloneDeep from 'lodash/cloneDeep';
import pick from 'lodash/pick';
import isEqual from 'lodash/isEqual';
@ -21,4 +22,11 @@ import differenceBy from 'lodash/differenceBy';
import groupBy from 'lodash/groupBy';
import unionBy from 'lodash/unionBy';
import pullAll from 'lodash/pullAll';
export { unset, pull, uniq, uniqBy, get, set, intersection, intersectionBy, omit, merge, cloneDeep, pick, isEqual, union, difference, differenceBy, groupBy, unionBy, pullAll, };
/**
* merge两个对象array时使用连接合并
* @param object
* @param source
* @returns
*/
declare function mergeRecursively<TObject, TSource>(object: TObject, source: TSource): TObject & TSource;
export { unset, pull, uniq, uniqBy, get, set, intersection, intersectionBy, omit, merge, mergeWith, mergeRecursively, cloneDeep, pick, isEqual, union, difference, differenceBy, groupBy, unionBy, pullAll, };

View File

@ -1,6 +1,6 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.pullAll = exports.unionBy = exports.groupBy = exports.differenceBy = exports.difference = exports.union = exports.isEqual = exports.pick = exports.cloneDeep = exports.merge = exports.omit = exports.intersectionBy = exports.intersection = exports.set = exports.get = exports.uniqBy = exports.uniq = exports.pull = exports.unset = void 0;
exports.pullAll = exports.unionBy = exports.groupBy = exports.differenceBy = exports.difference = exports.union = exports.isEqual = exports.pick = exports.cloneDeep = exports.mergeRecursively = exports.mergeWith = exports.merge = exports.omit = exports.intersectionBy = exports.intersection = exports.set = exports.get = exports.uniqBy = exports.uniq = exports.pull = exports.unset = void 0;
const tslib_1 = require("tslib");
/**
* 避免lodash打包体积过大
@ -26,6 +26,8 @@ const omit_1 = tslib_1.__importDefault(require("lodash/omit"));
exports.omit = omit_1.default;
const merge_1 = tslib_1.__importDefault(require("lodash/merge"));
exports.merge = merge_1.default;
const mergeWith_1 = tslib_1.__importDefault(require("lodash/mergeWith"));
exports.mergeWith = mergeWith_1.default;
const cloneDeep_1 = tslib_1.__importDefault(require("lodash/cloneDeep"));
exports.cloneDeep = cloneDeep_1.default;
const pick_1 = tslib_1.__importDefault(require("lodash/pick"));
@ -44,3 +46,19 @@ const unionBy_1 = tslib_1.__importDefault(require("lodash/unionBy"));
exports.unionBy = unionBy_1.default;
const pullAll_1 = tslib_1.__importDefault(require("lodash/pullAll"));
exports.pullAll = pullAll_1.default;
const assert_1 = tslib_1.__importDefault(require("assert"));
/**
* merge两个对象遇到array时使用连接合并
* @param object
* @param source
* @returns
*/
function mergeRecursively(object, source) {
return (0, mergeWith_1.default)(object, source, (objValue, srcValue) => {
if (objValue instanceof Array) {
(0, assert_1.default)(srcValue instanceof Array, '合并的对象必须结构一致');
return objValue.concat(srcValue);
}
});
}
exports.mergeRecursively = mergeRecursively;

15
lib/utils/module/combine.common.d.ts vendored Normal file
View File

@ -0,0 +1,15 @@
import { AsyncContext } from "../../store/AsyncRowStore";
import { SyncContext } from "../../store/SyncRowStore";
import { EntityDict } from "../../types/Entity";
import { EntityDict as BaseEntityDict } from '../../base-app-domain';
import { Checker } from '../../types/Auth';
import { CommonConfiguration } from '../../types/Configuration';
/**
* checker和common
* @param modules
* @returns
*/
export default function combineBaseModules<ED extends EntityDict & BaseEntityDict, Cxt extends AsyncContext<ED> | SyncContext<ED>>(...modules: string[]): {
checkers: Array<Checker<ED, keyof ED, Cxt>>;
common: CommonConfiguration<ED>;
};

View File

@ -0,0 +1,27 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const tslib_1 = require("tslib");
const lodash_1 = require("../../utils/lodash");
const assert_1 = tslib_1.__importDefault(require("assert"));
/**
* 合并引入模块中的checker和common
* @param modules
* @returns
*/
function combineBaseModules(...modules) {
// 合并模块中的checker/common
return modules.map((module) => {
const checkers = require(`${module}/lib/checkers`).default;
const common = require(`${module}/lib/configuration`).default;
(0, assert_1.default)(checkers instanceof Array, `${module}模块中的checkers不是数组`);
(0, assert_1.default)(typeof common === 'object', `${module}模块中的common配置不是对象`);
return {
checkers,
common,
};
}).reduce((prev, current) => ({
checkers: (0, lodash_1.mergeRecursively)(prev.checkers, current.checkers),
common: (0, lodash_1.mergeRecursively)(prev.common, current.common),
}));
}
exports.default = combineBaseModules;

1
lib/utils/module/combine.d.ts vendored Normal file
View File

@ -0,0 +1 @@
export * from './combine.dev';

17
lib/utils/module/combine.dev.d.ts vendored Normal file
View File

@ -0,0 +1,17 @@
import { AsyncContext } from "../../store/AsyncRowStore";
import { SyncContext } from "../../store/SyncRowStore";
import { EntityDict } from "../../types/Entity";
import { EntityDict as BaseEntityDict } from '../../base-app-domain';
import { Aspect, Exportation, Importation, Routine, Timer, Trigger, Watcher } from '../../types';
export default function combineModuleDev<ED extends EntityDict & BaseEntityDict, Cxt extends AsyncContext<ED>, FrontCxt extends SyncContext<ED>>(...modules: string[]): {
aspectDict: Record<string, Aspect<ED, Cxt>>;
data: { [T in keyof ED]?: ED[T]["OpSchema"][] | undefined; };
importations: Importation<ED, keyof ED, string, Cxt>;
exportations: Exportation<ED, keyof ED, string, Cxt>;
watchers: Watcher<ED, keyof ED, Cxt>[];
timers: Timer<ED, keyof ED, Cxt>[];
startRoutines: Routine<ED, keyof ED, Cxt>[];
triggers: Trigger<ED, keyof ED, Cxt>[];
checkers: import("../../types").Checker<ED, keyof ED, never>[];
common: import("../../types/Configuration").CommonConfiguration<ED>;
};

View File

@ -0,0 +1,55 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const tslib_1 = require("tslib");
const combine_common_1 = tslib_1.__importDefault(require("./combine.common"));
const lodash_1 = require("../../utils/lodash");
const assert_1 = tslib_1.__importDefault(require("assert"));
function combineModuleDev(...modules) {
const { checkers, common } = (0, combine_common_1.default)(...modules);
const others = modules.map((module) => ({
triggers: require(`${module}/lib/triggers`).default,
aspectDict: require(`${module}/lib/aspects`).default,
watchers: require(`${module}/lib/watchers`).default,
timers: require(`${module}/lib/timers`).default,
startRoutines: require(`${module}/lib/routines/start`).default,
importations: require(`${module}/lib/ports`).importations,
exportations: require(`${module}/lib/ports`).exportations,
data: require(`${module}/lib/data`).default,
})).reduce((prev, current, index) => {
const check = (module, name) => {
(0, assert_1.default)(typeof module.aspectDict === 'object', `${name}模块中的aspectDict不是对象`);
(0, assert_1.default)(typeof module.data === 'object', `${name}模块中的data不是对象`);
(0, assert_1.default)(module.exportations instanceof Array, `${name}模块中的exportations不是数组`);
(0, assert_1.default)(module.importations instanceof Array, `${name}模块中的importations不是数组`);
(0, assert_1.default)(module.watchers instanceof Array, `${name}模块中的watchers不是数组`);
(0, assert_1.default)(module.timers instanceof Array, `${name}模块中的timers不是数组`);
(0, assert_1.default)(module.triggers instanceof Array, `${name}模块中的triggers不是数组`);
(0, assert_1.default)(module.startRoutines instanceof Array, `${name}模块中的startRoutines不是数组`);
};
if (index === 1) {
check(prev, modules[0]);
}
check(current, modules[index]);
// aspectDict中不应当有同名对象
const its = (0, lodash_1.intersection)(Object.keys(prev.aspectDict), Object.keys(current.aspectDict));
if (its.length > 0) {
throw new Error(`模块${modules[index]}的aspectDict中存在和其它模块同步的aspect【${its.join(',')}】,请正确处理`);
}
return {
aspectDict: (0, lodash_1.mergeRecursively)(prev.aspectDict, current.aspectDict),
data: (0, lodash_1.mergeRecursively)(prev.data, current.data),
importations: (0, lodash_1.mergeRecursively)(prev.importations, current.importations),
exportations: (0, lodash_1.mergeRecursively)(prev.exportations, current.exportations),
watchers: (0, lodash_1.mergeRecursively)(prev.watchers, current.watchers),
timers: (0, lodash_1.merge)(prev.timers, current.timers),
startRoutines: (0, lodash_1.merge)(prev.startRoutines, current.startRoutines),
triggers: (0, lodash_1.merge)(prev.triggers, current.triggers),
};
});
return {
checkers,
common,
...others,
};
}
exports.default = combineModuleDev;

View File

@ -0,0 +1,4 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const tslib_1 = require("tslib");
tslib_1.__exportStar(require("./combine.dev"), exports);

8
lib/utils/module/combine.prod.d.ts vendored Normal file
View File

@ -0,0 +1,8 @@
import { AsyncContext } from "../../store/AsyncRowStore";
import { SyncContext } from "../../store/SyncRowStore";
import { EntityDict } from "../../types/Entity";
import { EntityDict as BaseEntityDict } from '../../base-app-domain';
export default function combineModuleDev<ED extends EntityDict & BaseEntityDict, Cxt extends AsyncContext<ED>, FrontCxt extends SyncContext<ED>>(...modules: string[]): {
checkers: import("../../types").Checker<ED, keyof ED, never>[];
common: import("../../types/Configuration").CommonConfiguration<ED>;
};

View File

@ -0,0 +1,8 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const tslib_1 = require("tslib");
const combine_common_1 = tslib_1.__importDefault(require("./combine.common"));
function combineModuleDev(...modules) {
return (0, combine_common_1.default)(...modules);
}
exports.default = combineModuleDev;

17
lib/utils/module/combine.server.d.ts vendored Normal file
View File

@ -0,0 +1,17 @@
import { AsyncContext } from "../../store/AsyncRowStore";
import { SyncContext } from "../../store/SyncRowStore";
import { EntityDict } from "../../types/Entity";
import { EntityDict as BaseEntityDict } from '../../base-app-domain';
import { Aspect, Exportation, Importation, Routine, Timer, Trigger, Watcher } from '../../types';
export default function combineModuleServer<ED extends EntityDict & BaseEntityDict, Cxt extends AsyncContext<ED>, FrontCxt extends SyncContext<ED>>(...modules: string[]): {
aspectDict: Record<string, Aspect<ED, Cxt>>;
data: { [T in keyof ED]?: ED[T]["OpSchema"][] | undefined; };
importations: Importation<ED, keyof ED, string, Cxt>;
exportations: Exportation<ED, keyof ED, string, Cxt>;
watchers: Watcher<ED, keyof ED, Cxt>[];
timers: Timer<ED, keyof ED, Cxt>[];
startRoutines: Routine<ED, keyof ED, Cxt>[];
triggers: Trigger<ED, keyof ED, Cxt>[];
checkers: import("../../types").Checker<ED, keyof ED, never>[];
common: import("../../types/Configuration").CommonConfiguration<ED>;
};

View File

@ -0,0 +1,55 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const tslib_1 = require("tslib");
const combine_common_1 = tslib_1.__importDefault(require("./combine.common"));
const lodash_1 = require("../../utils/lodash");
const assert_1 = tslib_1.__importDefault(require("assert"));
function combineModuleServer(...modules) {
const { checkers, common } = (0, combine_common_1.default)(...modules);
const others = modules.map((module) => ({
triggers: require(`${module}/lib/triggers`).default,
aspectDict: require(`${module}/lib/aspects`).default,
watchers: require(`${module}/lib/watchers`).default,
timers: require(`${module}/lib/timers`).default,
startRoutines: require(`${module}/lib/routines/start`).default,
importations: require(`${module}/lib/ports`).importations,
exportations: require(`${module}/lib/ports`).exportations,
data: require(`${module}/lib/data`).default,
})).reduce((prev, current, index) => {
const check = (module, name) => {
(0, assert_1.default)(typeof module.aspectDict === 'object', `${name}模块中的aspectDict不是对象`);
(0, assert_1.default)(typeof module.data === 'object', `${name}模块中的data不是对象`);
(0, assert_1.default)(module.exportations instanceof Array, `${name}模块中的exportations不是数组`);
(0, assert_1.default)(module.importations instanceof Array, `${name}模块中的importations不是数组`);
(0, assert_1.default)(module.watchers instanceof Array, `${name}模块中的watchers不是数组`);
(0, assert_1.default)(module.timers instanceof Array, `${name}模块中的timers不是数组`);
(0, assert_1.default)(module.triggers instanceof Array, `${name}模块中的triggers不是数组`);
(0, assert_1.default)(module.startRoutines instanceof Array, `${name}模块中的startRoutines不是数组`);
};
if (index === 1) {
check(prev, modules[0]);
}
check(current, modules[index]);
// aspectDict中不应当有同名对象
const its = (0, lodash_1.intersection)(Object.keys(prev.aspectDict), Object.keys(current.aspectDict));
if (its.length > 0) {
throw new Error(`模块${modules[index]}的aspectDict中存在和其它模块同步的aspect【${its.join(',')}】,请正确处理`);
}
return {
aspectDict: (0, lodash_1.mergeRecursively)(prev.aspectDict, current.aspectDict),
data: (0, lodash_1.mergeRecursively)(prev.data, current.data),
importations: (0, lodash_1.mergeRecursively)(prev.importations, current.importations),
exportations: (0, lodash_1.mergeRecursively)(prev.exportations, current.exportations),
watchers: (0, lodash_1.mergeRecursively)(prev.watchers, current.watchers),
timers: (0, lodash_1.merge)(prev.timers, current.timers),
startRoutines: (0, lodash_1.merge)(prev.startRoutines, current.startRoutines),
triggers: (0, lodash_1.merge)(prev.triggers, current.triggers),
};
});
return {
checkers,
common,
...others,
};
}
exports.default = combineModuleServer;

View File

@ -38,7 +38,7 @@ export class TriggerExecutor<ED extends EntityDict & BaseEntityDict, Cxt extends
private volatileEntities: Array<keyof ED>;
private logger: Logger;
private contextBuilder: (cxtString?: string) => Promise<Cxt>;
private contextBuilder: () => Cxt;
private onVolatileTrigger: <T extends keyof ED>(
entity: T,
trigger: VolatileTrigger<ED, T, Cxt>,
@ -48,7 +48,7 @@ export class TriggerExecutor<ED extends EntityDict & BaseEntityDict, Cxt extends
) => Promise<void>;
constructor(
contextBuilder: (cxtString?: string) => Promise<Cxt>,
contextBuilder: () => Cxt,
logger: Logger = console,
onVolatileTrigger?: <T extends keyof ED>(
entity: T,
@ -64,7 +64,7 @@ export class TriggerExecutor<ED extends EntityDict & BaseEntityDict, Cxt extends
this.volatileEntities = [];
this.counter = 0;
this.onVolatileTrigger = onVolatileTrigger || (async (entity, trigger, ids, cxtStr, option) => {
const context = await this.contextBuilder(cxtStr);
const context = this.contextBuilder();
await context.begin();
try {
await this.execVolatileTrigger(entity, trigger.name, ids, context, option);
@ -551,7 +551,7 @@ export class TriggerExecutor<ED extends EntityDict & BaseEntityDict, Cxt extends
$lt: timestamp,
}
};
const context = await this.contextBuilder();
const context = this.contextBuilder();
if (context.clusterInfo?.usingCluster) {
const { instanceCount, instanceId } = context.clusterInfo!;
filter.$$seq$$ = {

View File

@ -16,7 +16,7 @@ export type ServerConfiguration<ED extends BaseEntityDict & EntityDict, Cxt exte
type: 'mysql',
host: string;
database: string;
port: number;
port?: number;
user: string;
password?: string;
connectionLimit: number;
@ -50,8 +50,11 @@ export type AccessConfiguration = {
bridge?: string;
},
http: {
// 后台所在域名
hostname: string;
// 监听端口号
port: number;
port?: number;
// 是否配用https(nginx)
ssl?: boolean;
@ -64,12 +67,10 @@ export type AccessConfiguration = {
/**
*
*/
export type CommonConfiguration<ED extends BaseEntityDict & EntityDict, Cxt extends AsyncContext<ED>> = {
export type CommonConfiguration<ED extends BaseEntityDict & EntityDict> = {
attrUpdateMatrix: AttrUpdateMatrix<ED>;
actionDefDict: ActionDefDict<ED>;
authDeduceRelationMap: AuthDeduceRelationMap<ED>;
importations?: Importation<ED, keyof ED, any, Cxt>[];
exportations?: Exportation<ED, keyof ED, any, Cxt>[];
selectFreeEntities?: (keyof ED)[];
updateFreeDict?: {
[A in keyof ED]?: string[];
@ -78,6 +79,8 @@ export type CommonConfiguration<ED extends BaseEntityDict & EntityDict, Cxt exte
cacheKeepFreshPeriod?: number;
};
export type DependencyConfiguration = string[];
/**
*
*/

View File

@ -61,4 +61,9 @@ export interface Connector<ED extends EntityDict, FrontCxt extends SyncContext<E
url: string;
headers?: Record<string, string>;
};
// 获得所有数据(测试环境用)
getFullData: (keys?: (keyof ED)[]) => Promise<{
[T in keyof ED]?: ED[T]['OpSchema'][];
}>
}

View File

@ -266,4 +266,9 @@ export class SimpleConnector<ED extends EntityDict, FrontCxt extends SyncContext
headers: headers && JSON.parse(headers),
};
}
async getFullData() {
console.error('前后台模式下暂时不支持此操作,请到数据库查看数据');
return {};
}
}

View File

@ -12,6 +12,7 @@ import intersection from 'lodash/intersection';
import intersectionBy from 'lodash/intersectionBy';
import omit from 'lodash/omit';
import merge from 'lodash/merge';
import mergeWith from 'lodash/mergeWith';
import cloneDeep from 'lodash/cloneDeep';
import pick from 'lodash/pick';
import isEqual from 'lodash/isEqual';
@ -21,6 +22,22 @@ import differenceBy from 'lodash/differenceBy';
import groupBy from 'lodash/groupBy';
import unionBy from 'lodash/unionBy';
import pullAll from 'lodash/pullAll';
import assert from 'assert';
/**
* merge两个对象array时使用连接合并
* @param object
* @param source
* @returns
*/
function mergeRecursively<TObject, TSource>(object: TObject, source: TSource) {
return mergeWith(object, source, (objValue, srcValue) => {
if (objValue instanceof Array) {
assert(srcValue instanceof Array, '合并的对象必须结构一致');
return objValue.concat(srcValue);
}
});
}
export {
unset,
@ -33,6 +50,8 @@ export {
intersectionBy,
omit,
merge,
mergeWith,
mergeRecursively,
cloneDeep,
pick,
isEqual,

View File

@ -0,0 +1,36 @@
import { mergeRecursively } from '../../utils/lodash';
import { AsyncContext } from "../../store/AsyncRowStore";
import { SyncContext } from "../../store/SyncRowStore";
import { EntityDict } from "../../types/Entity";
import { EntityDict as BaseEntityDict } from '../../base-app-domain';
import { Checker } from '../../types/Auth';
import { CommonConfiguration } from '../../types/Configuration';
import assert from 'assert';
/**
* checker和common
* @param modules
* @returns
*/
export default function combineBaseModules<ED extends EntityDict & BaseEntityDict, Cxt extends AsyncContext<ED> | SyncContext<ED>>(...modules: string[]) {
// 合并模块中的checker/common
return modules.map(
(module) => {
const checkers = require(`${module}/lib/checkers`).default;
const common = require(`${module}/lib/configuration`).default;
assert(checkers instanceof Array, `${module}模块中的checkers不是数组`);
assert(typeof common === 'object', `${module}模块中的common配置不是对象`);
return {
checkers,
common,
};
}
).reduce((prev, current) => ({
checkers: mergeRecursively(prev.checkers, current.checkers),
common: mergeRecursively(prev.common, current.common),
})) as {
checkers: Array<Checker<ED, keyof ED, Cxt>>;
common: CommonConfiguration<ED>;
};
}

View File

@ -0,0 +1,77 @@
import combineBaseModules from './combine.common';
import { intersection, merge, mergeRecursively } from '../../utils/lodash';
import { AsyncContext } from "../../store/AsyncRowStore";
import { SyncContext } from "../../store/SyncRowStore";
import { EntityDict } from "../../types/Entity";
import { EntityDict as BaseEntityDict } from '../../base-app-domain';
import assert from 'assert';
import { Aspect, Exportation, Importation, Routine, Timer, Trigger, Watcher } from '../../types';
import { RenderConfiguration } from '../../types/Configuration';
export default function combineModuleDev<ED extends EntityDict & BaseEntityDict, Cxt extends AsyncContext<ED>, FrontCxt extends SyncContext<ED>>(...modules: string[]) {
const { checkers, common } = combineBaseModules<ED, Cxt & FrontCxt>(...modules);
const others = modules.map(
(module) => ({
triggers: require(`${module}/lib/triggers`).default,
aspectDict: require(`${module}/lib/aspects`).default,
watchers: require(`${module}/lib/watchers`).default,
timers: require(`${module}/lib/timers`).default,
startRoutines: require(`${module}/lib/routines/start`).default,
importations: require(`${module}/lib/ports`).importations,
exportations: require(`${module}/lib/ports`).exportations,
data: require(`${module}/lib/data`).default,
})
).reduce(
(prev, current, index) => {
const check = (module: typeof prev, name: string) => {
assert(typeof module.aspectDict === 'object', `${name}模块中的aspectDict不是对象`);
assert(typeof module.data === 'object', `${name}模块中的data不是对象`);
assert(module.exportations instanceof Array, `${name}模块中的exportations不是数组`);
assert(module.importations instanceof Array, `${name}模块中的importations不是数组`);
assert(module.watchers instanceof Array, `${name}模块中的watchers不是数组`);
assert(module.timers instanceof Array, `${name}模块中的timers不是数组`);
assert(module.triggers instanceof Array, `${name}模块中的triggers不是数组`);
assert(module.startRoutines instanceof Array, `${name}模块中的startRoutines不是数组`);
};
if (index === 1) {
check(prev, modules[0]);
}
check(current, modules[index]);
// aspectDict中不应当有同名对象
const its = intersection(Object.keys(prev.aspectDict), Object.keys(current.aspectDict));
if (its.length > 0) {
throw new Error(`模块${modules[index]}的aspectDict中存在和其它模块同步的aspect【${its.join(',')}】,请正确处理`);
}
return {
aspectDict: mergeRecursively(prev.aspectDict, current.aspectDict) ,
data: mergeRecursively(prev.data, current.data),
importations: mergeRecursively(prev.importations, current.importations),
exportations: mergeRecursively(prev.exportations, current.exportations),
watchers: mergeRecursively(prev.watchers, current.watchers),
timers: merge(prev.timers, current.timers),
startRoutines: merge(prev.startRoutines, current.startRoutines),
triggers: merge(prev.triggers, current.triggers),
};
}
) as {
aspectDict: Record<string, Aspect<ED, Cxt>>;
data: {
[T in keyof ED]?: Array<ED[T]['OpSchema']>;
};
importations: Importation<ED, keyof ED, string, Cxt>;
exportations: Exportation<ED, keyof ED, string, Cxt>;
watchers: Watcher<ED, keyof ED, Cxt>[];
timers: Timer<ED, keyof ED, Cxt>[];
startRoutines: Routine<ED, keyof ED, Cxt>[];
triggers: Trigger<ED, keyof ED, Cxt>[];
};
return {
checkers,
common,
...others,
};
}

View File

@ -0,0 +1,13 @@
import combineBaseModules from './combine.common';
import { mergeRecursively } from '../../utils/lodash';
import { AsyncContext } from "../../store/AsyncRowStore";
import { SyncContext } from "../../store/SyncRowStore";
import { EntityDict } from "../../types/Entity";
import { EntityDict as BaseEntityDict } from '../../base-app-domain';
import assert from 'assert';
import { RenderConfiguration } from '../../types/Configuration';
export default function combineModuleDev<ED extends EntityDict & BaseEntityDict, Cxt extends AsyncContext<ED>, FrontCxt extends SyncContext<ED>>(...modules: string[]) {
return combineBaseModules<ED, Cxt & FrontCxt>(...modules);
}

View File

@ -0,0 +1,76 @@
import combineBaseModules from './combine.common';
import { intersection, merge, mergeRecursively } from '../../utils/lodash';
import { AsyncContext } from "../../store/AsyncRowStore";
import { SyncContext } from "../../store/SyncRowStore";
import { EntityDict } from "../../types/Entity";
import { EntityDict as BaseEntityDict } from '../../base-app-domain';
import assert from 'assert';
import { Aspect, Exportation, Importation, Routine, Timer, Trigger, Watcher } from '../../types';
export default function combineModuleServer<ED extends EntityDict & BaseEntityDict, Cxt extends AsyncContext<ED>, FrontCxt extends SyncContext<ED>>(...modules: string[]) {
const { checkers, common } = combineBaseModules<ED, Cxt & FrontCxt>(...modules);
const others = modules.map(
(module) => ({
triggers: require(`${module}/lib/triggers`).default,
aspectDict: require(`${module}/lib/aspects`).default,
watchers: require(`${module}/lib/watchers`).default,
timers: require(`${module}/lib/timers`).default,
startRoutines: require(`${module}/lib/routines/start`).default,
importations: require(`${module}/lib/ports`).importations,
exportations: require(`${module}/lib/ports`).exportations,
data: require(`${module}/lib/data`).default,
})
).reduce(
(prev, current, index) => {
const check = (module: typeof prev, name: string) => {
assert(typeof module.aspectDict === 'object', `${name}模块中的aspectDict不是对象`);
assert(typeof module.data === 'object', `${name}模块中的data不是对象`);
assert(module.exportations instanceof Array, `${name}模块中的exportations不是数组`);
assert(module.importations instanceof Array, `${name}模块中的importations不是数组`);
assert(module.watchers instanceof Array, `${name}模块中的watchers不是数组`);
assert(module.timers instanceof Array, `${name}模块中的timers不是数组`);
assert(module.triggers instanceof Array, `${name}模块中的triggers不是数组`);
assert(module.startRoutines instanceof Array, `${name}模块中的startRoutines不是数组`);
};
if (index === 1) {
check(prev, modules[0]);
}
check(current, modules[index]);
// aspectDict中不应当有同名对象
const its = intersection(Object.keys(prev.aspectDict), Object.keys(current.aspectDict));
if (its.length > 0) {
throw new Error(`模块${modules[index]}的aspectDict中存在和其它模块同步的aspect【${its.join(',')}】,请正确处理`);
}
return {
aspectDict: mergeRecursively(prev.aspectDict, current.aspectDict) ,
data: mergeRecursively(prev.data, current.data),
importations: mergeRecursively(prev.importations, current.importations),
exportations: mergeRecursively(prev.exportations, current.exportations),
watchers: mergeRecursively(prev.watchers, current.watchers),
timers: merge(prev.timers, current.timers),
startRoutines: merge(prev.startRoutines, current.startRoutines),
triggers: merge(prev.triggers, current.triggers),
};
}
) as {
aspectDict: Record<string, Aspect<ED, Cxt>>;
data: {
[T in keyof ED]?: Array<ED[T]['OpSchema']>;
};
importations: Importation<ED, keyof ED, string, Cxt>;
exportations: Exportation<ED, keyof ED, string, Cxt>;
watchers: Watcher<ED, keyof ED, Cxt>[];
timers: Timer<ED, keyof ED, Cxt>[];
startRoutines: Routine<ED, keyof ED, Cxt>[];
triggers: Trigger<ED, keyof ED, Cxt>[];
};
return {
checkers,
common,
...others,
};
}

View File

@ -0,0 +1 @@
export * from './combine.dev';