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

@ashnazg/literalizer

v0.0.1

Published

creates literals for code-gen of JS use cases

Downloads

3

Readme


title: "@ashnazg/literalizer" sidebar_label: "literalizer"

Much like the carpal-tunnel silly oneliners in utils, this liblet was born because I like the literal notation in javascript more than the simpler rules of JSON.

There's plenty of relaxed JSON parsers, but no serializers to those variants that I could find, and I want this for code-generation and config-writing templating tools.

(In other words, I want to dynamically create plain-old-javascript things and then export them as a config file like ".eslintrc.js" in the same style that would result if I did it by hand.)

Usage

At it's core, it's just an equivalent to JSON.stringify($, null, '\t') that avoids quoting keys:

var literalizer = require('@ashnazg/literalizer'); // ~/projects/ashnazg-npm/literalizer/literalizer.js

var map = {foo: 'bar'};
console.log(literalizer(map)); // => {foo: "bar"}

It doesn't (yet) take a replacer, but it does take an optional 2nd param that's a config:

var example_predefined_js_variable = ...;
var map = {foo: 'bar'};
literalizer(map, {
	name: 'variable_name_in_output',
	exports: !!caller_wants_a_node_module_file,
	fold_width: 80, // simple non-scalars who's final line is shorter than this are compacted
	local_scope: {example_predefined_js_variable} // the final output will NOT express the values of any variable mentioned here.
});

Compacting some fields based on final width

The compactor will pretty-print a map or list in one-line form if and only if:

  1. fold_width is set
  2. The final line is shorter than fold_width (including unpacked tabs at 4-space, key names, and the comma at the end.)
  3. no child element is a non-empty map or list
var literalizer = require('./literalizer.js');
var this_folds = {
	smartcode: false,
	'much foldy': 'so much fold.',
};
var this_does_not = {
	smartcode: false,
	'much foldy': 'too much to fold.',
	ribbit: 'ribbit ribbit ribbit.', // because this line pushes it above the width limit given below
};

var these_are_all_fine = ['but this is fine', 42, [], {}, null, undefined];

var but_this_array_has_a_nontrivial_child = [{f:1}];

console.log(literalizer({
	this_folds,
	this_does_not,
	these_are_all_fine,
	but_this_array_has_a_nontrivial_child
}, {
	fold_width: 80
}));

results

{
	this_folds: {smartcode: false, "much foldy": "so much fold."},
	this_does_not: {
		smartcode: false,
		"much foldy": "too much to fold.",
		ribbit: "ribbit ribbit ribbit."
	},
	these_are_all_fine: ["but this is fine", 42, [], {}, null, undefined],
	but_this_array_has_a_nontrivial_child: [
		{f: 1}
	]
}

instant module pattern

There's some trivial syntactic sugar to wrap the final output in one of a few common file patterns:

var literalizer = require('./literalizer.js');
function genConf() {
	return {
		prop1: 'val1',
		subsettings: {
			thing:'1'
		}
	};
}
console.log(literalizer(genConf(), {exports: true}));

results

module.exports = {
	prop1: "val1",
	subsettings: {
		thing: "1"
	}
};

named module level vars

console.log(literalizer(genConf(), {name: 'new_conf'}));

results

var new_conf = {
	prop1: "val1",
	subsettings: {
		thing: "1"
	}
};

named exports

console.log(literalizer(genConf(), {name: 'subconfig', exports: true}));

results

exports.subconfig = {
	prop1: "val1",
	subsettings: {
		thing: "1"
	}
};

depend on existing local scope vars

If you're already writing js vars in the file's preamble before the part generated using this library, you can have the output re-use those instead of blindly serializing the value redundantly:

var existing_map = {foo:'bar'};
function existingFunc() {};

console.log(`
var existing_map = {foo:'bar'};
function existingFunc() {};
`);

console.log(literalizer({
	top: 'level prop',
	works_in_maps: {
		mixed: 'data',
		existingFunc,
		existing_map
	},
	works_in_lists: [
		"because we look up these by value, we can tell when to just use the var name in list mode",
		existingFunc,
		existing_map
	]
}, {
	name: 'external',
	exports: true,
	local_scope: { existing_map, existingFunc }
}));

results

var existing_map = {foo:'bar'};
function existingFunc() {};

exports.external = {
	top: "level prop",
	works_in_maps: {
		mixed: "data",
		existingFunc,
		existing_map
	},
	works_in_lists: [
		"because we look up these by value, we can tell when to just use the var name in list mode",
		existingFunc,
		existing_map
	]
};

TODO

  1. support renaming in local_scope.
    this_doesnt_work: {
    	newname: existingFunc
    },
  2. regexs
  3. generators
  4. inline fat arrows

Release 0.0.1

Happy with it for the plain old json-like work I'm on right now; annoyed at how much work it takes to reflect details about a JS-function like "are you a fat arrow?" that you'd need to isomorphically print the source code in all contexts.

(Since I don't need function literals in my current projects, I'm stopping here, as playing with functions has consumed 90% of the time put in so far for imperfect results.)