UNPKG

immutable-js

Version:
263 lines (227 loc) 6.99 kB
/** * 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, isSequence, hasCache, IS_ITERABLE_FLAG, IS_KEYED_FLAG, IS_INDEXED_FLAG, IS_ORDERED_FLAG, IS_SEQUENCE_FLAG } from './Flags'; import { arrayLike as isArrayLike, nullOrUndefined } from './util/is'; import { Iterable } from './Iterable'; import { typedef as defineTypeOf } from './util/toolset'; export var SEQUENCE_TYPEDEF = '[Iterable ImmutableSequence]'; export 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, ']'); } } export var INDEXED_SEQUENCE_TYPEDEF = '[Sequence IndexedSequence]'; export 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'); } } export var ARRAY_SEQUENCE_TYPEDEF = '[IndexedSequence ArraySequence]'; export 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; } } export var KEYED_SEQUENCE_TYPEDEF = '[Sequence KeyedSequence]'; export class KeyedSequence extends Sequence { constructor(obj) { } toKeyedSequence() { return this; } } export var OBJECT_SEQUENCE_TYPEDEF = '[KeyedSequence ObjectSequence]'; export 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; } } export var SET_SEQUENCE_TYPEDEF = '[ArraySequence SetSequence]'; export 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( isArrayLike(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; } defineTypeOf({ 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 = isSequence; Sequence.prototype[IS_SEQUENCE_FLAG] = true;