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 🙏

© 2024 – Pkg Stats / Ryan Hefner

pipe-transaction

v1.1.1

Published

The official library for managing multi-stage operations. Support async actions

Downloads

40

Readme

Welcome to pipe-transaction 👋

Version License: MIT Stars npm version

pipe-transaction is the official library for managing multi-stage operations.

pipe-transaction designed to easily deal with common situations that you are want to perform several related actions. This process will be considered a success only if all the actions are performed.

In another hand, if any process fails along the way - the situation became complicated. In this case, you want to be able to return to the initial state as much as another state as a result of the failure. For this purpose exactly, pipe-transaction developed.

For example, if you want to update the database through CRUD API, after executing action (such as saving a file), pipe-transaction helps you to return to the initial state (delete the file) if the database update failed.

The library is very easy to use and allows a wide range of different options. pipe-transaction support async & sync actions at once.

The official library for managing multi-stage operations.

Installation

$ npm install pipe-transaction

Importing

// Using Node.js `require()`
const { Transaction } = require('pipe-transaction');

// Using ES6 imports
import { Transaction } from 'pipe-transaction';

Usage

new Transaction([options], [actions])

Create a new Transaction instance. options(optional) - an object that includes the setting of the Transaction instance.

  • showLogs: Boolean. Allow the library to write errors & information messages to the console. Default is true.
  • autoIdGenerate: Boolean. Allow the library to generate an automatic number id for the actions, start from 0. Default is false.
  • continueOnUndoError: Boolean. When an action failed, Allow the library to continue to execute all relevant undo functions, even if an undo function failed. Default true.
  • retryOptions: An object which maps to the retry module options:
    • retries: Number. The maximum amount of times to retry the operation. Default is 3.
    • factor: Number. The exponential factor to use. Default is 2.
    • minTimeout: Number. The number of milliseconds before starting the first retry. Default is 1000.
    • maxTimeout: Number. The maximum number of milliseconds between two retries. Default is Infinity.
    • randomize: Boolean. Randomizes the timeouts by multiplying with a factor between 1 to 2. Default is false.
    • errorRetryHandler: Function. Custom callback function that should be called if retry of action is failed. The errorRetryHandler function received two arguments: First retyNumber - The number of failed retries, starts from 0. Second transactionsInfo - Object that describe the transactions statues (see below for transactionsInfo structure).

actions(optional) - Array of actions description (see below for action structure).

exec()

Execute the actions pipeline. Return result object (see below for result structure) if all the actions succeed, or if an action failed but all the relevant undo actions succeed. Throw result object if an action failed and at least a relevant unto action failed.

Models

action = {
    action: ( transactionsInfo: transactionsInfo, actionArgs?: object) => any
    actionArgs: {} // Any (optional)
    undoArgs: {} // Any (optional)
    undo?: (error: any, transactionsInfo: transactionsInfo, undoArgs?: object) => any
}

transactionsInfo = {
    transactions: action[],
    currentTransaction: action,
    previousResponses: { [id]: value },
    previousUndoResponses?: { [id]: value }
}

 result = {
    isSuccess: Boolean, // If an action failed - return false  
    actionsInfo: {
        responses: {
            [id]: value
        }
        errorInfo?: { // If an action failed
            index: number,
            id: string | number,
            error: Error
        }
    },
    undoInfo?: { // if isSuccess === false
        responses: {
            [id]: value
        },
        errorInfo?: [ // / If an undo action failed
            {
                index: number,
                id: string | number,
                error: Error
            }
        ]
    }
}

Method

  • clear() - Clear the transaction instance from actions.
  • isValidAction(action) - Check if an action is valid. Return array of erros messages.
  • append(action) - Append an action to the actions list.
  • appendArray(action[]) - Append actions to the actions list.
  • remove(id) - Remove an action from the actions list.
  • getTransactions() - Get all the actions.

Example

const Transaction = require('pipe-transaction');

// Simple example
const transaction = new Transaction({
    showLogs: true,
    continueOnUndoError: true
}, [
    {
        id: "start",
        action: () => console.log('Start') // Just a sync function
    }
    {
        id: "notifyInProgress"
        actionArgs: {id: "1"},
        undoArgs: {id: "1"},
        // Just an async function, using actionArgs
        action: (transactionsInfo, actionArgs) =>
            notifyInProgress(actionArgs.id),
        // Just an async function, using undoArgs
        undo: (error, transactionsInfo, undoArgs) => notifyFailed(undoArgs.id) 
    },
    {
        id: "saveInDb"
        // Just an async function, using previousResponses
        action: (transactionsInfo) => saveInDb(
             transactionsInfo.previousResponses["notifyInProgress"]
        ),
        // Just an async function, using previousResponses
        undo: (error, transactionsInfo) => deleteInDb(
             transactionsInfo.previousResponses["notifyInProgress"].id
        ),
    },
    {
        id: "notifyEnd"
        actionArgs: {id: "1"},
        undoArgs: {id: "1"},
        // Just an async function, using actionArgs
        action: (transactionsInfo, actionArgs) => 
            notifyEnd(actionArgs.id),
    }
]);

transaction.exec()
    .then(result => {
        if(result.isSuccess) 
            console.log("The transaction success, all actions done");
        else 
            console.log("The transaction failed, not all actions done. 
                All relevant undo actions executed");
                
        // result = {
        //     isSuccess: false,
        //     actionsInfo: {
        //          responses: {
        //              start: undefined,
        //              notifyInProgress: {
        //                  id: 1,
        //                  starus: "InProgress"
        //              },
        //              saveInDb: "1234",
        //          },
        //          errorInfo: {
        //              index: 3,
        //              id: "notifyEnd",
        //              error: Error
        //          }
        //     },
        //     undoInfo: {
        //         responses: {
        //              start: undefined,
        //              notifyInProgress: "Successfuly notify failed message",
        //              saveInDb: undefined,
        //          }   
        //     }
        // }
    }).catch(result => {
        console.log("The transaction failed, not all actions done. Undo 
          actions pipeline executed and at least one undo action failed");
                
        // result = {
        //     isSuccess: false,
        //     actionsInfo: {
        //          responses: {
        //              start: undefined,
        //              notifyInProgress: {
        //                  id: 1,
        //                  starus: "InProgress"
        //              },
        //              saveInDb: "1234",
        //          },
        //          errorInfo: {
        //              index: 3,
        //              id: "notifyEnd",
        //              error: Error
        //          }
        //     },
        //     undoInfo: {
        //         responses: {
        //              start: undefined,
        //              saveInDb: undefined,
        //          },
        //          errorInfo" [
        //              {
        //                   index: 1,
        //                   id: "notifyInProgress",
        //                   error: Error
        //              }
        //          ]
        //     }
        // }
    });
    
transaction .clear();

// Other way
const transaction = new Transaction({
    showLogs: true,
    continueOnUndoError: true
})

transaction.appendArray([
    {
        id: "start",
        action: () => console.log('Start') // Just a sync function
    }
    {
        id: "notifyInProgress"
        actionArgs: {id: "1"},
        undoArgs: {id: "1"},
        // Just an async function, using actionArgs
        action: (transactionsInfo, actionArgs) =>
            notifyInProgress(actionArgs.id),
        // Just an async function, using undoArgs
        undo: (error, transactionsInfo, undoArgs) => notifyFailed(undoArgs.id) 
    },
    {
        id: "saveInDb"
        // Just an async function, using previousResponses
        action: (transactionsInfo) => saveInDb(
             transactionsInfo.previousResponses["notifyInProgress"]
        ),
        // Just an async function, using previousResponses
        undo: (error, transactionsInfo) => deleteInDb(
             transactionsInfo.previousResponses["notifyInProgress"].id
        ),
    }
]);
    
transaction.append({
    id: "notifyEnd"
    actionArgs: {id: "1"},
    undoArgs: {id: "1"},
    // Just an async function, using actionArgs
    action: (transactionsInfo, actionArgs) => 
        notifyEnd(actionArgs.id),
});

transaction.exec()
    .then(result => {
        if(result.isSuccess) 
            console.log("The transaction success, all actions done");
        else 
            console.log("The transaction failed, not all actions done. 
                All relevant undo actions executed");
                
        // result = {
        //     isSuccess: true,
        //     actionsInfo: {
        //          responses: {
        //              start: undefined,
        //              notifyInProgress: {
        //                  id: 1,
        //                  starus: "InProgress"
        //              },
        //              saveInDb: "1234",
        //          }
        //     },
        // }
    }).catch(result => {
        console.log("The transaction failed, not all actions done. Undo 
          actions pipeline executed and at least one undo action failed");
                
        // result = {
        //     isSuccess: false,
        //     actionsInfo: {
        //          responses: {
        //              start: undefined,
        //              notifyInProgress: {
        //                  id: 1,
        //                  starus: "InProgress"
        //              },
        //              saveInDb: "1234",
        //          },
        //          errorInfo: {
        //              index: 3,
        //              id: "notifyEnd",
        //              error: Error
        //          }
        //     },
        //     undoInfo: {
        //         responses: {
        //              start: undefined,
        //              saveInDb: undefined,
        //          },
        //          errorInfo" [
        //              {
        //                   index: 1,
        //                   id: "notifyInProgress",
        //                   error: Error
        //              }
        //          ]
        //     }
        // }
    });

transaction .clear();

TypeScript support

pipe-transaction is written in Typescript and supports it perfectly!

🏠 Homepage

Author

👤 Ariel Dayan

🤝 issues

Issues and feature requests are welcome!

Feel free to check issues page

Show your support

Give a ⭐️ if this project helped you!

License

Released under the MIT License.