<script type=module>
let tick = 0
// This interval tests to see if the entry in the TwoWayWeakMap is collected.
const loop = setInterval(() => {
const obj = window.map.keyFrom(42)
// logs undefined once enough time elapsed for `o` to be collected
console.log(`o still exists? (${tick++})`, !!obj)
if (!obj) {
clearInterval(loop)
console.log('o was collected!')
}
}, 300)
</script>
<script type=module>
class TwoWayWeakMap /*<K extends object = object, V = unknown>*/
extends WeakMap /*<K, V>*/ {
#refs /*: Set<WeakRef>*/ = new Set();
constructor() {
super();
setInterval(() => this.maybeCleanup(), 1000);
}
set(k /*: K*/ , v /*: V*/ ) /*: void*/ {
super.set(k, v);
this.#refs.add(new WeakRef(k));
}
keyFrom(v /*: V*/ ) /*: K | undefined*/ {
for (const ref of this.#refs) {
// Possibly clean up while we're at it.
const o = ref.deref();
if (!o) {
this.#refs.delete(ref);
continue;
}
if (this.get(o) === v) return o;
}
}
maybeCleanup() {
for (const ref of this.#refs) {
const o = ref.deref();
if (!o) this.#refs.delete(ref);
}
}
}
class SomeClass {}
function main() {
const map = (window.map = new TwoWayWeakMap /*<SomeClass, number>*/());
const o = new SomeClass();
map.set(o, 42);
console.log("value?", map.get(o)); // logs "42"
console.log("object?", !!map.keyFrom(42)); // logs true if it exists
}
main();
// At this point there is no reference to `o`, except by
// WeakRef and WeakMap, so `o` should be collectable.
</script>
This Pen doesn't use any external CSS resources.
This Pen doesn't use any external JavaScript resources.