Skip to content

Instantly share code, notes, and snippets.

@flipeador
Last active December 26, 2024 03:49
Show Gist options
  • Select an option

  • Save flipeador/8a599c952a91031790e162861c976c6d to your computer and use it in GitHub Desktop.

Select an option

Save flipeador/8a599c952a91031790e162861c976c6d to your computer and use it in GitHub Desktop.
JavaScript FinalizationRegistry & WeakRefs.
const $REF = Symbol();
const $DEL = Symbol();
/**
* Set a cleanup callback for the specified object.
* @param {object} target
* The target value to register.
* @param {Function} callback
* Function called when the target is garbage-collected.
* @returns {Function}
* A function to unregister the target value.
*/
function ongc(target, callback) {
const token = {};
let timer = null;
const reg = new FinalizationRegistry(
() => callback(clearInterval(timer))
);
reg.register(target, undefined, token);
timer = setInterval(() => reg, 2_147_483_647);
return () => {
clearInterval(timer);
reg.unregister(token);
};
}
class WeakRefs {
#set = new Set();
has(item) {
return this.#set.has(item[$REF]?.deref?.());
}
add(item) {
const ref = new WeakRef(item);
item[$REF] = new WeakRef(ref);
item[$DEL] = ongc(item, () => this.#set.delete(ref));
this.#set.add(ref);
}
delete(item) {
item[$DEL]?.();
return this.#set.delete(item[$REF]?.deref?.());
}
*[Symbol.iterator]() {
for (let ref of this.#set)
if (ref = ref.deref())
yield ref;
}
}
@flipeador

Copy link
Copy Markdown
Author

Reserved.

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