UNPKG

immutable-js

Version:
153 lines (138 loc) 4.3 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 { IndexedCollection } from './Collection'; import { IS_STACK_FLAG, isStack } from './Flags'; import { nullOrUndefined } from './util/is'; import { NativeObject, NativeArray, isNative } from './Native'; import { OwnerID } from './Owner'; import { typedef as defineTypeOf } from './util/toolset'; export var STACK_TYPEDEF = '[IndexedCollection Stack]'; export 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; } } defineTypeOf(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; }