immutable-tuple
Version:
Immutable finite list objects with constant-time equality testing (===) and no memory leaks
43 lines (37 loc) • 1.21 kB
JavaScript
import { isObjRef } from "./util.js";
// A map data structure that holds object keys weakly, yet can also hold
// non-object keys, unlike the native `WeakMap`.
export class UniversalWeakMap {
constructor() {
// Since a `WeakMap` cannot hold primitive values as keys, we need a
// backup `Map` instance to hold primitive keys. Both `this._weakMap`
// and `this._strongMap` are lazily initialized.
this._weakMap = null;
this._strongMap = null;
this.data = null;
}
// Since `get` and `set` are the only methods used, that's all I've
// implemented here.
get(key) {
const map = this._getMap(key, false);
if (map) {
return map.get(key);
}
}
set(key, value) {
this._getMap(key, true).set(key, value);
// An actual `Map` or `WeakMap` would return `this` here, but
// returning the `value` is more convenient for the `tuple`
// implementation.
return value;
}
_getMap(key, canCreate) {
if (! canCreate) {
return isObjRef(key) ? this._weakMap : this._strongMap;
}
if (isObjRef(key)) {
return this._weakMap || (this._weakMap = new WeakMap);
}
return this._strongMap || (this._strongMap = new Map);
}
}