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

@lytjs/common-cache

v6.9.6

Published

Caching strategies for LytJS

Readme

@lytjs/common-cache

缓存策略工具,提供 LRU 缓存、带过期时间的缓存和函数记忆化。

安装

pnpm add @lytjs/common-cache

API

LRUCache<K, V>

基于双向链表实现的 LRU(最近最少使用)缓存。

import { LRUCache } from '@lytjs/common-cache';

const cache = new LRUCache<string, number>(100);
cache.set('key', 42);
cache.get('key'); // 42

ExpiringCache<K, V>

带过期时间的缓存,条目在指定时间后失效。

import { ExpiringCache } from '@lytjs/common-cache';

const cache = new ExpiringCache<string, number>(5000); // 5 秒过期
cache.set('key', 42);
cache.get('key'); // 42(5 秒内有效)

memoize<T>(fn: T, options?): MemoizedFn<T>

函数记忆化,缓存函数调用结果以提高重复调用的性能。

import { memoize } from '@lytjs/common-cache';

const fn = memoize((a: number, b: number) => a + b);
fn(1, 2); // 3(首次计算并缓存)
fn(1, 2); // 3(直接返回缓存结果)
fn.clear(); // 清空缓存

边界行为与已知限制

memoize() 序列化限制

默认情况下,memoize() 使用 JSON.stringify 生成缓存 key。以下情况会导致缓存失效(每次调用都会重新执行原函数):

| 限制 | 说明 | | --------------------- | ------------------------------------------------------------------------------ | | 循环引用 | JSON.stringify 遇到循环引用会抛出异常,被内部 try/catch 捕获后跳过缓存 | | undefined 值 | JSON.stringify 会忽略对象中的 undefined 值,可能导致不同参数生成相同的 key | | Symbol key | JSON.stringify 会忽略 Symbol 类型的键 | | function / bigint | JSON.stringify 会将函数转为 undefined,将 bigint 抛出异常 |

解决方案:通过 options.resolver 提供自定义的 key 生成函数来处理上述情况。

const fn = memoize(complexFn, {
  resolver: (arg) => customKeyGenerator(arg),
});

memoize() maxSize 实际淘汰策略

当配置 maxSize 时,memoize() 的淘汰策略为 FIFO(先进先出),而非 LRU。当缓存条目数超过 maxSize 时,会删除最早插入的条目(Map.keys().next().value),而不是最近最少使用的条目。

const fn = memoize(myFn, { maxSize: 3 });
fn('a'); // 缓存: ['a']
fn('b'); // 缓存: ['a', 'b']
fn('c'); // 缓存: ['a', 'b', 'c']
fn('d'); // 缓存: ['b', 'c', 'd']('a' 被淘汰,而非最少使用的条目)

ExpiringCache() 无自动清理机制

ExpiringCache 不会主动扫描和清理过期条目。过期条目仅在以下时机被被动清理

| 触发时机 | 行为 | | ---------- | -------------------------------------- | | get(key) | 如果条目已过期,删除并返回 undefined | | has(key) | 如果条目已过期,删除并返回 false |

这意味着如果大量条目过期后不再被访问,它们会一直占用内存。需要手动调用 cleanup() 方法来批量清理过期条目:

const cleaned = cache.cleanup(); // 返回清理的条目数量

License

MIT