npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@hazeljs/saga

v1.0.5

Published

Saga pattern implementation for HazelJS - Orchestration and Choreography for distributed transactions

Downloads

777

Readme

@hazeljs/saga

Distributed Transaction Management for HazelJS. Orchestration, Choreography, and Auto-Compensation.

Manage complex, multi-service transactions with ease. Whether you prefer centralized control (Orchestration) or decentralized event-driven flows (Choreography), HazelJS Saga provides a robust, decorator-based framework to ensure data consistency across your distributed system.

npm version npm downloads License: Apache-2.0

Features

  • 🔄 Dual Models — Orchestration for centralized control and Choreography for decentralized, event-driven coordination.
  • 🛠️ Decorator-Based API — Declarative Saga definition using @Saga, @SagaStep, and @OnEvent.
  • Auto-Compensation — Automatically reverses completed steps in reverse order when a failure occurs.
  • 📊 Status Management — Built-in tracking for STARTED, COMPENSATING, ABORTED, and COMPLETED states.
  • 🧠 Context Awareness — Type-safe SagaContext to pass state and data across multiple transaction steps.
  • 🔌 HazelJS Integration — Seamlessly works with @hazeljs/event-emitter and @hazeljs/core.

Installation

npm install @hazeljs/saga

Peer Dependencies

@hazeljs/saga works with @hazeljs/core for runtime integration and @hazeljs/event-emitter for choreography events. Install them alongside:

npm install @hazeljs/core @hazeljs/event-emitter

You do not need to install or import reflect-metadata yourself. @hazeljs/saga declares it as a regular dependency and its decorator modules load it via a side-effect import. Just enable experimentalDecorators in your tsconfig.json.


Quick Start (Orchestration)

The Orchestration model uses a central class to coordinate the workflow. If a step fails, compensation methods are automatically triggered.

1. Define the Saga

import { Saga, SagaStep } from '@hazeljs/saga';

@Saga({ name: 'order-saga' })
export class OrderSaga {
  @SagaStep({ order: 1, compensate: 'cancelOrder' })
  async createOrder(data: any) {
    console.log('Order created for:', data.productId);
    return { orderId: 'ord_123' };
  }

  @SagaStep({ order: 2, compensate: 'releaseInventory' })
  async reserveInventory(data: any) {
    // Logic to reserve stock...
    return { status: 'RESERVED' };
  }

  async cancelOrder(data: any) {
    console.log('Reversing order...');
  }

  async releaseInventory(data: any) {
    console.log('Releasing stock...');
  }
}

2. Execute the Saga

import { SagaOrchestrator } from '@hazeljs/saga';

const orchestrator = SagaOrchestrator.getInstance();
const context = await orchestrator.start('order-saga', { productId: 'p1', userId: 'u1' });

console.log(`Saga Status: ${context.status}`); // COMPLETED or ABORTED

Orchestration vs. Choreography

| Feature | Orchestration | Choreography | | -------------- | ----------------------------------- | ---------------------------------------------- | | Control | Centralized in one class | Decentralized across handlers | | Coupling | High (Orchestrator knows all steps) | Low (Each service reacts to events) | | Complexity | Simple for small/medium flows | Better for very large, loosely coupled systems | | Visibility | Single point of truth | Distributed across the system |


Saga Choreography

Choreography is entirely event-driven. Handlers subscribe to events and emit new ones to trigger the next phase of the transaction.

import { SagaChoreography, OnEvent } from '@hazeljs/saga';

@SagaChoreography()
export class ShippingChoreography {
  @OnEvent('inventory.reserved')
  async handleInventoryReserved(order: any) {
    console.log('Shipping label generated for:', order.id);
    // Emit 'shipping.labeled' to continue the flow
  }

  @OnEvent('payment.failed')
  async handlePaymentFailed(order: any) {
    console.log('Cancelling shipping for:', order.id);
    // Manual compensation for choreography
  }
}

Saga Lifecycle & Statuses

The SagaContext tracks the status of the transaction as it progresses:

| Status | Description | | -------------- | ------------------------------------------------------ | | STARTED | Execution has begun. | | COMPLETED | All steps finished successfully. | | FAILED | A step encountered an error; compensation is pending. | | COMPENSATING | Reversing previously completed steps. | | ABORTED | Compensation finished; the transaction is rolled back. |


API Reference

SagaOrchestrator

class SagaOrchestrator {
  static getInstance(): SagaOrchestrator;
  registerSaga(name: string, target: any): void;
  registerStep(sagaName: string, methodName: string, options: SagaStepOptions): void;
  start<T>(sagaName: string, initialData: T): Promise<SagaContext<T>>;
}

Decorators

  • @Saga(options) — Marks a class as a centralized Saga Orchestrator.
  • @SagaStep(options) — Marks a method as a step. Options include order and compensate (method name).
  • @SagaChoreography() — Marks a class as a collection of event-driven saga handlers.
  • @OnEvent(eventName) — Subscribes a method to a specific event within a choreography.

Use Cases

  • 🛒 E-commerce Checkout — Coordinating orders, payments, and inventory.
  • 🏨 Hotel/Flight Bookings — Managing multi-vendor reservation systems.
  • 💳 Financial Transfers — Ensuring atomic-like consistency across different account services.
  • 🏗️ Infrastructure Provisioning — rolling back cloud resource creation on failure.

License

Apache-2.0

Contributing

Contributions are welcome! See CONTRIBUTING.md for details.