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

radhist

v0.1.2

Published

Radical history and action state

Downloads

6

Readme

Radical HTML history library. Inspired by this tweetstorm. Check out ➡️ a demo. This lets you pop history, and set 'action state'.

Why do you want this? Let's start with a video demo, from Twitter (about Twitter)! This library helps you implement this behavior, whether user-initated or programatically:

https://user-images.githubusercontent.com/119184/126085151-0b7fd457-6f44-48f0-9754-77d8cad1a7fc.mp4

In the example, the user pops the third "retweet" state. Because we have two buffer states, it can actually pop again and restore a 'new' middle state—removing the ability to press Forward in the user's browser. Read on for what radhist can do. ⬇️📖

Usage

This replaces the History API (it still exists, but you shouldn't use it—radhist takes over). Published on NPM.

import { attach } from 'radhist';

const stack = attach();  // idempotent, will always return the same instance

// nb. You must not use the History API at this point; radhist handles all
// 'popstate' events and pushes carefully-crafted history state.

stack.addListener(() => {
  console.info('current URL', window.location, 'state', stack.state);
  if (stack.isAction) {
    console.info('...action state', stack.actionState);
  }
});

someButton.onclick = () => {
  stack.push('/new/path');

  // or, optionally:
  const state = { 'optional': state };
  const title = 'optional title';
  stack.push('#hash', { state, title });
};

backButton.onclick = () => {
  // pop the current page, removing it from stack (preventing user forward)
  if (stack.canPop) {
    stack.pop();
  }
};

openConfirmDialogButton.onclick = () => {
  // set an 'action state' (read on below)
  stack.setAction({ optional: 'state' });
};

For more features, check out the types file.

Notes

  • Don't use the History API (pushState, replaceState, and the popstate handler). This library expects to trigger these regularly in odd asynchronous ways.

  • You can use the older window.location.assign or window.location.hash = ... approaches to changing the URL, because they mostly look like a user-initiated change (and reload the page in all cases but hash changes).

    • Don't set the same hashed URL (e.g., window.location.hash = window.location.hash). Firefox made an awkward choice when implementing the History API that means this change can go unnoticed.
  • Chrome has an odd issue around navigation after you reload a page that was in the action state. Bug TBD.

Library Features

This library adds a new concept (in 'action state'), a related capability, plus a bunch of nicities in the stack object.

Action State

This library lets you set an Action State. It cannot change the current page's URL.

Setting this lets the user perform a temporary action that is not retained within the History API, yet still (usually^) allows the user to close it via the browser's Back button.

An example of this might be—you want to show a confirm modal, and allow the user to close it natively, but it won't reappear if the user reloads the site or sends its URL to a friend.

If the user closes the state, its entry is removed from the underlying History API. They can't go Forward again and bring it back—this works via the mechanism described above, plus a few corner cases (site reload, the user pressing Back to go back many entries).

^If you set an action state without any 'buffer' of History API entries, pressing Back will also leave the site. This is similar to Twitter and Slack and other places that this library inspires, because there's no buffer of pages to work with.

Pop Capability

Much of the above is implemented via supporting the 'pop' capability. If your history API has at least three entries, you can pop the current page and ensure that the user cannot hit Forward in their browser.

This works just like the video above suggests—technically, it goes back two pages and pushes the same page. However, this library hides this implementation and simply calls you once.

Background

For background, the History API has a few limitations, and isn't that well-suited to building app-like experiences on the web. This has been discussed in length, but as of mid-2021, is not ready yet.