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 🙏

© 2025 – Pkg Stats / Ryan Hefner

@dotcom-tool-kit/validated

v1.0.2

Published

Types and functions for an errors-as-first-class-values pattern

Downloads

1,614

Readme

@dotcom-tool-kit/validated

Types and functions for an errors-as-first-class-values pattern

Rationale

In Tool Kit, we handle loading many plugins with different types of entry point (for Tasks, Hooks etc) in parallel. There are various points this process could go wrong: importing an entry point, checking version compatibility, and more.

If we naïvely used exception throwing or Promise rejections, Tool Kit would stop at the first problem that happened; the user would fix that only to run into the next error, which would be frustrating. We want to get as far as we can and collect all the errors that happen to present once, as late as possible.

We could still use exceptions/rejections for this, along with Promise.allSettled. However, with that pattern it would be difficult to follow the data flow of the errors, and easy to accidentally forget to collate some errors, falling into the same issue of throwing one error at a time.

Instead, we model these errors using an explicit return value, Validated<T>. This type is a union of Valid<T> which represents a correct value, and Invalid which represents a problem with a list of string reasons. By making this an explicit type, we clearly mark all the functions that can return errors we may want to collate, and make it impossible to use the values without deciding what to do with the errors.

This pattern is modelled after Go's error handling using multiple return values, Rust's Result<T, E> type and Haskell's Either a b type.

Usage

Creating a Validated

@dotcom-tool-kit/validated exports two constructor functions, valid and invalid. Use these to create a wrapper when the status of the value is known, e.g.:

valid({ some: 'object' })

invalid([
	'list of problems'
])

Using Validated values

Validated objects have methods that are similar to the Array or Promise methods, allowing you to do things with the values or error reasons without having to inspect the types:

validated.map(value => {
    /* do something with value */
	// `return` something else. replaces the value with this return value if valid, does nothing if invalid
})

validated.mapError(reasons => {
	/* do something with reasons */
	// `return` something else. replaces the reasons with this return value if invalid, does nothing if valid
})

Extracting values from a Validated

Validated has an .unwrap method that allows you to extract its value if valid, or throws an error with its reasons if invalid. This should be used as late as possible, when you can't get any further without the value, and need to stop if it's invalid.

validated.unwrap('something was invalid!')

Grouping an array of Validated

Similar to Promise.all, if you have multiple Validateds and you need to group their values and reasons (i.e. you have Array<Validated<T>> and you want Validated<Array<T>>), we have reduceValidated:

reduceValidated([
	validated1,
	validated2,
	validated3
])

This is used in Tool Kit when e.g. we load multiple plugins in parallel.