@woltz/rich-domain 0.2.1

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.
Files changed (178) hide show
  1. package/.github/workflows/ci.yml +40 -0
  2. package/.husky/commit-msg +1 -0
  3. package/.husky/pre-commit +1 -0
  4. package/.versionrc.json +21 -0
  5. package/.vscode/settings.json +3 -0
  6. package/CHANGELOG.md +81 -0
  7. package/LICENSE +21 -0
  8. package/README.md +712 -0
  9. package/commitlint.config.js +23 -0
  10. package/dist/base-entity.d.ts +67 -0
  11. package/dist/base-entity.d.ts.map +1 -0
  12. package/dist/base-entity.js +309 -0
  13. package/dist/base-entity.js.map +1 -0
  14. package/dist/constants.d.ts +3 -0
  15. package/dist/constants.d.ts.map +1 -0
  16. package/dist/constants.js +6 -0
  17. package/dist/constants.js.map +1 -0
  18. package/dist/criteria.d.ts +60 -0
  19. package/dist/criteria.d.ts.map +1 -0
  20. package/dist/criteria.js +214 -0
  21. package/dist/criteria.js.map +1 -0
  22. package/dist/deep-proxy.d.ts +34 -0
  23. package/dist/deep-proxy.d.ts.map +1 -0
  24. package/dist/deep-proxy.js +297 -0
  25. package/dist/deep-proxy.js.map +1 -0
  26. package/dist/domain-event-bus.d.ts +57 -0
  27. package/dist/domain-event-bus.d.ts.map +1 -0
  28. package/dist/domain-event-bus.js +112 -0
  29. package/dist/domain-event-bus.js.map +1 -0
  30. package/dist/domain-event.d.ts +55 -0
  31. package/dist/domain-event.d.ts.map +1 -0
  32. package/dist/domain-event.js +42 -0
  33. package/dist/domain-event.js.map +1 -0
  34. package/dist/entity.d.ts +13 -0
  35. package/dist/entity.d.ts.map +1 -0
  36. package/dist/entity.js +15 -0
  37. package/dist/entity.js.map +1 -0
  38. package/dist/filtering.d.ts +107 -0
  39. package/dist/filtering.d.ts.map +1 -0
  40. package/dist/filtering.js +202 -0
  41. package/dist/filtering.js.map +1 -0
  42. package/dist/id.d.ts +51 -0
  43. package/dist/id.d.ts.map +1 -0
  44. package/dist/id.js +84 -0
  45. package/dist/id.js.map +1 -0
  46. package/dist/index.d.ts +15 -0
  47. package/dist/index.d.ts.map +1 -0
  48. package/dist/index.js +25 -0
  49. package/dist/index.js.map +1 -0
  50. package/dist/ordering.d.ts +93 -0
  51. package/dist/ordering.d.ts.map +1 -0
  52. package/dist/ordering.js +154 -0
  53. package/dist/ordering.js.map +1 -0
  54. package/dist/paginated-result.d.ts +62 -0
  55. package/dist/paginated-result.d.ts.map +1 -0
  56. package/dist/paginated-result.js +201 -0
  57. package/dist/paginated-result.js.map +1 -0
  58. package/dist/pagination.d.ts +218 -0
  59. package/dist/pagination.d.ts.map +1 -0
  60. package/dist/pagination.js +281 -0
  61. package/dist/pagination.js.map +1 -0
  62. package/dist/repository/base-repository.d.ts +77 -0
  63. package/dist/repository/base-repository.d.ts.map +1 -0
  64. package/dist/repository/base-repository.js +80 -0
  65. package/dist/repository/base-repository.js.map +1 -0
  66. package/dist/repository/in-memory-repository.d.ts +46 -0
  67. package/dist/repository/in-memory-repository.d.ts.map +1 -0
  68. package/dist/repository/in-memory-repository.js +85 -0
  69. package/dist/repository/in-memory-repository.js.map +1 -0
  70. package/dist/repository/index.d.ts +42 -0
  71. package/dist/repository/index.d.ts.map +1 -0
  72. package/dist/repository/index.js +47 -0
  73. package/dist/repository/index.js.map +1 -0
  74. package/dist/repository/mapper.d.ts +56 -0
  75. package/dist/repository/mapper.d.ts.map +1 -0
  76. package/dist/repository/mapper.js +15 -0
  77. package/dist/repository/mapper.js.map +1 -0
  78. package/dist/repository/types.d.ts +87 -0
  79. package/dist/repository/types.d.ts.map +1 -0
  80. package/dist/repository/types.js +6 -0
  81. package/dist/repository/types.js.map +1 -0
  82. package/dist/repository/unit-of-work.d.ts +70 -0
  83. package/dist/repository/unit-of-work.d.ts.map +1 -0
  84. package/dist/repository/unit-of-work.js +122 -0
  85. package/dist/repository/unit-of-work.js.map +1 -0
  86. package/dist/repository.d.ts +2 -0
  87. package/dist/repository.d.ts.map +1 -0
  88. package/dist/repository.js +21 -0
  89. package/dist/repository.js.map +1 -0
  90. package/dist/specification.d.ts +102 -0
  91. package/dist/specification.d.ts.map +1 -0
  92. package/dist/specification.js +187 -0
  93. package/dist/specification.js.map +1 -0
  94. package/dist/types/criteria.d.ts +35 -0
  95. package/dist/types/criteria.d.ts.map +1 -0
  96. package/dist/types/criteria.js +17 -0
  97. package/dist/types/criteria.js.map +1 -0
  98. package/dist/types/domain.d.ts +30 -0
  99. package/dist/types/domain.d.ts.map +1 -0
  100. package/dist/types/domain.js +2 -0
  101. package/dist/types/domain.js.map +1 -0
  102. package/dist/types/history-tracker.d.ts +36 -0
  103. package/dist/types/history-tracker.d.ts.map +1 -0
  104. package/dist/types/history-tracker.js +2 -0
  105. package/dist/types/history-tracker.js.map +1 -0
  106. package/dist/types/index.d.ts +8 -0
  107. package/dist/types/index.d.ts.map +1 -0
  108. package/dist/types/index.js +8 -0
  109. package/dist/types/index.js.map +1 -0
  110. package/dist/types/repository.d.ts +43 -0
  111. package/dist/types/repository.d.ts.map +1 -0
  112. package/dist/types/repository.js +2 -0
  113. package/dist/types/repository.js.map +1 -0
  114. package/dist/types/standard-schema.d.ts +15 -0
  115. package/dist/types/standard-schema.d.ts.map +1 -0
  116. package/dist/types/standard-schema.js +2 -0
  117. package/dist/types/standard-schema.js.map +1 -0
  118. package/dist/types/unit-of-work.d.ts +39 -0
  119. package/dist/types/unit-of-work.d.ts.map +1 -0
  120. package/dist/types/unit-of-work.js +2 -0
  121. package/dist/types/unit-of-work.js.map +1 -0
  122. package/dist/types/utils.d.ts +14 -0
  123. package/dist/types/utils.d.ts.map +1 -0
  124. package/dist/types/utils.js +2 -0
  125. package/dist/types/utils.js.map +1 -0
  126. package/dist/types.d.ts +88 -0
  127. package/dist/types.d.ts.map +1 -0
  128. package/dist/types.js +12 -0
  129. package/dist/types.js.map +1 -0
  130. package/dist/validation-error.d.ts +42 -0
  131. package/dist/validation-error.d.ts.map +1 -0
  132. package/dist/validation-error.js +73 -0
  133. package/dist/validation-error.js.map +1 -0
  134. package/dist/value-object.d.ts +47 -0
  135. package/dist/value-object.d.ts.map +1 -0
  136. package/dist/value-object.js +136 -0
  137. package/dist/value-object.js.map +1 -0
  138. package/eslint.config.js +51 -0
  139. package/jest.config.js +21 -0
  140. package/package.json +58 -0
  141. package/src/base-entity.ts +401 -0
  142. package/src/constants.ts +7 -0
  143. package/src/criteria.ts +291 -0
  144. package/src/deep-proxy.ts +339 -0
  145. package/src/domain-event-bus.ts +166 -0
  146. package/src/domain-event.ts +90 -0
  147. package/src/entity.ts +16 -0
  148. package/src/id.ts +94 -0
  149. package/src/index.ts +33 -0
  150. package/src/paginated-result.ts +274 -0
  151. package/src/repository/base-repository.ts +152 -0
  152. package/src/repository/in-memory-repository.ts +104 -0
  153. package/src/repository/index.ts +55 -0
  154. package/src/repository/mapper.ts +74 -0
  155. package/src/repository/unit-of-work.ts +148 -0
  156. package/src/types/criteria.ts +79 -0
  157. package/src/types/domain.ts +37 -0
  158. package/src/types/history-tracker.ts +45 -0
  159. package/src/types/index.ts +7 -0
  160. package/src/types/repository.ts +51 -0
  161. package/src/types/standard-schema.ts +19 -0
  162. package/src/types/unit-of-work.ts +46 -0
  163. package/src/types/utils.ts +29 -0
  164. package/src/validation-error.ts +97 -0
  165. package/src/value-object.ts +187 -0
  166. package/tests/criteria.test.ts +432 -0
  167. package/tests/domain-events.test.ts +445 -0
  168. package/tests/entity-equality.test.ts +487 -0
  169. package/tests/entity-validation.test.ts +339 -0
  170. package/tests/entity.test.ts +33 -0
  171. package/tests/history-tracker.spec.ts +667 -0
  172. package/tests/id.test.ts +341 -0
  173. package/tests/repository.test.ts +641 -0
  174. package/tests/to-json.test.ts +91 -0
  175. package/tests/utils.ts +151 -0
  176. package/tests/value-object-validation.test.ts +228 -0
  177. package/tests/value-objects.test.ts +52 -0
  178. package/tsconfig.json +31 -0
@@ -0,0 +1 @@
1
+ {"version":3,"file":"base-repository.js","sourceRoot":"","sources":["../../src/repository/base-repository.ts"],"names":[],"mappings":"AAAA,+EAA+E;AAC/E,8DAA8D;AAC9D,+EAA+E;AAS/E;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,MAAM,OAAgB,cAAc;IAKlC,YAA+B,MAAsC;QAAtC,WAAM,GAAN,MAAM,CAAgC;IAAG,CAAC;IAsDzE,+EAA+E;IAC/E,kDAAkD;IAClD,+EAA+E;IAE/E,KAAK,CAAC,QAAQ,CAAC,EAAM;QACnB,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,WAAW,CAAC,EAAE,CAAC,KAAK,CAAC,CAAC;QAChD,IAAI,CAAC,MAAM;YAAE,OAAO,IAAI,CAAC;QACzB,OAAO,MAAM,CAAC;IAChB,CAAC;IAED,KAAK,CAAC,IAAI,CAAC,QAA2B;QACpC,OAAO,MAAM,IAAI,CAAC,aAAa,CAAC,QAAQ,CAAC,CAAC;IAC5C,CAAC;IAED,KAAK,CAAC,OAAO,CAAC,QAA4B;QACxC,IAAI,QAAQ,EAAE,CAAC;YACb,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;YACzC,OAAO,MAAM,CAAC,IAAI,CAAC;QACrB,CAAC;QAED,MAAM,OAAO,GAAG,MAAM,IAAI,CAAC,QAAQ,EAAE,CAAC;QACtC,OAAO,OAAO,CAAC;IACjB,CAAC;IAED,KAAK,CAAC,OAAO,CAAC,QAA2B;QACvC,oBAAoB;QACpB,MAAM,eAAe,GAAG,QAAQ,CAAC,KAAK,EAAE,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;QAClD,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,IAAI,CAAC,eAAe,CAAC,CAAC;QAEhD,OAAO,MAAM,CAAC,IAAI,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;IACxD,CAAC;IAED,KAAK,CAAC,IAAI,CAAC,SAAkB;QAC3B,MAAM,WAAW,GAAG,IAAI,CAAC,MAAM,CAAC,aAAa,CAAC,SAAS,CAAC,CAAC;QAEzD,IAAI,SAAS,CAAC,KAAK,EAAE,CAAC;YACpB,MAAM,IAAI,CAAC,SAAS,CAAC,WAAW,CAAC,CAAC;QACpC,CAAC;aAAM,CAAC;YACN,MAAM,IAAI,CAAC,SAAS,CAAC,SAAS,CAAC,EAAE,CAAC,KAAK,EAAE,WAAW,CAAC,CAAC;QACxD,CAAC;IACH,CAAC;IAED,KAAK,CAAC,MAAM,CAAC,SAAkB;QAC7B,MAAM,IAAI,CAAC,SAAS,CAAC,SAAS,CAAC,EAAE,CAAC,KAAK,CAAC,CAAC;IAC3C,CAAC;IAED,KAAK,CAAC,UAAU,CAAC,EAAM;QACrB,MAAM,IAAI,CAAC,SAAS,CAAC,EAAE,CAAC,KAAK,CAAC,CAAC;IACjC,CAAC;IAED,KAAK,CAAC,MAAM,CAAC,EAAM;QACjB,OAAO,IAAI,CAAC,UAAU,CAAC,EAAE,CAAC,KAAK,CAAC,CAAC;IACnC,CAAC;IAED,KAAK,CAAC,KAAK,CAAC,QAA4B;QACtC,OAAO,IAAI,CAAC,eAAe,CAAC,QAAQ,CAAC,CAAC;IACxC,CAAC;CACF"}
@@ -0,0 +1,46 @@
1
+ import type { Id } from "../id";
2
+ import type { Aggregate } from "../entity";
3
+ import type { Criteria } from "../criteria";
4
+ import { PaginatedResult } from "../paginated-result";
5
+ import type { IRepository } from "../types";
6
+ /**
7
+ * In-memory repository implementation
8
+ * Perfect for unit tests and prototyping
9
+ *
10
+ * @example
11
+ * ```ts
12
+ * const userRepo = new InMemoryRepository<User>();
13
+ *
14
+ * await userRepo.save(user);
15
+ * const found = await userRepo.findById(user.id);
16
+ * const active = await userRepo.find(
17
+ * Criteria.create<User>().whereEquals('status', 'active')
18
+ * );
19
+ * ```
20
+ */
21
+ export declare class InMemoryRepository<TDomain extends Aggregate<any>> implements IRepository<TDomain> {
22
+ protected items: Map<string, TDomain>;
23
+ findById(id: Id): Promise<TDomain | null>;
24
+ find(criteria: Criteria<TDomain>): Promise<PaginatedResult<TDomain>>;
25
+ findAll(criteria?: Criteria<TDomain>): Promise<TDomain[]>;
26
+ findOne(criteria: Criteria<TDomain>): Promise<TDomain | null>;
27
+ save(aggregate: TDomain): Promise<void>;
28
+ saveMany(aggregates: TDomain[]): Promise<void>;
29
+ delete(aggregate: TDomain): Promise<void>;
30
+ deleteById(id: Id): Promise<void>;
31
+ exists(id: Id): Promise<boolean>;
32
+ count(criteria?: Criteria<TDomain>): Promise<number>;
33
+ /**
34
+ * Clear all items (useful for test cleanup)
35
+ */
36
+ clear(): void;
37
+ /**
38
+ * Get all items as array (useful for debugging)
39
+ */
40
+ getAll(): TDomain[];
41
+ /**
42
+ * Get items count
43
+ */
44
+ size(): number;
45
+ }
46
+ //# sourceMappingURL=in-memory-repository.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"in-memory-repository.d.ts","sourceRoot":"","sources":["../../src/repository/in-memory-repository.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,EAAE,EAAE,MAAM,OAAO,CAAC;AAChC,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,WAAW,CAAC;AAC3C,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AAC5C,OAAO,EAAE,eAAe,EAAE,MAAM,qBAAqB,CAAC;AACtD,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,UAAU,CAAC;AAE5C;;;;;;;;;;;;;;GAcG;AACH,qBAAa,kBAAkB,CAAC,OAAO,SAAS,SAAS,CAAC,GAAG,CAAC,CAC5D,YAAW,WAAW,CAAC,OAAO,CAAC;IAE/B,SAAS,CAAC,KAAK,EAAE,GAAG,CAAC,MAAM,EAAE,OAAO,CAAC,CAAa;IAE5C,QAAQ,CAAC,EAAE,EAAE,EAAE,GAAG,OAAO,CAAC,OAAO,GAAG,IAAI,CAAC;IAIzC,IAAI,CAAC,QAAQ,EAAE,QAAQ,CAAC,OAAO,CAAC,GAAG,OAAO,CAAC,eAAe,CAAC,OAAO,CAAC,CAAC;IAKpE,OAAO,CAAC,QAAQ,CAAC,EAAE,QAAQ,CAAC,OAAO,CAAC,GAAG,OAAO,CAAC,OAAO,EAAE,CAAC;IASzD,OAAO,CAAC,QAAQ,EAAE,QAAQ,CAAC,OAAO,CAAC,GAAG,OAAO,CAAC,OAAO,GAAG,IAAI,CAAC;IAK7D,IAAI,CAAC,SAAS,EAAE,OAAO,GAAG,OAAO,CAAC,IAAI,CAAC;IAIvC,QAAQ,CAAC,UAAU,EAAE,OAAO,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC;IAM9C,MAAM,CAAC,SAAS,EAAE,OAAO,GAAG,OAAO,CAAC,IAAI,CAAC;IAIzC,UAAU,CAAC,EAAE,EAAE,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC;IAIjC,MAAM,CAAC,EAAE,EAAE,EAAE,GAAG,OAAO,CAAC,OAAO,CAAC;IAIhC,KAAK,CAAC,QAAQ,CAAC,EAAE,QAAQ,CAAC,OAAO,CAAC,GAAG,OAAO,CAAC,MAAM,CAAC;IAQ1D;;OAEG;IACH,KAAK,IAAI,IAAI;IAIb;;OAEG;IACH,MAAM,IAAI,OAAO,EAAE;IAInB;;OAEG;IACH,IAAI,IAAI,MAAM;CAGf"}
@@ -0,0 +1,85 @@
1
+ // ============================================================================
2
+ // In-Memory Repository - Perfect for testing
3
+ // ============================================================================
4
+ import { PaginatedResult } from "../paginated-result";
5
+ /**
6
+ * In-memory repository implementation
7
+ * Perfect for unit tests and prototyping
8
+ *
9
+ * @example
10
+ * ```ts
11
+ * const userRepo = new InMemoryRepository<User>();
12
+ *
13
+ * await userRepo.save(user);
14
+ * const found = await userRepo.findById(user.id);
15
+ * const active = await userRepo.find(
16
+ * Criteria.create<User>().whereEquals('status', 'active')
17
+ * );
18
+ * ```
19
+ */
20
+ export class InMemoryRepository {
21
+ constructor() {
22
+ this.items = new Map();
23
+ }
24
+ async findById(id) {
25
+ return this.items.get(id.value) || null;
26
+ }
27
+ async find(criteria) {
28
+ const allItems = Array.from(this.items.values());
29
+ return PaginatedResult.fromArray(allItems, criteria);
30
+ }
31
+ async findAll(criteria) {
32
+ if (criteria) {
33
+ const result = await this.find(criteria);
34
+ return result.data;
35
+ }
36
+ return Array.from(this.items.values());
37
+ }
38
+ async findOne(criteria) {
39
+ const result = await this.find(criteria.clone().limit(1));
40
+ return result.data.length > 0 ? result.data[0] : null;
41
+ }
42
+ async save(aggregate) {
43
+ this.items.set(aggregate.id.value, aggregate);
44
+ }
45
+ async saveMany(aggregates) {
46
+ for (const aggregate of aggregates) {
47
+ await this.save(aggregate);
48
+ }
49
+ }
50
+ async delete(aggregate) {
51
+ this.items.delete(aggregate.id.value);
52
+ }
53
+ async deleteById(id) {
54
+ this.items.delete(id.value);
55
+ }
56
+ async exists(id) {
57
+ return this.items.has(id.value);
58
+ }
59
+ async count(criteria) {
60
+ if (criteria) {
61
+ const result = await this.find(criteria);
62
+ return result.meta.total;
63
+ }
64
+ return this.items.size;
65
+ }
66
+ /**
67
+ * Clear all items (useful for test cleanup)
68
+ */
69
+ clear() {
70
+ this.items.clear();
71
+ }
72
+ /**
73
+ * Get all items as array (useful for debugging)
74
+ */
75
+ getAll() {
76
+ return Array.from(this.items.values());
77
+ }
78
+ /**
79
+ * Get items count
80
+ */
81
+ size() {
82
+ return this.items.size;
83
+ }
84
+ }
85
+ //# sourceMappingURL=in-memory-repository.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"in-memory-repository.js","sourceRoot":"","sources":["../../src/repository/in-memory-repository.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,42 @@
1
+ export { BaseMapper } from "./mapper";
2
+ export type { IMapper } from "./mapper";
3
+ export { BaseRepository } from "./base-repository";
4
+ export { InMemoryRepository } from "./in-memory-repository";
5
+ export { UnitOfWork, BaseTransactionContext, InMemoryUnitOfWork, } from "./unit-of-work";
6
+ /**
7
+ * QUICK START:
8
+ *
9
+ * 1. For Testing:
10
+ * ```ts
11
+ * import { InMemoryRepository } from 'rich-domain';
12
+ *
13
+ * const userRepo = new InMemoryRepository<User>();
14
+ * await userRepo.save(user);
15
+ * const found = await userRepo.findById(user.id);
16
+ * ```
17
+ *
18
+ * 2. For Production (Prisma, TypeORM, etc):
19
+ * - Extend BaseRepository
20
+ * - Implement abstract methods
21
+ * - Create a Mapper
22
+ * - See examples/ folder for reference
23
+ *
24
+ * 3. With Criteria:
25
+ * ```ts
26
+ * const result = await userRepo.find(
27
+ * Criteria.create<User>()
28
+ * .whereEquals('status', 'active')
29
+ * .orderByDesc('createdAt')
30
+ * .paginate(1, 10)
31
+ * );
32
+ * ```
33
+ *
34
+ * 4. With Unit of Work:
35
+ * ```ts
36
+ * await uow.transaction(async (ctx) => {
37
+ * const userRepo = uow.getRepository(UserRepository);
38
+ * await userRepo.save(user);
39
+ * });
40
+ * ```
41
+ */
42
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/repository/index.ts"],"names":[],"mappings":"AAKA,OAAO,EAAE,UAAU,EAAE,MAAM,UAAU,CAAC;AACtC,YAAY,EAAE,OAAO,EAAE,MAAM,UAAU,CAAC;AAGxC,OAAO,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAC;AACnD,OAAO,EAAE,kBAAkB,EAAE,MAAM,wBAAwB,CAAC;AAG5D,OAAO,EACL,UAAU,EACV,sBAAsB,EACtB,kBAAkB,GACnB,MAAM,gBAAgB,CAAC;AAExB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAmCG"}
@@ -0,0 +1,47 @@
1
+ // ============================================================================
2
+ // Repository Module - Clean exports
3
+ // ============================================================================
4
+ // Mapper
5
+ export { BaseMapper } from "./mapper";
6
+ // Base implementations
7
+ export { BaseRepository } from "./base-repository";
8
+ export { InMemoryRepository } from "./in-memory-repository";
9
+ // Unit of Work
10
+ export { UnitOfWork, BaseTransactionContext, InMemoryUnitOfWork, } from "./unit-of-work";
11
+ /**
12
+ * QUICK START:
13
+ *
14
+ * 1. For Testing:
15
+ * ```ts
16
+ * import { InMemoryRepository } from 'rich-domain';
17
+ *
18
+ * const userRepo = new InMemoryRepository<User>();
19
+ * await userRepo.save(user);
20
+ * const found = await userRepo.findById(user.id);
21
+ * ```
22
+ *
23
+ * 2. For Production (Prisma, TypeORM, etc):
24
+ * - Extend BaseRepository
25
+ * - Implement abstract methods
26
+ * - Create a Mapper
27
+ * - See examples/ folder for reference
28
+ *
29
+ * 3. With Criteria:
30
+ * ```ts
31
+ * const result = await userRepo.find(
32
+ * Criteria.create<User>()
33
+ * .whereEquals('status', 'active')
34
+ * .orderByDesc('createdAt')
35
+ * .paginate(1, 10)
36
+ * );
37
+ * ```
38
+ *
39
+ * 4. With Unit of Work:
40
+ * ```ts
41
+ * await uow.transaction(async (ctx) => {
42
+ * const userRepo = uow.getRepository(UserRepository);
43
+ * await userRepo.save(user);
44
+ * });
45
+ * ```
46
+ */
47
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/repository/index.ts"],"names":[],"mappings":"AAAA,+EAA+E;AAC/E,oCAAoC;AACpC,+EAA+E;AAE/E,SAAS;AACT,OAAO,EAAE,UAAU,EAAE,MAAM,UAAU,CAAC;AAGtC,uBAAuB;AACvB,OAAO,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAC;AACnD,OAAO,EAAE,kBAAkB,EAAE,MAAM,wBAAwB,CAAC;AAE5D,eAAe;AACf,OAAO,EACL,UAAU,EACV,sBAAsB,EACtB,kBAAkB,GACnB,MAAM,gBAAgB,CAAC;AAExB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAmCG"}
@@ -0,0 +1,56 @@
1
+ import type { Aggregate } from "../entity";
2
+ /**
3
+ * Mapper interface for converting between Domain and Persistence models
4
+ *
5
+ * @template TDomain - Domain aggregate/entity
6
+ * @template TPersistence - Database model (Prisma, TypeORM, etc.)
7
+ *
8
+ * @example
9
+ * ```ts
10
+ * class UserMapper implements IMapper<User, PrismaUser> {
11
+ * toDomain(persistence: PrismaUser): User {
12
+ * return new User({
13
+ * id: Id.from(persistence.id),
14
+ * name: persistence.name,
15
+ * email: persistence.email,
16
+ * });
17
+ * }
18
+ *
19
+ * toPersistence(domain: User): PrismaUser {
20
+ * return {
21
+ * id: domain.id.value,
22
+ * name: domain.props.name,
23
+ * email: domain.props.email,
24
+ * };
25
+ * }
26
+ * }
27
+ * ```
28
+ */
29
+ export interface IMapper<TDomain extends Aggregate<any>, TPersistence = any> {
30
+ /**
31
+ * Convert from persistence model to domain aggregate
32
+ */
33
+ toDomain(persistence: TPersistence): TDomain;
34
+ /**
35
+ * Convert from domain aggregate to persistence model
36
+ */
37
+ toPersistence(domain: TDomain): TPersistence;
38
+ /**
39
+ * Convert array of persistence models to domain aggregates
40
+ */
41
+ toDomainList?(persistence: TPersistence[]): TDomain[];
42
+ /**
43
+ * Convert array of domain aggregates to persistence models
44
+ */
45
+ toPersistenceList?(domain: TDomain[]): TPersistence[];
46
+ }
47
+ /**
48
+ * Base mapper with default array implementations
49
+ */
50
+ export declare abstract class BaseMapper<TDomain extends Aggregate<any>, TPersistence = any> implements IMapper<TDomain, TPersistence> {
51
+ abstract toDomain(persistence: TPersistence): TDomain;
52
+ abstract toPersistence(domain: TDomain): TPersistence;
53
+ toDomainList(persistence: TPersistence[]): TDomain[];
54
+ toPersistenceList(domain: TDomain[]): TPersistence[];
55
+ }
56
+ //# sourceMappingURL=mapper.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mapper.d.ts","sourceRoot":"","sources":["../../src/repository/mapper.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,WAAW,CAAC;AAE3C;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AACH,MAAM,WAAW,OAAO,CAAC,OAAO,SAAS,SAAS,CAAC,GAAG,CAAC,EAAE,YAAY,GAAG,GAAG;IACzE;;OAEG;IACH,QAAQ,CAAC,WAAW,EAAE,YAAY,GAAG,OAAO,CAAC;IAE7C;;OAEG;IACH,aAAa,CAAC,MAAM,EAAE,OAAO,GAAG,YAAY,CAAC;IAE7C;;OAEG;IACH,YAAY,CAAC,CAAC,WAAW,EAAE,YAAY,EAAE,GAAG,OAAO,EAAE,CAAC;IAEtD;;OAEG;IACH,iBAAiB,CAAC,CAAC,MAAM,EAAE,OAAO,EAAE,GAAG,YAAY,EAAE,CAAC;CACvD;AAED;;GAEG;AACH,8BAAsB,UAAU,CAC9B,OAAO,SAAS,SAAS,CAAC,GAAG,CAAC,EAC9B,YAAY,GAAG,GAAG,CAClB,YAAW,OAAO,CAAC,OAAO,EAAE,YAAY,CAAC;IAEzC,QAAQ,CAAC,QAAQ,CAAC,WAAW,EAAE,YAAY,GAAG,OAAO;IACrD,QAAQ,CAAC,aAAa,CAAC,MAAM,EAAE,OAAO,GAAG,YAAY;IAErD,YAAY,CAAC,WAAW,EAAE,YAAY,EAAE,GAAG,OAAO,EAAE;IAIpD,iBAAiB,CAAC,MAAM,EAAE,OAAO,EAAE,GAAG,YAAY,EAAE;CAGrD"}
@@ -0,0 +1,15 @@
1
+ // ============================================================================
2
+ // Mapper - Domain ↔ Persistence
3
+ // ============================================================================
4
+ /**
5
+ * Base mapper with default array implementations
6
+ */
7
+ export class BaseMapper {
8
+ toDomainList(persistence) {
9
+ return persistence.map((p) => this.toDomain(p));
10
+ }
11
+ toPersistenceList(domain) {
12
+ return domain.map((d) => this.toPersistence(d));
13
+ }
14
+ }
15
+ //# sourceMappingURL=mapper.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mapper.js","sourceRoot":"","sources":["../../src/repository/mapper.ts"],"names":[],"mappings":"AAAA,+EAA+E;AAC/E,gCAAgC;AAChC,+EAA+E;AAqD/E;;GAEG;AACH,MAAM,OAAgB,UAAU;IAQ9B,YAAY,CAAC,WAA2B;QACtC,OAAO,WAAW,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC;IAClD,CAAC;IAED,iBAAiB,CAAC,MAAiB;QACjC,OAAO,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC,CAAC,CAAC,CAAC;IAClD,CAAC;CACF"}
@@ -0,0 +1,87 @@
1
+ import type { Id } from "../id";
2
+ import type { Aggregate } from "../entity";
3
+ import type { Criteria } from "../criteria";
4
+ import type { PaginatedResult } from "../paginated-result";
5
+ /**
6
+ * Base repository interface
7
+ * Keep it minimal - only what you actually need
8
+ */
9
+ export interface IRepository<TDomain extends Aggregate<any>> {
10
+ /**
11
+ * Find by ID
12
+ */
13
+ findById(id: Id): Promise<TDomain | null>;
14
+ /**
15
+ * Find using criteria (filtering, ordering, pagination)
16
+ */
17
+ find(criteria: Criteria<TDomain>): Promise<PaginatedResult<TDomain>>;
18
+ /**
19
+ * Find all (with optional criteria)
20
+ */
21
+ findAll(criteria?: Criteria<TDomain>): Promise<TDomain[]>;
22
+ /**
23
+ * Find one (first matching criteria)
24
+ */
25
+ findOne(criteria: Criteria<TDomain>): Promise<TDomain | null>;
26
+ /**
27
+ * Save (insert or update based on aggregate.isNew)
28
+ */
29
+ save(aggregate: TDomain): Promise<void>;
30
+ /**
31
+ * Save multiple aggregates
32
+ */
33
+ saveMany(aggregates: TDomain[]): Promise<void>;
34
+ /**
35
+ * Delete aggregate
36
+ */
37
+ delete(aggregate: TDomain): Promise<void>;
38
+ /**
39
+ * Delete by ID
40
+ */
41
+ deleteById(id: Id): Promise<void>;
42
+ /**
43
+ * Check if exists
44
+ */
45
+ exists(id: Id): Promise<boolean>;
46
+ /**
47
+ * Count matching criteria
48
+ */
49
+ count(criteria?: Criteria<TDomain>): Promise<number>;
50
+ }
51
+ /**
52
+ * Transaction context for Unit of Work
53
+ */
54
+ export interface TransactionContext {
55
+ /**
56
+ * Commit all changes
57
+ */
58
+ commit(): Promise<void>;
59
+ /**
60
+ * Rollback all changes
61
+ */
62
+ rollback(): Promise<void>;
63
+ /**
64
+ * Check if transaction is active
65
+ */
66
+ isActive(): boolean;
67
+ }
68
+ /**
69
+ * Unit of Work interface
70
+ * Manages transactions across multiple repositories
71
+ */
72
+ export interface IUnitOfWork {
73
+ /**
74
+ * Start a new transaction
75
+ */
76
+ begin(): Promise<TransactionContext>;
77
+ /**
78
+ * Execute work within a transaction
79
+ * Auto-commits on success, rolls back on error
80
+ */
81
+ transaction<T>(work: (ctx: TransactionContext) => Promise<T>): Promise<T>;
82
+ /**
83
+ * Get repository within transaction context
84
+ */
85
+ getRepository<TDomain extends Aggregate<any>>(repository: new (...args: any[]) => IRepository<TDomain>): IRepository<TDomain>;
86
+ }
87
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/repository/types.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,EAAE,EAAE,MAAM,OAAO,CAAC;AAChC,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,WAAW,CAAC;AAC3C,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AAC5C,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,qBAAqB,CAAC;AAG3D;;;GAGG;AACH,MAAM,WAAW,WAAW,CAAC,OAAO,SAAS,SAAS,CAAC,GAAG,CAAC;IACzD;;OAEG;IACH,QAAQ,CAAC,EAAE,EAAE,EAAE,GAAG,OAAO,CAAC,OAAO,GAAG,IAAI,CAAC,CAAC;IAE1C;;OAEG;IACH,IAAI,CAAC,QAAQ,EAAE,QAAQ,CAAC,OAAO,CAAC,GAAG,OAAO,CAAC,eAAe,CAAC,OAAO,CAAC,CAAC,CAAC;IAErE;;OAEG;IACH,OAAO,CAAC,QAAQ,CAAC,EAAE,QAAQ,CAAC,OAAO,CAAC,GAAG,OAAO,CAAC,OAAO,EAAE,CAAC,CAAC;IAE1D;;OAEG;IACH,OAAO,CAAC,QAAQ,EAAE,QAAQ,CAAC,OAAO,CAAC,GAAG,OAAO,CAAC,OAAO,GAAG,IAAI,CAAC,CAAC;IAE9D;;OAEG;IACH,IAAI,CAAC,SAAS,EAAE,OAAO,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAExC;;OAEG;IACH,QAAQ,CAAC,UAAU,EAAE,OAAO,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAE/C;;OAEG;IACH,MAAM,CAAC,SAAS,EAAE,OAAO,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAE1C;;OAEG;IACH,UAAU,CAAC,EAAE,EAAE,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAElC;;OAEG;IACH,MAAM,CAAC,EAAE,EAAE,EAAE,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;IAEjC;;OAEG;IACH,KAAK,CAAC,QAAQ,CAAC,EAAE,QAAQ,CAAC,OAAO,CAAC,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;CACtD;AAED;;GAEG;AACH,MAAM,WAAW,kBAAkB;IACjC;;OAEG;IACH,MAAM,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;IAExB;;OAEG;IACH,QAAQ,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;IAE1B;;OAEG;IACH,QAAQ,IAAI,OAAO,CAAC;CACrB;AAED;;;GAGG;AACH,MAAM,WAAW,WAAW;IAC1B;;OAEG;IACH,KAAK,IAAI,OAAO,CAAC,kBAAkB,CAAC,CAAC;IAErC;;;OAGG;IACH,WAAW,CAAC,CAAC,EAAE,IAAI,EAAE,CAAC,GAAG,EAAE,kBAAkB,KAAK,OAAO,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC,CAAC;IAE1E;;OAEG;IACH,aAAa,CAAC,OAAO,SAAS,SAAS,CAAC,GAAG,CAAC,EAC1C,UAAU,EAAE,KAAK,GAAG,IAAI,EAAE,GAAG,EAAE,KAAK,WAAW,CAAC,OAAO,CAAC,GACvD,WAAW,CAAC,OAAO,CAAC,CAAC;CACzB"}
@@ -0,0 +1,6 @@
1
+ "use strict";
2
+ // ============================================================================
3
+ // Repository Types - Simple and Type-Safe
4
+ // ============================================================================
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/repository/types.ts"],"names":[],"mappings":";AAAA,+EAA+E;AAC/E,0CAA0C;AAC1C,+EAA+E"}
@@ -0,0 +1,70 @@
1
+ import type { IUnitOfWork, TransactionContext } from "../types";
2
+ /**
3
+ * Abstract Unit of Work
4
+ * Provides transaction management across multiple repositories
5
+ *
6
+ * @example
7
+ * ```ts
8
+ * // Using transaction helper (recommended)
9
+ * await uow.transaction(async (ctx) => {
10
+ * const userRepo = uow.getRepository(UserRepository);
11
+ * const orderRepo = uow.getRepository(OrderRepository);
12
+ *
13
+ * await userRepo.save(user);
14
+ * await orderRepo.save(order);
15
+ *
16
+ * // Auto-commits on success, rolls back on error
17
+ * });
18
+ *
19
+ * // Manual control
20
+ * const ctx = await uow.begin();
21
+ * try {
22
+ * await userRepo.save(user);
23
+ * await orderRepo.save(order);
24
+ * await ctx.commit();
25
+ * } catch (error) {
26
+ * await ctx.rollback();
27
+ * throw error;
28
+ * }
29
+ * ```
30
+ */
31
+ export declare abstract class UnitOfWork implements IUnitOfWork {
32
+ protected currentContext: TransactionContext | null;
33
+ protected repositoryCache: Map<string, any>;
34
+ abstract begin(): Promise<TransactionContext>;
35
+ /**
36
+ * Execute work within a transaction
37
+ * Auto-commits on success, rolls back on error
38
+ */
39
+ transaction<T>(work: (ctx: TransactionContext) => Promise<T>): Promise<T>;
40
+ /**
41
+ * Get repository instance (cached per transaction)
42
+ */
43
+ getRepository<TRepo>(RepositoryClass: new (...args: any[]) => TRepo): TRepo;
44
+ /**
45
+ * Create repository instance - implement in subclass
46
+ */
47
+ protected abstract createRepository<TRepo>(RepositoryClass: new (...args: any[]) => TRepo): TRepo;
48
+ }
49
+ /**
50
+ * Base Transaction Context
51
+ */
52
+ export declare abstract class BaseTransactionContext implements TransactionContext {
53
+ protected _isActive: boolean;
54
+ abstract commit(): Promise<void>;
55
+ abstract rollback(): Promise<void>;
56
+ isActive(): boolean;
57
+ protected markInactive(): void;
58
+ }
59
+ /**
60
+ * In-Memory Unit of Work (for testing)
61
+ */
62
+ export declare class InMemoryUnitOfWork extends UnitOfWork {
63
+ private committed;
64
+ private rolledBack;
65
+ begin(): Promise<TransactionContext>;
66
+ protected createRepository<TRepo>(RepositoryClass: new (...args: any[]) => TRepo): TRepo;
67
+ isCommitted(): boolean;
68
+ isRolledBack(): boolean;
69
+ }
70
+ //# sourceMappingURL=unit-of-work.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"unit-of-work.d.ts","sourceRoot":"","sources":["../../src/repository/unit-of-work.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,WAAW,EAAE,kBAAkB,EAAE,MAAM,UAAU,CAAC;AAEhE;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG;AACH,8BAAsB,UAAW,YAAW,WAAW;IACrD,SAAS,CAAC,cAAc,EAAE,kBAAkB,GAAG,IAAI,CAAQ;IAC3D,SAAS,CAAC,eAAe,EAAE,GAAG,CAAC,MAAM,EAAE,GAAG,CAAC,CAAa;IAExD,QAAQ,CAAC,KAAK,IAAI,OAAO,CAAC,kBAAkB,CAAC;IAE7C;;;OAGG;IACG,WAAW,CAAC,CAAC,EACjB,IAAI,EAAE,CAAC,GAAG,EAAE,kBAAkB,KAAK,OAAO,CAAC,CAAC,CAAC,GAC5C,OAAO,CAAC,CAAC,CAAC;IAkBb;;OAEG;IACH,aAAa,CAAC,KAAK,EACjB,eAAe,EAAE,KAAK,GAAG,IAAI,EAAE,GAAG,EAAE,KAAK,KAAK,GAC7C,KAAK;IAYR;;OAEG;IACH,SAAS,CAAC,QAAQ,CAAC,gBAAgB,CAAC,KAAK,EACvC,eAAe,EAAE,KAAK,GAAG,IAAI,EAAE,GAAG,EAAE,KAAK,KAAK,GAC7C,KAAK;CACT;AAED;;GAEG;AACH,8BAAsB,sBAAuB,YAAW,kBAAkB;IACxE,SAAS,CAAC,SAAS,UAAQ;IAE3B,QAAQ,CAAC,MAAM,IAAI,OAAO,CAAC,IAAI,CAAC;IAChC,QAAQ,CAAC,QAAQ,IAAI,OAAO,CAAC,IAAI,CAAC;IAElC,QAAQ,IAAI,OAAO;IAInB,SAAS,CAAC,YAAY,IAAI,IAAI;CAG/B;AAED;;GAEG;AACH,qBAAa,kBAAmB,SAAQ,UAAU;IAChD,OAAO,CAAC,SAAS,CAAS;IAC1B,OAAO,CAAC,UAAU,CAAS;IAErB,KAAK,IAAI,OAAO,CAAC,kBAAkB,CAAC;IAO1C,SAAS,CAAC,gBAAgB,CAAC,KAAK,EAC9B,eAAe,EAAE,KAAK,GAAG,IAAI,EAAE,GAAG,EAAE,KAAK,KAAK,GAC7C,KAAK;IAMR,WAAW,IAAI,OAAO;IAItB,YAAY,IAAI,OAAO;CAGxB"}
@@ -0,0 +1,122 @@
1
+ // ============================================================================
2
+ // Unit of Work - Simple transaction management
3
+ // ============================================================================
4
+ /**
5
+ * Abstract Unit of Work
6
+ * Provides transaction management across multiple repositories
7
+ *
8
+ * @example
9
+ * ```ts
10
+ * // Using transaction helper (recommended)
11
+ * await uow.transaction(async (ctx) => {
12
+ * const userRepo = uow.getRepository(UserRepository);
13
+ * const orderRepo = uow.getRepository(OrderRepository);
14
+ *
15
+ * await userRepo.save(user);
16
+ * await orderRepo.save(order);
17
+ *
18
+ * // Auto-commits on success, rolls back on error
19
+ * });
20
+ *
21
+ * // Manual control
22
+ * const ctx = await uow.begin();
23
+ * try {
24
+ * await userRepo.save(user);
25
+ * await orderRepo.save(order);
26
+ * await ctx.commit();
27
+ * } catch (error) {
28
+ * await ctx.rollback();
29
+ * throw error;
30
+ * }
31
+ * ```
32
+ */
33
+ export class UnitOfWork {
34
+ constructor() {
35
+ this.currentContext = null;
36
+ this.repositoryCache = new Map();
37
+ }
38
+ /**
39
+ * Execute work within a transaction
40
+ * Auto-commits on success, rolls back on error
41
+ */
42
+ async transaction(work) {
43
+ const ctx = await this.begin();
44
+ try {
45
+ const result = await work(ctx);
46
+ await ctx.commit();
47
+ return result;
48
+ }
49
+ catch (error) {
50
+ if (ctx.isActive()) {
51
+ await ctx.rollback();
52
+ }
53
+ throw error;
54
+ }
55
+ finally {
56
+ this.currentContext = null;
57
+ this.repositoryCache.clear();
58
+ }
59
+ }
60
+ /**
61
+ * Get repository instance (cached per transaction)
62
+ */
63
+ getRepository(RepositoryClass) {
64
+ const key = RepositoryClass.name;
65
+ if (this.repositoryCache.has(key)) {
66
+ return this.repositoryCache.get(key);
67
+ }
68
+ const repo = this.createRepository(RepositoryClass);
69
+ this.repositoryCache.set(key, repo);
70
+ return repo;
71
+ }
72
+ }
73
+ /**
74
+ * Base Transaction Context
75
+ */
76
+ export class BaseTransactionContext {
77
+ constructor() {
78
+ this._isActive = true;
79
+ }
80
+ isActive() {
81
+ return this._isActive;
82
+ }
83
+ markInactive() {
84
+ this._isActive = false;
85
+ }
86
+ }
87
+ /**
88
+ * In-Memory Unit of Work (for testing)
89
+ */
90
+ export class InMemoryUnitOfWork extends UnitOfWork {
91
+ constructor() {
92
+ super(...arguments);
93
+ this.committed = false;
94
+ this.rolledBack = false;
95
+ }
96
+ async begin() {
97
+ this.currentContext = new InMemoryTransactionContext();
98
+ this.committed = false;
99
+ this.rolledBack = false;
100
+ return this.currentContext;
101
+ }
102
+ createRepository(RepositoryClass) {
103
+ // For in-memory, just create a new instance
104
+ // In real implementation, pass transaction client
105
+ return new RepositoryClass();
106
+ }
107
+ isCommitted() {
108
+ return this.committed;
109
+ }
110
+ isRolledBack() {
111
+ return this.rolledBack;
112
+ }
113
+ }
114
+ class InMemoryTransactionContext extends BaseTransactionContext {
115
+ async commit() {
116
+ this.markInactive();
117
+ }
118
+ async rollback() {
119
+ this.markInactive();
120
+ }
121
+ }
122
+ //# sourceMappingURL=unit-of-work.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"unit-of-work.js","sourceRoot":"","sources":["../../src/repository/unit-of-work.ts"],"names":[],"mappings":"AAAA,+EAA+E;AAC/E,+CAA+C;AAC/C,+EAA+E;AAI/E;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG;AACH,MAAM,OAAgB,UAAU;IAAhC;QACY,mBAAc,GAA8B,IAAI,CAAC;QACjD,oBAAe,GAAqB,IAAI,GAAG,EAAE,CAAC;IAmD1D,CAAC;IA/CC;;;OAGG;IACH,KAAK,CAAC,WAAW,CACf,IAA6C;QAE7C,MAAM,GAAG,GAAG,MAAM,IAAI,CAAC,KAAK,EAAE,CAAC;QAE/B,IAAI,CAAC;YACH,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,GAAG,CAAC,CAAC;YAC/B,MAAM,GAAG,CAAC,MAAM,EAAE,CAAC;YACnB,OAAO,MAAM,CAAC;QAChB,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,IAAI,GAAG,CAAC,QAAQ,EAAE,EAAE,CAAC;gBACnB,MAAM,GAAG,CAAC,QAAQ,EAAE,CAAC;YACvB,CAAC;YACD,MAAM,KAAK,CAAC;QACd,CAAC;gBAAS,CAAC;YACT,IAAI,CAAC,cAAc,GAAG,IAAI,CAAC;YAC3B,IAAI,CAAC,eAAe,CAAC,KAAK,EAAE,CAAC;QAC/B,CAAC;IACH,CAAC;IAED;;OAEG;IACH,aAAa,CACX,eAA8C;QAE9C,MAAM,GAAG,GAAG,eAAe,CAAC,IAAI,CAAC;QAEjC,IAAI,IAAI,CAAC,eAAe,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,CAAC;YAClC,OAAO,IAAI,CAAC,eAAe,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;QACvC,CAAC;QAED,MAAM,IAAI,GAAG,IAAI,CAAC,gBAAgB,CAAC,eAAe,CAAC,CAAC;QACpD,IAAI,CAAC,eAAe,CAAC,GAAG,CAAC,GAAG,EAAE,IAAI,CAAC,CAAC;QACpC,OAAO,IAAI,CAAC;IACd,CAAC;CAQF;AAED;;GAEG;AACH,MAAM,OAAgB,sBAAsB;IAA5C;QACY,cAAS,GAAG,IAAI,CAAC;IAY7B,CAAC;IAPC,QAAQ;QACN,OAAO,IAAI,CAAC,SAAS,CAAC;IACxB,CAAC;IAES,YAAY;QACpB,IAAI,CAAC,SAAS,GAAG,KAAK,CAAC;IACzB,CAAC;CACF;AAED;;GAEG;AACH,MAAM,OAAO,kBAAmB,SAAQ,UAAU;IAAlD;;QACU,cAAS,GAAG,KAAK,CAAC;QAClB,eAAU,GAAG,KAAK,CAAC;IAwB7B,CAAC;IAtBC,KAAK,CAAC,KAAK;QACT,IAAI,CAAC,cAAc,GAAG,IAAI,0BAA0B,EAAE,CAAC;QACvD,IAAI,CAAC,SAAS,GAAG,KAAK,CAAC;QACvB,IAAI,CAAC,UAAU,GAAG,KAAK,CAAC;QACxB,OAAO,IAAI,CAAC,cAAc,CAAC;IAC7B,CAAC;IAES,gBAAgB,CACxB,eAA8C;QAE9C,4CAA4C;QAC5C,kDAAkD;QAClD,OAAO,IAAI,eAAe,EAAE,CAAC;IAC/B,CAAC;IAED,WAAW;QACT,OAAO,IAAI,CAAC,SAAS,CAAC;IACxB,CAAC;IAED,YAAY;QACV,OAAO,IAAI,CAAC,UAAU,CAAC;IACzB,CAAC;CACF;AAED,MAAM,0BAA2B,SAAQ,sBAAsB;IAC7D,KAAK,CAAC,MAAM;QACV,IAAI,CAAC,YAAY,EAAE,CAAC;IACtB,CAAC;IAED,KAAK,CAAC,QAAQ;QACZ,IAAI,CAAC,YAAY,EAAE,CAAC;IACtB,CAAC;CACF"}
@@ -0,0 +1,2 @@
1
+ export * from "./repository/index";
2
+ //# sourceMappingURL=repository.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"repository.d.ts","sourceRoot":"","sources":["../src/repository.ts"],"names":[],"mappings":"AAIA,cAAc,oBAAoB,CAAC"}
@@ -0,0 +1,21 @@
1
+ "use strict";
2
+ // ============================================================================
3
+ // Repository - Main export (backward compatibility)
4
+ // ============================================================================
5
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
6
+ if (k2 === undefined) k2 = k;
7
+ var desc = Object.getOwnPropertyDescriptor(m, k);
8
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
9
+ desc = { enumerable: true, get: function() { return m[k]; } };
10
+ }
11
+ Object.defineProperty(o, k2, desc);
12
+ }) : (function(o, m, k, k2) {
13
+ if (k2 === undefined) k2 = k;
14
+ o[k2] = m[k];
15
+ }));
16
+ var __exportStar = (this && this.__exportStar) || function(m, exports) {
17
+ for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
18
+ };
19
+ Object.defineProperty(exports, "__esModule", { value: true });
20
+ __exportStar(require("./repository/index"), exports);
21
+ //# sourceMappingURL=repository.js.map