woltage
Version:
A CQRS and Event-Sourcing Framework
48 lines (47 loc) • 1.97 kB
JavaScript
import { executionStorage } from "../localStorages.js";
import NotFoundError from "../errors/NotFoundError.js";
import validate from "../validate.js";
class ReadModel {
constructor() {
this.schemaRegistry = {};
this.validate = validate;
}
static getName(className) {
return className.toLowerCase();
}
static toString() {
return this.getName(this.name);
}
static get() {
const readModelMap = executionStorage.getStore()?.readModelMap;
if (!readModelMap)
throw new Error('Read model is not callable in this context.');
const readModelName = this.toString();
if (!readModelMap[readModelName])
throw new Error(`Read model ${readModelName} not found.`);
return readModelMap[readModelName];
}
get store() {
const projectionMap = executionStorage.getStore()?.projectionMap;
if (!projectionMap)
throw new Error(`Read model for '${this.projectionName}' is not callable in this context.`);
const projection = projectionMap.get(this.projectionName);
if (!projection)
throw new Error(`Projection '${this.projectionName}' not found.`);
return projection.projector.store;
}
async call(handlerName, query) {
if (!(handlerName in this) || Object.getOwnPropertyNames(ReadModel.prototype).includes(handlerName))
throw new NotFoundError(`Handler '${handlerName}' of read model '${this.constructor.name}' not found.`);
const handler = this[handlerName];
if (handler instanceof Function) {
if (handler.name in this.schemaRegistry)
query = this.validate(this.schemaRegistry[handler.name], query);
const context = Object.freeze({
...(executionStorage.getStore()?.context ?? {}),
});
return handler.bind(this)(query, context);
}
}
}
export default ReadModel;