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

gn-queue

v1.0.1

Published

A simple utility to handle multiple concurrent task for your browser.

Readme

Queue

SLSA 3 SLSA 3 SLSA 3

Queue Management provides a Queue class that helps you manage multiple concurrent tasks efficiently without blocking the main thread. It allows you to enqueue tasks, handle errors gracefully, track progress, and cancel all tasks if needed.

The EventQueue module provides a flexible and event-driven way to manage tasks in a browser environment. By using this module, you can handle long-running operations, progress updates, error handling, and task cancellation in a clean and efficient manner.

Features

  • Enqueue Task: Enqueue tasks and execute them sequentially without blocking the main thread
  • Handle errors: Handle errors for each task with custom error handling functions
  • Track progress: Track progress for each task with custom progress handling functions
  • Cancel all tasks: Cancel all tasks in the queue, including the currently running task
  • Event-Driven: Utilizes the EventTarget interface for handling task-related events, making it flexible and decoupled from direct method calls.
  • Task Enqueuing: Easily enqueue tasks with optional error and progress handlers.
  • Progress Updates: Supports real-time progress updates for each task.
  • Task Cancellation: Allows for cancellation of individual tasks or all tasks in the queue.
  • Error Handling: Provides a mechanism to handle errors within tasks gracefully.
  • Promise-Based: Uses Promises for task execution, making it easy to handle asynchronous operations.
  • Compatibility: Designed to work in modern browsers with support for ES6 modules and the EventTarget interface.

Note : Since this module is designed for a browser environment, ensure you have a way to include ES6 modules. You can use tools like Webpack, Parcel, or simply include it in a script tag if your browser supports ES6 modules natively.

Installation

  npm install gn-queue

Usage [gn-queue]

  1. Create an instance of the Queue class:
const queue = new Queue();
  1. Define your task functions. These functions should return a Promise and optionally accept onProgress and signal callbacks for progress tracking and task cancellation, respectively:
function apiRequest(onProgress, signal) {
  return new Promise((resolve, reject) => {
    // Your API request logic here
    // Call onProgress with progress information
    // Check signal.aborted to handle cancellation
  });
}

function convertVideoToFrames(onProgress, signal) {
  return new Promise((resolve, reject) => {
    // Your video conversion logic here
    // Call onProgress with progress information
    // Check signal.aborted to handle cancellation
  });
}
  1. Define error handling and progress handling functions (optional):
function handleApiRequestError(error) {
  // Handle API request error
}

function handleVideoConversionError(error) {
  // Handle video conversion error
}

function handleApiRequestProgress(progress) {
  // Handle API request progress
}

function handleVideoConversionProgress(progress) {
  // Handle video conversion progress
}
  1. Enqueue tasks with optional error handling and progress tracking functions:
queue.enqueue(apiRequest, handleApiRequestError, handleApiRequestProgress);
queue.enqueue(
  convertVideoToFrames,
  handleVideoConversionError,
  handleVideoConversionProgress
);
  1. To cancel all tasks in the queue, including the currently running task, call the cancelAllTasks method:
queue.cancelAllTasks();

Example

Basic Example

import { Queue } from "gn-queue";

const queue = new Queue();

function apiRequest() {
  return new Promise((resolve) => {
    setTimeout(() => {
      console.log("API request completed");
      resolve();
    }, 2000);
  });
}

function convertVideoToFrames() {
  return new Promise((resolve) => {
    setTimeout(() => {
      console.log("Video converted to frames");
      resolve();
    }, 5000);
  });
}

queue.enqueue(apiRequest);
queue.enqueue(convertVideoToFrames);
queue.enqueue(apiRequest);
queue.enqueue(convertVideoToFrames);

In this example, we enqueue two API request tasks and two video conversion tasks. The tasks will be executed sequentially without blocking the main thread.

Example with Error Handling

import { Queue } from "gn-queue";

const queue = new Queue();

function apiRequest() {
  return new Promise((resolve, reject) => {
    setTimeout(() => {
      const success = Math.random() > 0.5;
      if (success) {
        console.log("API request completed");
        resolve();
      } else {
        reject(new Error("API request failed"));
      }
    }, 2000);
  });
}

function convertVideoToFrames() {
  return new Promise((resolve, reject) => {
    setTimeout(() => {
      const success = Math.random() > 0.5;
      if (success) {
        console.log("Video converted to frames");
        resolve();
      } else {
        reject(new Error("Video conversion failed"));
      }
    }, 5000);
  });
}

function handleApiRequestError(error) {
  console.error("API request error:", error);
  // Implement your error handling logic here
}

function handleVideoConversionError(error) {
  console.error("Video conversion error:", error);
  // Implement your error handling logic here
}

queue.enqueue(apiRequest, handleApiRequestError);
queue.enqueue(convertVideoToFrames, handleVideoConversionError);
queue.enqueue(apiRequest, handleApiRequestError);
queue.enqueue(convertVideoToFrames, handleVideoConversionError);

In this example, we define error handling functions for API requests and video conversions. If any task fails, the corresponding error handling function will be called with the error object.

Example with Progress Tracking

import { Queue } from "gn-queue";

const queue = new Queue();

function apiRequest(onProgress) {
  return new Promise((resolve, reject) => {
    const totalSteps = 5;
    let currentStep = 0;
    const interval = setInterval(() => {
      currentStep++;
      onProgress((currentStep / totalSteps) * 100);
      if (currentStep === totalSteps) {
        clearInterval(interval);
        const success = Math.random() > 0.5;
        if (success) {
          console.log("API request completed");
          resolve();
        } else {
          reject(new Error("API request failed"));
        }
      }
    }, 1000);
  });
}

function convertVideoToFrames(onProgress) {
  return new Promise((resolve, reject) => {
    const totalSteps = 10;
    let currentStep = 0;
    const interval = setInterval(() => {
      currentStep++;
      onProgress((currentStep / totalSteps) * 100);
      if (currentStep === totalSteps) {
        clearInterval(interval);
        const success = Math.random() > 0.5;
        if (success) {
          console.log("Video converted to frames");
          resolve();
        } else {
          reject(new Error("Video conversion failed"));
        }
      }
    }, 500);
  });
}

function handleApiRequestError(error) {
  console.error("API request error:", error);
  // Implement your error handling logic here
}

function handleVideoConversionError(error) {
  console.error("Video conversion error:", error);
  // Implement your error handling logic here
}

function handleApiRequestProgress(progress) {
  console.log(`API request progress: ${progress}%`);
}

function handleVideoConversionProgress(progress) {
  console.log(`Video conversion progress: ${progress}%`);
}

queue.enqueue(apiRequest, handleApiRequestError, handleApiRequestProgress);
queue.enqueue(
  convertVideoToFrames,
  handleVideoConversionError,
  handleVideoConversionProgress
);
queue.enqueue(apiRequest, handleApiRequestError, handleApiRequestProgress);
queue.enqueue(
  convertVideoToFrames,
  handleVideoConversionError,
  handleVideoConversionProgress
);

In this example, we define progress handling functions for API requests and video conversions. The task functions call the onProgress callback periodically with the current progress value. The corresponding progress handling function will be called with the progress information, allowing you to update your user interface or perform any other actions based on the progress.

Example with Task Cancellation

const Queue = require("./queue");

const queue = new Queue();

function apiRequest(onProgress, signal) {
  return new Promise((resolve, reject) => {
    const totalSteps = 5;
    let currentStep = 0;
    const interval = setInterval(() => {
      if (signal.aborted) {
        clearInterval(interval);
        reject(new DOMException("AbortError", "Task has been canceled."));
      } else {
        currentStep++;
        onProgress((currentStep / totalSteps) * 100);
        if (currentStep === totalSteps) {
          clearInterval(interval);
          const success = Math.random() > 0.5;
          if (success) {
            console.log("API request completed");
            resolve();
          } else {
            reject(new Error("API request failed"));
          }
        }
      }
    }, 1000);
  });
}

function convertVideoToFrames(onProgress, signal) {
  return new Promise((resolve, reject) => {
    const totalSteps = 10;
    let currentStep = 0;
    const interval = setInterval(() => {
      if (signal.aborted) {
        clearInterval(interval);
        reject(new DOMException("AbortError", "Task has been canceled."));
      } else {
        currentStep++;
        onProgress((currentStep / totalSteps) * 100);
        if (currentStep === totalSteps) {
          clearInterval(interval);
          const success = Math.random() > 0.5;
          if (success) {
            console.log("Video converted to frames");
            resolve();
          } else {
            reject(new Error("Video conversion failed"));
          }
        }
      }
    }, 500);
  });
}

function handleApiRequestError(error) {
  console.error("API request error:", error);
  // Implement your error handling logic here
}

function handleVideoConversionError(error) {
  console.error("Video conversion error:", error);
  // Implement your error handling logic here
}

function handleApiRequestProgress(progress) {
  console.log(`API request progress: ${progress}%`);
}

function handleVideoConversionProgress(progress) {
  console.log(`Video conversion progress: ${progress}%`);
}

queue.enqueue(apiRequest, handleApiRequestError, handleApiRequestProgress);
queue.enqueue(
  convertVideoToFrames,
  handleVideoConversionError,
  handleVideoConversionProgress
);
queue.enqueue(apiRequest, handleApiRequestError, handleApiRequestProgress);
queue.enqueue(
  convertVideoToFrames,
  handleVideoConversionError,
  handleVideoConversionProgress
);

// Cancel all tasks after 5 seconds
setTimeout(() => {
  queue.cancelAllTasks();
}, 5000);

n this example, we've updated the apiRequest and convertVideoToFrames functions to accept a signal argument. This signal is used to check if the task has been canceled (signal.aborted). If the task is canceled, we clear the interval and reject the Promise with a DOMException of type AbortError. Additionally, we've added a setTimeout function that calls queue.cancelAllTasks() after 5 seconds. This will cancel all tasks in the queue, including the currently running task. When you run this code, you'll see that tasks start executing, and after 5 seconds, all tasks are canceled. The output might look something like this:

Usage [gn-queue (EventQueue)]

Importing EventQueue

import { EventQueue } from "gn-queue";

Creating an EventQueue Instance

const queue = new EventQueue();

Enqueuing Tasks

Tasks can be enqueued with optional error and progress handlers.

const task = (progressCallback, signal) => {
  return new Promise((resolve, reject) => {
    let progress = 0;
    const interval = setInterval(() => {
      if (signal.aborted) {
        clearInterval(interval);
        reject(new Error("Task aborted"));
      } else {
        progress += 10;
        progressCallback(progress);
        if (progress >= 100) {
          clearInterval(interval);
          resolve("Task completed");
        }
      }
    }, 100);
  });
};

queue.enqueue(
  task,
  (error) => console.error("Task failed:", error),
  (progress) => console.log("Task progress:", progress)
);

Cancelling All Tasks

You can cancel all tasks in the queue:

queue.cancelAllTasks();

Examples

Simple Counter Task

const simpleCounterTask = (progressCallback, signal) => {
  return new Promise((resolve, reject) => {
    let count = 0;
    const interval = setInterval(() => {
      if (signal.aborted) {
        clearInterval(interval);
        reject(new Error("Task aborted"));
      } else {
        count += 10;
        progressCallback(count);
        if (count >= 100) {
          clearInterval(interval);
          resolve("Simple Counter Task completed");
        }
      }
    }, 100);
  });
};

queue.enqueue(
  simpleCounterTask,
  (error) => console.error("Simple Counter Task failed:", error),
  (progress) => console.log("Simple Counter Task progress:", progress)
);

Network Request Simulation

const networkRequestTask = (progressCallback, signal) => {
  return new Promise((resolve, reject) => {
    setTimeout(() => {
      if (signal.aborted) {
        reject(new Error("Task aborted"));
      } else {
        progressCallback(100);
        resolve("Network Request Task completed");
      }
    }, 2000);
  });
};

queue.enqueue(
  networkRequestTask,
  (error) => console.error("Network Request Task failed:", error),
  (progress) => console.log("Network Request Task progress:", progress)
);

File Upload Simulation

const fileUploadTask = (progressCallback, signal) => {
  return new Promise((resolve, reject) => {
    let progress = 0;
    const interval = setInterval(() => {
      if (signal.aborted) {
        clearInterval(interval);
        reject(new Error("Task aborted"));
      } else {
        progress += 20;
        progressCallback(progress);
        if (progress >= 100) {
          clearInterval(interval);
          resolve("File Upload Task completed");
        }
      }
    }, 500);
  });
};

queue.enqueue(
  fileUploadTask,
  (error) => console.error("File Upload Task failed:", error),
  (progress) => console.log("File Upload Task progress:", progress)
);

Task with Error Handling

const errorHandlingTask = (progressCallback, signal) => {
  return new Promise((resolve, reject) => {
    setTimeout(() => {
      if (signal.aborted) {
        reject(new Error("Task aborted"));
      } else {
        reject(new Error("Task failed due to an error"));
      }
    }, 1000);
  });
};

queue.enqueue(
  errorHandlingTask,
  (error) => console.error("Error Handling Task failed:", error),
  (progress) => console.log("Error Handling Task progress:", progress)
);

Task Cancellation

const cancellationTask = (progressCallback, signal) => {
  return new Promise((resolve, reject) => {
    let progress = 0;
    const interval = setInterval(() => {
      if (signal.aborted) {
        clearInterval(interval);
        reject(new Error("Task aborted"));
      } else {
        progress += 10;
        progressCallback(progress);
        if (progress >= 100) {
          clearInterval(interval);
          resolve("Cancellation Task completed");
        }
      }
    }, 100);
  });
};

queue.enqueue(
  cancellationTask,
  (error) => console.error("Cancellation Task failed:", error),
  (progress) => console.log("Cancellation Task progress:", progress)
);

Cancelling All Tasks After a Delay

setTimeout(() => {
  queue.cancelAllTasks();
}, 3000);