immutable-js
Version:
Immutable types in JavaScript
1,479 lines (1,285 loc) • 42.2 kB
JavaScript
/**
* Copyright (c) 2015, Jan Biasi.
* All rights reserved.
*
* This source code is licensed under the BSD-style license found in the
* LICENSE file in the root directory of this source tree. An additional grant
* of patent rights can be found in the PATENTS file in the same directory.
*/
(function (global, factory) {
typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() :
typeof define === 'function' && define.amd ? define(factory) :
global.Immutable = factory()
}(this, function () { 'use strict';
/**
* IE Array.isArray Polyfill
* developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Array/isArray
*
*/
if(!Array.isArray) {
Array.isArray = function (vArg) {
return Object.prototype.toString.call(vArg) === "[object Array]";
};
}
/**
* ES5 Object.assign Polyfill by MDN
* developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Object/assign
*
* This polyfill doesn't support symbol properties, since ES5
* doesn't have symbols anyway.
*/
if (!Object.assign) {
Object.defineProperty(Object, 'assign', {
enumerable: false,
configurable: true,
writable: true,
value: function(target) {
'use strict';
if (target === undefined || target === null) {
throw new TypeError('Cannot convert first argument to object');
}
var to = Object(target);
for (var i = 1; i < arguments.length; i++) {
var nextSource = arguments[i];
if (nextSource === undefined || nextSource === null) {
continue;
}
nextSource = Object(nextSource);
var keysArray = Object.keys(Object(nextSource));
for (var nextIndex = 0, len = keysArray.length; nextIndex < len; nextIndex++) {
var nextKey = keysArray[nextIndex];
var desc = Object.getOwnPropertyDescriptor(nextSource, nextKey);
if (desc !== undefined && desc.enumerable) {
to[nextKey] = nextSource[nextKey];
}
}
}
return to;
}
});
}
var IS_ITERABLE_FLAG = '@@__IMMUTABLE_ITERABLE__@@';
var IS_KEYED_FLAG = '@@__IMMUTABLE_KEYED__@@';
var IS_INDEXED_FLAG = '@@__IMMUTABLE_INDEXED__@@';
var IS_ORDERED_FLAG = '@@__IMMUTABLE_ORDERED__@@';
var IS_SEQUENCE_FLAG = '@@__IMMUTABLE_SEQUENCE__@@';
var IS_STACK_FLAG = '@@__IMMUTABLE_STACK__@@';
var IS_MAP_FLAG = '@@__IMMUTABLE_MAP__@@';
var IS_LIST_FLAG = '@@__IMMUTABLE_LIST__@@';
var CACHE_FLAG = '@@__CACHE__@@';
function isIterable(maybeIterable) {
return !!(maybeIterable && maybeIterable[IS_ITERABLE_FLAG]);
}
function isKeyed(maybeKeyed) {
return !!(maybeKeyed && maybeKeyed[IS_KEYED_FLAG]);
}
function isIndexed(maybeIndexed) {
return !!(maybeIndexed && maybeIndexed[IS_INDEXED_FLAG]);
}
function isAssociative(maybeAssociative) {
return isKeyed(maybeAssociative) || isIndexed(maybeAssociative);
}
function isOrdered(maybeOrdered) {
return !!(maybeOrdered && maybeOrdered[IS_ORDERED_FLAG]);
}
function Flags__isSequence(maybeSequence) {
return !!(maybeSequence && maybeSequence[IS_SEQUENCE_FLAG]);
}
function isStack(maybeStack) {
return !!(maybeStack && maybeStack[IS_STACK_FLAG]);
}
function isMap(maybeMap) {
return !!(maybeMap && maybeMap[IS_MAP_FLAG]);
}
function isList(maybeList) {
return !!(maybeList && maybeList[IS_LIST_FLAG]);
}
function hasCache(maybeHasCache) {
return !!(maybeHasCache && maybeHasCache[CACHE_FLAG] && maybeHasCache._cache)
}
function is__arrayLike(value) {
return !!(value && typeof value.length === 'number');
}
function nullOrUndefined(value) {
return !!(value === null || value === undefined);
}
/**
* An extension of the "same-value" algorithm as [described for use by ES6 Map
* and Set](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Map#Key_equality)
*
* NaN is considered the same as NaN, however -0 and 0 are considered the same
* value, which is different from the algorithm described by
* [`Object.is`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/is).
*
* This is extended further to allow Objects to describe the values they
* represent, by way of `valueOf` or `equals` (and `hashCode`).
*
* Note: because of this extension, the key equality of Immutable.Map and the
* value equality of Immutable.Set will differ from ES6 Map and Set.
*
*/
function equal(valueA, valueB) {
if (valueA === valueB || (valueA !== valueA && valueB !== valueB)) {
return true;
}
if (!valueA || !valueB) {
return false;
}
if (typeof valueA.valueOf === 'function' &&
typeof valueB.valueOf === 'function') {
valueA = valueA.valueOf();
valueB = valueB.valueOf();
if (valueA === valueB || (valueA !== valueA && valueB !== valueB)) {
return true;
}
if (!valueA || !valueB) {
return false;
}
}
if (typeof valueA.equals === 'function' &&
typeof valueB.equals === 'function' &&
valueA.equals(valueB)) {
return true;
}
return false;
}
var TYPEDEF_FIELD = '__type__';
function toolset__typedef(blueprint, prefered) {
if(typeof blueprint === 'object') {
if(!blueprint.prototype) {
return;
}
for(var scheme in blueprint) {
if(scheme && blueprint.hasOwnProperty(scheme)) {
toolset__typedef(blueprint[scheme], scheme);
}
}
} else if(blueprint && typeof prefered === 'string') {
blueprint.prototype[TYPEDEF_FIELD] = prefered;
}
}
function invariant(condition, error) {
if (!condition) throw new Error(error);
}
/**
* Contributes additional methods to a constructor
*/
function mixin(ctor, funcs) {
var copier = key => { ctor.prototype[key] = funcs[key]; };
Object.keys(funcs).forEach(copier);
Object.getOwnPropertySymbols && Object.getOwnPropertySymbols(funcs).forEach(copier);
return ctor;
}
function createClass(ctor, superClass) {
if (superClass) {
ctor.prototype = Object.create(superClass.prototype);
}
ctor.prototype.constructor = ctor;
}
var ITERABLE_TYPEDEF = '[object Iterable]';
class Iterable {
constructor(value) {
return isIterable(value) ? value : Sequence(value);
}
__toString(head, data, tail) {
if(!data) {
return head + tail;
}
return head + ' ' + data + ' ' + tail;
}
isSequence() {
return (this[TYPEDEF_FIELD] === SEQUENCE_TYPEDEF);
}
toSequence() {
return isIndexed(this) ? this.toIndexedSequence()
: this.toKeyedSequence();
}
updateSize(newSize) {
if(nullOrUndefined(newSize)) {
if(this.getNative()) {
if(typeof this.getNative() === 'object') {
this.size = Object.keys(this.getNative()).length;
} else if(Array.isArray(this.getNative())) {
this.size = this.getNative().length;
}
} else {
this.size = 0;
}
} else if(typeof newSize === 'number') {
this.size = Math.round(newSize);
} else {
throw new TypeError(
'Need a number to set size and not ' + typeof newSize
);
}
}
getNative() {
return this.__internal;
}
map(handle) {
return this.__iterate(handle);
}
wasAltered() {
return this.__altered;
}
asMutable() {
return this.__ownerID ? this : this.__ensureOwner(new OwnerID());
}
asImmutable() {
if(!this.__ensureOwner) { // if implementation missing
throw Error('Can\'t ensure owner to make immutable of ' + this);
}
if(this.__ownerID) {
this.__ownerID = undefined;
this.__altered = false;
this.size = this.__internal.length;
return this;
}
}
isKeyedSequence() {
return (this[TYPEDEF_FIELD] === KEYED_SEQUENCE_TYPEDEF);
}
toKeyedSequence() {
return new KeyedSequence(this.getNative());
}
isIndexedSequence() {
return (this[TYPEDEF_FIELD] === INDEXED_SEQUENCE_TYPEDEF);
}
toIndexedSequence() {
return new IndexedSequence(this.getNative());
}
isSetSequence() {
return (this[TYPEDEF_FIELD] === SET_SEQUENCE_TYPEDEF);
}
toSetSequence() {
return new SetSequence(this.getNative());
}
}
var KEYED_ITERABLE_TYPEDEF = '[Iterable KeyedIterable]';
class KeyedIterable extends Iterable {
constructor(value) {
super(value);
}
}
var INDEXED_ITERABLE_TYPEDEF = '[Iterable IndexedIterable]';
class IndexedIterable extends Iterable {
constructor(value) {
super(value);
}
}
var SET_ITERABLE_TYPEDEF = '[Iterable SetIterable]';
class SetIterable extends Iterable {
constructor(value) {
super(value);
}
}
var IterablePrototype = Iterable.prototype;
IterablePrototype[IS_ITERABLE_FLAG] = true;
var KeyedIterablePrototype = KeyedIterable.prototype;
KeyedIterablePrototype[IS_KEYED_FLAG] = true;
var IndexedIterablePrototype = IndexedIterable.prototype;
IndexedIterablePrototype[IS_INDEXED_FLAG] = true;
function quoteString(value) {
return typeof value === 'string' ? JSON.stringify(value) : value;
}
toolset__typedef({
Iterable: ITERABLE_TYPEDEF,
KeyedIterable: KEYED_ITERABLE_TYPEDEF,
IndexedIterable: INDEXED_ITERABLE_TYPEDEF
});
Iterable.isIterable = isIterable;
Iterable.isKeyed = isKeyed;
Iterable.isIndexed = isIndexed;
Iterable.isAssociative = isAssociative;
Iterable.isOrdered = isOrdered;
Iterable.Keyed = KeyedIterable;
Iterable.Indexed = IndexedIterable;
Iterable.Set = SetIterable;
var COLLECTION_TYPEDEF = '[Iterable Collection]';
class Collection extends Iterable {
constructor() {
throw TypeError('Abstract');
}
}
var KEYED_COLLECTION_TYPEDEF = '[KeyedIterable KeyedCollection]';
class KeyedCollection extends KeyedIterable {}
var INDEXED_COLLECTION_TYPEDEF = '[IndexedIterable IndexedCollection]';
class IndexedCollection extends IndexedIterable {}
var SET_COLLECTION_TYPEDEF = '[SetIterable SetCollection]';
class SetCollection extends SetIterable {}
toolset__typedef({
Collection: COLLECTION_TYPEDEF,
KeyedCollection: KEYED_COLLECTION_TYPEDEF,
IndexedCollection: INDEXED_COLLECTION_TYPEDEF,
SetCollection: SET_COLLECTION_TYPEDEF
});
Collection.Keyed = KeyedCollection;
Collection.Indexed = IndexedCollection;
Collection.Set = SetCollection;
function clone(item) {
if (!item) {
// null, undefined values check
return item;
}
var types = [Number, String, Boolean],
result;
// normalizing primitives if someone did new String('aaa'), or new Number('444');
types.forEach(function(type) {
if (item instanceof type) {
result = type(item);
}
});
if (typeof result === 'undefined') {
if (Object.prototype.toString.call(item) === '[object Array]') {
result = [];
item.forEach(function(child, index, array) {
result[index] = clone(child);
});
} else if (typeof item === 'object') {
// testing that this is DOM
if (item.nodeType && typeof item.cloneNode === 'function') {
result = item.cloneNode(true);
} else if (!item.prototype) { // check that this is a literal
if (item instanceof Date) {
result = new Date(item);
} else {
// it is an object literal
result = {};
for (var i in item) {
if(item.hasOwnProperty(i)) {
result[i] = clone(item[i]);
}
}
}
} else {
// depending what you would like here,
// just keep the reference, or create new object
if (false && item.constructor) {
result = Object.create(item.prototype);
} else {
result = item;
}
}
} else {
result = item;
}
}
return result;
}
var IS_NATIVE_FLAG = '@@__IS_NATIVE__@@';
function isNative(maybeNative) {
return !!(maybeNative && maybeNative[IS_NATIVE_FLAG]);
}
var NATIVE_COLLECTION_TYPEDEF = '[native Collection]'
class NativeCollection {
constructor() {
var args = Array.prototype.slice.call(arguments);
if(args.length > 1) {
let array = new NativeArray();
array.__initialSize = args.length;
args.forEach(v => array.push(v));
return array;
} else if(args.length === 1) {
var single = args[0];
if(Array.isArray(single)) {
let array = new NativeArray();
single.forEach(v => array.push(v));
array.__initialSize = single.length || 0;
return array;
} else if(typeof single === 'object') {
let object = new NativeObject();
object.__initialSize = Object.keys(single).length;
return object.extend(single);
}
} else {
return new NativeObject();
}
}
toString() {
return NATIVE_COLLECTION_TYPEDEF;
}
}
var NATIVE_ARRAY_TYPEDEF = '[native Array]';
class NativeArray extends Array {
constructor() {
super(0);
}
toString() {
return NATIVE_ARRAY_TYPEDEF;
}
toNative() {
return this;
}
isNativeArray(maybeNativeArray) {
return maybeNativeArray && maybeNativeArray.toString &&
maybeNativeArray.toString() === NATIVE_ARRAY_TYPEDEF;
}
__clone() {
return this.slice();
}
}
var NATIVE_OBJECT_TYPEDEF = '[native Object]';
class NativeObject extends Object {
constructor() {
super(null);
}
__clone() {
return clone(this);
}
extend(source) {
var object = Object.assign(new NativeObject(), source);
return object;
}
toString() {
return NATIVE_OBJECT_TYPEDEF;
}
isNativeObject(maybeNativeObject) {
return maybeNativeObject && maybeNativeObject.toString &&
maybeNativeObject.toString() === NATIVE_OBJECT_TYPEDEF;
}
}
NativeCollection.prototype[IS_NATIVE_FLAG] = true;
NativeObject.prototype[IS_NATIVE_FLAG] = true;
NativeArray.prototype[IS_NATIVE_FLAG] = true;
/**
* RFC4122 version 4 compliant solution that solves that issue by offsetting
* the first 13 hex numbers by a hex portion of the timestamp.
*/
function guid() {
var d = new Date().getTime();
var uuid = 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function(c) {
var r = (d + Math.random()*16)%16 | 0;
d = Math.floor(d/16);
return (c === 'x' ? r : (r&0x3|0x8)).toString(16);
});
return uuid;
}
var OWNER_TYPEDEF = '[OwnerID]';
class OwnerID {
constructor() {
this.__key__ = guid();
}
toString() {
return '[OwnerID ' + this.__toString() + ']';
}
__toString() {
return this.__key__;
}
}
toolset__typedef(OwnerID, OWNER_TYPEDEF);
var STACK_TYPEDEF = '[IndexedCollection Stack]';
class Stack extends IndexedCollection {
constructor() {
var args = Array.prototype.slice.call(arguments);
if(nullOrUndefined(args)) {
return emptyStack();
} else if(args.length === 1) {
let singleArg = args[0];
if(Array.isArray(singleArg)) {
return makeStack(singleArg);
} else if(typeof singleArg === 'object') {
return makeStack(objectToArray(singleArg));
}
} else if(args.length > 1) {
return makeStack(args);
}
}
static of(...values) {
return new Stack(values);
}
push(...values) {
if(this.__ownerID) {
values.forEach(v => this.__internal.push(v));
this.size = this.__internal.length;
this.__altered = true;
return this;
}
return new Stack(
this.__internal.__clone().concat(
Array.prototype.slice.call(arguments)
)
);
}
shift() {
if(this.__ownerID) {
this.__internal.pop();
this.size = this.__internal.length;
this.__altered = true;
return this;
}
var cloned = this.__internal.__clone();
var newSize = cloned.pop();
return new Stack(cloned);
}
clear() {
if(this.size === 0) {
return this;
}
if(this.__ownerID) {
this.size = 0;
this.__altered = true;
return this.toStack();
}
return emptyStack();
}
toString() {
return this.__toString('Stack [', this.__internal.join(',') ,']');
}
toStack() {
return this;
}
__ensureOwner(ownerID) {
if(ownerID === this.__ownerID) {
return this;
}
if(!ownerID || nullOrUndefined(ownerID)) {
this.__ownerID = ownerID;
this.__altered = false;
return this;
}
return makeStack(this.__internal, ownerID);
}
__iterate(handle, reverse) {
var maxLength = this.size;
for(var n = 0; n <= maxLength; n++) {
let entry = this.__internal[reverse ? maxLength - n : n];
if(handle(entry, n, this) === false) {
return n + 1;
}
}
return n;
}
}
toolset__typedef(Stack, STACK_TYPEDEF);
Stack.prototype[IS_STACK_FLAG] = true;
var EMPTY_STACK;
function emptyStack() {
return EMPTY_STACK || (EMPTY_STACK = makeStack());
}
function makeStack(array, ownerID) {
var stack = Object.create(Stack.prototype);
stack.__ownerID = ownerID;
stack.__altered = false;
if(isNative(array)) {
stack.__internal = array.toNative();
} else {
stack.__internal = new NativeArray();
if(Array.isArray(array)) {
array.forEach(v => stack.__internal.push(v));
stack.size = array.length;
}
}
return stack;
}
function objectToArray(object) {
var stack = new NativeArray();
if(object && typeof object === 'object') {
for(var key in object) {
if(object[key] && object.hasOwnProperty(key)) {
if(typeof object[key] === 'object') {
stack.push(objectToArray(object[key]));
} else if(!nullOrUndefined(object[key])) {
stack.push(object[key]);
}
}
}
} else {
throw TypeError(
'Object to array conversion needs object ' +
'and not ' + typeof object
);
}
return stack;
}
var LIST_TYPEDEF = '[IndexedCollection List]';
class List extends IndexedCollection {
constructor(value) {
return arguments.length > 1 ? makeList(
Array.prototype.slice.call(arguments)
) : makeList(value);
}
static of (...values) {
return this(values);
}
toString() {
return this.__toString('List [', this.__internal.join(',') ,']');
}
push(...values) {
if(this.__ownerID) {
values.forEach(v => this.__internal.push(v));
this.size = this.__internal.length;
this.__altered = true;
return this;
}
return makeList(this.__internal.__clone().concat(values));
}
shift() {
if(this.__ownerID) {
this.__internal.pop();
this.size = this.__internal.length;
this.__altered = true;
return this;
}
var cloned = this.__internal.__clone();
var newSize = cloned.pop();
return new List(cloned);
}
clean() {
if(this.size === 0) {
return this;
}
if(this.__ownerID) {
this.__altered = true;
this.__internal = new NativeArray();
this.size = this.__internal.length;
return this;
}
return emptyList();
}
__iterator(handle, reverse) {
}
__ensureOwner(ownerID) {
if(ownerID === this.__ownerID) {
return this;
}
if(!ownerID || nullOrUndefined(ownerID)) {
this.__ownerID = ownerID;
this.__altered = false;
return this;
}
return makeList(this.__internal, ownerID);
}
}
var EMPTY_LIST;
function emptyList() {
return EMPTY_LIST || (EMPTY_LIST = makeList(null));
}
function makeList(values, ownerID) {
var list = Object.create(List.prototype);
list.__ownerID = ownerID;
list.__altered = false;
list.__internal = new NativeArray();
list.size = 0;
if(nullOrUndefined(values)) {
return list;
} else if(isNative(values)) {
list.__internal = values;
} else if (Array.isArray(values)) {
list.__internal = new NativeArray();
values.forEach((value, index) => {
list.__internal.push(value);
});
list.size = list.__internal.length;
} else {
throw TypeError(
'Expected an array or values as input and not ' +
typeof values
);
}
return list;
}
toolset__typedef({
List: LIST_TYPEDEF
});
List.prototype[IS_LIST_FLAG] = true;
List.isList = isList;
var MAP_TYPEDEF = '[KeyedCollection Map]';
class src_Map__Map extends KeyedCollection {
constructor(value) {
return value ? makeMap(value) : emptyMap();
}
has(key) {
if(key && !nullOrUndefined(this.__internal[key])) {
if(this.__internal.hasOwnProperty(key)) {
return true;
}
}
return false;
}
get(key, notSetValue) {
if(key && this.has(key)) {
return this.__internal[key];
}
return notSetValue;
}
set(key, value) {
if(this.__ownerID) {
this.__internal[key] = value;
this.__altered = true;
return this;
}
var updated = this.__internal.__clone();
updated[key] = value;
return makeMap(updated, null);
}
remove(key) {
if(!key || !this.has(key)) {
return this;
}
if(this.__ownerID) {
delete this.__internal[key];
this.size = this.size--;
this.__altered = true;
return this;
}
var copied = this.__internal.__clone();
delete copied[key];
return makeMap(copied);
}
clear() {
if(this.size === 0) {
return this;
}
if(this.__ownerID) {
this.size = 0;
this.__altered = true;
this.__internal = new NativeObject();
return this;
}
return makeMap(new NativeObject(null));
}
__iterate(handle, reverse) {
var object = this.__internal;
var keys = this.__keys || Object.keys(object);
var maxIndex = keys.length - 1;
for(var n = 0; n <= maxIndex; n++) {
let key = keys[reverse ? maxIndex - n: n];
if(handle(object[key], key, this) === false) {
return n + 1;
}
}
return n;
}
wasAltered() {
return this.__altered;
}
toString() {
return this.__toString('Map {',
Object.keys(this.__internal).map((v, index) => {
return typeof this.__internal[v] === 'string' ?
JSON.stringify(this.__internal[v]) :
this.__internal[v];
}),'}');
}
toMap() {
return this;
}
}
var EMPTY_MAP;
function emptyMap() {
return EMPTY_MAP || (EMPTY_MAP = makeMap());
}
function makeMap(init, ownerID) {
var map = Object.create(src_Map__Map.prototype);
map.__internal = new NativeObject();
map.__ownerID = ownerID;
map.__altered = false;
if(init && (isNative(init) || (typeof init === 'object'))) {
map.__internal = map.__internal.extend(init);
}
map.size = Object.keys(map.__internal).length;
return map;
}
toolset__typedef({
Map: MAP_TYPEDEF
});
src_Map__Map.prototype[IS_MAP_FLAG] = true;
src_Map__Map.isMap = isMap;
var SEQUENCE_TYPEDEF = '[Iterable ImmutableSequence]';
class Sequence extends Iterable {
constructor(value) {
if(value === null || value === undefined) {
return emptySequence();
} else if(isIterable(value)) {
return value.toSequence();
} else {
return sequenceFromValue(value);
}
throw new Error(
'Couldn\'t create an immutable-sequence of: ' + value
);
}
static of(...value) {
return Sequence(value);
}
toSequence() {
return this;
}
cacheResult() {
if (!this._cache) {
this._cache = 'this.entrySeq().toArray()';
//this.size = this._cache.length;
}
return this;
}
toString() {
return this.__toString('Sequence [', null, ']');
}
}
var INDEXED_SEQUENCE_TYPEDEF = '[Sequence IndexedSequence]';
class IndexedSequence extends Sequence {
constructor(value) {
if(nullOrUndefined(value)) {
return emptySequence();
} else if(!isIterable(value)) {
return indexedSequenceFromData(value);
} else if(isKeyed(value)) {
return value.entrySequence();
} else {
return value.toIndexedSequence();
}
throw new Error(
'Couldn\'t create an indexed-sequence of: ' + value
);
}
static of(sequence) {
return IndexedSequence(sequence);
}
toIndexedSequence() {
return this;
}
toString() {
return this.__toString(INDEXED_SEQUENCE_TYPEDEF)
}
__iterate() {
console.log('Iterate on IterableSequence');
}
}
var ARRAY_SEQUENCE_TYPEDEF = '[IndexedSequence ArraySequence]';
class ArraySequence extends IndexedSequence {
constructor(array) {
this.__internal = array;
this.size = array.length;
}
__iterate(handle, reverse) {
var array = this.__internal;
var maxIndex = array.length - 1;
for(var n = 0; n <= maxIndex; n++) {
let findex = reverse ? maxIndex - n : n;
if(handle(array[findex], n, this) === false) {
return n + 1;
}
}
return n;
}
static of(array) {
return new ArraySequence(array);
}
toArraySequence() {
return this;
}
}
var KEYED_SEQUENCE_TYPEDEF = '[Sequence KeyedSequence]';
class KeyedSequence extends Sequence {
constructor(obj) {
}
toKeyedSequence() {
return this;
}
}
var OBJECT_SEQUENCE_TYPEDEF = '[KeyedSequence ObjectSequence]';
class ObjectSequence extends KeyedSequence {
constructor(object) {
var keys = Object.keys(object);
this.__object = object;
this.__keys = keys;
this.size = keys.length;
}
__iterate(handle, reverse) {
var object = this.__object;
var keys = this.__keys;
var maxIndex = keys.length - 1;
for(var n = 0; n <= maxIndex; n++) {
let key = keys[reverse ? maxIndex - n: n];
if(handle(object[key], key, this) === false) {
return n + 1;
}
}
return n;
}
static of(object) {
return new ObjectSequence(object);
}
toObjectSequence() {
return this;
}
has(key) {
return this._object.hasOwnProperty(key);
}
keys() {
return this.__keys;
}
values() {
var results = [];
this.keys().map(val => results.push(val));
return results;
}
}
var SET_SEQUENCE_TYPEDEF = '[ArraySequence SetSequence]';
class SetSequence extends ArraySequence {
constructor(value) {
if(nullOrUndefined(value)) {
/* If no value is given, return an empty sequence */
return emptySequence().toSetSequence();
} else if(!isIterable(value)) {
/* If not is iterable, return a index sequence */
return indexedSequenceFromData(value).toSetSequence();
} else if(isKeyed(value)) {
/* If has keys, get the raw sequence */
return value.entrySequence().toSetSequence();
} else {
return emptySequence(value);
}
throw new Error(
'Couldn\'t create a set-sequence of: ' + value
);
}
toSetSequence() {
return this;
}
}
ObjectSequence.prototype[IS_ORDERED_FLAG] = true;
var EMPTY_SEQUENCE;
function emptySequence() {
return EMPTY_SEQUENCE || (EMPTY_SEQUENCE = new ArraySequence([]));
}
function maybeIndexedSequenceFromData(value) {
return(
is__arrayLike(value) ? new ArraySequence(value) :
isIterable(value) ? new IndexedSequence(value) :
undefined
);
}
function keyedSequenceFromData(value) {
var seq = Array.isArray(value) ? new ArraySequence(value) :
typeof value === 'object' ? new ObjectSequence(value) :
undefined;
if(!seq) {
throw new TypeError(
'Expected Array or iterable obejct of [k, v] entries, ' +
'or keyed object: ' + value
);
}
return seq;
}
function indexedSequenceFromData(value) {
var seq = maybeIndexedSequenceFromData(value);
if(!seq) {
throw new TypeError(
'Expected Array-like or iterable object of values: ' + value
);
}
return seq;
}
function sequenceFromValue(value) {
var seq = (typeof value === 'object' && new ObjectSequence(value)) ||
maybeIndexedSequenceFromData(value);
if(!seq) {
throw new TypeError(
'Expected Array or iterable object of values, ' +
'or keyed objects: ' + value
);
}
return seq;
}
toolset__typedef({
Sequence: SEQUENCE_TYPEDEF,
ArraySequence: ARRAY_SEQUENCE_TYPEDEF,
IndexedSequence: INDEXED_SEQUENCE_TYPEDEF,
KeyedSequence: KEYED_SEQUENCE_TYPEDEF,
ObjectSequence: OBJECT_SEQUENCE_TYPEDEF,
SetSequence: SET_SEQUENCE_TYPEDEF
});
Sequence.Object = ObjectSequence;
Sequence.Indexed = IndexedSequence;
Sequence.Keyed = KeyedSequence;
Sequence.Array = ArraySequence;
Sequence.Set = SetSequence;
Sequence.isSequence = Flags__isSequence;
Sequence.prototype[IS_SEQUENCE_FLAG] = true;
function fromJS(native, converter) {
return converter ?
fromJSWith(converter, native, '', {'': native}) :
fromJSDefault(native);
}
function fromJSWith(converter, native, key, parent) {
if(Array.isArray(native)) {
return converter.call(parent, key, IndexedSequence(native).map((v, k) => {
fromJSWith(converter, v, k, native);
}));
} else if(maybePlainObject(native)) {
return converter.call(parent, key, KeyedSequence(native).map((v, k) => {
fromJSWith(converter, v, k, native);
}));
}
}
function fromJSDefault(json) {
if(Array.isArray(json)) {
return IndexedSequence(json);
}
if(maybePlainObject(json)) {
return KeyedSequence(json);
}
}
function maybePlainObject(value) {
return value && (value.constructor === Object || value.constructor === undefined);
}
var SET_TYPEDEF = '[SetCollection Set]';
class src_Set__Set extends SetCollection {
constructor(object) {
return makeSet(object);
}
toSet() {
return this;
}
toString() {
return this.__toString('Set {', this.__keys.join(','), '}');
}
set(key) {
var copy = this.__internal.__clone();
copy[key] = true;
console.log(copy);
return new src_Set__Set(
);
}
unset(key) {
var reduc = delete this.__internal.clone()[key];
return new src_Set__Set(reduc);
}
__iterate(handle, reverse) {
var object = this.__internal;
var keys = this.__keys;
var maxIndex = keys.length - 1;
for(var n = 0; n <= maxIndex; n++) {
let key = keys[reverse ? maxIndex - n: n];
if(handle(object[key], key, this) === false) {
return n + 1;
}
}
return n;
}
}
var EMPTY_SET;
function emptySet() {
return EMPTY_SET || (EMPTY_SET = makeSet());
}
function makeSet(map, ownerID) {
var set = Object.create(src_Set__Set.prototype);
set.__internal = new NativeObject();
set.__ownerID = ownerID;
if(map && isNative(map)) {
set.__internal = map;
} else if(map && typeof map === 'object') {
set.__internal = set.__internal.extend(map);
}
set.__keys = Object.keys(set.__internal);
set.size = set.__keys.length;
return set;
}
var RECORD_TYPEDEF = '[KeyedCollection Record]';
class Record extends KeyedCollection {
constructor(defaultValues, name) {
var init;
var RecordType = function Record(values) {
if(values instanceof RecordType) {
return values;
}
if(!(this instanceof RecordType)) {
return new RecordType(values);
}
if(!init) {
init = true;
var keys = Object.keys(defaultValues);
setProps(RecordTypePrototype, keys);
RecordTypePrototype.size = keys.length || 0;
RecordTypePrototype.name = name;
RecordTypePrototype.__keys = keys;
RecordTypePrototype.__defaultValues = defaultValues;
}
RecordTypePrototype.__internal = new src_Map__Map();
return RecordTypePrototype;
}
var RecordTypePrototype = RecordType.prototype = Object.create(Record.prototype);
RecordTypePrototype.constructor = RecordType;
return RecordType;
}
toString() {
return this.__toString(recordName(this) + '{', this.__keys.join(','), '}');
}
toMap() {
return makeMap(this.__internal, this.__ownerID);
}
has(key) {
return this.__defaultValues.hasOwnProperty(key);
}
get(key, notSetValue) {
if(!this.has(key)) {
return notSetValue;
}
var defval = this.__defaultValues[key];
return this.__internal ? this.__internal.get(key, defval) : defval;
}
set(key, value) {
if(!this.has(key)) {
throw new Error('Can\'t set unknown key "' + key + '" on ' + recordName(this));
}
var newMap = this.__internal && this.__internal.set(key, value);
if(this.__ownerID || newMap === this.__internal) {
return this;
}
return makeRecord(this, newMap);
}
remove(key) {
if (!this.has(key)) {
return this;
}
var newMap = this._map && this.__internal.remove(key);
if (this.__ownerID || newMap === this.__internal) {
return this;
}
return makeRecord(this, newMap);
}
clear() {
if(this.__ownerID) {
this.__internal && this.__internal.clear();
return this;
}
var RecordType = this.constructor;
return RecordType.__empty || (RecordType.__empty = makeRecord(this, emptyMap()))
}
wasAltered() {
return this.__internal.wasAltered();
}
__ensureOwner(ownerID) {
if(ownerID === this.__ownerID) {
return this;
}
if(!ownerID || nullOrUndefined(ownerID)) {
this.__ownerID = ownerID;
this.__altered = false;
return this;
}
return makeRecord(this, this.__internal, ownerID);
}
}
function makeRecord(recordType, map, ownerID) {
var record = Object.create(Object.getPrototypeOf(recordType));
record.__internal = map;
record.__ownerID = ownerID;
return record;
}
function recordName(record) {
return record._name || record.constructor.name || 'Record';
}
function setProp(prototype, name) {
Object.defineProperty(prototype, name, {
get: function() {
return this.get(name);
},
set: function(value) {
invariant(this.__ownerID, 'Can\'t call set on an immutable record.');
this.set(name, value);
}
});
}
function setProps(prototype, names) {
try {
names.forEach(setProp.bind(undefined, prototype));
} catch (error) {
// Maybe IE8.
}
}
toolset__typedef({
Record: RECORD_TYPEDEF
});
class Range extends IndexedSequence {
constructor(start, end, step) {
if(!(this instanceof Range)) {
return new Range(start, end, step);
}
invariant(step !== 0, 'Can\'t create a range with steps by 0');
start = start || 0;
if(end === undefined) {
end = Infinity;
}
step = step === undefined ? 1 : Math.abs(step); // Absolute value of number
if(end < start) {
step = -step;
}
this.__start = start;
this.__end = end;
this.__step = step;
this.size = Math.max(0, Math.ceil((end - start) / step - 1) + 1);
if(this.size === 0) {
if(EMPTY_RANGE) {
return EMPTY_RANGE;
}
EMPTY_RANGE = this;
}
}
}
var EMPTY_RANGE;
class Repeat extends Sequence {
constructor(value, repeater) {
if(!(this instanceof Repeat)) {
return new Repeat(value, repeater);
}
this.__value = value;
this.size = repeater === undefined ? Infinity : Math.max(0, repeater);
if(this.size === 0) {
if(EMPTY_REPEAT) {
return EMPTY_REPEAT;
}
EMPTY_REPEAT = this;
}
}
toString() {
return this.__toString('Repeat [', this.__value + ' ' + this.size + ' times', ']');
}
includes(search) {
return equal(this.__value, search);
}
indexOf(search) {
if(this.includes(search)) {
return 0;
}
return -1;
}
__iterate(handle) {
for(var ii = 0; ii < this.size; ii++) {
if(handle(this.__value, ii, this) === false) {
return ii + 1;
}
}
return ii;
}
__ensureOwner(ownerID) {
if(ownerID === this.__ownerID) {
return this;
}
if(!ownerID || nullOrUndefined(ownerID)) {
this.__ownerID = ownerID;
this.__altered = false;
return this;
}
return new Repeat(this.__value, this.size, ownerID);
}
}
var EMPTY_REPEAT;
// Polyfills for ES5 and older Browsers
var Immutable = {
Sequence: Sequence,
Iterable: Iterable,
Collection: Collection,
List: List,
Map: src_Map__Map,
Native: NativeCollection,
Set: src_Set__Set,
Stack: Stack,
Range: Range,
Record: Record,
Repeat: Repeat,
fromJS: fromJS
}
return Immutable;
}));