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

jazzi

v4.2.0

Published

Implementations of common functional structures. Available structures and features:

Downloads

19

Readme

Jazzi: Juan's Algebraic Data Structures

Implementations of common functional structures. Available structures and features:

  • Either
  • Maybe
  • Async
  • All structures have a toPromise and toThenable methods

Installing

From npm registry

npm install jazzi
// or
yarn add jazzi

From denoland

import * as jazzi from 'https://deno.land/x/jazzi/mod.ts'

Usage

This README.md is a summary of all that is available in jazzi. For more details go to API.md

All structures and global functions are exported as named exports from the jazzi module

import { Maybe, Either, Async } from 'jazzi';
// or if you use deno
import { Maybe, Either, Async } from 'https://deno.land/x/jazzi/mod.ts'; 

Constructors and operators are exported as named exports of the structure they are meant to be used on.

import * as M from 'jazzi/Maybe';

M.of(40)['|>'](M.map(x => x + 2)) // Just 42

A wrapper that mimics a fluent interface is also available

import * as M from 'jazzi/Maybe/fluent';

M.of(40).map(x => x + 2)

Conversion between the two styles is possible via the wrap and unwrap operators

import * as M from 'jazzi/Maybe';
import * as F from 'jazzi/Maybe/fluent';

const pipeToFluent = F.wrap(M.of(41));
const fluentToPipe = F.of(41).unwrap();

Summary

From this point onwards, all imports are omitted

All structures have a toThenable function that returns an object complies with the thenable interface. This allows for ease of composition with JS Promises and to be used with async/await syntax. In general, all happy cases return inner value, all adverse cases throw inner value. In versions <=2.2.1, the structure was a thenable with a then function. This caused some implicit behavior and the thenable feature was made opt-in with the toThenable function.

const eitherLeftOrRight = Either.from(/*...*/);
const example = async () => {
    try {
        const x = await eitherLeftOrRight.toThenable()
        console.log(`It was Right ${x}`);
    } catch(e){
        console.log(`It was Left ${e}`)
    }
}

It also comes with a toPromise function that converts any structure to a promise.

Maybe

Maybe represents the possibility of the absensce of value. Just for values, None for no values. The default constructor returns Just of truthy values and None otherwise. Unlike Either where Left and Right both behave like functors, None does not behave like a functor, rather map of a None simply returns the structure unchanged.

Maybe.of(42)    // Just 42
Maybe.of(false) // None

Either

Either represents a value that can be one of two possibilities, either Left or Right (badum tssss). By convention Left is treated as the error case and Right as the happy path but they are just two possibilities. The from constructor receives a left value l and right value r where if r is neither null nor undefined then we get Right r otherwise we get a Left l. There is a curried version of the fromFalsy constructor that was made for convenience. The of constructor is the same as calling the from constructor but passing the same value as both arguments

const default42 = Either.defaultTo(42);
defaultTo42(undefined) // returns Left 42
defaultTo42(6 * 9) // returns Right (6 * 9)

const Right42 = Either.attempt(() => 42) // returns Right 42 
const Left42 = Either.attempt(() => { throw 42 }) // returns Left 42 

Async

The Async structure represents an async computation that may need some input. It can be seen as a mix between IO, Reader and a Promise. Unlike IO, run returns a promise with the result of the computation. Like IO, it is a lazy monad. Like Reader, the run method must receive the environment.

const s42 = Async.Success(42)
const f42 = Async.Fail(42)

await s42.run() // resolves with 42
await f42.run() // rejects with 42

const withEnv = Async.from(async (x) => x + 2)
await withEnv.run(40) // resolves with 42

// Environment can be provided using provide
const withEnvProvided = Async.from(async (x) => x + 2).provide(40)
await withEnvProvided.run() // resolves with 42

// Zip sequences two Asyncs and collects the result in a tuple. Left and Right variants discard one result.
// a.zip(b) is equivalent to a.flatMap(x => b.map(y => [x,y]))
await s42.zip(s42).run() // resolves to [42,42]
await s42.zipRight(Async.Success("right")).run() // resolves to "right"
await Async.Success("left").zipLeft(s42).run() // resolves to "left"

// The only way to recover from a Fail
await f42.recover((e) => Async.Success(e)).run() // resolves to 42

await Async.from(() => Promise.resolve(42)).run() // resolves to 42