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

enumerated

v1.0.3

Published

A simple, lightweight, easy-to-use and high performance implementation of enumerated type for JavaScript.

Downloads

21

Readme

view on npm npm module downloads per month Build Status Analytics

Enumerated

What's Enumerated?

A simple, lightweight, easy-to-use and high performance implementation of Enum type for JavaScript. Enumerated uses lookup tables and bit operators internally, so is blazingly fast and also provides a friendly interface to reduce the time you spend on exploring and integrating the module. It's really lightweight - ~420 sloc excluding comments - but contains all the usual features you need and works in modern browsers (IE8+) too.

Usage


var Enum = require('enumerated')

var colors = new Enum('red', 'green', 'blue')
var selectedColors = colors.red | colors.blue

colors.valuesOf(selectedColors) // [ 'red', 'blue' ]

var numbers = Enum({
    one:   1,
    two:   2,
    three: 3,
    four:  4,
    five:  5
})

var selectedNumbers = numbers.four | numbers.two

numbers.valuesOf(selectedNumbers) // [ 2, 4 ]

selectedNumbers |= numbers.five // extend selectedNumbers with another value

numbers.keysOf(selectedNumbers) // [ 'two', 'four', 'five' ]

selectedNumbers ^= numbers.two // remove one item from selectedNumbers

numbers.valuesOf(selectedNumbers) // [ 4, 5 ]

selectedNumbers ^= numbers.five | numbers.four // remove two items in one step

numbers.valuesOf(selectedNumbers) // []

// not flaggable enum 

var states = Enum('pending', 'processing', 'finished', 'failed', { single: true })

var selectedState = states.processing

states.valueOf(selectedState) // 'processing'

var selectedStates = states.processing | states.pending

try {
    states.valuesOf(selectedStates)
}
catch(ex) {
    // throws "Error: This enum allows only one single choice."
}

// make it case insensitive

var days = Enum('Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday', 'Sunday', { ignoreCase: true })

days.get('monday') // { key: 'monday', value: 'Monday' }
days.get('fRiDaY') // { key: 'friday', value: 'Friday' }

// items will be accessible lowercased with the dot or index operator if ignoreCase option is set to true
var selectedDays = days.saturday | days['sunday']

// ...

If you don't want to require Enumerated again and again in different modules, but instead only once in the main module, do the following:


require('enumerated').global = true

// after that point Enum constructor has been exposed to the global context, 
// so feel free to use it anywhere

var animals = Enum({
    eagle: 'bird',
    snake: 'reptile',
    cat:   'four-footed'
})

// ...

Examples of comparisons:


var foodList = [ 'pizza', 'hamburger', 'macaroni', 'ketchup' ],
    food     = Enum(foodList)

var dinner = food.pizza | food.ketchup

Enum.item(food.pizza).in(dinner) // true
Enum.item(food.hamburger).in(dinner) // false

food.item('pizza').in(dinner) // true
food.item('hamburger').in(dinner) // false

dinner === food.ketchup | food.pizza // true
dinner === food.ketchup | food.hamburger // false
dinner === food.pizza // false

var food2 = Enum('pizza', 'hamburger', 'macaroni', 'ketchup')

food == food2 // false, since object is a reference type

food.pizza === food2.pizza // true, because under the hood Enum uses simple integers to mark items

food instanceof Enum // true
food.pizza instanceof Enum // false
typeof food === 'object' // true
typeof food.pizza === 'number' // true

Supported constructors:


var a = Enum('a', 'b', 'c'),
    b = Enum([ 'a', 'b', 'c' ]), // equivalent with the previous
    c = new Enum({ a: 1, b: 2, c: 3 }), // new operator is optional 
    d = Enum('a', 'b', 'c', { ignoreCase: true /* default: false */ }), // you can pass an object containing the desired options as the last argument
    e = Enum([ 'a', 'b', 'c' ], { single: true /* default: false */ }) // usually the second argument will be the last :)

Examples of useful Enum instance members:


var fruitNames = { apple: 'red', orange: 'orange', grape: 'green', banana: 'yellow', pineapple: 'brown' },
    fruits     = Enum(fruitNames),
    selected   = fruits.apple | fruits.banana
     
fruits.valueOf(selected)  // 'red', because it returns the first selected item
fruits.valuesOf(selected) // [ 'red', 'yellow' ]
fruits.keyOf(selected)    // 'apple'
fruits.keysOf(selected)   // [ 'apple', 'banana' ]

fruits.get('grape') // { key: 'grape', value: 'green' }
fruits.get(3) // { key: 'banana', value: 'yellow' }

fruits.valueByKey('grape')                 // 'green'
fruits.valuesByKeys('apple', 'pineapple')  // [ 'red', 'brown' ]
fruits.keyByValue('yellow')                // 'banana'
fruits.keysByValues([ 'orange', 'green' ]) // [ 'orange', 'grape' ], note that you also can pass an array as well to all the member functions expecting multiple parameters
fruits.item('apple').in(selected)          // true
fruits.item('orange').in(selected)         // false
fruits.item('fake').in(selected)           // false
fruits.length                              // 5
fruits.keys                                // [ 'apple', 'orange', 'grape', 'banana', 'pineapple' ]
fruits.values                              // [ 'red', 'orange', 'green', 'yellow', 'brown' ]
fruits.items /*

[
    { key: 'apple', value: 'red' },
    { key: 'orange', value: 'orange' },
    { key: 'grape', value: 'green' },
    { key: 'banana', value: 'yellow' },
    { key: 'pineapple', value: 'brown' }
]

*/

fruits.toJSON()         // { descriptor: { apple: 'red', orange: 'orange', grape: 'green', banana: 'yellow', pineapple: 'brown' }, options: { single: false, ignoreCase: false } }
fruits.toJSON(selected) // [ 'red', 'yellow' ]

JSON.stringify(fruits)  // '{"descriptor":{"apple":"red","orange":"orange","grape":"green","banana":"yellow","pineapple":"brown"},"options":{"single":false,"ignoreCase":false}}'

fruits.fromJSON('["red","yellow"]') === selected // true
  
console.log(fruits) /*

Enum({
    "apple": "red",
    "orange": "orange",
    "grape": "green",
    "banana": "yellow",
    "pineapple": "brown"
})

*/

Examples of useful Enum "static" members:


var fruits = Enum.fromJSON('{"descriptor":{"apple":"red","orange":"orange","grape":"green","banana":"yellow","pineapple":"brown"},"options":{"single":false,"ignoreCase":false}}')

Enum.global = true // set it true to expose Enum constructor into the global context
 
Enum.item(fruits.apple).in(fruits.banana | fruits.apple)     // true
Enum.item(fruits.apple).in(fruits.orange | fruits.pineapple) // false
Enum.item(fruits.apple).in(fruits.apple)                     // true
Enum.item(fruits.apple).in(fruits.pineapple)                 // false

Enum.item(fruits.apple).isSingle()                   // true
Enum.item(fruits.apple).isMultiple()                 // false
Enum.item(fruits.apple | fruits.orange).isSingle()   // false
Enum.item(fruits.apple | fruits.orange).isMultiple() // true

Enum.MAX_LENGTH // 31 or 63, the maximum count of items in an Enum instance. depends on the integer size of the system

And there is some extra sugar:


// for non-flaggable enums you can use the language's built-in switch statement

var state   = Enum('pending', 'finished', { single: true }),
    current = state.pending

switch(current) {
    case state.pending:
        // ...
        break
        
    case state.finished:
        // ...
        break
        
    default:
        // ...
        break
}

// unfortunately you can't do the same with flagged enums,
// but Enumerated is shipped with a handy helper method

var fruits      = Enum('apple', 'orange', 'strawberry', 'lemon', 'banana'),
    likedFruits = fruits.apple | fruits.strawberry | fruits.banana

function printCase(value) {
    console.log('user likes', value)
}

fruits.switch(likedFruits)
      .case('apple', printCase)
      .case('orange', printCase)
      .case('strawberry', printCase)
      .case('lemon', printCase)
      .case('banana', printCase)
      
/*

output:

user likes apple
user likes strawberry
user likes banana

*/

Note: Proper examples will be added soon to the examples folder.

Installation

With npm:

npm install --save enumerated

With git:

git clone git://github.com/schwarzkopfb/enumerated.git
cd enumerated
npm test

Browser usage

If you want to use Enumerated in a browser, just download and include enumerated.min.js in your front-end project. Don't worry, it weights only about 5 kB.

Documentation

The complete documentation with examples for all the instance and static members can be found here.

AMD (Requirejs) support

It's supported to load Enumerated with a module loader that follows the AMD pattern, like the deservedly popular Requirejs.


requirejs([ 'enumerated' ], function(Enum) {

    var mouseButtons = Enum('left', 'middle', 'right')
    
    // ...

})

Unit tests

The project is entirely covered with unit tests. Of course you can npm test to run them in Node.js environment or click here if you're curious about the results in a web browser.

Benchmark

Performance is important, so I wrote a simple benchmark for the project. The results on my MacBook Pro (Mid 2010) are the following:

  • 50000000 get() calls performed in 1.36 seconds (36764705.88 ops/sec)
  • 50000000 valueOf() calls performed in 2.88 seconds (17361111.11 ops/sec)
  • 50000000 valuesOf() calls performed in 9.27 seconds (5393743.26 ops/sec)
  • 1000000 fromValues() calls performed in 3.84 seconds (260416.67 ops/sec)
  • 1000000 valuesByKeys() calls performed in 3.90 seconds (256410.26 ops/sec)
  • 100000 constructor calls performed in 5.77 seconds (17331.02 ops/sec)

In the light of the results, the overhead compared to more primitive solutions is negligible.

You can run the benchmark on your machine with the following command:

npm run benchmark

License

MIT license.