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

rob-result

v0.2.6

Published

An ergonomic TypeScript Result type library.

Downloads

1

Readme

Rob Result

An ergonomic TypeScript Result type library.

This is something I'm developing for personal use in mind, but the ins and outs of how this works are documented here in case anyone wants to understand the library.

Getting started

Install the dependency with npm, yarn, or pnpm

npm install rob-result
yarn add rob-result
pnpm install rob-result

Basic Example:

import { match, isErr, isOk, Result, Err, Ok } from 'rob-result';

// create a Result function that has a number Ok case and string Error case
const validDivide = (a: number, b: number): Result<number, string> => {
  if (b === 0) {
    return Err("Cannot divide by 0!");
  }
  return Ok(a/b);
}

// execute validDivide
const divideResult = validDivide(4, 2);

// log a message depending on outcome
if (isOk(divideResult)) {
  console.log(`The answer is: ${divideResult.data}`);
}
if (isErr(divideResult)) {
  console.log(`Divide Error: ${divideResult.data}`);
}

// can also use a match utility instead of if statements
match({
  on: divideResult,
  ifOk: (value) => console.log(`The answer is: ${divideResult.data}`),
  ifErr: (error) => console.log(`Divide Error: ${divideResult.data}`),
})

Features

Result Type

  type Result<Ok, Err> = OkType<Ok> | ErrType<Err>;

The Result type is a discriminated union for handling errors. The first generic argument is the data expected when a function has an Ok result. The second generic argument defines the error data type for when a function has an Err result.

AsyncResult

  type AsyncResult<Ok, Err> =  Promise<Result<Ok, Err>>

AsyncResult is syntatic sugar for when a Result type wrapped by a Promise type.

Ok

Ok example:

  const okResult = Ok(4);

Ok is a type constructor which builds the Ok variant for results.

Err

Err example:

  const errResult = Err("Something went wrong!");

Err is a type constructor which builds the Ok variant for results.

isOk

isOk example:

  const okResult = Ok(2);
  isOk(okResult) // true

  const errResult = Err(2);
  isOk(errResult) // false

isOk is a type predicate that returns true if a result type value is Ok and false if is Err.

isErr

isErr example:

  const okResult = Ok(2);
  isErr(okResult) // false

  const errResult = Err(2);
  isErr(errResult) // true

isErr is a type predicate that returns false if a result type value is Ok and true if is Err.

map

map example:

  const double = (n: number) => n * 2;

  const okValue = ok(2);
  const newOkValue = map(okValue, double);
  // newOkValue is Ok(4);

  const errValue = Err(2);
  const newOkValue = map(okValue, double);
  // newOkValue is Err(2) -- nothing happens since its an Err type

Because Result is a functor, it's convenient to provide a map function. The map function applies a function to the value of Ok if the provided result value is Ok. If the result value is Err, then map simply returns back the Err.

flatMap

flatMap example:

  const double = (n: number) => Ok(n * 2);

  const okValue = ok(2);
  const newOkValue = map(okValue, double);
  // newOkValue is Ok(4);

  const errValue = Err(2);
  const newOkValue = map(okValue, double);
  // newOkValue is Err(2) -- nothing happens since its an Err type

Like map except the return type of the mapping function returns a Result. This is useful for composing several result functions together.

match

match example instead of checking both ifOk and ifErr utilities like in the getting started example, we can also use a match function. match returns an unwrapped union of the Ok and Err types which can be useful in JSX when both the Ok case and Err case both return JSX.

  const divideResult = [[Code from getting started example above]];
  match(divideResult, {
    ifOk: (value) => console.log(`The answer is: ${divideResult.data}`),
    ifErr: (error) => console.log(`Divide Error: ${divideResult.data}`),
  })

flatMatch

flatMatch example:

  const divideResult = [[Code from getting started example above]];
  const x = flatMatch(divideResult, {
    ifOk: (value) => value
    ifErr: (error) => error,
  })
  // x is a Result type instead of a union of values like in match

flatMatch will likely be renamed (It's not really flattening anything). It's like match except it returns a Result.

attempt

attempt example:

  // apiResult will be Ok(value) if the api succeeds otherwise it returns Err(e) where e the parameter of
  // what would otherwise be a catch block
  const apiFunction = attempt(async (name: string) => {
    const derpResponse = await fetch('https://derp.com?name=' + name);
    return await derpResponse.json();
  });

  const apiResult = await apiFunction();
  

The purpose of attempt is to remove the need for try catch blocks in your code as much as possible. The attempt function internally wraps the async code in a try catch and returns Ok with whatever is returned in the callback or will return an Err response with whatever the error parameter would return in the catch block.

attemptSync

attemptSync example:

  // apiResult will be Ok(value) if the api succeeds otherwise it returns Err(e) where e the parameter of
  // what would otherwise be a catch block
  const validDivide = attemptSync((a: number, b: number) => {
    if (b === 0) {
      throw 'Cannot divide by 0';
    }
    return a/b;
  });
  
  const divideResult = validDivide(4, 2); // Ok(2)

attemptSync is like attempt except for synchronous functions.