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

top-layer-observer

v0.1.0

Published

Scripting API to query the document's top layer and observe changes, i.e. elements entering and leaving the top layer

Readme

top layer observer

The top-layer-observer tracks the content of the top layer; it offers web developers the means to...

  1. check at any time which elements are displayed in the top layer, in what order, and which web platform mechanism promoted each of them into the top layer (modal dialog, popover, fullscreen, customized select dropdown)
  2. register a callback that is called when top layer content is added or removed
import { TopLayerObserver } from 'top-layer-observer'

const printTopLayerStats = (currentTopLayerStack) => {
  if (currentTopLayerStack.length === 0) {
    console.log("The top layer is empty.");
  } else {
    console.log(`There are currently ${currentTopLayerStack.length} different entries in the top layer`);
    const topEntry = currentTopLayerStack.at(-1);
    console.log(`The top-most entry was caused by: ${topEntry.cause}`);
    console.log("The corresponding element is:");
    console.log(topEntry.element);
  }
};

printTopLayerStats(TopLayerObserver.currentTopLayerStack);

const observer = new TopLayerObserver((observation, observer) => {
  console.log("The top layer changed.");
  printTopLayerStats(observation.currentTopLayerStack);
});
observer.observe();

motivation

Having more control over the top layer, or at least a way to know whether a given top layer entry is obscured by other content (and ideally to get notified when this fact changes), is a much requested feature in open WHATWG discussions.

This package is an attempt to solve the immediate need (albeit in user land, therefore with limitations) and to test whether an API that follows the established Observer pattern is a good fit; it might thereby give new impetus to the WHATWG feature discussion.

API

The API is modelled on other web platform Observer APIs; the callback is provided as a constructor argument; the observer is started via .observe() and stopped via .disconnect().

The package has only one export: the TopLayerObserver

import { TopLayerObserver } from 'top-layer-observer'

TopLayerObserver.currentTopLayerStack

TopLayerObserver.currentTopLayerStack

Static getter to access the current top layer stack, which is an array of TopLayerEntry instances. The result is identical to the result of the instance accessor of the same name.

Constructor

new TopLayerObserver(callback)

new TopLayerObserver((observation, observer) => {...})

You must provide a callback to the constructor. The callback will be invoked when top layer changes are detected. The callback will receive two arguments:

  • observation: a plain object that contains the property currentTopLayerStack (which is an array of TopLayerEntry instances)
  • observer: reference to the TopLayerObserver instance

instance.observe()

Call .observe() to begin watching for top layer changes.

instance.disconnect()

Call .disconnect() to stop watching for top layer changes. After disconnect you can call observe again to continue watching for top layer changes.

instance.currentTopLayerStack

Instance getter to access the current top layer stack, which is an array of TopLayerEntry instances. The result is identical to the result of the static accessor of the same name.

TopLayerEntry

A TopLayerEntry object represents an entry in the current top layer. It has two properties:

  • element: reference to the corresponding DOM element.
  • cause: a string that identifies the web platform mechanism that caused the top layer promotion 'dialog.modal' | 'fullscreen' | 'popover' | 'select.popover'

The TopLayerEntry object only holds a weak reference to the DOM element, therefore keeping a strong reference to the TopLayerEntry object itself does not create any risk for memory leaks, the weak reference is dereferenced when TopLayerEntry.element is accessed and returns a strong reference again, so don't hold on to those references longer than needed.

Capabilities and Limitations

Currently four different ways exist to promote elements to the top layer

  • opening a modal <dialog>
  • opening a popover
  • requesting fullscreen
  • opening the picker dropdown of a customized <select>

Each of the four mechanisms can concern elements in the regular DOM as well as elements in shadow DOM. Currently top-layer-observer is capable of detecting any top layer content caused by any of those four mechanisms...

  • when in the regular DOM
  • when in open shadow DOM ...but not when in closed shadow DOM.

Feedback

Any feedback is welcome; if you encounter any bugs please report them.