@arts-n-crafts/ts 3.17.0 → 3.17.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@arts-n-crafts/ts",
3
- "version": "3.17.0",
3
+ "version": "3.17.1",
4
4
  "repository": {
5
5
  "type": "git",
6
6
  "url": "git+https://github.com/arts-n-crafts/typescript.git"
@@ -228,6 +228,11 @@ function isDomainEvent(event) {
228
228
  return isEvent(event) && "aggregateId" in event && event.kind === "domain";
229
229
  }
230
230
 
231
+ // src/domain/utils/isRejection.ts
232
+ function isRejection(event) {
233
+ return isEvent(event) && "commandId" in event && "reasonCode" in event && event.kind === "rejection";
234
+ }
235
+
231
236
  // src/infrastructure/CommandBus/implementations/SimpleCommandBus.ts
232
237
  var SimpleCommandBus = class {
233
238
  handlers = /* @__PURE__ */ new Map();
@@ -580,6 +585,7 @@ exports.isEqual = isEqual;
580
585
  exports.isEvent = isEvent;
581
586
  exports.isIntegrationEvent = isIntegrationEvent;
582
587
  exports.isQuery = isQuery;
588
+ exports.isRejection = isRejection;
583
589
  exports.makeStreamKey = makeStreamKey;
584
590
  exports.parseAsError = parseAsError;
585
591
  //# sourceMappingURL=index.cjs.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/core/utils/getTimestamp.ts","../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/createRejection.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/utils/isEqual/isEqual.ts","../src/utils/parseAsError/parseAsError.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"],"names":["randomUUID","Operation","event"],"mappings":"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","file":"index.cjs","sourcesContent":["export const getTimestamp = (date: Date = new Date()): number => Math.floor(date.getTime() / 1000)\n","import type { Command, CommandMetadata } from '@core/Command.ts'\nimport { randomUUID } from 'node:crypto'\nimport { getTimestamp } from '@core/utils/getTimestamp.ts'\n\nexport function createCommand<TType extends string, TPayload>(type: TType, aggregateId: string, aggregateType: string, payload: TPayload, metadata: Partial<CommandMetadata> = {}): Command<TType, TPayload> {\n return Object.freeze({\n id: randomUUID(),\n type,\n aggregateType,\n aggregateId: String(aggregateId),\n payload,\n kind: 'command',\n timestamp: getTimestamp(),\n metadata,\n })\n}\n","import type { Query, QueryMetadata } from '@core/Query.ts'\nimport { randomUUID } from 'node:crypto'\nimport { getTimestamp } from '@core/utils/getTimestamp.ts'\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: getTimestamp(),\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 interface Specification<T> {\n isSatisfiedBy(entity: T): boolean\n}\n\nexport abstract class CompositeSpecification<T> implements Specification<T> {\n abstract isSatisfiedBy(entity: T): boolean\n\n abstract toQuery(): QueryNode\n\n and(other: CompositeSpecification<T>): CompositeSpecification<T> {\n return new AndSpecification(this, other)\n }\n\n or(other: CompositeSpecification<T>): CompositeSpecification<T> {\n return new OrSpecification(this, other)\n }\n\n not(): CompositeSpecification<T> {\n return new NotSpecification(this)\n }\n}\n\nexport class AndSpecification<T> extends CompositeSpecification<T> {\n constructor(private left: CompositeSpecification<T>, private right: CompositeSpecification<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 CompositeSpecification<T> {\n constructor(private left: CompositeSpecification<T>, private right: CompositeSpecification<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 CompositeSpecification<T> {\n constructor(private spec: CompositeSpecification<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 { CompositeSpecification } from '../Specification.ts'\nimport { createQueryNode } from '../utils/createQueryNode.ts'\n\nexport class FieldEquals<T> extends CompositeSpecification<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 { CompositeSpecification } from '../Specification.ts'\nimport { createQueryNode } from '../utils/createQueryNode.ts'\n\nexport class FieldGreaterThan<T> extends CompositeSpecification<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'\nimport { getTimestamp } from '@core/utils/getTimestamp.ts'\n\nexport function createDomainEvent<TPayload = unknown>(\n type: string,\n aggregateId: string,\n aggregateType: string,\n payload: TPayload,\n metadata: Partial<DomainEventMetadata> = {},\n): DomainEvent<TPayload> {\n return Object.freeze({\n id: randomUUID(),\n type,\n aggregateId,\n aggregateType,\n payload,\n kind: 'domain',\n timestamp: getTimestamp(),\n metadata,\n })\n}\n","import type { Rejection, RejectionMetadata } from '@domain/Rejection.ts'\nimport { randomUUID } from 'node:crypto'\nimport { getTimestamp } from '@core/utils/getTimestamp.ts'\n\nexport function createRejection<TDetails = unknown>(\n rejectionSpecifics: {\n commandId: Rejection['commandId']\n commandType: Rejection['commandType']\n reasonCode: Rejection['reasonCode']\n reason?: Rejection['reason']\n aggregateType?: Rejection['aggregateType']\n aggregateId?: Rejection['aggregateId']\n classification: Rejection['classification']\n retryable?: Rejection['retryable']\n validationErrors?: Rejection['validationErrors']\n type: 'Failed' | 'Rejected' | string\n details?: TDetails\n },\n metadata: Partial<RejectionMetadata> = {},\n): Rejection<TDetails> {\n return Object.freeze({\n id: randomUUID(),\n commandId: rejectionSpecifics.commandId,\n commandType: rejectionSpecifics.commandType,\n reasonCode: rejectionSpecifics.reasonCode,\n reason: rejectionSpecifics.reason,\n aggregateType: rejectionSpecifics.aggregateType,\n aggregateId: rejectionSpecifics.aggregateId,\n classification: rejectionSpecifics.classification,\n retryable: rejectionSpecifics.retryable,\n validationErrors: rejectionSpecifics.validationErrors,\n type: `${rejectionSpecifics.commandType}${rejectionSpecifics.type}`,\n details: rejectionSpecifics.details,\n kind: 'rejection',\n timestamp: getTimestamp(),\n metadata,\n })\n}\n","import type { DomainEvent } from '@domain/DomainEvent.ts'\nimport type { Rejection } from '@domain/Rejection.ts'\nimport type { ExternalEvent } from '@infrastructure/EventBus/ExternalEvent.ts'\nimport type { IntegrationEvent } from '@infrastructure/EventBus/IntegrationEvent.ts'\n\nexport function isEvent(event: unknown): event is DomainEvent | IntegrationEvent | ExternalEvent | Rejection {\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 'kind' 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.kind === 'domain'\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 { CompositeSpecification } 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: CompositeSpecification<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 { CompositeSpecification } 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: CompositeSpecification<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 { DomainEvent } from '@domain/DomainEvent.ts'\nimport type { ExternalEvent } from '@infrastructure/EventBus/ExternalEvent.ts'\nimport type { IntegrationEvent } from '@infrastructure/EventBus/IntegrationEvent.ts'\nimport type { EventConsumer, EventProducer } from '../EventBus.ts'\n\nexport class SimpleEventBus<TEvent extends DomainEvent | IntegrationEvent | ExternalEvent>\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 timestamp: new Date().toISOString(),\n metadata: {\n ...metadata,\n },\n kind: 'integration',\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.kind === 'integration'\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","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","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","import type { DomainEvent } from '@domain/DomainEvent.ts'\nimport type { StoredEvent } from '../StoredEvent.ts'\nimport { getTimestamp } from '@core/utils/getTimestamp.ts'\nimport { makeStreamKey } from '@utils/index.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 timestamp: getTimestamp(),\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 { DomainEvent } from '@domain/DomainEvent.ts'\nimport type { EventProducer } from '@infrastructure/EventBus/EventBus.js'\nimport type { ExternalEvent } from '@infrastructure/EventBus/ExternalEvent.ts'\nimport type { IntegrationEvent } from '@infrastructure/EventBus/IntegrationEvent.ts'\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<DomainEvent | IntegrationEvent | ExternalEvent>,\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'\nimport { getTimestamp } from '@core/utils/getTimestamp.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 = getTimestamp()\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 { Rejection } from '@domain/Rejection.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, TRejection extends Rejection> 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, TRejection>['evolve'],\n private readonly initialState: Decider<TState, TCommand, TEvent, TRejection>['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"]}
1
+ {"version":3,"sources":["../src/core/utils/getTimestamp.ts","../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/createRejection.ts","../src/domain/utils/isEvent.ts","../src/domain/utils/isDomainEvent.ts","../src/domain/utils/isRejection.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/utils/isEqual/isEqual.ts","../src/utils/parseAsError/parseAsError.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"],"names":["randomUUID","Operation","event"],"mappings":"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","file":"index.cjs","sourcesContent":["export const getTimestamp = (date: Date = new Date()): number => Math.floor(date.getTime() / 1000)\n","import type { Command, CommandMetadata } from '@core/Command.ts'\nimport { randomUUID } from 'node:crypto'\nimport { getTimestamp } from '@core/utils/getTimestamp.ts'\n\nexport function createCommand<TType extends string, TPayload>(type: TType, aggregateId: string, aggregateType: string, payload: TPayload, metadata: Partial<CommandMetadata> = {}): Command<TType, TPayload> {\n return Object.freeze({\n id: randomUUID(),\n type,\n aggregateType,\n aggregateId: String(aggregateId),\n payload,\n kind: 'command',\n timestamp: getTimestamp(),\n metadata,\n })\n}\n","import type { Query, QueryMetadata } from '@core/Query.ts'\nimport { randomUUID } from 'node:crypto'\nimport { getTimestamp } from '@core/utils/getTimestamp.ts'\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: getTimestamp(),\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 interface Specification<T> {\n isSatisfiedBy(entity: T): boolean\n}\n\nexport abstract class CompositeSpecification<T> implements Specification<T> {\n abstract isSatisfiedBy(entity: T): boolean\n\n abstract toQuery(): QueryNode\n\n and(other: CompositeSpecification<T>): CompositeSpecification<T> {\n return new AndSpecification(this, other)\n }\n\n or(other: CompositeSpecification<T>): CompositeSpecification<T> {\n return new OrSpecification(this, other)\n }\n\n not(): CompositeSpecification<T> {\n return new NotSpecification(this)\n }\n}\n\nexport class AndSpecification<T> extends CompositeSpecification<T> {\n constructor(private left: CompositeSpecification<T>, private right: CompositeSpecification<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 CompositeSpecification<T> {\n constructor(private left: CompositeSpecification<T>, private right: CompositeSpecification<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 CompositeSpecification<T> {\n constructor(private spec: CompositeSpecification<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 { CompositeSpecification } from '../Specification.ts'\nimport { createQueryNode } from '../utils/createQueryNode.ts'\n\nexport class FieldEquals<T> extends CompositeSpecification<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 { CompositeSpecification } from '../Specification.ts'\nimport { createQueryNode } from '../utils/createQueryNode.ts'\n\nexport class FieldGreaterThan<T> extends CompositeSpecification<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'\nimport { getTimestamp } from '@core/utils/getTimestamp.ts'\n\nexport function createDomainEvent<TPayload = unknown>(\n type: string,\n aggregateId: string,\n aggregateType: string,\n payload: TPayload,\n metadata: Partial<DomainEventMetadata> = {},\n): DomainEvent<TPayload> {\n return Object.freeze({\n id: randomUUID(),\n type,\n aggregateId,\n aggregateType,\n payload,\n kind: 'domain',\n timestamp: getTimestamp(),\n metadata,\n })\n}\n","import type { Rejection, RejectionMetadata } from '@domain/Rejection.ts'\nimport { randomUUID } from 'node:crypto'\nimport { getTimestamp } from '@core/utils/getTimestamp.ts'\n\nexport function createRejection<TDetails = unknown>(\n rejectionSpecifics: {\n commandId: Rejection['commandId']\n commandType: Rejection['commandType']\n reasonCode: Rejection['reasonCode']\n reason?: Rejection['reason']\n aggregateType?: Rejection['aggregateType']\n aggregateId?: Rejection['aggregateId']\n classification: Rejection['classification']\n retryable?: Rejection['retryable']\n validationErrors?: Rejection['validationErrors']\n type: 'Failed' | 'Rejected' | string\n details?: TDetails\n },\n metadata: Partial<RejectionMetadata> = {},\n): Rejection<TDetails> {\n return Object.freeze({\n id: randomUUID(),\n commandId: rejectionSpecifics.commandId,\n commandType: rejectionSpecifics.commandType,\n reasonCode: rejectionSpecifics.reasonCode,\n reason: rejectionSpecifics.reason,\n aggregateType: rejectionSpecifics.aggregateType,\n aggregateId: rejectionSpecifics.aggregateId,\n classification: rejectionSpecifics.classification,\n retryable: rejectionSpecifics.retryable,\n validationErrors: rejectionSpecifics.validationErrors,\n type: `${rejectionSpecifics.commandType}${rejectionSpecifics.type}`,\n details: rejectionSpecifics.details,\n kind: 'rejection',\n timestamp: getTimestamp(),\n metadata,\n })\n}\n","import type { DomainEvent } from '@domain/DomainEvent.ts'\nimport type { Rejection } from '@domain/Rejection.ts'\nimport type { ExternalEvent } from '@infrastructure/EventBus/ExternalEvent.ts'\nimport type { IntegrationEvent } from '@infrastructure/EventBus/IntegrationEvent.ts'\n\nexport function isEvent(event: unknown): event is DomainEvent | IntegrationEvent | ExternalEvent | Rejection {\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 'kind' 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.kind === 'domain'\n}\n","import type { Rejection } from '@domain/Rejection.ts'\nimport { isEvent } from './isEvent.ts'\n\nexport function isRejection(event: unknown): event is Rejection {\n return isEvent(event)\n && 'commandId' in event\n && 'reasonCode' in event\n && event.kind === 'rejection'\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 { CompositeSpecification } 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: CompositeSpecification<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 { CompositeSpecification } 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: CompositeSpecification<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 { DomainEvent } from '@domain/DomainEvent.ts'\nimport type { ExternalEvent } from '@infrastructure/EventBus/ExternalEvent.ts'\nimport type { IntegrationEvent } from '@infrastructure/EventBus/IntegrationEvent.ts'\nimport type { EventConsumer, EventProducer } from '../EventBus.ts'\n\nexport class SimpleEventBus<TEvent extends DomainEvent | IntegrationEvent | ExternalEvent>\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 timestamp: new Date().toISOString(),\n metadata: {\n ...metadata,\n },\n kind: 'integration',\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.kind === 'integration'\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","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","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","import type { DomainEvent } from '@domain/DomainEvent.ts'\nimport type { StoredEvent } from '../StoredEvent.ts'\nimport { getTimestamp } from '@core/utils/getTimestamp.ts'\nimport { makeStreamKey } from '@utils/index.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 timestamp: getTimestamp(),\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 { DomainEvent } from '@domain/DomainEvent.ts'\nimport type { EventProducer } from '@infrastructure/EventBus/EventBus.js'\nimport type { ExternalEvent } from '@infrastructure/EventBus/ExternalEvent.ts'\nimport type { IntegrationEvent } from '@infrastructure/EventBus/IntegrationEvent.ts'\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<DomainEvent | IntegrationEvent | ExternalEvent>,\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'\nimport { getTimestamp } from '@core/utils/getTimestamp.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 = getTimestamp()\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 { Rejection } from '@domain/Rejection.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, TRejection extends Rejection> 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, TRejection>['evolve'],\n private readonly initialState: Decider<TState, TCommand, TEvent, TRejection>['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"]}
@@ -362,6 +362,8 @@ declare function isDomainEvent(event: unknown): event is DomainEvent;
362
362
 
363
363
  declare function isEvent(event: unknown): event is DomainEvent | IntegrationEvent | ExternalEvent | Rejection;
364
364
 
365
+ declare function isRejection(event: unknown): event is Rejection;
366
+
365
367
  interface Registerable$1<TCommand extends Command, TResult = void> {
366
368
  register(aTypeOfCommand: TCommand['type'], anHandler: CommandHandler<TCommand>): TResult;
367
369
  }
@@ -572,4 +574,4 @@ declare function parseAsError(value: unknown): Error;
572
574
 
573
575
  declare function makeStreamKey(streamName: string, aggregateId: string): StreamKey;
574
576
 
575
- export { type AggregateRoot, AndSpecification, type BaseMetadata, type Command, type CommandBus, type CommandHandler, type CommandMetadata, CompositeSpecification, type CreateStatement, type Database, type Decider, type DeleteStatement, type Directive, type DomainEvent, type DomainEventMetadata, type EventBasedAggregateRoot, type EventConsumer, type EventHandler, type EventProducer, type EventStore, FieldEquals, FieldGreaterThan, type FilledArray, GenericOutboxWorker, type ISODateTime, InMemoryOutbox, type IntegrationEvent, type IntegrationEventMetadata, type Maybe, type Module, NotSpecification, type Nullable, Operation, OrSpecification, type Outbox, type OutboxEntry, type OutboxWorker, type PatchStatement, type Primitive, type PutStatement, type Query, type QueryBus, type QueryHandler, type QueryMetadata, type QueryNode, type Rejection, type RejectionMetadata, type Repository, SimpleCommandBus, SimpleDatabase, SimpleEventBus, SimpleEventStore, SimpleQueryBus, SimpleRepository, type Specification, type StoredEvent, type StreamKey, type UnixTimestampInSeconds, type WithIdentifier, createCommand, createDomainEvent, createIntegrationEvent, createOutboxEntry, createQuery, createQueryNode, createRejection, createStoredEvent, fail, getTimestamp, invariant, isCommand, isDomainEvent, isEqual, isEvent, isIntegrationEvent, isQuery, makeStreamKey, parseAsError };
577
+ export { type AggregateRoot, AndSpecification, type BaseMetadata, type Command, type CommandBus, type CommandHandler, type CommandMetadata, CompositeSpecification, type CreateStatement, type Database, type Decider, type DeleteStatement, type Directive, type DomainEvent, type DomainEventMetadata, type EventBasedAggregateRoot, type EventConsumer, type EventHandler, type EventProducer, type EventStore, FieldEquals, FieldGreaterThan, type FilledArray, GenericOutboxWorker, type ISODateTime, InMemoryOutbox, type IntegrationEvent, type IntegrationEventMetadata, type Maybe, type Module, NotSpecification, type Nullable, Operation, OrSpecification, type Outbox, type OutboxEntry, type OutboxWorker, type PatchStatement, type Primitive, type PutStatement, type Query, type QueryBus, type QueryHandler, type QueryMetadata, type QueryNode, type Rejection, type RejectionMetadata, type Repository, SimpleCommandBus, SimpleDatabase, SimpleEventBus, SimpleEventStore, SimpleQueryBus, SimpleRepository, type Specification, type StoredEvent, type StreamKey, type UnixTimestampInSeconds, type WithIdentifier, createCommand, createDomainEvent, createIntegrationEvent, createOutboxEntry, createQuery, createQueryNode, createRejection, createStoredEvent, fail, getTimestamp, invariant, isCommand, isDomainEvent, isEqual, isEvent, isIntegrationEvent, isQuery, isRejection, makeStreamKey, parseAsError };
@@ -362,6 +362,8 @@ declare function isDomainEvent(event: unknown): event is DomainEvent;
362
362
 
363
363
  declare function isEvent(event: unknown): event is DomainEvent | IntegrationEvent | ExternalEvent | Rejection;
364
364
 
365
+ declare function isRejection(event: unknown): event is Rejection;
366
+
365
367
  interface Registerable$1<TCommand extends Command, TResult = void> {
366
368
  register(aTypeOfCommand: TCommand['type'], anHandler: CommandHandler<TCommand>): TResult;
367
369
  }
@@ -572,4 +574,4 @@ declare function parseAsError(value: unknown): Error;
572
574
 
573
575
  declare function makeStreamKey(streamName: string, aggregateId: string): StreamKey;
574
576
 
575
- export { type AggregateRoot, AndSpecification, type BaseMetadata, type Command, type CommandBus, type CommandHandler, type CommandMetadata, CompositeSpecification, type CreateStatement, type Database, type Decider, type DeleteStatement, type Directive, type DomainEvent, type DomainEventMetadata, type EventBasedAggregateRoot, type EventConsumer, type EventHandler, type EventProducer, type EventStore, FieldEquals, FieldGreaterThan, type FilledArray, GenericOutboxWorker, type ISODateTime, InMemoryOutbox, type IntegrationEvent, type IntegrationEventMetadata, type Maybe, type Module, NotSpecification, type Nullable, Operation, OrSpecification, type Outbox, type OutboxEntry, type OutboxWorker, type PatchStatement, type Primitive, type PutStatement, type Query, type QueryBus, type QueryHandler, type QueryMetadata, type QueryNode, type Rejection, type RejectionMetadata, type Repository, SimpleCommandBus, SimpleDatabase, SimpleEventBus, SimpleEventStore, SimpleQueryBus, SimpleRepository, type Specification, type StoredEvent, type StreamKey, type UnixTimestampInSeconds, type WithIdentifier, createCommand, createDomainEvent, createIntegrationEvent, createOutboxEntry, createQuery, createQueryNode, createRejection, createStoredEvent, fail, getTimestamp, invariant, isCommand, isDomainEvent, isEqual, isEvent, isIntegrationEvent, isQuery, makeStreamKey, parseAsError };
577
+ export { type AggregateRoot, AndSpecification, type BaseMetadata, type Command, type CommandBus, type CommandHandler, type CommandMetadata, CompositeSpecification, type CreateStatement, type Database, type Decider, type DeleteStatement, type Directive, type DomainEvent, type DomainEventMetadata, type EventBasedAggregateRoot, type EventConsumer, type EventHandler, type EventProducer, type EventStore, FieldEquals, FieldGreaterThan, type FilledArray, GenericOutboxWorker, type ISODateTime, InMemoryOutbox, type IntegrationEvent, type IntegrationEventMetadata, type Maybe, type Module, NotSpecification, type Nullable, Operation, OrSpecification, type Outbox, type OutboxEntry, type OutboxWorker, type PatchStatement, type Primitive, type PutStatement, type Query, type QueryBus, type QueryHandler, type QueryMetadata, type QueryNode, type Rejection, type RejectionMetadata, type Repository, SimpleCommandBus, SimpleDatabase, SimpleEventBus, SimpleEventStore, SimpleQueryBus, SimpleRepository, type Specification, type StoredEvent, type StreamKey, type UnixTimestampInSeconds, type WithIdentifier, createCommand, createDomainEvent, createIntegrationEvent, createOutboxEntry, createQuery, createQueryNode, createRejection, createStoredEvent, fail, getTimestamp, invariant, isCommand, isDomainEvent, isEqual, isEvent, isIntegrationEvent, isQuery, isRejection, makeStreamKey, parseAsError };
@@ -226,6 +226,11 @@ function isDomainEvent(event) {
226
226
  return isEvent(event) && "aggregateId" in event && event.kind === "domain";
227
227
  }
228
228
 
229
+ // src/domain/utils/isRejection.ts
230
+ function isRejection(event) {
231
+ return isEvent(event) && "commandId" in event && "reasonCode" in event && event.kind === "rejection";
232
+ }
233
+
229
234
  // src/infrastructure/CommandBus/implementations/SimpleCommandBus.ts
230
235
  var SimpleCommandBus = class {
231
236
  handlers = /* @__PURE__ */ new Map();
@@ -546,6 +551,6 @@ var SimpleRepository = class {
546
551
  }
547
552
  };
548
553
 
549
- export { AndSpecification, CompositeSpecification, FieldEquals, FieldGreaterThan, GenericOutboxWorker, InMemoryOutbox, NotSpecification, Operation, OrSpecification, SimpleCommandBus, SimpleDatabase, SimpleEventBus, SimpleEventStore, SimpleQueryBus, SimpleRepository, createCommand, createDomainEvent, createIntegrationEvent, createOutboxEntry, createQuery, createQueryNode, createRejection, createStoredEvent, fail, getTimestamp, invariant, isCommand, isDomainEvent, isEqual, isEvent, isIntegrationEvent, isQuery, makeStreamKey, parseAsError };
554
+ export { AndSpecification, CompositeSpecification, FieldEquals, FieldGreaterThan, GenericOutboxWorker, InMemoryOutbox, NotSpecification, Operation, OrSpecification, SimpleCommandBus, SimpleDatabase, SimpleEventBus, SimpleEventStore, SimpleQueryBus, SimpleRepository, createCommand, createDomainEvent, createIntegrationEvent, createOutboxEntry, createQuery, createQueryNode, createRejection, createStoredEvent, fail, getTimestamp, invariant, isCommand, isDomainEvent, isEqual, isEvent, isIntegrationEvent, isQuery, isRejection, makeStreamKey, parseAsError };
550
555
  //# sourceMappingURL=index.js.map
551
556
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/core/utils/getTimestamp.ts","../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/createRejection.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/utils/isEqual/isEqual.ts","../src/utils/parseAsError/parseAsError.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"],"names":["randomUUID","Operation","event"],"mappings":"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","file":"index.js","sourcesContent":["export const getTimestamp = (date: Date = new Date()): number => Math.floor(date.getTime() / 1000)\n","import type { Command, CommandMetadata } from '@core/Command.ts'\nimport { randomUUID } from 'node:crypto'\nimport { getTimestamp } from '@core/utils/getTimestamp.ts'\n\nexport function createCommand<TType extends string, TPayload>(type: TType, aggregateId: string, aggregateType: string, payload: TPayload, metadata: Partial<CommandMetadata> = {}): Command<TType, TPayload> {\n return Object.freeze({\n id: randomUUID(),\n type,\n aggregateType,\n aggregateId: String(aggregateId),\n payload,\n kind: 'command',\n timestamp: getTimestamp(),\n metadata,\n })\n}\n","import type { Query, QueryMetadata } from '@core/Query.ts'\nimport { randomUUID } from 'node:crypto'\nimport { getTimestamp } from '@core/utils/getTimestamp.ts'\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: getTimestamp(),\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 interface Specification<T> {\n isSatisfiedBy(entity: T): boolean\n}\n\nexport abstract class CompositeSpecification<T> implements Specification<T> {\n abstract isSatisfiedBy(entity: T): boolean\n\n abstract toQuery(): QueryNode\n\n and(other: CompositeSpecification<T>): CompositeSpecification<T> {\n return new AndSpecification(this, other)\n }\n\n or(other: CompositeSpecification<T>): CompositeSpecification<T> {\n return new OrSpecification(this, other)\n }\n\n not(): CompositeSpecification<T> {\n return new NotSpecification(this)\n }\n}\n\nexport class AndSpecification<T> extends CompositeSpecification<T> {\n constructor(private left: CompositeSpecification<T>, private right: CompositeSpecification<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 CompositeSpecification<T> {\n constructor(private left: CompositeSpecification<T>, private right: CompositeSpecification<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 CompositeSpecification<T> {\n constructor(private spec: CompositeSpecification<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 { CompositeSpecification } from '../Specification.ts'\nimport { createQueryNode } from '../utils/createQueryNode.ts'\n\nexport class FieldEquals<T> extends CompositeSpecification<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 { CompositeSpecification } from '../Specification.ts'\nimport { createQueryNode } from '../utils/createQueryNode.ts'\n\nexport class FieldGreaterThan<T> extends CompositeSpecification<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'\nimport { getTimestamp } from '@core/utils/getTimestamp.ts'\n\nexport function createDomainEvent<TPayload = unknown>(\n type: string,\n aggregateId: string,\n aggregateType: string,\n payload: TPayload,\n metadata: Partial<DomainEventMetadata> = {},\n): DomainEvent<TPayload> {\n return Object.freeze({\n id: randomUUID(),\n type,\n aggregateId,\n aggregateType,\n payload,\n kind: 'domain',\n timestamp: getTimestamp(),\n metadata,\n })\n}\n","import type { Rejection, RejectionMetadata } from '@domain/Rejection.ts'\nimport { randomUUID } from 'node:crypto'\nimport { getTimestamp } from '@core/utils/getTimestamp.ts'\n\nexport function createRejection<TDetails = unknown>(\n rejectionSpecifics: {\n commandId: Rejection['commandId']\n commandType: Rejection['commandType']\n reasonCode: Rejection['reasonCode']\n reason?: Rejection['reason']\n aggregateType?: Rejection['aggregateType']\n aggregateId?: Rejection['aggregateId']\n classification: Rejection['classification']\n retryable?: Rejection['retryable']\n validationErrors?: Rejection['validationErrors']\n type: 'Failed' | 'Rejected' | string\n details?: TDetails\n },\n metadata: Partial<RejectionMetadata> = {},\n): Rejection<TDetails> {\n return Object.freeze({\n id: randomUUID(),\n commandId: rejectionSpecifics.commandId,\n commandType: rejectionSpecifics.commandType,\n reasonCode: rejectionSpecifics.reasonCode,\n reason: rejectionSpecifics.reason,\n aggregateType: rejectionSpecifics.aggregateType,\n aggregateId: rejectionSpecifics.aggregateId,\n classification: rejectionSpecifics.classification,\n retryable: rejectionSpecifics.retryable,\n validationErrors: rejectionSpecifics.validationErrors,\n type: `${rejectionSpecifics.commandType}${rejectionSpecifics.type}`,\n details: rejectionSpecifics.details,\n kind: 'rejection',\n timestamp: getTimestamp(),\n metadata,\n })\n}\n","import type { DomainEvent } from '@domain/DomainEvent.ts'\nimport type { Rejection } from '@domain/Rejection.ts'\nimport type { ExternalEvent } from '@infrastructure/EventBus/ExternalEvent.ts'\nimport type { IntegrationEvent } from '@infrastructure/EventBus/IntegrationEvent.ts'\n\nexport function isEvent(event: unknown): event is DomainEvent | IntegrationEvent | ExternalEvent | Rejection {\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 'kind' 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.kind === 'domain'\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 { CompositeSpecification } 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: CompositeSpecification<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 { CompositeSpecification } 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: CompositeSpecification<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 { DomainEvent } from '@domain/DomainEvent.ts'\nimport type { ExternalEvent } from '@infrastructure/EventBus/ExternalEvent.ts'\nimport type { IntegrationEvent } from '@infrastructure/EventBus/IntegrationEvent.ts'\nimport type { EventConsumer, EventProducer } from '../EventBus.ts'\n\nexport class SimpleEventBus<TEvent extends DomainEvent | IntegrationEvent | ExternalEvent>\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 timestamp: new Date().toISOString(),\n metadata: {\n ...metadata,\n },\n kind: 'integration',\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.kind === 'integration'\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","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","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","import type { DomainEvent } from '@domain/DomainEvent.ts'\nimport type { StoredEvent } from '../StoredEvent.ts'\nimport { getTimestamp } from '@core/utils/getTimestamp.ts'\nimport { makeStreamKey } from '@utils/index.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 timestamp: getTimestamp(),\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 { DomainEvent } from '@domain/DomainEvent.ts'\nimport type { EventProducer } from '@infrastructure/EventBus/EventBus.js'\nimport type { ExternalEvent } from '@infrastructure/EventBus/ExternalEvent.ts'\nimport type { IntegrationEvent } from '@infrastructure/EventBus/IntegrationEvent.ts'\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<DomainEvent | IntegrationEvent | ExternalEvent>,\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'\nimport { getTimestamp } from '@core/utils/getTimestamp.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 = getTimestamp()\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 { Rejection } from '@domain/Rejection.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, TRejection extends Rejection> 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, TRejection>['evolve'],\n private readonly initialState: Decider<TState, TCommand, TEvent, TRejection>['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"]}
1
+ {"version":3,"sources":["../src/core/utils/getTimestamp.ts","../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/createRejection.ts","../src/domain/utils/isEvent.ts","../src/domain/utils/isDomainEvent.ts","../src/domain/utils/isRejection.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/utils/isEqual/isEqual.ts","../src/utils/parseAsError/parseAsError.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"],"names":["randomUUID","Operation","event"],"mappings":"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","file":"index.js","sourcesContent":["export const getTimestamp = (date: Date = new Date()): number => Math.floor(date.getTime() / 1000)\n","import type { Command, CommandMetadata } from '@core/Command.ts'\nimport { randomUUID } from 'node:crypto'\nimport { getTimestamp } from '@core/utils/getTimestamp.ts'\n\nexport function createCommand<TType extends string, TPayload>(type: TType, aggregateId: string, aggregateType: string, payload: TPayload, metadata: Partial<CommandMetadata> = {}): Command<TType, TPayload> {\n return Object.freeze({\n id: randomUUID(),\n type,\n aggregateType,\n aggregateId: String(aggregateId),\n payload,\n kind: 'command',\n timestamp: getTimestamp(),\n metadata,\n })\n}\n","import type { Query, QueryMetadata } from '@core/Query.ts'\nimport { randomUUID } from 'node:crypto'\nimport { getTimestamp } from '@core/utils/getTimestamp.ts'\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: getTimestamp(),\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 interface Specification<T> {\n isSatisfiedBy(entity: T): boolean\n}\n\nexport abstract class CompositeSpecification<T> implements Specification<T> {\n abstract isSatisfiedBy(entity: T): boolean\n\n abstract toQuery(): QueryNode\n\n and(other: CompositeSpecification<T>): CompositeSpecification<T> {\n return new AndSpecification(this, other)\n }\n\n or(other: CompositeSpecification<T>): CompositeSpecification<T> {\n return new OrSpecification(this, other)\n }\n\n not(): CompositeSpecification<T> {\n return new NotSpecification(this)\n }\n}\n\nexport class AndSpecification<T> extends CompositeSpecification<T> {\n constructor(private left: CompositeSpecification<T>, private right: CompositeSpecification<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 CompositeSpecification<T> {\n constructor(private left: CompositeSpecification<T>, private right: CompositeSpecification<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 CompositeSpecification<T> {\n constructor(private spec: CompositeSpecification<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 { CompositeSpecification } from '../Specification.ts'\nimport { createQueryNode } from '../utils/createQueryNode.ts'\n\nexport class FieldEquals<T> extends CompositeSpecification<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 { CompositeSpecification } from '../Specification.ts'\nimport { createQueryNode } from '../utils/createQueryNode.ts'\n\nexport class FieldGreaterThan<T> extends CompositeSpecification<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'\nimport { getTimestamp } from '@core/utils/getTimestamp.ts'\n\nexport function createDomainEvent<TPayload = unknown>(\n type: string,\n aggregateId: string,\n aggregateType: string,\n payload: TPayload,\n metadata: Partial<DomainEventMetadata> = {},\n): DomainEvent<TPayload> {\n return Object.freeze({\n id: randomUUID(),\n type,\n aggregateId,\n aggregateType,\n payload,\n kind: 'domain',\n timestamp: getTimestamp(),\n metadata,\n })\n}\n","import type { Rejection, RejectionMetadata } from '@domain/Rejection.ts'\nimport { randomUUID } from 'node:crypto'\nimport { getTimestamp } from '@core/utils/getTimestamp.ts'\n\nexport function createRejection<TDetails = unknown>(\n rejectionSpecifics: {\n commandId: Rejection['commandId']\n commandType: Rejection['commandType']\n reasonCode: Rejection['reasonCode']\n reason?: Rejection['reason']\n aggregateType?: Rejection['aggregateType']\n aggregateId?: Rejection['aggregateId']\n classification: Rejection['classification']\n retryable?: Rejection['retryable']\n validationErrors?: Rejection['validationErrors']\n type: 'Failed' | 'Rejected' | string\n details?: TDetails\n },\n metadata: Partial<RejectionMetadata> = {},\n): Rejection<TDetails> {\n return Object.freeze({\n id: randomUUID(),\n commandId: rejectionSpecifics.commandId,\n commandType: rejectionSpecifics.commandType,\n reasonCode: rejectionSpecifics.reasonCode,\n reason: rejectionSpecifics.reason,\n aggregateType: rejectionSpecifics.aggregateType,\n aggregateId: rejectionSpecifics.aggregateId,\n classification: rejectionSpecifics.classification,\n retryable: rejectionSpecifics.retryable,\n validationErrors: rejectionSpecifics.validationErrors,\n type: `${rejectionSpecifics.commandType}${rejectionSpecifics.type}`,\n details: rejectionSpecifics.details,\n kind: 'rejection',\n timestamp: getTimestamp(),\n metadata,\n })\n}\n","import type { DomainEvent } from '@domain/DomainEvent.ts'\nimport type { Rejection } from '@domain/Rejection.ts'\nimport type { ExternalEvent } from '@infrastructure/EventBus/ExternalEvent.ts'\nimport type { IntegrationEvent } from '@infrastructure/EventBus/IntegrationEvent.ts'\n\nexport function isEvent(event: unknown): event is DomainEvent | IntegrationEvent | ExternalEvent | Rejection {\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 'kind' 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.kind === 'domain'\n}\n","import type { Rejection } from '@domain/Rejection.ts'\nimport { isEvent } from './isEvent.ts'\n\nexport function isRejection(event: unknown): event is Rejection {\n return isEvent(event)\n && 'commandId' in event\n && 'reasonCode' in event\n && event.kind === 'rejection'\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 { CompositeSpecification } 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: CompositeSpecification<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 { CompositeSpecification } 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: CompositeSpecification<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 { DomainEvent } from '@domain/DomainEvent.ts'\nimport type { ExternalEvent } from '@infrastructure/EventBus/ExternalEvent.ts'\nimport type { IntegrationEvent } from '@infrastructure/EventBus/IntegrationEvent.ts'\nimport type { EventConsumer, EventProducer } from '../EventBus.ts'\n\nexport class SimpleEventBus<TEvent extends DomainEvent | IntegrationEvent | ExternalEvent>\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 timestamp: new Date().toISOString(),\n metadata: {\n ...metadata,\n },\n kind: 'integration',\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.kind === 'integration'\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","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","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","import type { DomainEvent } from '@domain/DomainEvent.ts'\nimport type { StoredEvent } from '../StoredEvent.ts'\nimport { getTimestamp } from '@core/utils/getTimestamp.ts'\nimport { makeStreamKey } from '@utils/index.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 timestamp: getTimestamp(),\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 { DomainEvent } from '@domain/DomainEvent.ts'\nimport type { EventProducer } from '@infrastructure/EventBus/EventBus.js'\nimport type { ExternalEvent } from '@infrastructure/EventBus/ExternalEvent.ts'\nimport type { IntegrationEvent } from '@infrastructure/EventBus/IntegrationEvent.ts'\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<DomainEvent | IntegrationEvent | ExternalEvent>,\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'\nimport { getTimestamp } from '@core/utils/getTimestamp.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 = getTimestamp()\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 { Rejection } from '@domain/Rejection.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, TRejection extends Rejection> 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, TRejection>['evolve'],\n private readonly initialState: Decider<TState, TCommand, TEvent, TRejection>['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"]}