DEV Community

Cover image for Distributed Sagas, Locking, and Zero-Config Documentation in NodeJS
Muhammad Arslan
Muhammad Arslan

Posted on

Distributed Sagas, Locking, and Zero-Config Documentation in NodeJS

We are thrilled to announce the release of HazelJS v0.4.0, a major update focused on building resilient, distributed systems with ease. This release introduces two powerhouse packagesβ€”@hazeljs/saga and @hazeljs/distributed-lockβ€”along with significant observability and developer productivity enhancements across our entire ecosystem.

As the HazelJS ecosystem continues to grow with 45+ specialized packages, we remain committed to our mission: providing a modular, AI-native framework that scales from local experiments to production-grade distributed architectures.

What's New in v0.4.0?


1. Distributed Sagas (@hazeljs/saga) πŸ”„

Managing data consistency in microservices shouldn't require complex, manual state machine code. @hazeljs/saga brings declarative distributed transactions to HazelJS with both Orchestration and Choreography patterns.

Key Features:

  • Dual Pattern Support: Choose between centralized orchestration or decentralized event-driven choreography
  • Decorator-Based API: Clean, intuitive @Saga, @SagaStep, and @OnEvent decorators
  • Auto-Compensation: Automatic reversal of completed steps in reverse order on failure
  • Status Management: Built-in tracking for STARTED, COMPENSATING, ABORTED, and COMPLETED states
  • Type-Safe Context: Pass state and data across transaction steps with full TypeScript support

Orchestration Example:

@Saga({ name: 'checkout-saga' })
export class CheckoutSaga {
  @SagaStep({ order: 1, compensate: 'cancelReservation' })
  async reserveProduct(ctx: SagaContext) {
    return await this.inventory.reserve(ctx.input.productId);
  }

  @SagaStep({ order: 2, compensate: 'refund' })
  async chargeUser(ctx: SagaContext) {
    return await this.payment.charge(ctx.input.userId, ctx.input.amount);
  }

  async cancelReservation(ctx: SagaContext) {
    await this.inventory.cancel(ctx.input.productId);
  }
}
Enter fullscreen mode Exit fullscreen mode

Choreography Example:

@Injectable()
export class OrderService {
  @OnEvent('order.created')
  async handleOrderCreated(data: any) {
    // Automatically participates in distributed transaction
    await this.processOrder(data);
  }
}
Enter fullscreen mode Exit fullscreen mode

2. Distributed Locking (@hazeljs/distributed-lock) πŸ”’

Race conditions can destroy data integrity in multi-node environments. @hazeljs/distributed-lock provides first-class mutual exclusion with Redis and In-Memory backends.

Key Features:

  • Decorator-Based API: @DistributedLock() for declarative method-level locking
  • Dynamic Key Resolution: Template placeholders ({id}, {user.token}) resolve from method arguments
  • Multiple Backends: Redis for production, Memory for development/testing
  • Atomic Mutual Exclusion: Exactly one process executes critical sections across all nodes
  • Configurable Strategies: Retry counts, delays, TTLs, and wait behaviors
  • Automatic Cleanup: Locks released on method completion, regardless of success/failure

Usage:

@Injectable()
export class StockService {
  @DistributedLock({ 
    key: 'update-stock-{{productId}}', 
    ttl: 10000, 
    wait: true 
  })
  async decrementStock(productId: string) {
    // Only one instance can execute this for the same productId
    return await this.db.update(productId);
  }
}
Enter fullscreen mode Exit fullscreen mode

3. Zero-Config Swagger Documentation πŸ“š

Documentation should keep up with your code, not slow you down. @hazeljs/swagger now features generateAutoSpec(), producing complete OpenAPI 3.0 specifications by scanning your module's controllersβ€”no decorators required.

Key Features:

  • Zero-Config Generation: Complete API specs without adding a single decorator
  • Path Discovery: Automatic detection of routes including complex path parameters
  • Smart Summaries: Infers operation descriptions from TypeScript method names
  • Method Mapping: Correct handling of GET, POST, PUT, DELETE, and PATCH methods
  • Default Schemas: Automatic inclusion of 400 and 500 error response schemas

How it works:

import { SwaggerService } from '@hazeljs/swagger';
import { AppModule } from './app.module';

@Service()
export class MyDocService {
  constructor(private readonly swagger: SwaggerService) {}

  getDocs() {
    // Discovers all controllers in AppModule and builds a spec
    return this.swagger.generateAutoSpec(AppModule, {
      title: 'Auto-Generated API',
      version: '1.0.0'
    });
  }
}
Enter fullscreen mode Exit fullscreen mode

4. Core Observability: Performance Monitoring & Tracing πŸ“Š

Observability is now a first-class citizen in HazelJS Core with built-in performance monitoring and OpenTelemetry support.

Performance Monitoring:

// Built-in performance hooks
app.addPerformanceHook(BuiltinPerformanceHooks.slowRequestLogger(1000));
app.addPerformanceHook(BuiltinPerformanceHooks.memoryMonitor());
app.addPerformanceHook(BuiltinPerformanceHooks.metricsCollector());

// Custom hooks
app.addPerformanceHook({
  name: 'custom-metrics',
  onResponse: (metrics) => {
    // Track custom metrics
    this.metrics.track(metrics.duration, metrics.statusCode);
  }
});
Enter fullscreen mode Exit fullscreen mode

Tracing with @trace:

@Service()
export class AIService {
  @Trace('ai.generate_summary')
  async summarize(text: string) {
    // Execution time automatically tracked and exported
    return await this.llm.call(text);
  }
}
Enter fullscreen mode Exit fullscreen mode

Key Features:

  • Built-in Hooks: Slow request logger, memory monitor, rate limiter, metrics collector
  • Custom Hooks: Easy extension with custom performance monitoring
  • OpenTelemetry Integration: @Trace decorator for automatic span creation
  • Request Lifecycle: Full request tracking from start to finish
  • Performance Metrics: Active requests, response times, error rates

5. Enhanced Error Handling with EnhancedErrors 🚨

Consistency is key to a great developer experience. The new EnhancedErrors utility provides standardized error handling with helpful suggestions and context.

Key Features:

  • Standardized Errors: Consistent error codes and messages across your application
  • Helpful Suggestions: Automatic suggestions for common error scenarios
  • Context Preservation: Maintain request context and metadata
  • Type Safety: Full TypeScript support with proper error typing

Usage:

if (!user) {
  throw EnhancedErrors.notFound('User not found in registry');
}

if (!permission) {
  throw EnhancedErrors.unauthorized('Insufficient permissions');
}

if (validationError) {
  throw EnhancedErrors.validationFailed('Invalid input data');
}
Enter fullscreen mode Exit fullscreen mode

Available Error Types:

  • validationFailed() - 400 Bad Request
  • unauthorized() - 401 Unauthorized
  • notFound() - 404 Not Found
  • methodNotAllowed() - 405 Method Not Allowed
  • rateLimitExceeded() - 429 Too Many Requests

6. Lazy Loading for Performance Optimization ⚑

New lazy loading capabilities in the Core DI container improve startup performance and reduce memory usage.

Key Features:

  • Module-Level Lazy: Load entire modules only when needed
  • Provider-Level Lazy: Individual providers instantiate on first use
  • Circular Dependency Handling: Graceful resolution of circular dependencies
  • Memory Optimization: Reduced initial memory footprint

Usage:

@Lazy()
@Injectable()
export class HeavyService {
  // Only instantiated when first resolved
}

@Module({
  lazy: true, // Entire module loads lazily
  providers: [HeavyService]
})
export class LazyModule {}
Enter fullscreen mode Exit fullscreen mode

Ecosystem Highlights: 45+ Packages & Growing

HazelJS v0.4.0 continues our commitment to modularity with specialized packages for every need:

AI & Machine Learning πŸ€–

  • @hazeljs/ai - Multi-provider AI integration (OpenAI, Anthropic, Gemini, Cohere, Ollama)
  • @hazeljs/rag - Complete RAG + GraphRAG pipeline with 11 document loaders
  • @hazeljs/ml - Machine learning utilities and model management
  • @hazeljs/prompts - Prompt engineering and template management
  • @hazeljs/guardrails - AI safety and content filtering

Data & Persistence πŸ’Ύ

  • @hazeljs/data - Data pipelines and ETL workflows
  • @hazeljs/prisma - Prisma ORM integration
  • @hazeljs/typeorm - TypeORM integration
  • @hazeljs/cache - Multi-backend caching (Redis, Memory, etc.)

Distributed Systems 🌐

  • @hazeljs/saga - Distributed transaction management
  • @hazeljs/distributed-lock - Cross-node mutual exclusion
  • @hazeljs/kafka - Apache Kafka integration
  • @hazeljs/messaging - Message queue abstractions
  • @hazeljs/event-emitter - Event-driven architecture

Security & Auth πŸ”

  • @hazeljs/auth - Authentication and authorization
  • @hazeljs/oauth - OAuth 2.0 integration
  • @hazeljs/casl - Access control lists
  • @hazelcs/security-headers - Security middleware

Observability & Monitoring πŸ“ˆ

  • @hazeljs/observability - Metrics and tracing
  • @hazeljs/inspector - Application inspection and debugging
  • @hazeljs/audit - Audit logging and compliance

Developer Tools πŸ› οΈ

  • @hazeljs/cli - Command-line interface and scaffolding
  • @hazeljs/testing - Enhanced testing utilities
  • @hazeljs/flow - Workflow and orchestration engine
  • @hazeljs/serverless - Serverless deployment support

Performance & Quality Improvements

Test Coverage: 83.73% 🎯

  • Performance Monitoring: 91.8% coverage
  • Enhanced Errors: 90.56% coverage
  • Container DI: 80.68% coverage
  • Overall Suite: 908 passing tests

TypeScript Enhancements

  • Strict Type Safety: Improved type inference across all packages
  • Better IntelliSense: Enhanced IDE support with proper exports
  • Reduced Bundle Size: Optimized imports and tree-shaking support

Developer Experience

  • Zero-Config Defaults: Sensible defaults that work out of the box
  • Progressive Enhancement: Start simple, add complexity as needed
  • Unified APIs: Consistent patterns across all packages

Migration Guide

From v0.3.x to v0.4.0

The migration is straightforward with most changes being additive:

# Update existing packages
npm update @hazeljs/core @hazeljs/swagger

# Add new packages (optional)
npm install @hazeljs/saga @hazeljs/distributed-lock
Enter fullscreen mode Exit fullscreen mode

Breaking Changes

  • None - This is a fully backward-compatible release

Recommended Upgrades

  1. Add Performance Monitoring: Enable built-in performance hooks
  2. Implement Enhanced Errors: Standardize error handling
  3. Try Zero-Config Docs: Replace manual Swagger decorators with auto-generation
  4. Evaluate Distributed Needs: Consider sagas and locking for multi-node deployments

Getting Started

New Project Setup

# Install HazelJS CLI
npm install -g @hazeljs/cli

# Create new project
hazel create my-app

# Add distributed features
cd my-app
npm install @hazeljs/saga @hazeljs/distributed-lock
Enter fullscreen mode Exit fullscreen mode

Existing Project Enhancement

# Update to latest
npm update @hazeljs/core @hazeljs/swagger

# Add new capabilities
npm install @hazeljs/saga @hazeljs/distributed-lock @hazeljs/ai
Enter fullscreen mode Exit fullscreen mode

What's Next?

Looking ahead to v0.5.0, we're focusing on:

  • Advanced Observability: Distributed tracing and APM integrations
  • GraphQL Enhancements: Federation and subscription improvements
  • AI Agent Framework: Multi-agent systems with coordination
  • Edge Computing: Optimizations for serverless and edge deployments
  • Performance Tuning: Further optimizations for high-throughput scenarios

HazelJS v0.4.0 represents our most significant release yet, bringing enterprise-grade distributed systems capabilities to the Node.js ecosystem while maintaining the simplicity and developer experience that makes HazelJS special.

Join thousands of developers building the next generation of TypeScript applications with HazelJS.

HazelJS: The Future of Modular, AI-Native TypeScript Frameworks.


Related Links

πŸ“š Documentation & Guides

πŸš€ Quick Start Resources

πŸ”§ Package Documentation

πŸ€– AI & ML Resources

Top comments (0)