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

matchanator

v1.0.4

Published

better than switch statments

Downloads

7

Readme

Matchanator

Multiple function heads with pattern matching

Why

Pattern matching is a powerful artefact of (typically) functional programming languages. While we have some of these items in JavaScript, we don't have the ability to express exact value matches within function definitions.

While this is a language level construct in other languages, we can still achieve this in JavaScript through functions. Matchanator is just that, a higher order function that takes parameter and function definitions and only runs one matching result. If a result is not found, a warning issued.

Usage

Examples

Simplify State Transitions

import match, { string, number } from 'matchanator'

const transition = match(
  [{ user: { name: string, id: number }, authenticated: true }, (state) => redirectToProfile(state)]
  [{ user: { authenticated: false } }, (state) => redirectToLoginPage(state)]
)

Reduce if Branching

From

import match, { not, nil, any, emptyArray, array } from 'matchanator'

const pgCallbackWrapper = (f) => match(
  [not(nil), any, (error, _) => console.error(error)], // when there is an error
  [nil, { rows: not(emptyArray) }, (_, empty) => console.log('no results')], // no error, but no results either
  [nil, { rows: array }, (_ results) => f(results.rows)] // no error, but results this time
)

const database = (query, data, callback) => pg.client(query, data, pgCallbackWrapper(callback))

database(
  'select * from users where name = $1::string',
  ['Adam'],
  (results) => results.each(name => console.log(name))
)

Match

(...matchers) => (...params) => any

The main interface for matchanator. It takes matcher definitions and returns a function that will match against these definitions and run the corresponding function body.

Matcher Definitions

[...any, func(...any) => any]

A matcher definition is an array with N elements. All elements can be a mixture of any javascript primitive. The last element must be a function. This function will be called with the provided arguments if there are a successful match.

// valid matcher definitions
[1, (one) => 1]
[1, 2, 3 (one, two ,three) => 'onetwothree']

Exact Matches

Anything that is not an object is matched exactly, using ===.

import match from 'matchanator'

const hello = match(
  ['Dave', () => 'Hello, Dave'],
  ['Sally', () => 'Hello, Sally']
)

hello('Dave') // 'Hello, Dave'

Partial Matches

In the above example, we use strings to match against a provided name. Anything that is not an object requires an exact match. Objects, however, are partially matched.

import match from 'matchanator'

const street = match(
  [{ address: { street: { name: 'Foo' } } }, () => 'your street is Foo']
)

street({ address: { street: { name: 'Foo' } } }) // your street is Foo

// also fine
street({ address: { street: { name: 'Foo' , number: 123 } } })// your street is Foo

Typed parameter matches

Matchanator comes with basic type checkers as to do generic matching on provided parameters. These type checkers cover the basic primitives available in javascript.

Matchers are processed in the order in which they are provided. It is best to organise your matches from most specific to least specific.

Matchanator exports the following type checkers

  • object
  • func
  • string
  • number
  • array
  • emptyArray
  • any
import match, {
  object,
  func,
  string,
  number,
  array,
  emptyArray,
  any
} from 'matchanator'

const head = match(
  [array, ([h, ..._]) => h],
  [emptyArray, (empty) => empty]
)

head([1, 2]) // 1
head([]) // []
Type checkers

The provided type checkers are simple functions that take the suggested item and perform a typeof check on the item.

Custom Type Checkers

(T) => boolean

The provided type checkers are functions. You can provide your own type checkers by implementing the (T) => boolean signature.

For example, if you wanted to check for NaN then the following function could be used

import match from 'matchanator'

const nan = (n) => isNaN(n)
const notNan = (n) => !nan(n)

const square = match(
  [nan, (nan) => nan],
  [notNan, (x) => x * x]
)

Not finding a match

When a match is not found a console.warn is issued with the originaly provided matchers, the provided parameters. An example is below.

const square = match(
  [number, (x) => x * x]
)

square('1')
// Given the matches of: function () {
//          return typeof n === 'number'
//        }, (x) => x * x,
// Given the provided params: [
//  {}
// ],
// A match was not found

Roadmap

  • [ ] Break type checking functions out into their own repository
  • [ ] Allow type checking functions from within arrays
  • [ ] Improve 'no match found' warning