CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/npm-node-persist

Super-easy (and fast) persistent data structures in Node.js, modeled after HTML5 localStorage

Pending
Quality

Pending

Does it follow best practices?

Impact

Pending

No eval scenarios have been run

SecuritybySnyk

Pending

The risk profile of this skill

Overview
Eval results
Files

query-operations.mddocs/

Data Query and Inspection

Methods for querying stored data, retrieving keys and values, and inspecting storage contents with filtering capabilities.

Capabilities

Get All Keys

Returns an array of all stored keys, optionally filtered.

/**
 * Returns an array of all stored keys, optionally filtered
 * @param filter - Optional filter function to select specific items
 * @returns Promise resolving to array of key strings
 */
async function keys(filter?: (datum: any) => boolean): Promise<string[]>;

Usage Examples:

const storage = require('node-persist');
await storage.init();

// Store some data
await storage.setItem('user1', { name: 'Alice', active: true });
await storage.setItem('user2', { name: 'Bob', active: false });
await storage.setItem('config', { theme: 'dark' });

// Get all keys
const allKeys = await storage.keys();
console.log(allKeys); // ['user1', 'user2', 'config']

// Filter keys (filter receives full datum object with key, value, ttl)
const activeUserKeys = await storage.keys(datum => 
  datum.key.startsWith('user') && datum.value.active
);
console.log(activeUserKeys); // ['user1']

Get All Values

Returns an array of all stored values, optionally filtered.

/**
 * Returns an array of all stored values, optionally filtered
 * @param filter - Optional filter function to select specific items
 * @returns Promise resolving to array of stored values
 */
async function values(filter?: (datum: any) => boolean): Promise<any[]>;

Usage Examples:

// Get all values
const allValues = await storage.values();
console.log(allValues); 
// [{ name: 'Alice', active: true }, { name: 'Bob', active: false }, { theme: 'dark' }]

// Filter values
const activeUsers = await storage.values(datum => 
  datum.key.startsWith('user') && datum.value.active
);
console.log(activeUsers); // [{ name: 'Alice', active: true }]

// Filter by value properties
const darkThemeConfigs = await storage.values(datum => 
  datum.value.theme === 'dark'
);

Get Storage Length

Returns the count of stored items, optionally filtered.

/**
 * Returns the count of stored items, optionally filtered
 * @param filter - Optional filter function to select specific items
 * @returns Promise resolving to number of items
 */
async function length(filter?: (datum: any) => boolean): Promise<number>;

Usage Examples:

// Get total count
const totalItems = await storage.length();
console.log(totalItems); // 3

// Count filtered items
const userCount = await storage.length(datum => datum.key.startsWith('user'));
console.log(userCount); // 2

const activeUserCount = await storage.length(datum => 
  datum.key.startsWith('user') && datum.value.active
);
console.log(activeUserCount); // 1

Values with Key Match

Returns values for keys that match a string or regular expression pattern.

/**
 * Returns values for keys matching a string or RegExp pattern
 * @param match - String or RegExp to match against keys
 * @returns Promise resolving to array of matching values
 */
function valuesWithKeyMatch(match: string | RegExp): Promise<any[]>;

Usage Examples:

await storage.setItem('user:alice', { name: 'Alice' });
await storage.setItem('user:bob', { name: 'Bob' });
await storage.setItem('admin:charlie', { name: 'Charlie' });
await storage.setItem('config:theme', 'dark');

// String matching (substring search)
const userValues = await storage.valuesWithKeyMatch('user');
console.log(userValues); // [{ name: 'Alice' }, { name: 'Bob' }]

// RegExp matching
const colonUsers = await storage.valuesWithKeyMatch(/^user:/);
console.log(colonUsers); // [{ name: 'Alice' }, { name: 'Bob' }]

// Case-insensitive RegExp
const adminValues = await storage.valuesWithKeyMatch(/admin/i);
console.log(adminValues); // [{ name: 'Charlie' }]

Iterate Over All Items

Asynchronously iterates over all stored key-value pairs.

/**
 * Asynchronously iterates over all stored key-value pairs
 * @param callback - Async function called for each item
 * @returns Promise resolving when iteration completes
 */
async function forEach(callback: (datum: { key: string, value: any }) => Promise<void>): Promise<void>;

Usage Examples:

// Simple iteration
await storage.forEach(async (datum) => {
  console.log(`${datum.key}: ${JSON.stringify(datum.value)}`);
});

// Process each item
await storage.forEach(async (datum) => {
  if (datum.key.startsWith('user:')) {
    // Perform async operation on user data
    await processUser(datum.value);
  }
});

// Update items during iteration
await storage.forEach(async (datum) => {
  if (datum.value.needsUpdate) {
    await storage.setItem(datum.key, { 
      ...datum.value, 
      updated: new Date().toISOString() 
    });
  }
});

Get All Data

Returns the complete raw data array with all datum objects containing key, value, and TTL information.

/**
 * Returns all stored data as array of datum objects
 * @returns Promise resolving to array of datum objects
 */
function data(): Promise<Array<{ key: string, value: any, ttl?: number }>>;

/**
 * Gets the raw JSON string content of a storage file
 * @param key - The key to get raw data for
 * @returns Promise resolving to raw JSON string
 */
function getRawDatum(key: string): Promise<string>;

Usage Examples:

// Get complete data structure
const allData = await storage.data();
console.log(allData);
// [
//   { key: 'user1', value: { name: 'Alice' }, ttl: 1640995200000 },
//   { key: 'config', value: { theme: 'dark' } }
// ]

// Inspect TTL information
allData.forEach(datum => {
  console.log(`Key: ${datum.key}`);
  if (datum.ttl) {
    const expiresAt = new Date(datum.ttl);
    console.log(`Expires at: ${expiresAt.toISOString()}`);
  } else {
    console.log('No expiration');
  }
});

// Find items expiring soon
const expiringSoon = allData.filter(datum => {
  if (!datum.ttl) return false;
  const now = Date.now();
  const timeUntilExpiry = datum.ttl - now;
  return timeUntilExpiry > 0 && timeUntilExpiry < 60000; // expires within 1 minute
});

Get Raw Datum

Returns the raw JSON string content of a storage file for debugging or inspection purposes.

Usage Examples:

await storage.setItem('user', { name: 'Alice', age: 30 }, { ttl: 60000 });

// Get raw JSON string
const rawData = await storage.getRawDatum('user');
console.log(rawData);
// '{"key":"user","value":{"name":"Alice","age":30},"ttl":1640995200000}'

// Parse it manually if needed
const parsedData = JSON.parse(rawData);
console.log(parsedData); // { key: 'user', value: { name: 'Alice', age: 30 }, ttl: 1640995200000 }

// Non-existent key returns empty JSON object string
const missing = await storage.getRawDatum('nonexistent');
console.log(missing); // '{}'

Advanced Query Patterns

Complex Filtering

The filter functions receive the complete datum object with key, value, and ttl properties:

// Filter by multiple criteria
const complexFilter = (datum) => {
  return datum.key.startsWith('user:') && 
         datum.value.active === true &&
         datum.value.role === 'admin';
};

const adminUsers = await storage.values(complexFilter);
const adminUserKeys = await storage.keys(complexFilter);
const adminUserCount = await storage.length(complexFilter);

Data Analysis and Reporting

// Analyze storage usage
const allData = await storage.data();

const report = {
  totalItems: allData.length,
  itemsWithTTL: allData.filter(d => d.ttl).length,
  itemsWithoutTTL: allData.filter(d => !d.ttl).length,
  expiredItems: allData.filter(d => d.ttl && d.ttl < Date.now()).length,
  keyPrefixes: {}
};

// Count items by key prefix
allData.forEach(datum => {
  const prefix = datum.key.split(':')[0];
  report.keyPrefixes[prefix] = (report.keyPrefixes[prefix] || 0) + 1;
});

console.log(report);

Working with Large Datasets

// Process large datasets in batches
const batchSize = 100;
let processed = 0;

await storage.forEach(async (datum) => {
  await processItem(datum);
  processed++;
  
  if (processed % batchSize === 0) {
    console.log(`Processed ${processed} items`);
    // Optional: Add delay to prevent overwhelming the system
    await new Promise(resolve => setTimeout(resolve, 10));
  }
});

Performance Considerations

  • Filter functions: Execute on all items in memory after loading from disk
  • Large datasets: Consider using specific key patterns and valuesWithKeyMatch() for better performance
  • Frequent queries: Cache results when appropriate, as file system access is required
  • Memory usage: data(), keys(), and values() load all items into memory simultaneously

docs

index.md

initialization.md

low-level-operations.md

query-operations.md

storage-operations.md

tile.json