This library provides three iterable weak data structures for JavaScript, IterableWeakSet, IterableWeakMap, and WeakValueMap. They keep only weak references to their keys or values, so entries disappear automatically once the referenced objects are garbage collected instead of blocking GC.
import{IterableWeakMap,IterableWeakSet,WeakValueMap}from"@denostack/weakref";constset=newIterableWeakSet();constmap=newIterableWeakMap();constweakValueMap=newWeakValueMap();Install
npm install weakrefimport{IterableWeakMap,IterableWeakSet,WeakValueMap}from"weakref";Note
Examples below call globalThis.gc?.() only to symbolize “a GC cycle just finished”. Manual GC is available only when
the runtime exposes it (e.g. Node.js started with --expose-gc); otherwise entries disappear the next time the
runtime notifies the FinalizationRegistry.
IterableWeakSet implements the semantics of both WeakSet (weak keys) and Set (iteration helpers) so you can keep a deduplicated collection of objects without preventing them from being garbage collected. Once an object is collected, the entry is removed automatically.
Interface
classIterableWeakSet<Textendsobject>implementsWeakSet<T>,Set<T>{constructor(values?: readonlyT[]|null);constructor(iterable: Iterable<T>);}Example
constset=newIterableWeakSet();// create an object with a weak reference{constuser={id: 1,email: "hey@wan2.land"};set.add(user);}// end of scope, user will be garbage collected// ...later, after a GC cycle (optional manual trigger shown here)globalThis.gc?.();// Node needs --expose-gc// check the set sizeconsole.log(set.size);// output: 0IterableWeakMap combines a WeakMap with iterable Map helpers so you can inspect entries without blocking GC. Keys are weakly referenced and disappear once they are no longer referenced elsewhere.
Interface
classIterableWeakMap<Kextendsobject,V>implementsWeakMap<K,V>,Map<K,V>{constructor(entries?: readonly(readonly[K,V])[]|null);constructor(iterable: Iterable<readonly[K,V]>);}Example
constmap=newIterableWeakMap();// create an object with a weak reference{constuser={id: 1,email: "hey@wan2.land"};constmetadata={created: newDate()};map.set(user,metadata);}// end of scope, user will be garbage collected// ...later, after a GC cycle (optional manual trigger shown here)globalThis.gc?.();// Node needs --expose-gc// check the map sizeconsole.log(map.size);// output: 0WeakValueMap is a class that allows you to create a map of non-object keys with weak references to object values. It is useful when primitive identifiers are used to look up objects that should be collected when no longer referenced elsewhere.
Interface
classWeakValueMap<K,Vextendsobject>implementsMap<K,V>{constructor(entries?: readonly(readonly[K,V])[]|null);constructor(iterable: Iterable<readonly[K,V]>);}Example
constmap=newWeakValueMap();// create an object with a weak reference{constuser={id: 1,email: "hey@wan2.land"};map.set(user.id,user);}// end of scope, user will be garbage collected// ...later, after a GC cycle (optional manual trigger shown here)globalThis.gc?.();// Node needs --expose-gc// check the map sizeconsole.log(map.size);// output: 0Tip
Methods like get(), has(), and iterators (entries(), keys(), values(), forEach(), for...of) check the
underlying WeakRef on access and automatically skip (or clean up) entries whose values have already been
garbage-collected.
However, the size property reflects the internal map's count and may temporarily include stale entries until the
FinalizationRegistry callback runs. If you need an exact count of live entries, use [...map.values()].length
instead.
- Python weakref inspired this project.
- MDN - JS WeakMap
- MDN - JS WeakSet
- MDN - JS WeakRef
- MDN - JS FinalizationRegistry