Skip to main content

Base Cache Driver

The base cache driver is an abstract class that all built-in cache drivers extend. It provides common methods and properties to reduce code duplication.

When to Extend

  • When building a new cache driver
  • When you want to reuse logging, key parsing, and option handling
  • When you need automatic TTL management and data preparation

Example: Extending BaseCacheDriver

import { BaseCacheDriver } from "@warlock.js/cache";
import type { CacheDriver } from "@warlock.js/cache";

interface MyOptions {
globalPrefix?: string;
ttl?: number;
}

export class MyDriver extends BaseCacheDriver<MyDriver, MyOptions>
implements CacheDriver<MyDriver, MyOptions> {

public name = "myDriver";

// Implement required abstract methods
public async removeNamespace(namespace: string) {
// Implementation
}

public async set(key: string | GenericObject, value: any, ttl?: number) {
// Implementation
}

public async get(key: string | GenericObject) {
// Implementation
}

public async remove(key: string | GenericObject) {
// Implementation
}

public async flush() {
// Implementation
}
}

Implemented Methods

Core Methods

  • setOptions(options): Set the cache driver options
  • parseKey(key): Parse the cache key (uses parseCacheKey)
  • connect(): Default connection method (logs connecting/connected)
  • disconnect(): Default disconnection method (logs disconnecting/disconnected)

TTL Management

  • get ttl(): Get the default TTL from options
  • getExpiresAt(ttl): Calculate expiration timestamp in milliseconds
  • prepareDataForStorage(data, ttl): Prepare data with TTL and expiration
  • parseCachedData(key, data): Parse cached data and handle expiration

Logging

  • log(operation, key?): Log cache operations with consistent formatting
  • Automatically logs success, error, and connection operations
  • Uses the driver name as the log channel

Available Operations

The log() method supports these operation types:

OperationDescriptionLog Level
fetchingGetting a value from cacheinfo
fetchedSuccessfully retrieved valuesuccess
cachingSetting a value in cacheinfo
cachedSuccessfully stored valuesuccess
removingRemoving a value from cacheinfo
removedSuccessfully removed valuesuccess
clearingClearing namespaceinfo
clearedSuccessfully cleared namespacesuccess
flushingFlushing entire cacheinfo
flushedSuccessfully flushed cachesuccess
expiredCache entry expirederror
notFoundCache key not founderror
connectingConnecting to cache backendinfo
connectedSuccessfully connectedsuccess
disconnectingDisconnecting from cache backendinfo
disconnectedSuccessfully disconnectedsuccess
errorError occurrederror

Data Structure

The base driver automatically wraps cached data in this structure:

interface CacheData {
data: any; // The actual cached value
ttl?: number; // Time to live in seconds
expiresAt?: number; // Expiration timestamp in milliseconds
}

Example: Custom Driver with BaseCacheDriver

import { BaseCacheDriver } from "@warlock.js/cache";
import type { CacheDriver } from "@warlock.js/cache";

interface MyCacheOptions {
globalPrefix?: string;
ttl?: number;
storage: Map<string, any>;
}

export class MyCacheDriver extends BaseCacheDriver<MyCacheDriver, MyCacheOptions>
implements CacheDriver<MyCacheDriver, MyCacheOptions> {

public name = "myCache";

public async removeNamespace(namespace: string) {
namespace = await this.parseKey(namespace);

this.log("clearing", namespace);

// Remove all keys starting with namespace
for (const key of this.options.storage.keys()) {
if (key.startsWith(namespace)) {
this.options.storage.delete(key);
}
}

this.log("cleared", namespace);
}

public async set(key: string | GenericObject, value: any, ttl?: number) {
key = await this.parseKey(key);

this.log("caching", key);

const data = this.prepareDataForStorage(value, ttl);
this.options.storage.set(key, data);

this.log("cached", key);
return value;
}

public async get(key: string | GenericObject) {
key = await this.parseKey(key);

this.log("fetching", key);

const data = this.options.storage.get(key);
if (!data) {
this.log("notFound", key);
return null;
}

return this.parseCachedData(key, data);
}

public async remove(key: string | GenericObject) {
key = await this.parseKey(key);

this.log("removing", key);
this.options.storage.delete(key);
this.log("removed", key);
}

public async flush() {
this.log("flushing");
this.options.storage.clear();
this.log("flushed");
}
}

See Cache Driver Interface for the complete interface definition.