woltage
Version:
A CQRS and Event-Sourcing Framework
87 lines (86 loc) • 4.52 kB
JavaScript
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;