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 🙏

© 2024 – Pkg Stats / Ryan Hefner

@wessberg/connection-observer

v1.0.5

Published

An API that provides a way to asynchronously observe the connectedness of a target Node or querySelector inside a document

Downloads

42

Readme

An API that provides a way to asynchronously observe the connectedness of a target Node or querySelector inside a document

Description

ConnectionObserver is a tiny (1kb) API that provides a way to asynchronously observe the connectedness of a target Node or querySelector inside a document.

With ConnectionObserver, you have a low-level building block that can be used to build functionality on top of when you need to perform work when a Node lives inside the DOM, and/or perform work when it becomes detached.

Features

Table of Contents

Install

npm

$ npm install @wessberg/connection-observer

Yarn

$ yarn add @wessberg/connection-observer

pnpm

$ pnpm add @wessberg/connection-observer

Usage

If you are familiar with the family of observers such as MutationObserver and IntersectionObserver, you will feel right at home with ConnectionObserver. Not only is the API very similar, it is also asynchronous and batches together records on the microtask queue.

import {ConnectionObserver} from "@wessberg/connection-observer";

// Hook up a new ConnectionObserver
const observer = new ConnectionObserver(entries => {
	// For each entry, print the connection state as well as the target node to the console
	for (const {connected, target} of entries) {
		console.log("target:", target);
		console.log("connected:", connected);
	}
});

// Observe 'someElement' for connectedness
observer.observe(someElement);

// Eventually disconnect the observer when you are done observing elements for connectedness
observer.disconnect();

Constructing a ConnectionObserver

The ConnectionObserver constructor creates and returns a new observer which invokes a specified callback when there are new connectedness entries available. If you don't call provide any Nodes to the observe method on the ConnectionObserver instance, the callback will never be called since no Nodes will be observed for connectedness.

const connectionObserver = new ConnectionObserver(callback);

Observing Nodes for connectedness

The ConnectionObserver method observe configures the ConnectionObserver callback to begin receiving notifications of changes to the connectedness of the given Node(s). The callback will be invoked immediately with the connectedness of the observed Node(s).

connectionObserver.observe(target);

Observing querySelectors for connectedness

The ConnectionObserver method observe also accepts a query selector as the first argument, instead of a specific Node. This enables you to subscribe to connectedness events for any Nodes that matches your querySelector inside of the document, including any Shadow roots. You can use this functionality for performing actions on elements matching your querySelector as they enter and leave the DOM. For example:

const connectionObserver = new ConnectionObserver(entries => {
	for (const {connected, target} of entries) {
		if (connected) {
			makeImageFancy(target);
		}
	}
});
connectionObserver.observe(`img[data-fancy]`);

Disconnecting the ConnectionObserver

The ConnectionObserver method disconnect will stop watching for the connectedness of all observed Nodes such that the callback won't be triggered any longer.

connectionObserver.disconnect();

Taking ConnectionRecords immediately

ConnectionObserver is asynchronous which means that ConnectionEntries will be batched together and be provided to the callback given in the constructor (see this section) as a microtask. The method takeRecords returns the entries that are currently queued in the batch and haven't been processed yet, leaving the connection queue empty. This may be useful if you want to immediately fetch all pending connection records immediately before disconnecting the observer, so that any pending changes can be processed.

const entries = connectionObserver.takeRecords();

API reference

This section includes a more code-oriented introduction to the types and interfaces of ConnectionObserver

ConnectionObserver

class ConnectionObserver {
	[Symbol.toStringTag]: string;

	/**
	 * Constructs a new ConnectionObserver
	 * @param {ConnectionCallback} callback
	 */
	constructor(callback: ConnectionCallback);

	/**
	 * Observe the given node or query selector for connections/disconnections.
	 * If given a Node, that specific Node will be observed. If given a query selector, such
	 * as for example "img[data-some-attr]", for each new MutationRecord, the query selector
	 * will be executed and the matched nodes will be observed for connections/disconnections
	 * @param {string} target
	 * @example {observe("img[data-some-attr]")}
	 */
	observe(target: Node | string): void;

	/**
	 * Takes the records immediately (instead of waiting for the next flush)
	 * @return {ConnectionRecord[]}
	 */
	takeRecords(): ConnectionRecord[];

	/**
	 * Disconnects the ConnectionObserver such that none of its callbacks will be invoked any longer
	 */
	disconnect(): void;
}

ConnectionCallback

A ConnectionCallback must be provided to the constructor of ConnectionObserver and will be invoked when there are new ConnectionRecords available.

type ConnectionCallback = (entries: ConnectionRecord[], observer: IConnectionObserver) => void;

ConnectionRecord

ConnectionCallbacks are invoked with an array of ConnectionRecords. Those have the following members:

interface ConnectionRecord {
	/**
	 * Whether or not the node is Connected
	 */
	readonly connected: boolean;

	/**
	 * The target Node
	 */
	readonly target: Node;
}

Contributing

Do you want to contribute? Awesome! Please follow these recommendations.

Maintainers

| | | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | Frederik WessbergTwitter: @FredWessbergGithub: @wessbergLead Developer |

Backers

| | | | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------- | | BubblesTwitter: @use_bubbles | Christopher Blanchard |

Patreon

FAQ

Why can't you just use MutationObservers for this

With MutationObserver, we can watch for changes being made to the DOM tree from any root, but using it to watch for when an arbitrary Node is attached to or detached from the DOM is very hard since that requires tracking all Shadow Roots.

There is an ongoing discussion about adding support for tracking connectedness of any Node via MutationObservers, and this library aims to render itself obsolete if and when that becomes a reality in favor of a polyfill.

Why wouldn't you use MutationEvents for this

MutationEvents are deprecated and I would discourage you from using them. Additionally, these were designed and implemented in browser before Shadow DOM v1 came to be, and they are somewhat unreliable for tracking the connectedness of Nodes inside of Shadow roots. Additionally, they are synchronous which is bad for performance and has proven to be performance-killers in numerous benchmarks and investigations.

License

MIT © Frederik Wessberg (@FredWessberg) (Website)