‚̧Nuked: Probably Microwaved
    Wondering what‚Äôs next for npm?Check out our public roadmap! ¬Ľ

    @mrbarrysoftware/js-enumerize

    1.1.0¬†‚Äʬ†Public¬†‚Äʬ†Published

    jsEnumerize

    • Simple - No tricks, not complicated code, just plain old javascript.
    • Consistent - Enforce checking against the real value.
    • Correct - Enum values shouldn't exist outside of your enum.
    • Modern - Uses latest javascript language features for a seamless experience.

    Table of Contents

    Getting Started

    Install from npm or yarn:

    npm i --save @mrbarrysoftware/js-enumerize
    

    What sort of enumeration is this?

    This is some sort of union enumeration type, made popular from languages like Elm and Haskell.

    First and foremost, this is just a type that has an affinity to a set of constants. For instance, you could write a simple boolean enumeration like this: const bool = enumerize({ true: [], false: [] }) To use the bool enum type, bool exposes methods for each item passed into jsEnumerize. In this case, we have bool.true() and bool.false().

    Second, each enumeration supports pattern matching. This makes it easy to handle the various ways the enum can be used in one handy function. For instance, using the above bool type, let's say we want to print something on the screen based on whether or not the bool value is true: const returnedString = bool.caseOf({ true: () => 'The value is true', false: () => 'The value is false' }, bool.true());

    Usage

    Import it

    // es6/babel
    import enumerize, { Any } from 'js-enumerize';
     
    // from unpkg
    import enumerize, { Any } from 'https://unpkg.com/@mrbarrysoftware/js-enumerize?module=1';
     
    // from script tag
    // <script src="https://unpkg.com/@mrbarrysoftware/js-enumerize"></script>
    const { enumerize } = window;
    const { Any } = enumerize;
     
    // node
    const enumerize = require('js-enumerize');
    const { Any } = enumerize;

    Simple

    Let's make a simple enum type, Maybe, which can have a value, or have nothing.

    const Maybe = enumerize({
      just: [Any],
      nothing: [],
    });
     
    const greet = value => Maybe.caseOf({
      just: name => `Hello ${name}`,
      nothing: () => `Nice to meet you, what's your name?`,
    }, value);
     
    console.log(greet(Maybe.just('mrozbarry'))); // Hello mrozbarry
    console.log(greet(Maybe.nothing()));         // Nice to meet you, what's your name

    In our case, we are saying that when our Maybe has a value, it has to be a singular Any value. This could be more specific, like String, a custom class you've made, or multiple type constructors.

    Maybe.caseOf allows us to extract the values we store. For a Maybe, we can either extract the just value, or handle the case when we don't have data.

    Important: YourEnumType.caseOf of any enumeration must account for all cases. This means each type key you declare, like just and nothing, must exist as keys in your .caseOf call. If you want to skip cases, use the _ fall-through.

    Real-life Use Case

    What if we want to track the progress of an action, and return the result of that at the end? Here's a progress enum type, and how we could render that with a JSX function component:

    const Progress = enumerize({
      incomplete: [],
      partial: [Number, Number],
      complete: [Any],
      error: [Error],
    });
     
    const SomeComponent = ({ progress }) => Progress.caseOf({
      incomplete: () => (
        <section>
          <PendingIcon />
          <ProgressBar percent={0} />
        </section>
      ),
      partial: (current, total) => (
        <section>
          <ActiveIcon />
          <ProgressBar percent={current / total} />
        </section>
      ),
      complete: (resultingThing) => (
        <section>
          <CheckIcon />
          <DisplayThing thing={resultingThing} />
        </section>
      ),
      error: (error) => (
        <section>
          <Error message={error.toString()} />
        </section>
      ),
    }, progress);

    API

    enumerize(definition[, name]) : class Enumeration


    Create a new enumeration.

    Parameters

    definition (required)

    An object with the following shape descriptor:

    {
      nameOfUnionType: [String, Number, ...otherTypes],
      otherType: [Boolean, Object, Function],
    }

    Each key is a union type in this enumeration. For instance, if we were to make a boolean, the two keys would likely be true and false. Each key must have an array of type constructors. This array can be empty, contain built-in types, custom classes, or other enumerized() types.

    name (optional)

    A string name to assign the enumerization. This is handy for debugging using the two toString() methods off Enumeration. It defaults to 'Enumeration'.

    Return value

    Returns a unique Enumeration class.

    Notes

    None

    Example

    const MyEnumUnion = enumerize({
      foo: [String, Boolean],
      bar: [Function],
      baz: [],
    }, 'MyEnumUnion');

    class Enumeration


    A class representing a enumerated union type. Each instance is a union value of this type.

    Enumeration.toString() : String

    A string representation of an enumeration.

    Parameters

    None

    Return Value

    Will take the form of Maybe<just|nothing>.

    Notes

    None

    Example

    const MyEnumUnion = enumerize({
      foo: [String, Boolean],
      bar: [Function],
      baz: [],
    }, 'MyEnumUnion');
     
    console.log(MyEnumUnion.toString()) // Output: MyEnumUnion<foo|bar|baz>

    Enumeration.caseOf(objectOfDefinitionKeys, enumerationValue) : Any

    A method that acts like a decode/switch statement of the various union types of an enumeration. Given a value generated from your enumeration, it will call the supplied keyed function in objectOfDefinitionKeys and return that value.

    Parameters

    objectOfDefinitionKeys (required)

    An object taking a shape similar to the definition in a union. Instead of arrays with constructors as values, the values should be functions that accept the ordered parameters reflected in the definition. These functions can return a value that is piped to the return value of the caseOf function. All keys from the definition are required to be present, but it is possible to create a fall-through using the _ key.

    valueFromEnumeration (required)

    A value generated from your enumeration. This will typically take the form of YourEnumUnion.someType(...parameters). The types of your parameters must match the expected type constructors given to your enumerize call.

    Return Value

    The value returned from the appropriate keyed function.

    Notes

    This function will throw under the following conditions:

    • If you have missing definition keys and do not supply a _.
    • If you have definition keys that do not exist in the original enumerize definition.
    • If you pass a value that is not of the same enumeration type.

    Example

    Using all definition keys:

    const greet = maybeName => Maybe.caseOf({
      just: name => `Hello ${name}`,
      nothing: () => 'Hey stranger',
    }, maybeName);
     
    console.log(greet(Maybe.just('Alex'))); // Hello Alex
    console.log(greet(Maybe.nothing()));    // Hey stranger

    Using a _ fall-through:

    const greet = maybeName => Maybe.caseOf({
      nothing: () => 'Hey stranger',
      _: () => `Hello friend`,
    }, maybeName);
     
    console.log(greet(Maybe.just('Alex'))); // Hello friend
    console.log(greet(Maybe.nothing()));    // Hey stranger

    Enumeration.{{type}}(...params) : Enumeration instance

    When you create an enumerization with union types, each type gets a function to create that union type.

    Parameters

    A dynamic list of parameters that must match the constructor types provided in your enumerize definition.

    Return value

    An instance of your enumeration.

    Notes

    If the params don't match their respective type, an error will be thrown.

    Example

    const MyType = enumerize({
      foo: [String, Number],
      bar: [Boolean],
    }, 'MyType');
     
    console.log(MyType.foo('hello', 42)); // Outputs: MyType.foo(hello, 42)
    console.log(MyType.bar(true));        // Outputs: MyType.bar(true)
    console.log(MyType.foo({}, false));   // Throws a TypeError
     
    const isInstanceOfMyType = MyType.foo('hello', 42) instanceof MyType;
    console.log(isInstanceOfMyType);      // Outputs: true

    Enumeration#toString() : String

    Output the type and values of an Enumeration instance.

    Parameters

    None

    Return value

    Returns a string representation of your enumeration value.

    Notes

    None

    Example

    const MyType = enumerize({
      foo: [String, Number],
      bar: [Boolean],
    }, 'MyType');
     
    const value = MyType.foo('hello', 42);
    console.log(value.toString()); // Outputs: MyType.foo(hello, 42)

    Enumeration#toTypeString() : String

    Output the type and parameter types of an enumeration instance.

    Parameters

    None

    Return value

    A string representation of your enumeration type's parameter types.

    Notes

    None

    Examples

    const MyType = enumerize({
      foo: [String, Number],
      bar: [Boolean],
    }, 'MyType');
     
    const value = MyType.foo('hello', 42);
    console.log(value.toTypeString()); // Outputs: MyType.foo(<String>, <Number>)

    Other Important Stuff

    • Check out the license here
    • And other cool stuff here

    Keywords

    none

    Install

    npm i @mrbarrysoftware/js-enumerize

    DownloadsWeekly Downloads

    37

    Version

    1.1.0

    License

    MIT

    Unpacked Size

    40.8 kB

    Total Files

    22

    Last publish

    Collaborators

    • avatar