npm package: @sgod5904/mongoose-transaction-manager
Description: A Mongoose Transaction Manager inspired by Spring TX, for handling transactions in MongoDB with decorators. 
Author: Root
Latest version: 0.1.0

# Mongoose Transaction Manager

A Mongoose Transaction Manager library inspired by Spring TX, for handling transactions in MongoDB with decorators.

## Features

- **Declarative Transaction Management**: Use `@Transactional()` decorator to define transaction boundaries
- **Transaction Propagation**: Support for various propagation modes (REQUIRED, REQUIRES_NEW, etc.)
- **Transaction Isolation Levels**: Configurable isolation levels
- **Class-Level Transactions**: Apply transactions to all methods in a class with `@TransactionalClass()`
- **Transaction Hooks**: Register callbacks for transaction lifecycle events
- **Automatic Session Propagation**: No need to pass session objects through multiple layers
- **Rollback Control**: Configure which exceptions trigger rollback

## Installation

```bash
npm install @sgod5904/mongoose-transaction-manager
```

or

```bash
yarn add @sgod5904/mongoose-transaction-manager
```

## Basic Usage

### Step 1: Initialize the Transaction Context

Start by initializing the transaction context in your application:

```typescript
import { nextFn } from '@sgod5904/mongoose-transaction-manager';
import mongoose from 'mongoose';

// Your MongoDB connection
const connection = mongoose.connection;

// Wrap your function with nextFn to initialize the transaction context
await nextFn(connection, async () => {
  // Your code that will use transactions
}, { enableLog: true });
```

### Step 2: Use the Transactional Decorator

```typescript
import { Transactional, Propagation, IsolationLevel } from '@sgod5904/mongoose-transaction-manager';

class UserService {
  @Transactional({
    propagation: Propagation.REQUIRED,
    isolation: IsolationLevel.SNAPSHOT_ISOLATION,
    rollbackFor: [Error]
  })
  async createUser(userData: any) {
    // This method will use a transaction
    const user = new UserModel(userData);
    await user.save();
    return user;
  }
}
```

### Step 3: Apply Class-Level Transactions (Optional)

```typescript
import { TransactionalClass, Propagation } from '@sgod5904/mongoose-transaction-manager';

@TransactionalClass({
  propagation: Propagation.REQUIRED,
  rollbackFor: [Error]
})
class OrderService {
  // All methods in this class will use transactions 
  // based on the class-level configuration
  async createOrder(orderData: any) {
    // ...
  }
}
```

## Transaction Hooks

You can register hooks for different stages of a transaction:

```typescript
import { 
  Transactional, 
  $BeforeCommit, 
  $Committed, 
  $Rollback, 
  $Completed 
} from '@sgod5904/mongoose-transaction-manager';

class UserService {
  @Transactional()
  async createUser(userData: any) {
    // Register hooks
    $BeforeCommit(() => {
      console.log('Before committing transaction');
    });

    $Committed((result) => {
      console.log('Transaction committed successfully', result);
    });

    $Rollback((error) => {
      console.error('Transaction rolled back', error);
    });

    $Completed(() => {
      console.log('Transaction completed');
    });

    // Transaction code
    const user = new UserModel(userData);
    await user.save();
    return user;
  }
}
```

## Propagation Types

The library supports various propagation types:

- `REQUIRED`: Support a current transaction, create a new one if none exists (default).
- `REQUIRES_NEW`: Create a new transaction, and suspend the current transaction if one exists.
- `NESTED`: Execute within a nested transaction if a current transaction exists, behave like REQUIRED otherwise.
- `SUPPORTS`: Support a current transaction, execute non-transactional if none exists.
- `MANDATORY`: Support a current transaction, throw an exception if none exists.
- `NEVER`: Execute non-transactional, throw an exception if a transaction exists.
- `NOT_SUPPORTED`: Execute non-transactional, suspend the current transaction if one exists.

```typescript
import { Transactional, Propagation } from '@sgod5904/mongoose-transaction-manager';

class UserService {
  @Transactional({
    propagation: Propagation.REQUIRES_NEW
  })
  async createUser(userData: any) {
    // Always creates a new transaction
  }
}
```

## Error Handling and Rollback

By default, all exceptions will trigger a rollback. You can customize this behavior:

```typescript
import { Transactional } from '@sgod5904/mongoose-transaction-manager';

class UserService {
  @Transactional({
    // Rollback only for these error types
    rollbackFor: [DatabaseError, ValidationError],
    // Never rollback for these error types
    noRollbackFor: [NonCriticalError]
  })
  async createUser(userData: any) {
    // ...
  }
}
```

## License

MIT