Skip to content

Instantly share code, notes, and snippets.

@devsnek
Created July 9, 2019 19:54
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save devsnek/e3ee8be1fc235e2bee43b2c1cd262adf to your computer and use it in GitHub Desktop.
Save devsnek/e3ee8be1fc235e2bee43b2c1cd262adf to your computer and use it in GitHub Desktop.
const KEYS = 1;
const VALUES = 2;
const KEYS_VALUES = 3;
export default class WeakValueMap {
#map = new Map();
#group = new FinalizationGroup((iterator) => {
for (const key of iterator) {
this.#map.delete(key);
}
});
constructor(iterable) {
if (iterable !== undefined && iterable !== null) {
for (const [key, value] of iterable) {
this.set(key, value);
}
}
}
set(key, value) {
this.#group.unregister(key);
this.#map.set(key, new WeakRef(value));
this.#group.register(value, key, key);
}
has(key) {
const w = this.#map.get(key);
if (w === undefined) {
return false;
}
if (w.deref() === undefined) {
this.#map.delete(key);
this.#group.unregister(key);
return false;
}
return true;
}
get(key) {
const w = this.#map.get(key);
if (w === undefined) {
return undefined;
}
const v = w.deref();
if (v === undefined) {
this.#map.delete(key);
this.#group.unregister(key);
return undefined;
}
return v;
}
delete(key) {
const removed = this.#map.delete(key);
if (removed) {
this.#group.unregister(key);
return true;
}
return false;
}
clear() {
for (const key of this.#map.keys()) {
this.#group.unregister(key);
}
this.#map.clear();
}
#iterator = function* iterator(type) {
for (const [key, weak] of this.#map) {
const v = weak.deref();
if (v === undefined) {
this.#map.delete(key);
this.#group.unregister(key);
} else if (type === KEYS) {
yield key;
} else if (type === VALUES) {
yield v;
} else {
yield [key, v];
}
}
};
keys() {
return this.#iterator(KEYS);
}
values() {
return this.#iterator(VALUES);
}
entries() {
return this.#iterator(KEYS_VALUES);
}
forEach(callback, thisArg) {
for (const [key, value] of this) {
callback.call(thisArg, key, value, this);
}
}
}
Object.defineProperty(WeakValueMap.prototype, Symbol.iterator, {
value: WeakValueMap.prototype.entries,
writable: true,
enumerable: false,
configurable: true,
});
@Bnaya
Copy link

Bnaya commented Oct 30, 2019

Does this code has any license? i want to use it and want to make sure it will be ok :)

@devsnek
Copy link
Author

devsnek commented Oct 30, 2019

@Bnaya
Copy link

Bnaya commented Oct 31, 2019

Thanks!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment