npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@wfp99/async-lru-cache

v1.2.0

Published

A simple memory cache using the LRU algorithm and supporting asynchronous data access.

Readme

Async LRU Cache

npm version License: MIT Node.js Version

一個支援非同步載入與保存操作、並自動處理並發請求的 LRU(Least Recently Used)記憶體快取,適用於 Node.js 與 TypeScript。

特色

  • 支援非同步的載入器(loader)與保存器(saver)函數
  • 對同一 key 的並發 get() 呼叫共用單一載入器執行
  • 對同一 key 的多個 put() 呼叫會序列化並依序執行
  • 超出設定容量時自動執行 LRU 淘汰
  • 支援每筆項目的可選 TTL(存活時間),並可設定週期性背景清理
  • 可透過 onError 自訂錯誤處理,預設為記錄到 console
  • get() 可省略 loader 進行唯讀查詢;peek() 則提供完全不影響 LRU 順序的查詢方式

安裝

npm install @wfp99/async-lru-cache

系統需求

  • Node.js >= 14.0.0

使用方法

基本使用

import { AsyncLRUCache } from '@wfp99/async-lru-cache';

const cache = new AsyncLRUCache<string, User>({ capacity: 100 });

// get() 在快取未命中時呼叫 loader,並快取其回傳值。
const user = await cache.get('user:123', async () => {
  const response = await fetch('/api/users/123');
  return response.json();
});

// put() 直接儲存值,並可選擇透過 saver 進行持久化。
await cache.put('user:456', userData, async (key, value) => {
  await saveToDatabase(key, value);
});

唯讀查詢

// 省略 loader 的 get() 屬於唯讀查詢:命中時行為與一般 get() 相同(會更新 LRU 順序);
// 未命中時回傳 undefined,且不會新增任何項目或影響 LRU 順序。
const cached = await cache.get('user:123'); // User | undefined

// peek() 無論命中或未命中都不會影響 LRU 順序。
const peeked = await cache.peek('user:123'); // Promise<User> | undefined

TTL(存活時間)

const cache = new AsyncLRUCache({
  capacity: 100,
  defaultTtlMs: 5000,       // 套用到每筆項目的預設 TTL
  cleanupIntervalMs: 10000, // 週期性背景清理過期項目
});

// 為特定項目覆寫預設 TTL。
await cache.get('key1', async () => fetchData(), 30000);

cache.has('key1');        // 項目過期後回傳 false
cache.cleanupExpired();   // 手動移除過期項目
cache.destroy();          // 停止清理計時器並清除所有資料

並發處理

// 以下並發的 get() 呼叫會共用同一個 loader 執行。
const [a, b, c] = await Promise.all([
  cache.get('shared-key', loader),
  cache.get('shared-key', loader),
  cache.get('shared-key', loader),
]);

// 以下 put() 呼叫即使並發啟動,也會依序序列化執行。
cache.put('key', 'value1', saver1);
cache.put('key', 'value2', saver2);
cache.put('key', 'value3', saver3);

錯誤處理

  • 若載入器(get)拋出例外,該項目會從快取中移除,錯誤會傳遞給呼叫端。
  • 若保存器(put)拋出例外,該項目也會被移除,避免快取到尚未持久化的值。
  • put() 會忽略同一 key 前一個已結束操作的失敗,讓新的操作可以繼續進行。
  • 預設情況下,上述失敗會透過 console.error/console.warn 記錄。若要自行處理,可提供 onError
const cache = new AsyncLRUCache({
  capacity: 100,
  onError(error, { key, source }) {
    // source 為 'loader' | 'saver' | 'put-chain'
    myLogger.error(`cache ${source} failed for ${key}`, error);
  },
});

API 參考

AsyncLRUCache<K, V>

constructor(option: AsyncLRUCacheOption<K>)

AsyncLRUCacheOption<K>

| 屬性 | 類型 | 必需 | 描述 | |---|---|---|---| | capacity | number | 是 | 快取中允許的最大項目數量,最小值為 10 | | defaultTtlMs | number | 否 | 套用到未指定 TTL 之項目的預設 TTL | | cleanupIntervalMs | number | 否 | 自動背景清理過期項目的執行間隔 | | onError | (error: unknown, context: { key: K; source: 'loader' \| 'saver' \| 'put-chain' }) => void | 否 | 載入器/保存器失敗時的回呼函數。提供後將取代預設的 console 記錄行為 |

方法

| 方法 | 描述 | |---|---| | get(key, loader, ttlMs?) | 回傳快取值;未命中時呼叫 loader() 並快取其結果 | | get(key) | 省略 loader 的唯讀查詢。命中時行為與上方多載相同(會更新 LRU 順序);未命中時回傳 undefined,不會異動快取 | | peek(key) | 回傳快取值的 Promise<V>;若不存在或已過期則回傳 undefined。無論命中與否都不影響 LRU 順序 | | put(key, value, saver?, ttlMs?) | 儲存 value,並可選擇等待 saver(key, value) 進行持久化 | | invalidate(key) | 若存在,移除 key 對應的項目 | | clear() | 移除所有項目 | | has(key) | 回傳 key 是否存在且未過期。此檢查會順帶清除已過期的項目,但不影響 LRU 順序 | | size() | 回傳目前的項目數量 | | cleanupExpired() | 立即移除所有過期項目 | | destroy() | 停止清理計時器(若有)並清除所有資料 |

TypeScript

此套件以 TypeScript 撰寫並內建型別宣告檔,無需另外安裝 @types 套件。

授權

MIT

貢獻

歡迎在 GitHub 上提出問題和發送 Pull Request。