HA-store API Documentation

A high-availability data-fetching wrapper with smart coalescing, batching, and TLRU caching for optimal performance.

💡
Key Benefits

Reduces database load through intelligent request coalescing and batching. TLRU caching optimized for Zipfian distribution patterns. Battle-tested and lightweight.

Installation

npm install ha-store

Quick Start

Basic setup with a resolver function:

import haStore from 'ha-store';

const store = haStore({
  resolver: async (ids, params) => {
    // Fetch your data
    const results = await db.users.find({
      _id: { $in: ids }
    });
    return results;
  },
  tick: 50,
  max: 100,
  cache: {
    ttl: 60000,
    size: 1000
  }
});

// Fetch single item
const user = await store.get('user-123');

// Fetch multiple items
const users = await store.getMany(['user-1', 'user-2', 'user-3']);

Coalescing

Detects duplicate requests and reuses the original Promise handle instead of making redundant calls.

âš¡
How it works

When multiple identical requests are made simultaneously, HA-store recognizes duplicates and returns the same Promise to all callers, reducing load on your data source.

Batching

Buffers incoming requests for a set duration and bundles them together before sending to the data source.

Configuration

  • tick: Time interval between batches (in milliseconds)
  • max: Maximum number of records per batch
const store = haStore({
  resolver: myResolver,
  tick: 50,    // Wait 50ms
  max: 100     // Up to 100 items per batch
});

Caching

Uses Time-aware Least Recently Used (TLRU) caching strategy, optimized for data following Zipfian distribution patterns.

🚀
Smart Caching

Only frequently-accessed "hot" data benefits from caching. HA-store automatically manages cache based on access patterns, keeping your most-requested items instantly available.

Constructor

haStore(config: Config): HaStore

Creates a new HA-store instance with the provided configuration.

Parameters

Name Type Description
config Object Configuration object

Example

const store = haStore({
  resolver: async (ids, params) => {
    return await database.findByIds(ids, params);
  },
  tick: 50,
  max: 100
});

get()

store.get(id: string, params?: object, agg?: function): Promise

Fetches a single item by ID with automatic coalescing, batching, and caching.

Parameters

Name Type Default Description
id string - Unique identifier
params object {} Context parameters passed to resolver
agg function null Aggregation function

Example

const user = await store.get('user-123');
const user = await store.get('user-123', { includeProfile: true });

getMany()

store.getMany(ids: string[], params?: object, agg?: function): Promise

Fetches multiple items by their IDs. Returns an object mapping each ID to its result.

Parameters

Name Type Default Description
ids string[] - Array of unique identifiers
params object {} Context parameters
agg function null Aggregation function

Example

const users = await store.getMany(['user-1', 'user-2', 'user-3']);

// Result format (uses Promise.allSettled):
// {
//   'user-1': { status: 'fulfilled', value: {...} },
//   'user-2': { status: 'fulfilled', value: {...} },
//   'user-3': { status: 'rejected', reason: Error(...) }
// }

set()

store.set(items: any[], ids: string[], params?: object): Promise

Manually sets items in the cache. Useful for cache warming or updating cached values.

Parameters

Name Type Description
items any[] Array of items to cache
ids string[] Array of IDs (required)
params object Context parameters

Example

await store.set(
  [{ name: 'Alice' }, { name: 'Bob' }],
  ['user-1', 'user-2']
);

clear()

store.clear(ids: string | string[], params?: object): any

Clears items from the cache.

Example

// Clear single item
await store.clear('user-123');

// Clear multiple items
await store.clear(['user-1', 'user-2', 'user-3']);

size()

store.size(): Promise<object>

Returns statistics about the current store state.

Example

const stats = await store.size();
console.log(stats);
// {
//   records: 150,
//   queue: { ... }
// }

Configuration Options

Option Type Default Description
resolver function - Data fetching function
tick number 50 Batching interval (ms)
max number 100 Max items per batch
delimiter string '|' Key delimiter
cache object - Cache configuration

Cache Configuration

Option Type Description
ttl number Time-to-live (ms)
size number Maximum cached items
store string | object 'inMemory' or 'redis'

Example

const store = haStore({
  resolver: myResolver,
  cache: {
    ttl: 60000,
    size: 1000,
    store: 'inMemory'
  }
});

Cache Stores

In-Memory Store

Default cache store that keeps data in application memory.

import haStore, { caches } from 'ha-store';

const store = haStore({
  resolver: myResolver,
  cache: {
    store: caches.inMemory
  }
});

Redis Store

Distributed cache store using Redis.

import haStore, { caches } from 'ha-store';

const store = haStore({
  resolver: myResolver,
  cache: {
    store: caches.redis,
    redis: {
      host: 'localhost',
      port: 6379
    }
  }
});

Resolvers

PostgreSQL Resolver

import haStore, { resolvers } from 'ha-store';

const store = haStore({
  resolver: resolvers.postgres({
    connection: {
      host: 'localhost',
      database: 'mydb'
    },
    table: 'users',
    idColumn: 'id'
  })
});

Custom Resolver

const customResolver = async (ids, params, agg) => {
  const results = await fetchFromAPI(ids, params);
  return results;
};

const store = haStore({
  resolver: customResolver
});

Events

The store instance extends EventEmitter and emits events for monitoring:

store.on('cache-hit', (data) => {
  console.log('Cache hit:', data);
});

store.on('cache-miss', (data) => {
  console.log('Cache miss:', data);
});

store.on('batch-sent', (data) => {
  console.log('Batch sent:', data);
});

store.on('error', (error) => {
  console.error('Error:', error);
});