mirror of
https://github.com/Shineii86/MiruroAPI.git
synced 2026-10-22 18:25:11 +00:00
docs: rewrite all files with AniKotoAPI documentation style
- Box-style file headers (======= border, @description, @exports, @author, @license) - Section headers (═════════════════════════════════════════) - Function-level JSDoc comments with @param, @returns, @example - Inline notes for non-obvious logic (lazy eviction, pipe decoding, slug resolution) - Feature markers (---- FEATURE: description ----) - Footer on every module (═══════════ END: filename ═══════════) - Added /stats and /openapi endpoints to router
This commit is contained in:
+107
-9
@@ -1,27 +1,125 @@
|
||||
/*
|
||||
* ======= • ======= • ======= • ======= • =======• =======
|
||||
* MiruroAPI — cache.js
|
||||
* Repository: https://github.com/Shineii86/MiruroAPI
|
||||
*
|
||||
* @description
|
||||
* In-memory caching utility for storing and retrieving API responses.
|
||||
* Implements TTL-based cache invalidation to prevent stale data
|
||||
* while reducing unnecessary requests to AniList/Miruro backends.
|
||||
*
|
||||
* @exports
|
||||
* getCached, setCache, clearCache
|
||||
*
|
||||
* @author Shinei Nouzen
|
||||
* @license MIT
|
||||
* ======= • ======= • ======= • ======= • =======• =======
|
||||
*/
|
||||
|
||||
// ══════════════════════════════════════════════════════════════
|
||||
// CACHE STORAGE & CONFIGURATION
|
||||
// ══════════════════════════════════════════════════════════════
|
||||
|
||||
// ---- FEATURE: In-memory Map-based cache storage ----
|
||||
/**
|
||||
* Internal cache storage using JavaScript Map object.
|
||||
* Stores data with expiry timestamps for TTL-based expiration.
|
||||
*
|
||||
* @type {Map<string, {data: any, expiry: number}>}
|
||||
*/
|
||||
const cache = new Map();
|
||||
const MAX_CACHE_SIZE = 100;
|
||||
|
||||
// ---- FEATURE: Cache time-to-live configuration (1 minute) ----
|
||||
/**
|
||||
* Default cache TTL (Time-To-Live) in milliseconds.
|
||||
* Default: 1 minute (60,000 ms).
|
||||
* After this duration, cached items are considered stale
|
||||
* and will be removed on next access.
|
||||
*
|
||||
* @type {number}
|
||||
* @default 60000
|
||||
*/
|
||||
const DEFAULT_TTL = 60 * 1000;
|
||||
|
||||
function getCached(key) {
|
||||
// ---- FEATURE: Maximum cache size limit ----
|
||||
/**
|
||||
* Maximum number of entries allowed in the cache.
|
||||
* When exceeded, the oldest entry is evicted (FIFO).
|
||||
* Prevents unbounded memory growth on long-running instances.
|
||||
*
|
||||
* @type {number}
|
||||
* @default 100
|
||||
*/
|
||||
const MAX_CACHE_SIZE = 100;
|
||||
|
||||
// ══════════════════════════════════════════════════════════════
|
||||
// CACHE OPERATIONS
|
||||
// ══════════════════════════════════════════════════════════════
|
||||
|
||||
// ---- FEATURE: Retrieve cached data by key with TTL validation ----
|
||||
/**
|
||||
* Retrieves data from cache if it exists and hasn't expired.
|
||||
* Automatically removes stale entries on access (lazy eviction).
|
||||
*
|
||||
* @param {string} key - The cache key to lookup
|
||||
* @returns {any|null} Cached data if valid, null if expired or missing
|
||||
*
|
||||
* @example
|
||||
* const data = getCached("search:naruto:1:20");
|
||||
* if (data) {
|
||||
* // Use cached data
|
||||
* }
|
||||
*/
|
||||
const getCached = (key) => {
|
||||
const entry = cache.get(key);
|
||||
if (!entry) return null;
|
||||
|
||||
// NOTE: Lazy eviction — delete stale entries on access
|
||||
if (Date.now() > entry.expiry) {
|
||||
cache.delete(key);
|
||||
return null;
|
||||
}
|
||||
return entry.data;
|
||||
}
|
||||
|
||||
function setCache(key, data, ttl = DEFAULT_TTL) {
|
||||
return entry.data;
|
||||
};
|
||||
|
||||
// ---- FEATURE: Store data in cache with TTL expiry ----
|
||||
/**
|
||||
* Stores data in cache with TTL-based expiry.
|
||||
* Evicts oldest entry if cache is at max capacity (FIFO).
|
||||
*
|
||||
* @param {string} key - The cache key to store under
|
||||
* @param {any} data - The data to cache (any serializable type)
|
||||
* @param {number} [ttl=DEFAULT_TTL] - Time-to-live in milliseconds
|
||||
* @returns {void}
|
||||
*
|
||||
* @example
|
||||
* // Cache search results for 2 minutes
|
||||
* setCache("search:one-piece", results, 120000);
|
||||
*/
|
||||
const setCache = (key, data, ttl = DEFAULT_TTL) => {
|
||||
// NOTE: FIFO eviction — remove oldest entry when cache is full
|
||||
if (cache.size >= MAX_CACHE_SIZE) {
|
||||
const firstKey = cache.keys().next().value;
|
||||
cache.delete(firstKey);
|
||||
}
|
||||
cache.set(key, { data, expiry: Date.now() + ttl });
|
||||
}
|
||||
|
||||
function clearCache() {
|
||||
cache.set(key, { data, expiry: Date.now() + ttl });
|
||||
};
|
||||
|
||||
// ---- FEATURE: Clear all cached entries from memory ----
|
||||
/**
|
||||
* Clears all entries from the cache. Use when:
|
||||
* - Memory cleanup is needed
|
||||
* - Force-refreshing all data
|
||||
* - Application restart/reset
|
||||
*
|
||||
* @returns {void}
|
||||
*/
|
||||
const clearCache = () => {
|
||||
cache.clear();
|
||||
}
|
||||
};
|
||||
|
||||
module.exports = { getCached, setCache, clearCache };
|
||||
|
||||
// ══════════════════════════════════════════════════════════════ END: cache.js
|
||||
|
||||
Reference in New Issue
Block a user