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

@m4rsh/cones

v1.2.1

Published

tools to roll js

Readme

@m4rsh/cones

tools to roll js

NPM Version npm bundle size


using tagged templates to generate files with ease

  • jstag: template string with indents & object strings & automatic imports
  • fmt: template string with indents & object strings
  • ranges: find matching ranges with regex
  • changes: apply edited ranges
  • objstr: print javascript objects (like JSON but less verbose)
  • jsonstr: object to JSON with better spacing

Examples

Automatic barrel files

ID Compressor

Generate Markdown

Custom naming scheme for jstag

Annotating Log Statements


API

jstag

function to create a custom js tagged template function to compose javascript code with automatic imports

import { jstag, Ref } from '@m4rsh/cones'

const js = jstag()

let code = js`
    let x = ${ Ref("@ui/Button", ['styles']) };
    let y = ${ Ref("@ui/Button", ['render']) };

    ${js`
        let fn = () => ${ Ref("@ui/Button", ["handlers"]) };
    `}
`

Output

import { styles as $__0, render as $__1, handlers as $__2 } from "@ui/Button"

let x = $__0;
let y = $__1;

let fn = () => $__2;

Ref objects are basically pointers to an imported resource - defined by path + exports. They are converted to strings at the very end, once all Refs in the template are known. This allows for generating optimized import statements when the template is stringified.

Imports are generated with the following heuristics:

  • References to the same path + export will reuse the same identifier
  • Importing * alongside named exports will generate 2 different imports to allow for tree-shaking
  • Not specifying an export will default to the 'default' export
  • Refs within nested jstag templates will automatically merge with the 'root' template that gets stringifed.
  • Paths are treated as raw strings, not resolved or changed

fmt

import { fmt } from '@m4rsh/cones'

let code = fmt`
    <h1>left-aligned</h1>
    <div>
        ${fmt`
            <h2>preserved indent</h2>
        `}
    </div>
`

Output

<h1>left-aligned</h1>
<div>
    <h2>preserved indent</h2>
<div>

(without fmt)


    <h1>left-aligned</h1>
    <div>
        
            <h2>preserved indent</h2>

    </div>
  • When parsing a template string, if a Hole is on a line that's preceded by tabs or spaces, save that as 'padding'
  • If the value for that Hole contains newlines, insert that 'padding' at the beginning of every newline (after the first)
  • Trim the empty lines before the first non-whitespace character
  • On the first line with content, count the number of tabs/spaces on that line
  • For every subsequent line, remove up to that much whitespace on subsequent lines

If everything goes smoothly:

  • Indenting templates with a newline at top/bottom are nicely trimmed away for the output
  • Inserting values within a template preserve the indentation of the opening ${
  • Nested indentation is consistent

ranges

Find selections within a source text that match the regex pattern. Returns ideal format for running changes

(For serious file manipulation, I recommend using tree-sitter instead of this regex method)

changes

Apply changes (in reverse order to preserve correctness) to source text at given range indices, returning the new string.

import { fmt, ranges, changes } from '@m4rsh/cones'
let src = fmt`
    /*<context>*/
    function a(){}
    function b(){}
    /*</context>*/

    function c(){}

    /*<context>*/
    function d(){}
    /*</context>*/
`

let zones = ranges(src,/^\/\*<\/?context>\*\/$/gm)

console.log(zones)
// [ 0, 13, "/*<context>*/" ],
// [ 44, 58, "/*</context>*/" ],
// [ 76, 89, "/*<context>*/" ],
// [ 105, 119, "/*</context>*/" ]

let group_i = 1
let modified = changes(src, zones.map(([b,e,str]) => {
  if(str.includes("</")){
    return [b,e,"// --- CLOSE " + (group_i++)]
  }
  return [b,e,"// --- OPEN " + (group_i)]
}))

console.log(modified == fmt`
  // --- OPEN 1
  function a(){}
  function b(){}
  // --- CLOSE 1
  
  function c(){}

  // --- OPEN 2
  function d(){}
  // --- CLOSE 2
`) // true

objstr

Pulled from stringify-object

import { objstr } from '@m4rsh/cones'

let obj = {
    x: 30,
    y: "test",
    z: {
        "int-er/es*ting": [9.2291]
    }
}

let str = objstr(obj, {
    indent:'  ', // two spaces is default
    singleQuotes:false, // ' vs "
    inlineCharacterLimit:80, // line wrap limit
    pad:'', // used internally to preserve indents
    valueTransform: (v)=>v, // undefined by default
})

console.log(str)
// {x: 30, y: "test", z: {"int-er/es*ting": [9.2291]}} 

jsonstr

Pulled from json-stringify-pretty-compact

import { jsonstr } from '@m4rsh/cones'

let list = [
    { id: 1, $: ["home", "about"] },
    { id: 2, $: ["faq", "contact"] },
    { id: 3, $: ["test", "app"] },
]

let str = jsonstr(obj, {
    indent:'  ', // two spaces is default
    inlineCharacterLimit:80, // line wrap limit
    pad:'', // used internally to preserve indents
})

console.log(str)

Output

[                                     
  {"id": 1, "$": ["home", "about"]},  
  {"id": 2, "$": ["faq", "contact"]}, 
  {"id": 3, "$": ["test", "app"]}     
]                                     

With JSON.stringify()

[
 {
  "id": 1,
  "$": [
   "home",
   "about"
  ]
 },
 {
  "id": 2,
  "$": [
   "faq",
   "contact"
  ]
 },
 {
  "id": 3,
  "$": [
   "test",
   "app"
  ]
 }
]

References