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

tryad

v1.0.0

Published

Monadic mashup of Maybe & Either that represents a value, nothing, or an error.

Downloads

3

Readme

tryad · Version License Travis CI JavaScript Standard Style

Monadic mashup of Maybe & Either that represents a value, nothing, or an error.

There are a few major reasons for tryad to exist:

  • most existing Maybe / Option / Either / Result types in JavaScript don't seamlessly interop with Promises
  • if the Maybe contains an array, you have to map inside a map because it doesn't dispatch
  • toMaybe and toEither become unnecessary if the type simply has a third branch to cover exceptions

So tryad attempts to create a new type that incorporates all of this - replacing both null-ish checks and try/catch while working well with Promises.

installation

npm i tryad

usage

import tryad from 'tryad'
import { resolve } from 'path'

const loadPlugin = atPath => {
  return require(atPath).initialize()
}

const plugin = { name: 'a-plugin' /*, path: './plugin.js' */ }
const loaded = tryad(plugin.path)
  .map(path => resolve(process.cwd(), path))
  .try(absolute => loadPlugin(absolute))
  .unwrap(
    // `loaded` becomes equal to the return value of
    // whichever branch we hit here in `unwrap`
    Some => 'loaded the plugin'
    None => 'plugin.path was not defined, so nothing was executed'
    Fail => 'a wild error appeared! ' + Fail.message
  )

// in this case `path` is not defined, so we get a `None`:
// -> 'plugin.path was not defined, so nothing was executed'

Or if you're all about that async, let's check out Promises!

import tryad from 'tryad'
import { readJson } from 'fs-extra'

;(async () => {
  const result = await tryad('./package.json')
    // returning a Promise here like `readJson` does
    // makes the chain's result become asynchronous
    .try(path => readJson(path))
    .map(pkg => pkg.keywords)
    // methods dispatch to the inner value, so this
    // maps over each keyword in the array
    .map(key => key.toLowerCase())
    .filter(key => key === 'maybe')
    .unwrap(
      Some => 'found the maybe keyword',
      None => 'did not find the maybe keyword',
      Fail => 'an error occurred! ' + Fail.message
    )

  /*...*/
})()

And remember that if at any point a transformation causes a nil / falsy value to be returned or if .try() throws an Error, the following transformations will not be executed. This makes null handling very easy - in this case the chain would 'skip forward' to the unwrap call.

api

tryad

tryad(value)

Returns a new object that is either a None if value == null or a Some containing value otherwise.

Expand the following sections to see the full documentation.

of

tryad.of(value)

Alternate constructor that checks for truthiness rather than loose equality to null.

try

tryad.try(value, fn)

Shortcut for tryad.of(value).try(fn). If value != null it will be applied to the function fn, and any errors will be caught to transform the tryad into a Fail. fn is only executed on a Some.

Arguments

  • value: any

  • fn: value -> any

    Function that will receive value as its only parameter. All errors are caught and returned in a new Fail object.

Returns Some | None | Fail

async

tryad.async(value)

Asynchronous version of the tryad constructor that accepts value as a Promise, or wraps it in one if it isn't already a Promise.

async.of

tryad.async.of(value)

Asynchronous version of the tryad.of constructor that accepts value as a Promise, or wraps it in one if it isn't already a Promise.

isSomeLike

tryad.isSomeLike(value)

Useful for checking if an arbitrary object is a Some, meaning it is not == null and has an isSome method that returns true.

Arguments

  • value: any

Returns Boolean

isNoneLike

tryad.isNoneLike(value)

Useful for checking if an arbitrary object is a None, meaning it is not == null and has an isNone method that returns true.

Arguments

  • value: any

Returns Boolean

isFailLike

tryad.isFailLike(value)

Useful for checking if an arbitrary object is a Fail, meaning it is not == null and has an isFail method that returns true.

Arguments

  • value: any

Returns Boolean

These methods are callable on instances of a Some, None, or Fail. Examples will use the name box to represent one of these instances.

filter

box.filter(fn)

fn will only be executed if box is a Some, and receives its value as its only argument. If it returns falsy, a None will be returned. If it returns truthy, the current instance is returned as-is. Dispatches to value.filter() if it is callable.

Arguments

  • fn: (value) -> Boolean

Returns Some | None

flatMap

box.flatMap(fn)

fn will only be executed if box is a Some, and receives its value as its only argument. Any returned tryad will be absorbed. Dispatches to value.flatMap() if it is callable.

Arguments

  • fn: (value) -> Some | None | Fail

Returns Some | None | Fail

forEach

box.forEach(fn)

fn will only be executed if box is a Some, and receives its value as its only argument. This method ends the chain. Dispatches to value.forEach() if it is callable.

Arguments

  • fn: (value) -> any

Returns undefined

includes

box.includes(other)

If box is a Some, compares other against the value contained within box and returns true if they are equal. Returns false if box is not a Some. Dispatches to value.includes() if it is callable.

Returns Boolean

map

box.map(fn)

fn will only be executed if box is a Some, and receives its value as its only argument. The return value will be used to construct a new tryad. If fn will return a tryad, you probably want to use flatMap instead. Dispatches to value.map() if it is callable.

Arguments

  • fn: (value) -> any

Returns Some | None

orElse

box.orElse(fn)

fn is only called if box is a None or a Fail. If box is a Fail, fn will receive the error contained within.

Arguments

  • fn: (error?) -> any

Returns Some | any

orSome

box.orSome(other)

Returns the value contained within box if it is a Some, or returns other if it is a None or a Fail. This method ends the chain.

Arguments

  • other: any

Returns any

some

box.some()

Returns the value contained within box. Throws if box is not a Some, so it's safer to use orSome. This method ends the chain.

Returns any

try

box.try(fn)

Attempts to call fn(value) and catches any error that occurs, returning a Fail with the error. Not executed if box is not a Some.

Arguments

  • fn: value -> Some | None | Fail

Returns Some | None | Fail

unwrap

box.unwrap(ifSome, ifNone, ifFail)

Calls whichever function corresponds to the instance type and returns its value.

Arguments

  • ifSome: value -> any
  • ifNone: () -> any
  • ifFail: error -> any

Returns any

see also

  • param.macro - Babel plugin for compile time partial application & lambda parameters

contributing

Pull requests and any issues found are always welcome.

  1. Fork the project, and preferably create a branch named something like feat-make-better
  2. Modify the source files as needed
  3. Make sure all tests continue to pass, and it never hurts to have more tests
  4. Push & pull request! :tada:

license

MIT © Bo Lingen / citycide