index.jsjavascript
/**
* A small, fully-documented sample module that exists purely to demonstrate
* what an **API reference page** looks like when generated by
* `clean-jsdoc-theme`. It is not a real library — it is a showcase of the
* common JSDoc constructs (classes, methods, params, returns, examples,
* typedefs, and cross-references) and how the theme renders them.
*
* @module sample-api
*/
/**
* Options accepted by the {@link Cache} constructor.
*
* @typedef {Object} CacheOptions
* @property {number} [maxSize=100] - Maximum number of entries to keep before
* the least-recently-used entry is evicted.
* @property {number} [ttl=0] - Time-to-live for an entry in milliseconds. `0`
* disables expiry.
*/
/**
* A tiny in-memory, least-recently-used (LRU) cache.
*
* This class is a demo of how `clean-jsdoc-theme` renders a documented class:
* the signature, the constructor, properties, and each method get their own
* section with parameters, return types, and examples.
*
* @example <caption>Basic usage</caption>
* const cache = new Cache({ maxSize: 2 });
* cache.set('a', 1);
* cache.set('b', 2);
* cache.get('a'); // => 1
*
* @see {@link CacheOptions}
*/
export class Cache {
/**
* Create a new cache.
*
* @param {CacheOptions} [options={}] - Configuration for the cache.
*/
constructor(options = {}) {
/**
* The maximum number of entries this cache will hold.
*
* @type {number}
*/
this.maxSize = options.maxSize ?? 100;
/**
* Time-to-live per entry, in milliseconds. `0` means entries never expire.
*
* @type {number}
*/
this.ttl = options.ttl ?? 0;
/** @private */
this._store = new Map();
}
/**
* The number of entries currently stored.
*
* @type {number}
* @readonly
*/
get size() {
return this._store.size;
}
/**
* Store a value under a key. If the cache is full, the least-recently-used
* entry is evicted first.
*
* @param {string} key - The key to store the value under.
* @param {*} value - The value to cache.
* @returns {Cache} The cache instance, for chaining.
*
* @example
* cache.set('user:1', { name: 'Ada' }).set('user:2', { name: 'Linus' });
*/
set(key, value) {
if (this._store.size >= this.maxSize && !this._store.has(key)) {
const oldest = this._store.keys().next().value;
this._store.delete(oldest);
}
this._store.set(key, value);
return this;
}
/**
* Look up a value by key, marking it as recently used.
*
* @param {string} key - The key to look up.
* @returns {*} The cached value, or `undefined` if the key is not present.
*/
get(key) {
if (!this._store.has(key)) return undefined;
const value = this._store.get(key);
this._store.delete(key);
this._store.set(key, value);
return value;
}
/**
* Check whether a key is present without affecting its recency.
*
* @param {string} key - The key to test.
* @returns {boolean} `true` if the key is cached.
*/
has(key) {
return this._store.has(key);
}
/**
* Remove every entry from the cache.
*
* @returns {void}
*/
clear() {
this._store.clear();
}
}
/**
* Create a {@link Cache} pre-populated from an object of key/value pairs.
*
* @param {Object<string, *>} entries - Initial entries to seed the cache with.
* @param {CacheOptions} [options] - Options forwarded to the {@link Cache}
* constructor.
* @returns {Cache} A new, seeded cache.
*
* @example
* const cache = createCache({ a: 1, b: 2 }, { maxSize: 10 });
* cache.get('b'); // => 2
*/
export function createCache(entries, options) {
const cache = new Cache(options);
for (const [key, value] of Object.entries(entries)) {
cache.set(key, value);
}
return cache;
}