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

re-opaque

v1.3.0

Published

A ReasonML library for opaque data types with validation.

Downloads

10

Readme

re-opaque

A ReasonML library for opaque data types with validation.

Opaque strings

At runtime, they are just strings. But since each of them is a distinct module, they form distinct types; so you can never e.g. mix up an Email with a Name. In addition,

Example

Below we create three string-like modules, UserName, Email, and MessageText. Each has its own validation logic (or lack thereof).

open Opaque.String;

module UserName: StringType = Make(
  Validation.Compose(
    Validation.MinLength({let n = 10;}),
    Validation.MaxLength({let n = 80;}),
  ), ()
);

module Email = Opaque.String.Make(Opaque.RegexValidation({
  let regex = [%re {|/magic email regex/|}];
}, ()));

// This has no validation (although in practice a max length might be good)
module MessageText = Opaque.String.Make(String.NoValidation);

We can't create a username that's less than 5 characters:

// raises `TooShort("bad", 10)`
let badUsername = "bad"->UserName.fromString;

Or an email that doesn't match our regex:

// raises `RegexMatchError("i am not an email", <some regex>)`
let badEmail = "i am not an email"->Email.fromString;

This guarantee means that you have total confidence that you won't be handling invalid data, and pushes error boundaries as early as possible.

Error handling

The fromString function will raise an exn exceptions to on failure. Different validators raise different exceptions, so you can switch on them with try or | exception _ to do error handling.

Alternatively you can use resultFromString, which avoids potential error cascades. It's up to you.

// Ok("probablyok"), which is typed as result(UserName.t, exn)
let goodUsername = "probablyok"->UserName.resultFromString;

// Error(TooShort("nope", 10))
let badUsername = "nope"->UserName.resultFromString;

Extras

The module also generates fromJson and toJson functions, allowing easy conversion to/from JSON for the custom types.

There's also a MakeStringSet functor which creates a Set module for managing sets of custom types with Belt.String. There might be more on this later.

Build

yarn re:build

# Alternatively, in watch mode
yarn re:watch

Test

yarn test

# Alternatively, in watch mode
yarn test:watch