New Research: Supply Chain Attack on Axios Pulls Malicious Dependency from npm.Details →
Socket
Book a DemoSign in
Socket

@augu/immutable

Package Overview
Dependencies
Maintainers
1
Versions
32
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@augu/immutable - npm Package Compare versions

Comparing version
0.5.0
to
0.6.0
+384
build//Collection.js
"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
const errors_1 = require("./util/errors");
const isObject_1 = __importDefault(require("./util/isObject"));
const getKindOf_1 = __importDefault(require("./util/getKindOf"));
/**
* The `Collection` immutable object
*/
class Collection extends Map {
/**
* Creates a new instance of the `Collection` immutable class
* @param from Any values to add
*/
constructor(from) {
super();
this.mutable = true;
if (from) {
if (Array.isArray(from)) {
for (let i = 0; i < from.length; i++)
this.set(i, from[i]);
}
else if (isObject_1.default(from)) {
for (const [prop, value] of Object.entries(from))
this.set(prop, value);
}
else {
throw new TypeError(`"from" expects to be an Object or Array, received ${typeof from}`);
}
}
}
/** Getter if the collection is empty */
get empty() {
return this.size === 0;
}
/**
* Adds a value to the collection without using a key
* @param val The value to add to the collection
*/
add(val) {
if (!this.mutable)
throw new errors_1.ImmutabilityError('collection', 'add');
this.set(this.size, val);
}
/**
* Use a predicate function to filter out anything and return a new Array
* @param predicate The predicate function to filter out
* @returns A new Array of the values that returned `true` in the predicate function
*/
filter(predicate) {
const result = [];
for (const value of this.values()) {
const func = predicate.bind(this);
if (func(value))
result.push(value);
}
return result;
}
/**
* Use a predicate function to map anything into a new array
* @param predicate The predicate function to map out and return a new array
* @returns A new Array of the values from that function
*/
map(predicate) {
const result = [];
const func = predicate.bind(this);
let index = -1;
for (const value of this.values())
result.push(func(value, ++index));
return result;
}
/**
* Returns a random value from the collection
* @returns A random value or `null` if the collection is empty
*/
random() {
if (this.empty)
return null;
const iterable = Array.from(this.values());
return iterable[Math.floor(Math.random() * iterable.length)];
}
/**
* Merges all collections provided and this one to a new collection
* @param collections Any collections to merge into this one
*/
merge(...collections) {
if (collections.some(x => !x.mutable)) {
const immutable = collections.filter(x => !x.mutable);
throw new errors_1.MergeConflictError(immutable.length);
}
const newColl = new this.constructor();
for (const [key, value] of this)
newColl.set(key, value);
for (const coll of collections) {
for (const [key, val] of coll)
newColl.set(key, val);
}
return newColl;
}
/**
* Paritition the collection and return an Array of 2 collections that returned `true` or `false`
* @param predicate The predicate function
* @returns An array with 2 collections that represent a `true (first one)` and `false (second one)`
*/
partition(predicate) {
const [item1, item2] = [new this.constructor(), new this.constructor()];
for (const [key, value] of this) {
const func = predicate.bind(this);
const result = func(value);
if (result)
item1.set(key, value);
else
item2.set(key, value);
}
return [item1, item2];
}
/**
* Reduce the collection and return a new initial value
* @param predicate The predicate function
* @param initialValue The initial value
*/
reduce(predicate, initialValue) {
const iterable = this.values();
let value;
let res = initialValue === undefined ? iterable.next().value : initialValue;
const func = predicate.bind(this);
while ((value = iterable.next().value) !== undefined)
res = func(res, value);
return res;
}
/**
* Returns the first element in the collection or an Array of the values from the correspondant `amount`
* @param amount The amount to fetch from
*/
first(amount) {
if (typeof amount === 'undefined') {
const iterable = this.values();
return iterable.next().value;
}
if (amount < 0)
return this.last(amount * -1);
amount = Math.min(amount, this.size);
const iterable = this.values();
return Array.from({ length: amount }, () => iterable.next().value);
}
/**
* Returns the last element in the collection or an Array of the values from the correspondant `amount`
* @param amount The amount to fetch from
*/
last(amount) {
const iter = [...this.values()];
if (typeof amount === 'undefined')
return iter[iter.length - 1];
if (amount < 0)
return this.first(amount * -1);
if (!amount)
return [];
return iter.slice(-amount);
}
/**
* Find a value in the collection from it's predicate function
* @param predicate The predicate function
* @returns The value found or `null` if not found
*/
find(predicate) {
let result = null;
for (const value of this.values()) {
const find = predicate.bind(this);
if (find(value)) {
result = value;
break;
}
}
return result;
}
/**
* Returns the last element in the collection or an Array of the values from the correspondant `amount`
* @param amount The amount to fetch from
*/
lastKey(amount) {
const iter = [...this.keys()];
if (typeof amount === 'undefined')
return iter[iter.length - 1];
if (amount < 0)
return this.firstKey(amount * -1);
if (!amount)
return [];
return iter.slice(-amount);
}
/**
* Returns the first key in the collection or an Array of the values from the correspondant `amount`
* @param amount The amount to fetch from
*/
firstKey(amount) {
if (typeof amount === 'undefined') {
return (this.keys()).next().value;
}
if (amount < 0)
return this.lastKey(amount * -1);
amount = Math.min(amount, this.size);
const iterable = this.keys();
return Array.from({ length: amount }, () => iterable.next().value);
}
/**
* Deletes all elements from the collection
*/
deleteAll() {
if (!this.mutable)
throw new errors_1.ImmutabilityError('collection', 'deleteAll');
for (const key of this.keys())
this.delete(key);
}
/** Overriden from `Map#delete` */
delete(key) {
if (!this.mutable)
throw new errors_1.ImmutabilityError('collection', 'delete');
return super.delete(key);
}
/** Overriden from `Map#set` */
set(key, value) {
if (!this.mutable)
throw new errors_1.ImmutabilityError('collection', 'set');
return super.set(key, value);
}
/**
* Gets the first item in the collection and removes it (if provided)
* @param remove If we should remove it or not
*/
shift(remove = false) {
const item = this.first();
const key = this.firstKey();
if (item === undefined || key === undefined)
return null;
if (remove)
this.delete(key);
return item;
}
/**
* Gets the last item in the collection and removes it(if provided)
* @param remove If we should remove it or not
*/
unshift(remove = false) {
const item = this.last();
const key = this.lastKey();
if (item === undefined || key === undefined)
return null;
if (remove)
this.delete(key);
return item;
}
/** Make this class immutable */
freeze() {
this.mutable = false;
Object.freeze(this);
Object.freeze(this.constructor);
}
/** Makes this class mutable and returns a new collection of the copied values of this immutable collection */
unfreeze() {
// There is no "way" that this can be unfrozed, so we make a
// new collection for safety precautions
const collection = new this.constructor();
for (const [key, value] of this)
collection.set(key, value);
return collection;
}
/**
* Returns all of the values as an Array
*/
toArray() {
return [...this.values()];
}
/**
* Returns all of the keys as an Array
*/
toKeyArray() {
return [...this.keys()];
}
/**
* Computes a value if it's absent in this Collection
* @param key The key to find
* @param insert Item to add when it doesn't exist
*/
emplace(key, insert) {
if (!this.has(key)) {
if (!this.mutable)
throw new errors_1.ImmutabilityError('collection', 'emplace');
const item = typeof insert !== 'function' ? insert : insert();
this.set(key, item);
return insert;
}
else {
return this.get(key);
}
}
/**
* Similar to [Array.sort], which basically sorts the values of this Collection
* to return a value
*
* @param compareFn The compare function
* @returns The value
*/
sort(compareFn) {
const values = this.toArray();
values.sort(compareFn.bind(this));
return values;
}
/**
* Similar to [Array.sort], which basically sorts the values of this Collection
* to return a value
*
* @param compareFn The compare function
* @returns The value
*/
sortKeys(compareFn) {
const keys = this.toKeyArray();
keys.sort(compareFn.bind(this));
return keys;
}
/**
* Similar to [Array.some], this function tests whether atleast 1 item
* in the predicate function passes the test in the values cache.
*
* @param func The function to use to filter out
* @returns A boolean value if 1 item of the cache is truthy
*/
some(func) {
const values = this.toArray();
for (let i = 0; i < values.length; i++) {
if (func.call(this, values[i]))
return true;
else
return false;
}
}
/**
* Similar to [Array.some], this functions tests whether atleast 1 key
* in the predicate function passes the test in the key cache.
*
* @param func The function to use to filter out
* @returns A boolean value if 1 item of the cache is truthy
*/
someKeys(func) {
const keys = this.toKeyArray();
for (let i = 0; i < keys.length; i++) {
if (func.call(this, keys[i]))
return true;
else
return false;
}
}
/**
* Build a new Collection with(out) initial values
* @param values The values to add
*/
static from(values) {
const collection = new Collection();
if (Array.isArray(values)) {
for (let i = 0; i < values.length; i++)
collection.set(i, values[i]);
}
else if (isObject_1.default(values)) {
for (const [key, value] of Object.entries(values))
collection.set(key, value);
}
else {
throw new TypeError(`Collection#from requires the values to be an Object or Array, received ${typeof values}`);
}
return collection;
}
/**
* Override function to return this as a String
*/
toString() {
const all = [];
this.map(getKindOf_1.default).filter((item) => {
if (!all.includes(item))
all.push(item);
});
return `Collection<${all.join(' | ')}>`;
}
}
exports.default = Collection;
"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.Pair = exports.Queue = exports.TimedQueue = exports.Collection = exports.version = void 0;
const Collection_1 = __importDefault(require("./Collection"));
exports.Collection = Collection_1.default;
const TimedQueue_1 = __importDefault(require("./TimedQueue"));
exports.TimedQueue = TimedQueue_1.default;
const Queue_1 = __importDefault(require("./Queue"));
exports.Queue = Queue_1.default;
const Pair_1 = __importDefault(require("./Pair"));
exports.Pair = Pair_1.default;
exports.version = require('../package.json').version;
"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
const getKindOf_1 = __importDefault(require("./util/getKindOf"));
class Pair {
/**
* Construct a new `Pair` instance
* @param right The right side
* @param left The left side
*/
constructor(right, left) {
this.mutable = true;
this.first = right;
this.second = left;
}
/** Make this class immutable */
freeze() {
this.mutable = false;
Object.freeze(this);
Object.freeze(this.constructor);
}
/** Returns a new Pair instance of this immutable class */
unfreeze() {
return new Pair(this.first, this.second);
}
/**
* Override function to return this as a String
*/
toString() {
return `Pair<${getKindOf_1.default(this.first)}, ${getKindOf_1.default(this.second)}>`;
}
}
exports.default = Pair;
"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
const errors_1 = require("./util/errors");
const deprecated_1 = require("./util/deprecated");
const removeArray_1 = __importDefault(require("./util/removeArray"));
const Collection_1 = __importDefault(require("./Collection"));
const getKindOf_1 = __importDefault(require("./util/getKindOf"));
/**
* Queue-based collection to fetch, requeue, and do other stuff!
*/
class Queue {
/**
* Constructs a new instance of the `Queue` class
* @param cache Optional value to set your own cache to the queue
*/
constructor(cache = []) {
this.mutable = true;
this.cache = cache;
}
/**
* Checks if the queue is empty
*/
get empty() {
return this.cache.length === 0;
}
/**
* Adds an item to the cache but hirearchy is on first instead of last
* @param item The item to add at the cache
*/
addFirst(item) {
if (!this.mutable)
throw new errors_1.ImmutabilityError('queue', 'addFirst');
this.cache.unshift(item);
return this;
}
/**
* Enqueue a new value to the cache, run `tick` to process it!
*
* This method is deprecated, use `Queue#add`
*
* @param value The value to put
*/
enqueue(value) {
deprecated_1.deprecate('enqueue', 'add');
this.cache.push(value);
return this;
}
/**
* Adds a item to the cache
* @param value The value to add
*/
add(value) {
if (!this.mutable)
throw new errors_1.ImmutabilityError('queue', 'add');
this.cache.push(value);
return this;
}
/**
* Runs all of the queue values that was put with `add`.
*
* This removes the cache while a for loop doesn't
*
* @param func The function when a new queue item has ticked
*/
tick(func) {
for (const item of this.cache)
func(item);
this.cache.length = 0;
}
/**
* Peek at the last value of the queue
*/
peek() {
if (!this.cache.length)
throw new Error('There are no items in the queue');
deprecated_1.deprecate('peek', 'last');
return this.cache[this.cache.length - 1];
}
/**
* Peek at an index of the cache
* @param index The index to peek at
* @returns A value if it didn't return null
*/
peekAt(index) {
deprecated_1.deprecate('peekAt', 'get');
if (!this.cache.length)
throw new Error('There are no items in the queue');
const item = this.cache[index];
return (item === void 0 || item === null) ? null : item;
}
/**
* Returns the last value of the cache
*/
last() {
return this.cache[this.cache.length - 1];
}
/**
* Returns the value or `null` if not found
* @param index The index to peek at
* @returns A value if it didn't return null
*/
get(index) {
if (!this.cache.length)
throw new Error('There are no items in the queue');
const item = this.cache[index];
return (item === void 0 || item === null) ? null : item;
}
/**
* Removes the item from the queue
*
* @warning Use `Queue#tick` to remove all items!
* @param item The item to remove
*/
remove(item) {
if (!this.mutable)
throw new errors_1.ImmutabilityError('queue', 'remove');
removeArray_1.default(this.cache, item);
return this;
}
/**
* Checks if the key is included in the cache
* @param key The key to find
*/
includes(key) {
return this.cache.includes(key);
}
/**
* Returns the size of the cache
*/
size() {
return this.cache.length;
}
/**
* Returns the cache as an Array
*/
toArray() {
return this.cache;
}
/**
* Returns the cache as an Collection
*/
toCollection() {
return Collection_1.default.from(this.cache);
}
/** Make this class immutable */
freeze() {
this.mutable = false;
Object.freeze(this);
Object.freeze(this.constructor);
}
/** Make this class mutable and returns a new Queue instance that is mutable */
unfreeze() {
const queue = new this.constructor();
for (const item of this)
queue.add(item);
return queue;
}
/**
* Returns the first item in the cache and removes it from the cache
*/
shift() {
return this.cache.shift();
}
/**
* Returns the last item in the cache and removes it from the cache
*/
unshift() {
return this.cache.pop();
}
/**
* Finds an item in the cache or returns `undefined` if not found
* @param predicate The predicate function
*/
find(predicate) {
return this.cache.find(predicate);
}
/**
* Override function to return this as a String
*/
toString() {
const all = [];
this.cache.map(getKindOf_1.default).filter((item) => {
if (!all.includes(item))
all.push(item);
});
return `Queue<${all.join(' | ')}>`;
}
[Symbol.iterator]() {
let index = -1;
const items = this.toArray();
return {
next: () => ({
value: items[++index],
done: index >= items.length
})
};
}
}
exports.default = Queue;
"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
const errors_1 = require("./util/errors");
const events_1 = require("events");
const removeArray_1 = __importDefault(require("./util/removeArray"));
const getKindOf_1 = __importDefault(require("./util/getKindOf"));
const sleep_1 = __importDefault(require("./util/sleep"));
/**
* Queue instance but times everything when started/stopped
*/
class TimedQueue extends events_1.EventEmitter {
/**
* Creates a new TimedQueue
* @param options The options to use
*/
constructor(options) {
super();
this.itemCount = options ? options.hasOwnProperty('itemCount') ? options.itemCount : 1 : 1;
this.started = false;
this.mutable = true;
this.cache = [];
this.every = options ? options.hasOwnProperty('every') ? options.every : 30000 : 30000;
this.time = options ? options.hasOwnProperty('time') ? options.time : 5000 : 5000;
}
/**
* Adds an item to the queue
* @param item The item to push
*/
add(item) {
if (!this.mutable)
throw new errors_1.ImmutabilityError('timedQueue', 'add');
const items = Array.isArray(item) ? item : [item];
this.cache.push(...items);
return this;
}
/**
* Removes an item from the queue
* @param item The item to remove
*/
remove(item) {
if (!this.mutable)
throw new errors_1.ImmutabilityError('timedQueue', 'remove');
removeArray_1.default(this.cache, item);
}
/**
* Clears the cache
*/
clear() {
this.cache.length = 0;
}
/**
* Returns the size of this TimedQueue
*/
size() {
return this.cache.length;
}
/**
* Starts the timed queue
*/
async start() {
if (this.started)
throw new Error('Timed queue has already started');
this.emit('start');
this.started = true;
this._timer = setTimeout(async () => {
if (this.itemCount === 1) {
while (this.started && this.cache.length > 0) {
const item = this.cache.shift();
this.emit('tick', item);
await sleep_1.default(this.time);
}
}
else {
let index = -1;
while (this.started && this.cache.length > 0) {
const items = this.cache.splice(this.itemCount, this.itemCount);
this.emit('tick', items);
await sleep_1.default(this.time);
}
}
this.emit('end');
this._timer = undefined;
}, this.every);
return this;
}
/**
* Stops the timed queue
*/
stop() {
if (!this.started)
throw new Error('Timed queue has not started');
this.started = false;
clearTimeout(this._timer);
return this;
}
/** Make this class immutable */
freeze() {
this.mutable = false;
Object.freeze(this);
Object.freeze(this.constructor);
}
/** Make this class mutable and returns a new TimedQueue instance that is mutable */
unfreeze() {
const queue = new this.constructor();
for (const item of this.cache)
queue.add(item);
return queue;
}
/**
* Override function to return this as a String
*/
toString() {
const all = [];
this.cache.map(getKindOf_1.default).filter((item) => {
if (!all.includes(item))
all.push(item);
});
return `TimedQueue<${all.join(' | ')}>`;
}
}
exports.default = TimedQueue;
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.deprecate = void 0;
/**
* Properly tell the user that this function is deprecated and will be removed in a future release
* @param method The method itself
* @param functions The other functions to use
*/
function deprecate(method, functions) {
const all = typeof functions === 'string' ? `function ${functions}` : `functions ${functions.join(', ')}`;
console.log(`(immutable:${process.pid}) DeprecationWarning: Method "${method}" is deprecated and will be removed in a future release, please use ${all}.`);
}
exports.deprecate = deprecate;
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.MergeConflictError = exports.ImmutabilityError = void 0;
// Find a better way of doing this
const names = {
collection: 'Collection',
timedQueue: 'TimedQueue',
queue: 'Queue'
};
class ImmutabilityError extends Error {
constructor(type, func) {
super(`${names[type]} is immutable, values cannot be changed (Called by ${names[type]}#${func})`);
//Error.captureStackTrace(this);
this.name = 'ImmutabilityError';
}
}
exports.ImmutabilityError = ImmutabilityError;
class MergeConflictError extends Error {
constructor(collections) {
super(`${collections} collections cannot be merged due to some being immutable`);
this.name = 'MergeConflictError';
}
}
exports.MergeConflictError = MergeConflictError;
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
/**
* Stringifies a JavaScript object
* @param element The element
* @returns The stringified name
*/
exports.default = (element) => {
if (element === undefined)
return 'undefined';
if (element === null)
return 'null';
if (!['object', 'function'].includes(typeof element))
return (typeof element);
if (Array.isArray(element))
return 'array';
if (typeof element === 'function') {
const func = element.toString();
if (func.startsWith('function'))
return 'function';
if (func.startsWith('class'))
return func.slice(5, func.indexOf('{')).trim();
}
return 'object';
};
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
/**
* Utility check to see if it's an object
* @param obj The object iself
* @returns a boolean check
*/
exports.default = (obj) => !Array.isArray(obj) && typeof obj === 'object';
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
function removeArray(cache, item) {
if (typeof item === 'number') {
const value = cache[item];
if (!value || value === null)
throw new Error(`Item at index ${item} is not in the cache.`);
const i = cache.indexOf(value);
if (i !== -1)
cache.splice(i, 1);
}
else {
const i = cache.indexOf(item);
if (i !== -1)
cache.splice(i, 1);
}
}
exports.default = removeArray;
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
/**
* Asynchronously make the program "sleep"
* @param ms The amount of milliseconds to "sleep"
* @returns A promise that is resolved when the timer has reached it's end
*/
exports.default = (ms) => new Promise(resolve => setTimeout(resolve, ms));
+0
-0

@@ -0,0 +0,0 @@ import Immutable from './build/index.js';

+15
-15

@@ -64,3 +64,3 @@ declare module '@augu/immutable' {

public random(): T | null;
/**

@@ -100,3 +100,3 @@ * Merges all collections provided and this one to a new collection

*/
public last(): T | undefined;
public last(): (string | number | bigint) | undefined;

@@ -107,3 +107,3 @@ /**

*/
public last(amount: number): T[];
public last(amount: number): (string | number | bigint)[];

@@ -136,3 +136,3 @@ /**

*/
public lastKey(): T | undefined;
public lastKey(): (string | number | bigint) | undefined;

@@ -143,3 +143,3 @@ /**

*/
public lastKey(amount: number): T[];
public lastKey(amount: number): (string | number | bigint)[];

@@ -188,3 +188,3 @@ /**

* to return a value
*
*
* @param compareFn The compare function

@@ -198,3 +198,3 @@ * @returns The value

* to return a value
*
*
* @param compareFn The compare function

@@ -208,3 +208,3 @@ * @returns The value

* in the predicate function passes the test in the values cache.
*
*
* @param func The function to use to filter out

@@ -218,3 +218,3 @@ * @returns A boolean value if 1 item of the cache is truthy

* in the predicate function passes the test in the key cache.
*
*
* @param func The function to use to filter out

@@ -284,3 +284,3 @@ * @returns A boolean value if 1 item of the cache is truthy

* Enqueue a new value to the cache, run `tick` to process it!
*
*
* @deprecated Use Queue#add

@@ -299,5 +299,5 @@ * @param value The value to put

* Runs all of the queue values that was put with `add`.
*
*
* This removes the cache while a for loop doesn't
*
*
* @param func The function when a new queue item has ticked

@@ -321,3 +321,3 @@ */

* Removes an item from the cache
*
*
* @warning Use `Queue#tick` to remove all!

@@ -331,3 +331,3 @@ * @param item The item to remove or it's index

* Returns the last value of the queue
*
*
* @deprecated Use Queue#last

@@ -339,3 +339,3 @@ */

* Returns the value or `null` if not found
*
*
* @deprecated Use Queue#get

@@ -342,0 +342,0 @@ * @param index The index to peek at

@@ -0,0 +0,0 @@ Copyright (c) 2019-2020 August

{
"name": "@augu/immutable",
"description": "📝 Collections library made in TypeScript",
"version": "0.5.0",
"version": "0.6.0",
"types": "index.d.ts",
"main": "build/index.js",
"homepage": "https://docs.augu.dev/immutable",
"files": ["build/", "esm.mjs", "index.d.ts"],
"files": [
"build/",
"esm.mjs",
"index.d.ts"
],
"author": "August <august@augu.dev>",

@@ -22,11 +26,11 @@ "repository": "https://github.com/auguwu/immutable",

"devDependencies": {
"@augu/eslint-config": "1.8.2",
"@types/node": "14.10.1",
"@types/jest": "26.0.13",
"@typescript-eslint/eslint-plugin": "4.1.0",
"@typescript-eslint/parser": "4.1.0",
"eslint": "7.9.0",
"jest": "26.4.2",
"typescript": "4.0.2",
"ts-jest": "26.3.0"
"@augu/eslint-config": "1.9.0",
"@types/jest": "26.0.15",
"@types/node": "14.14.8",
"@typescript-eslint/eslint-plugin": "4.8.1",
"@typescript-eslint/parser": "4.8.1",
"eslint": "7.13.0",
"jest": "26.6.3",
"ts-jest": "26.4.4",
"typescript": "4.0.5"
},

@@ -39,2 +43,2 @@ "scripts": {

}
}
}
"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
const errors_1 = require("./util/errors");
const isObject_1 = __importDefault(require("./util/isObject"));
const getKindOf_1 = __importDefault(require("./util/getKindOf"));
/**
* The `Collection` immutable object
*/
class Collection extends Map {
/**
* Creates a new instance of the `Collection` immutable class
* @param from Any values to add
*/
constructor(from) {
super();
this.mutable = true;
if (from) {
if (Array.isArray(from)) {
for (let i = 0; i < from.length; i++)
this.set(i, from[i]);
}
else if (isObject_1.default(from)) {
for (const [prop, value] of Object.entries(from))
this.set(prop, value);
}
else {
throw new TypeError(`"from" expects to be an Object or Array, received ${typeof from}`);
}
}
}
/** Getter if the collection is empty */
get empty() {
return this.size === 0;
}
/**
* Adds a value to the collection without using a key
* @param val The value to add to the collection
*/
add(val) {
if (!this.mutable)
throw new errors_1.ImmutabilityError('collection', 'add');
this.set(this.size, val);
}
/**
* Use a predicate function to filter out anything and return a new Array
* @param predicate The predicate function to filter out
* @returns A new Array of the values that returned `true` in the predicate function
*/
filter(predicate) {
const result = [];
for (const value of this.values()) {
const func = predicate.bind(this);
if (func(value))
result.push(value);
}
return result;
}
/**
* Use a predicate function to map anything into a new array
* @param predicate The predicate function to map out and return a new array
* @returns A new Array of the values from that function
*/
map(predicate) {
const result = [];
const func = predicate.bind(this);
let index = -1;
for (const value of this.values())
result.push(func(value, ++index));
return result;
}
/**
* Returns a random value from the collection
* @returns A random value or `null` if the collection is empty
*/
random() {
if (this.empty)
return null;
const iterable = Array.from(this.values());
return iterable[Math.floor(Math.random() * iterable.length)];
}
/**
* Merges all collections provided and this one to a new collection
* @param collections Any collections to merge into this one
*/
merge(...collections) {
if (collections.some(x => !x.mutable)) {
const immutable = collections.filter(x => !x.mutable);
throw new errors_1.MergeConflictError(immutable.length);
}
const newColl = new Collection();
for (const [key, value] of this)
newColl.set(key, value);
for (const coll of collections) {
for (const [key, val] of coll)
newColl.set(key, val);
}
return newColl;
}
/**
* Paritition the collection and return an Array of 2 collections that returned `true` or `false`
* @param predicate The predicate function
* @returns An array with 2 collections that represent a `true (first one)` and `false (second one)`
*/
partition(predicate) {
const [item1, item2] = [new Collection(), new Collection()];
for (const [key, value] of this) {
const func = predicate.bind(this);
const result = func(value);
if (result)
item1.set(key, value);
else
item2.set(key, value);
}
return [item1, item2];
}
/**
* Reduce the collection and return a new initial value
* @param predicate The predicate function
* @param initialValue The initial value
*/
reduce(predicate, initialValue) {
const iterable = this.values();
let value;
let res = initialValue === undefined ? iterable.next().value : initialValue;
const func = predicate.bind(this);
while ((value = iterable.next().value) !== undefined)
res = func(res, value);
return res;
}
/**
* Returns the first element in the collection or an Array of the values from the correspondant `amount`
* @param amount The amount to fetch from
*/
first(amount) {
if (typeof amount === 'undefined') {
const iterable = this.values();
return iterable.next().value;
}
if (amount < 0)
return this.last(amount * -1);
amount = Math.min(amount, this.size);
const iterable = this.values();
return Array.from({ length: amount }, () => iterable.next().value);
}
/**
* Returns the last element in the collection or an Array of the values from the correspondant `amount`
* @param amount The amount to fetch from
*/
last(amount) {
const iter = [...this.values()];
if (typeof amount === 'undefined')
return iter[iter.length - 1];
if (amount < 0)
return this.first(amount * -1);
if (!amount)
return [];
return iter.slice(-amount);
}
/**
* Find a value in the collection from it's predicate function
* @param predicate The predicate function
* @returns The value found or `null` if not found
*/
find(predicate) {
let result = null;
for (const value of this.values()) {
const find = predicate.bind(this);
if (find(value)) {
result = value;
break;
}
}
return result;
}
/**
* Returns the last element in the collection or an Array of the values from the correspondant `amount`
* @param amount The amount to fetch from
*/
lastKey(amount) {
const iter = [...this.keys()];
if (typeof amount === 'undefined')
return iter[iter.length - 1];
if (amount < 0)
return this.firstKey(amount * -1);
if (!amount)
return [];
return iter.slice(-amount);
}
/**
* Returns the first key in the collection or an Array of the values from the correspondant `amount`
* @param amount The amount to fetch from
*/
firstKey(amount) {
if (typeof amount === 'undefined') {
return (this.keys()).next().value;
}
if (amount < 0)
return this.lastKey(amount * -1);
amount = Math.min(amount, this.size);
const iterable = this.keys();
return Array.from({ length: amount }, () => iterable.next().value);
}
/**
* Deletes all elements from the collection
*/
deleteAll() {
if (!this.mutable)
throw new errors_1.ImmutabilityError('collection', 'deleteAll');
for (const key of this.keys())
this.delete(key);
}
/** Overriden from `Map#delete` */
delete(key) {
if (!this.mutable)
throw new errors_1.ImmutabilityError('collection', 'delete');
return super.delete(key);
}
/** Overriden from `Map#set` */
set(key, value) {
if (!this.mutable)
throw new errors_1.ImmutabilityError('collection', 'set');
return super.set(key, value);
}
/**
* Gets the first item in the collection and removes it (if provided)
* @param remove If we should remove it or not
*/
shift(remove = false) {
const item = this.first();
const key = this.firstKey();
if (item === undefined || key === undefined)
return null;
if (remove)
this.delete(key);
return item;
}
/**
* Gets the last item in the collection and removes it(if provided)
* @param remove If we should remove it or not
*/
unshift(remove = false) {
const item = this.last();
const key = this.lastKey();
if (item === undefined || key === undefined)
return null;
if (remove)
this.delete(key);
return item;
}
/** Make this class immutable */
freeze() {
this.mutable = false;
Object.freeze(this);
Object.freeze(this.constructor);
}
/** Makes this class mutable and returns a new collection of the copied values of this immutable collection */
unfreeze() {
// There is no "way" that this can be unfrozed, so we make a
// new collection for safety precautions
const collection = new this.constructor();
for (const [key, value] of this)
collection.set(key, value);
return collection;
}
/**
* Returns all of the values as an Array
*/
toArray() {
return [...this.values()];
}
/**
* Returns all of the keys as an Array
*/
toKeyArray() {
return [...this.keys()];
}
/**
* Computes a value if it's absent in this Collection
* @param key The key to find
* @param insert Item to add when it doesn't exist
*/
emplace(key, insert) {
if (!this.has(key)) {
if (!this.mutable)
throw new errors_1.ImmutabilityError('collection', 'emplace');
const item = typeof insert !== 'function' ? insert : insert();
this.set(key, item);
return insert;
}
else {
return this.get(key);
}
}
/**
* Similar to [Array.sort], which basically sorts the values of this Collection
* to return a value
*
* @param compareFn The compare function
* @returns The value
*/
sort(compareFn) {
const values = this.toArray();
values.sort(compareFn.bind(this));
return values;
}
/**
* Similar to [Array.sort], which basically sorts the values of this Collection
* to return a value
*
* @param compareFn The compare function
* @returns The value
*/
sortKeys(compareFn) {
const keys = this.toKeyArray();
keys.sort(compareFn.bind(this));
return keys;
}
/**
* Similar to [Array.some], this function tests whether atleast 1 item
* in the predicate function passes the test in the values cache.
*
* @param func The function to use to filter out
* @returns A boolean value if 1 item of the cache is truthy
*/
some(func) {
const values = this.toArray();
for (let i = 0; i < values.length; i++) {
if (func.call(this, values[i]))
return true;
else
return false;
}
}
/**
* Similar to [Array.some], this functions tests whether atleast 1 key
* in the predicate function passes the test in the key cache.
*
* @param func The function to use to filter out
* @returns A boolean value if 1 item of the cache is truthy
*/
someKeys(func) {
const keys = this.toKeyArray();
for (let i = 0; i < keys.length; i++) {
if (func.call(this, keys[i]))
return true;
else
return false;
}
}
/**
* Build a new Collection with(out) initial values
* @param values The values to add
*/
static from(values) {
const collection = new Collection();
if (Array.isArray(values)) {
for (let i = 0; i < values.length; i++)
collection.set(i, values[i]);
}
else if (isObject_1.default(values)) {
for (const [key, value] of Object.entries(values))
collection.set(key, value);
}
else {
throw new TypeError(`Collection#from requires the values to be an Object or Array, received ${typeof values}`);
}
return collection;
}
/**
* Override function to return this as a String
*/
toString() {
const all = [];
this.map(getKindOf_1.default).filter((item) => {
if (!all.includes(item))
all.push(item);
});
return `Collection<${all.join(' | ')}>`;
}
}
exports.default = Collection;
"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
const getKindOf_1 = __importDefault(require("./util/getKindOf"));
class Pair {
/**
* Construct a new `Pair` instance
* @param right The right side
* @param left The left side
*/
constructor(right, left) {
this.mutable = true;
this.first = right;
this.second = left;
}
/** Make this class immutable */
freeze() {
this.mutable = false;
Object.freeze(this);
Object.freeze(this.constructor);
}
/** Returns a new Pair instance of this immutable class */
unfreeze() {
return new Pair(this.first, this.second);
}
/**
* Override function to return this as a String
*/
toString() {
return `Pair<${getKindOf_1.default(this.first)}, ${getKindOf_1.default(this.second)}>`;
}
}
exports.default = Pair;
"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
const errors_1 = require("./util/errors");
const deprecated_1 = require("./util/deprecated");
const removeArray_1 = __importDefault(require("./util/removeArray"));
const Collection_1 = __importDefault(require("./Collection"));
const getKindOf_1 = __importDefault(require("./util/getKindOf"));
/**
* Queue-based collection to fetch, requeue, and do other stuff!
*/
class Queue {
/**
* Constructs a new instance of the `Queue` class
* @param cache Optional value to set your own cache to the queue
*/
constructor(cache = []) {
this.mutable = true;
this.cache = cache;
}
/**
* Checks if the queue is empty
*/
get empty() {
return this.cache.length === 0;
}
/**
* Adds an item to the cache but hirearchy is on first instead of last
* @param item The item to add at the cache
*/
addFirst(item) {
if (!this.mutable)
throw new errors_1.ImmutabilityError('queue', 'addFirst');
this.cache.unshift(item);
return this;
}
/**
* Enqueue a new value to the cache, run `tick` to process it!
*
* This method is deprecated, use `Queue#add`
*
* @param value The value to put
*/
enqueue(value) {
deprecated_1.deprecate('enqueue', 'add');
this.cache.push(value);
return this;
}
/**
* Adds a item to the cache
* @param value The value to add
*/
add(value) {
if (!this.mutable)
throw new errors_1.ImmutabilityError('queue', 'add');
this.cache.push(value);
return this;
}
/**
* Runs all of the queue values that was put with `add`.
*
* This removes the cache while a for loop doesn't
*
* @param func The function when a new queue item has ticked
*/
tick(func) {
for (const item of this.cache)
func(item);
this.cache.length = 0;
}
/**
* Peek at the last value of the queue
*/
peek() {
if (!this.cache.length)
throw new Error('There are no items in the queue');
deprecated_1.deprecate('peek', 'last');
return this.cache[this.cache.length - 1];
}
/**
* Peek at an index of the cache
* @param index The index to peek at
* @returns A value if it didn't return null
*/
peekAt(index) {
deprecated_1.deprecate('peekAt', 'get');
if (!this.cache.length)
throw new Error('There are no items in the queue');
const item = this.cache[index];
return (item === void 0 || item === null) ? null : item;
}
/**
* Returns the last value of the cache
*/
last() {
return this.cache[this.cache.length - 1];
}
/**
* Returns the value or `null` if not found
* @param index The index to peek at
* @returns A value if it didn't return null
*/
get(index) {
if (!this.cache.length)
throw new Error('There are no items in the queue');
const item = this.cache[index];
return (item === void 0 || item === null) ? null : item;
}
/**
* Removes the item from the queue
*
* @warning Use `Queue#tick` to remove all items!
* @param item The item to remove
*/
remove(item) {
if (!this.mutable)
throw new errors_1.ImmutabilityError('queue', 'remove');
removeArray_1.default(this.cache, item);
return this;
}
/**
* Checks if the key is included in the cache
* @param key The key to find
*/
includes(key) {
return this.cache.includes(key);
}
/**
* Returns the size of the cache
*/
size() {
return this.cache.length;
}
/**
* Returns the cache as an Array
*/
toArray() {
return this.cache;
}
/**
* Returns the cache as an Collection
*/
toCollection() {
return Collection_1.default.from(this.cache);
}
/** Make this class immutable */
freeze() {
this.mutable = false;
Object.freeze(this);
Object.freeze(this.constructor);
}
/** Make this class mutable and returns a new Queue instance that is mutable */
unfreeze() {
const queue = new this.constructor();
for (const item of this)
queue.add(item);
return queue;
}
/**
* Returns the first item in the cache and removes it from the cache
*/
shift() {
return this.cache.shift();
}
/**
* Returns the last item in the cache and removes it from the cache
*/
unshift() {
return this.cache.pop();
}
/**
* Finds an item in the cache or returns `undefined` if not found
* @param predicate The predicate function
*/
find(predicate) {
return this.cache.find(predicate);
}
/**
* Override function to return this as a String
*/
toString() {
const all = [];
this.cache.map(getKindOf_1.default).filter((item) => {
if (!all.includes(item))
all.push(item);
});
return `Queue<${all.join(' | ')}>`;
}
[Symbol.iterator]() {
let index = -1;
const items = this.toArray();
return {
next: () => ({
value: items[++index],
done: index === items.length
})
};
}
}
exports.default = Queue;
// Add it to the prototype
Queue.prototype[Symbol.iterator] = function iterator() {
let index = -1;
const items = this.toArray();
return {
next: () => ({
value: items[++index],
done: index === items.length
})
};
};
"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
const errors_1 = require("./util/errors");
const events_1 = require("events");
const removeArray_1 = __importDefault(require("./util/removeArray"));
const getKindOf_1 = __importDefault(require("./util/getKindOf"));
const sleep_1 = __importDefault(require("./util/sleep"));
/**
* Queue instance but times everything when started/stopped
*/
class TimedQueue extends events_1.EventEmitter {
/**
* Creates a new TimedQueue
* @param options The options to use
*/
constructor(options) {
super();
this.itemCount = options ? options.hasOwnProperty('itemCount') ? options.itemCount : 1 : 1;
this.started = false;
this.mutable = true;
this.cache = [];
this.every = options ? options.hasOwnProperty('every') ? options.every : 30000 : 30000;
this.time = options ? options.hasOwnProperty('time') ? options.time : 5000 : 5000;
}
/**
* Adds an item to the queue
* @param item The item to push
*/
add(item) {
if (!this.mutable)
throw new errors_1.ImmutabilityError('timedQueue', 'add');
const items = Array.isArray(item) ? item : [item];
this.cache.push(...items);
return this;
}
/**
* Removes an item from the queue
* @param item The item to remove
*/
remove(item) {
if (!this.mutable)
throw new errors_1.ImmutabilityError('timedQueue', 'remove');
removeArray_1.default(this.cache, item);
}
/**
* Clears the cache
*/
clear() {
this.cache.length = 0;
}
/**
* Returns the size of this TimedQueue
*/
size() {
return this.cache.length;
}
/**
* Starts the timed queue
*/
async start() {
if (this.started)
throw new Error('Timed queue has already started');
this.emit('start');
this.started = true;
this._timer = setTimeout(async () => {
if (this.itemCount === 1) {
while (this.started && this.cache.length > 0) {
const item = this.cache.shift();
this.emit('tick', item);
await sleep_1.default(this.time);
}
}
else {
let index = -1;
while (this.started && this.cache.length > 0) {
const items = this.cache.splice(this.itemCount, this.itemCount);
this.emit('tick', items);
await sleep_1.default(this.time);
}
}
this.emit('end');
this._timer = undefined;
}, this.every);
return this;
}
/**
* Stops the timed queue
*/
stop() {
if (!this.started)
throw new Error('Timed queue has not started');
this.started = false;
clearTimeout(this._timer);
return this;
}
/** Make this class immutable */
freeze() {
this.mutable = false;
Object.freeze(this);
Object.freeze(this.constructor);
}
/** Make this class mutable and returns a new TimedQueue instance that is mutable */
unfreeze() {
const queue = new this.constructor();
for (const item of this.cache)
queue.add(item);
return queue;
}
/**
* Override function to return this as a String
*/
toString() {
const all = [];
this.cache.map(getKindOf_1.default).filter((item) => {
if (!all.includes(item))
all.push(item);
});
return `TimedQueue<${all.join(' | ')}>`;
}
}
exports.default = TimedQueue;
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.deprecate = void 0;
/**
* Properly tell the user that this function is deprecated and will be removed in a future release
* @param method The method itself
* @param functions The other functions to use
*/
function deprecate(method, functions) {
const all = typeof functions === 'string' ? `function ${functions}` : `functions ${functions.join(', ')}`;
console.log(`(immutable:${process.pid}) DeprecationWarning: Method "${method}" is deprecated and will be removed in a future release, please use ${all}.`);
}
exports.deprecate = deprecate;
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.MergeConflictError = exports.ImmutabilityError = void 0;
// Find a better way of doing this
const names = {
collection: 'Collection',
timedQueue: 'TimedQueue',
queue: 'Queue'
};
class ImmutabilityError extends Error {
constructor(type, func) {
super(`${names[type]} is immutable, values cannot be changed (Called by ${names[type]}#${func})`);
//Error.captureStackTrace(this);
this.name = 'ImmutabilityError';
}
}
exports.ImmutabilityError = ImmutabilityError;
class MergeConflictError extends Error {
constructor(collections) {
super(`${collections} collections cannot be merged due to some being immutable`);
this.name = 'MergeConflictError';
}
}
exports.MergeConflictError = MergeConflictError;
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
/**
* Stringifies a JavaScript object
* @param element The element
* @returns The stringified name
*/
exports.default = (element) => {
if (element === undefined)
return 'undefined';
if (element === null)
return 'null';
if (!['object', 'function'].includes(typeof element))
return (typeof element);
if (Array.isArray(element))
return 'array';
if (typeof element === 'function') {
const func = element.toString();
if (func.startsWith('function'))
return 'function';
if (func.startsWith('class'))
return func.slice(5, func.indexOf('{')).trim();
}
return 'object';
};
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
/**
* Utility check to see if it's an object
* @param obj The object iself
* @returns a boolean check
*/
exports.default = (obj) => !Array.isArray(obj) && typeof obj === 'object';
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
function removeArray(cache, item) {
if (typeof item === 'number') {
const value = cache[item];
if (!value || value === null)
throw new Error(`Item at index ${item} is not in the cache.`);
const i = cache.indexOf(value);
if (i !== -1)
cache.splice(i, 1);
}
else {
const i = cache.indexOf(item);
if (i !== -1)
cache.splice(i, 1);
}
}
exports.default = removeArray;
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
/**
* Asynchronously make the program "sleep"
* @param ms The amount of milliseconds to "sleep"
* @returns A promise that is resolved when the timer has reached it's end
*/
exports.default = (ms) => new Promise(resolve => setTimeout(resolve, ms));