@tmorin/ceb-messaging-simple
Version:
The package is part of the `<ceb/>` library. It provides an implementation of the messaging model leveraging on a vanilla TypeScript/JavaScript environment.
101 lines • 3.92 kB
JavaScript
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
};
import { MessageBuilder, } from "@tmorin/ceb-messaging-core";
import { waitForReturn } from "./common";
/**
* The symbol used to register {@link SimpleCommandBus}.
*/
export const SimpleCommandBusSymbol = Symbol.for("ceb/inversion/SimpleCommandBus");
export class SimpleCommandBus {
constructor(eventBus, emitter, handlers = new Map()) {
this.eventBus = eventBus;
this.emitter = emitter;
this.handlers = handlers;
}
get observer() {
return this.emitter;
}
execute(command, options) {
return __awaiter(this, void 0, void 0, function* () {
this.emitter.emit("command_received", {
bus: this,
command,
});
const handler = this.resolveHandler(command);
const opts = Object.assign({ timeout: 500 }, options);
const result = yield waitForReturn(() => __awaiter(this, void 0, void 0, function* () { return yield handler(command); }), opts.timeout)
.then((output) => this.processHandlerOutput(output))
.catch((error) => {
this.emitter.emit("command_handler_failed", {
bus: this,
command,
error,
});
throw error;
});
// @ts-ignore
return result || MessageBuilder.result(command).type("empty").build();
});
}
executeAndForget(command) {
this.emitter.emit("command_received", {
bus: this,
command,
});
const handler = this.resolveHandler(command);
Promise.resolve((() => __awaiter(this, void 0, void 0, function* () { return handler(command); }))())
.then((output) => this.processHandlerOutput(output))
.catch((error) => {
this.emitter.emit("command_handler_failed", {
bus: this,
command,
error,
});
});
}
handle(commandType, handler) {
if (this.handlers.has(commandType)) {
throw new Error(`the command type ${commandType} is already handled`);
}
this.handlers.set(commandType, handler);
return {
remove: () => {
this.handlers.delete(commandType);
},
};
}
dispose() {
return __awaiter(this, void 0, void 0, function* () {
this.handlers.clear();
this.emitter.emit("disposed", { bus: this });
});
}
resolveHandler(command) {
const handler = this.handlers.get(command.headers.messageType);
if (handler) {
return handler;
}
const error = new Error(`handler not found for ${command.headers.messageType}`);
this.emitter.emit("command_handler_not_found", {
bus: this,
command,
error,
});
throw error;
}
processHandlerOutput(output) {
var _a;
if (output) {
(_a = output.events) === null || _a === void 0 ? void 0 : _a.forEach((event) => this.eventBus.publish(event));
return output.result;
}
}
}
//# sourceMappingURL=command.js.map