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

vue-reactive-queue

v0.0.1

Published

A Vue 3 composable for managing async task queues with reactive state, concurrency control, pause/resume, and retry support

Readme

vue-reactive-queue

Reactive async task queue for Vue 3 with concurrency control.

Features

  • 🚀 Concurrency Control - Limit parallel task execution
  • 📊 Reactive State - Track task status in real-time with Vue reactivity
  • ⏸️ Pause/Resume - Control queue execution flow
  • 🔄 Retry - Retry failed tasks with one call
  • 📝 Task History - Keep track of completed tasks
  • 🎯 Manual Execution - Start specific tasks on demand
  • 💪 TypeScript - Full type support with generics

Install

npm install vue-reactive-queue

Usage

Basic

import { useQueue } from 'vue-reactive-queue'

const queue = useQueue()

// Add tasks to the queue
queue.add(async () => {
  await processFile('document.pdf')
})

queue.add(async () => {
  await processFile('image.png')
})

Concurrency Control

const queue = useQueue({ concurrency: 3 })

// Only 3 tasks will run in parallel
queue.add(() => fetchUser(1))
queue.add(() => fetchUser(2))
queue.add(() => fetchUser(3))
queue.add(() => fetchUser(4)) // waits for a slot

Reactive State

<script setup>
import { useQueue } from 'vue-reactive-queue'

const queue = useQueue({ concurrency: 2 })

function addTask() {
  queue.add(async () => {
    await new Promise(r => setTimeout(r, 1000))
    return 'done'
  })
}
</script>

<template>
  <div>
    <p>Pending: {{ queue.stats.value.pending }}</p>
    <p>Running: {{ queue.stats.value.running }}</p>
    <p>Completed: {{ queue.stats.value.completed }}</p>

    <button @click="addTask">Add Task</button>

    <div v-for="task in queue.tasks.value" :key="task.id">
      <span>Task #{{ task.id }}: {{ task.status }}</span>
      <button v-if="task.status === 'rejected'" @click="queue.retry(task.id)">
        Retry
      </button>
    </div>
  </div>
</template>

Pause and Resume

const queue = useQueue()

queue.add(() => task1())
queue.add(() => task2())

queue.pause()  // Stop executing new tasks
queue.resume() // Continue execution

Start Paused

const queue = useQueue({ immediate: false })

queue.add(() => task1())
queue.add(() => task2())

// Tasks are pending, not running
console.log(queue.stats.value.isPaused) // true

// Start when ready
queue.resume()

Manual Task Execution

Start a specific task immediately, ignoring the pause state:

const queue = useQueue({ immediate: false })

const { id: idA } = queue.add(() => taskA())
const { id: idB } = queue.add(() => taskB())
const { id: idC } = queue.add(() => taskC())

// Only execute taskB, leave others pending
await queue.start(idB)

Retry Failed Tasks

const queue = useQueue()

const { id } = queue.add(async () => {
  await uploadFile(file) // might fail due to network issues
})

// Later, if the task failed
const result = queue.retry(id)
if (result.success) {
  await result.promise
}

Task Metadata

Attach custom data to tasks for UI rendering:

interface TaskMeta {
  filename: string
  size: number
}

const queue = useQueue<TaskMeta>()

queue.add(
  () => uploadFile(file),
  { filename: file.name, size: file.size }
)
<template>
  <div v-for="task in queue.tasks.value" :key="task.id">
    <span>{{ task.meta?.filename }}</span>
    <span>{{ task.status }}</span>
  </div>
</template>

Callbacks

const queue = useQueue({
  onSuccess(task) {
    console.log('Task completed:', task.result)
  },
  onError(task, error) {
    console.error('Task failed:', error)
  },
  onFinished() {
    console.log('All tasks done!')
  },
})

Limit History

// Only keep the last 10 completed tasks
const queue = useQueue({ maxHistory: 10 })

// Keep no history (only pending/running tasks visible)
const queue = useQueue({ maxHistory: 0 })

Wait for Idle

const queue = useQueue()

queue.add(() => task1())
queue.add(() => task2())
queue.add(() => task3())

await queue.waitForIdle()
console.log('All tasks completed!')

Dynamic Concurrency

import { ref } from 'vue'

const limit = ref(2)
const queue = useQueue({ concurrency: limit })

// Reactively update concurrency
limit.value = 5

// Or use setConcurrency
queue.setConcurrency(10)

Type Declarations

export interface QueueTask<T = unknown, M = unknown> {
  readonly id: number
  status: 'pending' | 'running' | 'fulfilled' | 'rejected'
  readonly createdAt: number
  startedAt?: number
  finishedAt?: number
  result?: T
  error?: unknown
  readonly meta?: M
}

export interface QueueStats {
  readonly pending: number
  readonly running: number
  readonly completed: number
  readonly failed: number
  readonly total: number
  readonly isIdle: boolean
  readonly isPaused: boolean
}

export interface UseQueueOptions<M = unknown> {
  concurrency?: MaybeRefOrGetter<number>  // default: 1
  immediate?: boolean                      // default: true
  maxHistory?: number                      // default: undefined (keep all)
  onSuccess?: (task: QueueTask<unknown, M>) => void
  onError?: (task: QueueTask<unknown, M>, error: unknown) => void
  onFinished?: () => void
}

export interface UseQueueReturn<M = unknown> {
  tasks: Readonly<ShallowRef<QueueTask<unknown, M>[]>>
  stats: ComputedRef<QueueStats>
  concurrency: Readonly<ShallowRef<number>>
  add: <T>(fn: () => T | Promise<T>, meta?: M) => { id: number; task: QueueTask<T, M>; promise: Promise<T> }
  start: (id: number) => Promise<unknown> | undefined
  retry: (id: number) => RetryResult
  remove: (id: number) => boolean
  clear: () => void
  pause: () => void
  resume: () => void
  setConcurrency: (value: number) => void
  waitForIdle: () => Promise<void>
}

License

MIT