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

fast-pager

v1.1.4

Published

Cached Pagination for Node.JS

Downloads

17

Readme

FastPager

Build Status

Cached Paginator for Node.JS

The goal of FastPager is to introduce an easy way to paginate a long list of results into pages through a storage strategy to improve web page loads and server performance.

The common web developer writes code such that pagination is done on every every page load. However, this may be inefficient and prevents scalability as the same result is reproduced multiple times for different users. One way to tackle this is to put this into a cache.

FastPager combines file/memory caching with pagination.

Usage

There are two stages involved in FastPager: building and fetching. The building process retrieves each page's results and storage it. When requested, the fetching process may retrieve from the storage. It is recommended to run the building process in a background process separate from the process that serves the webpages.

Building pages

There are two key information needed by FastPager when building pages: the context and the retrieval function.

  • The context represents the series of pages being retrieved: it is needed for storage so that it can be uniquely identified later.
  • The retrieval function takes in a page number and performs the actual retrieval and pagination logic. It is repeatedly called with increments to the page parameter until an empty return is returned. A Promise is expected to be returned from this function.

The following shows an example of a script that builds pages for posts sorted by date in descending order. In this example, Sequelize is used for the script to retrieve the list of posts to be displayed. The pages are stored as JSON in files in a system temporary directory.

const os = require('os');
const path = require('path');
const models = require('../models');

const pager = new FastPager(path.join(os.tmpdir(), 'fastpager'));
const POSTS_PER_PAGE = 10;

function buildLatestPostsPages() {
  return pager
    .context('latest-posts')
    .from((page) => {
      return models.Post
        .findAll({
          order: ['datePosted', 'desc'],
          offset: (page - 1) * POSTS_PER_PAGE,
          limit: POSTS_PER_PAGE
        });
    })
    .build();
};

buildLatestPostsPages()
  .then(() => {
    console.log('Build Complete!');
  });
  

The build method returns a Promise which can be used to do additional work once the pagination build process is done. You can write a timer / scheduler around the buildLatestPostsPages() that periodically invalidate and rebuild the cache. One example using setTimeout is as follows:

const PROCESSING_INTERVAL = 300000; // every 5 mins
const startProcessing = () => {
  buildLatestPostsPages()
    .then(() => {
      console.log('Build Complete!');
      setTimeout(startProcessing, PROCESSING_INTERVAL);
    });
};

startProcessing();

Retrieving pages

Once the pages are built, the webpages can retrieve the result without having to perform any pagination or retrieval from database logic:

const os = require('os');
const path = require('path');

const pager = new FastPager(path.join(os.tmpdir(), 'fastpager'));

app.get('/posts', (req, res, next) => {
  let page = req.query.page || 1;
  page = Number(page);
  if (page < 0) {
    page = 1;
  }
  return pager
    .context('latest-posts')
    .at(page)
    .retrieve()
    .then((posts) => {
      res.json(posts);
    })
    .catch((err) => {
      console.error(err);
      res.status(400);
    });
});

License

Open-source under The MIT License.