UNPKG

smart-saga-pattern

Version:

A library implementing the Saga pattern for microservice architecture

98 lines (97 loc) 2.97 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.SagaStepContainer = exports.COMPENSATION_METADATA = exports.INVOKE_METADATA = exports.SAGA_STEP_METADATA = void 0; exports.SagaStepDecorator = SagaStepDecorator; exports.Invoke = Invoke; exports.CompensationDecorator = CompensationDecorator; require("reflect-metadata"); // Metadata keys exports.SAGA_STEP_METADATA = "saga:step"; exports.INVOKE_METADATA = "saga:invoke"; exports.COMPENSATION_METADATA = "saga:compensation"; /** * Decorator to mark a class as a Saga step * @param options Options for the step */ function SagaStepDecorator(options = {}) { return (target) => { // Set default options const stepOptions = { order: 0, requiresCompensation: true, ...options, }; // Store metadata on the class Reflect.defineMetadata(exports.SAGA_STEP_METADATA, { name: target.name, options: stepOptions, }, target); // Register the step with the container SagaStepContainer.registerStep(target); }; } /** * Decorator to mark a method as the invoke function for a Saga step * @param options Options for the invoke method */ function Invoke(options = {}) { return (target, propertyKey, descriptor) => { // Store metadata on the method Reflect.defineMetadata(exports.INVOKE_METADATA, { methodName: propertyKey, options, }, target.constructor, propertyKey); return descriptor; }; } /** * Decorator to mark a method as the compensation function for a Saga step * @param options Options for the compensation method */ function CompensationDecorator(options = {}) { return (target, propertyKey, descriptor) => { // Store metadata on the method Reflect.defineMetadata(exports.COMPENSATION_METADATA, { methodName: propertyKey, options, }, target.constructor, propertyKey); return descriptor; }; } /** * Container for Saga steps */ class SagaStepContainer { /** * Registers a step with the container * @param stepClass Step class to register */ static registerStep(stepClass) { const metadata = Reflect.getMetadata(exports.SAGA_STEP_METADATA, stepClass); if (!metadata) { throw new Error(`Class ${stepClass.name} is not a valid Saga step`); } this.steps.set(stepClass.name, stepClass); } /** * Gets a step by name * @param name Name of the step */ static getStep(name) { return this.steps.get(name); } /** * Gets all registered steps */ static getAllSteps() { return Array.from(this.steps.values()); } /** * Clears all registered steps */ static clear() { this.steps.clear(); } } exports.SagaStepContainer = SagaStepContainer; SagaStepContainer.steps = new Map();