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 🙏

© 2026 – Pkg Stats / Ryan Hefner

lhd

v0.7.0

Published

(Another) Light HTTP(s) Dispatcher

Downloads

60

Readme

LHD

(Another) Light HTTP(s) Dispatcher

LHD is a light http(s) dispatcher based on HttpDispatcher

LHD allows developer to have a clear dispatcher for dynamic pages and static resources. Classes http.ServerRequest and http.ServerResponse earns new params property containing a map of received HTTP parameters.

Prerequisites

nodejs and npm

Installing

Installing is very easy. Enter into the root directory of your project and npm

cd root_directory_where_is_located_your_file_package.json
npm install --save lhd

Usage

HTTP(S) Client

    const lhd = require('lhd');
    const dis = new lhd(); // No arguments needed
    
    const options = {
      protocol: 'https:',
      host: 'www.servizi.toscana.it',
      port: 443,
      path: '/index.html',
      method: 'POST',
      headers: {
        Content-Type: 'application/json'
      },
      rejectUnauthorized: true
    };
    
    var data = 'Some data to send ...';
    dis.request(options,data,callBack); // data is optional

where:

options.protocol defines the protocol to be used, ie. http: or https:

options is defined in nodejs http(s) class.

HTTP(S) Server

    const lhd         = require('lhd');
    let cfg = {
      'name': 'MyWebApplication',
      'version': '1.0.0',
      'environment': 'Develope',
      'server': {
        'protocol': 'http:',
        'tcp': {
          'host': '0.0.0.0',
          'port': 9091
        },
        'options': {
        }
      },
      'dispatcherConfig': {
        'maxlen': {
          'application/json': 100e3,
          'default': 0
        }
      }
    };
    const dis = new lhd(cfg);

    // some listeners as example (API)
    // :type means a value that is a parameter with name 'type'
    dis.beforeFilter(jwt, knownUser);
    dis.onGet('/config/:type', isAdmin, .... , okresponse);
    dis.onPost('/config/:type', isAdmin, .... , okresponse);
    dis.onPut('/config/:type', isAdmin, .... , okresponse);
    dis.onDelete('/config/:type', isAdmin, .... , okresponse);

    // Static files are checked if no API is referenced
    // First parameter i the url path the second is the local folder where files are located
    dis.setStatic('/','static');

    // start the server
    dis.start(cfg);
    
    function isAdmin(req,res) {
      if ( ! cfg.managers[req.user.sub] ) {
        req.err = {
          n: 403,
          text: 'Forbidden: Insufficient privileges'
        }
        req.cfg.dispatcher.errorListener(req,res);
      }
      req.chain.next(req,res);
    }
    
    function knownUser(req,res) {
      if ( typeof req.user.sub === 'undefined' ) {
        req.err = {
          n: 401,
          text: 'Unauthorized'
        }
        req.cfg.dispatcher.errorListener(req,res);
      }
      req.chain.next(req,res);
    }
    
    function readBody(req,res) {
      req.cfg.dispatcher.getBody(req,res)
    }
    
    function okresponse(stat,docs,req,res){
      const status = 200;
      const rsp = 'The response data, string, json, ...';
      req.cfg.dispatcher.response(status,rsp,req,res);
    }

The methods onGet, onPost, .., in the above example are used to register listeners. When a request is received the methods are chained and executed in sequence. Small methods are better verified and tested. Usually a sequence like the following may be a good choice

  • Authenticate
  • Autorize
  • Check input data
  • Do the job
  • Filter the response

In the example above cfg is the server configuration, where:

  • server.protocol defines the protocol to be used, ie. http: or https:. In the case o https the server.options MUST contain the server key and certificate according to https.createServer
  • server.tcp are ip and port
  • server.dispatcherConfig defines the max file length by file content type that the server can receive (in POST or PUT for example). Types not mentioned are treated as default. In the example above json have to be smaller than 100KBytes, any othes file is rejected. the content type of the file is determined first by the magic bytes, last by content type.

request and response

Every listeners is called with two parameters request and response.

Request object is an instance of http.ClientRequest with some custom properties:

The request object extesions are the following:

  • req.user: Object
    • content depends on authentication type (Authorization header)
      • contains JWT token i present in Autorization (bearer) header (JWT, OpenID, ...)
      • contains {'sub': username} in Autorization (basic) header (User/password)
      • contains {'sub': 'Anonimous'} in other cases
  • req.params: Object
    • The properties of this object are those extracted from the request url. In the above example (see :type in the above example)
  • req.bodyBuffer : Buffer
    • Present in POST, PUT, ...
  • req.body : String Content of input data (if possbile string representation o body buffer)
  • req.bodyData: Object Content of input data when form encoded

Response object is an instance of http.ServerResponse.

The response object extesions are the following:

  • res.err: Object
    • Contains the error description which interrupts the execution of chained methods and causes the error response

Author

LHD is based on HttpDispatcher

License

This project is licensed under the MIT License - see the LICENSE file for details