immutable-js
Version:
Immutable types in JavaScript
179 lines (147 loc) • 4.88 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.
*/
import {
isIterable, isKeyed, isIndexed, isAssociative, isOrdered,
IS_ITERABLE_FLAG, IS_KEYED_FLAG, IS_INDEXED_FLAG, IS_ORDERED_FLAG,
} from './Flags';
import { STACK_TYPEDEF } from './Stack';
import { LIST_TYPEDEF } from './List';
import { MAP_TYPEDEF } from './Map';
import {
COLLECTION_TYPEDEF, KEYED_COLLECTION_TYPEDEF,
INDEXED_COLLECTION_TYPEDEF, SET_COLLECTION_TYPEDEF
} from './Collection';
import {
SEQUENCE_TYPEDEF, SET_SEQUENCE_TYPEDEF, OBJECT_SEQUENCE_TYPEDEF,
KEYED_SEQUENCE_TYPEDEF, INDEXED_SEQUENCE_TYPEDEF, ARRAY_SEQUENCE_TYPEDEF
} from './Sequence';
import { Sequence, KeyedSequence, IndexedSequence, SetSequence } from './Sequence';
import { OwnerID } from './Owner';
import { nullOrUndefined } from './util/is';
import { typedef as defineTypeOf, TYPEDEF_FIELD } from './util/toolset';
import { fromJS } from './util/fromJS';
export var ITERABLE_TYPEDEF = '[object Iterable]';
export 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());
}
}
export var KEYED_ITERABLE_TYPEDEF = '[Iterable KeyedIterable]';
export class KeyedIterable extends Iterable {
constructor(value) {
super(value);
}
}
export var INDEXED_ITERABLE_TYPEDEF = '[Iterable IndexedIterable]';
export class IndexedIterable extends Iterable {
constructor(value) {
super(value);
}
}
export var SET_ITERABLE_TYPEDEF = '[Iterable SetIterable]';
export class SetIterable extends Iterable {
constructor(value) {
super(value);
}
}
export var IterablePrototype = Iterable.prototype;
IterablePrototype[IS_ITERABLE_FLAG] = true;
export var KeyedIterablePrototype = KeyedIterable.prototype;
KeyedIterablePrototype[IS_KEYED_FLAG] = true;
export var IndexedIterablePrototype = IndexedIterable.prototype;
IndexedIterablePrototype[IS_INDEXED_FLAG] = true;
function quoteString(value) {
return typeof value === 'string' ? JSON.stringify(value) : value;
}
defineTypeOf({
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;