UNPKG

woltage

Version:

A CQRS and Event-Sourcing Framework

87 lines (86 loc) 4.52 kB
var __classPrivateFieldSet = (this && this.__classPrivateFieldSet) || function (receiver, state, value, kind, f) { if (kind === "m") throw new TypeError("Private method is not writable"); if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a setter"); if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot write private member to an object whose class did not declare it"); return (kind === "a" ? f.call(receiver, value) : f ? f.value = value : state.set(receiver, value)), value; }; var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (receiver, state, kind, f) { if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a getter"); if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot read private member from an object whose class did not declare it"); return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver); }; var _Aggregate_instances, _Aggregate_registry, _Aggregate_commands, _Aggregate_getStatus; import { z } from 'zod/v4'; import NotFoundError from "../errors/NotFoundError.js"; import EventStore from "../EventStore.js"; import { STATE_NEW } from "../adapters/EventStore.js"; import EventRegistry from "../EventRegistry.js"; import { executionStorage } from "../localStorages.js"; import validate from "../validate.js"; class Aggregate { static create(name, projector) { return new this(name, projector); } constructor(name, projector) { _Aggregate_instances.add(this); _Aggregate_registry.set(this, void 0); _Aggregate_commands.set(this, {}); this.name = name; this.projector = projector; __classPrivateFieldSet(this, _Aggregate_registry, new EventRegistry(projector), "f"); } registerCommand(schema, command, commandName) { if (typeof schema === 'function') { commandName = command; command = schema; schema = z.any(); } commandName = commandName ?? command.name; if (!commandName.length) throw new Error('Command has no name. Provide a named function or the commandName argument to registerCommand.'); if (__classPrivateFieldGet(this, _Aggregate_commands, "f")[commandName]) throw new Error(`Command '${commandName}' already exists in aggregate '${this.name}'.`); __classPrivateFieldGet(this, _Aggregate_commands, "f")[commandName] = { schema, command }; } async executeCommand(aggregateId, commandName, payload) { if (!__classPrivateFieldGet(this, _Aggregate_commands, "f")[commandName]) throw new NotFoundError(`Command ${commandName} not found for aggregate ${this.name}.`); const { schema, command } = __classPrivateFieldGet(this, _Aggregate_commands, "f")[commandName]; payload = validate(schema, payload); const { state, revision } = await __classPrivateFieldGet(this, _Aggregate_instances, "m", _Aggregate_getStatus).call(this, aggregateId); const context = Object.freeze({ ...(executionStorage.getStore()?.context ?? {}), aggregateId }); let events = await command(state, payload, context); if (!events) return; if (!Array.isArray(events)) events = [events]; events.forEach(event => { event.aggregateId = aggregateId; }); await EventStore.append(this.name, aggregateId, events, revision); } } _Aggregate_registry = new WeakMap(), _Aggregate_commands = new WeakMap(), _Aggregate_instances = new WeakSet(), _Aggregate_getStatus = async function _Aggregate_getStatus(aggregateId) { const events = EventStore.read(this.name, aggregateId); const status = { state: (this.projector.$init?.() ?? {}), revision: STATE_NEW, }; try { for await (const event of events) { status.revision = event.position; const { event: transformedEvent, handler = this.projector.$all } = await __classPrivateFieldGet(this, _Aggregate_registry, "f").get(event); status.state = handler?.(status.state, transformedEvent) ?? status.state; } return status; } catch (error) { if (error instanceof NotFoundError) return status; throw error; } }; export default Aggregate;