@hexaijs/core 0.4.0 → 0.5.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.
Files changed (73) hide show
  1. package/dist/{message.d.ts → event-store-BDib72ud.d.ts} +19 -7
  2. package/dist/index.d.ts +67 -5
  3. package/dist/index.js +202 -19
  4. package/dist/index.js.map +1 -1
  5. package/dist/test/index.d.ts +38 -7
  6. package/dist/test/index.js +304 -42
  7. package/dist/test/index.js.map +1 -1
  8. package/package.json +6 -7
  9. package/dist/config.d.ts +0 -2
  10. package/dist/config.d.ts.map +0 -1
  11. package/dist/config.js +0 -5
  12. package/dist/config.js.map +0 -1
  13. package/dist/domain/aggregate-root.d.ts +0 -11
  14. package/dist/domain/aggregate-root.d.ts.map +0 -1
  15. package/dist/domain/aggregate-root.js +0 -21
  16. package/dist/domain/aggregate-root.js.map +0 -1
  17. package/dist/domain/domain-error.d.ts +0 -11
  18. package/dist/domain/domain-error.d.ts.map +0 -1
  19. package/dist/domain/domain-error.js +0 -25
  20. package/dist/domain/domain-error.js.map +0 -1
  21. package/dist/domain/domain-event.d.ts +0 -5
  22. package/dist/domain/domain-event.d.ts.map +0 -1
  23. package/dist/domain/domain-event.js +0 -11
  24. package/dist/domain/domain-event.js.map +0 -1
  25. package/dist/domain/identifiable.d.ts +0 -11
  26. package/dist/domain/identifiable.d.ts.map +0 -1
  27. package/dist/domain/identifiable.js +0 -18
  28. package/dist/domain/identifiable.js.map +0 -1
  29. package/dist/domain/index.d.ts +0 -6
  30. package/dist/domain/index.d.ts.map +0 -1
  31. package/dist/domain/index.js +0 -22
  32. package/dist/domain/index.js.map +0 -1
  33. package/dist/domain/repository.d.ts +0 -16
  34. package/dist/domain/repository.d.ts.map +0 -1
  35. package/dist/domain/repository.js +0 -25
  36. package/dist/domain/repository.js.map +0 -1
  37. package/dist/event-store.d.ts +0 -13
  38. package/dist/event-store.d.ts.map +0 -1
  39. package/dist/event-store.js +0 -3
  40. package/dist/event-store.js.map +0 -1
  41. package/dist/index.d.ts.map +0 -1
  42. package/dist/message.d.ts.map +0 -1
  43. package/dist/message.js +0 -120
  44. package/dist/message.js.map +0 -1
  45. package/dist/test/dummy-message.d.ts +0 -8
  46. package/dist/test/dummy-message.d.ts.map +0 -1
  47. package/dist/test/dummy-message.js +0 -22
  48. package/dist/test/dummy-message.js.map +0 -1
  49. package/dist/test/expect.d.ts +0 -3
  50. package/dist/test/expect.d.ts.map +0 -1
  51. package/dist/test/expect.js +0 -13
  52. package/dist/test/expect.js.map +0 -1
  53. package/dist/test/in-memory-event-store.d.ts +0 -11
  54. package/dist/test/in-memory-event-store.d.ts.map +0 -1
  55. package/dist/test/in-memory-event-store.js +0 -38
  56. package/dist/test/in-memory-event-store.js.map +0 -1
  57. package/dist/test/index.d.ts.map +0 -1
  58. package/dist/test/matchers.d.ts +0 -5
  59. package/dist/test/matchers.d.ts.map +0 -1
  60. package/dist/test/matchers.js +0 -77
  61. package/dist/test/matchers.js.map +0 -1
  62. package/dist/test/partial-match.d.ts +0 -4
  63. package/dist/test/partial-match.d.ts.map +0 -1
  64. package/dist/test/partial-match.js +0 -33
  65. package/dist/test/partial-match.js.map +0 -1
  66. package/dist/test/utils.d.ts +0 -5
  67. package/dist/test/utils.d.ts.map +0 -1
  68. package/dist/test/utils.js +0 -25
  69. package/dist/test/utils.js.map +0 -1
  70. package/dist/unit-of-work.d.ts +0 -13
  71. package/dist/unit-of-work.d.ts.map +0 -1
  72. package/dist/unit-of-work.js +0 -10
  73. package/dist/unit-of-work.js.map +0 -1
@@ -1,47 +1,309 @@
1
- "use strict";
2
- var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
- if (k2 === undefined) k2 = k;
4
- var desc = Object.getOwnPropertyDescriptor(m, k);
5
- if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
- desc = { enumerable: true, get: function() { return m[k]; } };
7
- }
8
- Object.defineProperty(o, k2, desc);
9
- }) : (function(o, m, k, k2) {
10
- if (k2 === undefined) k2 = k;
11
- o[k2] = m[k];
12
- }));
13
- var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
- Object.defineProperty(o, "default", { enumerable: true, value: v });
15
- }) : function(o, v) {
16
- o["default"] = v;
1
+ import _ from 'lodash';
2
+ import { v4 } from 'uuid';
3
+
4
+ var __defProp = Object.defineProperty;
5
+ var __export = (target, all) => {
6
+ for (var name in all)
7
+ __defProp(target, name, { get: all[name], enumerable: true });
8
+ };
9
+
10
+ // src/test/matchers.ts
11
+ var matchers_exports = {};
12
+ __export(matchers_exports, {
13
+ expectMessageToMatch: () => expectMessageToMatch,
14
+ expectMessagesToBeFullyEqual: () => expectMessagesToBeFullyEqual,
15
+ expectMessagesToContain: () => expectMessagesToContain
17
16
  });
18
- var __importStar = (this && this.__importStar) || (function () {
19
- var ownKeys = function(o) {
20
- ownKeys = Object.getOwnPropertyNames || function (o) {
21
- var ar = [];
22
- for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
- return ar;
24
- };
25
- return ownKeys(o);
17
+ var anyString = /* @__PURE__ */ Symbol.for("string");
18
+ var anyDate = /* @__PURE__ */ Symbol.for("date");
19
+ function partialMatch(source, target) {
20
+ for (const key of Object.keys(target)) {
21
+ const shouldRecurse = _.isObject(source[key]) && _.isObject(target[key]);
22
+ if (shouldRecurse) {
23
+ if (!partialMatch(source[key], target[key])) {
24
+ return false;
25
+ }
26
+ } else {
27
+ if (target[key] === anyString && typeof source[key] === "string") {
28
+ continue;
29
+ }
30
+ if (target[key] === anyDate && source[key] instanceof Date) {
31
+ continue;
32
+ }
33
+ if (!_.isEqual(source[key], target[key])) {
34
+ return false;
35
+ }
36
+ }
37
+ }
38
+ return true;
39
+ }
40
+
41
+ // src/test/utils.ts
42
+ async function waitForTicks(number = 10) {
43
+ for (let i = 0; i < number; i++) {
44
+ await new Promise((resolve) => setTimeout(resolve, 0));
45
+ }
46
+ }
47
+ async function waitForMs(number = 10) {
48
+ await new Promise((resolve) => setTimeout(resolve, number));
49
+ }
50
+ async function waitFor(type = "ticks", number = 10) {
51
+ if (type === "ticks") {
52
+ await waitForTicks(number);
53
+ } else {
54
+ await waitForMs(number);
55
+ }
56
+ }
57
+
58
+ // src/test/expect.ts
59
+ var expect;
60
+ function setExpect(expectStatic) {
61
+ expect = expectStatic;
62
+ }
63
+
64
+ // src/test/matchers.ts
65
+ function expectMessagesToBeFullyEqual(messages, expectedMessages) {
66
+ const actualSummary = formatMessagesSummary(messages);
67
+ const expectedSummary = formatMessagesSummary(expectedMessages);
68
+ expect(actualSummary, "Messages should match").toEqual(expectedSummary);
69
+ for (let i = 0; i < Math.max(messages.length, expectedMessages.length); i++) {
70
+ const actual = messages[i]?.serialize();
71
+ const expected = expectedMessages[i]?.serialize();
72
+ expect(actual, `message[${i}]`).toEqual(expected);
73
+ }
74
+ }
75
+ function expectMessagesToContain(messages, expectedMessages) {
76
+ for (const message of expectedMessages) {
77
+ expectMessageToMatch(
78
+ messages,
79
+ message.getMessageType(),
80
+ message.getPayload()
81
+ );
82
+ }
83
+ }
84
+ function expectMessageToMatch(messages, messageType, payload = {}) {
85
+ const resolvedMessageType = typeof messageType === "string" ? messageType : messageType.getType();
86
+ const sameTypeMessages = messages.filter(
87
+ (msg) => msg.getMessageType() === resolvedMessageType
88
+ );
89
+ if (sameTypeMessages.length === 0) {
90
+ const availableTypes = [...new Set(messages.map((m) => m.getMessageType()))];
91
+ expect.fail(
92
+ `Message not found: "${resolvedMessageType}"
93
+
94
+ Available message types:
95
+ ` + (availableTypes.length === 0 ? " (none)" : availableTypes.map((t) => ` - ${t}`).join("\n"))
96
+ );
97
+ }
98
+ const found = sameTypeMessages.find(
99
+ (msg) => partialMatch(msg.getPayload(), payload)
100
+ );
101
+ if (!found) {
102
+ const closestMatch = findClosestMatch(sameTypeMessages, payload);
103
+ expect(
104
+ closestMatch.payload,
105
+ `Found ${sameTypeMessages.length} message(s) of type "${resolvedMessageType}", but payload did not match.
106
+ Showing closest match (${closestMatch.matchedKeys}/${closestMatch.totalKeys} keys matched):`
107
+ ).toMatchObject(payload);
108
+ }
109
+ }
110
+ function formatMessagesSummary(messages) {
111
+ return messages.map((msg) => ({
112
+ type: msg.getMessageType(),
113
+ payload: msg.getPayload()
114
+ }));
115
+ }
116
+ function findClosestMatch(messages, expectedPayload) {
117
+ const expectedKeys = Object.keys(expectedPayload);
118
+ let bestMatch = {
119
+ payload: messages[0]?.getPayload() ?? {},
120
+ matchedKeys: 0,
121
+ totalKeys: expectedKeys.length
122
+ };
123
+ for (const msg of messages) {
124
+ const actualPayload = msg.getPayload();
125
+ const matchedKeys = countMatchedKeys(actualPayload, expectedPayload);
126
+ if (matchedKeys > bestMatch.matchedKeys) {
127
+ bestMatch = { payload: actualPayload, matchedKeys, totalKeys: expectedKeys.length };
128
+ }
129
+ }
130
+ return bestMatch;
131
+ }
132
+ function countMatchedKeys(actual, expected) {
133
+ let matched = 0;
134
+ for (const key of Object.keys(expected)) {
135
+ if (_.isEqual(actual[key], expected[key])) {
136
+ matched++;
137
+ }
138
+ }
139
+ return matched;
140
+ }
141
+ var Message = class {
142
+ constructor(payload, headers = {}) {
143
+ this.payload = payload;
144
+ this.headers = Object.freeze(
145
+ this.constructor.mergeHeaders(headers)
146
+ );
147
+ if (payload && typeof payload === "object") {
148
+ Object.freeze(payload);
149
+ }
150
+ }
151
+ headers;
152
+ static getSchemaVersion() {
153
+ return this.schemaVersion ?? void 0;
154
+ }
155
+ static getType() {
156
+ return this.type ?? this.name;
157
+ }
158
+ static getIntent() {
159
+ return this.intent ?? void 0;
160
+ }
161
+ static newHeaders(...excludes) {
162
+ return generateHeaderFor(this, ...excludes);
163
+ }
164
+ static from(rawPayload, headers) {
165
+ const payload = this.deserializeRawPayload(rawPayload);
166
+ return new this(
167
+ payload,
168
+ headers ? this.deserializeRawHeaders(headers) : this.newHeaders()
169
+ );
170
+ }
171
+ static deserializeRawPayload(rawPayload) {
172
+ return rawPayload;
173
+ }
174
+ static deserializeRawHeaders(headers) {
175
+ headers.createdAt = new Date(headers.createdAt);
176
+ return headers;
177
+ }
178
+ static mergeHeaders(headers) {
179
+ return {
180
+ ...this.newHeaders(...Object.keys(headers)),
181
+ ...headers
182
+ };
183
+ }
184
+ withHeader(field, value) {
185
+ const newHeaders = { ...this.headers, [field]: value };
186
+ return new this.constructor(this.payload, newHeaders);
187
+ }
188
+ clone() {
189
+ return new this.constructor(this.payload, { ...this.headers });
190
+ }
191
+ getHeader(field) {
192
+ return this.headers[field];
193
+ }
194
+ getHeaders() {
195
+ return Object.freeze({ ...this.headers });
196
+ }
197
+ getPayload() {
198
+ return this.payload;
199
+ }
200
+ getMessageId() {
201
+ return this.headers.id;
202
+ }
203
+ getMessageType() {
204
+ return this.headers.type;
205
+ }
206
+ getSchemaVersion() {
207
+ return this.headers.schemaVersion;
208
+ }
209
+ getTimestamp() {
210
+ return this.headers.createdAt;
211
+ }
212
+ getIntent() {
213
+ return this.constructor.getIntent();
214
+ }
215
+ serialize() {
216
+ return JSON.parse(JSON.stringify(this.doSerialize()));
217
+ }
218
+ doSerialize() {
219
+ return {
220
+ headers: { ...this.headers },
221
+ payload: this.serializePayload(this.payload)
26
222
  };
27
- return function (mod) {
28
- if (mod && mod.__esModule) return mod;
29
- var result = {};
30
- if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
- __setModuleDefault(result, mod);
32
- return result;
223
+ }
224
+ serializePayload(payload) {
225
+ return payload;
226
+ }
227
+ asType(cls) {
228
+ const { headers, payload } = this.serialize();
229
+ return cls.from(payload, headers);
230
+ }
231
+ };
232
+ function generateHeaderFor(cls, ...excludes) {
233
+ const headers = {};
234
+ if (!excludes.includes("id")) {
235
+ headers.id = v4();
236
+ }
237
+ if (!excludes.includes("type")) {
238
+ headers.type = cls.getType();
239
+ }
240
+ if (!excludes.includes("intent")) {
241
+ const intent = cls.getIntent();
242
+ if (intent !== void 0) {
243
+ headers.intent = intent;
244
+ }
245
+ }
246
+ if (!excludes.includes("schemaVersion")) {
247
+ const schemaVersion = cls.getSchemaVersion();
248
+ if (schemaVersion !== void 0) {
249
+ headers.schemaVersion = schemaVersion;
250
+ }
251
+ }
252
+ if (!excludes.includes("createdAt")) {
253
+ headers.createdAt = /* @__PURE__ */ new Date();
254
+ }
255
+ return headers;
256
+ }
257
+
258
+ // src/test/dummy-message.ts
259
+ var DummyMessage = class extends Message {
260
+ static type = "test.dummy-message";
261
+ static create() {
262
+ return new this({});
263
+ }
264
+ static createMany(number) {
265
+ return _.times(number, () => this.create());
266
+ }
267
+ static from(_4, headers) {
268
+ return new this({}, headers);
269
+ }
270
+ };
271
+
272
+ // src/test/in-memory-event-store.ts
273
+ var InMemoryEventStore = class {
274
+ events = [];
275
+ async store(event) {
276
+ const position = this.events.length + 1;
277
+ const storedEvent = { position, event };
278
+ this.events.push(storedEvent);
279
+ return storedEvent;
280
+ }
281
+ async storeAll(events) {
282
+ const storedEvents = [];
283
+ for (const event of events) {
284
+ storedEvents.push(await this.store(event));
285
+ }
286
+ return storedEvents;
287
+ }
288
+ async fetch(afterPosition, limit) {
289
+ const lastPosition = await this.getLastPosition();
290
+ let filtered = this.events.filter((e) => e.position > afterPosition);
291
+ if (limit !== void 0) {
292
+ filtered = filtered.slice(0, limit);
293
+ }
294
+ return {
295
+ events: filtered,
296
+ lastPosition
33
297
  };
34
- })();
35
- var __exportStar = (this && this.__exportStar) || function(m, exports) {
36
- for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
298
+ }
299
+ async getLastPosition() {
300
+ return this.events.length;
301
+ }
302
+ clear() {
303
+ this.events = [];
304
+ }
37
305
  };
38
- Object.defineProperty(exports, "__esModule", { value: true });
39
- exports.setExpect = exports.matchers = void 0;
40
- exports.matchers = __importStar(require("./matchers"));
41
- __exportStar(require("./matchers"), exports);
42
- __exportStar(require("./dummy-message"), exports);
43
- var expect_1 = require("./expect");
44
- Object.defineProperty(exports, "setExpect", { enumerable: true, get: function () { return expect_1.setExpect; } });
45
- __exportStar(require("./utils"), exports);
46
- __exportStar(require("./in-memory-event-store"), exports);
306
+
307
+ export { DummyMessage, InMemoryEventStore, expectMessageToMatch, expectMessagesToBeFullyEqual, expectMessagesToContain, matchers_exports as matchers, partialMatch, setExpect, waitFor, waitForMs, waitForTicks };
308
+ //# sourceMappingURL=index.js.map
47
309
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/test/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA,uDAAuC;AACvC,6CAA2B;AAC3B,kDAAgC;AAChC,mCAAqC;AAA5B,mGAAA,SAAS,OAAA;AAClB,0CAAwB;AACxB,0DAAwC"}
1
+ {"version":3,"sources":["../../src/test/matchers.ts","../../src/test/partial-match.ts","../../src/test/utils.ts","../../src/test/expect.ts","../../src/message.ts","../../src/test/dummy-message.ts","../../src/test/in-memory-event-store.ts"],"names":["_","uuid"],"mappings":"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","file":"index.js","sourcesContent":["import _ from \"lodash\";\n\nimport { Message, MessageClass } from \"@/message\";\nimport { partialMatch } from \"./utils\";\nimport { expect } from \"./expect\";\n\nexport function expectMessagesToBeFullyEqual(\n messages: Message[],\n expectedMessages: Message[]\n): void {\n const actualSummary = formatMessagesSummary(messages);\n const expectedSummary = formatMessagesSummary(expectedMessages);\n\n expect(actualSummary, \"Messages should match\").toEqual(expectedSummary);\n\n for (let i = 0; i < Math.max(messages.length, expectedMessages.length); i++) {\n const actual = messages[i]?.serialize();\n const expected = expectedMessages[i]?.serialize();\n\n expect(actual, `message[${i}]`).toEqual(expected);\n }\n}\n\nexport function expectMessagesToContain(\n messages: Message[],\n expectedMessages: Message[]\n): void {\n for (const message of expectedMessages) {\n expectMessageToMatch(\n messages,\n message.getMessageType(),\n message.getPayload()\n );\n }\n}\n\nexport function expectMessageToMatch(\n messages: Message[],\n messageType: string | MessageClass<any>,\n payload: Record<string, unknown> = {}\n): void {\n const resolvedMessageType =\n typeof messageType === \"string\" ? messageType : messageType.getType();\n const sameTypeMessages = messages.filter(\n (msg) => msg.getMessageType() === resolvedMessageType\n );\n\n if (sameTypeMessages.length === 0) {\n const availableTypes = [...new Set(messages.map((m) => m.getMessageType()))];\n expect.fail(\n `Message not found: \"${resolvedMessageType}\"\\n\\n` +\n `Available message types:\\n` +\n (availableTypes.length === 0\n ? \" (none)\"\n : availableTypes.map((t) => ` - ${t}`).join(\"\\n\"))\n );\n }\n\n const found = sameTypeMessages.find((msg) =>\n partialMatch(msg.getPayload(), payload)\n );\n\n if (!found) {\n const closestMatch = findClosestMatch(sameTypeMessages, payload);\n\n expect(\n closestMatch.payload,\n `Found ${sameTypeMessages.length} message(s) of type \"${resolvedMessageType}\", ` +\n `but payload did not match.\\n` +\n `Showing closest match (${closestMatch.matchedKeys}/${closestMatch.totalKeys} keys matched):`\n ).toMatchObject(payload);\n }\n}\n\nfunction formatMessagesSummary(messages: Message[]): Array<{ type: string; payload: unknown }> {\n return messages.map((msg) => ({\n type: msg.getMessageType(),\n payload: msg.getPayload(),\n }));\n}\n\nfunction findClosestMatch(\n messages: Message[],\n expectedPayload: Record<string, unknown>\n): { payload: Record<string, unknown>; matchedKeys: number; totalKeys: number } {\n const expectedKeys = Object.keys(expectedPayload);\n let bestMatch = {\n payload: messages[0]?.getPayload() ?? {},\n matchedKeys: 0,\n totalKeys: expectedKeys.length,\n };\n\n for (const msg of messages) {\n const actualPayload = msg.getPayload();\n const matchedKeys = countMatchedKeys(actualPayload, expectedPayload);\n\n if (matchedKeys > bestMatch.matchedKeys) {\n bestMatch = { payload: actualPayload, matchedKeys, totalKeys: expectedKeys.length };\n }\n }\n\n return bestMatch;\n}\n\nfunction countMatchedKeys(\n actual: Record<string, unknown>,\n expected: Record<string, unknown>\n): number {\n let matched = 0;\n for (const key of Object.keys(expected)) {\n if (_.isEqual(actual[key], expected[key])) {\n matched++;\n }\n }\n return matched;\n}\n","import _ from \"lodash\";\n\nexport const anyString = Symbol.for(\"string\");\n\nexport const anyDate = Symbol.for(\"date\");\n\nexport function partialMatch(\n source: Record<any, any>,\n target: Record<any, any>\n): boolean {\n for (const key of Object.keys(target)) {\n const shouldRecurse =\n _.isObject(source[key]) && _.isObject(target[key]);\n\n if (shouldRecurse) {\n if (!partialMatch(source[key], target[key])) {\n return false;\n }\n } else {\n if (target[key] === anyString && typeof source[key] === \"string\") {\n continue;\n }\n\n if (target[key] === anyDate && source[key] instanceof Date) {\n continue;\n }\n\n if (!_.isEqual(source[key], target[key])) {\n return false;\n }\n }\n }\n\n return true;\n}\n","export { partialMatch } from \"./partial-match\";\n\nexport async function waitForTicks(number = 10): Promise<void> {\n for (let i = 0; i < number; i++) {\n await new Promise((resolve) => setTimeout(resolve, 0));\n }\n}\n\nexport async function waitForMs(number = 10): Promise<void> {\n await new Promise((resolve) => setTimeout(resolve, number));\n}\n\nexport async function waitFor(\n type: \"ticks\" | \"ms\" = \"ticks\",\n number = 10\n): Promise<void> {\n if (type === \"ticks\") {\n await waitForTicks(number);\n } else {\n await waitForMs(number);\n }\n}\n","import { RUNNING_HEXAI_TEST } from \"@/config\";\n\nexport let expect!: any;\n\n// if (RUNNING_HEXAI_TEST) {\n// import(\"vitest\").then(({ expect: expectStatic }) => {\n// expect = expectStatic;\n// });\n// }\n\nexport function setExpect(expectStatic: any) {\n expect = expectStatic;\n}\n","import { v4 as uuid } from \"uuid\";\n\ntype Version = string | number | undefined;\n\nexport interface MessageHeaders {\n id: string;\n type: string;\n intent?: string;\n schemaVersion?: Version;\n createdAt: Date;\n\n [key: string]: unknown;\n}\n\ntype ExtraHeaderField = Exclude<\n keyof MessageHeaders,\n \"id\" | \"type\" | \"intent\" | \"schemaVersion\" | \"createdAt\"\n>;\n\ntype RawMessageHeaders = Omit<MessageHeaders, \"createdAt\"> & {\n createdAt: string | Date;\n};\n\nexport class Message<Payload = any> {\n protected headers!: MessageHeaders;\n\n public static getSchemaVersion(): Version {\n return (this as any).schemaVersion ?? undefined;\n }\n\n public static getType(): string {\n return (this as any).type ?? this.name;\n }\n\n public static getIntent(): string | undefined {\n return (this as any).intent ?? undefined;\n }\n\n protected static newHeaders(...excludes: string[]): MessageHeaders {\n return generateHeaderFor(this as any, ...excludes);\n }\n\n public static from(\n rawPayload: Record<string, unknown>,\n headers?: RawMessageHeaders\n ): Message {\n const payload = this.deserializeRawPayload(rawPayload);\n return new this(\n payload,\n headers ? this.deserializeRawHeaders(headers) : this.newHeaders()\n );\n }\n\n protected static deserializeRawPayload(rawPayload: any): any {\n return rawPayload;\n }\n\n protected static deserializeRawHeaders(\n headers: RawMessageHeaders\n ): MessageHeaders {\n headers.createdAt = new Date(headers.createdAt);\n\n return headers as MessageHeaders;\n }\n\n constructor(\n protected readonly payload: Payload,\n headers: Record<string, unknown> = {}\n ) {\n this.headers = Object.freeze(\n (this.constructor as any).mergeHeaders(headers)\n );\n\n if (payload && typeof payload === \"object\") {\n Object.freeze(payload);\n }\n }\n\n protected static mergeHeaders(\n headers: Record<string, unknown>\n ): MessageHeaders {\n return {\n ...this.newHeaders(...Object.keys(headers)),\n ...headers,\n };\n }\n\n public withHeader(field: ExtraHeaderField, value: unknown): this {\n const newHeaders = { ...this.headers, [field]: value };\n return new (this.constructor as any)(this.payload, newHeaders);\n }\n\n protected clone(): this {\n return new (this.constructor as any)(this.payload, { ...this.headers });\n }\n\n public getHeader<T = string>(field: string): T | undefined {\n return this.headers[field] as any;\n }\n\n public getHeaders(): MessageHeaders {\n return Object.freeze({ ...this.headers });\n }\n\n public getPayload(): Payload {\n return this.payload;\n }\n\n public getMessageId(): string {\n return this.headers.id;\n }\n\n public getMessageType(): string {\n return this.headers.type;\n }\n\n public getSchemaVersion(): Version | undefined {\n return this.headers.schemaVersion;\n }\n\n public getTimestamp(): Date {\n return this.headers.createdAt;\n }\n\n public getIntent(): string | undefined {\n return (this.constructor as MessageClass).getIntent();\n }\n\n public serialize(): {\n headers: MessageHeaders;\n payload: Record<string, unknown>;\n } {\n // we do this to convert the Date object to a string\n // and also to remove any reference to the original object\n return JSON.parse(JSON.stringify(this.doSerialize()));\n }\n\n private doSerialize(): {\n headers: MessageHeaders;\n payload: unknown;\n } {\n return {\n headers: { ...this.headers },\n payload: this.serializePayload(this.payload),\n };\n }\n\n protected serializePayload(payload: Payload): unknown {\n return payload;\n }\n\n public asType<M extends MessageClass>(cls: M): InstanceType<M> {\n const { headers, payload } = this.serialize();\n return cls.from(payload, headers) as InstanceType<M>;\n }\n}\n\nexport type AnyMessage = Message;\n\nexport type MessageClass<T extends Message = Message> = {\n getSchemaVersion(): Version;\n getType(): string;\n getIntent(): string | undefined;\n from: (rawPayload: any, header?: MessageHeaders) => T;\n new (...args: any[]): T;\n};\n\nfunction generateHeaderFor(\n cls: MessageClass,\n ...excludes: string[]\n): MessageHeaders {\n const headers: Partial<MessageHeaders> = {};\n\n if (!excludes.includes(\"id\")) {\n headers.id = uuid();\n }\n\n if (!excludes.includes(\"type\")) {\n headers.type = cls.getType();\n }\n\n if (!excludes.includes(\"intent\")) {\n const intent = cls.getIntent();\n if (intent !== undefined) {\n headers.intent = intent;\n }\n }\n\n if (!excludes.includes(\"schemaVersion\")) {\n const schemaVersion = cls.getSchemaVersion();\n if (schemaVersion !== undefined) {\n headers.schemaVersion = schemaVersion;\n }\n }\n\n if (!excludes.includes(\"createdAt\")) {\n headers.createdAt = new Date();\n }\n\n return headers as MessageHeaders;\n}\n\nexport type PayloadOf<M> = M extends Message<infer P> ? P : never;\n","import _ from \"lodash\";\n\nimport { Message, MessageHeaders } from \"@/message\";\n\nexport class DummyMessage extends Message<Record<never, never>> {\n static type = \"test.dummy-message\";\n\n public static create() {\n return new this({});\n }\n\n public static createMany(number: number) {\n return _.times(number, () => this.create());\n }\n\n public static from(\n _: Record<never, never>,\n headers?: MessageHeaders\n ): DummyMessage {\n return new this({}, headers);\n }\n}\n","import { EventStore, EventStoreFetchResult, StoredEvent } from \"@/event-store\";\nimport { Message } from \"@/message\";\n\nexport class InMemoryEventStore implements EventStore {\n private events: StoredEvent[] = [];\n\n async store(event: Message): Promise<StoredEvent> {\n const position = this.events.length + 1;\n const storedEvent: StoredEvent = { position, event };\n this.events.push(storedEvent);\n return storedEvent;\n }\n\n async storeAll(events: Message[]): Promise<StoredEvent[]> {\n const storedEvents: StoredEvent[] = [];\n for (const event of events) {\n storedEvents.push(await this.store(event));\n }\n return storedEvents;\n }\n\n async fetch(\n afterPosition: number,\n limit?: number\n ): Promise<EventStoreFetchResult> {\n const lastPosition = await this.getLastPosition();\n let filtered = this.events.filter((e) => e.position > afterPosition);\n\n if (limit !== undefined) {\n filtered = filtered.slice(0, limit);\n }\n\n return {\n events: filtered,\n lastPosition,\n };\n }\n\n async getLastPosition(): Promise<number> {\n return this.events.length;\n }\n\n clear(): void {\n this.events = [];\n }\n}\n"]}
package/package.json CHANGED
@@ -3,7 +3,8 @@
3
3
  "publishConfig": {
4
4
  "access": "public"
5
5
  },
6
- "version": "0.4.0",
6
+ "version": "0.5.0",
7
+ "type": "module",
7
8
  "description": "Core utilities/types/base classes for hexai projects",
8
9
  "license": "MIT",
9
10
  "author": "Sangwoo Hyun <wkdny.hyun@gmail.com>",
@@ -36,26 +37,24 @@
36
37
  "exports": {
37
38
  ".": {
38
39
  "types": "./dist/index.d.ts",
39
- "import": "./dist/index.js",
40
- "require": "./dist/index.js"
40
+ "import": "./dist/index.js"
41
41
  },
42
42
  "./test": {
43
43
  "types": "./dist/test/index.d.ts",
44
- "import": "./dist/test/index.js",
45
- "require": "./dist/test/index.js"
44
+ "import": "./dist/test/index.js"
46
45
  },
47
46
  "./package.json": "./package.json"
48
47
  },
49
48
  "scripts": {
50
49
  "test": "vitest run",
51
- "build": "pnpm clean && tsc -p ./tsconfig.build.json && tsc-alias",
52
- "clean": "rm -rf dist"
50
+ "build": "tsup"
53
51
  },
54
52
  "dependencies": {
55
53
  "lodash": "^4.17.21",
56
54
  "uuid": "^9.0.1"
57
55
  },
58
56
  "devDependencies": {
57
+ "@hexaijs/tooling": "workspace:*",
59
58
  "@types/uuid": "^9.0.8"
60
59
  }
61
60
  }
package/dist/config.d.ts DELETED
@@ -1,2 +0,0 @@
1
- export declare const RUNNING_HEXAI_TEST: boolean;
2
- //# sourceMappingURL=config.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,kBAAkB,SAAoC,CAAC"}
package/dist/config.js DELETED
@@ -1,5 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.RUNNING_HEXAI_TEST = void 0;
4
- exports.RUNNING_HEXAI_TEST = !!process.env.RUNNING_HEXAI_TESTS;
5
- //# sourceMappingURL=config.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":";;;AAAa,QAAA,kBAAkB,GAAG,CAAC,CAAC,OAAO,CAAC,GAAG,CAAC,mBAAmB,CAAC"}
@@ -1,11 +0,0 @@
1
- import { DomainEvent } from "./domain-event";
2
- import { Id, Identifiable } from "./identifiable";
3
- export declare class AggregateRoot<T extends Id<string | number>> implements Identifiable<T> {
4
- protected readonly id: T;
5
- protected events: DomainEvent[];
6
- constructor(id: T);
7
- getId(): T;
8
- protected raise(event: DomainEvent): void;
9
- getEventsOccurred(): DomainEvent[];
10
- }
11
- //# sourceMappingURL=aggregate-root.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"aggregate-root.d.ts","sourceRoot":"","sources":["../../src/domain/aggregate-root.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAC;AAC7C,OAAO,EAAE,EAAE,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAElD,qBAAa,aAAa,CAAC,CAAC,SAAS,EAAE,CAAC,MAAM,GAAG,MAAM,CAAC,CACpD,YAAW,YAAY,CAAC,CAAC,CAAC;IAId,SAAS,CAAC,QAAQ,CAAC,EAAE,EAAE,CAAC;IAFpC,SAAS,CAAC,MAAM,EAAE,WAAW,EAAE,CAAM;gBAEN,EAAE,EAAE,CAAC;IAE7B,KAAK,IAAI,CAAC;IAIjB,SAAS,CAAC,KAAK,CAAC,KAAK,EAAE,WAAW,GAAG,IAAI;IAIlC,iBAAiB,IAAI,WAAW,EAAE;CAG5C"}
@@ -1,21 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.AggregateRoot = void 0;
4
- class AggregateRoot {
5
- id;
6
- events = [];
7
- constructor(id) {
8
- this.id = id;
9
- }
10
- getId() {
11
- return this.id;
12
- }
13
- raise(event) {
14
- this.events.push(event);
15
- }
16
- getEventsOccurred() {
17
- return [...this.events];
18
- }
19
- }
20
- exports.AggregateRoot = AggregateRoot;
21
- //# sourceMappingURL=aggregate-root.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"aggregate-root.js","sourceRoot":"","sources":["../../src/domain/aggregate-root.ts"],"names":[],"mappings":";;;AAGA,MAAa,aAAa;IAKS;IAFrB,MAAM,GAAkB,EAAE,CAAC;IAErC,YAA+B,EAAK;QAAL,OAAE,GAAF,EAAE,CAAG;IAAG,CAAC;IAEjC,KAAK;QACR,OAAO,IAAI,CAAC,EAAE,CAAC;IACnB,CAAC;IAES,KAAK,CAAC,KAAkB;QAC9B,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;IAC5B,CAAC;IAEM,iBAAiB;QACpB,OAAO,CAAC,GAAG,IAAI,CAAC,MAAM,CAAC,CAAC;IAC5B,CAAC;CACJ;AAlBD,sCAkBC"}
@@ -1,11 +0,0 @@
1
- export declare class DomainError extends Error {
2
- }
3
- export declare class InvariantNotSatisfiedError extends DomainError {
4
- readonly code: string;
5
- constructor(code: string, message?: string);
6
- }
7
- export declare class ValidationError extends InvariantNotSatisfiedError {
8
- readonly field: string;
9
- constructor(field: string, code: string, message?: string);
10
- }
11
- //# sourceMappingURL=domain-error.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"domain-error.d.ts","sourceRoot":"","sources":["../../src/domain/domain-error.ts"],"names":[],"mappings":"AAAA,qBAAa,WAAY,SAAQ,KAAK;CAAG;AAEzC,qBAAa,0BAA2B,SAAQ,WAAW;aAEnC,IAAI,EAAE,MAAM;gBAAZ,IAAI,EAAE,MAAM,EAC5B,OAAO,GAAE,MAAW;CAK3B;AAED,qBAAa,eAAgB,SAAQ,0BAA0B;aAEvC,KAAK,EAAE,MAAM;gBAAb,KAAK,EAAE,MAAM,EAC7B,IAAI,EAAE,MAAM,EACZ,OAAO,GAAE,MAAW;CAM3B"}
@@ -1,25 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.ValidationError = exports.InvariantNotSatisfiedError = exports.DomainError = void 0;
4
- class DomainError extends Error {
5
- }
6
- exports.DomainError = DomainError;
7
- class InvariantNotSatisfiedError extends DomainError {
8
- code;
9
- constructor(code, message = "") {
10
- super(message);
11
- this.code = code;
12
- this.name = "InvariantNotSatisfiedError";
13
- }
14
- }
15
- exports.InvariantNotSatisfiedError = InvariantNotSatisfiedError;
16
- class ValidationError extends InvariantNotSatisfiedError {
17
- field;
18
- constructor(field, code, message = "") {
19
- super(code, message);
20
- this.field = field;
21
- this.name = "ValidationError";
22
- }
23
- }
24
- exports.ValidationError = ValidationError;
25
- //# sourceMappingURL=domain-error.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"domain-error.js","sourceRoot":"","sources":["../../src/domain/domain-error.ts"],"names":[],"mappings":";;;AAAA,MAAa,WAAY,SAAQ,KAAK;CAAG;AAAzC,kCAAyC;AAEzC,MAAa,0BAA2B,SAAQ,WAAW;IAEnC;IADpB,YACoB,IAAY,EAC5B,UAAkB,EAAE;QAEpB,KAAK,CAAC,OAAO,CAAC,CAAC;QAHC,SAAI,GAAJ,IAAI,CAAQ;QAI5B,IAAI,CAAC,IAAI,GAAG,4BAA4B,CAAC;IAC7C,CAAC;CACJ;AARD,gEAQC;AAED,MAAa,eAAgB,SAAQ,0BAA0B;IAEvC;IADpB,YACoB,KAAa,EAC7B,IAAY,EACZ,UAAkB,EAAE;QAEpB,KAAK,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC;QAJL,UAAK,GAAL,KAAK,CAAQ;QAM7B,IAAI,CAAC,IAAI,GAAG,iBAAiB,CAAC;IAClC,CAAC;CACJ;AAVD,0CAUC"}
@@ -1,5 +0,0 @@
1
- import { Message } from "@/message";
2
- export declare class DomainEvent<P extends Record<string, any> = Record<string, unknown>> extends Message<P> {
3
- static getIntent(): string;
4
- }
5
- //# sourceMappingURL=domain-event.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"domain-event.d.ts","sourceRoot":"","sources":["../../src/domain/domain-event.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAEpC,qBAAa,WAAW,CACpB,CAAC,SAAS,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CACzD,SAAQ,OAAO,CAAC,CAAC,CAAC;WACA,SAAS;CAG5B"}
@@ -1,11 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.DomainEvent = void 0;
4
- const message_1 = require("@/message");
5
- class DomainEvent extends message_1.Message {
6
- static getIntent() {
7
- return "event";
8
- }
9
- }
10
- exports.DomainEvent = DomainEvent;
11
- //# sourceMappingURL=domain-event.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"domain-event.js","sourceRoot":"","sources":["../../src/domain/domain-event.ts"],"names":[],"mappings":";;;AAAA,uCAAoC;AAEpC,MAAa,WAEX,SAAQ,iBAAU;IAChB,MAAM,CAAU,SAAS;QACrB,OAAO,OAAO,CAAC;IACnB,CAAC;CACJ;AAND,kCAMC"}
@@ -1,11 +0,0 @@
1
- export declare class Id<T extends string | number> {
2
- private readonly value;
3
- constructor(value: T);
4
- getValue(): T;
5
- equals(other: Id<T>): boolean;
6
- }
7
- export type IdOf<T> = T extends Identifiable<infer Id> ? Id : never;
8
- export interface Identifiable<T extends Id<string | number> = Id<string>> {
9
- getId(): T;
10
- }
11
- //# sourceMappingURL=identifiable.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"identifiable.d.ts","sourceRoot":"","sources":["../../src/domain/identifiable.ts"],"names":[],"mappings":"AAAA,qBAAa,EAAE,CAAC,CAAC,SAAS,MAAM,GAAG,MAAM;IAClB,OAAO,CAAC,QAAQ,CAAC,KAAK;gBAAL,KAAK,EAAE,CAAC;IAErC,QAAQ,IAAI,CAAC;IAIb,MAAM,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC,CAAC,GAAG,OAAO;CAMvC;AAED,MAAM,MAAM,IAAI,CAAC,CAAC,IAAI,CAAC,SAAS,YAAY,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,GAAG,KAAK,CAAC;AAEpE,MAAM,WAAW,YAAY,CAAC,CAAC,SAAS,EAAE,CAAC,MAAM,GAAG,MAAM,CAAC,GAAG,EAAE,CAAC,MAAM,CAAC;IACpE,KAAK,IAAI,CAAC,CAAC;CACd"}
@@ -1,18 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.Id = void 0;
4
- class Id {
5
- value;
6
- constructor(value) {
7
- this.value = value;
8
- }
9
- getValue() {
10
- return this.value;
11
- }
12
- equals(other) {
13
- return (this.constructor === other.constructor &&
14
- this.getValue() === other.getValue());
15
- }
16
- }
17
- exports.Id = Id;
18
- //# sourceMappingURL=identifiable.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"identifiable.js","sourceRoot":"","sources":["../../src/domain/identifiable.ts"],"names":[],"mappings":";;;AAAA,MAAa,EAAE;IACyB;IAApC,YAAoC,KAAQ;QAAR,UAAK,GAAL,KAAK,CAAG;IAAG,CAAC;IAEzC,QAAQ;QACX,OAAO,IAAI,CAAC,KAAK,CAAC;IACtB,CAAC;IAEM,MAAM,CAAC,KAAY;QACtB,OAAO,CACH,IAAI,CAAC,WAAW,KAAK,KAAK,CAAC,WAAW;YACtC,IAAI,CAAC,QAAQ,EAAE,KAAK,KAAK,CAAC,QAAQ,EAAE,CACvC,CAAC;IACN,CAAC;CACJ;AAbD,gBAaC"}
@@ -1,6 +0,0 @@
1
- export * from "./aggregate-root";
2
- export * from "./domain-error";
3
- export * from "./domain-event";
4
- export * from "./identifiable";
5
- export * from "./repository";
6
- //# sourceMappingURL=index.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/domain/index.ts"],"names":[],"mappings":"AAAA,cAAc,kBAAkB,CAAC;AACjC,cAAc,gBAAgB,CAAC;AAC/B,cAAc,gBAAgB,CAAC;AAC/B,cAAc,gBAAgB,CAAC;AAC/B,cAAc,cAAc,CAAC"}