gdmb 1.0.0 → 1.2.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/dist/gdmb.es.js CHANGED
@@ -1,5 +1,5 @@
1
- import { container as l, Lifecycle as a, predicateAwareClassFactory as h, instancePerContainerCachingFactory as g, instanceCachingFactory as d } from "tsyringe";
2
- class R {
1
+ import { container as l, Lifecycle as a, predicateAwareClassFactory as f, instancePerContainerCachingFactory as d, instanceCachingFactory as g } from "tsyringe";
2
+ class m {
3
3
  /**
4
4
  * 事件容器
5
5
  */
@@ -8,14 +8,14 @@ class R {
8
8
  * 为使用模块注册事件容器
9
9
  * @param eventName 事件模块名称
10
10
  */
11
- register(s) {
12
- s in this._mapper || (this._mapper[s] = []);
11
+ register(e) {
12
+ e in this._mapper || (this._mapper[e] = []);
13
13
  }
14
14
  /**
15
15
  * 删除事件模块
16
16
  */
17
- remove(s) {
18
- s in this._mapper && delete this._mapper[s];
17
+ remove(e) {
18
+ e in this._mapper && delete this._mapper[e];
19
19
  }
20
20
  /**
21
21
  * 事件监听注册
@@ -23,20 +23,20 @@ class R {
23
23
  * @param handler 处理器
24
24
  * @returns 监听句柄
25
25
  */
26
- on(s, r) {
27
- const t = this._mapper[s];
28
- t ? t.push(r) : (this.register(s), this.on(s, r));
26
+ on(e, s) {
27
+ const r = this._mapper[e];
28
+ r ? r.push(s) : (this.register(e), this.on(e, s));
29
29
  }
30
30
  /**
31
31
  * 移出指定监听函数监听
32
32
  * @param eventName 事件名称
33
33
  * @param handler 监听函数
34
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);
35
+ off(e, s) {
36
+ const r = this._mapper[e];
37
+ if (r) {
38
+ const i = r.indexOf(s);
39
+ i !== -1 && r.splice(i, 1);
40
40
  }
41
41
  }
42
42
  /**
@@ -44,11 +44,11 @@ class R {
44
44
  * @param eventName 事件名称
45
45
  * @param args 时间回调参数
46
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);
47
+ trigger(e, ...s) {
48
+ const r = this._mapper[e];
49
+ r && setTimeout(() => {
50
+ for (const i of Object.values(r))
51
+ i(...s);
52
52
  }, 0);
53
53
  }
54
54
  /**
@@ -57,9 +57,9 @@ class R {
57
57
  constructor() {
58
58
  }
59
59
  }
60
- class v {
61
- }
62
60
  class _ {
61
+ }
62
+ class w {
63
63
  /**
64
64
  * @summary 领域内部依赖注入容器
65
65
  * @description 领域内部依赖注入容器,用于注册和解析领域服务、实体、值对象等。
@@ -68,7 +68,7 @@ class _ {
68
68
  /**
69
69
  * @description 领域事件句柄,用于触发、监听、取消监听领域事件
70
70
  */
71
- e = new R();
71
+ e = new m();
72
72
  /**
73
73
  * @description 向领域依赖注入容器中注册一个或多个领域服务
74
74
  * @param service 单个领域服务类或数组
@@ -76,31 +76,37 @@ class _ {
76
76
  * @example
77
77
  * ```typescript
78
78
  * class ServiceOne extends DomainService {
79
+ *
80
+ * // before resolve 拦截器
81
+ * public static beforeResolution(token: InjectionToken, resolutionType: string) {}
82
+ *
83
+ * // after resolve 拦截器
84
+ * public static afterResolution(token: InjectionToken, result: ServiceOne | ServiceOne[], resolutionType: string) {}
85
+ *
79
86
  * constructor(public arg: string, public arg2: number) {
80
87
  * super();
81
88
  * }
82
89
  * }
83
90
  *
84
- * domain.registerService(ServiceOne, { args: ['hello', 3] })
85
- * // 多个服务时,配置条目允许 undefined null,此时配置会被忽略
86
- * domain.registerService([ServiceOne, ServiceTwo], [{ args: ['hello', 3] }, null])
91
+ * // 注册领域服务
92
+ * domain.registerService(ServiceOne, { beforeResolution: ServiceOne.beforeResolution, afterResolution: ServiceOne.afterResolution })
87
93
  * ```
88
94
  */
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
+ registerService(e, s) {
96
+ const r = Array.isArray(e) ? e : [e], i = s ? Array.isArray(s) ? s : [s] : [];
97
+ for (let n = 0; n < r.length; n += 1) {
98
+ const t = r[n], c = i[n];
99
+ if (this.dic.isRegistered(t.name) || this.dic.isRegistered(t)) {
100
+ console.warn(`服务 ${t.name} 已注册,跳过注册`);
95
101
  continue;
96
102
  }
97
- this.dic.register(e.name, { useClass: e }), this.dic.register(e, { useClass: e }), c?.beforeResolution && (this.dic.beforeResolution(e.name, c.beforeResolution, {
103
+ this.dic.register(t.name, { useClass: t }), this.dic.register(t, { useClass: t }), c?.beforeResolution && (this.dic.beforeResolution(t.name, c.beforeResolution, {
98
104
  frequency: c?.beforeResolutionFrequency || "Always"
99
- }), this.dic.beforeResolution(e, c.beforeResolution, {
105
+ }), this.dic.beforeResolution(t, c.beforeResolution, {
100
106
  frequency: c?.beforeResolutionFrequency || "Always"
101
- })), c?.afterResolution && (this.dic.afterResolution(e.name, c.afterResolution, {
107
+ })), c?.afterResolution && (this.dic.afterResolution(t.name, c.afterResolution, {
102
108
  frequency: c?.afterResolutionFrequency || "Always"
103
- }), this.dic.afterResolution(e, c?.afterResolution, {
109
+ }), this.dic.afterResolution(t, c?.afterResolution, {
104
110
  frequency: c?.afterResolutionFrequency || "Always"
105
111
  }));
106
112
  }
@@ -112,45 +118,51 @@ class _ {
112
118
  * @example
113
119
  * ```typescript
114
120
  * class EntityOne extends DomainEntity {
121
+ *
122
+ * // before resolve 拦截器
123
+ * public static beforeResolution(token: InjectionToken, resolutionType: string) {}
124
+ *
125
+ * // after resolve 拦截器
126
+ * public static afterResolution(token: InjectionToken, result: EntityOne | EntityOne[], resolutionType: string) {}
127
+ *
115
128
  * constructor(public arg: string, public arg2: number) {
116
129
  * super();
117
130
  * }
118
131
  * }
119
132
  *
120
- * domain.registerEntity(EntityOne, { args: ['hello', 3] })
121
- * // 多个实体时,配置条目允许 undefined null,此时配置会被忽略
122
- * domain.registerEntity([EntityOne, EntityTwo], [{ args: ['hello', 3] }, null])
133
+ * // 注册领域实体
134
+ * domain.registerEntity(EntityOne, { cachePolicy: 'cache', beforeResolution: EntityOne.beforeResolution, afterResolution: EntityOne.afterResolution })
123
135
  * ```
124
136
  */
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} 已注册,跳过注册`);
137
+ registerEntity(e, s) {
138
+ const r = Array.isArray(e) ? e : [e], i = s ? Array.isArray(s) ? s : [s] : [];
139
+ for (let n = 0; n < r.length; n += 1) {
140
+ const t = r[n], c = i[n];
141
+ if (this.dic.isRegistered(t.name) || this.dic.isRegistered(t)) {
142
+ console.warn(`实体 ${t.name} 已注册,跳过注册`);
131
143
  continue;
132
144
  }
133
145
  if (c?.cachePolicy)
134
146
  switch (c.cachePolicy) {
135
147
  case "cache":
136
- l.register(e.name, { useClass: e }, { lifecycle: a.Singleton }), l.register(e, { useClass: e }, { lifecycle: a.Singleton });
148
+ l.register(t.name, { useClass: t }, { lifecycle: a.Singleton }), l.register(t, { useClass: t }, { lifecycle: a.Singleton });
137
149
  break;
138
150
  case "containerCache":
139
- this.dic.register(e.name, { useClass: e }, { lifecycle: a.ContainerScoped }), this.dic.register(e, { useClass: e }, { lifecycle: a.ContainerScoped });
151
+ this.dic.register(t.name, { useClass: t }, { lifecycle: a.ContainerScoped }), this.dic.register(t, { useClass: t }, { lifecycle: a.ContainerScoped });
140
152
  break;
141
153
  case "resolution":
142
- this.dic.register(e.name, { useClass: e }, { lifecycle: a.ResolutionScoped }), this.dic.register(e, { useClass: e }, { lifecycle: a.ResolutionScoped });
154
+ this.dic.register(t.name, { useClass: t }, { lifecycle: a.ResolutionScoped }), this.dic.register(t, { useClass: t }, { lifecycle: a.ResolutionScoped });
143
155
  break;
144
156
  }
145
157
  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, {
158
+ this.dic.register(t.name, { useClass: t }, { lifecycle: a.Transient }), this.dic.register(t, { useClass: t }, { lifecycle: a.Transient });
159
+ c?.beforeResolution && (this.dic.beforeResolution(t.name, c.beforeResolution, {
148
160
  frequency: "Always"
149
- }), this.dic.beforeResolution(e, c.beforeResolution, {
161
+ }), this.dic.beforeResolution(t, c.beforeResolution, {
150
162
  frequency: "Always"
151
- })), c?.afterResolution && (this.dic.afterResolution(e.name, c.afterResolution, {
163
+ })), c?.afterResolution && (this.dic.afterResolution(t.name, c.afterResolution, {
152
164
  frequency: "Always"
153
- }), this.dic.afterResolution(e, c.afterResolution, {
165
+ }), this.dic.afterResolution(t, c.afterResolution, {
154
166
  frequency: "Always"
155
167
  }));
156
168
  }
@@ -168,22 +180,22 @@ class _ {
168
180
  * })
169
181
  * ```
170
182
  */
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];
183
+ registerVO(e) {
184
+ const s = Array.isArray(e) ? e : [e];
185
+ for (let r = 0; r < s.length; r += 1) {
186
+ const i = s[r], n = Array.isArray(i.token) ? i.token : [i.token];
187
+ for (let t = 0; t < n.length; t += 1) {
188
+ const c = n[t];
177
189
  switch (i.factoryType) {
178
190
  case "cache":
179
- l.register(c, { useFactory: d(i.resolveFactory) });
191
+ l.register(c, { useFactory: g(i.resolveFactory) });
180
192
  break;
181
193
  case "containerCache":
182
- this.dic.register(c, { useFactory: g(i.resolveFactory) });
194
+ this.dic.register(c, { useFactory: d(i.resolveFactory) });
183
195
  break;
184
196
  case "predicate":
185
197
  this.dic.register(c, {
186
- useFactory: h(
198
+ useFactory: f(
187
199
  i.resolveFactory,
188
200
  i.positiveTarget,
189
201
  i.negativeTarget
@@ -202,9 +214,9 @@ class _ {
202
214
  * @param token 领域服务token
203
215
  * @returns 领域服务实例对象
204
216
  */
205
- services(s) {
206
- const r = this.dic.resolve(s);
207
- return r && !r?.e && (r.e = this.e), r;
217
+ services(e) {
218
+ const s = this.dic.resolve(e);
219
+ return s && !s?.e && (s.e = this.e), s;
208
220
  }
209
221
  /**
210
222
  * @description 从依赖注入容器中获取领域实体实例对象
@@ -212,14 +224,14 @@ class _ {
212
224
  * @param adapter 领域实体适配器,将 DEF 类型转换为 DE 类型
213
225
  * @returns 领域实体实例对象
214
226
  */
215
- entities(s, r) {
216
- let t;
217
- if (r) {
218
- const i = this.dic.resolve(s);
219
- t = r.transform(i);
227
+ entities(e, s) {
228
+ let r;
229
+ if (s) {
230
+ const i = this.dic.resolve(e);
231
+ r = s.transform(i);
220
232
  } else
221
- t = this.dic.resolve(s);
222
- return t && !t?.e && (t.e = this.e), t;
233
+ r = this.dic.resolve(e);
234
+ return r && !r?.e && (r.e = this.e), r;
223
235
  }
224
236
  /**
225
237
  * @description 从依赖注入容器中获取领域值对象实例对象
@@ -227,12 +239,12 @@ class _ {
227
239
  * @param adapter 领域值对象适配器,将 VF 类型转换为 V 类型
228
240
  * @returns 领域值对象实例对象
229
241
  */
230
- vos(s, r) {
231
- if (r) {
232
- const t = this.dic.resolve(s);
233
- return r.transform(t);
242
+ vos(e, s) {
243
+ if (s) {
244
+ const r = this.dic.resolve(e);
245
+ return s.transform(r);
234
246
  } else
235
- return this.dic.resolve(s);
247
+ return this.dic.resolve(e);
236
248
  }
237
249
  /**
238
250
  * 域基类构造函数
@@ -240,14 +252,14 @@ class _ {
240
252
  constructor() {
241
253
  }
242
254
  }
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;
255
+ const y = (o) => (o.prototype.$ins = null, class extends o {
256
+ constructor(...e) {
257
+ return super(...e), o.prototype.$ins || (o.prototype.$ins = this), o.prototype.$ins;
246
258
  }
247
259
  });
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);
260
+ var p = Object.getOwnPropertyDescriptor, v = (o, e, s, r) => {
261
+ for (var i = r > 1 ? void 0 : r ? p(e, s) : e, n = o.length - 1, t; n >= 0; n--)
262
+ (t = o[n]) && (i = t(i) || i);
251
263
  return i;
252
264
  };
253
265
  let u = class {
@@ -259,10 +271,10 @@ let u = class {
259
271
  constructor() {
260
272
  }
261
273
  };
262
- u = m([
274
+ u = v([
263
275
  y
264
276
  ], u);
265
- class w {
277
+ class F {
266
278
  /** 事件句柄 */
267
279
  e = void 0;
268
280
  /**
@@ -271,68 +283,319 @@ class w {
271
283
  constructor() {
272
284
  }
273
285
  }
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);
286
+ class R {
287
+ /**
288
+ * 命令历史记录
289
+ */
290
+ history = [];
291
+ /**
292
+ * 撤销历史记录
293
+ */
294
+ undoHistory = [];
295
+ /**
296
+ * 命令历史最大深度
297
+ */
298
+ maxHistoryDepth;
299
+ /**
300
+ * 撤销历史最大深度
301
+ */
302
+ maxUndoHistoryDepth;
303
+ /**
304
+ * 执行命令
305
+ * @param command 要执行的命令
306
+ */
307
+ execute(e) {
308
+ e.execute(), this.history.push({
309
+ command: e,
310
+ timestamp: Date.now()
311
+ }), this.undoHistory = [], this.history.length > this.maxHistoryDepth && this.history.shift();
312
+ }
313
+ /**
314
+ * 撤销上一个命令
315
+ * @returns 是否成功撤销
316
+ */
317
+ undo() {
318
+ if (this.history.length === 0)
319
+ return !1;
320
+ const e = this.history.pop();
321
+ return e ? (e.command.undo(), this.undoHistory.push(e), this.undoHistory.length > this.maxUndoHistoryDepth && this.undoHistory.shift(), !0) : !1;
322
+ }
323
+ /**
324
+ * 重做上一个撤销的命令
325
+ * @returns 是否成功重做
326
+ */
327
+ redo() {
328
+ if (this.undoHistory.length === 0)
329
+ return !1;
330
+ const e = this.undoHistory.pop();
331
+ return e ? (e.command.execute(), this.history.push(e), this.history.length > this.maxHistoryDepth && this.history.shift(), !0) : !1;
332
+ }
333
+ /**
334
+ * 批量执行命令
335
+ * @param commands 要执行的命令数组
336
+ */
337
+ executeBatch(e) {
338
+ e.forEach((s) => this.execute(s));
339
+ }
340
+ /**
341
+ * 清空命令历史
342
+ */
343
+ clearHistory() {
344
+ this.history = [], this.undoHistory = [];
345
+ }
346
+ /**
347
+ * 获取命令历史记录
348
+ * @returns 命令历史记录数组
349
+ */
350
+ getHistory() {
351
+ return [...this.history];
352
+ }
353
+ /**
354
+ * 获取撤销历史记录
355
+ * @returns 撤销历史记录数组
356
+ */
357
+ getUndoHistory() {
358
+ return [...this.undoHistory];
359
+ }
360
+ /**
361
+ * 获取历史记录数量
362
+ * @returns 历史记录数量
363
+ */
364
+ getHistoryCount() {
365
+ return this.history.length;
366
+ }
367
+ /**
368
+ * 获取撤销历史记录数量
369
+ * @returns 撤销历史记录数量
370
+ */
371
+ getUndoHistoryCount() {
372
+ return this.undoHistory.length;
373
+ }
374
+ /**
375
+ * 构造函数
376
+ * @param option 命令调用者构造配置参数
377
+ */
378
+ constructor(e) {
379
+ this.maxHistoryDepth = e?.maxHistoryDepth || 1 / 0, this.maxUndoHistoryDepth = e?.maxUndoHistoryDepth || 1 / 0;
380
+ }
381
+ }
382
+ class C {
383
+ /**
384
+ * 命令接收者
385
+ */
386
+ receiver;
387
+ /**
388
+ * 执行操作的函数
389
+ */
390
+ executeFn;
391
+ /**
392
+ * 撤销操作的函数
393
+ */
394
+ undoFn;
395
+ /**
396
+ * 命令描述
397
+ */
398
+ description;
399
+ /**
400
+ * 构造函数
401
+ * @param receiver 命令接收者
402
+ * @param executeFn 执行操作的函数
403
+ * @param undoFn 撤销操作的函数
404
+ * @param description 命令描述
405
+ */
406
+ constructor(e, s, r, i) {
407
+ this.receiver = e, this.executeFn = s, this.undoFn = r, this.description = i;
408
+ }
409
+ /**
410
+ * 执行命令
411
+ */
412
+ execute() {
413
+ this.executeFn(this.receiver);
414
+ }
415
+ /**
416
+ * 撤销命令
417
+ */
418
+ undo() {
419
+ this.undoFn(this.receiver);
420
+ }
421
+ /**
422
+ * 获取命令描述
423
+ * @returns 命令描述
424
+ */
425
+ getDescription() {
426
+ return this.description;
427
+ }
428
+ }
429
+ function H(o, e, s, r) {
430
+ return new C(o, e, s, r);
431
+ }
432
+ class D {
433
+ /**
434
+ * 命令调用者
435
+ */
436
+ invoker;
437
+ /**
438
+ * 创建命令
439
+ * @param receiver 命令接收者
440
+ * @param executeFn 执行操作的函数
441
+ * @param undoFn 撤销操作的函数
442
+ * @param description 命令描述
443
+ * @returns 命令对象
444
+ */
445
+ create(e, s, r, i) {
446
+ return H(e, s, r, i);
447
+ }
448
+ /**
449
+ * 执行命令
450
+ * @param command 要执行的命令
451
+ */
452
+ execute(e) {
453
+ this.invoker.execute(e);
454
+ }
455
+ /**
456
+ * 撤销上一个命令
457
+ * @returns 是否成功撤销
458
+ */
459
+ undo() {
460
+ return this.invoker.undo();
461
+ }
462
+ /**
463
+ * 重做上一个撤销的命令
464
+ * @returns 是否成功重做
465
+ */
466
+ redo() {
467
+ return this.invoker.redo();
468
+ }
469
+ /**
470
+ * 批量执行命令
471
+ * @param commands 要执行的命令数组
472
+ */
473
+ executeBatch(e) {
474
+ this.invoker.executeBatch(e);
475
+ }
476
+ /**
477
+ * 清空命令历史
478
+ */
479
+ clearHistory() {
480
+ this.invoker.clearHistory();
481
+ }
482
+ /**
483
+ * 获取命令历史记录
484
+ * @returns 命令历史记录数组
485
+ */
486
+ getHistory() {
487
+ return this.invoker.getHistory();
488
+ }
489
+ /**
490
+ * 获取撤销历史记录
491
+ * @returns 撤销历史记录数组
492
+ */
493
+ getUndoHistory() {
494
+ return this.invoker.getUndoHistory();
495
+ }
496
+ /**
497
+ * 获取历史记录数量
498
+ * @returns 历史记录数量
499
+ */
500
+ getHistoryCount() {
501
+ return this.invoker.getHistoryCount();
502
+ }
503
+ /**
504
+ * 获取撤销历史记录数量
505
+ * @returns 撤销历史记录数量
506
+ */
507
+ getUndoHistoryCount() {
508
+ return this.invoker.getUndoHistoryCount();
509
+ }
510
+ /**
511
+ * 构造函数
512
+ * @param option 配置参数
513
+ */
514
+ constructor(e) {
515
+ this.invoker = new R({
516
+ maxHistoryDepth: e?.maxHistoryDepth,
517
+ maxUndoHistoryDepth: e?.maxUndoHistoryDepth
518
+ });
519
+ }
520
+ }
521
+ var b = Object.getOwnPropertyDescriptor, x = (o, e, s, r) => {
522
+ for (var i = r > 1 ? void 0 : r ? b(e, s) : e, n = o.length - 1, t; n >= 0; n--)
523
+ (t = o[n]) && (i = t(i) || i);
277
524
  return i;
278
525
  };
279
- let f = class {
526
+ let h = class {
280
527
  /** 全局 DIC */
281
528
  globalDIC = l;
529
+ /** 命令系统 */
530
+ c;
282
531
  /**
283
532
  * 注册领域对象
284
533
  */
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} 已注册,无法重复注册`);
534
+ registerDomain(o, e) {
535
+ const s = Array.isArray(o) ? o : [o], r = e ? Array.isArray(e) ? e : [e] : [];
536
+ for (let i = 0; i < s.length; i += 1) {
537
+ const n = s[i], t = r[i];
538
+ if (this.globalDIC.isRegistered(n.name)) {
539
+ console.warn(`领域 ${n.name} 已注册,无法重复注册`);
291
540
  return;
292
541
  }
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"
542
+ const c = new n(...t?.args || []);
543
+ this.globalDIC.register(n.name, { useValue: c }), this.globalDIC.register(n, { useValue: c }), t?.beforeResolution && (this.globalDIC.beforeResolution(n.name, t.beforeResolution, {
544
+ frequency: t.beforeResolutionFrequency || "Always"
545
+ }), this.globalDIC.beforeResolution(n, t.beforeResolution, {
546
+ frequency: t.afterResolutionFrequency || "Always"
547
+ })), t?.afterResolution && (this.globalDIC.afterResolution(n.name, t.afterResolution, {
548
+ frequency: t.afterResolutionFrequency || "Always"
549
+ }), this.globalDIC.afterResolution(n, t.afterResolution, {
550
+ frequency: t.afterResolutionFrequency || "Always"
302
551
  }));
303
552
  }
304
553
  }
305
554
  /**
306
555
  * 获取领域对象
307
556
  */
308
- domains(n) {
309
- return this.globalDIC.resolve(n);
557
+ domains(o) {
558
+ return this.globalDIC.resolve(o);
310
559
  }
311
560
  /**
312
561
  * 提供全局的转换方法
313
562
  */
314
- transform(n, s) {
315
- return s.transform(n);
563
+ transform(o, e) {
564
+ return e.transform(o);
316
565
  }
317
566
  /**
318
567
  * 提供全局的转换方法,支持批量转换
319
568
  */
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);
569
+ transformAll(o, e) {
570
+ const s = [];
571
+ for (let r = 0; r < o.length; r += 1) {
572
+ const i = e.transform(o[r]);
573
+ i != null && s.push(i);
325
574
  }
326
- return r;
575
+ return s;
576
+ }
577
+ /**
578
+ * 构造函数
579
+ * @param option 配置参数
580
+ */
581
+ constructor(o) {
582
+ this.c = new D({
583
+ maxHistoryDepth: o?.maxHistoryDepth,
584
+ maxUndoHistoryDepth: o?.maxUndoHistoryDepth
585
+ });
327
586
  }
328
587
  };
329
- f = A([
588
+ h = x([
330
589
  y
331
- ], f);
590
+ ], h);
332
591
  export {
333
- v as Adapter,
334
- _ as Domain,
335
- w as DomainEntity,
592
+ _ as Adapter,
593
+ R as CommandInvoker,
594
+ D as CommandSystem,
595
+ C as ConcreteCommand,
596
+ w as Domain,
597
+ F as DomainEntity,
336
598
  u as DomainService,
337
- f as GDMB
599
+ h as GDMB,
600
+ H as createCommand
338
601
  };
package/dist/gdmb.umd.js CHANGED
@@ -1 +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"})}));
1
+ (function(l,a){typeof exports=="object"&&typeof module<"u"?a(exports,require("tsyringe")):typeof define=="function"&&define.amd?define(["exports","tsyringe"],a):(l=typeof globalThis<"u"?globalThis:l||self,a(l.gdmb={},l.tsyringe))})(this,(function(l,a){"use strict";class g{_mapper={};register(e){e in this._mapper||(this._mapper[e]=[])}remove(e){e in this._mapper&&delete this._mapper[e]}on(e,s){const i=this._mapper[e];i?i.push(s):(this.register(e),this.on(e,s))}off(e,s){const i=this._mapper[e];if(i){const r=i.indexOf(s);r!==-1&&i.splice(r,1)}}trigger(e,...s){const i=this._mapper[e];i&&setTimeout(()=>{for(const r of Object.values(i))r(...s)},0)}constructor(){}}class p{}class v{dic=a.container.createChildContainer();e=new g;registerService(e,s){const i=Array.isArray(e)?e:[e],r=s?Array.isArray(s)?s:[s]:[];for(let n=0;n<i.length;n+=1){const t=i[n],o=r[n];if(this.dic.isRegistered(t.name)||this.dic.isRegistered(t)){console.warn(`服务 ${t.name} 已注册,跳过注册`);continue}this.dic.register(t.name,{useClass:t}),this.dic.register(t,{useClass:t}),o?.beforeResolution&&(this.dic.beforeResolution(t.name,o.beforeResolution,{frequency:o?.beforeResolutionFrequency||"Always"}),this.dic.beforeResolution(t,o.beforeResolution,{frequency:o?.beforeResolutionFrequency||"Always"})),o?.afterResolution&&(this.dic.afterResolution(t.name,o.afterResolution,{frequency:o?.afterResolutionFrequency||"Always"}),this.dic.afterResolution(t,o?.afterResolution,{frequency:o?.afterResolutionFrequency||"Always"}))}}registerEntity(e,s){const i=Array.isArray(e)?e:[e],r=s?Array.isArray(s)?s:[s]:[];for(let n=0;n<i.length;n+=1){const t=i[n],o=r[n];if(this.dic.isRegistered(t.name)||this.dic.isRegistered(t)){console.warn(`实体 ${t.name} 已注册,跳过注册`);continue}if(o?.cachePolicy)switch(o.cachePolicy){case"cache":a.container.register(t.name,{useClass:t},{lifecycle:a.Lifecycle.Singleton}),a.container.register(t,{useClass:t},{lifecycle:a.Lifecycle.Singleton});break;case"containerCache":this.dic.register(t.name,{useClass:t},{lifecycle:a.Lifecycle.ContainerScoped}),this.dic.register(t,{useClass:t},{lifecycle:a.Lifecycle.ContainerScoped});break;case"resolution":this.dic.register(t.name,{useClass:t},{lifecycle:a.Lifecycle.ResolutionScoped}),this.dic.register(t,{useClass:t},{lifecycle:a.Lifecycle.ResolutionScoped});break}else this.dic.register(t.name,{useClass:t},{lifecycle:a.Lifecycle.Transient}),this.dic.register(t,{useClass:t},{lifecycle:a.Lifecycle.Transient});o?.beforeResolution&&(this.dic.beforeResolution(t.name,o.beforeResolution,{frequency:"Always"}),this.dic.beforeResolution(t,o.beforeResolution,{frequency:"Always"})),o?.afterResolution&&(this.dic.afterResolution(t.name,o.afterResolution,{frequency:"Always"}),this.dic.afterResolution(t,o.afterResolution,{frequency:"Always"}))}}registerVO(e){const s=Array.isArray(e)?e:[e];for(let i=0;i<s.length;i+=1){const r=s[i],n=Array.isArray(r.token)?r.token:[r.token];for(let t=0;t<n.length;t+=1){const o=n[t];switch(r.factoryType){case"cache":a.container.register(o,{useFactory:a.instanceCachingFactory(r.resolveFactory)});break;case"containerCache":this.dic.register(o,{useFactory:a.instancePerContainerCachingFactory(r.resolveFactory)});break;case"predicate":this.dic.register(o,{useFactory:a.predicateAwareClassFactory(r.resolveFactory,r.positiveTarget,r.negativeTarget)});break;default:this.dic.register(o,{useFactory:r.resolveFactory});break}}}}services(e){const s=this.dic.resolve(e);return s&&!s?.e&&(s.e=this.e),s}entities(e,s){let i;if(s){const r=this.dic.resolve(e);i=s.transform(r)}else i=this.dic.resolve(e);return i&&!i?.e&&(i.e=this.e),i}vos(e,s){if(s){const i=this.dic.resolve(e);return s.transform(i)}else return this.dic.resolve(e)}constructor(){}}const u=c=>(c.prototype.$ins=null,class extends c{constructor(...e){return super(...e),c.prototype.$ins||(c.prototype.$ins=this),c.prototype.$ins}});var C=Object.getOwnPropertyDescriptor,D=(c,e,s,i)=>{for(var r=i>1?void 0:i?C(e,s):e,n=c.length-1,t;n>=0;n--)(t=c[n])&&(r=t(r)||r);return r};l.DomainService=class{e=void 0;constructor(){}},l.DomainService=D([u],l.DomainService);class R{e=void 0;constructor(){}}class h{history=[];undoHistory=[];maxHistoryDepth;maxUndoHistoryDepth;execute(e){e.execute(),this.history.push({command:e,timestamp:Date.now()}),this.undoHistory=[],this.history.length>this.maxHistoryDepth&&this.history.shift()}undo(){if(this.history.length===0)return!1;const e=this.history.pop();return e?(e.command.undo(),this.undoHistory.push(e),this.undoHistory.length>this.maxUndoHistoryDepth&&this.undoHistory.shift(),!0):!1}redo(){if(this.undoHistory.length===0)return!1;const e=this.undoHistory.pop();return e?(e.command.execute(),this.history.push(e),this.history.length>this.maxHistoryDepth&&this.history.shift(),!0):!1}executeBatch(e){e.forEach(s=>this.execute(s))}clearHistory(){this.history=[],this.undoHistory=[]}getHistory(){return[...this.history]}getUndoHistory(){return[...this.undoHistory]}getHistoryCount(){return this.history.length}getUndoHistoryCount(){return this.undoHistory.length}constructor(e){this.maxHistoryDepth=e?.maxHistoryDepth||1/0,this.maxUndoHistoryDepth=e?.maxUndoHistoryDepth||1/0}}class f{receiver;executeFn;undoFn;description;constructor(e,s,i,r){this.receiver=e,this.executeFn=s,this.undoFn=i,this.description=r}execute(){this.executeFn(this.receiver)}undo(){this.undoFn(this.receiver)}getDescription(){return this.description}}function y(c,e,s,i){return new f(c,e,s,i)}class d{invoker;create(e,s,i,r){return y(e,s,i,r)}execute(e){this.invoker.execute(e)}undo(){return this.invoker.undo()}redo(){return this.invoker.redo()}executeBatch(e){this.invoker.executeBatch(e)}clearHistory(){this.invoker.clearHistory()}getHistory(){return this.invoker.getHistory()}getUndoHistory(){return this.invoker.getUndoHistory()}getHistoryCount(){return this.invoker.getHistoryCount()}getUndoHistoryCount(){return this.invoker.getUndoHistoryCount()}constructor(e){this.invoker=new h({maxHistoryDepth:e?.maxHistoryDepth,maxUndoHistoryDepth:e?.maxUndoHistoryDepth})}}var H=Object.getOwnPropertyDescriptor,b=(c,e,s,i)=>{for(var r=i>1?void 0:i?H(e,s):e,n=c.length-1,t;n>=0;n--)(t=c[n])&&(r=t(r)||r);return r};l.GDMB=class{globalDIC=a.container;c;registerDomain(e,s){const i=Array.isArray(e)?e:[e],r=s?Array.isArray(s)?s:[s]:[];for(let n=0;n<i.length;n+=1){const t=i[n],o=r[n];if(this.globalDIC.isRegistered(t.name)){console.warn(`领域 ${t.name} 已注册,无法重复注册`);return}const m=new t(...o?.args||[]);this.globalDIC.register(t.name,{useValue:m}),this.globalDIC.register(t,{useValue:m}),o?.beforeResolution&&(this.globalDIC.beforeResolution(t.name,o.beforeResolution,{frequency:o.beforeResolutionFrequency||"Always"}),this.globalDIC.beforeResolution(t,o.beforeResolution,{frequency:o.afterResolutionFrequency||"Always"})),o?.afterResolution&&(this.globalDIC.afterResolution(t.name,o.afterResolution,{frequency:o.afterResolutionFrequency||"Always"}),this.globalDIC.afterResolution(t,o.afterResolution,{frequency:o.afterResolutionFrequency||"Always"}))}}domains(e){return this.globalDIC.resolve(e)}transform(e,s){return s.transform(e)}transformAll(e,s){const i=[];for(let r=0;r<e.length;r+=1){const n=s.transform(e[r]);n!=null&&i.push(n)}return i}constructor(e){this.c=new d({maxHistoryDepth:e?.maxHistoryDepth,maxUndoHistoryDepth:e?.maxUndoHistoryDepth})}},l.GDMB=b([u],l.GDMB),l.Adapter=p,l.CommandInvoker=h,l.CommandSystem=d,l.ConcreteCommand=f,l.Domain=v,l.DomainEntity=R,l.createCommand=y,Object.defineProperty(l,Symbol.toStringTag,{value:"Module"})}));
@@ -0,0 +1,218 @@
1
+ ---
2
+ name: gdmb
3
+ description: 领域驱动设计架构(DDD)专家,专注于处理领域模型相关的任务。可以积极解决领域对象、值对象、实体、聚合根、领域事件、领域服务等领域模型成员的定义、注册、维护、优化和复杂依赖注入的问题,以满足不同应用程序的需求。提供轻量级事件系统和命令系统,支持领域事件的发布和订阅,以及命令的创建和执行。
4
+ category: framework
5
+ ---
6
+
7
+ # 领域驱动设计专家(Domain Driven Design Expert)
8
+
9
+ 你是一个领域驱动设计(DDD)架构专家,对企业级应用程序的DDD架构有深入的理解和实践经验。你熟悉DDD的核心概念,如领域模型、聚合根、值对象、实体、领域事件、领域服务等,并能够根据业务需求设计和实现符合DDD原则的领域模型。
10
+
11
+ ## 当被调用时(When invoked):
12
+
13
+ 0. 如果有更专业的专家更适合,建议切换并停止:
14
+ - 纯 TypeScript 问题 → typescript-type-expert
15
+ - 数据库查询优化问题 → database-expert
16
+ - Node.js 运行时问题 → nodejs-expert
17
+ - 前端 React 问题 → react-expert
18
+ - 前端 Vue 问题 → vue-expert
19
+
20
+ Example: "这是一个 TypeScript 类型系统问题。请使用 typescript-type-expert 子代理,这里停止。"
21
+
22
+ 1. 识别项目的架构和现有领域模型组件(如聚合根、实体、值对象、领域事件、领域服务等)。
23
+ 3. 验证顺序: 类型 → 单元测试 → 集成测试 → 端到端测试
24
+
25
+ ## 领域模型通用模式与解决方案(Common Patterns & Solutions)
26
+
27
+ ### 领域对象创建与注册(Domain Object Creation & Registration)
28
+ ```typescript
29
+ import { gdmb, Domain } from 'gdmb';
30
+ // 领域对象类
31
+ class DomainObject extends Domain<DomainEvent> {}
32
+ // 领域对象注册
33
+ gdmb.registerDomain(DomainObject);
34
+ // 从全局对象获取领域对象实例,领域对象实例为全局单例
35
+ const domainObject = gdmb.domains<DomainObject>(DomainObject);
36
+ ```
37
+
38
+ ### 领域服务创建与注册(Domain Service Creation & Registration)
39
+ ```typescript
40
+ import { gdmb, DomainService } from 'gdmb';
41
+ import type { InjectionToken } from 'tsyringe';
42
+ // 领域服务类
43
+ class DomainServiceObject extends DomainService<DomainEvent> {
44
+ // 领域服务在解析前调用
45
+ public static beforeResolution(token: InjectionToken, resolutionType: string) {
46
+ // resolve 前拦截器这里处理
47
+ }
48
+ // 领域服务在解析后调用
49
+ public static afterResolution(token: InjectionToken, result: DomainServiceObject | DomainServiceObject[], resolutionType: string) {
50
+ // resovle 后拦截器这里处理
51
+ }
52
+ }
53
+ // 领域服务注册
54
+ domainObject.registerService(DomainServiceObject, {
55
+ // 领域服务在解析前调用
56
+ beforeResolution: DomainServiceObject.beforeResolution,
57
+ // 领域服务在解析前调用频率,可用值 'Always' | 'Once'
58
+ beforeResolutionFrequency: 'Once',
59
+ // 领域服务在解析后调用
60
+ afterResolution: DomainServiceObject.afterResolution,
61
+ // 领域服务在解析后调用频率,可用值 'Always' | 'Once'
62
+ afterResolutionFrequency: 'Always'
63
+ });
64
+ // 从全局对象获取领域服务实例
65
+ const domainService = domainObject.services<DomainService>(DomainService);
66
+ ```
67
+
68
+ ### 领域事件定义、触发与监听(Domain Event Definition & Trigger & Listen)
69
+ ```typescript
70
+ import { gdmb, Domain } from 'gdmb';
71
+ // 定义领域事件
72
+ type DomainEvent = {
73
+ /** 事件名称 + 处理函数注入参数数组 */
74
+ eventName: [arg: number, arg2: string]
75
+ }
76
+ // 领域对象类
77
+ class DomainObject extends Domain<DomainEvent> {
78
+ constructor() {
79
+ super();
80
+ // 事件处理
81
+ this.e?.trigger('eventName', 1, 'arg2');
82
+ }
83
+ }
84
+ // 领域注册
85
+ gdmb.registerDomain(DomainObject);
86
+ // 获取领域对象实例
87
+ const domainObject = gdmb.domains<DomainObject>(DomainObject);
88
+ // 监听领域事件
89
+ domainObject.e?.on('eventName', (arg: number, arg2: string) => {
90
+ // 处理事件
91
+ })
92
+ ```
93
+
94
+ ### 领域实体创建与注册(Domain Entity Creation & Registration)
95
+ ```typescript
96
+ import { gdmb, Domain, DomainEntity } from 'gdmb';
97
+ // 领域对象类
98
+ class DomainObject extends Domain<DomainEvent> {}
99
+ // 领域对象注册
100
+ gdmb.registerDomain(DomainObject);
101
+ // 领域实体类
102
+ class DomainEntityObject extends DomainEntity<DomainEvent> {
103
+ // 领域实体在解析前调用
104
+ public static beforeResolution(token: InjectionToken, resolutionType: string) {
105
+ // resolve 前拦截器这里处理
106
+ }
107
+ // 领域实体在解析后调用
108
+ public static afterResolution(token: InjectionToken, result: DomainEntityObject | DomainEntityObject[], resolutionType: string) {
109
+ // resovle 后拦截器这里处理
110
+ }
111
+ }
112
+ // 获取领域对象
113
+ const domainObject = gdmb.domains<DomainObject>(DomainObject);
114
+ // 领域实体注册
115
+ domainObject.registerEntity(DomainEntityObject, {
116
+ cachePolicy: 'cache',
117
+ beforeResolution: DomainEntityObject.beforeResolution,
118
+ afterResolution: DomainEntityObject.afterResolution
119
+ });
120
+ // 从全局对象获取领域实体实例
121
+ const domainEntity = domainObject.entities<DomainEntityObject>(DomainEntityObject);
122
+ ```
123
+
124
+ ### 值对象创建与注册(Value Object Creation & Registration)
125
+ ```typescript
126
+ import { gdmb, Domain } from 'gdmb';
127
+ // 定义值对象接口
128
+ interface IVOOne {
129
+ /** 文本 */
130
+ text: string;
131
+ /** 数字 */
132
+ num: number;
133
+ }
134
+ // 领域对象类
135
+ class DomainObject extends Domain<DomainEvent> {}
136
+ // 领域对象注册
137
+ gdmb.registerDomain(DomainObject);
138
+ // 获取领域对象实例
139
+ const domainObject = gdmb.domains<DomainObject>(DomainObject);
140
+ // 注册值对象
141
+ domainObject.registerVO<IVOOne>({
142
+ token: 'IVOOne',
143
+ factoryType: 'containerCache',
144
+ resolveFactory() {
145
+ return {
146
+ text: 'text',
147
+ num: 1,
148
+ }
149
+ }
150
+ });
151
+ // resolve 值对象
152
+ const voOne = domainObject.vos<IVOOne>('IVOOne'); // { text: 'text', num: 1 }
153
+ ```
154
+
155
+ ### 命令系统(Command System)
156
+ ```typescript
157
+ import { GDMB } from 'gdmb';
158
+ import type { Command, CommandReceiver } from 'gdmb';
159
+ // 实例化全局对象
160
+ const gdmb = new GDMB();
161
+ // 定义命令接受者作为命令执行者
162
+ class CounterReceiver implements CounterReceiver {
163
+ // 执行函数(必要)
164
+ executeOperation({ type, value = 1 }: { type: string; value?: number }): void {
165
+ // 执行函数实现
166
+ };
167
+ // 撤销函数(必要)
168
+ undoOperation({ type, value = 1 }: { type: string; value?: number }): void {
169
+ // 撤销函数实现
170
+ };
171
+ }
172
+ // 创建命令对象
173
+ const command = gdmb.c.create(
174
+ new CounterReceiver(),
175
+ (r: CounterReceiver) => r.executeOperation({ type: 'increment', value: 5 }),
176
+ (r: CounterReceiver) => r.undoOperation({ type: 'increment', value: 5 }),
177
+ '增加计数器值'
178
+ );
179
+ // 执行命令
180
+ gdmb.c.execute(command);
181
+ ```
182
+
183
+ ## 代码检查清单(Code Review Checklist)
184
+
185
+ 在审查gdmb应用程序时,请关注:
186
+
187
+ ### 领域结构与依赖注入(Domain Architecture & Dependency Injection)
188
+ - [ ] 所有领域对象(domainObject)都继承自Domain类。通过 gdmb.registerDomain() 注册;通过 gdmb.domains() 获取实例。
189
+ - [ ] 所有领域服务都继承自DomainService类。通过 domainObject.registerService() 注册;通过 domainObject.services() 获取实例。
190
+ - [ ] 所有领域实体都继承自DomainEntity类。通过 domainObject.registerEntity() 注册;通过 domainObject.entities() 获取实例。
191
+ - [ ] 所有值对象只是一个普通接口,必须通过依赖注入实例化。通过 domainObject.registerVO() 注册;通过 domainObject.vos() 获取实例。
192
+ - [ ] 所有领域对象、领域服务、领域实体、值对象都必须在注册后才能使用。
193
+ - [ ] 领域模型之间不存在循环依赖关系。
194
+
195
+ ### 领域事件与命令系统(Domain Event & Command System)
196
+ - [ ] 领域事件句柄绑定在领域对象(domainObject)内,通过 this.e 访问。
197
+ - [ ] 领域服务、领域实体在注册时注入了事件句柄,通过 this.e 访问。
198
+ - [ ] 命令系统绑定在 gdmb 对象上,通过 gdmb.c 访问。
199
+ - [ ] 所有命令接收者都实现CommandReceiver接口。并使用 @injectable() 装饰器函数装饰,实现依赖注入。
200
+ - [ ] 命令对象通过 gdmb.c.create() 创建;通过 gdmb.c.execute() 执行。
201
+
202
+ ### 测试与模拟(Testing & Mocking)
203
+ - [ ] 测试模块尽可能小。
204
+ - [ ] 在测试中,所有 async 操作,都应配合 await 使用。
205
+
206
+ ### 性能与优化(Performance & Optimization)
207
+ - [ ] 缓存是为昂贵的操作实现的
208
+ - [ ] 防止内存泄漏(清除事件侦听器)
209
+
210
+ ## 成功指标(Success Metrics)
211
+ - ✅ 在领域模块中结构中正确识别和定位问题
212
+ - ✅ 解决方案遵循DDD架构模式
213
+ - ✅ 所有测试通过(单元、集成、端到端)
214
+ - ✅ 没有引入循环依赖
215
+ - ✅ 维护或改进了性能指标
216
+ - ✅ 代码遵循既定的项目约定
217
+ - ✅ 实现了正确的错误处理
218
+ - ✅ 应用的安全最佳实践
@@ -0,0 +1,55 @@
1
+ /**
2
+ * 命令接口
3
+ * 定义执行操作的标准接口
4
+ */
5
+ export interface Command {
6
+ /**
7
+ * 执行命令
8
+ */
9
+ execute(): void;
10
+ /**
11
+ * 撤销命令
12
+ */
13
+ undo(): void;
14
+ /**
15
+ * 获取命令描述
16
+ */
17
+ getDescription(): string;
18
+ }
19
+ /**
20
+ * 命令历史记录项
21
+ */
22
+ export interface CommandHistoryItem {
23
+ command: Command;
24
+ timestamp: number;
25
+ }
26
+ /**
27
+ * 命令接收者接口
28
+ * 定义命令接收者的标准接口
29
+ */
30
+ export interface CommandReceiver {
31
+ /**
32
+ * 执行命令操作
33
+ * @param args 命令参数
34
+ */
35
+ executeOperation(...args: any[]): void;
36
+ /**
37
+ * 撤销命令操作
38
+ * @param args 命令参数
39
+ */
40
+ undoOperation(...args: any[]): void;
41
+ }
42
+ /** 命令调用历史记录最大深度配置参数接口 */
43
+ interface ICommandInvokMaxHistoryDepth {
44
+ /** 命令历史最大深度,默认为 Infinity(无限制) */
45
+ maxHistoryDepth?: number;
46
+ /** 撤销历史最大深度,默认为 Infinity(无限制) */
47
+ maxUndoHistoryDepth?: number;
48
+ }
49
+ /** 命令调用者构造配置参数 */
50
+ export type TCommandInvokerOption = ICommandInvokMaxHistoryDepth & {};
51
+ /** 命令系统构造配置参数 */
52
+ export type TCommandSystemOption = ICommandInvokMaxHistoryDepth & {};
53
+ /** gdmb 构造函数配置对象 */
54
+ export type TGDMBOption = ICommandInvokMaxHistoryDepth & {};
55
+ export {};
@@ -0,0 +1,68 @@
1
+ import { Command, CommandHistoryItem, TCommandInvokerOption } from './Command';
2
+ export declare class CommandInvoker {
3
+ /**
4
+ * 命令历史记录
5
+ */
6
+ private history;
7
+ /**
8
+ * 撤销历史记录
9
+ */
10
+ private undoHistory;
11
+ /**
12
+ * 命令历史最大深度
13
+ */
14
+ private maxHistoryDepth;
15
+ /**
16
+ * 撤销历史最大深度
17
+ */
18
+ private maxUndoHistoryDepth;
19
+ /**
20
+ * 执行命令
21
+ * @param command 要执行的命令
22
+ */
23
+ execute(command: Command): void;
24
+ /**
25
+ * 撤销上一个命令
26
+ * @returns 是否成功撤销
27
+ */
28
+ undo(): boolean;
29
+ /**
30
+ * 重做上一个撤销的命令
31
+ * @returns 是否成功重做
32
+ */
33
+ redo(): boolean;
34
+ /**
35
+ * 批量执行命令
36
+ * @param commands 要执行的命令数组
37
+ */
38
+ executeBatch(commands: Command[]): void;
39
+ /**
40
+ * 清空命令历史
41
+ */
42
+ clearHistory(): void;
43
+ /**
44
+ * 获取命令历史记录
45
+ * @returns 命令历史记录数组
46
+ */
47
+ getHistory(): CommandHistoryItem[];
48
+ /**
49
+ * 获取撤销历史记录
50
+ * @returns 撤销历史记录数组
51
+ */
52
+ getUndoHistory(): CommandHistoryItem[];
53
+ /**
54
+ * 获取历史记录数量
55
+ * @returns 历史记录数量
56
+ */
57
+ getHistoryCount(): number;
58
+ /**
59
+ * 获取撤销历史记录数量
60
+ * @returns 撤销历史记录数量
61
+ */
62
+ getUndoHistoryCount(): number;
63
+ /**
64
+ * 构造函数
65
+ * @param option 命令调用者构造配置参数
66
+ */
67
+ constructor(option?: TCommandInvokerOption);
68
+ }
@@ -0,0 +1,65 @@
1
+ import { Command, CommandReceiver, CommandHistoryItem, TCommandSystemOption } from './Command';
2
+ export declare class CommandSystem {
3
+ /**
4
+ * 命令调用者
5
+ */
6
+ private invoker;
7
+ /**
8
+ * 创建命令
9
+ * @param receiver 命令接收者
10
+ * @param executeFn 执行操作的函数
11
+ * @param undoFn 撤销操作的函数
12
+ * @param description 命令描述
13
+ * @returns 命令对象
14
+ */
15
+ create<R extends CommandReceiver>(receiver: R, executeFn: (receiver: R) => void, undoFn: (receiver: R) => void, description: string): Command;
16
+ /**
17
+ * 执行命令
18
+ * @param command 要执行的命令
19
+ */
20
+ execute(command: Command): void;
21
+ /**
22
+ * 撤销上一个命令
23
+ * @returns 是否成功撤销
24
+ */
25
+ undo(): boolean;
26
+ /**
27
+ * 重做上一个撤销的命令
28
+ * @returns 是否成功重做
29
+ */
30
+ redo(): boolean;
31
+ /**
32
+ * 批量执行命令
33
+ * @param commands 要执行的命令数组
34
+ */
35
+ executeBatch(commands: Command[]): void;
36
+ /**
37
+ * 清空命令历史
38
+ */
39
+ clearHistory(): void;
40
+ /**
41
+ * 获取命令历史记录
42
+ * @returns 命令历史记录数组
43
+ */
44
+ getHistory(): CommandHistoryItem[];
45
+ /**
46
+ * 获取撤销历史记录
47
+ * @returns 撤销历史记录数组
48
+ */
49
+ getUndoHistory(): CommandHistoryItem[];
50
+ /**
51
+ * 获取历史记录数量
52
+ * @returns 历史记录数量
53
+ */
54
+ getHistoryCount(): number;
55
+ /**
56
+ * 获取撤销历史记录数量
57
+ * @returns 撤销历史记录数量
58
+ */
59
+ getUndoHistoryCount(): number;
60
+ /**
61
+ * 构造函数
62
+ * @param option 配置参数
63
+ */
64
+ constructor(option?: TCommandSystemOption);
65
+ }
@@ -0,0 +1,49 @@
1
+ import { Command, CommandReceiver } from './Command';
2
+ export declare class ConcreteCommand<R extends CommandReceiver> implements Command {
3
+ /**
4
+ * 命令接收者
5
+ */
6
+ private receiver;
7
+ /**
8
+ * 执行操作的函数
9
+ */
10
+ private executeFn;
11
+ /**
12
+ * 撤销操作的函数
13
+ */
14
+ private undoFn;
15
+ /**
16
+ * 命令描述
17
+ */
18
+ private description;
19
+ /**
20
+ * 构造函数
21
+ * @param receiver 命令接收者
22
+ * @param executeFn 执行操作的函数
23
+ * @param undoFn 撤销操作的函数
24
+ * @param description 命令描述
25
+ */
26
+ constructor(receiver: R, executeFn: (receiver: R) => void, undoFn: (receiver: R) => void, description: string);
27
+ /**
28
+ * 执行命令
29
+ */
30
+ execute(): void;
31
+ /**
32
+ * 撤销命令
33
+ */
34
+ undo(): void;
35
+ /**
36
+ * 获取命令描述
37
+ * @returns 命令描述
38
+ */
39
+ getDescription(): string;
40
+ }
41
+ /**
42
+ * 创建命令的工厂函数
43
+ * @param receiver 命令接收者
44
+ * @param executeFn 执行操作的函数
45
+ * @param undoFn 撤销操作的函数
46
+ * @param description 命令描述
47
+ * @returns 命令对象
48
+ */
49
+ export declare function createCommand<R extends CommandReceiver>(receiver: R, executeFn: (receiver: R) => void, undoFn: (receiver: R) => void, description: string): Command;
@@ -0,0 +1,7 @@
1
+ /**
2
+ * 命令系统导出文件
3
+ */
4
+ export { CommandInvoker } from './CommandInvoker';
5
+ export { CommandSystem } from './CommandSystem';
6
+ export { ConcreteCommand, createCommand } from './ConcreteCommand';
7
+ export type { Command, CommandReceiver, CommandHistoryItem, TCommandSystemOption, TCommandInvokerOption, TGDMBOption } from './Command';
@@ -24,17 +24,23 @@ export declare class Domain<E extends TEventEmits = TEventEmits> {
24
24
  * @example
25
25
  * ```typescript
26
26
  * class ServiceOne extends DomainService {
27
+ *
28
+ * // before resolve 拦截器
29
+ * public static beforeResolution(token: InjectionToken, resolutionType: string) {}
30
+ *
31
+ * // after resolve 拦截器
32
+ * public static afterResolution(token: InjectionToken, result: ServiceOne | ServiceOne[], resolutionType: string) {}
33
+ *
27
34
  * constructor(public arg: string, public arg2: number) {
28
35
  * super();
29
36
  * }
30
37
  * }
31
38
  *
32
- * domain.registerService(ServiceOne, { args: ['hello', 3] })
33
- * // 多个服务时,配置条目允许 undefined null,此时配置会被忽略
34
- * domain.registerService([ServiceOne, ServiceTwo], [{ args: ['hello', 3] }, null])
39
+ * // 注册领域服务
40
+ * domain.registerService(ServiceOne, { beforeResolution: ServiceOne.beforeResolution, afterResolution: ServiceOne.afterResolution })
35
41
  * ```
36
42
  */
37
- registerService<S extends DomainService>(service: (new (...args: any[]) => S) | Array<new (...args: any[]) => S>, options?: IRegisterServiceOption<S> | (IRegisterServiceOption<S> | undefined | null)[]): void;
43
+ registerService<S extends DomainService>(service: new (...args: any[]) => S, options?: IRegisterServiceOption<S>): void;
38
44
  /**
39
45
  * @description 向领域依赖注入容器中注册领域实体,指定缓存策略为'cache'时全局单例。
40
46
  * @param entity 单个领域实体类或数组
@@ -42,17 +48,23 @@ export declare class Domain<E extends TEventEmits = TEventEmits> {
42
48
  * @example
43
49
  * ```typescript
44
50
  * class EntityOne extends DomainEntity {
51
+ *
52
+ * // before resolve 拦截器
53
+ * public static beforeResolution(token: InjectionToken, resolutionType: string) {}
54
+ *
55
+ * // after resolve 拦截器
56
+ * public static afterResolution(token: InjectionToken, result: EntityOne | EntityOne[], resolutionType: string) {}
57
+ *
45
58
  * constructor(public arg: string, public arg2: number) {
46
59
  * super();
47
60
  * }
48
61
  * }
49
62
  *
50
- * domain.registerEntity(EntityOne, { args: ['hello', 3] })
51
- * // 多个实体时,配置条目允许 undefined null,此时配置会被忽略
52
- * domain.registerEntity([EntityOne, EntityTwo], [{ args: ['hello', 3] }, null])
63
+ * // 注册领域实体
64
+ * domain.registerEntity(EntityOne, { cachePolicy: 'cache', beforeResolution: EntityOne.beforeResolution, afterResolution: EntityOne.afterResolution })
53
65
  * ```
54
66
  */
55
- registerEntity<E extends DomainEntity>(entity: (new (...args: any[]) => E) | Array<new (...args: any[]) => E>, options?: IRegisterEntityOption<E> | (IRegisterEntityOption<E> | undefined | null)[]): void;
67
+ registerEntity<E extends DomainEntity>(entity: new (...args: any[]) => E, options?: IRegisterEntityOption<E>): void;
56
68
  /**
57
69
  * @summary 项领域内依赖注入容器中注册值对象,当指定 factoryType 为'cache'时全局单例。
58
70
  * @description 需要泛型类型 V,约束工厂函数返回类型,V 满足 VO 类型约束,不允许包含函数属性
@@ -79,14 +91,14 @@ export declare class Domain<E extends TEventEmits = TEventEmits> {
79
91
  * @param adapter 领域实体适配器,将 DEF 类型转换为 DE 类型
80
92
  * @returns 领域实体实例对象
81
93
  */
82
- entities<DE extends DomainEntity = DomainEntity, DEF extends DomainEntity = DE>(sourceToken: TCustomInjectionToken, adapter?: Adapter<DE, DEF>): DE | undefined;
94
+ entities<DE extends DomainEntity = DomainEntity, DEF extends DomainEntity | VO<any> = DE>(sourceToken: TCustomInjectionToken, adapter?: Adapter<DE, DEF>): DE | undefined;
83
95
  /**
84
96
  * @description 从依赖注入容器中获取领域值对象实例对象
85
97
  * @param sourceToken 源领域值对象token,存在适配器时是 VF 泛型类型,否则为 V 泛型类型
86
98
  * @param adapter 领域值对象适配器,将 VF 类型转换为 V 类型
87
99
  * @returns 领域值对象实例对象
88
100
  */
89
- vos<V extends VO<any> = VO<any>, VF extends VO<any> = V>(sourceToken: TCustomInjectionToken, adapter?: Adapter<V, VF>): V | undefined;
101
+ vos<V extends VO<any> = VO<any>, VF extends VO<any> | DomainEntity = V>(sourceToken: TCustomInjectionToken, adapter?: Adapter<V, VF>): V | undefined;
90
102
  /**
91
103
  * 域基类构造函数
92
104
  */
@@ -1,4 +1,5 @@
1
1
  import { Adapter } from './base-class';
2
+ import { CommandSystem, TGDMBOption } from './command';
2
3
  import { Domain } from './domain/Domain';
3
4
  import { IDomainRegisterOption, TCustomInjectionToken } from './type';
4
5
  /**
@@ -7,6 +8,8 @@ import { IDomainRegisterOption, TCustomInjectionToken } from './type';
7
8
  export declare class GDMB {
8
9
  /** 全局 DIC */
9
10
  globalDIC: import('tsyringe').DependencyContainer;
11
+ /** 命令系统 */
12
+ c: CommandSystem;
10
13
  /**
11
14
  * 注册领域对象
12
15
  */
@@ -23,4 +26,9 @@ export declare class GDMB {
23
26
  * 提供全局的转换方法,支持批量转换
24
27
  */
25
28
  transformAll<T, TF>(source: TF[], adapter: Adapter<T, TF>): T[];
29
+ /**
30
+ * 构造函数
31
+ * @param option 配置参数
32
+ */
33
+ constructor(option?: TGDMBOption);
26
34
  }
@@ -4,5 +4,6 @@ export * from './domain/Domain';
4
4
  export * from './domain/DomainService';
5
5
  export * from './domain/DomainEntity';
6
6
  export * from './index';
7
+ export * from './command';
7
8
  export { Adapter };
8
9
  export type { TEventEmits, VO, IDomainRegisterOption, IRegisterServiceOption, IRegisterEntityOption };
@@ -10,7 +10,7 @@ export interface IAnyObject<D = any> {
10
10
  /**
11
11
  * 事件注册对象类型
12
12
  */
13
- export type TEventEmits = IAnyObject<any[]>;
13
+ export type TEventEmits = Record<string, any[]>;
14
14
  /** 自定义注入令牌类型 */
15
15
  export type TCustomInjectionToken<T = any> = string | constructor<T>;
16
16
  /**
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "gdmb",
3
- "version": "1.0.0",
3
+ "version": "1.2.0",
4
4
  "type": "module",
5
5
  "main": "dist/gdmb.umd.js",
6
6
  "module": "dist/gdmb.es.js",
@@ -27,6 +27,7 @@
27
27
  "typescript-eslint": "^8.39.1",
28
28
  "vite": "^7.1.2",
29
29
  "vite-plugin-dts": "^4.5.4",
30
+ "vite-plugin-static-copy": "^3.1.6",
30
31
  "vitest": "^3.2.4"
31
32
  },
32
33
  "dependencies": {