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

promise-logic

v2.9.1

Published

Compose promises with logic gate semantics (AND, OR, XOR, NAND, NOR, XNOR, Majority). Forget APIs, remember logic.

Downloads

163

Readme

Core Philosophy

Replace API Memory with Logical Concepts

The design philosophy of promise-logic is: Developers should focus on business logic, not on details of Promise APIs.

Traditional Promise combinations (such as Promise.all, Promise.race) have naming and semantics that are not intuitive enough, especially in complex asynchronous scenarios where code readability rapidly declines.

promise-logic abstracts asynchronous combinations into logical operations like and, or, xor through the concept of Logic Gates, making code semantically clear and self-explanatory.

Example Scenario: E-commerce Order Processing

import { PromiseLogic } from 'promise-logic';





// Order processing flow
async function createOrder() {
  // Unified error types
  const PAYMENT_OR_INVENTORY_ERROR = 'PAYMENT_OR_INVENTORY_ERROR';
  const ORDER_ERROR = 'ORDER_ERROR';
  const LOGISTICS_ERROR = 'LOGISTICS_ERROR';
  const COUPON_ERROR = 'COUPON_ERROR';

  // Destructure and, or methods from PromiseLogic for simpler syntax and understand the logical relationship of the current scenario
  const { and, or } = PromiseLogic;

  try {
    // Execute payment and inventory operations (both must succeed)

    const [
      [paymentResult, inventoryResult], // Payment and inventory operation results
      logistics,                        // Logistics operation result
      coupon                            // Coupon operation result
      ] = await and([
        and([paymentAPI(), inventoryAPI()],{
          errorType: PAYMENT_OR_INVENTORY_ERROR,// Custom payment or inventory error type
        }),
        or([oneLogisticsAPI(), twoLogisticsAPI()], {  
          errorType: LOGISTICS_ERROR,// Custom logistics error type
        }),
        or([couponAPI1(), couponAPI2()], {
          errorType: COUPON_ERROR,// Custom coupon error type
        })
    ], {
      errorType: ORDER_ERROR,// Custom order error type
      errorMessage: 'Order creation failed' // Custom order error message
    });

    // Order creation successful, return payment result, inventory result, logistics result and coupon result
    return {
      payment: paymentResult,
      inventory: inventoryResult,
      logistics: logistics,
      coupon: coupon,
      status: 'success'
    };
  } catch (error) {
    // Analyze error type
    switch (error.type) {
      case ORDER_ERROR:
        return {
          status: 'error',
          errorType: 'order_error',
          message: 'Order creation failed',
          details: error
        };
      case PAYMENT_OR_INVENTORY_ERROR:
        return {
          status: 'error',
          errorType: 'payment_or_inventory_failed',
          message: 'Payment or inventory operation failed',
          details: error
        };
      case LOGISTICS_ERROR:
        return {
          status: 'error',
          errorType: 'logistics_unavailable',
          message: 'All logistics services are unavailable',
          details: error
        };
      case COUPON_ERROR:
        return {
          status: 'error',
          errorType: 'coupon_error',
          message: 'All coupons are unavailable',
          details: error
        };
      default:
        return {
          status: 'error',
          errorType: 'default_error',
          message: 'Unknown error occurred during order creation',
          details: error
        };
    }
  }
}

As you can see, the code structure is completely consistent with business rules. Code is documentation, and logic is self-explanatory.


Features

1. Logical Semantics

  • and: All tasks must succeed (equivalent to Promise.all)
  • or: At least one task succeeds (equivalent to Promise.any)
  • xor: Exactly one task succeeds
  • nand: Not all tasks succeed (at least one fails)
  • nor: All tasks fail (no task succeeds)
  • xnor: All tasks succeed or all fail (same state)
  • not: Inverts the result of a single Promise
  • majority: Most tasks succeed

2. Zero Dependencies

Only depends on native Promise, no additional runtime dependencies.

3. Full Test Coverage

All logic gates have undergone rigorous unit testing to ensure behavior meets expectations.

4. Clear Error Classification

  • PromiseLogicError unified error type
  • error.type distinguishes specific logical errors (e.g., 'XOR_ERROR')
  • Supports custom error types and messages

5. Timeout Control

  • maxTimer: Adds timeout functionality to any Promise operation (unit: milliseconds)
  • Supports custom timeout error messages

Note: After timeout, it immediately interrupts the execution of the current Promise chain and jumps to error handling, but does not cancel underlying asynchronous operations that have already started (such as network requests, file read/write, etc.).

6. Extended Operations

  • allFulfilled: Returns all successful results in order, immediately tries to return when there are successful results
  • allRejected: Returns all failed results in order, immediately tries to return when there are failed results
  • allSettled: Returns all results (both successful and failed)

Installation

npm install promise-logic

Quick Start

Basic Usage Examples

Destructuring Assignment

import { PromiseLogic } from 'promise-logic';

// Destructure methods from PromiseLogic for simpler syntax
const { and, or, xor, not, race } = PromiseLogic;

// Use destructured methods
and([
  fetch('/api/user').then(r => r.json()),
  fetch('/api/profile').then(r => r.json())
]).then(results => console.log(results));

or([
  fetch('/api/primary').then(r => r.json()).catch(() => { throw new Error('primary failed'); }),
  fetch('/api/backup').then(r => r.json())
]).then(result => console.log(result));

xor([
  fetch('/api/method1').then(r => r.json()),
  fetch('/api/method2').then(r => r.json())
]).then(result => console.log(result));

Security Audit (XOR Scenario)

import { PromiseLogic } from 'promise-logic';

// Execute XOR logic: exactly one success
PromiseLogic.xor([
  biometricAuth(), // Biometric authentication
  hardwareKeyAuth() // Hardware key authentication
])
  .then((result) => {
    console.log('Successfully authenticated:', result);
  })
  .catch((error) => {
    if (error.type === 'XOR_ERROR') {
      console.error('Conflict between biometric and hardware key authentication');
    } else {
      console.error('Authentication error:', error);
    }
  });

Majority Decision (Majority Scenario)

import { PromiseLogic } from 'promise-logic';

const services = [
  fetch('https://api.node1.com/vote'),
  fetch('https://api.node2.com/vote'),
  fetch('https://api.node3.com/vote')
];

// Custom threshold 0.6 (60%)
PromiseLogic.majority(services, { max: 0.6 })
  .then((results) => {
    console.log('Custom threshold met, successful results:', results);
  })
  .catch((error) => {
    console.error('Custom threshold not met:', error);
  });

Timeout Control

import { PromiseLogic } from 'promise-logic';

// Execute operation with custom timeout error message
PromiseLogic.and([
  Promise.resolve(1),
  new Promise((resolve) => setTimeout(resolve, 3000)), // 3 second operation
  Promise.resolve(3)
])
  .maxTimer(2000, 'Custom timeout error: operation did not complete within 2000ms') // 2 second timeout
  .then((result) => {
    console.log('Operation completed within timeout:', result);
  })
  .catch((error) => {
    console.error('Operation timed out:', error.message);
  });

Extended Operations

import { PromiseLogic } from 'promise-logic';

const operations = [
  Promise.resolve('success1'),
  Promise.reject('error1'),
  Promise.resolve('success2'),
  Promise.reject('error2')
];

// Get all successful results (returns immediately when there are successes)
PromiseLogic.allFulfilled(operations).then((results) => {
  console.log('Successful results:', results); // ['success1', 'success2']
});

// Get all failed results (returns immediately when there are failures)
PromiseLogic.allRejected(operations).then((errors) => {
  console.log('Failed results:', errors); // ['error1', 'error2']
});

// Get all results (both success and failure)
PromiseLogic.allSettled(operations).then((results) => {
  console.log('All results:', results);
});

Custom Error Types and Messages

import { PromiseLogic } from 'promise-logic';

// Custom error type
const CUSTOM_ERROR_TYPE = 'CUSTOM_ERROR';

// Custom error message
const CUSTOM_ERROR_MESSAGE = 'Custom error message';

// Use custom error type and message
PromiseLogic.and([Promise.resolve('success1'), Promise.reject('error1')], {
  errorType: CUSTOM_ERROR_TYPE,
  errorMessage: CUSTOM_ERROR_MESSAGE
})
  .then((results) => {
    console.log(results);
  })
  .catch((error) => {
    if (error.type === CUSTOM_ERROR_TYPE) {
      console.error(error); // Output: Custom error message
    } else {
      console.error(error);
    }
  });

Using Factory Function

The factory function allows you to create PromiseLogic methods with custom names:

import { createPromiseLogic } from 'promise-logic';

// Create instance with custom naming
const logic = createPromiseLogic({
  prefix: 'api_',
  suffix: '_call',
  rename: {
    and: 'all',
    or: 'any',
    xor: 'exclusive'
  }
});

// Use custom-named methods
logic.api_all_call([fetch('/api/users'), fetch('/api/posts')]);
logic.api_any_call([fetch('/api/cache'), fetch('/api/database')]);

TypeScript Support

import { PromiseLogic } from 'promise-logic/typescript';

// Type inference
PromiseLogic.and([Promise.resolve(1), Promise.resolve(2)]).then(
  (results: number[]) => {
    console.log(results);
  }
);

// Type assertion
PromiseLogic.and<number>([Promise.resolve(1), Promise.resolve(2)]);

Dynamic Logic Nested

import { PromiseLogic } from 'promise-logic';


// Dynamic nesting example: adjust logistics strategy based on user level
const orderFlow = async (userLevel) => {
  // VIP users: dual high-availability logistics guarantee (at least one success)
  // Normal users: priority standard logistics, failover to economy logistics (at least one success)
  const logisticsStrategy = userLevel === 'VIP'
    ? PromiseLogic.or([premiumLogistics(), backupLogistics()])
    : PromiseLogic.or([standardLogistics(), economyLogistics()]);

  return await PromiseLogic.and([
    PromiseLogic.and([paymentAPI(), inventoryAPI()]), // Payment + inventory atomic operations
    logisticsStrategy,                                // Logistics strategy
    couponValidation()                                // Coupon validation
  ]);
};

API Reference

| API | Description | | :------------- | :--------------------------------------------------------------------------------------------------------------------------- | | and | All Promises succeed, returns result array; any failure causes overall failure. Equivalent to native Promise.all. | | or | At least one Promise succeeds, returns first success result; all failures cause overall failure. Equivalent to native Promise.any. | | xor | Exactly one Promise succeeds, returns that result; otherwise throws XOR_ERROR. | | nand | Not all Promises succeed (at least one fails), returns success result array; all succeed causes overall failure. | | nor | All Promises fail (no task succeeds), returns empty array; any success causes overall failure. | | xnor | All Promises succeed or all fail (same state), returns success result array; otherwise throws XNOR_ERROR. | | not | Inverts the result of a single Promise: success becomes failure, failure becomes success. | | majority | More than specified threshold of Promises succeed, returns success result array; otherwise overall failure. Accepts options parameter, where max property can customize threshold (default: 0.5), range: [0, 1]. | | allFulfilled | Returns all successful results as an array, ignoring failures. Returns immediately when a result exists, while maintaining consistent input and output order. | | allRejected | Returns all failed results as an array, ignoring successes. Returns immediately when a result exists, while maintaining consistent input and output order. | | allSettled | Returns all results (both successful and failed) as an array. Equivalent to native Promise.allSettled. | | race | Returns the first completed Promise result (regardless of success or failure). Equivalent to native Promise.race. | | maxTimer | Adds timeout functionality to any Promise operation (unit: milliseconds). Supports custom timeout error messages. |


Changelog

v2.9.0

Error Mechanism Improvements

  • Added errorType and errorMessage parameters to logic gates, supporting custom error types and messages, further fitting business scenarios
  • Optimized the existing error type system to ensure correct TypeScript type definitions
  • Optimized TypeScript type compatibility issues
  • Optimized allSettled gate return type error messages
  • Improved test scripts, covering most promise combination logic boundaries and tricky scenario issues, ensuring more stable operation of logic gates
  • Optimized logic gate execution efficiency, reducing unnecessary Promise wrapping

v2.8.0

  • Performance optimization: Optimized allFulfilled and allRejected implementation logic from the bottom layer, existing results return immediately while maintaining consistent input and output order
  • Added chain timeout control with custom error messages: Can customize timeout error messages in the maxTimer method
  • Type fixes: Fixed TypeScript version type declaration issues
  • Test completion: Added complete test cases for allFulfilled, allRejected, and maxTimer
  • Code refactoring: Improved code structure for better maintainability

Contribution Guide

1. Development Environment

git clone https://github.com/xier123456/promise-logic.git
cd promise-logic
npm install

2. Testing

npm test

3. Commit Guidelines

  • Commit messages must include prefixes like feat: (new feature), fix: (bug fix), docs: (documentation).
  • Pull Requests must include test cases.

Resource Links