mrkeyoor.com_
Wed 23 Sept 02:52 UTC
npmUtilsupdated 22 Sept 2026

oblivious-set review

oblivious-set 2.0.0 remembers whether a value was added within one fixed time-to-live. It stores a timestamp in a Map, refreshes that timestamp on another `add`, and rejects old entries when `has` checks them. Cleanup is lazy, so it avoids a timer per entry and can be garbage-collected with its owner. Version 2 requires Node 16 or newer and ships declarations plus ESM and CommonJS entry points. It stores no associated value, has no capacity bound, and does not fire an event at expiry, which makes it a recent-ID filter rather than a general cache.

Verdict

Our oblivious-set 2.0.0 install took 0.7 seconds and bundled to 0.4 KB gzipped with no dependencies, so it is a cheap recent-ID filter for one process and one TTL. Use a bounded cache or shared store when values, capacity, durable deduplication, or exact expiry behavior matter.

We installed it

Lab card: what happened when we installed oblivious-setScreenshot of oblivious-set documentation
Install✓ · 0.7s1 package on disk · 1 MB
ImportESM import works · require() works · CommonJS package with exports map
Browser0.4 KBgzipped (0.6 KB minified), bundled with esbuild
TypesTypeScript types bundled
Known vulns00 critical · 0 high · 0 moderate · 0 low (npm audit)

Answers from our run

Does oblivious-set install cleanly?

Yes. In a fresh container with an empty cache, npm install oblivious-set finished in 0.7s, leaving 1 package and 1 MB on disk. npm audit reported no known vulnerabilities.

How much does oblivious-set add to a browser bundle?

0.4 KB gzipped (0.6 KB minified) when the whole package is bundled for the browser with esbuild. Importing only part of it is usually smaller.

Does oblivious-set work with both ESM and CommonJS?

Yes. Both import 'oblivious-set' and require('oblivious-set') worked in Node 22 in our run. The package is published as CommonJS with an exports map.

Does oblivious-set include TypeScript types?

Yes, type declarations ship inside the package, so no @types install is needed.

oblivious-set or lru-cache: which should you use?

lru-cache: Use it for key-value entries, TTLs, a capacity limit, disposal hooks, and LRU eviction. Our oblivious-set 2.0.0 install took 0.7 seconds and bundled to 0.4 KB gzipped with no dependencies, so it is a cheap recent-ID filter for one process and one TTL.

When should you not use oblivious-set?

Entries carry data; this package stores only membership timestamps, while an LRU cache stores key-value pairs

API stability4/5The public job is narrow: construct with a millisecond TTL, then call `add`, `has`, or `clear`. Tests and source make refresh-on-add and lazy expiry straightforward to verify. Version 2.0.0 raised the Node requirement to 16 and changed package delivery enough to justify a major version, so upgrade assumptions still need checking. Once on 2.x, the tiny surface leaves few places for accidental behavioral drift.
Docs2/5The README gives a short TypeScript example and explains the central design choice: expiration works without intervals or timeouts. It does not spell out several consequences visible in source and tests. Expired keys may remain in the public Map, `map.size` may include stale entries, re-adding refreshes age, objects compare by identity, capacity is unbounded, and there is no single-key delete or expiry callback. Consumers must read implementation code for behavior that affects memory planning.
Maintenance3/5The unarchived repository was pushed on 2026-02-20, version 2.0.0 is current, and GitHub reports 0 open issues and pull requests. That looks clean until the README's contribution section explains that issues are closed and bug reports should arrive as pull requests with tests. Recent packaging and Node support exist, but the support channel puts diagnosis and reproduction work on users. Eight GitHub stars also suggest a small direct reviewer pool.
Ecosystem3/5The npm endpoint counted 3,266,400 downloads in the latest completed week, while GitHub shows 8 stars. Version 2 includes TypeScript declarations and working ESM and CommonJS paths with no runtime dependencies, making transitive adoption easy. There are no plugins, adapters, storage backends, or companion packages because the abstraction is intentionally one small Map wrapper. The download figure shows reach, though community help and examples remain thin.

Use it if

  • A process needs to suppress duplicate event IDs for one fixed number of milliseconds
  • Membership is enough and no value needs to be returned with the key
  • Lazy cleanup is preferable to keeping an interval or timeout for each entry
  • The same tiny typed helper must work from ESM and CommonJS
Skip it if

Setup reality

Our install of oblivious-set 2.0.0 completed in 0.7 seconds. It left 1 package and 1 MB on disk; the package was 164 KB unpacked with 0 direct dependencies and 0 peer dependencies. npm audit found 0 known vulnerabilities. It is CommonJS with an exports map, and both require() and ESM import worked in our Node 22 sandbox. TypeScript declarations were bundled. The esbuild browser result was 0.6 KB minified and 0.4 KB gzipped.

Construction takes one TTL in milliseconds, applied to every entry. Re-adding a value replaces its timestamp and moves it to the newest Map position. A second TTL window needs a second ObliviousSet instance. Objects follow Map identity: the same reference matches, while a new object with identical fields does not. Store primitive IDs when field equality is intended.

Expiration is deliberately lazy. has(value) checks the stored timestamp and removes that value if it is too old. add(value) schedules a zero-delay sweep instead of a timer at the actual expiry time. An expired key can therefore remain in the public map until a later check or cleanup, even though has correctly returns false. The raw map.size is not a guaranteed count of live entries.

There is no maximum capacity, persistence, cross-process coordination, expiration callback, or supported single-key delete method. A burst can retain every distinct key for the full TTL. The README also states that GitHub issues are closed and asks bug reporters to submit a pull request with a reproducing test. Use this only for process-local, best-effort duplicate suppression where losing all history on restart is acceptable.

Patterns

Remember one value for 30 seconds remember-value

import { ObliviousSet } from 'oblivious-set';

const recent = new ObliviousSet<string>(30_000);
recent.add('event-42');
console.log(recent.has('event-42'));

The 30,000 value is milliseconds and applies to every entry in this instance.

Drop a repeated event ID suppress-duplicate

const seen = new ObliviousSet<string>(5 * 60_000);

function acceptEvent(id: string) {
  if (seen.has(id)) return false;
  seen.add(id);
  return true;
}

This remembers IDs only inside the current process. A restart or a second worker has a separate history.

Refresh age on repeated activity refresh-ttl

const active = new ObliviousSet<string>(60_000);

active.add('session-a');
active.add('session-a');

The second `add` writes a new timestamp, so the 60-second window starts again.

Forget every recent value clear-set

const recent = new ObliviousSet<string>(10_000);
recent.add('a');
recent.add('b');
recent.clear();
console.log(recent.has('a'));

`clear` removes the whole Map. Version 2 has no supported wrapper method for deleting only `a`.

Check after the TTL observe-expiry

const short = new ObliviousSet<string>(100);
short.add('token');

setTimeout(() => {
  console.log(short.has('token')); // false
}, 150);

No timer runs at 100 ms. The later `has` call notices the timestamp, deletes the key, and returns false.

Sweep before reading the public Map inspect-size

import { ObliviousSet, removeTooOldValues } from 'oblivious-set';

const recent = new ObliviousSet<string>(1_000);
recent.add('job-1');
removeTooOldValues(recent);
console.log(recent.map.size);

The public Map can retain expired entries until cleanup. Depending on it also couples code to an implementation detail.

Use stable object references compare-objects

const recent = new ObliviousSet<{ id: number }>(5_000);
const item = { id: 1 };
recent.add(item);

console.log(recent.has(item)); // true
console.log(recent.has({ id: 1 })); // false

Map compares objects by identity. Put `id` in a string or number set when field equality is required.

Create one set per TTL window separate-windows

const recentRequests = new ObliviousSet<string>(5_000);
const recentLogins = new ObliviousSet<string>(15 * 60_000);

recentRequests.add('request-1');
recentLogins.add('user-9');

TTL belongs to the instance, not the entry. Two policies require two sets.

Alternatives

PackageRegistryPick it when
lru-cachenpmUse it for key-value entries, TTLs, a capacity limit, disposal hooks, and LRU eviction.
quick-lrunpmUse it for a smaller bounded key-value cache with maximum age support.
mnemonistnpmUse it when this set is one of several specialized collections the application needs.

More utils guides

lru-cache · ajv · type-fest · p-limit · find-up · js-yaml · the whole shelf →

How this guide is made: grounded in the library's documentation, release notes, changelog, and issue history, on a fixed rubric — not a hands-on install of every release. The 50 most-downloaded entries are additionally install-verified in clean containers. Corrections: contact the desk.