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

@daisugi/anzen

v0.4.0

Published

Anzen helps write safe code without exceptions, taking roots from Rust's Result and Haskell's Either.

Downloads

121

Readme

@daisugi/anzen

version npm downloads bundlephobia

This project is part of the @daisugi monorepo.

Anzen helps write safe code without exceptions, taking roots from Rust's Result and Haskell's Either.

🌟 Features

  • 💡 Minimum size overhead.
  • ⚡️ Written in TypeScript.
  • 📦 Only uses trusted dependencies.
  • 🔨 Powerful and agnostic to your code.
  • 🧪 Well tested.
  • 🤝 Is used in production.
  • ⚡️ Exports ES Modules as well as CommonJS.

Usage

import { Result } from '@daisugi/anzen';
import { readFileSync } from 'node:fs';

function readFile(path) {
  try {
    const response = readFileSync(path);
    return Result.success(response);
  } catch (err) {
    return Result.failure(err);
  }
}

// This line may fail unexpectedly without warnings.
const text = readFile('test.txt');

if (text.isFailure) {
  return text.getError();
}

return text.getValue();

Table of contents

Install

Using npm:

npm install @daisugi/anzen

Using yarn:

yarn add @daisugi/anzen

:top: back to top

Motivation

This library was created to address certain requirements that were not being fully met by other libraries of the same type, some libraries only partially met the requirements, while others fulfilled everything but also came with unnecessary overhead for the project.

If you are looking for a library that meets any of the following requirements, feel free to use this library. However, there are many other good libraries out there that implement the Result pattern, such as True-Myth or Folktale, that you can also use.

  • ✅ Early failures in invalid operations.
  • ✅ Can be written in a cleaner style, avoiding the need for chains.
  • ✅ Provides better TypeScript typing.
  • ✅ Keeps the API simple and does not try to mimic the Rust API or any other, but includes enough features to cover the most common use cases in the JavaScript world.

:top: back to top

#success(value)

Creates the successful variant instance of the Result, representing a successful outcome from an operation which may fail.

Usage

import { Result } from '@daisugi/anzen';

const res = Result.success('foo');

:top: back to top

#failure(err)

Creates the failure variant instance of the Result, representing a failure outcome from an operation which may fail.

Usage

import { Result } from '@daisugi/anzen';

const res = Result.failure('err');

:top: back to top

#isSuccess/#isFailure

Properties that indicates if the Result is a success or failure instance.

Usage

import { Result } from '@daisugi/anzen';

const res = Result.success('foo');
res.isSuccess;
// true
res.isFailure;
// false

const errRes = Result.failure('err');
errRes.isSuccess;
// false
errRes.isFailure;
// true

:top: back to top

#getValue()

Returns an value when comes from a success Result, and throws an error if comes from a failure instance.

Usage

import { Result } from '@daisugi/anzen';

Result.success('foo').getValue();
// 'foo'

:top: back to top

#getError()

Returns an error value when comes from a failure Result, and throws an error if comes from a success instance.

Usage

import { Result } from '@daisugi/anzen';

Result.failure('err').getError();
// 'err'

:top: back to top

#getOrElse(value)

If the Result is a success, the function returns the value; if it's a failure, it returns the provided value.

Usage

import { Result } from '@daisugi/anzen';

Result.failure('err').getOrElse('foo');
// 'foo'

:top: back to top

#map(fn)

Map over a Result instance, apply the callback to the Result value and returns an success instance, and the same failure instance if maps over a failure.

Usage

import { Result } from '@daisugi/anzen';

Result.success('foo')
  .map((value) => value)
  .getValue();
// 'foo'

:top: back to top

#chain(fn)

Map over a Result instance, apply the callback to the Result value and returns it, and the same failure instance if maps over a failure.

Usage

import { Result } from '@daisugi/anzen';

Result.success('foo')
  .chain((value) => Result.success(value))
  .getValue();
// 'foo'

#elseChain(fn)

Map over a Result instance as in each and get out the value if result is success, or apply a function (elseChain) to the value wrapped in the failure to get a default value.

Usage

import { Result } from '@daisugi/anzen';

Result.failure('err')
  .elseChain((err) => Result.success('foo'))
  .getValue();
// 'foo'

:top: back to top

#elseMap(fn)

Map over a Result instance as in map and get out the value if result is success, or apply a function (elseChain) to the value wrapped in the failure to get a default value.

Usage

import { Result } from '@daisugi/anzen';

Result.failure('err')
  .elseMap((err) => 'foo')
  .getValue();
// 'foo'

#unsafeUnwrap()

Retrieves the value/error from the Result, it can extract the value/error from a success or failure instances.

Usage

import { Result } from '@daisugi/anzen';

Result.failure('err').unsafeUnwrap();
// 'err'

:top: back to top

#toJSON()

Useful to serialize to JSON a Result instance.

Usage

import { Result } from '@daisugi/anzen';

Result.success('foo').toJSON();
// '{ "value": "foo", "isSuccess": true }'

Result.failure('err').toJSON();
// '{ "error": "err", "isSuccess": false }'

:top: back to top

#fromJSON(json)

Useful to deserialize from JSON Result instance like.

Usage

import { Result } from '@daisugi/anzen';

Result.fromJSON('{ "value": "foo", "isSuccess": true }')
  .getValue();
// 'foo'

:top: back to top

#promiseAll(fns)

A wrapper over Promise.all which helps work with promises whose returns a Result instances.

Usage

import { Result } from '@daisugi/anzen';

Result.promiseAll([
  async () => Result.success('foo')
])
  .getValue();
// ['foo']

In case of failure:

import { Result } from '@daisugi/anzen';

Result.promiseAll([
  async () => Result.failure('foo')
])
  .getError();
// 'foo'

:top: back to top

#fromThrowable(fn, parseErr)

This function executes an asynchronous function that could potentially raise an exception. It returns a success Result containing the function's return value if it executes successfully. Otherwise, it returns a failure Result containing the raised exception.

Usage

import { Result } from '@daisugi/anzen';

await Result.fromThrowable(
  async () => throw new Error('err'),
  (err) => err.message,
)
  .getError();
// 'err'

:top: back to top

#fromSyncThrowable(fn, parseErr)

This function is similar to fromThrowable, but it requires a synchronous function to be provided.

Usage

import { Result } from '@daisugi/anzen';

Result.fromSyncThrowable(
  () => throw new Error('err'),
  (err) => err.message,
)
  .getError();
// 'err'

:top: back to top

TypeScript

The Anzen is fully written in TypeScript, therefore you have available some types.

import {
  Result,
  type AnzenResultAny,
  type AnzenResultSuccess,
  type AnzenResultFailure,
} from '@daisugi/anzen';

function foo(): AnzenResultSuccess<string> {
  return Result.success('foo');
}

function bar(): AnzenResultFailure<string> {
  return Result.failure('foo');
}

function baz(): AnzenAnyResult<string, number> {
  if ((Math.random() * 10) % 2 === 0) {
    return Result.success(11);
  }
  return Result.failure('foo')
}

:top: back to top

Goal

The goal is to create an abstraction over errors that simplifies reasoning and ensures predictable results, thereby avoiding unexpected exceptions.

:top: back to top

Other projects

Meet the ecosystem

:top: back to top

License

MIT