CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/npm-keyv

Simple key-value storage with support for multiple backends

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

batch-operations.mddocs/

Batch Operations

High-performance batch operations for working with multiple keys simultaneously, with optimizations for storage adapters that support native batch operations.

Capabilities

Get Many

Retrieves multiple values simultaneously with better performance than individual get operations.

/**
 * Get multiple values by keys array
 * @param keys - Array of keys to retrieve
 * @param options - Options including raw data access
 * @returns Promise resolving to array of values in same order as keys
 */
async getMany<Value = GenericValue>(keys: string[], options?: {raw?: false}): Promise<Array<StoredDataNoRaw<Value>>>;
async getMany<Value = GenericValue>(keys: string[], options?: {raw?: true}): Promise<Array<StoredDataRaw<Value>>>;

Usage Examples:

const keyv = new Keyv();

// Setup test data
await keyv.set('user:1', { name: 'Alice', age: 30 });
await keyv.set('user:2', { name: 'Bob', age: 25 });
await keyv.set('user:3', { name: 'Charlie', age: 35 });

// Get multiple users
const users = await keyv.getMany(['user:1', 'user:2', 'user:4']); 
// [{ name: 'Alice', age: 30 }, { name: 'Bob', age: 25 }, undefined]

// Get raw data for multiple keys
const rawUsers = await keyv.getMany(['user:1', 'user:2'], { raw: true }); 
// [{ value: { name: 'Alice', age: 30 }, expires: undefined }, ...]

// Type safety with generics
interface User { name: string; age: number; }
const typedUsers = await keyv.getMany<User>(['user:1', 'user:2']);
// Array<User | undefined>

// Empty array handling
const empty = await keyv.getMany([]); // []

Set Many

Sets multiple key-value pairs simultaneously with optional individual TTL values.

/**
 * Set multiple key-value pairs
 * @param entries - Array of entries to set
 * @returns Promise resolving to array of success booleans
 */
async setMany<Value = GenericValue>(entries: KeyvEntry[]): Promise<boolean[]>;

interface KeyvEntry {
  /** Key to set */
  key: string;
  /** Value to set */
  value: any;
  /** Time to live in milliseconds (optional) */
  ttl?: number;
}

Usage Examples:

const keyv = new Keyv();

// Set multiple entries
const results = await keyv.setMany([
  { key: 'user:1', value: { name: 'Alice', age: 30 } },
  { key: 'user:2', value: { name: 'Bob', age: 25 } },
  { key: 'user:3', value: { name: 'Charlie', age: 35 } }
]);
// [true, true, true]

// Set with individual TTL values
await keyv.setMany([
  { key: 'session:1', value: 'abc123', ttl: 60000 }, // 1 minute
  { key: 'session:2', value: 'def456', ttl: 120000 }, // 2 minutes
  { key: 'permanent', value: 'data' } // no TTL, permanent
]);

// Mixed data types
await keyv.setMany([
  { key: 'string', value: 'hello' },
  { key: 'number', value: 42 },
  { key: 'object', value: { x: 1, y: 2 } },
  { key: 'array', value: [1, 2, 3] },
  { key: 'buffer', value: Buffer.from('data') }
]);

// Empty array handling
const emptyResults = await keyv.setMany([]); // []

Delete Many

Deletes multiple keys simultaneously.

/**
 * Delete multiple keys
 * @param keys - Array of keys to delete
 * @returns Promise resolving to true if operation succeeded
 */
async deleteMany(keys: string[]): Promise<boolean>;

Usage Examples:

const keyv = new Keyv();

// Setup test data
await keyv.set('temp:1', 'data1');
await keyv.set('temp:2', 'data2');
await keyv.set('temp:3', 'data3');

// Delete multiple keys
const success = await keyv.deleteMany(['temp:1', 'temp:2', 'nonexistent']);
// true (returns true if operation completed, regardless of individual key existence)

// Verify deletion
const remaining = await keyv.getMany(['temp:1', 'temp:2', 'temp:3']);
// [undefined, undefined, 'data3']

// Delete all remaining
await keyv.deleteMany(['temp:3']); // true

// Empty array handling
const emptyResult = await keyv.deleteMany([]); // true

Has Many

Checks existence of multiple keys simultaneously.

/**
 * Check if multiple keys exist and are not expired
 * @param keys - Array of keys to check
 * @returns Promise resolving to array of existence booleans
 */
async hasMany(keys: string[]): Promise<boolean[]>;

Usage Examples:

const keyv = new Keyv();

// Setup test data
await keyv.set('existing:1', 'value1');
await keyv.set('existing:2', 'value2');
await keyv.set('expiring', 'value', 1000); // expires in 1 second

// Check multiple keys
const exists = await keyv.hasMany(['existing:1', 'existing:2', 'nonexistent']);
// [true, true, false]

// Check with expired keys (after waiting > 1 second)
// const existsLater = await keyv.hasMany(['existing:1', 'expiring']);
// [true, false] - expired key returns false

// Empty array handling
const emptyExists = await keyv.hasMany([]); // []

// Type consistency
interface User { name: string; }
const keyvTyped = new Keyv<User>();
await keyvTyped.set('user:1', { name: 'Alice' });
const typedExists = await keyvTyped.hasMany(['user:1', 'user:2']);
// [true, false]

Performance Notes

Batch operations provide significant performance benefits:

  • Native Batch Support: When storage adapter supports native batch operations (like Redis MGET/MSET), these are used automatically
  • Fallback Behavior: For adapters without native batch support, operations are executed in parallel using Promise.all
  • Network Efficiency: Reduces network round trips for remote storage adapters
  • Memory Efficiency: Processes results in streaming fashion where possible

Example with Redis adapter:

import Keyv from "keyv";
import KeyvRedis from "@keyv/redis";

const keyv = new Keyv(new KeyvRedis('redis://localhost:6379'));

// This uses Redis MGET internally for optimal performance
const values = await keyv.getMany(['key1', 'key2', 'key3']);

// This uses Redis MSET internally
await keyv.setMany([
  { key: 'key1', value: 'value1' },
  { key: 'key2', value: 'value2' },
  { key: 'key3', value: 'value3' }
]);

docs

batch-operations.md

configuration.md

core-storage.md

events-hooks.md

index.md

raw-data-access.md

storage-adapters.md

tile.json