Creates a new Redis cache instance
Redis connection configuration
Optional redisInstance: RedisOptional Redis instance for testing (uses ioredis if not provided)
Optional logger for dependency injection (defaults to console)
Optional debug flag to enable verbose cache logging (defaults to false)
Clear lookup caches
JIRA project key
Optional fieldType: stringOptional field type (clears all if omitted)
Optional issueType: stringOptional issue type
// Clear all lookups for project
await cache.clearLookups('TEST');
// Clear specific lookup type
await cache.clearLookups('TEST', 'priority');
// Clear issuetype-specific lookup
await cache.clearLookups('TEST', 'component', 'Story');
Get a value from the cache with stale-while-revalidate support
Returns both the value and whether it's stale. By default, stale values are returned - callers should trigger background refresh when isStale=true.
Cache key (will be prefixed with jml:)
Optional options: { Optional rejectIf true, returns null for stale values (bypasses SWR)
CacheResult with value and isStale flag
Retrieve cached lookup values
Uses CacheClient.get() for consistent error handling and key prefixing.
JIRA project key
Type of lookup field
Optional issueType: stringOptional issue type for issuetype-specific lookups
Object with value (array or null) and isStale flag
const { value, isStale } = await cache.getLookup('TEST', 'priority');
const { value, isStale } = await cache.getLookup('TEST', 'component', 'Story');
Execute a refresh function with deduplication.
If a refresh is already in progress for this key, returns the existing promise instead of starting a new one. This prevents duplicate API calls when multiple stale cache hits occur for the same data.
Unique key identifying this refresh operation (e.g., cache key)
Async function that fetches fresh data and updates cache
Promise that resolves when refresh is complete
// Multiple concurrent calls to this will only trigger ONE API call
await cache.refreshOnce('lookup:TEST:users', async () => {
const users = await fetchUsersFromJira();
await cache.setLookup('TEST', 'users', users);
});
Set a value in the cache with soft TTL (supports stale-while-revalidate)
Stores value with soft expiry timestamp. After soft TTL, value is "stale" but still returned - callers should trigger background refresh. Hard TTL is 24 hours just to prevent infinite Redis growth.
Cache key (will be prefixed with jml:)
Value to store
Soft TTL - value is "stale" after this but still usable
Cache lookup values (priorities, components, versions, etc.)
Uses CacheClient.set() for consistent error handling and key prefixing.
Cache key pattern: lookup:{projectKey}:{fieldType}:{issueType?}
JIRA project key (e.g., "TEST")
Type of lookup field (e.g., "priority", "component", "version")
Array of lookup values to cache
Optional issueType: stringOptional issue type for issuetype-specific lookups
// Cache priority list (project-level)
await cache.setLookup('TEST', 'priority', [
{ id: '1', name: 'Blocker' },
{ id: '2', name: 'High' }
]);
// Cache components (issuetype-specific)
await cache.setLookup('TEST', 'component', [...], 'Story');
Redis-based cache implementation with graceful degradation
Implements both CacheClient (generic key-value) and LookupCache (converter-specific).
All cache keys are prefixed with
jml:to avoid conflicts. Cache operations fail gracefully - errors are logged but don't crash the library. Only theping()method throws errors.