/weaky

An easy way to avoid leaks.

Primary LanguageJavaScriptMIT LicenseMIT

weaky

Social Media Photo by Igor Dresjan A.P. on Unsplash

An easy way to avoid leaks.

Example

import { signal, effect } from 'https://esm.run/@preact/signals';
import { proxy, deref } from 'https://esm.run/weaky';

const fr = new FinalizationRegistry(cleanup => {
  console.log('cleaning up the effect');
  cleanup();
});

function Button(value) {
  const counter = signal(value);

  const button = Object.assign(
    document.createElement('button'),
    { onclick() { counter.value++ } }
  );

  // avoid retaining the `node` reference within the effect
  // because it would prevent GC from collecting the button
  // because such button will be referenced as parentNode
  const node = proxy(document.createTextNode(''));

  // use deref(proxy(value)) to get the original value
  button.append(deref(node));

  // cleanup the effect when the button is removed from the DOM
  fr.register(button, effect(() => {
    // forward operations to the internal reference
    // if that's still alive
    node.data = counter.value;
  }));

  return button;
}

// test one or thousand components
let [zero, one, two] = [Button(0), Button(1), Button(2)];
document.body.append(zero, one, two);

// test cleanup in a second (requires GC to kick in)
setTimeout(() => { one = one.remove() }, 1000);