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

liquid-assets

v1.0.0

Published

A library for dealing with assets without requiring any build tools.

Downloads

3

Readme

Liquid Assets

A library for dealing with assets without requiring any build tools.

Overview

This library comprises of three things:

  1. A class to represent assets
  2. A class to generate URLs for assets (and find an asset given a URL)
  3. A function to serve assets over Node's http server

The following example shows all of these parts in use:

import { asset, AssetMap, assetRequestHandler } from 'liquid-assets';

// Reference an asset relative to this file (1)
const profilePic = asset('./profile.jpg', import.meta.url);

// Keep a bidirectional map of Asset objects and URLS (2)
const mapper = await AssetMap.register('http://example.com/assets/', [profilePic]);

// Create a function that serves the assets (3)
const serveAsset = assetRequestHandler(mapper);

export default async function requestHandler(req, res) {
    // Serve any registered assets
    if(await serveAsset(req, res)) {
        // An asset was found and served; exit the request handler
        return;
    }

    // No asset was found; serve the default route
    return `<html><body>
        <h1>Mr Example</h1>
        <p>Hello, my name is Mr. Example. Here's a picture of me:</p>
        <img src="${
            // Get the URL for the asset from the asset map
            await mapper.getUrl(profilePic);
        }">`

}

Usage patterns

I've tried to make this library simple enough to use in whatever configuration is needed:

Webpack-style

If you're used to doing import assetUrl from './asset.jpg';, you might find the following pattern useful:

First, set up your mapper in its own file:

import { AssetMap, Asset, assetRequestHandler } from 'liquid-assets';

export const mapper = new AssetMap('http://example.com/assets/');

// Make sure you use this in your server callback so the assets are actually served
export const serveAssets = assetRequestHandler(mapper);

export default (...args) => mapper.getUrl(new Asset(...args));

Then, whenever you need to reference an asset in another file, import the asset mapper and use it to generate a URL:

import urlFor from './asset-mapper.js';

const virus = await urlFor('./virus.exe', import.meta.url);

export default `<a href="${virus}">Click here</a> for a picture of a cute panda!`;

Template-first

If you want to be able to specify assets in your templates without having to have a mapper set up first, that's possible too using a library like encode-html-template-tag that can replace assets at render time:

import { asset } from 'liquid-assets';
import html from 'encode-html-template-tag';

export const vom = asset('./vom.ogg', import.meta.url);

export default html`
This is what my cat sounds like when she's about to throw up:
<audio src="${vom}"></audio>`;

Then, in your server code, you can replace the asset with its URL at render time:

import html from 'encode-html-template-tag';
import { AssetMap, assetRequestHandler, Asset } from 'liquid-assets';
import vomTemplate, { vom } from './cat-vomit.js';

const notFound = html`That page was not found`;

export default async function(origin = 'http://example.com') {
    const assets = await AssetMap.register(`${origin}/assets/`, [vom]);
    const assetServer = assetRequestHandler(assets);

    return async function(req, res) {
        if(await assetServer(req, res)) {
            return;
        }

        // Imagine this is your router function
        const template = req.url === '/' ? vomTemplate : notFound;

        // Render the output and replace Assets with their URLs
        const output = await template.render(value => {
            if(value instanceof Asset) {
                // Get the asset URL
                const url = await assets.getUrl(value);

                // We can also make the URL relative if we want
                return url.toString().replace(origin, '');
            }

            return value;
        });
    }
}

Dependencies

  • mime-types: ^2.1.33

Modules

Classes

Functions

Typedefs

liquid-assets

Liquid Assets

liquid-assets.Asset

A generic representation of an asset

Kind: static class of liquid-assets

new exports.Asset(options)

Create a new asset

| Param | Type | Description | | --- | --- | --- | | options | Object | Options | | options.type | string | The mime-type of the asset | | options.toStream | function | A function that returns an async iterable yeilding the asset's contents | | options.toString | function | A function that returns the asset represented as a data url | | options.name | string | An optional filename for the asset | | options.size | number | The asset size in bytes |

asset.size ⇒ number

Get the asset's file size in bytes

Kind: instance property of Asset

asset.type ⇒ string

Get the asset's mime type

Kind: instance property of Asset

asset.name ⇒ string

Kind: instance property of Asset
Returns: string - The filename of the asset

asset.ext ⇒ string

Kind: instance property of Asset
Returns: string - The extname of the asset

asset.Symbol.asyncIterator()

Generator that yields the asset's contents

Kind: instance method of Asset

asset.toString() ⇒ string

Kind: instance method of Asset
Returns: string - Data URL of the asset

liquid-assets.FileAsset

An asset on the filesystem

Kind: static class of liquid-assets

new exports.FileAsset(file, baseUrl)

Create a new FileAsset

| Param | Type | Description | | --- | --- | --- | | file | string | Absolute or relative path of the file | | baseUrl | string | The base file:// URL to calculate relative path from |

liquid-assets.InlineAsset

An asset declared in code, stored in application memory

Kind: static class of liquid-assets

new exports.InlineAsset(blob, type, name)

Create a new InlineAsset

| Param | Type | Description | | --- | --- | --- | | blob | Buffer | string | The contents of the asset | | type | string | The mimetype of the asset | | name | string | Optional filename for the asset |

liquid-assets.asset ⇒ FileAsset

Create a new FileAsset

Kind: static constant of liquid-assets

| Param | Type | Description | | --- | --- | --- | | file | string | Absolute or relative path of the file | | baseUrl | string | The base file:// URL to calculate relative path from |

liquid-assets

Liquid Assets

liquid-assets.Asset

A generic representation of an asset

Kind: static class of liquid-assets

new exports.Asset(options)

Create a new asset

| Param | Type | Description | | --- | --- | --- | | options | Object | Options | | options.type | string | The mime-type of the asset | | options.toStream | function | A function that returns an async iterable yeilding the asset's contents | | options.toString | function | A function that returns the asset represented as a data url | | options.name | string | An optional filename for the asset | | options.size | number | The asset size in bytes |

asset.size ⇒ number

Get the asset's file size in bytes

Kind: instance property of Asset

asset.type ⇒ string

Get the asset's mime type

Kind: instance property of Asset

asset.name ⇒ string

Kind: instance property of Asset
Returns: string - The filename of the asset

asset.ext ⇒ string

Kind: instance property of Asset
Returns: string - The extname of the asset

asset.Symbol.asyncIterator()

Generator that yields the asset's contents

Kind: instance method of Asset

asset.toString() ⇒ string

Kind: instance method of Asset
Returns: string - Data URL of the asset

liquid-assets.FileAsset

An asset on the filesystem

Kind: static class of liquid-assets

new exports.FileAsset(file, baseUrl)

Create a new FileAsset

| Param | Type | Description | | --- | --- | --- | | file | string | Absolute or relative path of the file | | baseUrl | string | The base file:// URL to calculate relative path from |

liquid-assets.InlineAsset

An asset declared in code, stored in application memory

Kind: static class of liquid-assets

new exports.InlineAsset(blob, type, name)

Create a new InlineAsset

| Param | Type | Description | | --- | --- | --- | | blob | Buffer | string | The contents of the asset | | type | string | The mimetype of the asset | | name | string | Optional filename for the asset |

liquid-assets.asset ⇒ FileAsset

Create a new FileAsset

Kind: static constant of liquid-assets

| Param | Type | Description | | --- | --- | --- | | file | string | Absolute or relative path of the file | | baseUrl | string | The base file:// URL to calculate relative path from |

assetRequestHandler(assetMapper) ⇒ function

Create a request handler for serving assets. Note that the request handler expects asset URLs to be content-addressed, and therefore sets the cache-control header to immutable. If you don't want this behaviour, don't use this function.

Kind: global function
Returns: function - Request handling function

| Param | Type | Description | | --- | --- | --- | | assetMapper | AssetMapper | The asset mapper containing the assets to serve |

AssetMapOptions : object

Options for constructing the AssetMap

Kind: global typedef
Properties

| Name | Type | Description | | --- | --- | --- | | options.algorithm | string | The algorithm to use when generating the filename hash; default sha1 | | options.length | number | How many characters in length the hash part of the URL should be; default 7 | | options.minSize | number | The minimum size the asset needs to be for an http URL to be generated. Anything below this size will be converted as a data: URL |

RequestHandler ⇒ Boolean

Asset request handler

Kind: global typedef
Returns: Boolean - True if an asset was sent, false if no matching asset was found

| Param | Type | Description | | --- | --- | --- | | req | IncomingMessage | The Node incoming request object | | res | OutgoingResponse | The Node HTTP response object |