Fast and simple storage library for JavaScript with localStorage-like API that uses asynchronous storage (IndexedDB or WebSQL).
—
Pending
Does it follow best practices?
Impact
Pending
No eval scenarios have been run
Pending
The risk profile of this skill
Methods for inspecting and iterating over stored data, including key enumeration and batch processing capabilities. These methods allow you to examine the contents of your storage without needing to know specific keys in advance.
Returns the number of items currently stored in the storage instance.
/**
* Gets the number of items in storage
* @param callback - Optional callback function
* @returns Promise resolving to the number of keys
*/
function length(callback?: (err: any, numberOfKeys: number) => void): Promise<number>;Usage Examples:
import localforage from 'localforage';
// Check how many items are stored
const count = await localforage.length();
console.log(`Storage contains ${count} items`);
// Using callbacks
localforage.length((err, numberOfKeys) => {
if (err) {
console.error('Error getting length:', err);
} else {
console.log('Number of keys:', numberOfKeys);
}
});
// Conditional logic based on storage size
const itemCount = await localforage.length();
if (itemCount === 0) {
console.log('Storage is empty');
} else if (itemCount > 100) {
console.log('Storage is getting full, consider cleanup');
}Retrieves the key name at the specified index. Keys are ordered differently depending on the storage driver being used.
/**
* Gets the key at the specified index
* @param keyIndex - The index of the key to retrieve (0-based)
* @param callback - Optional callback function
* @returns Promise resolving to the key name
*/
function key(keyIndex: number, callback?: (err: any, key: string) => void): Promise<string>;Usage Examples:
import localforage from 'localforage';
// Get the first key
const firstKey = await localforage.key(0);
console.log('First key:', firstKey);
// Get the last key
const length = await localforage.length();
if (length > 0) {
const lastKey = await localforage.key(length - 1);
console.log('Last key:', lastKey);
}
// Using callbacks
localforage.key(2, (err, keyName) => {
if (err) {
console.error('Error getting key:', err);
} else {
console.log('Key at index 2:', keyName);
}
});
// Iterate through all keys using indices
const totalKeys = await localforage.length();
for (let i = 0; i < totalKeys; i++) {
const keyName = await localforage.key(i);
console.log(`Key ${i}: ${keyName}`);
}Retrieves an array of all key names in storage.
/**
* Gets all keys currently in storage
* @param callback - Optional callback function
* @returns Promise resolving to an array of key names
*/
function keys(callback?: (err: any, keys: string[]) => void): Promise<string[]>;Usage Examples:
import localforage from 'localforage';
// Get all keys
const allKeys = await localforage.keys();
console.log('All keys:', allKeys);
// Output: ['user', 'settings', 'cache', 'session']
// Check if a specific key exists
const keyList = await localforage.keys();
const hasUserData = keyList.includes('userData');
// Filter keys by pattern
const allKeys = await localforage.keys();
const cacheKeys = allKeys.filter(key => key.startsWith('cache_'));
const tempKeys = allKeys.filter(key => key.includes('temp'));
// Using callbacks
localforage.keys((err, keyList) => {
if (err) {
console.error('Error getting keys:', err);
} else {
console.log('Available keys:', keyList);
}
});
// Process all stored data
const keys = await localforage.keys();
for (const key of keys) {
const value = await localforage.getItem(key);
console.log(`${key}:`, value);
}Iterates over all items in storage, calling the provided function for each key/value pair. This is more efficient than manually iterating with keys() and getItem().
/**
* Iterates over all items in storage
* @param iteratee - Function called for each item (value, key, iterationNumber) => result
* @param callback - Optional callback function
* @returns Promise resolving to the result of the iteration
*/
function iterate<T, U>(
iteratee: (value: T, key: string, iterationNumber: number) => U,
callback?: (err: any, result: U) => void
): Promise<U>;Usage Examples:
import localforage from 'localforage';
// Simple iteration - log all items
await localforage.iterate((value, key, iterationNumber) => {
console.log(`[${iterationNumber}] ${key}:`, value);
});
// Count items matching a condition
let userCount = 0;
await localforage.iterate((value, key) => {
if (key.startsWith('user_')) {
userCount++;
}
});
console.log(`Found ${userCount} user records`);
// Find and return specific item
const foundUser = await localforage.iterate((value, key) => {
if (key === 'currentUser') {
return value; // This stops iteration and returns the value
}
// Continue iteration
});
// Calculate total size (conceptual example)
let totalItems = 0;
await localforage.iterate((value, key, iterationNumber) => {
totalItems++;
console.log(`Processing item ${iterationNumber + 1}: ${key}`);
});
// Using callbacks
localforage.iterate((value, key, iterationNumber) => {
// Process each item
console.log(`Item ${iterationNumber}: ${key} = ${value}`);
// Return undefined to continue iteration
// Return any other value to stop and return that value
}, (err, result) => {
if (err) {
console.error('Iteration error:', err);
} else {
console.log('Iteration completed, result:', result);
}
});
// Early termination example
const searchResult = await localforage.iterate((value, key) => {
if (typeof value === 'object' && value.type === 'important') {
return value; // Found what we're looking for, stop iterating
}
// Continue iterating
});
// Collect all values into an array
const allValues = [];
await localforage.iterate((value, key) => {
allValues.push({ key, value });
});
console.log('All stored data:', allValues);// Get comprehensive storage statistics
async function getStorageStats() {
const keys = await localforage.keys();
const length = await localforage.length();
const keysByPrefix = {};
keys.forEach(key => {
const prefix = key.split('_')[0];
keysByPrefix[prefix] = (keysByPrefix[prefix] || 0) + 1;
});
return {
totalItems: length,
keyPrefixes: keysByPrefix,
allKeys: keys
};
}
const stats = await getStorageStats();
console.log('Storage statistics:', stats);// Delete all keys matching a pattern
async function clearKeysByPattern(pattern) {
const keys = await localforage.keys();
const keysToRemove = keys.filter(key => key.includes(pattern));
for (const key of keysToRemove) {
await localforage.removeItem(key);
}
return keysToRemove.length;
}
const removedCount = await clearKeysByPattern('temp_');
console.log(`Removed ${removedCount} temporary items`);// Migrate data with key transformation
async function migrateKeys(oldPrefix, newPrefix) {
const keys = await localforage.keys();
const keysToMigrate = keys.filter(key => key.startsWith(oldPrefix));
for (const oldKey of keysToMigrate) {
const value = await localforage.getItem(oldKey);
const newKey = oldKey.replace(oldPrefix, newPrefix);
await localforage.setItem(newKey, value);
await localforage.removeItem(oldKey);
}
return keysToMigrate.length;
}
const migratedCount = await migrateKeys('old_', 'new_');
console.log(`Migrated ${migratedCount} keys`);iterate() is more efficient than manually using keys() + getItem() in a loopiterate() with early terminationkeys() grows with the number of stored items// Efficient: Use iterate() for processing all items
await localforage.iterate((value, key) => {
processItem(key, value);
});
// Less efficient: Manual iteration
const keys = await localforage.keys();
for (const key of keys) {
const value = await localforage.getItem(key);
processItem(key, value);
}