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

diff-dom-streaming

v0.6.4

Published

Diff DOM algorithm with streaming. Gets all modifications, insertions and removals between a DOM fragment and a stream HTML reader.

Downloads

3,000

Readme

npm version npm size PRs Welcome

The Diff DOM (Document Object Model) algorithm is used to compare two versions of the DOM, such as before and after an update on a web page. It aims to efficiently identify the changes between both DOMs, minimizing the number of manipulations required to update the user interface.

The Diff DOM Streaming library extends the traditional Diff DOM algorithm by introducing support for comparing a DOM node with a stream. This enables the library to process the changes incrementally as they occur during the diff process.

For more info, read this:

Getting started

NPM

Install:

bun install diff-dom-streaming

Then import it:

import diff from "diff-dom-streaming";

JSR

Install:

bunx jsr add @aralroca/diff-dom-streaming

Then import it:

import diff from "@aralroca/diff-dom-streaming";

UNPKG

Just import it:

import diff from "https://unpkg.com/diff-dom-streaming@latest";

Using it

const res = await fetch(/* some url */);

// Diff between the current document and the stream:
await diff(document, res.body);

API

diff(oldNode: Node, stream: ReadableStream<Uint8Array>, options?: Options): Promise<void>

This function performs a diffing operation between the oldNode and the DOM tree from a stream. It applies the necessary changes to update the oldNode accordingly. An optional options that include:

type Options = {
  // calback to handle each new docoument node during the streaming
  // (default: undefined)
  onNextNode?: NextNodeCallback;
  // update the DOM using document.startViewTransition (default: false)
  transition?: boolean;
  // callback to ignore nodes (default: undefined)
  shouldIgnoreNode?: (node: Node | null) => boolean;
};

Lists and key attribute

Keys help to identify which items have changed, are added, or are removed. Keys should be given to the elements inside the array to give the elements a stable identity:

const numbers = [1, 2, 3, 4, 5];
const listItems = numbers.map((number) => (
  <li key={number.toString()}>{number}</li>
));

(Example with JSX)

The diff-dom-streaming library takes into account the key attribute for these cases, if it does not exist, then see if they have id.

Transitions between pages (View Transition API)

You can activate the View Transition API updating the DOM with this property:

await diff(document, res.body, {
+ transition: true
})

[!TIP]

To access the transition with JavaScript/TypeScript you can access the global property window.lastDiffTransition

Incremental vs full transition

Many times it will make more sense to use a complete transition instead of incremental, especially if we do not use suspense and we want a single transition at once instead of several, in this case, instead of using the configuration, we can use the View Transition API directly:

+ document.startViewTransition(async () => {
await diff(document, res.body, {
-  transition: true,
});
+});

Strong Opinion on BODY Tag Attributes during Diffing

Our library has a strong opinion regarding the handling of the BODY tag attributes during the HTML diffing process. This approach is designed to provide greater flexibility and control over runtime modifications, such as themes, fonts, and other display properties that are managed through BODY tag attributes.

During the diffing process, all content within the HTML is typically updated to reflect the latest changes. However, we recognize that certain attributes of the BODY tag, like class and custom data-attributes, are often modified at runtime to control the presentation of the content. To avoid overwriting these runtime changes, our library's diffing algorithm specifically excludes these attributes from being updated.

Key Points

  • Preservation of Attributes: Attributes of the BODY tag (e.g., class, data-attributes) are preserved and not overwritten during the diffing process.
  • Consistent Display: This ensures that runtime modifications, such as theme changes or other display-related adjustments, remain intact across navigations and updates.
  • Enhanced Customization: Users can rely on the BODY tag attributes to manage display properties without concern for them being reset during content updates.

Example

Consider the following scenario where the initial HTML and updated HTML are as follows:

Initial HTML

<body class="light" data-theme="default">
  <div>Content A</div>
</body>

Updated HTML

After a navigation or content update, the new HTML may look like this:

<body class="dark" data-theme="night">
  <div>Content B</div>
</body>

Result After Diffing

After the diffing process, the resulting HTML will be as follows:

<body class="light" data-theme="default">
  <div>Content B</div>
</body>

Examples

In the repo we have examples for you to try.

Locally

There are some examples:

  • Run bun run example:boxes
  • Run bun run examples:spa-like

Stackblitz

You can run the boxes demo with Vanillajs here.

ezgif-4-1ff18912f4

Acknowledgments

The Diff DOM Algorithm with HTML Streaming is inspired by the set-dom library by @dylan_piercey and a technique for parsing streams pioneered by @jaffathecake.

Contributing

See Contributing Guide and please follow our Code of Conduct.

License

MIT