UNPKG

smart-saga-pattern

Version:

A library implementing the Saga pattern for microservice architecture

130 lines (129 loc) 4.58 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.StructuredSagaOrchestrator = void 0; const Saga_1 = require("../core/Saga"); const StructuredSagaExecutor_1 = require("./StructuredSagaExecutor"); const types_1 = require("../types"); /** * Orchestrator for executing Sagas with structured context * The context is structured as: * { * global: { ... }, * steps: { * "Step Name": { * input: { ... }, * output: { ... }, * compensation: { ... } * } * } * } * @template T Type of the input data * @template R Type of the result data */ class StructuredSagaOrchestrator extends Saga_1.Saga { /** * Creates a new StructuredSagaOrchestrator * @param definition Saga definition to orchestrate * @param options Saga options * @param stateStore Optional state store for persistence */ constructor(definition, options = {}, stateStore) { super(options); this.definition = definition; this.stateStore = stateStore; } /** * Executes the Saga * @param initialData Initial data for the Saga */ async execute(initialData) { try { // Update context with initial data if (initialData) { // Structure the initial data const structuredData = this.structureInitialData(initialData); this.updateContext(structuredData); } else { // Initialize empty structured data this.updateContext({ global: {}, steps: {} }); } // Save initial state if state store is provided if (this.stateStore) { await this.stateStore.save(this.getId(), this.getContext()); } // Create executor and execute the Saga const executor = new StructuredSagaExecutor_1.StructuredSagaExecutor(this.definition, this.getContext()); const result = await executor.execute(); // Update context with result this.context = result; // Update state store if provided if (this.stateStore) { await this.stateStore.update(this.getId(), this.context); } return this.getContext(); } catch (error) { this.setStatus(types_1.SagaStatus.FAILED, error instanceof Error ? error.message : String(error)); // Update state store if provided if (this.stateStore) { await this.stateStore.update(this.getId(), this.context); } return this.getContext(); } } /** * Structures the initial data into the format: * { * global: initialData, * steps: {} * } * @param initialData Initial data */ structureInitialData(initialData) { // If the data is already structured, return it as is if (initialData && typeof initialData === 'object' && 'global' in initialData && 'steps' in initialData) { return initialData; } // Otherwise, structure it return { global: initialData || {}, steps: {} }; } /** * Compensates the Saga (rolls back) */ async compensate() { try { this.setStatus(types_1.SagaStatus.COMPENSATING); // Update state store if provided if (this.stateStore) { await this.stateStore.update(this.getId(), this.context); } // Create executor and execute compensation const executor = new StructuredSagaExecutor_1.StructuredSagaExecutor(this.definition, this.getContext()); const result = await executor.execute(); // Update context with result this.context = result; // Update state store if provided if (this.stateStore) { await this.stateStore.update(this.getId(), this.context); } return this.getContext(); } catch (error) { this.setStatus(types_1.SagaStatus.COMPENSATION_FAILED, error instanceof Error ? error.message : String(error)); // Update state store if provided if (this.stateStore) { await this.stateStore.update(this.getId(), this.context); } return this.getContext(); } } } exports.StructuredSagaOrchestrator = StructuredSagaOrchestrator;