gdmb 1.0.0

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/README.md ADDED
@@ -0,0 +1,91 @@
1
+ # 项目介绍
2
+ 通用领域模型基座,提供领域模型设计开发通用基座能力。依赖 `tsyringe` 提供依赖注入能力。
3
+
4
+ ## 安装
5
+ `npm i gdmb --save`
6
+
7
+ ## 依赖
8
+
9
+ 以下依赖需要在项目中引入
10
+
11
+ - tsyringe:轻量级依赖注入容器
12
+ - reflect-metadata: 反射元数据
13
+
14
+ 修改 tsconfig.json 配置,开放元数据与反射支持
15
+ ``` json
16
+ "emitDecoratorMetadata": true,
17
+ "experimentalDecorators": true
18
+ ```
19
+
20
+ ## 用例
21
+
22
+ 注册领域、领域服务、领域实体
23
+
24
+ ```typescript
25
+ /** DomainOne.ts */
26
+ import { GDMB, Domain, DomainService, DomainEntity } from 'gdmb';
27
+
28
+ /** 值对象接口 */
29
+ export interface IVOOne {
30
+ text: string
31
+ }
32
+
33
+ /** 实例化gdmb实例对象,全局单例 */
34
+ const gdmb = new GDMB();
35
+
36
+ /** 领域一 */
37
+ class DomainOne extends Domain {
38
+ constructor() {
39
+ super();
40
+ // 注册服务域
41
+ this.registerService(ServiceOne);
42
+ // 注册实体域
43
+ this.registerEntity(EntityOne);
44
+ // 注册值对象
45
+ this.registerValueObject<IVOOne>({
46
+ token: 'IVOOne',
47
+ factoryType: 'containerCache',
48
+ resolveFactory() {
49
+ return { text: 'this is value object' };
50
+ }
51
+ });
52
+ // 更多使用方法参考类型定义
53
+ }
54
+ }
55
+
56
+ /** 服务一 */
57
+ class ServiceOne extends DomainService {}
58
+
59
+ /** 实体一 */
60
+ class EntityOne extends DomainEntity {}
61
+
62
+ /** 注册领域 */
63
+ gdmb.registerDomain(DomainOne);
64
+ ```
65
+
66
+ 获取领域相关实例
67
+
68
+ ```typescript
69
+ import { GDMB, Domain } from 'gdmb';
70
+
71
+ /** 实例化gdmb实例对象,全局单例 */
72
+ const gdmb = new GDMB();
73
+
74
+ // 获取领域对象
75
+ const domainOne = gdmb.domains(DomainOne.name);
76
+ /** 或者 */
77
+ const domainOne = gdmb.domains(DomainOne);
78
+
79
+ // 获取服务对象
80
+ const serviceOne = domainOne.services(ServiceOne.name);
81
+ /** 或者 */
82
+ const serviceOne = domainOne.services(ServiceOne);
83
+
84
+ // 获取实体对象
85
+ const entityOne = domainOne.entities(EntityOne.name);
86
+ /** 或者 */
87
+ const entityOne = domainOne.entities(EntityOne);
88
+
89
+ // 获取值对象
90
+ const voOne = domainOne.vos('IVOOne');
91
+ ```
@@ -0,0 +1,338 @@
1
+ import { container as l, Lifecycle as a, predicateAwareClassFactory as h, instancePerContainerCachingFactory as g, instanceCachingFactory as d } from "tsyringe";
2
+ class R {
3
+ /**
4
+ * 事件容器
5
+ */
6
+ _mapper = {};
7
+ /**
8
+ * 为使用模块注册事件容器
9
+ * @param eventName 事件模块名称
10
+ */
11
+ register(s) {
12
+ s in this._mapper || (this._mapper[s] = []);
13
+ }
14
+ /**
15
+ * 删除事件模块
16
+ */
17
+ remove(s) {
18
+ s in this._mapper && delete this._mapper[s];
19
+ }
20
+ /**
21
+ * 事件监听注册
22
+ * @param eventName 注册事件名称
23
+ * @param handler 处理器
24
+ * @returns 监听句柄
25
+ */
26
+ on(s, r) {
27
+ const t = this._mapper[s];
28
+ t ? t.push(r) : (this.register(s), this.on(s, r));
29
+ }
30
+ /**
31
+ * 移出指定监听函数监听
32
+ * @param eventName 事件名称
33
+ * @param handler 监听函数
34
+ */
35
+ off(s, r) {
36
+ const t = this._mapper[s];
37
+ if (t) {
38
+ const i = t.indexOf(r);
39
+ i !== -1 && t.splice(i, 1);
40
+ }
41
+ }
42
+ /**
43
+ * 触发事件
44
+ * @param eventName 事件名称
45
+ * @param args 时间回调参数
46
+ */
47
+ trigger(s, ...r) {
48
+ const t = this._mapper[s];
49
+ t && setTimeout(() => {
50
+ for (const i of Object.values(t))
51
+ i(...r);
52
+ }, 0);
53
+ }
54
+ /**
55
+ * 事件基类的构造函数
56
+ */
57
+ constructor() {
58
+ }
59
+ }
60
+ class v {
61
+ }
62
+ class _ {
63
+ /**
64
+ * @summary 领域内部依赖注入容器
65
+ * @description 领域内部依赖注入容器,用于注册和解析领域服务、实体、值对象等。
66
+ */
67
+ dic = l.createChildContainer();
68
+ /**
69
+ * @description 领域事件句柄,用于触发、监听、取消监听领域事件
70
+ */
71
+ e = new R();
72
+ /**
73
+ * @description 向领域依赖注入容器中注册一个或多个领域服务
74
+ * @param service 单个领域服务类或数组
75
+ * @param options 领域服务注册配置项,可传入领域服务构造参数以及配置依赖解决拦截器和频率等
76
+ * @example
77
+ * ```typescript
78
+ * class ServiceOne extends DomainService {
79
+ * constructor(public arg: string, public arg2: number) {
80
+ * super();
81
+ * }
82
+ * }
83
+ *
84
+ * domain.registerService(ServiceOne, { args: ['hello', 3] })
85
+ * // 多个服务时,配置条目允许 undefined 和 null,此时配置会被忽略
86
+ * domain.registerService([ServiceOne, ServiceTwo], [{ args: ['hello', 3] }, null])
87
+ * ```
88
+ */
89
+ registerService(s, r) {
90
+ const t = Array.isArray(s) ? s : [s], i = r ? Array.isArray(r) ? r : [r] : [];
91
+ for (let o = 0; o < t.length; o += 1) {
92
+ const e = t[o], c = i[o];
93
+ if (this.dic.isRegistered(e.name) || this.dic.isRegistered(e)) {
94
+ console.warn(`服务 ${e.name} 已注册,跳过注册`);
95
+ continue;
96
+ }
97
+ this.dic.register(e.name, { useClass: e }), this.dic.register(e, { useClass: e }), c?.beforeResolution && (this.dic.beforeResolution(e.name, c.beforeResolution, {
98
+ frequency: c?.beforeResolutionFrequency || "Always"
99
+ }), this.dic.beforeResolution(e, c.beforeResolution, {
100
+ frequency: c?.beforeResolutionFrequency || "Always"
101
+ })), c?.afterResolution && (this.dic.afterResolution(e.name, c.afterResolution, {
102
+ frequency: c?.afterResolutionFrequency || "Always"
103
+ }), this.dic.afterResolution(e, c?.afterResolution, {
104
+ frequency: c?.afterResolutionFrequency || "Always"
105
+ }));
106
+ }
107
+ }
108
+ /**
109
+ * @description 向领域依赖注入容器中注册领域实体,指定缓存策略为'cache'时全局单例。
110
+ * @param entity 单个领域实体类或数组
111
+ * @param options 领域实体注册配置项
112
+ * @example
113
+ * ```typescript
114
+ * class EntityOne extends DomainEntity {
115
+ * constructor(public arg: string, public arg2: number) {
116
+ * super();
117
+ * }
118
+ * }
119
+ *
120
+ * domain.registerEntity(EntityOne, { args: ['hello', 3] })
121
+ * // 多个实体时,配置条目允许 undefined 和 null,此时配置会被忽略
122
+ * domain.registerEntity([EntityOne, EntityTwo], [{ args: ['hello', 3] }, null])
123
+ * ```
124
+ */
125
+ registerEntity(s, r) {
126
+ const t = Array.isArray(s) ? s : [s], i = r ? Array.isArray(r) ? r : [r] : [];
127
+ for (let o = 0; o < t.length; o += 1) {
128
+ const e = t[o], c = i[o];
129
+ if (this.dic.isRegistered(e.name) || this.dic.isRegistered(e)) {
130
+ console.warn(`实体 ${e.name} 已注册,跳过注册`);
131
+ continue;
132
+ }
133
+ if (c?.cachePolicy)
134
+ switch (c.cachePolicy) {
135
+ case "cache":
136
+ l.register(e.name, { useClass: e }, { lifecycle: a.Singleton }), l.register(e, { useClass: e }, { lifecycle: a.Singleton });
137
+ break;
138
+ case "containerCache":
139
+ this.dic.register(e.name, { useClass: e }, { lifecycle: a.ContainerScoped }), this.dic.register(e, { useClass: e }, { lifecycle: a.ContainerScoped });
140
+ break;
141
+ case "resolution":
142
+ this.dic.register(e.name, { useClass: e }, { lifecycle: a.ResolutionScoped }), this.dic.register(e, { useClass: e }, { lifecycle: a.ResolutionScoped });
143
+ break;
144
+ }
145
+ else
146
+ this.dic.register(e.name, { useClass: e }, { lifecycle: a.Transient }), this.dic.register(e, { useClass: e }, { lifecycle: a.Transient });
147
+ c?.beforeResolution && (this.dic.beforeResolution(e.name, c.beforeResolution, {
148
+ frequency: "Always"
149
+ }), this.dic.beforeResolution(e, c.beforeResolution, {
150
+ frequency: "Always"
151
+ })), c?.afterResolution && (this.dic.afterResolution(e.name, c.afterResolution, {
152
+ frequency: "Always"
153
+ }), this.dic.afterResolution(e, c.afterResolution, {
154
+ frequency: "Always"
155
+ }));
156
+ }
157
+ }
158
+ /**
159
+ * @summary 项领域内依赖注入容器中注册值对象,当指定 factoryType 为'cache'时全局单例。
160
+ * @description 需要泛型类型 V,约束工厂函数返回类型,V 满足 VO 类型约束,不允许包含函数属性
161
+ * @param vos 值对象注册配置项
162
+ * @example
163
+ * ```typescript
164
+ * domain.registerVO({
165
+ * token: 'VO1',
166
+ * factoryType: 'cache',
167
+ * resolveFactory: () => ({ date: '2023-01-01' })
168
+ * })
169
+ * ```
170
+ */
171
+ registerVO(s) {
172
+ const r = Array.isArray(s) ? s : [s];
173
+ for (let t = 0; t < r.length; t += 1) {
174
+ const i = r[t], o = Array.isArray(i.token) ? i.token : [i.token];
175
+ for (let e = 0; e < o.length; e += 1) {
176
+ const c = o[e];
177
+ switch (i.factoryType) {
178
+ case "cache":
179
+ l.register(c, { useFactory: d(i.resolveFactory) });
180
+ break;
181
+ case "containerCache":
182
+ this.dic.register(c, { useFactory: g(i.resolveFactory) });
183
+ break;
184
+ case "predicate":
185
+ this.dic.register(c, {
186
+ useFactory: h(
187
+ i.resolveFactory,
188
+ i.positiveTarget,
189
+ i.negativeTarget
190
+ )
191
+ });
192
+ break;
193
+ default:
194
+ this.dic.register(c, { useFactory: i.resolveFactory });
195
+ break;
196
+ }
197
+ }
198
+ }
199
+ }
200
+ /**
201
+ * @description 从依赖注入容器中获取领域服务实例对象
202
+ * @param token 领域服务token
203
+ * @returns 领域服务实例对象
204
+ */
205
+ services(s) {
206
+ const r = this.dic.resolve(s);
207
+ return r && !r?.e && (r.e = this.e), r;
208
+ }
209
+ /**
210
+ * @description 从依赖注入容器中获取领域实体实例对象
211
+ * @param sourceToken 源领域实体token,存在适配器时是 DEF 泛型类型,否则为 DE 泛型类型
212
+ * @param adapter 领域实体适配器,将 DEF 类型转换为 DE 类型
213
+ * @returns 领域实体实例对象
214
+ */
215
+ entities(s, r) {
216
+ let t;
217
+ if (r) {
218
+ const i = this.dic.resolve(s);
219
+ t = r.transform(i);
220
+ } else
221
+ t = this.dic.resolve(s);
222
+ return t && !t?.e && (t.e = this.e), t;
223
+ }
224
+ /**
225
+ * @description 从依赖注入容器中获取领域值对象实例对象
226
+ * @param sourceToken 源领域值对象token,存在适配器时是 VF 泛型类型,否则为 V 泛型类型
227
+ * @param adapter 领域值对象适配器,将 VF 类型转换为 V 类型
228
+ * @returns 领域值对象实例对象
229
+ */
230
+ vos(s, r) {
231
+ if (r) {
232
+ const t = this.dic.resolve(s);
233
+ return r.transform(t);
234
+ } else
235
+ return this.dic.resolve(s);
236
+ }
237
+ /**
238
+ * 域基类构造函数
239
+ */
240
+ constructor() {
241
+ }
242
+ }
243
+ const y = (n) => (n.prototype.$ins = null, class extends n {
244
+ constructor(...s) {
245
+ return super(...s), n.prototype.$ins || (n.prototype.$ins = this), n.prototype.$ins;
246
+ }
247
+ });
248
+ var p = Object.getOwnPropertyDescriptor, m = (n, s, r, t) => {
249
+ for (var i = t > 1 ? void 0 : t ? p(s, r) : s, o = n.length - 1, e; o >= 0; o--)
250
+ (e = n[o]) && (i = e(i) || i);
251
+ return i;
252
+ };
253
+ let u = class {
254
+ /** 事件句柄 */
255
+ e = void 0;
256
+ /**
257
+ * 域基类构造函数
258
+ */
259
+ constructor() {
260
+ }
261
+ };
262
+ u = m([
263
+ y
264
+ ], u);
265
+ class w {
266
+ /** 事件句柄 */
267
+ e = void 0;
268
+ /**
269
+ * 域基类构造函数
270
+ */
271
+ constructor() {
272
+ }
273
+ }
274
+ var b = Object.getOwnPropertyDescriptor, A = (n, s, r, t) => {
275
+ for (var i = t > 1 ? void 0 : t ? b(s, r) : s, o = n.length - 1, e; o >= 0; o--)
276
+ (e = n[o]) && (i = e(i) || i);
277
+ return i;
278
+ };
279
+ let f = class {
280
+ /** 全局 DIC */
281
+ globalDIC = l;
282
+ /**
283
+ * 注册领域对象
284
+ */
285
+ registerDomain(n, s) {
286
+ const r = Array.isArray(n) ? n : [n], t = s ? Array.isArray(s) ? s : [s] : [];
287
+ for (let i = 0; i < r.length; i += 1) {
288
+ const o = r[i], e = t[i];
289
+ if (this.globalDIC.isRegistered(o.name)) {
290
+ console.warn(`领域 ${o.name} 已注册,无法重复注册`);
291
+ return;
292
+ }
293
+ const c = new o(...e?.args || []);
294
+ this.globalDIC.register(o.name, { useValue: c }), this.globalDIC.register(o, { useValue: c }), e?.beforeResolution && (this.globalDIC.beforeResolution(o.name, e.beforeResolution, {
295
+ frequency: e.beforeResolutionFrequency || "Always"
296
+ }), this.globalDIC.beforeResolution(o, e.beforeResolution, {
297
+ frequency: e.afterResolutionFrequency || "Always"
298
+ })), e?.afterResolution && (this.globalDIC.afterResolution(o.name, e.afterResolution, {
299
+ frequency: e.afterResolutionFrequency || "Always"
300
+ }), this.globalDIC.afterResolution(o, e.afterResolution, {
301
+ frequency: e.afterResolutionFrequency || "Always"
302
+ }));
303
+ }
304
+ }
305
+ /**
306
+ * 获取领域对象
307
+ */
308
+ domains(n) {
309
+ return this.globalDIC.resolve(n);
310
+ }
311
+ /**
312
+ * 提供全局的转换方法
313
+ */
314
+ transform(n, s) {
315
+ return s.transform(n);
316
+ }
317
+ /**
318
+ * 提供全局的转换方法,支持批量转换
319
+ */
320
+ transformAll(n, s) {
321
+ const r = [];
322
+ for (let t = 0; t < n.length; t += 1) {
323
+ const i = s.transform(n[t]);
324
+ i != null && r.push(i);
325
+ }
326
+ return r;
327
+ }
328
+ };
329
+ f = A([
330
+ y
331
+ ], f);
332
+ export {
333
+ v as Adapter,
334
+ _ as Domain,
335
+ w as DomainEntity,
336
+ u as DomainService,
337
+ f as GDMB
338
+ };
@@ -0,0 +1 @@
1
+ (function(l,c){typeof exports=="object"&&typeof module<"u"?c(exports,require("tsyringe")):typeof define=="function"&&define.amd?define(["exports","tsyringe"],c):(l=typeof globalThis<"u"?globalThis:l||self,c(l.gdmb={},l.tsyringe))})(this,(function(l,c){"use strict";class y{_mapper={};register(s){s in this._mapper||(this._mapper[s]=[])}remove(s){s in this._mapper&&delete this._mapper[s]}on(s,i){const r=this._mapper[s];r?r.push(i):(this.register(s),this.on(s,i))}off(s,i){const r=this._mapper[s];if(r){const t=r.indexOf(i);t!==-1&&r.splice(t,1)}}trigger(s,...i){const r=this._mapper[s];r&&setTimeout(()=>{for(const t of Object.values(r))t(...i)},0)}constructor(){}}class h{}class d{dic=c.container.createChildContainer();e=new y;registerService(s,i){const r=Array.isArray(s)?s:[s],t=i?Array.isArray(i)?i:[i]:[];for(let n=0;n<r.length;n+=1){const e=r[n],o=t[n];if(this.dic.isRegistered(e.name)||this.dic.isRegistered(e)){console.warn(`服务 ${e.name} 已注册,跳过注册`);continue}this.dic.register(e.name,{useClass:e}),this.dic.register(e,{useClass:e}),o?.beforeResolution&&(this.dic.beforeResolution(e.name,o.beforeResolution,{frequency:o?.beforeResolutionFrequency||"Always"}),this.dic.beforeResolution(e,o.beforeResolution,{frequency:o?.beforeResolutionFrequency||"Always"})),o?.afterResolution&&(this.dic.afterResolution(e.name,o.afterResolution,{frequency:o?.afterResolutionFrequency||"Always"}),this.dic.afterResolution(e,o?.afterResolution,{frequency:o?.afterResolutionFrequency||"Always"}))}}registerEntity(s,i){const r=Array.isArray(s)?s:[s],t=i?Array.isArray(i)?i:[i]:[];for(let n=0;n<r.length;n+=1){const e=r[n],o=t[n];if(this.dic.isRegistered(e.name)||this.dic.isRegistered(e)){console.warn(`实体 ${e.name} 已注册,跳过注册`);continue}if(o?.cachePolicy)switch(o.cachePolicy){case"cache":c.container.register(e.name,{useClass:e},{lifecycle:c.Lifecycle.Singleton}),c.container.register(e,{useClass:e},{lifecycle:c.Lifecycle.Singleton});break;case"containerCache":this.dic.register(e.name,{useClass:e},{lifecycle:c.Lifecycle.ContainerScoped}),this.dic.register(e,{useClass:e},{lifecycle:c.Lifecycle.ContainerScoped});break;case"resolution":this.dic.register(e.name,{useClass:e},{lifecycle:c.Lifecycle.ResolutionScoped}),this.dic.register(e,{useClass:e},{lifecycle:c.Lifecycle.ResolutionScoped});break}else this.dic.register(e.name,{useClass:e},{lifecycle:c.Lifecycle.Transient}),this.dic.register(e,{useClass:e},{lifecycle:c.Lifecycle.Transient});o?.beforeResolution&&(this.dic.beforeResolution(e.name,o.beforeResolution,{frequency:"Always"}),this.dic.beforeResolution(e,o.beforeResolution,{frequency:"Always"})),o?.afterResolution&&(this.dic.afterResolution(e.name,o.afterResolution,{frequency:"Always"}),this.dic.afterResolution(e,o.afterResolution,{frequency:"Always"}))}}registerVO(s){const i=Array.isArray(s)?s:[s];for(let r=0;r<i.length;r+=1){const t=i[r],n=Array.isArray(t.token)?t.token:[t.token];for(let e=0;e<n.length;e+=1){const o=n[e];switch(t.factoryType){case"cache":c.container.register(o,{useFactory:c.instanceCachingFactory(t.resolveFactory)});break;case"containerCache":this.dic.register(o,{useFactory:c.instancePerContainerCachingFactory(t.resolveFactory)});break;case"predicate":this.dic.register(o,{useFactory:c.predicateAwareClassFactory(t.resolveFactory,t.positiveTarget,t.negativeTarget)});break;default:this.dic.register(o,{useFactory:t.resolveFactory});break}}}}services(s){const i=this.dic.resolve(s);return i&&!i?.e&&(i.e=this.e),i}entities(s,i){let r;if(i){const t=this.dic.resolve(s);r=i.transform(t)}else r=this.dic.resolve(s);return r&&!r?.e&&(r.e=this.e),r}vos(s,i){if(i){const r=this.dic.resolve(s);return i.transform(r)}else return this.dic.resolve(s)}constructor(){}}const f=a=>(a.prototype.$ins=null,class extends a{constructor(...s){return super(...s),a.prototype.$ins||(a.prototype.$ins=this),a.prototype.$ins}});var m=Object.getOwnPropertyDescriptor,R=(a,s,i,r)=>{for(var t=r>1?void 0:r?m(s,i):s,n=a.length-1,e;n>=0;n--)(e=a[n])&&(t=e(t)||t);return t};l.DomainService=class{e=void 0;constructor(){}},l.DomainService=R([f],l.DomainService);class g{e=void 0;constructor(){}}var p=Object.getOwnPropertyDescriptor,b=(a,s,i,r)=>{for(var t=r>1?void 0:r?p(s,i):s,n=a.length-1,e;n>=0;n--)(e=a[n])&&(t=e(t)||t);return t};l.GDMB=class{globalDIC=c.container;registerDomain(s,i){const r=Array.isArray(s)?s:[s],t=i?Array.isArray(i)?i:[i]:[];for(let n=0;n<r.length;n+=1){const e=r[n],o=t[n];if(this.globalDIC.isRegistered(e.name)){console.warn(`领域 ${e.name} 已注册,无法重复注册`);return}const u=new e(...o?.args||[]);this.globalDIC.register(e.name,{useValue:u}),this.globalDIC.register(e,{useValue:u}),o?.beforeResolution&&(this.globalDIC.beforeResolution(e.name,o.beforeResolution,{frequency:o.beforeResolutionFrequency||"Always"}),this.globalDIC.beforeResolution(e,o.beforeResolution,{frequency:o.afterResolutionFrequency||"Always"})),o?.afterResolution&&(this.globalDIC.afterResolution(e.name,o.afterResolution,{frequency:o.afterResolutionFrequency||"Always"}),this.globalDIC.afterResolution(e,o.afterResolution,{frequency:o.afterResolutionFrequency||"Always"}))}}domains(s){return this.globalDIC.resolve(s)}transform(s,i){return i.transform(s)}transformAll(s,i){const r=[];for(let t=0;t<s.length;t+=1){const n=i.transform(s[t]);n!=null&&r.push(n)}return r}},l.GDMB=b([f],l.GDMB),l.Adapter=h,l.Domain=d,l.DomainEntity=g,Object.defineProperty(l,Symbol.toStringTag,{value:"Module"})}));
@@ -0,0 +1,9 @@
1
+ /**
2
+ * 适配器基类
3
+ */
4
+ export declare abstract class Adapter<T, F> {
5
+ /**
6
+ * @summary 抽象方法,自定义转换函数
7
+ */
8
+ abstract transform(source: F): T | undefined;
9
+ }
@@ -0,0 +1,42 @@
1
+ import { IAnyObject, TEventEmits } from '../type';
2
+ /**
3
+ * 自定义事件基类
4
+ */
5
+ export declare class BaseEvents<E extends TEventEmits = IAnyObject> {
6
+ /**
7
+ * 事件容器
8
+ */
9
+ private _mapper;
10
+ /**
11
+ * 为使用模块注册事件容器
12
+ * @param eventName 事件模块名称
13
+ */
14
+ private register;
15
+ /**
16
+ * 删除事件模块
17
+ */
18
+ protected remove(eventName: keyof E): void;
19
+ /**
20
+ * 事件监听注册
21
+ * @param eventName 注册事件名称
22
+ * @param handler 处理器
23
+ * @returns 监听句柄
24
+ */
25
+ on<K extends keyof E>(eventName: K, handler: (...args: E[K]) => void): void;
26
+ /**
27
+ * 移出指定监听函数监听
28
+ * @param eventName 事件名称
29
+ * @param handler 监听函数
30
+ */
31
+ off<K extends keyof E>(eventName: K, handler: (...args: E[K]) => void): void;
32
+ /**
33
+ * 触发事件
34
+ * @param eventName 事件名称
35
+ * @param args 时间回调参数
36
+ */
37
+ trigger<K extends keyof E>(eventName: K, ...args: E[K]): void;
38
+ /**
39
+ * 事件基类的构造函数
40
+ */
41
+ constructor();
42
+ }
@@ -0,0 +1,2 @@
1
+ export * from './BaseEvent';
2
+ export * from './Adapter';
@@ -0,0 +1 @@
1
+ export * from './singleton-decorator';
@@ -0,0 +1,6 @@
1
+ /**
2
+ * 单例装饰器
3
+ */
4
+ export declare const SingletenDecorator: <T extends {
5
+ new (...args: any[]): object;
6
+ }>(target: T) => T;
@@ -0,0 +1,95 @@
1
+ import { BaseEvents, Adapter } from '../base-class';
2
+ import { TEventEmits, VO, IRegisterServiceOption, IRegisterEntityOption, IRegisterVoOptionCache, IRegisterVoOptionContainerCache, IRegisterVoOptionPredicate, IRegisterVoOptionNoCache, TCustomInjectionToken } from '../type';
3
+ import { DomainService } from './DomainService';
4
+ import { DomainEntity } from './DomainEntity';
5
+ /** 值对象注册配置类型 */
6
+ type TRegisterVoOption<V extends VO<any>> = IRegisterVoOptionCache<V> | IRegisterVoOptionContainerCache<V> | IRegisterVoOptionPredicate<V> | IRegisterVoOptionNoCache<V>;
7
+ /**
8
+ * 领域对象类
9
+ */
10
+ export declare class Domain<E extends TEventEmits = TEventEmits> {
11
+ /**
12
+ * @summary 领域内部依赖注入容器
13
+ * @description 领域内部依赖注入容器,用于注册和解析领域服务、实体、值对象等。
14
+ */
15
+ dic: import('tsyringe').DependencyContainer;
16
+ /**
17
+ * @description 领域事件句柄,用于触发、监听、取消监听领域事件
18
+ */
19
+ e: BaseEvents<E>;
20
+ /**
21
+ * @description 向领域依赖注入容器中注册一个或多个领域服务
22
+ * @param service 单个领域服务类或数组
23
+ * @param options 领域服务注册配置项,可传入领域服务构造参数以及配置依赖解决拦截器和频率等
24
+ * @example
25
+ * ```typescript
26
+ * class ServiceOne extends DomainService {
27
+ * constructor(public arg: string, public arg2: number) {
28
+ * super();
29
+ * }
30
+ * }
31
+ *
32
+ * domain.registerService(ServiceOne, { args: ['hello', 3] })
33
+ * // 多个服务时,配置条目允许 undefined 和 null,此时配置会被忽略
34
+ * domain.registerService([ServiceOne, ServiceTwo], [{ args: ['hello', 3] }, null])
35
+ * ```
36
+ */
37
+ registerService<S extends DomainService>(service: (new (...args: any[]) => S) | Array<new (...args: any[]) => S>, options?: IRegisterServiceOption<S> | (IRegisterServiceOption<S> | undefined | null)[]): void;
38
+ /**
39
+ * @description 向领域依赖注入容器中注册领域实体,指定缓存策略为'cache'时全局单例。
40
+ * @param entity 单个领域实体类或数组
41
+ * @param options 领域实体注册配置项
42
+ * @example
43
+ * ```typescript
44
+ * class EntityOne extends DomainEntity {
45
+ * constructor(public arg: string, public arg2: number) {
46
+ * super();
47
+ * }
48
+ * }
49
+ *
50
+ * domain.registerEntity(EntityOne, { args: ['hello', 3] })
51
+ * // 多个实体时,配置条目允许 undefined 和 null,此时配置会被忽略
52
+ * domain.registerEntity([EntityOne, EntityTwo], [{ args: ['hello', 3] }, null])
53
+ * ```
54
+ */
55
+ registerEntity<E extends DomainEntity>(entity: (new (...args: any[]) => E) | Array<new (...args: any[]) => E>, options?: IRegisterEntityOption<E> | (IRegisterEntityOption<E> | undefined | null)[]): void;
56
+ /**
57
+ * @summary 项领域内依赖注入容器中注册值对象,当指定 factoryType 为'cache'时全局单例。
58
+ * @description 需要泛型类型 V,约束工厂函数返回类型,V 满足 VO 类型约束,不允许包含函数属性
59
+ * @param vos 值对象注册配置项
60
+ * @example
61
+ * ```typescript
62
+ * domain.registerVO({
63
+ * token: 'VO1',
64
+ * factoryType: 'cache',
65
+ * resolveFactory: () => ({ date: '2023-01-01' })
66
+ * })
67
+ * ```
68
+ */
69
+ registerVO<V extends VO<any>>(vos: TRegisterVoOption<V>): void;
70
+ /**
71
+ * @description 从依赖注入容器中获取领域服务实例对象
72
+ * @param token 领域服务token
73
+ * @returns 领域服务实例对象
74
+ */
75
+ services<S extends DomainService = DomainService>(token: TCustomInjectionToken): S | undefined;
76
+ /**
77
+ * @description 从依赖注入容器中获取领域实体实例对象
78
+ * @param sourceToken 源领域实体token,存在适配器时是 DEF 泛型类型,否则为 DE 泛型类型
79
+ * @param adapter 领域实体适配器,将 DEF 类型转换为 DE 类型
80
+ * @returns 领域实体实例对象
81
+ */
82
+ entities<DE extends DomainEntity = DomainEntity, DEF extends DomainEntity = DE>(sourceToken: TCustomInjectionToken, adapter?: Adapter<DE, DEF>): DE | undefined;
83
+ /**
84
+ * @description 从依赖注入容器中获取领域值对象实例对象
85
+ * @param sourceToken 源领域值对象token,存在适配器时是 VF 泛型类型,否则为 V 泛型类型
86
+ * @param adapter 领域值对象适配器,将 VF 类型转换为 V 类型
87
+ * @returns 领域值对象实例对象
88
+ */
89
+ vos<V extends VO<any> = VO<any>, VF extends VO<any> = V>(sourceToken: TCustomInjectionToken, adapter?: Adapter<V, VF>): V | undefined;
90
+ /**
91
+ * 域基类构造函数
92
+ */
93
+ constructor();
94
+ }
95
+ export {};
@@ -0,0 +1,13 @@
1
+ import { BaseEvents } from '../base-class';
2
+ import { IAnyObject, TEventEmits } from '../type';
3
+ /**
4
+ * 领域实体基类
5
+ */
6
+ export declare class DomainEntity<E extends TEventEmits = IAnyObject> {
7
+ /** 事件句柄 */
8
+ e: BaseEvents<E> | undefined;
9
+ /**
10
+ * 域基类构造函数
11
+ */
12
+ constructor();
13
+ }
@@ -0,0 +1,13 @@
1
+ import { BaseEvents } from '../base-class';
2
+ import { IAnyObject, TEventEmits } from '../type';
3
+ /**
4
+ * 领域服务基类
5
+ */
6
+ export declare class DomainService<E extends TEventEmits = IAnyObject> {
7
+ /** 事件句柄 */
8
+ e: BaseEvents<E> | undefined;
9
+ /**
10
+ * 域基类构造函数
11
+ */
12
+ constructor();
13
+ }
@@ -0,0 +1,26 @@
1
+ import { Adapter } from './base-class';
2
+ import { Domain } from './domain/Domain';
3
+ import { IDomainRegisterOption, TCustomInjectionToken } from './type';
4
+ /**
5
+ * gdmb 对象类
6
+ */
7
+ export declare class GDMB {
8
+ /** 全局 DIC */
9
+ globalDIC: import('tsyringe').DependencyContainer;
10
+ /**
11
+ * 注册领域对象
12
+ */
13
+ registerDomain<D extends Domain>(domain: new (...args: any[]) => D, option?: IDomainRegisterOption<D>): void;
14
+ /**
15
+ * 获取领域对象
16
+ */
17
+ domains<D extends Domain>(token: TCustomInjectionToken): D;
18
+ /**
19
+ * 提供全局的转换方法
20
+ */
21
+ transform<T, TF>(source: TF, adapter: Adapter<T, TF>): T | undefined | null;
22
+ /**
23
+ * 提供全局的转换方法,支持批量转换
24
+ */
25
+ transformAll<T, TF>(source: TF[], adapter: Adapter<T, TF>): T[];
26
+ }
@@ -0,0 +1,8 @@
1
+ import { Adapter } from './base-class';
2
+ import { TEventEmits, VO, IDomainRegisterOption, IRegisterServiceOption, IRegisterEntityOption } from './type';
3
+ export * from './domain/Domain';
4
+ export * from './domain/DomainService';
5
+ export * from './domain/DomainEntity';
6
+ export * from './index';
7
+ export { Adapter };
8
+ export type { TEventEmits, VO, IDomainRegisterOption, IRegisterServiceOption, IRegisterEntityOption };
@@ -0,0 +1,111 @@
1
+ import { DependencyContainer, InjectionToken } from 'tsyringe';
2
+ import { Domain } from './domain/Domain';
3
+ import { DomainService } from './domain/DomainService';
4
+ import { DomainEntity } from './domain/DomainEntity';
5
+ import { constructor } from 'tsyringe/dist/typings/types';
6
+ /** 任意扁平对象 */
7
+ export interface IAnyObject<D = any> {
8
+ [k: string | symbol]: D;
9
+ }
10
+ /**
11
+ * 事件注册对象类型
12
+ */
13
+ export type TEventEmits = IAnyObject<any[]>;
14
+ /** 自定义注入令牌类型 */
15
+ export type TCustomInjectionToken<T = any> = string | constructor<T>;
16
+ /**
17
+ * 服务注册配置项目接口
18
+ */
19
+ export interface IRegisterServiceOption<S extends DomainService> {
20
+ /** before 拦截器函数 */
21
+ beforeResolution?: (token: InjectionToken, resolutionType: string) => void;
22
+ /** before 拦截器触发评率 */
23
+ beforeResolutionFrequency?: 'Always' | 'Once';
24
+ /** after 拦截器函数 */
25
+ afterResolution?: (token: InjectionToken, result: S | S[], resolutionType: string) => void;
26
+ /** after 拦截器触发评率 */
27
+ afterResolutionFrequency?: 'Always' | 'Once';
28
+ }
29
+ /**
30
+ * 领域对象注册配置接口
31
+ */
32
+ export interface IDomainRegisterOption<D extends Domain> {
33
+ /** 注册参数,将带回领域对象类构造函数 */
34
+ args?: any[];
35
+ /** token 为领域名称的 before resolve拦截函数 */
36
+ beforeResolution?: (token: InjectionToken, resolutionType: string) => void;
37
+ /** token 为领域名称的 before resolve配置对象 */
38
+ beforeResolutionFrequency?: 'Always' | 'Once';
39
+ /** token 为领域名称的 after resolve拦截函数 */
40
+ afterResolution?: (token: InjectionToken, result: D | D[], resolutionType: string) => void;
41
+ /** token 为领域名称的 after resolve配置对象 */
42
+ afterResolutionFrequency?: 'Always' | 'Once';
43
+ }
44
+ /**
45
+ * 实体注册配置接口
46
+ */
47
+ export interface IRegisterEntityOption<E extends DomainEntity> {
48
+ /** 缓存策略 */
49
+ cachePolicy?: 'cache' | 'containerCache' | 'resolution';
50
+ /** before 拦截器函数 */
51
+ beforeResolution?: (token: InjectionToken, resolutionType: string) => void;
52
+ /** after 拦截器函数 */
53
+ afterResolution?: (token: InjectionToken, result: E | E[], resolutionType: string) => void;
54
+ }
55
+ /** 值对象注册配置类型 - 全局缓存缓存 */
56
+ export interface IRegisterVoOptionCache<V extends VO<any> = any> {
57
+ token: TCustomInjectionToken | TCustomInjectionToken[];
58
+ factoryType: 'cache';
59
+ /** 工厂函数 */
60
+ resolveFactory: VOFactory<V>;
61
+ }
62
+ /** 值对象注册配置类型 - 容器缓存缓存 */
63
+ export interface IRegisterVoOptionContainerCache<V extends VO<any> = any> {
64
+ token: TCustomInjectionToken | TCustomInjectionToken[];
65
+ factoryType: 'containerCache';
66
+ /** 工厂函数 */
67
+ resolveFactory: VOFactory<V>;
68
+ }
69
+ /** 值对象注册配置类型 - 条件resolve */
70
+ export interface IRegisterVoOptionPredicate<V extends VO<any> = any> {
71
+ token: TCustomInjectionToken | TCustomInjectionToken[];
72
+ factoryType: 'predicate';
73
+ /** 正值目标 */
74
+ positiveTarget: new (...args: any[]) => V;
75
+ /** 负值目标 */
76
+ negativeTarget: new (...args: any[]) => V;
77
+ /** 工厂函数 */
78
+ resolveFactory: VOConditionFactory<V>;
79
+ }
80
+ /** 值对象注册配置类型 - 无缓存 */
81
+ export interface IRegisterVoOptionNoCache<V extends VO<any> = any> {
82
+ token: TCustomInjectionToken | TCustomInjectionToken[];
83
+ factoryType: 'noCache';
84
+ /** 工厂函数 */
85
+ resolveFactory: VOFactory<V>;
86
+ }
87
+ type NonFunction<T> = T extends (...args: any[]) => any ? never : T;
88
+ /**
89
+ * 值对象类型约束
90
+ * @example
91
+ * ```ts
92
+ * interface TVODateTime {
93
+ * date: string;
94
+ * }
95
+ * const vo: VO<TVODateTime> = {
96
+ * date: '2023-01-01',
97
+ * };
98
+ * ```
99
+ */
100
+ export type VO<T extends IAnyObject<NonFunction<any>>> = {
101
+ [K in keyof T]: NonFunction<T[K]>;
102
+ };
103
+ /**
104
+ * 直接值对象工厂类型约束
105
+ */
106
+ export type VOFactory<T extends VO<any>> = (c?: DependencyContainer) => VO<T>;
107
+ /**
108
+ * 条件值对象工厂类型约束
109
+ */
110
+ export type VOConditionFactory<T extends VO<any>> = (c?: DependencyContainer, positiveTarget?: new (...args: any[]) => T, negativeTarget?: new (...args: any[]) => T) => boolean;
111
+ export {};
@@ -0,0 +1,6 @@
1
+ /**
2
+ * 判断一个数组是否是二维数组
3
+ * @param arr 要检查的数组
4
+ * @returns 是否为二维数组
5
+ */
6
+ export declare const is2DArray: (arr?: Array<any>) => arr is any[][];
package/package.json ADDED
@@ -0,0 +1,36 @@
1
+ {
2
+ "name": "gdmb",
3
+ "version": "1.0.0",
4
+ "type": "module",
5
+ "main": "dist/gdmb.umd.js",
6
+ "module": "dist/gdmb.es.js",
7
+ "types": "dist/src/main.d.ts",
8
+ "files": [
9
+ "dist"
10
+ ],
11
+ "scripts": {
12
+ "build": "tsc -b && vite build -c vitest.config.ts",
13
+ "build:watch": "tsc -b && vite build --watch -c vitest.config.ts",
14
+ "test": "vitest",
15
+ "test:coverage": "vitest --coverage"
16
+ },
17
+ "keywords": [],
18
+ "author": "yzh",
19
+ "license": "MIT",
20
+ "description": "",
21
+ "devDependencies": {
22
+ "@types/node": "^24.2.1",
23
+ "eslint": "^9.33.0",
24
+ "eslint-plugin-prettier": "^5.5.4",
25
+ "globals": "^16.3.0",
26
+ "typescript": "^5.9.2",
27
+ "typescript-eslint": "^8.39.1",
28
+ "vite": "^7.1.2",
29
+ "vite-plugin-dts": "^4.5.4",
30
+ "vitest": "^3.2.4"
31
+ },
32
+ "dependencies": {
33
+ "reflect-metadata": "^0.2.2",
34
+ "tsyringe": "^4.10.0"
35
+ }
36
+ }