|
@ -22,37 +22,38 @@ class InfiniteListItem { |
|
|
* @memberof InfiniteListItem |
|
|
* @memberof InfiniteListItem |
|
|
*/ |
|
|
*/ |
|
|
constructor(list, value, index) { |
|
|
constructor(list, value, index) { |
|
|
|
|
|
this.__list__ = list; |
|
|
this.value = value; |
|
|
this.value = value; |
|
|
this.index = index; |
|
|
this.index = index; |
|
|
this.next = z => (!z ? list.get(index + 1) : list.get(index + z)); |
|
|
this.next = z => (!z ? this.__list__.get(index + 1) : this.__list__.get(index + z)); |
|
|
this.previous = z => (!z ? list.get(index - 1) : list.get(index - z)); |
|
|
this.previous = z => (!z ? this.__list__.get(index - 1) : this.__list__.get(index - z)); |
|
|
|
|
|
} |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
// Check if Symbol exists
|
|
|
// Check if environment supports Symbol
|
|
|
if (typeof Symbol !== 'undefined' && Symbol.iterator) { |
|
|
if (typeof Symbol !== 'undefined' && Symbol.iterator) { |
|
|
/** |
|
|
/** |
|
|
* ES6 Symbol.iterator |
|
|
* ES6 Symbol.iterator |
|
|
* @returns {Iterable.<InfiniteListItem>} |
|
|
* @returns {Iterable.<InfiniteListItem>} |
|
|
*/ |
|
|
*/ |
|
|
this[Symbol.iterator] = () => ({ |
|
|
InfiniteListItem.prototype[Symbol.iterator] = () => ({ |
|
|
next: () => ({ |
|
|
next: () => ({ |
|
|
value: list.get(index + 1), |
|
|
value: this.__list__.get(index + 1), |
|
|
done: false |
|
|
done: false |
|
|
}) |
|
|
}) |
|
|
}); |
|
|
}); |
|
|
} |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
/** |
|
|
/** |
|
|
* toString method for pretty printing InfiniteListItem instance. |
|
|
* toString method for pretty printing InfiniteListItem instance. |
|
|
* @returns {String} Decycled and beautified string |
|
|
* @returns {String} Decycled and beautified string |
|
|
* @memberof InfiniteListItem |
|
|
* @memberof InfiniteListItem |
|
|
*/ |
|
|
*/ |
|
|
toString() { |
|
|
InfiniteListItem.prototype.toString = function () { |
|
|
return ('InfiniteListItem [ .. ' + |
|
|
return ('InfiniteListItem [ .. ' + |
|
|
stringify(this.value) + |
|
|
stringify(this.value) + |
|
|
' .. ]') |
|
|
' .. ]'); |
|
|
} |
|
|
}; |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
class InfiniteList { |
|
|
class InfiniteList { |
|
|
/** |
|
|
/** |
|
@ -68,9 +69,53 @@ class InfiniteList { |
|
|
*/ |
|
|
*/ |
|
|
constructor(start, next) { |
|
|
constructor(start, next) { |
|
|
|
|
|
|
|
|
// Closure magic!
|
|
|
this.__start__ = start; |
|
|
let cache = []; |
|
|
this.__next__ = next; |
|
|
|
|
|
this.__cache__ = []; |
|
|
|
|
|
|
|
|
|
|
|
if(typeof Proxy !== 'undefined') |
|
|
|
|
|
return new Proxy(this, { |
|
|
|
|
|
get: (obj, key) => { |
|
|
|
|
|
if(key in obj) return obj[key]; |
|
|
|
|
|
const index = ( |
|
|
|
|
|
typeof key === 'string' && /^\d*$/g.test(key) |
|
|
|
|
|
) ? parseInt(key) : undefined; |
|
|
|
|
|
if(index) return obj['get'](index); |
|
|
|
|
|
}, |
|
|
|
|
|
has: (obj, key) => { |
|
|
|
|
|
const index = ( |
|
|
|
|
|
typeof key === 'string' && /^\d*$/g.test(key) |
|
|
|
|
|
) ? parseInt(key) : undefined; |
|
|
|
|
|
return ( |
|
|
|
|
|
(key in obj) || |
|
|
|
|
|
(areNumbers(index) && |
|
|
|
|
|
(index % 1 === 0) && |
|
|
|
|
|
(index >= 0)) |
|
|
|
|
|
) |
|
|
|
|
|
}, |
|
|
|
|
|
enumerate: obj => obj.keys(), |
|
|
|
|
|
ownKeys: obj => obj.keys(), |
|
|
|
|
|
}) |
|
|
|
|
|
} |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
// Check if Symbol exists
|
|
|
|
|
|
if (typeof Symbol !== 'undefined' && Symbol.iterator) { |
|
|
|
|
|
/** |
|
|
|
|
|
* ES6 Symbol.iterator |
|
|
|
|
|
* @returns {Iterable.<InfiniteListItem>} |
|
|
|
|
|
* @memberof InfiniteList |
|
|
|
|
|
*/ |
|
|
|
|
|
InfiniteList.prototype[Symbol.iterator] = function () { |
|
|
let j = 0; |
|
|
let j = 0; |
|
|
|
|
|
return { |
|
|
|
|
|
next: () => ({ |
|
|
|
|
|
value: this.get(j++), |
|
|
|
|
|
done: false |
|
|
|
|
|
}) |
|
|
|
|
|
}; |
|
|
|
|
|
}; |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
/** |
|
|
/** |
|
|
* Get InfiniteListItem at index. |
|
|
* Get InfiniteListItem at index. |
|
@ -78,7 +123,7 @@ class InfiniteList { |
|
|
* @returns {InfiniteListItem} |
|
|
* @returns {InfiniteListItem} |
|
|
* @memberof InfiniteList |
|
|
* @memberof InfiniteList |
|
|
*/ |
|
|
*/ |
|
|
this.get = function (index) { |
|
|
InfiniteList.prototype.get = function (index) { |
|
|
|
|
|
|
|
|
// Validation
|
|
|
// Validation
|
|
|
if ( |
|
|
if ( |
|
@ -87,6 +132,10 @@ class InfiniteList { |
|
|
|| !areNumbers(index) |
|
|
|| !areNumbers(index) |
|
|
) return; |
|
|
) return; |
|
|
|
|
|
|
|
|
|
|
|
const start = this.__start__; |
|
|
|
|
|
const next = this.__next__; |
|
|
|
|
|
const cache = this.__cache__; |
|
|
|
|
|
|
|
|
//TODO: Cache limiting. (Removed for unexpected behaviour)
|
|
|
//TODO: Cache limiting. (Removed for unexpected behaviour)
|
|
|
|
|
|
|
|
|
// Initializing first item if it doesn't exist
|
|
|
// Initializing first item if it doesn't exist
|
|
@ -117,50 +166,9 @@ class InfiniteList { |
|
|
* @returns {undefined} |
|
|
* @returns {undefined} |
|
|
* @memberof InfiniteList |
|
|
* @memberof InfiniteList |
|
|
*/ |
|
|
*/ |
|
|
this.clearCache = () => (cache = [], undefined); |
|
|
InfiniteList.prototype.clearCache = function () { |
|
|
|
|
|
this.__cache__ = []; |
|
|
// Check if Symbol exists
|
|
|
|
|
|
if (typeof Symbol !== 'undefined' && Symbol.iterator) { |
|
|
|
|
|
/** |
|
|
|
|
|
* ES6 Symbol.iterator |
|
|
|
|
|
* @returns {Iterable.<InfiniteListItem>} |
|
|
|
|
|
* @memberof InfiniteList |
|
|
|
|
|
*/ |
|
|
|
|
|
this[Symbol.iterator] = function () { |
|
|
|
|
|
return { |
|
|
|
|
|
next: () => ({ |
|
|
|
|
|
value: this.get(j++), |
|
|
|
|
|
done: false |
|
|
|
|
|
}) |
|
|
|
|
|
}; |
|
|
|
|
|
}; |
|
|
}; |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
if(typeof Proxy !== 'undefined') |
|
|
|
|
|
return new Proxy(this, { |
|
|
|
|
|
get: (obj, key) => { |
|
|
|
|
|
if(key in obj) return obj[key]; |
|
|
|
|
|
const index = ( |
|
|
|
|
|
typeof key === 'string' && /^\d*$/g.test(key) |
|
|
|
|
|
) ? parseInt(key) : undefined; |
|
|
|
|
|
if(index) return obj['get'](index); |
|
|
|
|
|
}, |
|
|
|
|
|
has: (obj, key) => { |
|
|
|
|
|
const index = ( |
|
|
|
|
|
typeof key === 'string' && /^\d*$/g.test(key) |
|
|
|
|
|
) ? parseInt(key) : undefined; |
|
|
|
|
|
return ( |
|
|
|
|
|
(key in obj) || |
|
|
|
|
|
(areNumbers(index) && |
|
|
|
|
|
(index % 1 === 0) && |
|
|
|
|
|
(index >= 0)) |
|
|
|
|
|
) |
|
|
|
|
|
}, |
|
|
|
|
|
enumerate: obj => obj.keys(), |
|
|
|
|
|
ownKeys: obj => obj.keys(), |
|
|
|
|
|
}) |
|
|
|
|
|
} |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
/** |
|
|
/** |
|
|
* Takes a given number of elements from the InfiniteList. |
|
|
* Takes a given number of elements from the InfiniteList. |
|
|