Skip to content

Instantly share code, notes, and snippets.

@Ctrlmonster
Last active July 13, 2023 16:43
Show Gist options
  • Save Ctrlmonster/1be65141ce0de62e9e09942610cc5ae9 to your computer and use it in GitHub Desktop.
Save Ctrlmonster/1be65141ce0de62e9e09942610cc5ae9 to your computer and use it in GitHub Desktop.
Collection of Weakrefs that can be iterated
class WeakCollection<T extends object> {
#registry = new FinalizationRegistry((heldValue: WeakRef<T>) => {
this.delete(heldValue);
});
#refs: WeakRef<T>[] = [];
#values: T[] = [];
#clean() {
let index = 0;
this.#values.length = 0;
while (index < this.#refs.length) {
const value = this.#refs[index].deref();
if (value == undefined) {
this.#deleteIdx(index);
} else {
this.#values.push(value);
index++;
}
}
return this.#values;
}
get values() {
return this.#clean();
}
* [Symbol.iterator]() {
const values = this.#clean();
yield* values;
};
add(element: T) {
const ref = new WeakRef(element);
this.#refs.push(ref);
this.#registry.register(element, ref);
}
delete(element: WeakRef<T>) {
this.#registry.unregister(element);
const value = element.deref();
for (let i = 0; i < this.#refs.length; i++) {
if (value === this.#refs[i].deref()) {
this.#deleteIdx(i);
return true;
}
}
return false;
}
has(value: T) {
for (const ref of this.#refs)
if (ref.deref() === value)
return true;
return false;
}
#deleteIdx(idx: number) {
if (this.#refs.length === 0) return;
const lastIdx = this.#refs.length - 1;
if (idx === lastIdx) {
this.#refs.pop();
} else {
this.#refs[idx] = this.#refs[lastIdx]
this.#refs.pop();
}
}
}
// @ts-ignore
window.WeakCollection = WeakCollection;
const obj = {x: {name: "hi"}, y: {name: "world"}, z: {name: "yooo"}};
const w = new WeakCollection();
w.add(obj.x);
w.add(obj.y);
w.add(obj.y);
w.add(obj.y);
w.add(obj.z);
// @ts-ignore
delete obj.x;
// @ts-ignore
delete obj.y;
// @ts-ignore
obj.z = null;
// won't log anything, depending on timeout duration
setTimeout(() => {
for (const value of w) {
console.log(value)
}
}, 1000)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment