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

routelib

v1.0.5

Published

browser router library

Downloads

20

Readme

Client side browser Router lib

Router supports routes of types:

  • strings
  • regular expressions
  • functions

Router supports asynchronous hooks:

  • onBeforeEnter: called before page loading
  • onEnter: called on page loading
  • onLeave: called on page leaving

Router supports hash API and History API. Can be chosen on router instance creation.

On init Router sets the listener on document click and check if target is anchor. If anchor href is relative and starts from "/" it will be processed as route link. Any other links will be opened in a new window.

Installing

npm install routelib

Once the package is installed, you can import the library using import or require approach:

import { Router } from "routelib";

Router API public methods

addRoute

Adds new route

  addRoute(routeConfig: RouteConfig): void {

Where RouteConfig is an object that describe route path and callbacks (hooks) to process on navigation to this route (or out of it: onLeave):

type RouteConfig = {
  path: string | RegExp | Function; // Path as string or RegExp for pattern matching
  onBeforeEnter?: (params?: HookParams) => Promise<void> | void;
  onEnter: (params?: HookParams) => Promise<void> | void;
  onLeave?: (params?: HookParams) => Promise<void> | void;
};

and HookParams is an object with data:

type HookParams = {
  [key: string]: string;
};

removeRoute

If you don't need route any more - it could be removed

  removeRoute(path: string):void

setNotFoundRoute

To handle route errors you can add handler for not found routes.

  setNotFoundRoute(routeConfig: Omit<RouteConfig, "path">): void;

To handle error 404 your server should redirect any call to index.html! In webpack you can achive this by adding parameter historyApiFallback

module.exports = (env) => ({
  ...
  devServer: {
    ...
    historyApiFallback: true,
  },

navigate

You can navigate to any route by calling navigate method. Optional parameter update allows only change href without render. It's more internal option.

  navigate(path: string, update = true): void;

Example

import { Router } from "../src/RouterLib";

// Create initial markup
const nav = document.createElement("nav");
nav.id = "nav";
nav.innerHTML = `
  <ul>
    <li><a href="/">Home</a></li>
    <li><a href="/about">About</a></li>
    <li><a href="/year">Year view</a></li>
    <li><a href="/month">Month view</a></li>
    <li><a href="/month?filter=true&month=1&text=task1&tag=tag1">Month with params view</a></li>
    <li><a href="/day">Day view</a></li>
    <li><a href="/list">List view</a></li>
    <li><a href="/function">Function view</a></li>
    <li><a href="/asd123">Regular expression</a></li>
    <li><a href="/any">Any unknown page</a></li>
    <li><a href="/removed">This path is added and removed</a></li>
    <li><a href="https://google.com">External link - google.com</a></li>

  </ul>
`;

// append body with element
document.body.append(nav);

// create element to which will print information
const info = document.createElement("div");
info.id = "info";
document.body.append(info);

// creating router with modern History API
const router = new Router("history");

// creating router with hash API
// const router = new Router("hash");


// helper with onEnter hook, that will output information about
// selected route
const callback = (path: string | RegExp | Function) => ({
  path,
  onEnter: () => {
    console.log("Entered", path);
    if (typeof path === "string") {
      document.title = path.slice(1);
      const el = document.createElement("div");
      el.innerHTML = path;
      info.append(el);
    }
  },
});

// add Root route
router.addRoute(callback("/"));

// add About route demonstrating onBeforeEnter, onEnter
// and onLeave hooks with timer API
router.addRoute({
  path: "/about",
  onBeforeEnter: async () => {
    console.log("Before entering about page - wait 3 seconds...");
    let el = document.createElement("div");
    el.innerHTML = "Before entering about page - wait for 3...";
    info.append(el);
    await new Promise((resolve) => {
      setTimeout(resolve, 1000);
    });
    el = document.createElement("div");
    el.innerHTML = "Before entering about page - wait for 2...";
    info.append(el);
    await new Promise((resolve) => {
      setTimeout(resolve, 1000);
    });
    el = document.createElement("div");
    el.innerHTML = "Before entering about page - wait for 1...";
    info.append(el);
    await new Promise((resolve) => {
      setTimeout(resolve, 1000);
    });
  },
  onEnter: () => {
    console.log("Entered about page");
    document.title = "About";
    const el = document.createElement("div");
    el.innerHTML = "About";
    info.append(el);
  },
  onLeave: async () => {
    console.log("Leaving about page");
    const el = document.createElement("div");
    el.innerHTML = "Leaving about page - wait 3 seconds...";
    info.append(el);
    await new Promise((resolve) => {
      setTimeout(resolve, 3000);
    });
  },
});

// add route supporting with regular expression
router.addRoute({
  path: /[\S]{1,3}123/,
  onEnter: () => {
    console.log("Entered RegExp page");
    info.innerHTML = "RegExp";
    document.title = info.innerHTML;
  },
});

// add route supporting function as route
router.addRoute({
  path: () => "/function",
  onEnter: () => {
    console.log("Entered /function page");
    info.innerHTML = "Function";
    document.title = info.innerHTML;
  },
});

// add route with helper `callback`
router.addRoute(callback("/year"));
router.addRoute(callback("/month"));
router.addRoute(callback("/day"));
router.addRoute(callback("/list"));
router.addRoute(callback("/removed"));
router.removeRoute("/removed");

// add default route for any not found page
// 404 page route
router.setNotFoundRoute({
  onEnter: () => {
    console.log("404 - Page not found");
    info.innerHTML = "404 - Page not found";
    document.title = "404 - Page not found";
  },
});

// start navigation from Root
router.navigate("/");