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

tag-params

v1.0.6

Published

Transform a generic string into parameters suitable for template literals functions tags

Downloads

1,944

Readme

tag-params

Build Status Coverage Status

Transform a generic string into parameters suitable for template literals functions tags.

import {params} from 'tag-params';
// const {params} = require('tag-params');
// <script src="//unpkg.com/tag-params"></script>

console.log(
  params('Random: ${Math.random()}!')
);
// [["Random: ", "!"], 0.3456787643]

console.log(
  params('Hello ${user}', {user: 'test'})
);
// [["Hello ", ""], "test"]

// invoke tags through the returned parameters
genericTag(...params(content, namespace));

API

There are 3 utilities exported by this module, so that accordingly with your import, you should get:

  • params, the main utility, which parses and resolves values in one go.
  • parse, which returns a {template, values} object, with mapped "chunks" in the template, and the list of values (interpolations/holes), where each value is a string.
  • partial, which uses parse and returns a callback that will map new values through the optional object passed along.

params(content:string, object?:any) => [string[], ...any[]]

It's the "default" use case of this utility. It parses the content and returns a [template, ...values] Array with values retrieved through the optional object. If no object is passed along, it simply evaluates interpolations as plain JavaScript.

This utility is a shortcut for a one-off partial(content)(object) call.

parse(content:string, transform?:function) => {template:string[], values:string[]}

It parses a string, and it uses the optional transform callback, which is no-op as default, to assign each value to the list of expected values.

The transform optional callback is specially useful when the interpolated content might contains HTML normalized chars, such as value =&gt; stuff(value) instead of value => stuff(value), which is normal when the content is retrieved via element.innerHTML, as example.

The template property contains all chunks around ${...} interpolations, while values contains all interpolations content as string.

partial(content:string, transform?:function) => (object?) => [string[], ...any[]]

This utility parses the content through an optional transform, and returns a callback that accepts a new object each time.

This is particularly useful to avoid parsing the same template content over and over, and just update its interpolation values through the optional object.

import {partial} from 'tag-params';
const update = partial('Hello ${user}!');

console.log(update({user: 'First'}));
// [["Hello ", "!"], "First"]

console.log(update({user: 'Second'}));
// [["Hello ", "!"], "Second"]

// always true
console.assert(
  update({user: 'First'})[0] ===
  update({user: 'Second'})[0]
);

The main advantage of this utility is that it parses the content and it creates the template Array only once, meaning every template literal based library could benefit from it, using the uniqueness of the template to parse complex chunks of HTML, or anything else, once, enabling repeated updates at almost zero performance cost (well, values are still evaluated).

Use Cases

The most common/requested use case for this is likely landing templates on the page and use their content, as shown in this CodePen example:

<template id="list">
  <ul>${items.map(function (item) {
    return html`<li>${item.text}</li>`;
  })}</ul>
</template>
<div id="app"></div>

<script type="module">
import {params} from '//unpkg.com/tag-params?module';
import {render, html} from '//unpkg.com/uhtml?module';

render(
  document.getElementById('app'),
  html(...params(
    document.getElementById('list').innerHTML,
    {
      html,
      items: [{text: 'first'}, {text: 'second'}]
    }
  ))
);
</script>

This works well with libraries such as uhtml, lighterhtml, or hyperHTML, as well as any library based on template literals tags.

However, this module can work with literally any possible template literal tag function, as these all share the same signature, hence will accept transformed chunks, as template, and the rest of the interpolations as values.

Caveats

Please note this module inevitably needs/uses Function to evaluate the code within a with statement, as there's no other way to evaluated interpolations through passed data.

Moreover, the current interpolations parser is extremely rudimental, it simply skips extra { and } chars within the value, but it doesn't parse all possible JS syntax.

This means that if an interpolation contains a string such as ${"breaking { char"} or ${"breaking } char"} the result will break.

The good practice here is to pass strings via the object, instead of hard coding these within interpolations, as this won't likely get fixed any time soon (if ever).

Compatibility

Every JavaScript engine, either client, server, or IoT, that supports string[index] access, as I couldn't bother myself adding a slow and jurassic string.charAt(index) in the code.