npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@statewalker/utils-dom

v0.4.1

Published

DOM Utility methods and classes

Readme

@statewalker/utils-dom: DOM Utilities

This package contains the following DOM utilities used in other packages:

  • bindView(iterator, action, options) - creates and returns a DOM element which is updated each time when the given iterator returns a new value
  • getElementInvalidation(element) - returns a Promise instance associated with the given DOM element; the returned promise is resolved when the element is removed from the DOM tree
  • replaceDomContent(element, node) - replaces the content of the given DOM element by the given DOM node (element or text node).
  • trackDomNode(node, { onAdd, onRemove, getContainer }) - tracks the node and calls the specified onAdd/onRemove methods when the node is attached/removed from the DOM
  • toDomNode(value, doc) - transforms the given JavaScript value to a DOM node; text, numbers and boolean values are tranformed to Text instances; objects are serialized (with the JSON.stringify method) and also transformed to Text instances; DOM nodes are returned "as is", without modifications.

getElementInvalidation(element)

This method returns a Promise instance associated with the given DOM element; the returned promise is resolved when the element is removed from the DOM tree.

This method returns a single Promise instance for the specific DOM element. This Promise is stored in the invalidation field of the element.


const div = document.createElement("div");
document.body.appendChild(div);

// Get the invalidation promise associated with the given element:
const invalidation = getElementInvalidation(div);
...
// This function is called when the DOM element is detached from the DOM tree:
const onDetach = () => console.log('The element was detached from DOM...');
invalidation.then(onDetach);

// Check that the second time this method returns the same invalidation instance:
const invalidation2 = getElementInvalidation(div);
assert(invalidation === invalidation2);

// Shows this message:
// 'The element was detached from DOM...'

bindView(iterator, action, options)

This utility function allows to update HTML elements when the specified iterator yields a new value. It also allows to easily initialize the element and cleanup associated resources when this element is detached from DOM.

const elm: Element = bindView(
  // Async iterator returning new values to visualize:
  iterator : AsyncIterator,

  // The function returning the element
  action : Function,

  // Optional parameters:
  options : Object = {
    // Function used to handle errors
    handleError = console.error,

    // This function returns the root element to listen
    getRoot
    
  } : object = {}
)

The action(...) callback method recieves the following structure:

  • params : parameters object
  • params.init - sets the initialization function; it is called when the view is attached to the DOM
  • params.done - sets the finalization function which is called when the view is removed from the DOM
  • params.update - sets a new function to call on each value update; the function defined with the update method has the following signature: (view, value, oldValue) => { ... }

Example 1: in this example the activation method registers only one method to init/done/update the created view.

import { bindView } from '@statewalker/utils-dom'

// Generate a new sequence of values to update
// (see below for the implementation of the "generateValues" method):
const it = generateValues(50, 2000);

// Create a new view to append to the document.
const view = bindView(it, ({ init, update, done }) => {
  // View initialization:
  init((view) => view.innerHTML = "Initializing...");
  // Destroys the view and cleans up all associated resources:
  done((view) => view.innerHTML = "Destroying...");
  // This method is called each time when the iterator returns a new value:
  update((view, value, oldValue) => {
    view.innerText = `Counter: ${value}!`;
  })
  // Create and returns the view to update:
  return document.createElement("div");
})

// Append the resulting view to the document:
document.body.appendChild(view);

Example 2: in this example the activation method registers two methods for each of the "init/done/update" stages:

import { bindView } from '@statewalker/utils-dom'

// Generate a new sequence of values to update:
// (see below for the implementation of the "generateValues" method):
const it = generateValues(50, 2000);

// In this example the activation function registers two callbacks 
// for each of the "init/update/done" stages:
// - one method changes the conntent of the view
// - the second method prints some messages in the log
const div = bindView(it, ({ init, update, done }) => {
  
  // View initialization:
  init((view) => view.innerHTML = "Initializing...");
  // The second function to call on the view initialization:
  init(() => console.log("Init."))
  
  // Destroys the view and cleans up all associated resources:
  done((view) => view.innerHTML = "Destroying...");
  // The second method to call on initialization:
  done(() => console.log("Done."))

  // This method is called each time when the iterator returns a new value:
  update((view, value, oldValue) => {
    view.innerText = `Counter: ${value}!`;
  })
  // Print the values returned by the iterator:
  done((view, newValue, oldValue) => console.log("- Update:", { oldValue, newValue }));

  // Create and returns the view to update:
  return document.createElement("div");
})
// Append the resulting view to the document:
document.body.appendChild(div);

The generateValues method used in the examples above:

// This function generates values used to update the view
async function* generateValues(count = 100, maxTimeout = 1000) {
  for (let i = 0; i < count; i++) {
    yield i;
    await new Promise(r => setTimeout(Math.random() * maxTimeout));
  }
}

replaceDomContent(element, node)

This method replaces the content of the given DOM element by the given DOM node (element or text node).

Example:

import { replaceDomContent } from '@statewalker/utils-dom'

const root = document.querySelector("#root");

const div = document.createElement("div");
div.innerText = 'Hello, world';
replaceDomContent(root, div);

## trackDomNode(node, { onAdd, onRemove, getContainer })

This method tracks the node and calls the specified onAdd/onRemove methods when the node is attached/removed from the DOM.

Parameters:

  • node - the DOM node to track
  • params - an object containing method parameters
  • params.onAdd - an optional callback method invoked after the node is attached to DOM; it takes the node as the single parameter
  • params.onRemove - an optional callback method invoked when the node is removed from DOM; it recieves two parameters: the node itself and a boolean flag showing if the node was notified as attached or not (if the onAdd method was called before)
  • params.getContainer - returns the container to track for the specified node

toDomNode(value, doc)

This method transforms the given JavaScript value to a DOM node; text, numbers and boolean values are tranformed to Text instances; objects are serialized (with the JSON.stringify method) and also transformed to Text instances; DOM nodes are returned "as is", without modifications.

Example:

import { toDomNode } from '@statewalker/utils-dom'

const root = document.querySelector("#root");

// Transforms string a Text instance:
root.appendChild(toDomNode("Hello, world")) 

// Transforms the given number to a Text instance:
root.appendChild(toDomNode(12345)) 

// Returnes the DOM node without modifications: 
const h3 = toDomNode(document.createElement("h3"));
h3.innerHTML = "Hello, there!"
root.appendChild(h3)