API Reference

Complete API documentation for all redis-graph-cache methods.

Write API call styles

Every write method supports two equivalent call shapes. New code should prefer the object form for readability.

// Object form (recommended)
await cache.writeEntity({ entityType: 'post', data, ttl: 600 });

// Positional form (fully supported)
await cache.writeEntity('post', data, { ttl: 600 });

Entity Operations

writeEntity

Normalizes the input and writes every resulting key with an atomic compare-and-set merge. Nested relations are recursively normalized into their own keys.

await cache.writeEntity('post', {
  id: 1,
  title: 'Hello',
  author: { id: 9, name: 'Ada' },
});

// Returns: { success: true, keys: ['post:1', 'user:9'], operationId, timestamp }
OptionTypeDescription
ttlnumberOverride TTL for the root entity only
cascadeTTLbooleanUse root TTL as floor for all children
forceTTLbooleanApply uniform TTL to entire write tree

readEntity

Reads and hydrates an entity (walks relations). Returns null when the entity key doesn't exist.

const post = await cache.readEntity('post', 1, {
  maxDepth: 2,
  selectiveFields: ['title', 'author'],
  excludeRelations: ['comments'],
});
OptionTypeDescription
maxDepthnumberOverride per-call hydration depth
selectiveFieldsstring[]Only return these fields (still includes id)
excludeRelationsstring[]Skip these relation names

updateEntityIfExists

Conditional update: writes only if the entity already exists. Returns null if missing.

const updated = await cache.updateEntityIfExists('post', { id: 1, views: 42 });
if (updated === null) {
  // post doesn't exist; don't recreate
}

deleteEntity

Plain DEL on the entity key. Does NOT consult the membership back-index. Returns true if deleted, falseif it didn't exist.

For cascade invalidation across indexed lists with trackMembership, use invalidateEntity instead.

Plain List Operations

writeList

Replaces the entire list with the given items. Each item is also written as an entity.

await cache.writeList('recentPosts', { categoryId: 5 }, [
  { id: 1, title: 'A' },
  { id: 2, title: 'B' },
]);

readList

Reads all items in the list and hydrates each as an entity.

const posts = await cache.readList('recentPosts', { categoryId: 5 });

addListItem

Appends an item to the list and writes the entity atomically. Idempotent: if the id is already a member, no append happens. Returns true if newly appended, false if duplicate. The list TTL is reapplied on every successful insert.

// Pass the FULL entity object, not just the id.
// The cache extracts the id via entityData[listSchema.idField].
await cache.addListItem('recentPosts', {}, postData);

removeListItem

Atomic Lua remove. The list's existing TTL is preserved. Pass { deleteEntity: true } to also deleteEntity the underlying key. Returns true when the id was a member of the list.

await cache.removeListItem('recentPosts', {}, 2);
await cache.removeListItem('recentPosts', {}, 3, { deleteEntity: true });

deleteList

Plain DEL on the list key. Underlying entities remain. Returns true if a key was removed.

await cache.deleteList('recentPosts', {});

Indexed List Operations

writeIndexedList

Bulk upsert. Normalizes every item and writes entities + ZADDs in parallel batches. Does NOT clear existing members.

await cache.writeIndexedList('globalFeed', {}, [
  { id: 1, title: 'a', createdAt: '2026-04-26T10:00:00Z' },
  { id: 2, title: 'b', createdAt: '2026-04-26T11:00:00Z' },
]);

readIndexedList

Paginated, hydrated read.

const feed = await cache.readIndexedList('globalFeed', {}, {
  limit: 50,
  offset: 0,
  reverse: true, // highest score first
  excludeRelations: ['comments'],
});
OptionDefaultDescription
limit50Max items to return
offset0Skip this many items
reversefalseSort descending (newest-first for timestamp scores)
minScore / maxScore-∞ / +∞Score range filter

addIndexedListItem

Adds one entity to the indexed list. Returns true if newly added, false if score updated on existing id.

await cache.addIndexedListItem('globalFeed', {}, postData);

removeIndexedListItem

Removes one id. Pass { deleteEntity: true } to also cascade-invalidate the entity.

await cache.removeIndexedListItem('globalFeed', {}, 7);
await cache.removeIndexedListItem('globalFeed', {}, 7, { deleteEntity: true });

indexedListSize

ZCARD. Returns 0 when the key doesn't exist. O(1).

const n = await cache.indexedListSize('globalFeed', {});

deleteIndexedList

DELon the ZSET key. Entities remain; back-index entries remain (harmless — they self-clean via TTL or the next cascade invalidation).

await cache.deleteIndexedList('globalFeed', {});

Cache Management

invalidateEntity

The killer method. Atomically removes the entity key, looks up every indexed list with trackMembership that contains this id, and removes the id from all of those lists in one Lua script.

const cleaned = await cache.invalidateEntity('post', 42);
// → 3 (removed from post:42 + 3 feeds)

clearAllCache

Destructive. Wipes all keys owned by the engine.

await cache.clearAllCache({ confirm: 'YES_WIPE_ALL' });
// in production:
await cache.clearAllCache({ confirm: 'YES_WIPE_ALL', allowProduction: true });

Monitoring & Lifecycle

getMetrics

Synchronous snapshot of hit rate, latency, totals.

const m = cache.getMetrics();
// {
//   cacheHits, cacheMisses, hitRate,        // 0..1
//   totalOperations, avgResponseTime,        // ms
//   activeConnections,                       // 1 if any pool client up
//   failedOperations,
//   memoryUsage: 0,                          // cache-side; reserved
//   lastUpdated
// }

getHealthStatus

Async health check including Redis-side memory.

const h = await cache.getHealthStatus();
// {
//   status: 'healthy' | 'degraded' | 'unhealthy',
//   redis: {
//     connected: true,
//     latency: 2,             // ms; running average
//     memoryUsage: 1234567    // bytes; INFO memory used_memory
//   },
//   cache: {
//     activeOperations: 5,    // currently in-flight cache calls
//     memoryUsage: 0,         // reserved
//     errorRate: 0.001        // failed / total
//   },
//   timestamp: 1777207682877
// }
//
// Status:
//   'unhealthy' → PING failed
//   'degraded'  → error rate > 5% OR breaker non-CLOSED
//   'healthy'   → neither of the above

enableDebugMode

Toggles a flag in the monitoring config. The library does not currently emit verbose debug logs itself; this is provided as a hook for consumers and middlewares.

cache.enableDebugMode(true);
// ... do something ...
cache.enableDebugMode(false);

disconnect

Closes all pool connections gracefully. Always call this on shutdown.

await cache.disconnect();