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.
Maintainers
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-managerUsage
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 bystartLoading()
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 thanstartLoading()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
Repository
https://github.com/theloveofcode/vanilla-loading-state-manager
