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

vanilla-loading-state-manager

v1.0.0

Published

A token-based loading state manager to make sure that loading indicators only turn off once all loading elements have loaded.

Readme

Vanilla Loading State Manager

A token-based loading state manager to make sure that loading indicators only turn off once all loading elements have loaded.

Features

  • Token-based system: Each loading operation receives a unique Symbol token, preventing mismatched start/stop calls
  • Concurrent operation tracking: Safely manage multiple loading operations simultaneously
  • Callback-driven: React to loading state transitions with custom callbacks
  • Zero dependencies: Pure vanilla JavaScript
  • Type-safe: Private fields ensure tokens cannot be manipulated externally

Installation

npm install vanilla-loading-state-manager

Usage

Basic Example

import { LoadingStateManager } from 'vanilla-loading-state-manager';

// Create a manager with callbacks for loading state transitions
const loadingManager = new LoadingStateManager(
  () => console.log('Started loading'),
  () => console.log('Finished loading')
);

// Start a loading operation
const token = loadingManager.startLoading('fetching user data');

// Do your async work...
await fetchUserData();

// Stop the loading operation
loadingManager.stopLoading(token);

Multiple Concurrent Operations

const loadingManager = new LoadingStateManager(
  () => showSpinner(),
  () => hideSpinner()
);

// Start multiple operations
const token1 = loadingManager.startLoading('fetch posts');
const token2 = loadingManager.startLoading('fetch comments');
const token3 = loadingManager.startLoading('fetch user');

// The spinner stays visible until ALL operations complete
loadingManager.stopLoading(token1); // Spinner still visible
loadingManager.stopLoading(token2); // Spinner still visible
loadingManager.stopLoading(token3); // Spinner hidden (all done)

UI Integration Example

const spinner = document.getElementById('loading-spinner');

const loadingManager = new LoadingStateManager(
  () => spinner.classList.add('visible'),
  () => spinner.classList.remove('visible')
);

async function fetchData() {
  const token = loadingManager.startLoading('api call');
  try {
    const response = await fetch('/api/data');
    return await response.json();
  } finally {
    loadingManager.stopLoading(token);
  }
}

API

Constructor

new LoadingStateManager(isLoadingCallback, isNotLoadingCallback)

Parameters:

  • isLoadingCallback (Function): Called when transitioning from not-loading to loading (first token added)
  • isNotLoadingCallback (Function): Called when transitioning from loading to not-loading (last token removed)

Methods

startLoading(description)

Starts a loading operation and returns a unique token.

Parameters:

  • description (string, optional): Description for debugging purposes (default: 'loading')

Returns: symbol - A unique token to pass to stopLoading()

Example:

const token = loadingManager.startLoading('downloading file');

stopLoading(token)

Stops a loading operation by removing its token. Safe to call multiple times with the same token.

Parameters:

  • token (symbol): The token returned by startLoading()

Example:

loadingManager.stopLoading(token);

Properties

isLoading (getter)

Returns whether any loading operations are currently active.

Returns: boolean

Example:

if (loadingManager.isLoading) {
  console.log('Still loading...');
}

loadingTokenCount (getter)

Returns the number of active loading operations.

Returns: number

Example:

console.log(`${loadingManager.loadingTokenCount} operations in progress`);

loadingTokens (getter)

Returns the internal Set of loading tokens. Useful for debugging.

Returns: Set<symbol>

Example:

console.log('Active tokens:', loadingManager.loadingTokens);

Why Token-Based?

Traditional loading state managers often use simple counters or boolean flags, which can lead to issues:

  • Mismatched calls: Calling stopLoading() more times than startLoading() can turn off loading prematurely
  • Lost operations: Easy to forget to stop a loading operation
  • Debugging difficulties: Hard to track which operation corresponds to which stop call

The token-based approach solves these problems:

  • Each token is unique and must be provided to stop loading
  • Impossible to stop loading more times than started
  • Token descriptions make debugging easier
  • Safe to call stopLoading() multiple times with the same token

License

MIT

Author

theloveofcode

Repository

https://github.com/theloveofcode/vanilla-loading-state-manager