UNPKG

@beastboyadi/collection

Version:

A better collection package inspired by @discordjs/collection but faster and with two types, JSON and Map.

1,017 lines (945 loc) 32 kB
const customInspectSymbol = Symbol.for('nodejs.util.inspect.custom'); const fs = require("node:fs/promises"); const pt = require("node:path"); const { inspect } = require("node:util"); /** * @class * @namespace jsonCollection * @classdesc A collection class which uses JSON for storing datas * @constructs jsonCollection * @param {(Object|jsonCollection|mapCollection|Array)} data - The data to add to the collection while constructing the collection * @returns {jsonCollection} - The constructed collection * @example * let json = new jsonCollection({"hii": "hello", "ok": "bye"}) * @example * let json = new jsonCollection([["hii", "hello"], ["ok", "bye"]]) * @example * let json = new jsonCollection(jsonCollection2) * @example * let json = new jsonCollection(mapCollection) */ class jsonCollection { constructor(data) { this.json = {}; if (!data) return; if (typeof data === "object" && !Array.isArray(data)) { if (data instanceof Map || data instanceof this.constructor) { for (let [k, v] of data) { if (typeof k !== "symbol" && typeof k !== "string") k = inspect(k); this.json[k] = v; } } else { Object.assign(this.json, data) } } else if (Array.isArray(data) && data.every(m => Array.isArray(m) && m?.length === 2)) { for (let [k, v] of data) { if (typeof k !== "symbol" && typeof k !== "string") k = inspect(k); this.json[k] = v; } } else if (Array.isArray(data) && data.every(m => m && typeof m === "object")) { for (let d of data) { let en = Object.entries(d); for (let [k, v] of en) { if (k !== null && typeof k !== "undefined") this.json[k] = v; } } } } /** * @param {jsonKey} key - The collection key for setting a value to it * @param {jsonValue} value - The collection value you want to set * @description Adds an entry to the collection with the specified key and value * @returns {jsonCollection} * @example * jsonCollection.set("hii", "hello") //returns jsonCollection */ set(key, value) { let k = key; if (typeof k === "function") throw new TypeError("Key must not be a function"); if (typeof k !== "string" && typeof k !== "symbol" && typeof k !== "undefined") k = inspect(k); this.json[k] = value; return this; } /** * @param {jsonKey} key - The collection key to get a value attached to it * @description Returns the value of the key in the collection * @returns {jsonCollection} * @example * jsonCollection.get("hii") //returns {jsonCollection} */ get(key) { let k = key; if (typeof k === "function") throw new TypeError("Key must not be a function"); if (typeof k !== "string" && typeof k !== "symbol" && typeof k !== "undefined") k = inspect(k); if (!this.json.hasOwnProperty(key)) return null; return this.json[k]; }; /** * @param {jsonCollection~3P} fn - The function to find the values. Must return boolean * @description Finds the value with the specified function * @returns {jsonValue} value * @example * jsonCollection.find(v => v.includes("hii")) //returns "hii" */ find(fn) { if (typeof fn !== "function") throw new TypeError(`${fn} is not a function.`); if (!this.size) return null; for (let [k, v] of this) { if (fn(v, k, this)) return v; } } /** * @param {jsonCollection~3P} fn - The function to find the keys. Must return boolean * @description Finds the key in the collection with the specified function * @returns {jsonKey} key * @example * jsonCollection.findKey(v => v.includes("hii")) */ findKey(fn) { if (typeof fn !== "function") throw new TypeError(`${fn} is not a function.`); if (!this.size) return null; for (let [k, v] of this) { if (fn(v, k, this)) return k; } } /** * @param {jsonCollection~3P} fn - The function to find the entry. Must return boolean * @description Finds the entry in the collection with the specified function * @returns {Array.<jsonKey, jsonValue>} Array of the key, value * @example * jsonCollection.Entry(v => v.includes("hii")) // returns ["lol", "hii"] */ findEntry(fn) { if (typeof fn !== "function") throw new TypeError(`${fn} is not a function.`); if (!this.size) return null; for (let [k, v] of this) { if (fn(v, k, this)) return [k, v]; } } /** * @param {jsonCollection~3P} fn - The function to filter the keys. Must return boolean * @description Filters the keys in the collection with the specified function * @returns {jsonKey[]} - Array of keys * @example * jsonCollection.filterKeys(v => v.includes("hii")) */ filterKeys(fn) { if (typeof fn !== "function") throw new TypeError(`${fn} is not a function.`); let keys = []; if (!this.size) return keys; for (let [k, v] of this) { if (fn(v, k, this)) keys.push(k); } return keys; } /** * @param {jsonCollection~3P} fn - The function to filter the entries of the collection. Must return boolean. * @description Filters out the collection entries * @returns {jsonCollection} - Filtered Collection * @example * jsonCollection.filter(v => v.includes("hii")) */ filter(fn) { if (typeof fn !== "function") throw new TypeError(`${fn} is not a function.`); let col = this.create(); if (!this.size) return this; for (let [k, v] of this) { if (fn(v, k, this)) col.set(k, v); } return col; } /** * @param {jsonCollection~3P} fn - The function to filter the entries. Must return boolean * @description Filters the entries in the collection with the specified function * @returns {Array.<jsonKey, jsonValue>} - Array of multiple [key, value] * @example * jsonCollection.filterKeys(v => v.includes("hii")) // returns [["lol", "hii"], ["ok", "hii"]] */ filterEntries(fn) { if (typeof fn !== "function") throw new TypeError(`${fn} is not a function.`); let entries = []; if (!this.size) return entries; for (let [k, v] of this) { if (fn(v, k, this)) entries.push([k, v]); } return entries; } /** * @param {jsonCollection~VP} fn - The function for mapping the collection * @description Formats the collection * @returns {jsonValue[]} - Array of Mapped values * @example * jsonCollection.map(v => `Value: ${v}`) */ map(fn) { if (typeof fn !== "function") return this; if (!this.size) return []; return this.values.map(fn); } /** * @param {jsonCollection~KP} fn - The function for mapping the collection * @description Formats the collection keys * @returns {jsonKey[]} - Array of Mapped keys * @example * jsonCollection.map(k => `Key: ${k}`) */ mapKeys(fn) { if (typeof fn !== "function") return this; if (!this.size) return []; return this.keys.map(fn); } /** * @param {jsonCollection~CP} fn - The function to run on the collection * @description Runs the specified function on the collection * @returns {jsonCollection} - The Collection * @example * jsonCollection.tap((col) => { * console.log(col.get("hii")); * }).toJSON(); */ tap(fn) { if (typeof fn !== "function") throw new TypeError(`${fn} is not a function.`); fn(this); return this; } /** * @param {jsonCollection~3P} fn - The function. Must return a boolean. * @description Splits the collection into an Array of two collection. First collection that passed the function and the other that didn't pass the the function * @return {jsonCollection[]} - Array of Collections * @example * jsonCollection.split((v, k) => { return (typeof v === "string" && typeof k === "string") }) */ split(fn) { if (typeof fn !== "function") throw new TypeError(`${fn} is not a function`); let cols = [this.create(), this.create()]; for (let [k, v] of this) { if (fn(v, k, this)) { cols[0].set(k, v); } else { cols[1].set(k, v); } } return cols; } /** * @param {jsonCollection~2P} fn - The function for satisying the test on all entries. Must return boolean * @description Performs a test on all entries of the collection * @returns {Bool} * @example * jsonCollection.every((k,v) => { return (k.startsWith("server") && typeof v !== "undefined") }) */ every(fn) { if (typeof fn !== "function") return false; let bool = true; for (let [k, v] of this) { if (!fn(v, k)) bool = false; } return bool; } /** * @param {jsonCollection~VP} fn - Function for running on the values * @description Performs a forEach function on the values of the collection * @returns {?jsonValue} - Value returned from the function or undefined * @example * jsonCollection.each(v => { Array.push(v)}) */ each(fn) { return this.forEach(fn); } /** * @param {jsonCollection~VP} fn - Function for running on the values * @description Performs a forEach function on the values of the collection * @returns {?jsonValue} - Value return from the function or undefined * @example * jsonCollection.forEach(v => { Array.push(v)}) */ forEach(fn) { if (typeof fn !== "function") return null; return this.values.forEach(fn); } /** * @param {jsonCollection} collection - Collection to compare with the current collection * @description Compares both jsonCollection and returns true if they are equal * @returns {Bool} * @example * jsonCollection.equal(jsonCollection2) */ equal(collection) { if (!collection) return false; if (this === collection) return true; if (this.size !== collection.size) return false; if (!collection instanceof this.constructor) return false; for (let [key, value] of this) { if (!collection.has(key) || value !== collection.get(key)) { return false; } } return true; } /** * @param {jsonCollection~2P} fn - The function for testing the entries on the collection. Must return boolean * @description Performs a test on all entries of the Collection and returns true if anyone of them is true * @returns {Bool} * @example * jsonCollection.some((v,k) => v !== k) */ some(fn) { if (typeof fn !== "function") return false; let bool = false; for (let [k, v] of this) { if (fn(v, k)) bool = true; } return bool; } /** * @param {CallbackFn} fn - The reduce function same as {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/reduce|Array.reduce} parameters * @param {jsonValue} initialValue - The initial value to use as the previous value for initialising the reduce function * @description Reduces the values of the collection same as {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/reduce|Array.reduce} with same parameters * @returns {jsonValue} - Reduced value * @example * jsonCollection.reduce((v1, v2) => { return v1 + v2 }, v3); */ reduce(fn, initialValue) { if (typeof fn !== "function") return null; return this.values.reduce(fn, initialValue); } /** * @param {CallbackFn} fn - The reduce function same as {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/reduce|Array.reduce} parameters * @param {jsonKey} initialKey - The initial key to use as the previous key for initialising the reduce function * @description Reduces the keys of the collection same as {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/reduce|Array.reduce} with same parameters * @returns {jsonKey} - Reduced key * @example * jsonCollection.reduceKey((k1, k2) => { return k1 + k2 }, k3) */ reduceKey(fn, initialKey) { if (typeof fn !== "function") return null; return this.keys.reduce(fn, initialKey); } /** * @param {CallbackFn} fn - The function to sort the values same as {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/sort|Array.sort} parameters. Must return {boolean} * @description Sorts the values of the collection without affecting it. Same as {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/sort|Array.sort} * @returns {jsonValue[]} - Sorted Array of values * @example * jsonCollection.sort((v, v1) => v1 > v) */ sort(fn) { let val = this.values; return val.sort(fn); } /** * @param {CallbackFn} fn - The function to sort the keys same as {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/sort|Array.sort} parameters. Must return boolean * @description Sorts the keys of the collection without affecting it. Same as {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/sort|Array.sort} * @returns {jsonKey[]} - Sorted Array of keys * @example * jsonCollection.sortKeys((k, k1) => k1 < k) */ sortKeys(fn) { let key = this.keys; return key.sort(fn); } /** * @param {Number} [startIndex=0] - The starting index for randomising the value * @param {Number} [endIndex=1] - The ending index for randomising the value * @description Randomises between the entries of collection and returns the random value * @returns {jsonValue} - Random value * @example * jsonCollection.random(); * @example * jsonCollection.random(2, 6); */ random(startIndex, endIndex) { return this.get(this.randomKey(startIndex, endIndex)); } /** * @description Converts the collection into a json * @returns {StringObject} - The Stringified JSON Object * @example * jsonCollection.toJSON() */ toJSON() { return JSON.stringify(this.json); } /** * @param {...jsonKey} keys - Array of keys * @description Checks if all keys are present in the collection * @returns {Bool} * @example * // returns false * jsonCollection.hasAll("hii", "hello", "lol"); * @example * // returns true * jsonCollection.hasAll(["hii", "ok"]) */ hasAll(...keys) { return keys.every(x => this.has(x)); } /** * @param {...jsonKey} keys - Array of keys * @description Checks if any of the keys are present in the collection * @returns {Bool} * @example * //returns true * jsonCollection.hasAny("ok", "bye", "hii") */ hasAny(...keys) { return keys.some(x => this.has(x)); } /** * @param {...jsonValue} values - Array of Values * @description Checks if all values are present in the collection * @returns {Bool} * @example * //returns true * jsonCollection.hasAllValues("ye", "hii") */ hasAllValues(...values) { return values.every(x => this.hasValue(x)); } /** * @param {...jsonValue} values - Array of values * @description Checks if any of the values are in the collection * @returns {Bool} * @example * //returns false * jsonCollection.hasAnyValue("lol", "no") */ hasAnyValue(...values) { return values.some(x => this.hasValue(x)); } /** * @param {jsonValue} value - The value * @description Checks if the value is in the collection * @returns {Bool} * @example * //returns false * jsonCollection.hasValue("yes") */ hasValue(value) { if (!this.size) return false; for (let [k, v] of this) { if (v === value) return true; } return false; } /** * @param {jsonKey} key - The key * @description Checks if the key is present in the collection * @returns {Bool} * @example * //returns true * jsonCollection.has("hii") */ has(key) { if (!this.size) return false; let k = key; if (typeof k === "undefined") return false; if (typeof k === "function") throw new TypeError("Key must not be a function"); if (typeof k !== "string" && typeof k !== "symbol") k = inspect(k); return this.json.hasOwnProperty(k); } /** * @param {Number} [index=1] - The index till which the keys will be retrieved from the first. * @description To get the first key or an Array of keys from the first * @returns {(jsonKey|jsonKey[])} - The First key or an Array of keys from the first * @example * jsonCollection.firstKey(); * @example * jsonCollection.firstKey(2); */ firstKey(index) { if (!this.size) return null; if (index > this.size) return undefined; if (!index || index < 2) { return this.keys[0]; } else { return this.keys.slice(0, index); } } /** * @param {Number} [index=1] - The index till which the keys will be retrieved from the last. * @description To get the last key or an Array of keys from the last * @returns {(jsonKey|jsonKey[])} - The Last key or an Array of keys from the last * @example * jsonCollection.lastKey(); * @example * jsonCollection.lastKey(2); */ lastKey(index) { if (!this.size) return null; if (index > this.size) return undefined; let keys = this.reverseKeys(); if (!index || index < 2) { return keys[0]; } else { return keys.slice(0, index); } } /** * @param {Number} index - The index number * @description To get the value at that index number * @returns {jsonValue} - Value at the index * @example * jsonCollection.at(3); */ at(index) { if (!this.size) return null; return this.values.at(index); } /** * @param {Number} index - The index number * @description To get the key at that index number * @returns {jsonKey} - Key at the index * @example * jsonCollection.keyAt(2); */ keyAt(index) { if (!this.size) return null; return this.keys.at(index); } /** * @param {Number} [startIndex=0] - The starting index for randomising the key * @param {Number} [endIndex=1] - The ending index for randomising the key * @description Randomises between the entries of collection and returns the random key * @returns {jsonKey} - Random key * @example * jsonCollection.randomKey(); * @example * jsonCollection.randomKey(2, 6); */ randomKey(startIndex, endIndex) { if (!this.size) return null; let arr = this.keys; if (!arr.length) return []; if (typeof startIndex !== "Number" || typeof endIndex !== "Number ") { let random_amt = Math.floor(Math.random() * arr.length); return arr[random_amt]; } else { if (startIndex >= arr.length || endIndex >= arr.length) return []; let random_amt = Math.floor((Math.random() * startIndex) + endIndex); return arr[random_amt]; } } /** * @description Reverses the keys and values of the collection without affecting the original collection * @returns {jsonCollection} - The collection * @example * jsonCollection.reverse() */ reverse() { let entries = this.entries.reverse(); return this.create(entries); } /** * @description Reverses the values of the collection without affecting the original collection * @returns {jsonValue[]} - Array of reversed values * @example * jsonCollection.reverseValues() */ reverseValues() { return this.values.reverse(); } /** * @description Reverses the keys of the collection without affecting the origin collection * @returns {jsonKey[]} - Array of reversed keys * @example * jsonCollection.reverseKeys() */ reverseKeys() { return this.keys.reverse(); } /** @param {Number} [index=1] - The index till which the values will be retrieved from first. * @description To get the first value or an Array of values from the first * @returns {jsonValue|jsonValue[]} - The First value or an Array of values from the first * @example * jsonCollection.first(); */ first(index) { let keys = this.firstKey(index); if (!keys) return null; if (!Array.isArray(keys)) { return this.get(keys); } else { let vals = []; for (let k of keys) { vals.push(this.get(k)); } return vals; } } /** @param {Number} [index=1] - The index till which the values will be retrieved from last. * @description To get the last value or an Array of values from the last * @returns {jsonValue|jsonValue[]} - The Last Value or an Array of values from the last * @example * jsonCollection.last() */ last(index) { let keys = this.lastKey(index); if (!keys) return null; if (!Array.isArray(keys)) { return this.get(keys); } else { let vals = []; for (let k of keys) { vals.push(this.get(k)); } return vals; } } /** * @description Converts the collection to an array of values * @returns {jsonValue[]} - Array of values * @example * jsonCollection.array() */ array() { return this.values; } /** * @description Converts the collection to an array of keys * @returns {jsonKey[]} - Array of keys * @example * jsonCollection.keysArray() */ keysArray() { return this.keys; } /** * @param {Number} [start=0] - Starting index * @param {Number} [end=1] - Ending index * @description Slices the collection according to the indexes and generates a new collection. Same as {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/slice|Array.slice} * @returns {jsonCollection} - The Collection * @example * jsonCollection.slice(1, 5); */ slice(start = 0, end = 1) { let entries = this.entries.slice(start, end); return this.create(entries); } /** * @param {jsonKey} key - The key from the collection * @description Deletes the entry with the specified key from the collection * @returns {jsonCollection} - The collection * @example * jsonCollection.delete("hii") */ delete(key) { let k = key; if (typeof k === "undefined") return null; if (typeof k === "function") throw new TypeError("Key must not be a function"); if (typeof k !== "string" && typeof k !== "symbol" && typeof k !== "undefined") k = inspect(k); delete this.json[k]; return this; } /** * @param {Number} index - The index of the entry to delete * @description Deletes the entry at the specified index number. Index should be same like in Array starting from 0 * @returns {jsonCollection} - The Collection * @example * jsonCollection.deleteAt(3) */ deleteAt(index) { let key = this.keyAt(index); if (!key) return null; return this.delete(key); } /** * @param {Number} [index=1] - The index till which the entries will be deleted from the first. * @description Deletes the first entry or an Array of entries from the first of the collection * @returns {?jsonCollection} - The Collection * @example * jsonCollection.deleteFirst(10); */ deleteFirst(index) { let keys = this.firstKey(index); if (!keys) return null; if (!Array.isArray(keys)) { this.delete(keys); } else { for (let k of keys) { this.delete(k); } } return this; } /** @param {Number} [index=1] - The index till which entries will be deleted from the last * @description Deletes the last entry or an Array of entries from the last of the collection * @returns {?jsonCollection} - The Collection * @example * jsonCollection.deleteLast(3); */ deleteLast(index) { let keys = this.lastKey(index); if (!keys) return null; if (!Array.isArray(keys)) { this.delete(keys); } else { for (let k of keys) { this.delete(k); } } return this; } /** * @param {Number} [start=0] - The range starting number * @param {Number} [end=1] - The range ending number * @description Deletes all entries within the specified range * @returns {jsonCollection} - The Collection * @example * jsonCollection.deleteRange(2, 7); */ deleteRange(start = 0, end = 1) { let keys = this.keys.slice(start, end); for (let k of keys) { this.delete(k); } return this; } /** * @description Clears the entire collection * @returns {Bool} * @example * jsonCollection.clear(); */ clear() { this.sweep(() => true); return true; } /** * @param {...Object} collections - jsonCollection or mapCollection or instance of Map * @description Combines two or more collections and generates a new collection. Doesn't affects the any of the collection * @returns {jsonCollection} - The concated Collection * @example * jsonCollection.concat(jsonCollection1, jsonCollection2, jsonCollection3); */ concat(...collections) { let newColl = this.clone(); if (!collections.every(c => c instanceof Map || c instanceof this.constructor)) throw new TypeError("The collections specified must be an instance of Map or jsonCollection. But any or all doesn't meet the criteria."); for (let coll of collections) { for (let [k, v] of coll) { if (typeof k !== "string" && typeof k !== "symbol") k = inspect(k); newColl.set(k, v); } } return newColl; } /** * @param {(Object.<jsonKey, jsonValue>|jsonCollection|mapCollection|Array.<jsonKey, jsonValue>)} data - The data to add to the collection while creating a new collection * @description Creates a new collection with the provided data * @returns {jsonCollection} - The new collection * @example * jsonCollection.create({"hii": "hello", "ok": "bye"}) * @example * jsonCollection.create([["hii", "hello"], ["ok", "bye"]]) * @example * jsonCollection.create(jsonCollection2) * @example * jsonCollection.create(mapCollection) */ create(data) { let coll = new this.constructor(data); return coll; } /** * @description Clones the collection and generates a new clone of the current collection * @returns {jsonCollection} - The Cloned Collection * @example * jsonCollection.clone(); */ clone() { let cloned = this.create(this.json); return cloned; } /** * @param {jsonCollection~3P} fn - The function to sweep the entry. Must return boolean * @description Sweeps out entries according to the function * @returns {Number} - The number of entries that was sweeped * @example * jsonCollection.sweep(() => true); */ sweep(fn) { if (typeof fn !== "function") return 0; let prevSize = this.size; for (let [k, v] of this) { if (fn(v, k, this)) this.delete(k) } let diff = prevSize - this.size; return diff; } /** * @param {String} path - Path to the json file * @param {Bool} overwrite - Whether to overwrite the file with new collection entries. * @description Saves the collection in a json file * @returns {Promise<Bool>} * @example * jsonCollection.save("/home/container/json.json") */ async save(path, overwrite = true) { if (typeof path !== "string") throw new TypeError("Path must be a non-empty string."); if (!path.endsWith(".json")) throw new Error("The specified path must be of a json file."); if (!path.startsWith(process.cwd())) path = process.cwd() + `${path.startsWith("/") ? `/${path}` : path}`; let err; let res; if (!overwrite) { await fs.appendFile(path, this.toJSON()).catch((e) => { err = e; }); if (err) throw err; } else { await fs.writeFile(path, this.toJSON()).catch((e) => { err = e; }); if (err) throw err; res = true; } return Promise.resolve(res); } /** * @param {String} path - Path to the json file * @param {Bool} [overwrite=true] - Whether to overwrite old entries of the collection with the json data. * @description Loads the json file to the collection * @returns {Promise<jsonCollection>} * @example * jsonCollection.load("/home/container/json.json") */ async load(path, overwrite = true) { if (typeof path !== "string") throw new TypeError("Path must be a non-empty string."); if (!path.endsWith(".json")) throw new Error("The specified path must be of a json file."); if (!path.startsWith(process.cwd())) path = process.cwd() + `${path.startsWith("/") ? `/${path}` : path}`; let err; let data = await fs.readFile(path, { encoding: "utf8" }).catch(e => { err = e; }); if (err) throw err; try { data = JSON.parse(data); } catch { throw new Error("The file must not be empty and must have a valid json data."); } if (overwrite) { this.clear(); this.json = data; } else { for (let d in data) { this.set(d, data[d]); } } return Promise.resolve(this); } /** * @description Converts the Collection to an array of keys * @returns {jsonKey[]} - Array of keys * @example * jsonCollection.keys; */ get keys() { if (!this.size) return []; return Object.keys(this.json); } /** * @description Converts the Collection to an array of values * @returns {jsonValue[]} - Array of values * @example * jsonCollection.values */ get values() { if (!this.size) return []; return Object.values(this.json); } /** * @description Converts the collection into an array of [jsonKey, jsonValue] * @returns {Array.<jsonKey, jsonValue>} - Array of [mapKey, jsonValue] * @example * jsonCollection.entries */ get entries() { if (!this.size) return []; return Object.entries(this.json); } /** * @description Gets the total number of entries in the collection * @returns {Number} * @example * jsonCollection.count; */ get count() { return this.size; } /** * @description Gets the total number of entries in the collection * @returns {Number} * @example * jsonCollection.size */ get size() { return Object.keys(this.json).length; } *[Symbol.iterator]() { for (const key in this.json) { yield [key, this.json[key]]; }; }; [customInspectSymbol](depth, options, inspect) { if (depth < 0) return options.stylize(`[${this.constructor.name}]`, "special"); return `${options.stylize(`${this.constructor.name}(${this.size}) [JSON]`, "special")} ${inspect(this.json)}`; } }; /** * Exporting {jsonCollection} class */ module.exports = jsonCollection; /** * @callback jsonCollection~3P * @param {jsonValue} value - The value * @param {jsonKey} key - The key * @param {jsonCollection} collection - The Collection * @description A callback function with 3 parameters namely value, key, collection * @example * function(value, key, collection) { * console.log(value, key, collection); * } */ /** * @callback jsonCollection~2P * @param {jsonValue} value - The value * @param {jsonKey} key - The Key * @description A callback function with 2 parameters namely value, key * @example * function(value, key) { * console.log(value, key); * } */ /** * @callback jsonCollection~VP * @param {jsonValue} value - The value * @description A callback function with 1 parameter i.e. value * @example * function(value) { * console.log(value); * } */ /** * @callback jsonCollection~KP * @param {jsonKey} key - The key * @description A callback function with 1 parameter i.e. key * @example * function(key) { * console.log(key); * } */ /** * @callback jsonCollection~CP * @param {jsonCollection} collection - The collection * @description A callback function with 1 parameter i.e. collection * @example * function(collection) { * console.log(collection.toJSON()); * } */ /** * The key for {@link jsonCollection} class * @typedef {(Number|Object|String)} jsonKey */ /** * The value for {@link jsonCollection} class. * @typedef {Any} jsonValue */