@woltz/rich-domain 1.2.0 → 1.2.2
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/CHANGELOG.md +58 -0
- package/dist/aggregate-changes.d.ts +164 -0
- package/dist/aggregate-changes.d.ts.map +1 -0
- package/dist/aggregate-changes.js +281 -0
- package/dist/aggregate-changes.js.map +1 -0
- package/dist/base-entity.d.ts +32 -8
- package/dist/base-entity.d.ts.map +1 -1
- package/dist/base-entity.js +86 -93
- package/dist/base-entity.js.map +1 -1
- package/dist/change-tracker.d.ts +97 -0
- package/dist/change-tracker.d.ts.map +1 -0
- package/dist/change-tracker.js +758 -0
- package/dist/change-tracker.js.map +1 -0
- package/dist/constants.d.ts +7 -1
- package/dist/constants.d.ts.map +1 -1
- package/dist/constants.js +65 -0
- package/dist/constants.js.map +1 -1
- package/dist/criteria.d.ts +3 -3
- package/dist/criteria.d.ts.map +1 -1
- package/dist/criteria.js +6 -4
- package/dist/criteria.js.map +1 -1
- package/dist/crypto.d.ts +3 -0
- package/dist/crypto.d.ts.map +1 -0
- package/dist/crypto.js +29 -0
- package/dist/crypto.js.map +1 -0
- package/dist/domain-event.d.ts.map +1 -1
- package/dist/domain-event.js +0 -3
- package/dist/domain-event.js.map +1 -1
- package/dist/entity-changes.d.ts +84 -0
- package/dist/entity-changes.d.ts.map +1 -0
- package/dist/entity-changes.js +131 -0
- package/dist/entity-changes.js.map +1 -0
- package/dist/entity-schema-registry.d.ts +148 -0
- package/dist/entity-schema-registry.d.ts.map +1 -0
- package/dist/entity-schema-registry.js +213 -0
- package/dist/entity-schema-registry.js.map +1 -0
- package/dist/entity.d.ts +0 -6
- package/dist/entity.d.ts.map +1 -1
- package/dist/entity.js +0 -9
- package/dist/entity.js.map +1 -1
- package/dist/id.d.ts +11 -10
- package/dist/id.d.ts.map +1 -1
- package/dist/id.js +4 -28
- package/dist/id.js.map +1 -1
- package/dist/index.d.ts +9 -5
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +8 -11
- package/dist/index.js.map +1 -1
- package/dist/mapper.d.ts +1 -1
- package/dist/mapper.d.ts.map +1 -1
- package/dist/mapper.js.map +1 -1
- package/dist/paginated-result.d.ts.map +1 -1
- package/dist/paginated-result.js +0 -15
- package/dist/paginated-result.js.map +1 -1
- package/dist/repository/base-repository.d.ts +7 -33
- package/dist/repository/base-repository.d.ts.map +1 -1
- package/dist/repository/base-repository.js +0 -27
- package/dist/repository/base-repository.js.map +1 -1
- package/dist/repository/index.d.ts.map +1 -1
- package/dist/repository/index.js +0 -6
- package/dist/repository/index.js.map +1 -1
- package/dist/repository/unit-of-work.d.ts +0 -25
- package/dist/repository/unit-of-work.d.ts.map +1 -1
- package/dist/repository/unit-of-work.js +0 -28
- package/dist/repository/unit-of-work.js.map +1 -1
- package/dist/types/change-tracker.d.ts +196 -0
- package/dist/types/change-tracker.d.ts.map +1 -0
- package/dist/types/change-tracker.js +2 -0
- package/dist/types/change-tracker.js.map +1 -0
- package/dist/types/criteria.d.ts +5 -1
- package/dist/types/criteria.d.ts.map +1 -1
- package/dist/types/domain.d.ts +4 -6
- package/dist/types/domain.d.ts.map +1 -1
- package/dist/types/index.d.ts +1 -1
- package/dist/types/index.d.ts.map +1 -1
- package/dist/types/index.js +1 -1
- package/dist/types/index.js.map +1 -1
- package/dist/types/utils.d.ts +0 -1
- package/dist/types/utils.d.ts.map +1 -1
- package/dist/utils/criteria-operator-validation.d.ts +1 -0
- package/dist/utils/criteria-operator-validation.d.ts.map +1 -1
- package/dist/utils/criteria-operator-validation.js +39 -17
- package/dist/utils/criteria-operator-validation.js.map +1 -1
- package/dist/validation-error.d.ts.map +1 -1
- package/dist/validation-error.js +1 -6
- package/dist/validation-error.js.map +1 -1
- package/dist/value-object.d.ts +57 -8
- package/dist/value-object.d.ts.map +1 -1
- package/dist/value-object.js +49 -22
- package/dist/value-object.js.map +1 -1
- package/package.json +2 -1
- package/src/aggregate-changes.ts +335 -0
- package/src/base-entity.ts +102 -109
- package/src/change-tracker.ts +1062 -0
- package/src/constants.ts +75 -1
- package/src/criteria.ts +11 -4
- package/src/crypto.ts +31 -0
- package/src/domain-event.ts +0 -4
- package/src/entity-changes.ts +146 -0
- package/src/entity-schema-registry.ts +255 -0
- package/src/entity.ts +0 -11
- package/src/id.ts +17 -26
- package/src/index.ts +15 -19
- package/src/mapper.ts +4 -1
- package/src/paginated-result.ts +0 -21
- package/src/repository/base-repository.ts +7 -38
- package/src/repository/index.ts +0 -9
- package/src/repository/unit-of-work.ts +0 -29
- package/src/types/change-tracker.ts +233 -0
- package/src/types/criteria.ts +6 -1
- package/src/types/domain.ts +4 -8
- package/src/types/index.ts +1 -1
- package/src/types/utils.ts +0 -9
- package/src/utils/criteria-operator-validation.ts +57 -19
- package/src/validation-error.ts +1 -7
- package/src/value-object.ts +84 -24
- package/tests/aggregate-changes.test.ts +284 -0
- package/tests/criteria.test.ts +122 -161
- package/tests/entity-equality.test.ts +38 -61
- package/tests/entity-schema-registry.test.ts +382 -0
- package/tests/entity-validation.test.ts +7 -94
- package/tests/history-tracker.spec.ts +349 -617
- package/tests/id.test.ts +41 -44
- package/tests/load-test/data.json +346041 -0
- package/tests/load-test/entities.ts +97 -0
- package/tests/load-test/generate-data.ts +81 -0
- package/tests/load-test/lead-to-domain.mapper.ts +24 -0
- package/tests/load-test/load.test.ts +38 -0
- package/tests/repository.test.ts +30 -54
- package/tests/to-json.test.ts +14 -18
- package/tests/utils.ts +138 -102
- package/tests/value-objects.test.ts +57 -29
- package/dist/deep-proxy.d.ts +0 -36
- package/dist/deep-proxy.d.ts.map +0 -1
- package/dist/deep-proxy.js +0 -384
- package/dist/deep-proxy.js.map +0 -1
- package/dist/types/history-tracker.d.ts +0 -36
- package/dist/types/history-tracker.d.ts.map +0 -1
- package/dist/types/history-tracker.js +0 -2
- package/dist/types/history-tracker.js.map +0 -1
- package/src/deep-proxy.ts +0 -447
- package/src/types/history-tracker.ts +0 -45
- package/tests/entity.test.ts +0 -33
package/src/base-entity.ts
CHANGED
|
@@ -1,14 +1,8 @@
|
|
|
1
|
-
// ============================================================================
|
|
2
|
-
// Base Entity Class with Standard Schema Validation
|
|
3
|
-
// ============================================================================
|
|
4
|
-
|
|
5
1
|
import { Id } from "./id";
|
|
6
|
-
import { DeepProxy } from "./deep-proxy";
|
|
7
2
|
import { ValidationError } from "./validation-error";
|
|
8
3
|
import { IDomainEvent } from ".";
|
|
9
4
|
import {
|
|
10
5
|
BaseProps,
|
|
11
|
-
SubscriptionConfig,
|
|
12
6
|
HistoryEntry,
|
|
13
7
|
DeepJsonResult,
|
|
14
8
|
EntityHooks,
|
|
@@ -19,8 +13,9 @@ import {
|
|
|
19
13
|
import { DomainEventBus } from "./domain-event-bus";
|
|
20
14
|
import { DEFAULT_VALIDATION_CONFIG } from "./constants";
|
|
21
15
|
import { DomainError } from "./exceptions";
|
|
16
|
+
import { ChangeTracker } from "./change-tracker";
|
|
17
|
+
import { AggregateChanges } from "./aggregate-changes";
|
|
22
18
|
|
|
23
|
-
// Helper to get static properties from constructor
|
|
24
19
|
function getStaticProperty<T>(
|
|
25
20
|
instance: any,
|
|
26
21
|
propertyName: string
|
|
@@ -30,7 +25,7 @@ function getStaticProperty<T>(
|
|
|
30
25
|
|
|
31
26
|
export abstract class BaseEntity<T extends BaseProps> {
|
|
32
27
|
private _props: T;
|
|
33
|
-
private
|
|
28
|
+
private tracker: ChangeTracker;
|
|
34
29
|
private proxiedProps: T;
|
|
35
30
|
private snapshot: T | null = null;
|
|
36
31
|
private validationConfig: Required<ValidationConfig>;
|
|
@@ -38,12 +33,10 @@ export abstract class BaseEntity<T extends BaseProps> {
|
|
|
38
33
|
private entitySchema?: StandardSchema<T>;
|
|
39
34
|
private domainEvents: IDomainEvent[] = [];
|
|
40
35
|
|
|
41
|
-
// Static properties that subclasses can override
|
|
42
36
|
protected static validation?: EntityValidation<any>;
|
|
43
37
|
protected static hooks?: EntityHooks<any, any>;
|
|
44
38
|
|
|
45
39
|
constructor(props: Omit<T, "id"> & { id?: Id }) {
|
|
46
|
-
// Get static configuration from subclass
|
|
47
40
|
const validation = getStaticProperty<EntityValidation<T>>(
|
|
48
41
|
this,
|
|
49
42
|
"validation"
|
|
@@ -63,36 +56,31 @@ export abstract class BaseEntity<T extends BaseProps> {
|
|
|
63
56
|
|
|
64
57
|
let finalProps = { ...props } as T;
|
|
65
58
|
|
|
66
|
-
// Generate ID if not provided
|
|
67
59
|
if (!finalProps.id) {
|
|
68
60
|
finalProps.id = new Id();
|
|
69
61
|
}
|
|
70
62
|
|
|
71
|
-
// Validate schema on creation
|
|
72
63
|
if (this.entitySchema && this.validationConfig.onCreate) {
|
|
73
64
|
this.validateProps(finalProps);
|
|
74
65
|
}
|
|
75
66
|
|
|
76
67
|
this._props = finalProps;
|
|
77
|
-
this.
|
|
78
|
-
|
|
68
|
+
this.tracker = new ChangeTracker(this._props, this.constructor.name);
|
|
69
|
+
|
|
70
|
+
if (this.validationConfig.onUpdate) {
|
|
71
|
+
this.setupUpdateValidation();
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
this.proxiedProps = this.tracker.createProxy();
|
|
79
75
|
|
|
80
|
-
// Execute rules (custom validations)
|
|
81
76
|
if (hooks?.rules) {
|
|
82
77
|
hooks.rules(this as any);
|
|
83
78
|
}
|
|
84
79
|
|
|
85
|
-
// Hook onCreate
|
|
86
80
|
if (hooks?.onCreate) {
|
|
87
81
|
hooks.onCreate(this as any);
|
|
88
82
|
}
|
|
89
83
|
|
|
90
|
-
// Setup update validation
|
|
91
|
-
if (this.entitySchema && this.validationConfig.onUpdate) {
|
|
92
|
-
this.setupUpdateValidation();
|
|
93
|
-
}
|
|
94
|
-
|
|
95
|
-
// Take initial snapshot for onBeforeUpdate
|
|
96
84
|
this.takeSnapshot();
|
|
97
85
|
}
|
|
98
86
|
|
|
@@ -119,7 +107,6 @@ export abstract class BaseEntity<T extends BaseProps> {
|
|
|
119
107
|
throw validationError;
|
|
120
108
|
}
|
|
121
109
|
|
|
122
|
-
// If not throwing, store error for later retrieval
|
|
123
110
|
(this as any)._validationError = validationError;
|
|
124
111
|
}
|
|
125
112
|
}
|
|
@@ -128,90 +115,93 @@ export abstract class BaseEntity<T extends BaseProps> {
|
|
|
128
115
|
if (pathSegment === null || pathSegment === undefined) {
|
|
129
116
|
return "";
|
|
130
117
|
}
|
|
131
|
-
// Handle PropertyKey (string | number | symbol)
|
|
132
118
|
if (typeof pathSegment === "string" || typeof pathSegment === "number") {
|
|
133
119
|
return String(pathSegment);
|
|
134
120
|
}
|
|
135
121
|
if (typeof pathSegment === "symbol") {
|
|
136
122
|
return pathSegment.toString();
|
|
137
123
|
}
|
|
138
|
-
// Handle object with 'key' property (Zod's PathSegment)
|
|
139
124
|
if (typeof pathSegment === "object" && "key" in pathSegment) {
|
|
140
125
|
return String((pathSegment as { key: unknown }).key);
|
|
141
126
|
}
|
|
142
|
-
// Fallback
|
|
143
127
|
return String(pathSegment);
|
|
144
128
|
}
|
|
145
129
|
|
|
130
|
+
/**
|
|
131
|
+
* Setup validation that runs on every property change.
|
|
132
|
+
* Uses the ChangeTracker's onChangeValidator callback.
|
|
133
|
+
*/
|
|
146
134
|
private setupUpdateValidation(): void {
|
|
147
135
|
const self = this;
|
|
148
136
|
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
const shouldContinue = self.entityHooks.onBeforeUpdate(
|
|
153
|
-
self as any,
|
|
154
|
-
self.snapshot
|
|
155
|
-
);
|
|
156
|
-
if (!shouldContinue) {
|
|
157
|
-
// Revert changes
|
|
158
|
-
Object.assign(self._props, self.snapshot);
|
|
159
|
-
return;
|
|
160
|
-
}
|
|
161
|
-
}
|
|
137
|
+
this.tracker.setOnChangeValidator((path, oldValue, newValue) => {
|
|
138
|
+
const originalValue = self._props[path as keyof T];
|
|
139
|
+
(self._props as any)[path] = newValue;
|
|
162
140
|
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
console.warn(
|
|
169
|
-
"Async validation on update not supported. Consider using sync validation."
|
|
141
|
+
try {
|
|
142
|
+
if (self.entityHooks?.onBeforeUpdate && self.snapshot) {
|
|
143
|
+
const shouldContinue = self.entityHooks.onBeforeUpdate(
|
|
144
|
+
self as any,
|
|
145
|
+
self.snapshot
|
|
170
146
|
);
|
|
171
|
-
|
|
147
|
+
if (!shouldContinue) {
|
|
148
|
+
(self._props as any)[path] = originalValue;
|
|
149
|
+
return false;
|
|
150
|
+
}
|
|
172
151
|
}
|
|
173
152
|
|
|
174
|
-
if (
|
|
175
|
-
const
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
153
|
+
if (self.entitySchema) {
|
|
154
|
+
const result = self.entitySchema["~standard"].validate(self._props);
|
|
155
|
+
|
|
156
|
+
if (result instanceof Promise) {
|
|
157
|
+
console.warn(
|
|
158
|
+
"Async validation on update not supported. Consider using sync validation."
|
|
159
|
+
);
|
|
160
|
+
(self._props as any)[path] = originalValue;
|
|
161
|
+
return true;
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
if (result.issues && result.issues.length > 0) {
|
|
165
|
+
const validationError = new ValidationError(
|
|
166
|
+
result.issues.map((issue) => ({
|
|
167
|
+
path: issue.path?.map((p) => self.extractPathKey(p)) || [],
|
|
168
|
+
message: issue.message,
|
|
169
|
+
}))
|
|
170
|
+
);
|
|
181
171
|
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
if (self.
|
|
185
|
-
|
|
172
|
+
(self._props as any)[path] = originalValue;
|
|
173
|
+
|
|
174
|
+
if (self.validationConfig.throwOnError) {
|
|
175
|
+
throw validationError;
|
|
186
176
|
}
|
|
187
|
-
|
|
177
|
+
|
|
178
|
+
console.error("Validation failed on update:", validationError);
|
|
179
|
+
return false;
|
|
188
180
|
}
|
|
189
|
-
console.error("Validation failed on update:", validationError);
|
|
190
181
|
}
|
|
191
|
-
}
|
|
192
182
|
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
Object.assign(self._props, self.snapshot);
|
|
183
|
+
if (self.entityHooks?.rules) {
|
|
184
|
+
try {
|
|
185
|
+
self.entityHooks.rules(self as any);
|
|
186
|
+
} catch (error) {
|
|
187
|
+
(self._props as any)[path] = originalValue;
|
|
188
|
+
|
|
189
|
+
if (self.validationConfig.throwOnError) {
|
|
190
|
+
throw error;
|
|
202
191
|
}
|
|
203
|
-
|
|
192
|
+
|
|
193
|
+
console.error("Rules validation failed on update:", error);
|
|
194
|
+
return false;
|
|
204
195
|
}
|
|
205
|
-
console.error("Rules validation failed on update:", error);
|
|
206
196
|
}
|
|
207
|
-
}
|
|
208
|
-
|
|
209
|
-
// Update snapshot after successful validation
|
|
210
|
-
self.takeSnapshot();
|
|
211
|
-
};
|
|
212
197
|
|
|
213
|
-
|
|
214
|
-
|
|
198
|
+
(self._props as any)[path] = originalValue;
|
|
199
|
+
return true;
|
|
200
|
+
} catch (error) {
|
|
201
|
+
(self._props as any)[path] = originalValue;
|
|
202
|
+
throw error;
|
|
203
|
+
}
|
|
204
|
+
});
|
|
215
205
|
}
|
|
216
206
|
|
|
217
207
|
private takeSnapshot(): void {
|
|
@@ -220,36 +210,28 @@ export abstract class BaseEntity<T extends BaseProps> {
|
|
|
220
210
|
|
|
221
211
|
private deepCloneProps(obj: any, seen: WeakSet<object> = new WeakSet()): any {
|
|
222
212
|
if (obj === null || obj === undefined) return obj;
|
|
223
|
-
|
|
224
|
-
// Primitives
|
|
225
213
|
if (typeof obj !== "object") return obj;
|
|
226
|
-
|
|
227
|
-
// Special cases - don't clone these, just return the reference
|
|
228
214
|
if (obj instanceof Id) return obj;
|
|
229
215
|
if (obj instanceof Date) return new Date(obj.getTime());
|
|
230
216
|
|
|
231
|
-
// Check for circular references
|
|
232
217
|
if (seen.has(obj)) {
|
|
233
|
-
return obj;
|
|
218
|
+
return obj;
|
|
234
219
|
}
|
|
235
220
|
|
|
236
|
-
// Handle BaseEntity instances - just keep the reference
|
|
237
221
|
if (obj instanceof BaseEntity) {
|
|
238
222
|
return obj;
|
|
239
223
|
}
|
|
240
224
|
|
|
241
|
-
// Handle ValueObject instances - just keep the reference (they're immutable)
|
|
242
225
|
if (
|
|
243
226
|
obj.constructor &&
|
|
244
227
|
obj.constructor.name !== "Object" &&
|
|
245
228
|
obj.constructor.name !== "Array"
|
|
246
229
|
) {
|
|
247
|
-
// Check if it has toJson method (likely a ValueObject or similar)
|
|
248
230
|
if (
|
|
249
231
|
typeof obj.toJson === "function" &&
|
|
250
232
|
typeof obj.equals === "function"
|
|
251
233
|
) {
|
|
252
|
-
return obj;
|
|
234
|
+
return obj;
|
|
253
235
|
}
|
|
254
236
|
}
|
|
255
237
|
|
|
@@ -259,7 +241,6 @@ export abstract class BaseEntity<T extends BaseProps> {
|
|
|
259
241
|
return obj.map((item) => this.deepCloneProps(item, seen));
|
|
260
242
|
}
|
|
261
243
|
|
|
262
|
-
// Plain objects only
|
|
263
244
|
if (obj.constructor === Object) {
|
|
264
245
|
const cloned: any = {};
|
|
265
246
|
for (const key in obj) {
|
|
@@ -270,7 +251,6 @@ export abstract class BaseEntity<T extends BaseProps> {
|
|
|
270
251
|
return cloned;
|
|
271
252
|
}
|
|
272
253
|
|
|
273
|
-
// For other object types (custom classes), just keep the reference
|
|
274
254
|
return obj;
|
|
275
255
|
}
|
|
276
256
|
|
|
@@ -284,27 +264,20 @@ export abstract class BaseEntity<T extends BaseProps> {
|
|
|
284
264
|
|
|
285
265
|
/**
|
|
286
266
|
* Check equality with another entity by comparing IDs
|
|
287
|
-
* Entities are equal if they have the same ID, regardless of other properties
|
|
288
|
-
*
|
|
289
|
-
* @param other - Another entity or an ID to compare with
|
|
290
|
-
* @returns true if entities have the same ID
|
|
291
267
|
*/
|
|
292
268
|
equals(other: BaseEntity<T> | Id | string): boolean {
|
|
293
269
|
if (!other) {
|
|
294
270
|
return false;
|
|
295
271
|
}
|
|
296
272
|
|
|
297
|
-
// Compare with another entity
|
|
298
273
|
if (other instanceof BaseEntity) {
|
|
299
274
|
return this.id.equals(other.id);
|
|
300
275
|
}
|
|
301
276
|
|
|
302
|
-
// Compare with an ID
|
|
303
277
|
if (other instanceof Id) {
|
|
304
278
|
return this.id.equals(other);
|
|
305
279
|
}
|
|
306
280
|
|
|
307
|
-
// Compare with a string ID
|
|
308
281
|
if (typeof other === "string") {
|
|
309
282
|
return this.id.equals(other);
|
|
310
283
|
}
|
|
@@ -330,21 +303,37 @@ export abstract class BaseEntity<T extends BaseProps> {
|
|
|
330
303
|
return (this as any)._validationError;
|
|
331
304
|
}
|
|
332
305
|
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
306
|
+
/**
|
|
307
|
+
* Returns all detected changes as AggregateChanges.
|
|
308
|
+
*
|
|
309
|
+
* @example
|
|
310
|
+
* ```typescript
|
|
311
|
+
* const changes = user.getChanges();
|
|
312
|
+
* const batch = changes.toBatchOperations();
|
|
313
|
+
*
|
|
314
|
+
* for (const del of batch.deletes) { ... }
|
|
315
|
+
* for (const create of batch.creates) { ... }
|
|
316
|
+
* for (const upd of batch.updates) { ... }
|
|
317
|
+
* ```
|
|
318
|
+
*/
|
|
319
|
+
getChanges<TEntityMap = Record<string, any>>(): AggregateChanges<TEntityMap> {
|
|
320
|
+
return this.tracker.getChanges<TEntityMap>();
|
|
340
321
|
}
|
|
341
322
|
|
|
323
|
+
/**
|
|
324
|
+
* Returns the change history (for debugging).
|
|
325
|
+
*/
|
|
342
326
|
getHistory(): HistoryEntry[] {
|
|
343
|
-
return this.
|
|
327
|
+
return this.tracker.getHistory();
|
|
344
328
|
}
|
|
345
329
|
|
|
346
|
-
|
|
347
|
-
|
|
330
|
+
/**
|
|
331
|
+
* Clears history and marks entity as "clean".
|
|
332
|
+
* Call this after successfully persisting to the database.
|
|
333
|
+
*/
|
|
334
|
+
markAsClean(): void {
|
|
335
|
+
this.tracker.markAsClean();
|
|
336
|
+
this.takeSnapshot();
|
|
348
337
|
}
|
|
349
338
|
|
|
350
339
|
/**
|
|
@@ -354,8 +343,12 @@ export abstract class BaseEntity<T extends BaseProps> {
|
|
|
354
343
|
this.domainEvents.push(event);
|
|
355
344
|
}
|
|
356
345
|
|
|
357
|
-
|
|
346
|
+
/**
|
|
347
|
+
* Dispatch all events through the event bus
|
|
348
|
+
*/
|
|
349
|
+
public async dispatchAll(bus: DomainEventBus): Promise<void> {
|
|
358
350
|
await bus.publishAll(this.getUncommittedEvents());
|
|
351
|
+
this.clearEvents();
|
|
359
352
|
}
|
|
360
353
|
|
|
361
354
|
/**
|