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

fof

v1.2.0

Published

functional transforms, accessors, and an ES5 fat arrow translator

Downloads

40

Readme

fof

Functional JavaScript transforms, and a handy fat arrow syntax translator for ES5! Some examples:

var fof = require('fof');

// simple property accessor
fof('x')({x: 100}) === 100
fof('foo bar')({'foo bar': 'baz'}) === 'baz'

// deep property accessor, courtesy of dotmap
fof('x.y')){x: {y: 'z'}}) === 'z'
// you can use spaces here; '.' is the separator
fof('foo bar.baz')({'foo bar': {baz: 'qux'}}) === 'qux'

// numeric index accessor
fof(1)([true, false]) === false

// fat arrow syntax
fof('d => d.x')({x: 42}) === 42
// if, for some reason, your data has funky keys...
fof("d => d['gobbledy\\'gook']")({"gobbledy'gook": 1}) === 1
// note the double curly braces for return an object!
['a', 'b', 'c'].map(fof('(d, i) => {{data: d, index: i}}'))
// produces: [
//   {data: 'a', index: 0}, 
//   {data: 'b', index: 1}, 
//   {data: 'c', index: 2}
// ]

// object maps
fof({x: 0, y: 1})([-122, 35]) // produces {x: -122, y: 35}
// values in object maps can be any value recognized by fof()
fof({x: {y: 'd => d.z'}})({z: 100}) // produces: {x: {y: 100}}

// array maps
fof(['y', 'd => d.x'])({x: -100, y: 50}) // produces: [50, -100]

API

The Node module fof exports a single function that returns a different type of accessor function for different types of inputs, given fof(x):

  • If x is a string and roughly matches the syntax of an ES6 fat arrow function, then you'll get the roughly equivalent ES5 function (minus the lexical scope, and a couple of other caveats). For example:
    • fof('d => d.x') returns an accessor for the x property of an object.
    • fof('d => [+d.x, +d.y]') returns a function that turns an object with x and y keys into a two-element array of coerced numbers.
    • Note: our "version" of fat arrow functions have an explicit return wrapped around the function body, so you can use comma-separated expressions like d => d.x *= 100, d to modify the object in place and return it. This is not possible in native implementations.
  • If x is a string (and not a fat arrow expression), you get a deep object accessor from dotmap.
  • If x is a number, you get a numeric index accessor.
  • If x is an object (and not an Array), you get a mapping function that returns a new Object the same set of keys and a corresponding value determined by fof(x[key]). This allows you to do things like:
    • fof({x: 0, y: 1}) returns a function that converts a 2-element Array into an Object with x and y keys corresponding to the first and second elements.
  • If x is an Array, you get a mapping function that returns a new Array with values corresponding to each index, for which fof(x[i]) is the value. This allows you to do the inverse of object mapping:
    • fof(['x', 'y']) returns a function that converts the x and y keys of an object into a 2-element array.

fof.stream(x, options)

The module's stream() method returns an object transform stream that can optionally filter objects by an expression and leave the input objects untouched, or filter and transform with independent expressions:

// transform using an expression
objectStream
  .pipe(fof.stream('d => [d.x, d.y]'))

// filter using an expression, leaving the data as-is
objectStream
  .pipe(fof.stream('d => d.x > 100', {
    filter: true
  }))

// filter and transform with expressions
objectStream
  .pipe(fof.stream('d => [d.x, d.y]', {
    filter: 'd => d.x > 100'
  }))

Check out the tests for more examples.