/not-so-weak

Iterable WeakMap, WeakSet and WeakValue

Primary LanguageJavaScriptISC LicenseISC

Not So Weak

build status Coverage Status

Social Media Photo by Pete Nuij on Unsplash

Iterable WeakMap (WKey) and WeakSet (WSet) through FinalizationRegistry and WeakRef primitives, reimplementing also the WeakValue (WValue) module, including the optional callback for collected values.

// const {WSet, WKey, WValue} = require('not-so-weak');
import {WSet, WKey, WValue} from 'not-so-weak';

// class WSet<T extends object> extends WeakSet implements Set {}
// class WKey<K extends object, V> extends WeakMap implements Map {}
// class WValue<K, V extends object> extends Map {}

// node --expose-gc example
const ws = new WSet([{}]);
const wm = new WKey([[{}, 'value']]);

const wv = new WValue;
wv.set('value', {}, function (key) {
  console.assert(this === wv);
  console.assert(key === 'value');
  console.log(key, 'value collected');
});

console.assert(ws.size === 1);
console.assert(wm.size === 1);
console.assert([...wm.values()][0] === 'value');
console.assert([...wv.keys()][0] === 'value');

setTimeout(() => {
  gc();
  console.assert(ws.size === 0);
  console.assert(wm.size === 0);
  console.assert(wv.size === 0);
});

Suitable For

  • Weak key/value based state/store
  • Server Side related tasks that can't bother with manual removal of weakly referenced entries
  • every case where you end up swapping to Map or Set because you realize you cannot iterate over their Weak counterpart
  • every case where you think there's a memory leak due possibly missing weakThing.delete(ref) operations

Not Suitable For

  • raw performance or benchmarks against Map or Set
  • every case where weakThing.delete(ref) is already handled by the library or framework logic