@arts-n-crafts/ts 3.19.0 → 5.0.0-rc.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.
Files changed (79) hide show
  1. package/README.md +221 -6
  2. package/package.json +109 -22
  3. package/packages/v3/dist/index.cjs +63 -72
  4. package/packages/v3/dist/index.cjs.map +1 -1
  5. package/packages/v3/dist/index.d.cts +22 -22
  6. package/packages/v3/dist/index.d.ts +22 -22
  7. package/packages/v3/dist/index.js +63 -72
  8. package/packages/v3/dist/index.js.map +1 -1
  9. package/packages/v3/package.json +49 -50
  10. package/packages/v4/dist/index.cjs +71 -126
  11. package/packages/v4/dist/index.cjs.map +1 -1
  12. package/packages/v4/dist/index.d.cts +36 -47
  13. package/packages/v4/dist/index.d.ts +36 -47
  14. package/packages/v4/dist/index.js +72 -125
  15. package/packages/v4/dist/index.js.map +1 -1
  16. package/packages/v4/package.json +49 -50
  17. package/packages/v5/dist/DomainEvent-CSzUMw46.d.cts +23 -0
  18. package/packages/v5/dist/DomainEvent-w1jyCjai.d.ts +23 -0
  19. package/packages/v5/dist/Intent-B6l0bHZU.d.cts +13 -0
  20. package/packages/v5/dist/Intent-BLNY6RoG.d.ts +13 -0
  21. package/packages/v5/dist/Message-c9XdBoh4.d.cts +36 -0
  22. package/packages/v5/dist/Message-c9XdBoh4.d.ts +36 -0
  23. package/packages/v5/dist/Rejection-D9PlzquK.d.cts +19 -0
  24. package/packages/v5/dist/Rejection-D9PlzquK.d.ts +19 -0
  25. package/packages/v5/dist/adapters/outbound/capabilities/index.cjs +4 -0
  26. package/packages/v5/dist/adapters/outbound/capabilities/index.cjs.map +1 -0
  27. package/packages/v5/dist/adapters/outbound/capabilities/index.d.cts +77 -0
  28. package/packages/v5/dist/adapters/outbound/capabilities/index.d.ts +77 -0
  29. package/packages/v5/dist/adapters/outbound/capabilities/index.js +3 -0
  30. package/packages/v5/dist/adapters/outbound/capabilities/index.js.map +1 -0
  31. package/packages/v5/dist/adapters/outbound/shapes/index.cjs +4 -0
  32. package/packages/v5/dist/adapters/outbound/shapes/index.cjs.map +1 -0
  33. package/packages/v5/dist/adapters/outbound/shapes/index.d.cts +68 -0
  34. package/packages/v5/dist/adapters/outbound/shapes/index.d.ts +68 -0
  35. package/packages/v5/dist/adapters/outbound/shapes/index.js +3 -0
  36. package/packages/v5/dist/adapters/outbound/shapes/index.js.map +1 -0
  37. package/packages/v5/dist/core/capabilities/index.cjs +4 -0
  38. package/packages/v5/dist/core/capabilities/index.cjs.map +1 -0
  39. package/packages/v5/dist/core/capabilities/index.d.cts +33 -0
  40. package/packages/v5/dist/core/capabilities/index.d.ts +33 -0
  41. package/packages/v5/dist/core/capabilities/index.js +3 -0
  42. package/packages/v5/dist/core/capabilities/index.js.map +1 -0
  43. package/packages/v5/dist/core/shapes/index.cjs +4 -0
  44. package/packages/v5/dist/core/shapes/index.cjs.map +1 -0
  45. package/packages/v5/dist/core/shapes/index.d.cts +27 -0
  46. package/packages/v5/dist/core/shapes/index.d.ts +27 -0
  47. package/packages/v5/dist/core/shapes/index.js +3 -0
  48. package/packages/v5/dist/core/shapes/index.js.map +1 -0
  49. package/packages/v5/dist/useCases/command/capabilities/index.cjs +4 -0
  50. package/packages/v5/dist/useCases/command/capabilities/index.cjs.map +1 -0
  51. package/packages/v5/dist/useCases/command/capabilities/index.d.cts +27 -0
  52. package/packages/v5/dist/useCases/command/capabilities/index.d.ts +27 -0
  53. package/packages/v5/dist/useCases/command/capabilities/index.js +3 -0
  54. package/packages/v5/dist/useCases/command/capabilities/index.js.map +1 -0
  55. package/packages/v5/dist/useCases/command/shapes/index.cjs +4 -0
  56. package/packages/v5/dist/useCases/command/shapes/index.cjs.map +1 -0
  57. package/packages/v5/dist/useCases/command/shapes/index.d.cts +78 -0
  58. package/packages/v5/dist/useCases/command/shapes/index.d.ts +78 -0
  59. package/packages/v5/dist/useCases/command/shapes/index.js +3 -0
  60. package/packages/v5/dist/useCases/command/shapes/index.js.map +1 -0
  61. package/packages/v5/dist/useCases/policy/capabilities/index.cjs +4 -0
  62. package/packages/v5/dist/useCases/policy/capabilities/index.cjs.map +1 -0
  63. package/packages/v5/dist/useCases/policy/capabilities/index.d.cts +12 -0
  64. package/packages/v5/dist/useCases/policy/capabilities/index.d.ts +12 -0
  65. package/packages/v5/dist/useCases/policy/capabilities/index.js +3 -0
  66. package/packages/v5/dist/useCases/policy/capabilities/index.js.map +1 -0
  67. package/packages/v5/dist/useCases/query/capabilities/index.cjs +4 -0
  68. package/packages/v5/dist/useCases/query/capabilities/index.cjs.map +1 -0
  69. package/packages/v5/dist/useCases/query/capabilities/index.d.cts +8 -0
  70. package/packages/v5/dist/useCases/query/capabilities/index.d.ts +8 -0
  71. package/packages/v5/dist/useCases/query/capabilities/index.js +3 -0
  72. package/packages/v5/dist/useCases/query/capabilities/index.js.map +1 -0
  73. package/packages/v5/dist/useCases/query/shapes/index.cjs +4 -0
  74. package/packages/v5/dist/useCases/query/shapes/index.cjs.map +1 -0
  75. package/packages/v5/dist/useCases/query/shapes/index.d.cts +7 -0
  76. package/packages/v5/dist/useCases/query/shapes/index.d.ts +7 -0
  77. package/packages/v5/dist/useCases/query/shapes/index.js +3 -0
  78. package/packages/v5/dist/useCases/query/shapes/index.js.map +1 -0
  79. package/packages/v5/package.json +59 -0
@@ -27,23 +27,17 @@ function createQuery(type, payload, metadata = {}) {
27
27
 
28
28
  // src/core/utils/isCommand.ts
29
29
  function isCommand(candidate) {
30
- if (candidate === null)
31
- return false;
32
- if (typeof candidate !== "object")
33
- return false;
34
- if (!("type" in candidate))
35
- return false;
30
+ if (candidate === null) return false;
31
+ if (typeof candidate !== "object") return false;
32
+ if (!("type" in candidate)) return false;
36
33
  return "kind" in candidate && candidate.kind === "command";
37
34
  }
38
35
 
39
36
  // src/core/utils/isQuery.ts
40
37
  function isQuery(candidate) {
41
- if (candidate === null)
42
- return false;
43
- if (typeof candidate !== "object")
44
- return false;
45
- if (!("type" in candidate))
46
- return false;
38
+ if (candidate === null) return false;
39
+ if (typeof candidate !== "object") return false;
40
+ if (!("type" in candidate)) return false;
47
41
  return "kind" in candidate && candidate.kind === "query";
48
42
  }
49
43
 
@@ -146,8 +140,7 @@ function fail(anExpression) {
146
140
 
147
141
  // src/utils/invariant/invariant.ts
148
142
  function invariant(condition, onInvalid) {
149
- if (!condition)
150
- onInvalid();
143
+ if (!condition) onInvalid();
151
144
  }
152
145
 
153
146
  // src/domain/Specification/implementations/FieldGreaterThan.specification.ts
@@ -164,9 +157,7 @@ var FieldGreaterThan = class extends Specification {
164
157
  const field = entity[this.field];
165
158
  invariant(
166
159
  this.isNumber(field),
167
- fail(
168
- new TypeError(`Field ${String(this.field)} is not a number`)
169
- )
160
+ fail(new TypeError(`Field ${String(this.field)} is not a number`))
170
161
  );
171
162
  return field > this.value;
172
163
  }
@@ -188,12 +179,9 @@ function createDomainEvent(type, aggregateId, payload, metadata = {}) {
188
179
 
189
180
  // src/domain/utils/isEvent.ts
190
181
  function isEvent(event) {
191
- if (typeof event !== "object")
192
- return false;
193
- if (event === null)
194
- return false;
195
- if (!("type" in event))
196
- return false;
182
+ if (typeof event !== "object") return false;
183
+ if (event === null) return false;
184
+ if (!("type" in event)) return false;
197
185
  return "source" in event;
198
186
  }
199
187
 
@@ -251,43 +239,36 @@ var SimpleDatabase = class {
251
239
  datasource = /* @__PURE__ */ new Map();
252
240
  simulateOffline = false;
253
241
  async query(tableName, specification) {
254
- if (this.simulateOffline)
255
- throw new DatabaseOfflineException();
242
+ if (this.simulateOffline) throw new DatabaseOfflineException();
256
243
  const tableRecords = this.datasource.get(tableName) || [];
257
244
  return tableRecords.filter((record) => specification.isSatisfiedBy(record));
258
245
  }
259
246
  async execute(tableName, statement) {
260
- if (this.simulateOffline)
261
- throw new DatabaseOfflineException();
262
- if (!this.datasource.has(tableName))
263
- this.datasource.set(tableName, []);
247
+ if (this.simulateOffline) throw new DatabaseOfflineException();
248
+ if (!this.datasource.has(tableName)) this.datasource.set(tableName, []);
264
249
  const table = this.datasource.get(tableName);
265
250
  switch (statement.operation) {
266
251
  case "CREATE" /* CREATE */: {
267
252
  const isDuplicate = table.some((item) => item.id === statement.payload.id);
268
- if (isDuplicate)
269
- throw new DuplicateRecordException(statement.payload.id);
253
+ if (isDuplicate) throw new DuplicateRecordException(statement.payload.id);
270
254
  table.push(statement.payload);
271
255
  break;
272
256
  }
273
257
  case "PUT" /* PUT */: {
274
258
  const index = table.findIndex((item) => item.id === statement.payload.id);
275
- if (index === -1)
276
- throw new RecordNotFoundException(statement.payload.id);
259
+ if (index === -1) throw new RecordNotFoundException(statement.payload.id);
277
260
  table[index] = statement.payload;
278
261
  break;
279
262
  }
280
263
  case "PATCH" /* PATCH */: {
281
264
  const index = table.findIndex((item) => item.id === statement.payload.id);
282
- if (index === -1)
283
- throw new RecordNotFoundException(statement.payload.id);
265
+ if (index === -1) throw new RecordNotFoundException(statement.payload.id);
284
266
  table[index] = { ...table[index], ...statement.payload };
285
267
  break;
286
268
  }
287
269
  case "DELETE" /* DELETE */: {
288
270
  const index = table.findIndex((item) => item.id === statement.payload.id);
289
- if (index === -1)
290
- throw new RecordNotFoundException(statement.payload.id);
271
+ if (index === -1) throw new RecordNotFoundException(statement.payload.id);
291
272
  table.splice(index, 1);
292
273
  break;
293
274
  }
@@ -307,12 +288,13 @@ var SimpleEventBus = class {
307
288
  this.handlers.set(stream, handlersForType);
308
289
  }
309
290
  async consume(stream, anEvent) {
310
- if (!this.handlers.has(stream))
311
- return;
291
+ if (!this.handlers.has(stream)) return;
312
292
  const handlers = this.handlers.get(stream);
313
- await Promise.all(handlers.map(async (handler) => {
314
- return handler.handle(anEvent);
315
- }));
293
+ await Promise.all(
294
+ handlers.map(async (handler) => {
295
+ return handler.handle(anEvent);
296
+ })
297
+ );
316
298
  }
317
299
  async publish(stream, anEvent) {
318
300
  await this.consume(stream, anEvent);
@@ -374,11 +356,12 @@ var SimpleEventStore = class {
374
356
  }
375
357
  async append(streamName, events) {
376
358
  const uniqueAggregateIds = new Set(events.map((event2) => event2.aggregateId));
377
- if (uniqueAggregateIds.size > 1)
378
- throw new MultipleAggregatesException();
359
+ if (uniqueAggregateIds.size > 1) throw new MultipleAggregatesException();
379
360
  const event = events[0];
380
361
  const currentStream = await this.load(streamName, event.aggregateId);
381
- const eventsToStore = events.map((event2) => createStoredEvent(streamName, currentStream.length + 1, event2));
362
+ const eventsToStore = events.map(
363
+ (event2) => createStoredEvent(streamName, currentStream.length + 1, event2)
364
+ );
382
365
  await Promise.all(
383
366
  eventsToStore.map(
384
367
  async (payload) => this.database.execute(this.tableName, { operation: "CREATE" /* CREATE */, payload })
@@ -397,14 +380,16 @@ var GenericOutboxWorker = class {
397
380
  }
398
381
  async runOnce() {
399
382
  const pending = await this.outbox.getPending();
400
- await Promise.all(pending.map(async (entry) => {
401
- try {
402
- await this.eventBus.publish(this.stream, entry.event);
403
- await this.outbox.markAsPublished(entry.id);
404
- } catch {
405
- await this.outbox.markAsFailed(entry.id);
406
- }
407
- }));
383
+ await Promise.all(
384
+ pending.map(async (entry) => {
385
+ try {
386
+ await this.eventBus.publish(this.stream, entry.event);
387
+ await this.outbox.markAsPublished(entry.id);
388
+ } catch {
389
+ await this.outbox.markAsFailed(entry.id);
390
+ }
391
+ })
392
+ );
408
393
  }
409
394
  async tick() {
410
395
  await this.runOnce();
@@ -487,12 +472,7 @@ var SimpleRepository = class {
487
472
  }
488
473
  async store(events) {
489
474
  await Promise.all(
490
- events.map(
491
- async (event) => this.eventStore.append(
492
- this.streamName,
493
- [event]
494
- )
495
- )
475
+ events.map(async (event) => this.eventStore.append(this.streamName, [event]))
496
476
  );
497
477
  }
498
478
  };
@@ -521,20 +501,20 @@ var ScenarioTest = class {
521
501
  }
522
502
  givenInput = [];
523
503
  whenInput;
524
- given(...events) {
504
+ Given(...events) {
525
505
  this.givenInput = events;
526
506
  return {
527
- when: this.when.bind(this),
528
- then: this.then.bind(this)
507
+ When: this.When.bind(this),
508
+ Then: this.Then.bind(this)
529
509
  };
530
510
  }
531
- when(action) {
511
+ When(action) {
532
512
  this.whenInput = action;
533
513
  return {
534
- then: this.then.bind(this)
514
+ Then: this.Then.bind(this)
535
515
  };
536
516
  }
537
- async then(thenInput) {
517
+ async Then(thenInput) {
538
518
  const domainEvents = this.givenInput.filter(isDomainEvent);
539
519
  const integrationEvents = this.givenInput.filter(isIntegrationEvent);
540
520
  await Promise.all([
@@ -545,15 +525,28 @@ var ScenarioTest = class {
545
525
  throw new Error("In the ScenarioTest, the when-step cannot be empty");
546
526
  }
547
527
  if (isCommand(this.whenInput)) {
548
- invariant(isDomainEvent(thenInput), fail(new TypeError('When "command" expects a domain event in the then-step')));
528
+ invariant(
529
+ isDomainEvent(thenInput),
530
+ fail(new TypeError('When "command" expects a domain event in the then-step'))
531
+ );
549
532
  await this.handleCommand(this.whenInput, thenInput);
550
533
  }
551
534
  if (isQuery(this.whenInput)) {
552
- invariant(Array.isArray(thenInput), fail(new TypeError('When "query" expects an array of expected results in the then-step')));
535
+ invariant(
536
+ Array.isArray(thenInput),
537
+ fail(new TypeError('When "query" expects an array of expected results in the then-step'))
538
+ );
553
539
  await this.handleQuery(this.whenInput, thenInput);
554
540
  }
555
541
  if (isDomainEvent(this.whenInput) || isIntegrationEvent(this.whenInput)) {
556
- invariant(isDomainEvent(thenInput), fail(new TypeError('When "domain event" or "integration event" expects a domain event in the then-step')));
542
+ invariant(
543
+ isDomainEvent(thenInput),
544
+ fail(
545
+ new TypeError(
546
+ 'When "domain event" or "integration event" expects a domain event in the then-step'
547
+ )
548
+ )
549
+ );
557
550
  await this.handleEvent(this.whenInput, thenInput);
558
551
  }
559
552
  }
@@ -610,10 +603,8 @@ var ScenarioTest = class {
610
603
 
611
604
  // src/utils/parseAsError/parseAsError.ts
612
605
  function parseAsError(value) {
613
- if (value instanceof Error)
614
- return value;
615
- if (typeof value === "string")
616
- return new Error(value);
606
+ if (value instanceof Error) return value;
607
+ if (typeof value === "string") return new Error(value);
617
608
  try {
618
609
  const json = JSON.stringify(value);
619
610
  return new Error(json ?? String(value));
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/core/utils/createCommand.ts","../src/core/utils/createQuery.ts","../src/core/utils/isCommand.ts","../src/core/utils/isQuery.ts","../src/domain/Specification/Specification.ts","../src/domain/Specification/utils/createQueryNode.ts","../src/domain/Specification/implementations/FieldEquals.specification.ts","../src/utils/fail/fail.ts","../src/utils/invariant/invariant.ts","../src/domain/Specification/implementations/FieldGreaterThan.specification.ts","../src/domain/utils/createDomainEvent.ts","../src/domain/utils/isEvent.ts","../src/domain/utils/isDomainEvent.ts","../src/infrastructure/CommandBus/implementations/SimpleCommandBus.ts","../src/infrastructure/Database/Database.ts","../src/infrastructure/Database/implementations/SimpleDatabase.exceptions.ts","../src/infrastructure/Database/implementations/SimpleDatabase.ts","../src/infrastructure/EventBus/implementations/SimpleEventBus.ts","../src/infrastructure/EventBus/utils/createIntegrationEvent.ts","../src/infrastructure/EventBus/utils/isIntegrationEvent.ts","../src/utils/streamKey/makeStreamKey.ts","../src/infrastructure/EventStore/utils/createStoredEvent.ts","../src/infrastructure/EventStore/implementations/SimpleEventStore.exceptions.ts","../src/infrastructure/EventStore/implementations/SimpleEventStore.ts","../src/infrastructure/Outbox/implementations/GenericOutboxWorker.ts","../src/infrastructure/Outbox/implementations/InMemoryOutbox.ts","../src/infrastructure/Outbox/utils/createOutboxEntry.ts","../src/infrastructure/QueryBus/implementations/SimpleQueryBus.ts","../src/infrastructure/Repository/implementations/SimpleRepository.ts","../src/utils/isEqual/isEqual.ts","../src/infrastructure/ScenarioTest/ScenarioTest.ts","../src/utils/parseAsError/parseAsError.ts"],"names":["randomUUID","Operation","event"],"mappings":"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","file":"index.cjs","sourcesContent":["import type { Command, CommandMetadata } from '@core/Command.ts'\nimport { randomUUID } from 'node:crypto'\n\nexport function createCommand<TType extends string, TPayload>(type: TType, aggregateId: string, payload: TPayload, metadata: Partial<CommandMetadata> = {}): Command<TType, TPayload> {\n return Object.freeze({\n id: randomUUID(),\n type,\n aggregateId: String(aggregateId),\n payload,\n kind: 'command' as const,\n timestamp: new Date().toISOString(),\n metadata,\n })\n}\n","import type { Query, QueryMetadata } from '@core/Query.ts'\nimport { randomUUID } from 'node:crypto'\n\nexport function createQuery<TType extends string, TPayload>(type: TType, payload: TPayload, metadata: QueryMetadata = {}): Query<TType, TPayload> {\n return Object.freeze({\n id: randomUUID(),\n type,\n payload,\n kind: 'query',\n timestamp: new Date().toISOString(),\n metadata,\n })\n}\n","import type { Command } from '@core/Command.ts'\n\nexport function isCommand(candidate: unknown): candidate is Command<string, unknown> {\n if (candidate === null)\n return false\n if (typeof candidate !== 'object')\n return false\n if (!('type' in candidate))\n return false\n return 'kind' in candidate && candidate.kind === 'command'\n}\n","import type { Query } from '@core/Query.ts'\n\nexport function isQuery(candidate: unknown): candidate is Query<unknown> {\n if (candidate === null)\n return false\n if (typeof candidate !== 'object')\n return false\n if (!('type' in candidate))\n return false\n return 'kind' in candidate && candidate.kind === 'query'\n}\n","import type { QueryNode } from './QueryNode.ts'\n\nexport abstract class Specification<T> {\n abstract isSatisfiedBy(entity: T): boolean\n abstract toQuery(): QueryNode\n\n and(other: Specification<T>): Specification<T> {\n return new AndSpecification(this, other)\n }\n\n or(other: Specification<T>): Specification<T> {\n return new OrSpecification(this, other)\n }\n\n not(): Specification<T> {\n return new NotSpecification(this)\n }\n}\n\nexport class AndSpecification<T> extends Specification<T> {\n constructor(private left: Specification<T>, private right: Specification<T>) {\n super()\n }\n\n isSatisfiedBy(entity: T): boolean {\n return this.left.isSatisfiedBy(entity) && this.right.isSatisfiedBy(entity)\n }\n\n toQuery(): QueryNode {\n return {\n type: 'and',\n nodes: [this.left.toQuery(), this.right.toQuery()],\n }\n }\n}\n\nexport class OrSpecification<T> extends Specification<T> {\n constructor(private left: Specification<T>, private right: Specification<T>) {\n super()\n }\n\n isSatisfiedBy(entity: T): boolean {\n return this.left.isSatisfiedBy(entity) || this.right.isSatisfiedBy(entity)\n }\n\n toQuery(): QueryNode {\n return {\n type: 'or',\n nodes: [this.left.toQuery(), this.right.toQuery()],\n }\n }\n}\n\nexport class NotSpecification<T> extends Specification<T> {\n constructor(private spec: Specification<T>) {\n super()\n }\n\n isSatisfiedBy(entity: T): boolean {\n return !this.spec.isSatisfiedBy(entity)\n }\n\n toQuery(): QueryNode {\n return {\n type: 'not',\n node: this.spec.toQuery(),\n }\n }\n}\n","import type { Primitive } from '@core/types/Primitive.ts'\nimport type { QueryNode } from '../QueryNode.ts'\n\nexport function createQueryNode(type: 'eq' | 'gt' | 'lt', field: string | number | symbol, value: Primitive): QueryNode\nexport function createQueryNode(type: 'and' | 'or', field: undefined, value: QueryNode[]): QueryNode\nexport function createQueryNode(type: 'not', field: undefined, value: QueryNode): QueryNode\nexport function createQueryNode(\n type: QueryNode['type'],\n field: string | number | symbol | undefined,\n value: Primitive | QueryNode | QueryNode[],\n): QueryNode {\n switch (type) {\n case 'eq':\n case 'gt':\n case 'lt':\n return { type, field: field as string, value: value as Primitive }\n case 'and':\n case 'or':\n return { type, nodes: value as QueryNode[] }\n case 'not':\n return { type, node: value as QueryNode }\n }\n}\n","import type { Primitive } from '@core/types/Primitive.ts'\nimport type { QueryNode } from '../QueryNode.ts'\nimport { Specification } from '../Specification.ts'\nimport { createQueryNode } from '../utils/createQueryNode.ts'\n\nexport class FieldEquals<T> extends Specification<T> {\n constructor(private field: keyof T, private value: Primitive) {\n super()\n }\n\n isSatisfiedBy(entity: T): boolean {\n return entity[this.field] === this.value\n }\n\n toQuery(): QueryNode {\n return createQueryNode('eq', this.field, this.value)\n }\n}\n","export function fail(anExpression: Error) {\n return () => {\n throw anExpression\n }\n}\n","export function invariant(condition: boolean, onInvalid: () => never): asserts condition {\n if (!condition)\n onInvalid()\n}\n","import type { QueryNode } from '../QueryNode.ts'\nimport { fail } from '@utils/fail/fail.ts'\nimport { invariant } from '@utils/invariant/invariant.ts'\nimport { Specification } from '../Specification.ts'\nimport { createQueryNode } from '../utils/createQueryNode.ts'\n\nexport class FieldGreaterThan<T> extends Specification<T> {\n constructor(\n private field: keyof T,\n private value: number,\n ) {\n super()\n }\n\n private isNumber(value: unknown): value is number {\n return typeof value === 'number'\n }\n\n isSatisfiedBy(entity: T): boolean {\n const field = entity[this.field]\n invariant(\n this.isNumber(field),\n fail(new TypeError(`Field ${String(this.field)} is not a number`),\n ),\n )\n return field > this.value\n }\n\n toQuery(): QueryNode {\n return createQueryNode('gt', this.field, this.value)\n }\n}\n","import type { DomainEvent, DomainEventMetadata } from '@domain/DomainEvent.ts'\nimport { randomUUID } from 'node:crypto'\n\nexport function createDomainEvent<TPayload = unknown>(\n type: string,\n aggregateId: string,\n payload: TPayload,\n metadata: Partial<DomainEventMetadata> = {},\n): DomainEvent<TPayload> {\n return Object.freeze({\n id: randomUUID(),\n type,\n aggregateId,\n payload,\n source: 'internal',\n timestamp: new Date().toISOString(),\n metadata,\n })\n}\n","import type { BaseEvent } from '@domain/BaseEvent.ts'\n\nexport function isEvent(event: unknown): event is BaseEvent {\n if (typeof event !== 'object')\n return false\n if (event === null)\n return false\n if (!('type' in event))\n return false\n return 'source' in event\n}\n","import type { DomainEvent } from '../DomainEvent.ts'\nimport { isEvent } from './isEvent.ts'\n\nexport function isDomainEvent(event: unknown): event is DomainEvent {\n return isEvent(event)\n && 'aggregateId' in event\n && event.source === 'internal'\n}\n","import type { Command } from '@core/Command.ts'\nimport type { CommandHandler } from '@core/CommandHandler.ts'\nimport type { CommandBus } from '../CommandBus.ts'\n\nexport class SimpleCommandBus<TCommand extends Command> implements CommandBus<TCommand> {\n private handlers: Map<TCommand['type'], CommandHandler<TCommand>> = new Map()\n\n register(aTypeOfCommand: TCommand['type'], anHandler: CommandHandler<TCommand>): void {\n if (this.handlers.has(aTypeOfCommand)) {\n throw new Error(`Handler already registered for command type: ${aTypeOfCommand}`)\n }\n this.handlers.set(aTypeOfCommand, anHandler)\n }\n\n async execute(aCommand: TCommand): Promise<void> {\n const handler = this.handlers.get(aCommand.type)\n if (!handler) {\n throw new Error(`No handler found for command type: ${aCommand.type}`)\n }\n return handler.execute(aCommand)\n }\n}\n","import type { Specification } from '@domain/Specification/Specification.ts'\nimport type { WithIdentifier } from '../../core/types/WithIdentifier.ts'\n\nexport enum Operation {\n CREATE = 'CREATE',\n PUT = 'PUT',\n PATCH = 'PATCH',\n DELETE = 'DELETE',\n}\n\ninterface Statement<TModel> {\n operation: Operation\n payload: TModel\n}\n\nexport interface CreateStatement<TModel> extends Statement<TModel> {\n operation: Operation.CREATE\n payload: TModel\n}\n\nexport interface PutStatement<TModel> extends Statement<TModel> {\n operation: Operation.PUT\n payload: TModel\n}\n\nexport interface PatchStatement<TModel> extends Statement<Partial<TModel>> {\n operation: Operation.PATCH\n payload: WithIdentifier<Partial<TModel>>\n}\n\nexport interface DeleteStatement extends Statement<WithIdentifier> {\n operation: Operation.DELETE\n payload: WithIdentifier\n}\n\ninterface Executable<TModel, TReturnType = Promise<void>> {\n execute(tableName: string, statement: CreateStatement<TModel>): TReturnType\n execute(tableName: string, statement: PutStatement<TModel>): TReturnType\n execute(tableName: string, statement: PatchStatement<TModel>): TReturnType\n execute(tableName: string, statement: DeleteStatement): TReturnType\n}\n\ninterface QueryAble<TModel, TReturnType = Promise<TModel[]>> {\n query(collectionName: string, specification: Specification<TModel>): TReturnType\n}\n\nexport interface Database<TModel, TExecuteReturnType = Promise<void>, TQueryReturnType = Promise<TModel[]>>\n extends\n QueryAble<TModel, TQueryReturnType>,\n Executable<TModel, TExecuteReturnType> { }\n","export class RecordNotFoundException extends Error {\n constructor(id: string) {\n super(`Record not found for id: ${id}`)\n }\n}\n\nexport class DuplicateRecordException extends Error {\n constructor(id: string) {\n super(`Duplicate record found for id: ${id}`)\n }\n}\n\nexport class DatabaseOfflineException extends Error {\n constructor() {\n super(`Database is offline`)\n }\n}\n","import type { Specification } from '@domain/Specification/Specification.ts'\nimport type { WithIdentifier } from '../../../core/types/WithIdentifier.ts'\nimport type { CreateStatement, Database, DeleteStatement, PatchStatement, PutStatement } from '../Database.ts'\nimport { Operation } from '../Database.ts'\nimport { DatabaseOfflineException, DuplicateRecordException, RecordNotFoundException } from './SimpleDatabase.exceptions.ts'\n\nexport class SimpleDatabase<TModel extends WithIdentifier> implements Database<TModel, Promise<void>, Promise<TModel[]>> {\n private readonly datasource = new Map<string, TModel[]>()\n private simulateOffline = false\n\n async query(\n tableName: string,\n specification: Specification<TModel>,\n ): Promise<TModel[]> {\n if (this.simulateOffline)\n throw new DatabaseOfflineException()\n\n const tableRecords = (this.datasource.get(tableName) || [])\n return tableRecords\n .filter((record: TModel) => specification.isSatisfiedBy(record))\n }\n\n async execute(\n tableName: string,\n statement: CreateStatement<TModel> | PutStatement<TModel> | PatchStatement<TModel> | DeleteStatement,\n ): Promise<void> {\n if (this.simulateOffline)\n throw new DatabaseOfflineException()\n\n if (!this.datasource.has(tableName))\n this.datasource.set(tableName, [])\n const table = this.datasource.get(tableName)!\n\n switch (statement.operation) {\n case Operation.CREATE: {\n const isDuplicate = table.some(item => item.id === statement.payload.id)\n if (isDuplicate)\n throw new DuplicateRecordException(statement.payload.id)\n table.push(statement.payload)\n break\n }\n case Operation.PUT:{\n const index = table.findIndex(item => item.id === statement.payload.id)\n if (index === -1)\n throw new RecordNotFoundException(statement.payload.id)\n table[index] = statement.payload\n break\n }\n case Operation.PATCH:{\n const index = table.findIndex(item => item.id === statement.payload.id)\n if (index === -1)\n throw new RecordNotFoundException(statement.payload.id)\n table[index] = { ...table[index], ...statement.payload }\n break\n }\n case Operation.DELETE:{\n const index = table.findIndex(item => item.id === statement.payload.id)\n if (index === -1)\n throw new RecordNotFoundException(statement.payload.id)\n table.splice(index, 1)\n break\n }\n }\n }\n\n goOffline(): void {\n this.simulateOffline = true\n }\n}\n","import type { EventHandler } from '@core/EventHandler.ts'\nimport type { BaseEvent } from '@domain/BaseEvent.ts'\nimport type { EventConsumer, EventProducer } from '../EventBus.ts'\n\nexport class SimpleEventBus<TEvent extends BaseEvent>\nimplements EventConsumer<TEvent>, EventProducer<TEvent> {\n private handlers = new Map<string, EventHandler<TEvent>[]>()\n\n subscribe(\n stream: string,\n aHandler: EventHandler<TEvent>,\n ): void {\n const handlersForType = this.handlers.get(stream) ?? []\n handlersForType.push(aHandler)\n this.handlers.set(stream, handlersForType)\n }\n\n async consume(stream: string, anEvent: TEvent): Promise<void> {\n if (!this.handlers.has(stream))\n return\n const handlers = this.handlers.get(stream) as EventHandler<TEvent>[]\n await Promise.all(handlers.map(async (handler) => {\n return handler.handle(anEvent)\n }))\n }\n\n async publish(stream: string, anEvent: TEvent): Promise<void> {\n await this.consume(stream, anEvent)\n }\n}\n","import type { IntegrationEvent, IntegrationEventMetadata } from '../IntegrationEvent.ts'\nimport { randomUUID } from 'node:crypto'\n\nexport function createIntegrationEvent<TPayload = unknown>(type: string, payload: TPayload, metadata?: Partial<IntegrationEventMetadata>): IntegrationEvent<TPayload> {\n return Object.freeze({\n id: randomUUID(),\n type,\n payload,\n source: 'external',\n timestamp: new Date().toISOString(),\n metadata: {\n ...metadata,\n },\n })\n}\n","import type { IntegrationEvent } from '../IntegrationEvent.ts'\nimport { isEvent } from '@domain/utils/isEvent.ts'\n\nexport function isIntegrationEvent<TPayload>(event: unknown): event is IntegrationEvent<TPayload> {\n return isEvent(event)\n && event.source === 'external'\n}\n","import type { StreamKey } from '@utils/streamKey/StreamKey.ts'\n\nexport function makeStreamKey(streamName: string, aggregateId: string): StreamKey {\n return `${streamName}#${aggregateId}`\n}\n","import type { DomainEvent } from '@domain/DomainEvent.ts'\nimport type { StoredEvent } from '../StoredEvent.ts'\nimport { makeStreamKey } from '@utils/streamKey/makeStreamKey.ts'\n\nexport function createStoredEvent<TEvent extends DomainEvent>(\n streamName: string,\n version: number,\n event: TEvent,\n): StoredEvent<TEvent> {\n return Object.freeze({\n id: event.id,\n streamKey: makeStreamKey(streamName, event.aggregateId),\n version,\n createdAt: new Date().toISOString(),\n event,\n })\n}\n","export class MultipleAggregatesException extends Error {\n constructor() {\n super('EventStore append does not support multiple aggregates to be stored')\n }\n}\n","import type { DomainEvent } from '@domain/DomainEvent.ts'\nimport type { Database } from '@infrastructure/Database/Database.ts'\nimport type { EventStore } from '@infrastructure/EventStore/EventStore.ts'\nimport type { Outbox } from '@infrastructure/Outbox/Outbox.ts'\nimport type { StreamKey } from '@utils/streamKey/StreamKey.ts'\nimport type { StoredEvent } from '../StoredEvent.ts'\nimport { FieldEquals } from '@domain/Specification/implementations/FieldEquals.specification.ts'\nimport { Operation } from '@infrastructure/Database/Database.ts'\nimport { makeStreamKey } from '@utils/streamKey/makeStreamKey.ts'\nimport { createStoredEvent } from '../utils/createStoredEvent.ts'\nimport { MultipleAggregatesException } from './SimpleEventStore.exceptions.ts'\n\nexport class SimpleEventStore<TEvent extends DomainEvent> implements EventStore<TEvent, Promise<void>, Promise<TEvent[]>> {\n private readonly tableName: string = 'event_store'\n\n constructor(\n private readonly database: Database<StoredEvent<TEvent>, Promise<void>, Promise<StoredEvent<TEvent>[]>>,\n private readonly outbox?: Outbox,\n ) { }\n\n async load(streamName: string, aggregateId: string): Promise<TEvent[]> {\n const streamKey: StreamKey = makeStreamKey(streamName, aggregateId)\n const specification = new FieldEquals('streamKey', streamKey)\n const storedEvents = await this.database.query(this.tableName, specification)\n return storedEvents.map(storedEvent => storedEvent.event)\n }\n\n async append(streamName: string, events: TEvent[]): Promise<void> {\n const uniqueAggregateIds = new Set(events.map(event => event.aggregateId))\n if (uniqueAggregateIds.size > 1)\n throw new MultipleAggregatesException()\n\n const event = events[0]\n const currentStream = await this.load(streamName, event.aggregateId)\n const eventsToStore = events\n .map(event => createStoredEvent(streamName, currentStream.length + 1, event))\n await Promise.all(\n eventsToStore.map(async payload => this.database.execute(this.tableName, { operation: Operation.CREATE, payload }),\n ),\n )\n await Promise.all(events.map(async event => this.outbox?.enqueue(event)))\n }\n}\n","import type { BaseEvent } from '@domain/BaseEvent.ts'\nimport type { EventProducer } from '@infrastructure/EventBus/EventBus.js'\nimport type { OutboxWorker } from '@infrastructure/Outbox/OutboxWorker.ts'\nimport type { Outbox } from '../Outbox.ts'\n\nexport class GenericOutboxWorker implements OutboxWorker {\n constructor(\n protected outbox: Outbox,\n protected eventBus: EventProducer<BaseEvent>,\n protected stream: string,\n ) {}\n\n async runOnce(): Promise<void> {\n const pending = await this.outbox.getPending()\n\n await Promise.all(pending.map(async (entry) => {\n try {\n await this.eventBus.publish(this.stream, entry.event)\n await this.outbox.markAsPublished(entry.id)\n }\n catch {\n await this.outbox.markAsFailed(entry.id)\n }\n }))\n }\n\n async tick(): Promise<void> {\n await this.runOnce()\n }\n\n start(intervalMs: number): void {\n setInterval(() => {\n void this.tick().catch(console.error)\n }, intervalMs)\n }\n}\n","import type { DomainEvent } from '@domain/DomainEvent.ts'\nimport type { Outbox } from '../Outbox.ts'\nimport type { OutboxEntry } from '../OutboxEntry.ts'\n\nexport class InMemoryOutbox implements Outbox {\n protected entries: OutboxEntry[] = []\n protected idCounter = 0\n\n async enqueue(event: DomainEvent<unknown>): Promise<void> {\n this.entries.push({\n id: (this.idCounter++).toString(),\n event,\n published: false,\n retryCount: 0,\n })\n }\n\n async getPending(limit = 100): Promise<OutboxEntry[]> {\n return this.entries.filter(e => !e.published).slice(0, limit)\n }\n\n async markAsPublished(id: string): Promise<void> {\n const entry = this.entries.find(e => e.id === id)\n if (entry) {\n entry.published = true\n }\n }\n\n async markAsFailed(id: string): Promise<void> {\n const entry = this.entries.find(e => e.id === id)\n if (entry) {\n entry.retryCount += 1\n entry.lastAttemptAt = new Date().toISOString()\n }\n }\n}\n","import type { DomainEvent } from '@domain/DomainEvent.ts'\nimport type { OutboxEntry } from '../OutboxEntry.ts'\nimport { randomUUID } from 'node:crypto'\n\nexport function createOutboxEntry(\n event: DomainEvent<unknown>,\n): OutboxEntry {\n return Object.freeze({\n id: randomUUID(),\n event,\n published: false,\n retryCount: 0,\n lastAttemptAt: undefined,\n })\n}\n","import type { Query } from '@core/Query.ts'\nimport type { QueryHandler } from '@core/QueryHandler.ts'\nimport type { QueryBus } from '../QueryBus.ts'\n\nexport class SimpleQueryBus<TQuery extends Query, TProjection> implements QueryBus<TQuery, Promise<TProjection>> {\n private handlers: Map<TQuery['type'], QueryHandler<TQuery, Promise<TProjection>>> = new Map()\n\n register(\n aTypeOfQuery: TQuery['type'],\n anHandler: QueryHandler<TQuery, Promise<TProjection>>,\n ): void {\n if (this.handlers.has(aTypeOfQuery)) {\n throw new Error(`Handler already registered for query type: ${aTypeOfQuery}`)\n }\n this.handlers.set(aTypeOfQuery, anHandler)\n }\n\n async execute(aQuery: TQuery): Promise<TProjection> {\n const handler = this.handlers.get(aQuery.type)\n if (!handler) {\n throw new Error(`No handler found for query type: ${aQuery.type}`)\n }\n return handler.execute(aQuery)\n }\n}\n","import type { Decider } from '@domain/Decider.ts'\nimport type { DomainEvent } from '@domain/DomainEvent.ts'\nimport type { Repository } from '@domain/Repository.ts'\nimport type { EventStore } from '@infrastructure/EventStore/EventStore.ts'\n\nexport class SimpleRepository<TState, TCommand, TEvent extends DomainEvent> implements Repository<TEvent, Promise<TState>, Promise<void>> {\n constructor(\n private readonly eventStore: EventStore<TEvent, Promise<void>, Promise<TEvent[]>>,\n readonly streamName: string,\n private readonly evolveFn: Decider<TState, TCommand, TEvent>['evolve'],\n private readonly initialState: Decider<TState, TCommand, TEvent>['initialState'],\n ) {\n }\n\n async load(aggregateId: string): Promise<TState> {\n const pastEvents = await this.eventStore.load(this.streamName, aggregateId)\n return pastEvents\n .reduce<TState>(this.evolveFn, this.initialState(aggregateId))\n }\n\n async store(events: TEvent[]): Promise<void> {\n await Promise.all(\n events.map(\n async event => this.eventStore.append(\n this.streamName,\n [event],\n ),\n ),\n )\n }\n}\n","export function isEqual<T>(a: T, b: T): boolean {\n if (a === b) {\n return true\n }\n\n // eslint-disable-next-line ts/strict-boolean-expressions\n const bothAreObjects = a && b && typeof a === 'object' && typeof b === 'object'\n\n return Boolean(\n bothAreObjects\n && Object.keys(a).length === Object.keys(b).length\n && Object.entries(a).every(([k, v]) => isEqual(v, b[k as keyof T])),\n )\n}\n","import type { Command } from '@core/Command.ts'\nimport type { Query } from '@core/Query.ts'\nimport type { BaseEvent } from '@domain/BaseEvent.ts'\nimport type { DomainEvent } from '@domain/DomainEvent.ts'\nimport type { Repository } from '@domain/Repository.ts'\nimport type { EventConsumer, EventProducer } from '@infrastructure/EventBus/EventBus.js'\nimport type { EventStore } from '@infrastructure/EventStore/EventStore.ts'\nimport type { OutboxWorker } from '@infrastructure/Outbox/OutboxWorker.ts'\nimport type { CommandBus } from '../CommandBus/CommandBus.ts'\nimport type { IntegrationEvent } from '../EventBus/IntegrationEvent.ts'\nimport type { QueryBus } from '../QueryBus/QueryBus.ts'\nimport { isCommand } from '@core/utils/isCommand.ts'\nimport { isQuery } from '@core/utils/isQuery.ts'\nimport { isDomainEvent } from '@domain/utils/isDomainEvent.ts'\nimport { isEvent } from '@domain/utils/isEvent.ts'\nimport { fail } from '@utils/fail/fail.ts'\nimport { invariant } from '@utils/invariant/invariant.ts'\nimport { isEqual } from '@utils/isEqual/isEqual.ts'\nimport { isIntegrationEvent } from '../EventBus/utils/isIntegrationEvent.ts'\n\ntype GivenInput = (DomainEvent | IntegrationEvent)[]\ntype WhenInput = Command | Query | DomainEvent | IntegrationEvent\ntype ThenInput = DomainEvent | Array<Record<string, unknown>>\n\nexport class ScenarioTest<TState, TEvent extends DomainEvent> {\n private givenInput: GivenInput = []\n private whenInput: WhenInput | undefined\n\n constructor(\n private readonly streamName: string,\n private readonly eventBus: EventProducer<BaseEvent> & EventConsumer<BaseEvent>,\n private readonly eventStore: EventStore<TEvent, Promise<void>, Promise<TEvent[]>>,\n private readonly commandBus: CommandBus<Command>,\n private readonly queryBus: QueryBus<Query, Promise<Record<string, unknown>[]>>,\n private readonly repository: Repository<DomainEvent, Promise<TState>>,\n private readonly outboxWorker: OutboxWorker,\n ) {}\n\n given(...events: GivenInput): {\n when(action: WhenInput): ReturnType<ScenarioTest<TState, TEvent>['when']>\n then(outcome: ThenInput): Promise<void>\n } {\n this.givenInput = events\n return {\n when: this.when.bind(this),\n then: this.then.bind(this),\n }\n }\n\n when(action: WhenInput): {\n then(outcome: ThenInput): Promise<void>\n } {\n this.whenInput = action\n return {\n then: this.then.bind(this),\n }\n }\n\n async then(thenInput: ThenInput): Promise<void> {\n const domainEvents = this.givenInput\n .filter(isDomainEvent)\n const integrationEvents = this.givenInput\n .filter(isIntegrationEvent)\n\n await Promise.all([\n this.repository.store(domainEvents),\n ...integrationEvents.map(async event => this.eventBus.consume(this.streamName, event)),\n ])\n\n if (!this.whenInput) {\n throw new Error('In the ScenarioTest, the when-step cannot be empty')\n }\n\n if (isCommand(this.whenInput)) {\n invariant(isDomainEvent(thenInput), fail(new TypeError('When \\\"command\\\" expects a domain event in the then-step')))\n await this.handleCommand(this.whenInput, thenInput)\n }\n\n if (isQuery(this.whenInput)) {\n invariant(Array.isArray(thenInput), fail(new TypeError('When \\\"query\\\" expects an array of expected results in the then-step')))\n await this.handleQuery(this.whenInput, thenInput)\n }\n\n if (isDomainEvent(this.whenInput) || isIntegrationEvent(this.whenInput)) {\n invariant(isDomainEvent(thenInput), fail(new TypeError('When \\\"domain event\\\" or \\\"integration event\\\" expects a domain event in the then-step')))\n await this.handleEvent(this.whenInput, thenInput)\n }\n }\n\n private async handleCommand(command: Command, outcome: DomainEvent): Promise<void> {\n await this.commandBus.execute(command)\n const actualEvents = await this.eventStore.load(this.streamName, outcome.aggregateId)\n const foundEvent = actualEvents.findLast(\n event =>\n isDomainEvent(event)\n && event.aggregateId === outcome.aggregateId\n && event.type === outcome.type,\n )\n invariant(!!foundEvent, fail(new Error('ScenarioTest: event/command was not found')))\n invariant(\n outcome.type === foundEvent.type,\n fail(new Error('ScenarioTest: event/command type was not equal')),\n )\n invariant(\n outcome.aggregateId === foundEvent.aggregateId,\n fail(new Error('ScenarioTest: event/command aggregate id was not equal')),\n )\n invariant(\n isEqual(outcome.payload, foundEvent.payload),\n fail(new Error('ScenarioTest: event/command payload was not equal')),\n )\n }\n\n private async handleQuery(query: Query, expected: Array<Record<string, unknown>>): Promise<void> {\n await this.outboxWorker.tick()\n const actual = await this.queryBus.execute(query)\n invariant(\n isEqual(actual, expected),\n fail(new Error('ScenarioTest: a different query result was returned')),\n )\n }\n\n private async handleEvent(\n event: DomainEvent | IntegrationEvent,\n outcome: DomainEvent,\n ): Promise<void> {\n await this.eventBus.publish(this.streamName, event)\n const actualEvents = await this.eventStore.load(this.streamName, outcome.aggregateId)\n const foundEvent = actualEvents.findLast(\n event =>\n isEvent(event) && event.aggregateId === outcome.aggregateId && event.type === outcome.type,\n )\n invariant(!!foundEvent, fail(new Error('ScenarioTest: event was not found')))\n invariant(isEvent(foundEvent), fail(new Error('ScenarioTest: event is not of type event')))\n invariant(\n outcome.type === foundEvent.type,\n fail(new Error('ScenarioTest: event type was not equal')),\n )\n invariant(\n outcome.aggregateId === foundEvent.aggregateId,\n fail(new Error('ScenarioTest: event aggregate id was not equal')),\n )\n invariant(\n isEqual(outcome.payload, foundEvent.payload),\n fail(new Error('ScenarioTest: event payload was not equal')),\n )\n }\n}\n","export function parseAsError(value: unknown): Error {\n if (value instanceof Error)\n return value\n if (typeof value === 'string')\n return new Error(value)\n try {\n const json = JSON.stringify(value)\n return new Error(json ?? String(value))\n }\n catch {\n return new Error('Unknown error')\n }\n}\n"]}
1
+ {"version":3,"sources":["../src/core/utils/createCommand.ts","../src/core/utils/createQuery.ts","../src/core/utils/isCommand.ts","../src/core/utils/isQuery.ts","../src/domain/Specification/Specification.ts","../src/domain/Specification/utils/createQueryNode.ts","../src/domain/Specification/implementations/FieldEquals.specification.ts","../src/utils/fail/fail.ts","../src/utils/invariant/invariant.ts","../src/domain/Specification/implementations/FieldGreaterThan.specification.ts","../src/domain/utils/createDomainEvent.ts","../src/domain/utils/isEvent.ts","../src/domain/utils/isDomainEvent.ts","../src/infrastructure/CommandBus/implementations/SimpleCommandBus.ts","../src/infrastructure/Database/Database.ts","../src/infrastructure/Database/implementations/SimpleDatabase.exceptions.ts","../src/infrastructure/Database/implementations/SimpleDatabase.ts","../src/infrastructure/EventBus/implementations/SimpleEventBus.ts","../src/infrastructure/EventBus/utils/createIntegrationEvent.ts","../src/infrastructure/EventBus/utils/isIntegrationEvent.ts","../src/utils/streamKey/makeStreamKey.ts","../src/infrastructure/EventStore/utils/createStoredEvent.ts","../src/infrastructure/EventStore/implementations/SimpleEventStore.exceptions.ts","../src/infrastructure/EventStore/implementations/SimpleEventStore.ts","../src/infrastructure/Outbox/implementations/GenericOutboxWorker.ts","../src/infrastructure/Outbox/implementations/InMemoryOutbox.ts","../src/infrastructure/Outbox/utils/createOutboxEntry.ts","../src/infrastructure/QueryBus/implementations/SimpleQueryBus.ts","../src/infrastructure/Repository/implementations/SimpleRepository.ts","../src/utils/isEqual/isEqual.ts","../src/infrastructure/ScenarioTest/ScenarioTest.ts","../src/utils/parseAsError/parseAsError.ts"],"names":["randomUUID","Operation","event"],"mappings":"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","file":"index.cjs","sourcesContent":["import type { Command, CommandMetadata } from \"@core/Command.ts\";\nimport { randomUUID } from \"node:crypto\";\n\nexport function createCommand<TType extends string, TPayload>(\n type: TType,\n aggregateId: string,\n payload: TPayload,\n metadata: Partial<CommandMetadata> = {},\n): Command<TType, TPayload> {\n return Object.freeze({\n id: randomUUID(),\n type,\n aggregateId: String(aggregateId),\n payload,\n kind: \"command\" as const,\n timestamp: new Date().toISOString(),\n metadata,\n });\n}\n","import type { Query, QueryMetadata } from \"@core/Query.ts\";\nimport { randomUUID } from \"node:crypto\";\n\nexport function createQuery<TType extends string, TPayload>(\n type: TType,\n payload: TPayload,\n metadata: QueryMetadata = {},\n): Query<TType, TPayload> {\n return Object.freeze({\n id: randomUUID(),\n type,\n payload,\n kind: \"query\",\n timestamp: new Date().toISOString(),\n metadata,\n });\n}\n","import type { Command } from \"@core/Command.ts\";\n\nexport function isCommand(candidate: unknown): candidate is Command<string, unknown> {\n if (candidate === null) return false;\n if (typeof candidate !== \"object\") return false;\n if (!(\"type\" in candidate)) return false;\n return \"kind\" in candidate && candidate.kind === \"command\";\n}\n","import type { Query } from \"@core/Query.ts\";\n\nexport function isQuery(candidate: unknown): candidate is Query<unknown> {\n if (candidate === null) return false;\n if (typeof candidate !== \"object\") return false;\n if (!(\"type\" in candidate)) return false;\n return \"kind\" in candidate && candidate.kind === \"query\";\n}\n","import type { QueryNode } from \"./QueryNode.ts\";\n\nexport abstract class Specification<T> {\n abstract isSatisfiedBy(entity: T): boolean;\n abstract toQuery(): QueryNode;\n\n and(other: Specification<T>): Specification<T> {\n return new AndSpecification(this, other);\n }\n\n or(other: Specification<T>): Specification<T> {\n return new OrSpecification(this, other);\n }\n\n not(): Specification<T> {\n return new NotSpecification(this);\n }\n}\n\nexport class AndSpecification<T> extends Specification<T> {\n constructor(\n private left: Specification<T>,\n private right: Specification<T>,\n ) {\n super();\n }\n\n isSatisfiedBy(entity: T): boolean {\n return this.left.isSatisfiedBy(entity) && this.right.isSatisfiedBy(entity);\n }\n\n toQuery(): QueryNode {\n return {\n type: \"and\",\n nodes: [this.left.toQuery(), this.right.toQuery()],\n };\n }\n}\n\nexport class OrSpecification<T> extends Specification<T> {\n constructor(\n private left: Specification<T>,\n private right: Specification<T>,\n ) {\n super();\n }\n\n isSatisfiedBy(entity: T): boolean {\n return this.left.isSatisfiedBy(entity) || this.right.isSatisfiedBy(entity);\n }\n\n toQuery(): QueryNode {\n return {\n type: \"or\",\n nodes: [this.left.toQuery(), this.right.toQuery()],\n };\n }\n}\n\nexport class NotSpecification<T> extends Specification<T> {\n constructor(private spec: Specification<T>) {\n super();\n }\n\n isSatisfiedBy(entity: T): boolean {\n return !this.spec.isSatisfiedBy(entity);\n }\n\n toQuery(): QueryNode {\n return {\n type: \"not\",\n node: this.spec.toQuery(),\n };\n }\n}\n","import type { Primitive } from \"@core/types/Primitive.ts\";\nimport type { QueryNode } from \"../QueryNode.ts\";\n\nexport function createQueryNode(\n type: \"eq\" | \"gt\" | \"lt\",\n field: string | number | symbol,\n value: Primitive,\n): QueryNode;\nexport function createQueryNode(\n type: \"and\" | \"or\",\n field: undefined,\n value: QueryNode[],\n): QueryNode;\nexport function createQueryNode(type: \"not\", field: undefined, value: QueryNode): QueryNode;\nexport function createQueryNode(\n type: QueryNode[\"type\"],\n field: string | number | symbol | undefined,\n value: Primitive | QueryNode | QueryNode[],\n): QueryNode {\n switch (type) {\n case \"eq\":\n case \"gt\":\n case \"lt\":\n return { type, field: field as string, value: value as Primitive };\n case \"and\":\n case \"or\":\n return { type, nodes: value as QueryNode[] };\n case \"not\":\n return { type, node: value as QueryNode };\n }\n}\n","import type { Primitive } from \"@core/types/Primitive.ts\";\nimport type { QueryNode } from \"../QueryNode.ts\";\nimport { Specification } from \"../Specification.ts\";\nimport { createQueryNode } from \"../utils/createQueryNode.ts\";\n\nexport class FieldEquals<T> extends Specification<T> {\n constructor(\n private field: keyof T,\n private value: Primitive,\n ) {\n super();\n }\n\n isSatisfiedBy(entity: T): boolean {\n return entity[this.field] === this.value;\n }\n\n toQuery(): QueryNode {\n return createQueryNode(\"eq\", this.field, this.value);\n }\n}\n","export function fail(anExpression: Error) {\n return () => {\n throw anExpression;\n };\n}\n","export function invariant(condition: boolean, onInvalid: () => never): asserts condition {\n if (!condition) onInvalid();\n}\n","import type { QueryNode } from \"../QueryNode.ts\";\nimport { fail } from \"@utils/fail/fail.ts\";\nimport { invariant } from \"@utils/invariant/invariant.ts\";\nimport { Specification } from \"../Specification.ts\";\nimport { createQueryNode } from \"../utils/createQueryNode.ts\";\n\nexport class FieldGreaterThan<T> extends Specification<T> {\n constructor(\n private field: keyof T,\n private value: number,\n ) {\n super();\n }\n\n private isNumber(value: unknown): value is number {\n return typeof value === \"number\";\n }\n\n isSatisfiedBy(entity: T): boolean {\n const field = entity[this.field];\n invariant(\n this.isNumber(field),\n fail(new TypeError(`Field ${String(this.field)} is not a number`)),\n );\n return field > this.value;\n }\n\n toQuery(): QueryNode {\n return createQueryNode(\"gt\", this.field, this.value);\n }\n}\n","import type { DomainEvent, DomainEventMetadata } from \"@domain/DomainEvent.ts\";\nimport { randomUUID } from \"node:crypto\";\n\nexport function createDomainEvent<TPayload = unknown>(\n type: string,\n aggregateId: string,\n payload: TPayload,\n metadata: Partial<DomainEventMetadata> = {},\n): DomainEvent<TPayload> {\n return Object.freeze({\n id: randomUUID(),\n type,\n aggregateId,\n payload,\n source: \"internal\",\n timestamp: new Date().toISOString(),\n metadata,\n });\n}\n","import type { BaseEvent } from \"@domain/BaseEvent.ts\";\n\nexport function isEvent(event: unknown): event is BaseEvent {\n if (typeof event !== \"object\") return false;\n if (event === null) return false;\n if (!(\"type\" in event)) return false;\n return \"source\" in event;\n}\n","import type { DomainEvent } from \"../DomainEvent.ts\";\nimport { isEvent } from \"./isEvent.ts\";\n\nexport function isDomainEvent(event: unknown): event is DomainEvent {\n return isEvent(event) && \"aggregateId\" in event && event.source === \"internal\";\n}\n","import type { Command } from \"@core/Command.ts\";\nimport type { CommandHandler } from \"@core/CommandHandler.ts\";\nimport type { CommandBus } from \"../CommandBus.ts\";\n\nexport class SimpleCommandBus<TCommand extends Command> implements CommandBus<TCommand> {\n private handlers: Map<TCommand[\"type\"], CommandHandler<TCommand>> = new Map();\n\n register(aTypeOfCommand: TCommand[\"type\"], anHandler: CommandHandler<TCommand>): void {\n if (this.handlers.has(aTypeOfCommand)) {\n throw new Error(`Handler already registered for command type: ${aTypeOfCommand}`);\n }\n this.handlers.set(aTypeOfCommand, anHandler);\n }\n\n async execute(aCommand: TCommand): Promise<void> {\n const handler = this.handlers.get(aCommand.type);\n if (!handler) {\n throw new Error(`No handler found for command type: ${aCommand.type}`);\n }\n return handler.execute(aCommand);\n }\n}\n","import type { Specification } from \"@domain/Specification/Specification.ts\";\nimport type { WithIdentifier } from \"../../core/types/WithIdentifier.ts\";\n\nexport enum Operation {\n CREATE = \"CREATE\",\n PUT = \"PUT\",\n PATCH = \"PATCH\",\n DELETE = \"DELETE\",\n}\n\ninterface Statement<TModel> {\n operation: Operation;\n payload: TModel;\n}\n\nexport interface CreateStatement<TModel> extends Statement<TModel> {\n operation: Operation.CREATE;\n payload: TModel;\n}\n\nexport interface PutStatement<TModel> extends Statement<TModel> {\n operation: Operation.PUT;\n payload: TModel;\n}\n\nexport interface PatchStatement<TModel> extends Statement<Partial<TModel>> {\n operation: Operation.PATCH;\n payload: WithIdentifier<Partial<TModel>>;\n}\n\nexport interface DeleteStatement extends Statement<WithIdentifier> {\n operation: Operation.DELETE;\n payload: WithIdentifier;\n}\n\ninterface Executable<TModel, TReturnType = Promise<void>> {\n execute(tableName: string, statement: CreateStatement<TModel>): TReturnType;\n execute(tableName: string, statement: PutStatement<TModel>): TReturnType;\n execute(tableName: string, statement: PatchStatement<TModel>): TReturnType;\n execute(tableName: string, statement: DeleteStatement): TReturnType;\n}\n\ninterface QueryAble<TModel, TReturnType = Promise<TModel[]>> {\n query(collectionName: string, specification: Specification<TModel>): TReturnType;\n}\n\nexport interface Database<\n TModel,\n TExecuteReturnType = Promise<void>,\n TQueryReturnType = Promise<TModel[]>,\n>\n extends QueryAble<TModel, TQueryReturnType>, Executable<TModel, TExecuteReturnType> {}\n","export class RecordNotFoundException extends Error {\n constructor(id: string) {\n super(`Record not found for id: ${id}`);\n }\n}\n\nexport class DuplicateRecordException extends Error {\n constructor(id: string) {\n super(`Duplicate record found for id: ${id}`);\n }\n}\n\nexport class DatabaseOfflineException extends Error {\n constructor() {\n super(`Database is offline`);\n }\n}\n","import type { Specification } from \"@domain/Specification/Specification.ts\";\nimport type { WithIdentifier } from \"../../../core/types/WithIdentifier.ts\";\nimport type {\n CreateStatement,\n Database,\n DeleteStatement,\n PatchStatement,\n PutStatement,\n} from \"../Database.ts\";\nimport { Operation } from \"../Database.ts\";\nimport {\n DatabaseOfflineException,\n DuplicateRecordException,\n RecordNotFoundException,\n} from \"./SimpleDatabase.exceptions.ts\";\n\nexport class SimpleDatabase<TModel extends WithIdentifier> implements Database<\n TModel,\n Promise<void>,\n Promise<TModel[]>\n> {\n private readonly datasource = new Map<string, TModel[]>();\n private simulateOffline = false;\n\n async query(tableName: string, specification: Specification<TModel>): Promise<TModel[]> {\n if (this.simulateOffline) throw new DatabaseOfflineException();\n\n const tableRecords = this.datasource.get(tableName) || [];\n return tableRecords.filter((record: TModel) => specification.isSatisfiedBy(record));\n }\n\n async execute(\n tableName: string,\n statement:\n | CreateStatement<TModel>\n | PutStatement<TModel>\n | PatchStatement<TModel>\n | DeleteStatement,\n ): Promise<void> {\n if (this.simulateOffline) throw new DatabaseOfflineException();\n\n if (!this.datasource.has(tableName)) this.datasource.set(tableName, []);\n const table = this.datasource.get(tableName)!;\n\n switch (statement.operation) {\n case Operation.CREATE: {\n const isDuplicate = table.some((item) => item.id === statement.payload.id);\n if (isDuplicate) throw new DuplicateRecordException(statement.payload.id);\n table.push(statement.payload);\n break;\n }\n case Operation.PUT: {\n const index = table.findIndex((item) => item.id === statement.payload.id);\n if (index === -1) throw new RecordNotFoundException(statement.payload.id);\n table[index] = statement.payload;\n break;\n }\n case Operation.PATCH: {\n const index = table.findIndex((item) => item.id === statement.payload.id);\n if (index === -1) throw new RecordNotFoundException(statement.payload.id);\n table[index] = { ...table[index], ...statement.payload };\n break;\n }\n case Operation.DELETE: {\n const index = table.findIndex((item) => item.id === statement.payload.id);\n if (index === -1) throw new RecordNotFoundException(statement.payload.id);\n table.splice(index, 1);\n break;\n }\n }\n }\n\n goOffline(): void {\n this.simulateOffline = true;\n }\n}\n","import type { EventHandler } from \"@core/EventHandler.ts\";\nimport type { BaseEvent } from \"@domain/BaseEvent.ts\";\nimport type { EventConsumer, EventProducer } from \"../EventBus.ts\";\n\nexport class SimpleEventBus<TEvent extends BaseEvent>\n implements EventConsumer<TEvent>, EventProducer<TEvent>\n{\n private handlers = new Map<string, EventHandler<TEvent>[]>();\n\n subscribe(stream: string, aHandler: EventHandler<TEvent>): void {\n const handlersForType = this.handlers.get(stream) ?? [];\n handlersForType.push(aHandler);\n this.handlers.set(stream, handlersForType);\n }\n\n async consume(stream: string, anEvent: TEvent): Promise<void> {\n if (!this.handlers.has(stream)) return;\n const handlers = this.handlers.get(stream) as EventHandler<TEvent>[];\n await Promise.all(\n handlers.map(async (handler) => {\n return handler.handle(anEvent);\n }),\n );\n }\n\n async publish(stream: string, anEvent: TEvent): Promise<void> {\n await this.consume(stream, anEvent);\n }\n}\n","import type { IntegrationEvent, IntegrationEventMetadata } from \"../IntegrationEvent.ts\";\nimport { randomUUID } from \"node:crypto\";\n\nexport function createIntegrationEvent<TPayload = unknown>(\n type: string,\n payload: TPayload,\n metadata?: Partial<IntegrationEventMetadata>,\n): IntegrationEvent<TPayload> {\n return Object.freeze({\n id: randomUUID(),\n type,\n payload,\n source: \"external\",\n timestamp: new Date().toISOString(),\n metadata: {\n ...metadata,\n },\n });\n}\n","import type { IntegrationEvent } from \"../IntegrationEvent.ts\";\nimport { isEvent } from \"@domain/utils/isEvent.ts\";\n\nexport function isIntegrationEvent<TPayload>(event: unknown): event is IntegrationEvent<TPayload> {\n return isEvent(event) && event.source === \"external\";\n}\n","import type { StreamKey } from \"@utils/streamKey/StreamKey.ts\";\n\nexport function makeStreamKey(streamName: string, aggregateId: string): StreamKey {\n return `${streamName}#${aggregateId}`;\n}\n","import type { DomainEvent } from \"@domain/DomainEvent.ts\";\nimport type { StoredEvent } from \"../StoredEvent.ts\";\nimport { makeStreamKey } from \"@utils/streamKey/makeStreamKey.ts\";\n\nexport function createStoredEvent<TEvent extends DomainEvent>(\n streamName: string,\n version: number,\n event: TEvent,\n): StoredEvent<TEvent> {\n return Object.freeze({\n id: event.id,\n streamKey: makeStreamKey(streamName, event.aggregateId),\n version,\n createdAt: new Date().toISOString(),\n event,\n });\n}\n","export class MultipleAggregatesException extends Error {\n constructor() {\n super(\"EventStore append does not support multiple aggregates to be stored\");\n }\n}\n","import type { DomainEvent } from \"@domain/DomainEvent.ts\";\nimport type { Database } from \"@infrastructure/Database/Database.ts\";\nimport type { EventStore } from \"@infrastructure/EventStore/EventStore.ts\";\nimport type { Outbox } from \"@infrastructure/Outbox/Outbox.ts\";\nimport type { StreamKey } from \"@utils/streamKey/StreamKey.ts\";\nimport type { StoredEvent } from \"../StoredEvent.ts\";\nimport { FieldEquals } from \"@domain/Specification/implementations/FieldEquals.specification.ts\";\nimport { Operation } from \"@infrastructure/Database/Database.ts\";\nimport { makeStreamKey } from \"@utils/streamKey/makeStreamKey.ts\";\nimport { createStoredEvent } from \"../utils/createStoredEvent.ts\";\nimport { MultipleAggregatesException } from \"./SimpleEventStore.exceptions.ts\";\n\nexport class SimpleEventStore<TEvent extends DomainEvent> implements EventStore<\n TEvent,\n Promise<void>,\n Promise<TEvent[]>\n> {\n private readonly tableName: string = \"event_store\";\n\n constructor(\n private readonly database: Database<\n StoredEvent<TEvent>,\n Promise<void>,\n Promise<StoredEvent<TEvent>[]>\n >,\n private readonly outbox?: Outbox,\n ) {}\n\n async load(streamName: string, aggregateId: string): Promise<TEvent[]> {\n const streamKey: StreamKey = makeStreamKey(streamName, aggregateId);\n const specification = new FieldEquals(\"streamKey\", streamKey);\n const storedEvents = await this.database.query(this.tableName, specification);\n return storedEvents.map((storedEvent) => storedEvent.event);\n }\n\n async append(streamName: string, events: TEvent[]): Promise<void> {\n const uniqueAggregateIds = new Set(events.map((event) => event.aggregateId));\n if (uniqueAggregateIds.size > 1) throw new MultipleAggregatesException();\n\n const event = events[0];\n const currentStream = await this.load(streamName, event.aggregateId);\n const eventsToStore = events.map((event) =>\n createStoredEvent(streamName, currentStream.length + 1, event),\n );\n await Promise.all(\n eventsToStore.map(async (payload) =>\n this.database.execute(this.tableName, { operation: Operation.CREATE, payload }),\n ),\n );\n await Promise.all(events.map(async (event) => this.outbox?.enqueue(event)));\n }\n}\n","import type { BaseEvent } from \"@domain/BaseEvent.ts\";\nimport type { EventProducer } from \"@infrastructure/EventBus/EventBus.js\";\nimport type { OutboxWorker } from \"@infrastructure/Outbox/OutboxWorker.ts\";\nimport type { Outbox } from \"../Outbox.ts\";\n\nexport class GenericOutboxWorker implements OutboxWorker {\n constructor(\n protected outbox: Outbox,\n protected eventBus: EventProducer<BaseEvent>,\n protected stream: string,\n ) {}\n\n async runOnce(): Promise<void> {\n const pending = await this.outbox.getPending();\n\n await Promise.all(\n pending.map(async (entry) => {\n try {\n await this.eventBus.publish(this.stream, entry.event);\n await this.outbox.markAsPublished(entry.id);\n } catch {\n await this.outbox.markAsFailed(entry.id);\n }\n }),\n );\n }\n\n async tick(): Promise<void> {\n await this.runOnce();\n }\n\n start(intervalMs: number): void {\n setInterval(() => {\n void this.tick().catch(console.error);\n }, intervalMs);\n }\n}\n","import type { DomainEvent } from \"@domain/DomainEvent.ts\";\nimport type { Outbox } from \"../Outbox.ts\";\nimport type { OutboxEntry } from \"../OutboxEntry.ts\";\n\nexport class InMemoryOutbox implements Outbox {\n protected entries: OutboxEntry[] = [];\n protected idCounter = 0;\n\n async enqueue(event: DomainEvent<unknown>): Promise<void> {\n this.entries.push({\n id: (this.idCounter++).toString(),\n event,\n published: false,\n retryCount: 0,\n });\n }\n\n async getPending(limit = 100): Promise<OutboxEntry[]> {\n return this.entries.filter((e) => !e.published).slice(0, limit);\n }\n\n async markAsPublished(id: string): Promise<void> {\n const entry = this.entries.find((e) => e.id === id);\n if (entry) {\n entry.published = true;\n }\n }\n\n async markAsFailed(id: string): Promise<void> {\n const entry = this.entries.find((e) => e.id === id);\n if (entry) {\n entry.retryCount += 1;\n entry.lastAttemptAt = new Date().toISOString();\n }\n }\n}\n","import type { DomainEvent } from \"@domain/DomainEvent.ts\";\nimport type { OutboxEntry } from \"../OutboxEntry.ts\";\nimport { randomUUID } from \"node:crypto\";\n\nexport function createOutboxEntry(event: DomainEvent<unknown>): OutboxEntry {\n return Object.freeze({\n id: randomUUID(),\n event,\n published: false,\n retryCount: 0,\n lastAttemptAt: undefined,\n });\n}\n","import type { Query } from \"@core/Query.ts\";\nimport type { QueryHandler } from \"@core/QueryHandler.ts\";\nimport type { QueryBus } from \"../QueryBus.ts\";\n\nexport class SimpleQueryBus<TQuery extends Query, TProjection> implements QueryBus<\n TQuery,\n Promise<TProjection>\n> {\n private handlers: Map<TQuery[\"type\"], QueryHandler<TQuery, Promise<TProjection>>> = new Map();\n\n register(\n aTypeOfQuery: TQuery[\"type\"],\n anHandler: QueryHandler<TQuery, Promise<TProjection>>,\n ): void {\n if (this.handlers.has(aTypeOfQuery)) {\n throw new Error(`Handler already registered for query type: ${aTypeOfQuery}`);\n }\n this.handlers.set(aTypeOfQuery, anHandler);\n }\n\n async execute(aQuery: TQuery): Promise<TProjection> {\n const handler = this.handlers.get(aQuery.type);\n if (!handler) {\n throw new Error(`No handler found for query type: ${aQuery.type}`);\n }\n return handler.execute(aQuery);\n }\n}\n","import type { Decider } from \"@domain/Decider.ts\";\nimport type { DomainEvent } from \"@domain/DomainEvent.ts\";\nimport type { Repository } from \"@domain/Repository.ts\";\nimport type { EventStore } from \"@infrastructure/EventStore/EventStore.ts\";\n\nexport class SimpleRepository<TState, TCommand, TEvent extends DomainEvent> implements Repository<\n TEvent,\n Promise<TState>,\n Promise<void>\n> {\n constructor(\n private readonly eventStore: EventStore<TEvent, Promise<void>, Promise<TEvent[]>>,\n readonly streamName: string,\n private readonly evolveFn: Decider<TState, TCommand, TEvent>[\"evolve\"],\n private readonly initialState: Decider<TState, TCommand, TEvent>[\"initialState\"],\n ) {}\n\n async load(aggregateId: string): Promise<TState> {\n const pastEvents = await this.eventStore.load(this.streamName, aggregateId);\n return pastEvents.reduce<TState>(this.evolveFn, this.initialState(aggregateId));\n }\n\n async store(events: TEvent[]): Promise<void> {\n await Promise.all(\n events.map(async (event) => this.eventStore.append(this.streamName, [event])),\n );\n }\n}\n","export function isEqual<T>(a: T, b: T): boolean {\n if (a === b) {\n return true;\n }\n\n // eslint-disable-next-line ts/strict-boolean-expressions\n const bothAreObjects = a && b && typeof a === \"object\" && typeof b === \"object\";\n\n return Boolean(\n bothAreObjects &&\n Object.keys(a).length === Object.keys(b).length &&\n Object.entries(a).every(([k, v]) => isEqual(v, b[k as keyof T])),\n );\n}\n","import type { Command } from \"@core/Command.ts\";\nimport type { Query } from \"@core/Query.ts\";\nimport type { BaseEvent } from \"@domain/BaseEvent.ts\";\nimport type { DomainEvent } from \"@domain/DomainEvent.ts\";\nimport type { Repository } from \"@domain/Repository.ts\";\nimport type { EventConsumer, EventProducer } from \"@infrastructure/EventBus/EventBus.js\";\nimport type { EventStore } from \"@infrastructure/EventStore/EventStore.ts\";\nimport type { OutboxWorker } from \"@infrastructure/Outbox/OutboxWorker.ts\";\nimport type { CommandBus } from \"../CommandBus/CommandBus.ts\";\nimport type { IntegrationEvent } from \"../EventBus/IntegrationEvent.ts\";\nimport type { QueryBus } from \"../QueryBus/QueryBus.ts\";\nimport { isCommand } from \"@core/utils/isCommand.ts\";\nimport { isQuery } from \"@core/utils/isQuery.ts\";\nimport { isDomainEvent } from \"@domain/utils/isDomainEvent.ts\";\nimport { isEvent } from \"@domain/utils/isEvent.ts\";\nimport { fail } from \"@utils/fail/fail.ts\";\nimport { invariant } from \"@utils/invariant/invariant.ts\";\nimport { isEqual } from \"@utils/isEqual/isEqual.ts\";\nimport { isIntegrationEvent } from \"../EventBus/utils/isIntegrationEvent.ts\";\n\ntype GivenInput = (DomainEvent | IntegrationEvent)[];\ntype WhenInput = Command | Query | DomainEvent | IntegrationEvent;\ntype ThenInput = DomainEvent | Array<Record<string, unknown>>;\n\nexport class ScenarioTest<TState, TEvent extends DomainEvent> {\n private givenInput: GivenInput = [];\n private whenInput: WhenInput | undefined;\n\n constructor(\n private readonly streamName: string,\n private readonly eventBus: EventProducer<BaseEvent> & EventConsumer<BaseEvent>,\n private readonly eventStore: EventStore<TEvent, Promise<void>, Promise<TEvent[]>>,\n private readonly commandBus: CommandBus<Command>,\n private readonly queryBus: QueryBus<Query, Promise<Record<string, unknown>[]>>,\n private readonly repository: Repository<DomainEvent, Promise<TState>>,\n private readonly outboxWorker: OutboxWorker,\n ) {}\n\n Given(...events: GivenInput): {\n When(action: WhenInput): ReturnType<ScenarioTest<TState, TEvent>[\"When\"]>;\n Then(outcome: ThenInput): Promise<void>;\n } {\n this.givenInput = events;\n return {\n When: this.When.bind(this),\n Then: this.Then.bind(this),\n };\n }\n\n When(action: WhenInput): {\n Then(outcome: ThenInput): Promise<void>;\n } {\n this.whenInput = action;\n return {\n Then: this.Then.bind(this),\n };\n }\n\n async Then(thenInput: ThenInput): Promise<void> {\n const domainEvents = this.givenInput.filter(isDomainEvent);\n const integrationEvents = this.givenInput.filter(isIntegrationEvent);\n\n await Promise.all([\n this.repository.store(domainEvents),\n ...integrationEvents.map(async (event) => this.eventBus.consume(this.streamName, event)),\n ]);\n\n if (!this.whenInput) {\n throw new Error(\"In the ScenarioTest, the when-step cannot be empty\");\n }\n\n if (isCommand(this.whenInput)) {\n invariant(\n isDomainEvent(thenInput),\n fail(new TypeError('When \"command\" expects a domain event in the then-step')),\n );\n await this.handleCommand(this.whenInput, thenInput);\n }\n\n if (isQuery(this.whenInput)) {\n invariant(\n Array.isArray(thenInput),\n fail(new TypeError('When \"query\" expects an array of expected results in the then-step')),\n );\n await this.handleQuery(this.whenInput, thenInput);\n }\n\n if (isDomainEvent(this.whenInput) || isIntegrationEvent(this.whenInput)) {\n invariant(\n isDomainEvent(thenInput),\n fail(\n new TypeError(\n 'When \"domain event\" or \"integration event\" expects a domain event in the then-step',\n ),\n ),\n );\n await this.handleEvent(this.whenInput, thenInput);\n }\n }\n\n private async handleCommand(command: Command, outcome: DomainEvent): Promise<void> {\n await this.commandBus.execute(command);\n const actualEvents = await this.eventStore.load(this.streamName, outcome.aggregateId);\n const foundEvent = actualEvents.findLast(\n (event) =>\n isDomainEvent(event) &&\n event.aggregateId === outcome.aggregateId &&\n event.type === outcome.type,\n );\n invariant(!!foundEvent, fail(new Error(\"ScenarioTest: event/command was not found\")));\n invariant(\n outcome.type === foundEvent.type,\n fail(new Error(\"ScenarioTest: event/command type was not equal\")),\n );\n invariant(\n outcome.aggregateId === foundEvent.aggregateId,\n fail(new Error(\"ScenarioTest: event/command aggregate id was not equal\")),\n );\n invariant(\n isEqual(outcome.payload, foundEvent.payload),\n fail(new Error(\"ScenarioTest: event/command payload was not equal\")),\n );\n }\n\n private async handleQuery(query: Query, expected: Array<Record<string, unknown>>): Promise<void> {\n await this.outboxWorker.tick();\n const actual = await this.queryBus.execute(query);\n invariant(\n isEqual(actual, expected),\n fail(new Error(\"ScenarioTest: a different query result was returned\")),\n );\n }\n\n private async handleEvent(\n event: DomainEvent | IntegrationEvent,\n outcome: DomainEvent,\n ): Promise<void> {\n await this.eventBus.publish(this.streamName, event);\n const actualEvents = await this.eventStore.load(this.streamName, outcome.aggregateId);\n const foundEvent = actualEvents.findLast(\n (event) =>\n isEvent(event) && event.aggregateId === outcome.aggregateId && event.type === outcome.type,\n );\n invariant(!!foundEvent, fail(new Error(\"ScenarioTest: event was not found\")));\n invariant(isEvent(foundEvent), fail(new Error(\"ScenarioTest: event is not of type event\")));\n invariant(\n outcome.type === foundEvent.type,\n fail(new Error(\"ScenarioTest: event type was not equal\")),\n );\n invariant(\n outcome.aggregateId === foundEvent.aggregateId,\n fail(new Error(\"ScenarioTest: event aggregate id was not equal\")),\n );\n invariant(\n isEqual(outcome.payload, foundEvent.payload),\n fail(new Error(\"ScenarioTest: event payload was not equal\")),\n );\n }\n}\n","export function parseAsError(value: unknown): Error {\n if (value instanceof Error) return value;\n if (typeof value === \"string\") return new Error(value);\n try {\n const json = JSON.stringify(value);\n return new Error(json ?? String(value));\n } catch {\n return new Error(\"Unknown error\");\n }\n}\n"]}