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

gram-route

v1.3.1

Published

A fast http router for node.

Downloads

69

Readme

gram-route

pipeline status coverage report pipeline status pipeline status

A fast http router for node. Matches static routes with hashmap lookup and parameter routes with assembled regex or the Radix Tree.

The Regex based on nikic/fast-route. Check out nikic blog post for more Explanation.

The Radix Tree based on find-my-way.

Radix Tree is the standard router for matching dynamic routes because it is faster in most cases.

Saving the static routes in a hashmap and dynamic in the radix tree is the fastest for matching http requests. Also with this you have the power of path-to-regex in combination with the fast Radix Tree.

Only Radix Tree without the hashmap is also possible.

Use the assembled regex for 100% type safety e.g. if you want to match like this: /(user|u). But this method don't support wildcard route (/*).


//es 6
import {router, dispatcher} from 'gram-route';

let r = router();

//a static route without parameters
//route has a method, a path (or pattern) and a handler (which can be anything)
r.get("/",(req, res) => {
	res.write("Hello world");
});

//a route with a placeholder (wildcard)
//:id can be anything until the next /
r.get("/user/:id",(req, res, id) => {
	res.write("page from user: " +id);
});

//group
//routes can placed in groups so every route got the same prefix
//a group needs a callback where all routes of this group will be placed
r.group("/admin",() => {
	r.get("",(req, res) => {
		res.write("Admin main page");
	});
	
	r.get("/server-status",(req, res) => {
		res.write("Server is still working");
	});
	
	//nested groups, the group inside will get the prefix of the outside group
	r.group("/user-manager",() => {
		//route: /admin/user-manager/:id
		r.get("/:id",(req, res, id) => {
			res.write("all data from user: " +id);
		});
		
		r.post("",(req, res) => {
			res.write("user successfully created");
		});
	});
});

//Adding middleware to a route with the add() function from the route object
r.get("/routeWithMiddleware",() => {
	
}).add(() => {
	
});

//Adding more middleware to a route
//add() returns the route object
r.get("/routeWithMoreMiddleware",() => {
	
})
.add(() => {
	
})
.add(() => {
	
});

//Adding middleware to a group
//All routes in this group will get this middleware
r.group("/admin", () => {
	r.get("",() => {
		//admin index
	});
	
	r.group("/user", () => {
		r.get("/:id",() => {
			//Get user
		});
		
		r.post("",() => {
			//Add user
		});
	});
}).add(() => {
	//e.g. authentication middleware to protected the endpoints /admin*
});


// router() will always returns the same instance with the same options (see Extendable)
let c = router();

c.get("/123",(req, res) => {
	res.write("hello 123");
});

//the dispatcher will match the requested path
//and returns a route object with all information's about the matched route and the paramter if the route where dynamic
//make sure dispatcher() will created AFTER the routes are collected (after all route collectors)
let d = dispatcher();

//sample server

var http = require('http');

const server = http.createServer(function (req, res) {
	//result contains the status (e.g. 200 or 404), the route id and the parameters
	// [status,route id,parameter]
	let result = d.dispatch(req.method,req.url);

	if(result[0] === 200) {
		//found
		let route = r.getRoute(result[1]);

		let callback = route.handler;	//handler is in the case a callback

		let middleware = route.getMiddleware();	//retuns all middleware to this route (group and route middleware) as an array

		callback(req,res, ...Object.values(result[2]));
	} else {
		//not found, 404
	}

	res.end();
});

const hostname = '127.0.0.1';
const port = 3000;

server.listen(port, hostname, () => {
	console.log(`Server running at http://${hostname}:${port}/`);
});

//es 5
var router = require("gram-route");

var r = router.router();	//router

var d = router.dispatcher();	//dispatcher

Extendable

The generator, dispatcher and collector can be changed.

import {router, dispatcher} from 'gram-route';

//options
//use functions to return an instance of a class. 
//Generator must implement GeneratorInterface and must be compatible with the dispatcher
//Dispatcher must implement the DispatcherInterface
//Collector must implement the RouteCollectorInterface
const options = {
	getGenerator: () => GeneratorInterface,
	getCollector: (generator) => RouteCollectorInterface,
	getDisPatcher: (collector) => DispatcherInterface
};

let r = router(options);	//now every instance of router() uses the new options

//e.g. the createRoute function in collector can be overridden
//if another route object is needed (e.g. to handle middleware different)
//so you don't need to rewrite the collector  

Credits