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

hyperdom-loader

v1.4.0

Published

resource loader for hyperdom

Downloads

4

Readme

hyperdom-loader

A magic asynchronous loader thingy for hyperdom.

magic?

Ok, fair enough. This is better described with an example. Let's say you have a page with a search box, and you want to load the results as you type. You want to make an AJAX GET request to fetch the results and display them in your DOM. Each time the user types a new character, you want to get some new results. Conversely, each time the user doesn't type a new character, you don't want to load search results, which sounds pretty obvious. What hyperdom-loader can do is allow you to get the search results on each new render, but only if the search query has changed. This is much easier than attaching event handlers to the search box.

var hyperdom = require('hyperdom');
var h = hyperdom.html;
var loader = require('hyperdom-loader');
var $ = require('jquery');

var searchResults = loader(function (query) {
  if (query) {
    return $.get('/search?q=' + encodeURIComponent(query));
  }
});

function render(model) {
  var results = searchResults(model.query);

  return h('div',
    h('label', 'Search', h('input', {type: 'text', binding: [model, 'query']})),
    results && model.query
      ? h('ol',
          results.map(function (result) {
            return h('li', result);
          })
        )
      : h('loading...')
  );
}

hyperdom.append(document.body, render, {});

The first time searchResults is called, it will start loading the results and return undefined. As soon as results come in hyperdom will refresh and searchResults will be called again, this time returning the results. As the search query changes, the new results will arrive and the page will be refreshed.

routes

Another example is when you have client-side routes. Let's say, for example, that you have a blog engine and each blog entry is on its own route, naturally. Each time you get to a new blog URL, you want to load the corresponding blog entry. With hyperdom-loader you can load the blog entry in the render function, and it will do the magic of only loading a new blog entry when the URL changes. In this case you may want to use {timeout: 0} to ensure that when the URL changes, you get a "loading" page instead of the previous page.

var hyperdom = require('hyperdom');
var h = hyperdom.html;
var loader = require('hyperdom-loader');
var $ = require('jquery');
var router = require('hyperdom-router');

router.start();

var postRoute = router.route('/post/:id');
var rootRoute = router.route('/');

var loadPost = loader(function (id) {
  return $.get('/api/post/' + encodeURIComponent(id));
}, {timeout: 0});

function render(model) {
  return h('div',
    rootRoute(function () {
      return h('h1', 'welcome to my blog!');
    }),
    postRoute(function (params) {
      var post = loadPost(params.id);
      
      if (post) {
        return h('.post',
          h('h1', post.title),
          h('article', post.body)
        );
      } else {
        return h('h1', 'loading...');
      }
    })
  );
}

hyperdom.append(document.body, render, {});

api

var loader = require('hyperdom-loader');

var loaderFn = loader(fn, [options]);
  • fn - a function that returns a resource, or a promise of a resource. This is only called if the arguments passed to loaderFn are different to the last arguments passed.

  • loaderFn - a function that returns either undefined if the promise returned from fn is still pending, or the fulfilled value of the promise when it has been fulfilled. If the promise is rejected with an error, then loaderFn will throw that error.

  • options.timeout - loaderFn will continue to return the previous value even when new arguments are passed to it, however if the promise returned from fn takes more than timeout then loaderFn will start returning undefined again. Default is 140ms. Set this to 0 to return undefined as soon as the arguments have changed.

  • options.onfulfilled - a function to be called when the promise returned from fn is fulfilled. By default refreshes the hyperdom view.

  • options.key - a function that takes the arguments passed to fn and returns an array of values that are relevant in comparing one call with another. Set this to the string 'json' if you want to compare arguments as rendered in JSON.

  • options.equality - [deprecated, use key above] Default argument equality is by reference, set this to json if you want to compare arguments by comparing the JSON representation of the arguments.

  • options.loading - a function that is called on the previous value while waiting for a new value to be fulfilled. This can be used to return (or throw) the previous value, or some variant to indicate that a new value will soon be available. The default behaviour is to always throw the previous error, or return the previous value if the new value has only been waiting for 140 milliseconds (options.timeout):

      function loading(lastValue, loadingSince, isException) {
        if (isException) {
          throw lastValue;
        } else if (loadingSince < timeout) {
          return lastValue;
        }
      }

reset

loader.reset();

Resets the argument cache, so the next call will call fn. Do this after you know the result will be different, i.e. something has changed on the server.