0.13.0 • Published 7 years ago

unmutable-extra v0.13.0

Weekly downloads
2
License
MIT
Repository
github
Last release
7 years ago

unmutable

Immutable.js functions for collections that may or may not be Immutable.

Immutable.js has a fantastic API, but sometimes you don't want to turn everything into Immutable collections. With large nested data structures, Immutable can be quite heavy on memory and slow, and you may need to cope with data that might sometimes contain immutable collections and sometimes not.

This project aims to bring that API over for use with plain objects and arrays, as well as Immutable.js Map and List collections. Like Immutable.jsm, unmutable never mutates data. Unlike Immutable.js, unmutable constructs nested data objects lazily, so when using nested data sets its memory footprint is much smaller than Immutable.js.

Quick example

Wrap will wrap your data in an UnmutableWrapper. You can then use Immutable.js style methods on it, then access .value when you want to get the contents of your wrapper back out again.

import {Wrap} from 'unmutable';

var wrappedObject = Wrap({
    a: {
        b: "hi"
    }
})

console.log(wrappedObject.getIn(['a', 'b']).value); // logs out "hi"

Installation

There are two main packages you can choose from, unmutable or unmutable-lite. There is also an optional package of extra functions called unmutable-extra.

unmutable

Unmutable requires immutable@v3.8.1 as a peer depencency, and will allow you to use almost all of Immutable.js' methods on your Unmutable collections. Use this if you already have Immutable.js as a dependency or want to take advantage of Immutable.js' large set of Map and List features on objects and arrays.

Refer to the Methods section to see which methods you can use on Unmutable collections.

yarn add immutable && yarn add unmutable

or

npm install immutable && npm install unmutable

unmutable-lite

Unmutable-lite is a standalone library that allows you to use a subset of Immutable.js' methods on objects and arrays, and on Immutable.js collections. Use this if you like Immutable.js' API but don't want the Immutable.js dependency.

Refer to the Methods section to see which methods you can use on Unmutable-lite collections.

yarn add unmutable-lite

or

npm install unmutable-lite

unmutable-extra

This package contains optional extra functions for unmutable that don't exist in Immutable.js. See Unmutable Extra.

More examples

Data types are preserved through the wrapping process. Pass in an object and you'll get back an object. Pass in a Map? You'll get a Map back. Same goes for Arrays vs Lists.

import {Wrap} from 'unmutable';
import {Map} from 'immutable';

var obj = {abc: 123};
var newObj = Wrap(obj).set('abc', 456)value;
// newObj is an object {abc: 456}

var map = Map({abc: 123});
var newMap = Wrap(map).set('abc', 456)value;
// newMap is a Map {abc: 456}

Wrap can actually wrap around any data type, not just collections. If your data isn't a collection then you won't be able to use any collection manipulation methods, but you will be able to access the wrapper's .value property and the methods isCollection(), isKeyed() and isIndexed().

Please note that while you can wrap Immutable collections other than Map and List, right now they won't be recognised as collections so you won't be able to access their methods on the Unmutable wrapper. As this library grows, the plan is to bring in more Immutable types.

import {Wrap} from 'unmutable';

console.log(Wrap("string")value); // logs out "string"
console.log(Wrap("string").isCollection()); // false

Helper functions

Unmutable exports the following helper functions:

  • IsUnmutable - Pass it anything and it'll return a boolean, true if the passed item is an unmutable wrapper of some kind.
  • Unwrap - Unmutable wrappers passed into this will be unwrapped, everything else will just pass through unchanged.

Methods

All unmutable wrappers will have the following member variables and methods:

  • .value: * - Returns the data contained inside the unmutable wrapper.
  • .isCollection(): boolean - Returns true if the wrapped data is a collection. If it is it will have the methods listed below, depending on the type of wrapper.
  • .isIndexed(): boolean - Returns true if the wrapped data is an Array or List, or false otherwise.
  • .isKeyed(): boolean - Returns true if the wrapped data is an Object or Map, or false otherwise.
  • .wrapperType(): string - Returns the name of the unmutable wrapper type.

Objects, Arrays, Lists and Maps will also have additional collection methods that mimic what Immutable.js' collections.

Most methods return unmutable wrappers, except for those that ask questions about the contents of a collections (e.g. has(), includes() etc).

Wrap(["1","2","3"]).get(0); // returns an unmutable wrapper containing "1"

Wrap(["1","2","3"]).includes("1"); // returns true

Methods that have function parameters like map() and reduce() are passed their values in unmutable wrappers. If the original iterable is also received, this is also wrapped. Keys are not wrapped.

Wrap([
    {name: "tedd"},
    {name: "todd"}
])
    .map((value, key, iter) => {
        // value is an unmutable wrapper containing {name: "tedd"}, then {name: "todd"}
        // key is the number 0, then 1
        // iter is the original unmutable wrapper
        return value.get("name");
    });

It makes no difference if the value returned from a function parameter is wrapped or not, unmutable works with either.

Wrap(["1","2","3"]).map(ii => ii); // returns Wrap(["1","2","3"])

Wrap(["1","2","3"]).map(ii => ii.value); // also returns Wrap(["1","2","3"])

Method feature set

Objects, Arrays, Lists and Maps will also have the following methods, depending on whether unmutable or unmutable-lite is being used. New methods will be added over time.

unmutable Object / Mapunmutable Array / Listunmutable-lite Object / Mapunmutable-lite Array / ListNotes
asImmutableasImmutableasImmutableasImmutable
asMutableasMutableasMutableasMutable
butLast ✔︎butLast ✔︎-butLast ✔︎
clear ✔︎clear ✔︎clear ✔︎clear ✔︎
concat ✔︎concat ✔︎concat ✔︎concat ✔︎
count ✔︎count ✔︎count ✔︎count ✔︎Returns plain number
countBycountBycountBycountBy
delete ✔︎delete ✔︎delete ✔︎delete ✔︎
deleteIn ✔︎deleteIn ✔︎deleteIn ✔︎deleteIn ✔︎
entriesentriesentriesentries
entrySeqentrySeqentrySeqentrySeq
equalsequalsequalsequals
every ✔︎every ✔︎every ✔︎every ✔︎Returns plain boolean
filter ✔︎filter ✔︎filter ✔︎filter ✔︎
filterNot ✔︎filterNot ✔︎filterNot ✔︎filterNot ✔︎
findfindfindfind
findEntryfindEntryfindEntryfindEntry
-findIndex-findIndex
findKeyfindKeyfindKeyfindKey
findLastfindLastfindLastfindLast
findLastEntryfindLastEntryfindLastEntryfindLastEntry
findLastIndexfindLastIndexfindLastIndexfindLastIndex
findLastKeyfindLastKeyfindLastKeyfindLastKey
first ✔︎first ✔︎-first ✔︎
flatMapflatMapflatMapflatMap
flattenflattenflattenflatten
flip-flip-
forEachforEachforEachforEach
-fromEntrySeq-fromEntrySeq
get ✔︎get ✔︎get ✔︎get ✔︎
getIn ✔︎getIn ✔︎getIn ✔︎getIn ✔︎
groupBygroupBygroupBygroupBy
has ✔︎has ✔︎has ✔︎has ✔︎Returns plain boolean
hashCodehashCode--
hasIn ✔︎hasIn ✔︎hasIn ✔︎hasIn ✔︎Returns plain boolean
includes ✔︎includes ✔︎includes ✔︎includes ✔︎Returns plain boolean
-indexOf-indexOf
-insert ✔︎-insert
-interleave ✔︎-interleave
-interpose ✔︎-interpose
isEmpty ✔︎isEmpty ✔︎isEmpty ✔︎isEmpty ✔︎
isSubsetisSubsetisSubsetisSubset
isSupersetisSupersetisSupersetisSuperset
joinjoinjoinjoin
keyOfkeyOfkeyOfkeyOf
keyskeyskeyskeys
keyListkeyListkeyListkeyListReturns keys as an array, this doesn't exist in Immutable.js
keySeqkeySeq--
last ✔︎last ✔︎-last ✔︎
-lastIndexOf-lastIndexOf
lastKeyOflastKeyOflastKeyOflastKeyOf
map ✔︎map ✔︎map ✔︎map ✔︎
mapEntries ✔︎-mapEntries-
maxmaxmaxmax
maxBymaxBymaxBymaxBy
merge ✔︎merge ✔︎mergemerge
mergeDeepmergeDeepmergeDeepmergeDeep
mergeDeepInmergeDeepInmergeDeepInmergeDeepIn
mergeDeepWithmergeDeepWithmergeDeepWithmergeDeepWith
mergeInmergeInmergeInmergeIn
mergeWith ✔︎mergeWith ✔︎mergeWithmergeWith
minminminmin
minByminByminByminBy
-pop ✔︎-pop ✔︎
-push ✔︎-push ✔︎
reduce ✔︎reduce ✔︎reduce ✔︎reduce ✔︎
reduceRight ✔︎reduceRight ✔︎reduceRight ✔︎reduceRight ✔︎
rest ✔︎rest ✔︎-rest ✔︎
reverse ✔︎reverse ✔︎-reverse ✔︎
set ✔︎set ✔︎set ✔︎set ✔︎
setIn ✔︎setIn ✔︎setIn ✔︎setIn ✔︎
-setSize-setSize
-shift ✔︎-shift ✔︎
skip ✔︎skip ✔︎-skip ✔︎
skipLast ✔︎skipLast ✔︎-skipLast ✔︎
skipUntil ✔︎skipUntil ✔︎-skipUntil
skipWhile ✔︎skipWhile ✔︎-skipWhile
slice ✔︎slice ✔︎slice ✔︎slice ✔︎
some ✔︎some ✔︎some ✔︎some ✔︎Returns plain boolean
sort ✔︎sort ✔︎sortsort
sortBy ✔︎sortBy ✔︎sortBysortBy
-splice-splice
take ✔︎take ✔︎-take ✔︎
takeLast ✔︎takeLast ✔︎-takeLast ✔︎
takeUntil ✔︎takeUntil ✔︎-takeUntil
takeWhile ✔︎takeWhile ✔︎-takeWhile
toArraytoArraytoArraytoArray
toIndexedSeqtoIndexedSeq--
toJStoJStoJStoJS
toJSONtoJSONtoJSONtoJSON
toKeyedSeqtoKeyedSeq--
toListtoList--
toMaptoMap--
toObjecttoObjecttoObjecttoObject
toOrderedMaptoOrderedMap--
toOrderedSettoOrderedSet--
toSeqtoSeq--
toSettoSet--
toSetSeqtoSetSeq--
toStacktoStack--
-unshift ✔︎-unshift ✔︎
update ✔︎update ✔︎update ✔︎update ✔︎
updateIn ✔︎updateIn ✔︎updateIn ✔︎updateIn ✔︎
valuesvaluesvaluesvalues
valueSeqvalueSeqvalueSeqvalueSeq
withMutationswithMutationswithMutationswithMutations
-zip-zip
-zipWith-zipWith

Unmutable Extra

This package contains optional extra functions for unmutable that don't exist in Immutable.js.

yarn add unmutable-extra

or

npm install unmutable-extra

Functions in this package use partially applied functions, which allow for easy chaining by using them inside of an update() method:

return Wrap([1,2,3])
    .update(pivot()) // using a pivot in a chain
    .map(doOtherStuff)
    .value

API

pivot

pivot() => (UnmutableWrapper)

Takes a collection that is 2 layers deep and flips the contents of each layer, in the same way that you might pivot a spreadsheet to turn rows into columns and vice versa. Works with any combination of Objects, Arrays, Maps and Lists.

import {pivot} from 'unmutable-extra';

return Wrap([
    [1,2,3],
    [4,5,6]
])
    .update(pivot())
    .value;

// Returns:
// [
//     [1,4],
//     [2,5],
//     [3,6]
// ]

return Wrap({
    a: {
        x: 1,
        y: 2
    },
    b: {
        x: 3
    }
})
    .update(pivot())
    .value;

// Returns:
// {
//     x: {
//         a: 1,
//         b: 3
//     },
//     y: {
//         a: 1
//     }
// }
0.13.0

7 years ago

0.12.1

7 years ago

0.12.0

7 years ago