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

baccano

v2.1.1

Published

Railway-oriented programming helper library

Downloads

26

Readme

Baccano

A railway-oriented programming helper library.

forthebadge forthebadge forthebadge

npm npm

Intro to Railway-oriented Programming

The term was coined by Scott Wlaschin of F# for Fun and Profit. Here's his talk on the subject. This method of programming allows us to deal with errors functionally in our applications. It involves having two paths (or tracks) if you will, one is the success path, and one is the error path. You start with the success path and when an error occurs, expected or not, you move to the error path. It's easier to understand if you try it out.

Getting Started

Importing the library

To use the library, first import it:

In Node:

const { compose, fromUnary, SomeError, Success } = require('baccano')

As ES Module:

import { compose, fromUnary, SomeError, Success } from 'baccano'

On the browser:

<script src="https://cdn.jsdelivr.net/npm/[email protected]/baccano.min.js"></script>
<script>
    const { compose, fromUnary, SomeError, Success } = Baccano
</script>

Using the library

Let's learn how to use the library by creating a pipeline of mathematical operations.

Define Errors

Features should not be the only things to be considered when planning software. Errors, or anything that can go wrong should also be planned. Hence, we have to define the possible errors that might occur in a particular pipeline of functions. Normally we'd use a type or a variant for this but we're in JavaScript so I suggest using Symbols for them. We'll be using division in the pipeline so we have to plan for a division by zero case.

const DIVISON_BY_ZERO = Symbol.for('DIVISION_BY_ZERO')

Define Functions

Now we'll define the functions that we will use. In Railway-Oriented Programming, a function should either return a success with the value, or some error with the error message. This would be easy in type-safe functional programming languages but that is not the case with JavaScript so we'll need some helpers from the library.

import { SomeError, Success } from 'baccano'

After importing our helper functions, let's define the functions we're going to use.

const divideBy = n => x => {
  if (n === 0) {
    return SomeError(DIVISON_BY_ZERO, "Cannot divide by zero.")
  } else {
    return Success(n / x)
  }
}

const plusOne = x => {
  return Success(x + 1)
}

In this case, we create a function divideBy which takes a number and returns a function that accepts a number and divides it by the previous number. If the previous number is zero, we return a DIVISON_BY_ZERO error using the SomeError function, which takes a value that represents the error and the error message. Else, we return a success using the Success function which accepts a value.

The plusOne function just takes a number and returns a Success with the number incremented by one.

Complete Example Code

Here is the complete example code:


// Import library
import { compose, fromUnary, SomeError, Success } from 'baccano'

// Define Errors
const DIVISON_BY_ZERO = Symbol.for('DIVISION_BY_ZERO')

const divideBy = n => x => {
  if (n === 0) {
    return SomeError(DIVISON_BY_ZERO, "Cannot divide by zero.")
  } else {
    return Success(n / x)
  }
}

const plusOne = x => {
  return Success(x + 1)
}

(async () => {

  // Take unary functions and convert them to compatible functions
  const compatibleDivideByZero = fromUnary(divideBy(0))
  const compatiblePlusOne = fromUnary(plusOne)

  // Create pipeline of functions
  const pipeline = compose(compatiblePlusOne, compatibleDivideByZero, compatiblePlusOne)

  // Get result of the pipeline
  const result = await pipeline(2)

  // Display end value
  console.log(result.value) // 4

  // Display errors
  console.log(result.errors) // [ { message: 'Cannot divide by zero.', type: Symbol(DIVISON_BY_ZERO) } ]
})()

Notes

  • I named the library Baccano because when I thought about trains and railways, I thought of the Baccano anime. @egoist is not the only one fond of anime references LOL.

Roadmap

  • [x] Handling Asynchronous functions

License

MIT