You can not select more than 25 topics
			Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
		
		
		
		
			
				
					89 lines
				
				2.2 KiB
			
		
		
			
		
	
	
					89 lines
				
				2.2 KiB
			| 
								 
											4 years ago
										 
									 | 
							
								
							 | 
						||
| 
								 | 
							
								module.exports = ProtoList
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								function setProto(obj, proto) {
							 | 
						||
| 
								 | 
							
								  if (typeof Object.setPrototypeOf === "function")
							 | 
						||
| 
								 | 
							
								    return Object.setPrototypeOf(obj, proto)
							 | 
						||
| 
								 | 
							
								  else
							 | 
						||
| 
								 | 
							
								    obj.__proto__ = proto
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								function ProtoList () {
							 | 
						||
| 
								 | 
							
								  this.list = []
							 | 
						||
| 
								 | 
							
								  var root = null
							 | 
						||
| 
								 | 
							
								  Object.defineProperty(this, 'root', {
							 | 
						||
| 
								 | 
							
								    get: function () { return root },
							 | 
						||
| 
								 | 
							
								    set: function (r) {
							 | 
						||
| 
								 | 
							
								      root = r
							 | 
						||
| 
								 | 
							
								      if (this.list.length) {
							 | 
						||
| 
								 | 
							
								        setProto(this.list[this.list.length - 1], r)
							 | 
						||
| 
								 | 
							
								      }
							 | 
						||
| 
								 | 
							
								    },
							 | 
						||
| 
								 | 
							
								    enumerable: true,
							 | 
						||
| 
								 | 
							
								    configurable: true
							 | 
						||
| 
								 | 
							
								  })
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								ProtoList.prototype =
							 | 
						||
| 
								 | 
							
								  { get length () { return this.list.length }
							 | 
						||
| 
								 | 
							
								  , get keys () {
							 | 
						||
| 
								 | 
							
								      var k = []
							 | 
						||
| 
								 | 
							
								      for (var i in this.list[0]) k.push(i)
							 | 
						||
| 
								 | 
							
								      return k
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								  , get snapshot () {
							 | 
						||
| 
								 | 
							
								      var o = {}
							 | 
						||
| 
								 | 
							
								      this.keys.forEach(function (k) { o[k] = this.get(k) }, this)
							 | 
						||
| 
								 | 
							
								      return o
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								  , get store () {
							 | 
						||
| 
								 | 
							
								      return this.list[0]
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								  , push : function (obj) {
							 | 
						||
| 
								 | 
							
								      if (typeof obj !== "object") obj = {valueOf:obj}
							 | 
						||
| 
								 | 
							
								      if (this.list.length >= 1) {
							 | 
						||
| 
								 | 
							
								        setProto(this.list[this.list.length - 1], obj)
							 | 
						||
| 
								 | 
							
								      }
							 | 
						||
| 
								 | 
							
								      setProto(obj, this.root)
							 | 
						||
| 
								 | 
							
								      return this.list.push(obj)
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								  , pop : function () {
							 | 
						||
| 
								 | 
							
								      if (this.list.length >= 2) {
							 | 
						||
| 
								 | 
							
								        setProto(this.list[this.list.length - 2], this.root)
							 | 
						||
| 
								 | 
							
								      }
							 | 
						||
| 
								 | 
							
								      return this.list.pop()
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								  , unshift : function (obj) {
							 | 
						||
| 
								 | 
							
								      setProto(obj, this.list[0] || this.root)
							 | 
						||
| 
								 | 
							
								      return this.list.unshift(obj)
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								  , shift : function () {
							 | 
						||
| 
								 | 
							
								      if (this.list.length === 1) {
							 | 
						||
| 
								 | 
							
								        setProto(this.list[0], this.root)
							 | 
						||
| 
								 | 
							
								      }
							 | 
						||
| 
								 | 
							
								      return this.list.shift()
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								  , get : function (key) {
							 | 
						||
| 
								 | 
							
								      return this.list[0][key]
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								  , set : function (key, val, save) {
							 | 
						||
| 
								 | 
							
								      if (!this.length) this.push({})
							 | 
						||
| 
								 | 
							
								      if (save && this.list[0].hasOwnProperty(key)) this.push({})
							 | 
						||
| 
								 | 
							
								      return this.list[0][key] = val
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								  , forEach : function (fn, thisp) {
							 | 
						||
| 
								 | 
							
								      for (var key in this.list[0]) fn.call(thisp, key, this.list[0][key])
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								  , slice : function () {
							 | 
						||
| 
								 | 
							
								      return this.list.slice.apply(this.list, arguments)
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								  , splice : function () {
							 | 
						||
| 
								 | 
							
								      // handle injections
							 | 
						||
| 
								 | 
							
								      var ret = this.list.splice.apply(this.list, arguments)
							 | 
						||
| 
								 | 
							
								      for (var i = 0, l = this.list.length; i < l; i++) {
							 | 
						||
| 
								 | 
							
								        setProto(this.list[i], this.list[i + 1] || this.root)
							 | 
						||
| 
								 | 
							
								      }
							 | 
						||
| 
								 | 
							
								      return ret
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								  }
							 |