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

@major-tanya/itty-compression

v0.2.0

Published

A compression middleware for use with itty-router

Downloads

191

Readme

itty-compression

Coverage Status Lint Status Test Status GitHub issues Package version

A work-in-progress, proof-of-concept compression middleware to provide Response Compression for use in itty-router projects.

Probably compatible with a variety of other routers.

Not recommended for production use.

Features

Your choice of algorithm

itty-compression includes:

| Middleware | Algorithm(s) | |-------------------------|----------------------------| | brotliCompression | brotli (br) only | | deflateCompression | deflate only | | gzipCompression | gzip only | | negotiatedCompression | brotli (br), gzip, deflate |

What is negotiatedCompression?

negotiatedCompression compares the client's Accept-Encoding header against the list of supported encodings (see table) and uses the first algorithm both the client and itty-compression can agree on. The priority is as follows:

  1. brotli (br)
  2. gzip
  3. deflate
  4. no compression

If the client doesn't accept any supported algorithm, the middleware will add the Vary header with the value Accept-Encoding (or append the value if the header already exists) to inform the client of this capability.

As with the other middlewares, the original request object is needed to read the client's Accept-Encoding header. If the request is not provided, the Accept-Encoding header isn't set, or no mutually supported algorithm could be determined, this middleware will function as a no-op instead, returning the input with only the Vary: Accept-Encoding header added.

No duplicate compression of Responses.

itty-compression won't attempt to compress already compressed Responses again, be it from other routing steps/middleware or from accidentally duplicating it in the route handling.

Rather small middlewares

While not in the same ballpark as itty-router itself, the middlewares are kept as small as possible, with further optimisations always on the table.

Current sizes are:

| middleware | size | |-------------------------|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| | brotliCompression | brotliCompression | | deflateCompression | deflateCompression | | gzipCompression | gzipCompression | | negotiatedCompression | negotiatedCompression |

Typed

itty-compression is entirely written in TypeScript, so it comes with types automatically.

Currently supported compression algorithms:

  • brotli (br)
  • gzip
  • deflate

Vary Header setting

itty-compression will always set the Vary header to include Accept-Encoding, even if the response was not compressed.

How to use

itty-compression directly depends on Node's zlib via importing node:zlib.

Install with npm install @major-tanya/itty-compression (or your favoured alternative to npm).

Once installed, pick your compression algorithm, or use the flexible negotiatedCompression middleware (Your Choice of Algorithm).

itty-router v5 with AutoRouter or Router

The freshly released v5 of itty-router includes some more batteries-included routers that allow for some more concise syntax when using itty-compression. Example based on the v5 AutoRouter documentation.

Example: negotiatedCompression (replace with your middleware of choice)

import { negotiatedCompression } from 'itty-compression';
import { AutoRouter } from 'itty-router';

const router = AutoRouter({ // using batteries-included AutoRouter
  finally: [negotiatedCompression],
});
// const router = Router({ // using the medium Router
//  // do not forget to add the json handler for the medium Router before the compression middleware
//  finally: [json, negotiatedCompression],
// });

// AutoRouter's integrated json formatter handles this automatically
router.get('/dogs/toto', (request) => ({
  name: 'Toto',
  breed: 'Cairn Terrier',
  color: 'black',
}));

export default router;

itty-router v5 with IttyRouter (also itty-router v4)

Example: negotiatedCompression (replace with your middleware of choice)

import { negotiatedCompression } from 'itty-compression';
import { error, IttyRouter, json } from 'itty-router';

// const router = Router(); // only itty-router v4
const router = IttyRouter(); // only itty-router v5

// downstream json middleware handles stringifying
router.get('/dogs/toto', (request) => ({
  name: 'Toto',
  breed: 'Cairn Terrier',
  color: 'black',
}));

export default {
  fetch: (request, ...args) => router
    // .handle(...args) // only itty-router v4
    .fetch(...args) // only itty-router v5
    .then(json) // <-- do not forget an appropriate handler here or you may encounter problems with itty-compression
    .then((response) => negotiatedCompression(response, request)) // <-- add the compression handler downstream
    .catch(error),
};

Note: It's important to add the original request in order for itty-compression to be able to respect the client's Accept-Encoding header. If the request (or the header) is not provided, the compression middleware will function as a no-op, returning the input with only the Vary header added.

Compatibility & Testing

Known compatible with

Theoretically compatible with any framework/library/router that allows for access to the client request and the in-progress response before it is sent to the client and also supports async middleware.

Goals

  • Provide compression for itty-router similar to the middleware provided by compression for Express

TODO

  • [ ] More library/framework compatibility data?
  • [ ] Code golfing
  • [ ] More robust approach to suboptimal inputs

Thanks

  • kwhitley for the creation of the ittiest router I've ever seen.