UNPKG

@squarecloud/api

Version:
1 lines 15.7 kB
{"version":3,"sources":["../../src/structures/collection.ts"],"sourcesContent":["/**\n * @internal\n */\nexport interface CollectionConstructor {\n\tnew (): Collection<unknown, unknown>;\n\tnew <K, V>(entries?: readonly (readonly [K, V])[] | null): Collection<K, V>;\n\tnew <K, V>(iterable: Iterable<readonly [K, V]>): Collection<K, V>;\n\treadonly prototype: Collection<unknown, unknown>;\n\treadonly [Symbol.species]: CollectionConstructor;\n}\n\n/**\n * Separate interface for the constructor so that emitted js does not have a constructor that overwrites itself\n *\n * @internal\n */\nexport interface Collection<K, V> extends Map<K, V> {\n\tconstructor: CollectionConstructor;\n}\n\n/**\n * A Map with additional utility methods. This is used throughout \\@squarecloud/api rather than Arrays for anything that has\n * an ID, for significantly improved performance and ease-of-use.\n *\n * @typeParam K - The key type this collection holds\n * @typeParam V - The value type this collection holds\n */\n// biome-ignore lint/suspicious/noUnsafeDeclarationMerging: Needed to merge the constructor and the instance methods\nexport class Collection<K, V> extends Map<K, V> {\n\t/**\n\t * Obtains the first value(s) in this collection.\n\t *\n\t * @param amount - Amount of values to obtain from the beginning\n\t * @returns A single value if no amount is provided or an array of values, starting from the end if amount is negative\n\t */\n\tpublic first(): V | undefined;\n\tpublic first(amount: number): V[];\n\tpublic first(amount?: number): V | V[] | undefined {\n\t\tif (typeof amount === \"undefined\") {\n\t\t\treturn this.values().next().value;\n\t\t}\n\n\t\tif (amount < 0) {\n\t\t\treturn this.last(amount * -1);\n\t\t}\n\n\t\tamount = Math.min(this.size, amount);\n\t\treturn Array.from({ length: amount }, (): V => this.values().next().value);\n\t}\n\n\t/**\n\t * Obtains the last value(s) in this collection.\n\t *\n\t * @param amount - Amount of values to obtain from the end\n\t * @returns A single value if no amount is provided or an array of values, starting from the start if\n\t * amount is negative\n\t */\n\tpublic last(): V | undefined;\n\tpublic last(amount: number): V[];\n\tpublic last(amount?: number): V | V[] | undefined {\n\t\tconst arr = [...this.values()];\n\t\tif (typeof amount === \"undefined\") return arr[arr.length - 1];\n\t\tif (amount < 0) return this.first(amount * -1);\n\t\tif (!amount) return [];\n\t\treturn arr.slice(-amount);\n\t}\n\n\t/**\n\t * Identical to {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/reverse Array.reverse()}\n\t * but returns a Collection instead of an Array.\n\t */\n\tpublic reverse() {\n\t\tconst entries = [...this.entries()].reverse();\n\t\tthis.clear();\n\n\t\tfor (const [key, value] of entries) {\n\t\t\tthis.set(key, value);\n\t\t}\n\n\t\treturn this;\n\t}\n\n\t/**\n\t * Searches for a single item where the given function returns a truthy value. This behaves like\n\t * {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/find Array.find()}.\n\t *\n\t * @param fn - The function to test with (should return boolean)\n\t * @param thisArg - Value to use as `this` when executing function\n\t * @example\n\t * ```ts\n\t * collection.find(user => user.username === 'Bob');\n\t * ```\n\t */\n\tpublic find<V2 extends V>(\n\t\tfn: (value: V, key: K, collection: this) => value is V2,\n\t): V2 | undefined;\n\n\tpublic find(\n\t\tfn: (value: V, key: K, collection: this) => unknown,\n\t): V | undefined;\n\n\tpublic find<This, V2 extends V>(\n\t\tfn: (this: This, value: V, key: K, collection: this) => value is V2,\n\t\tthisArg: This,\n\t): V2 | undefined;\n\n\tpublic find<This>(\n\t\tfn: (this: This, value: V, key: K, collection: this) => unknown,\n\t\tthisArg: This,\n\t): V | undefined;\n\n\tpublic find(\n\t\tfn: (value: V, key: K, collection: this) => unknown,\n\t\tthisArg?: unknown,\n\t): V | undefined {\n\t\tif (typeof fn !== \"function\") {\n\t\t\tthrow new TypeError(`${fn} is not a function`);\n\t\t}\n\n\t\tif (typeof thisArg !== \"undefined\") {\n\t\t\tfn = fn.bind(thisArg);\n\t\t}\n\n\t\tfor (const [key, val] of this) {\n\t\t\tif (fn(val, key, this)) return val;\n\t\t}\n\t}\n\n\t/**\n\t * Identical to\n\t * {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/filter Array.filter()},\n\t * but returns a Collection instead of an Array.\n\t *\n\t * @param fn - The function to test with (should return boolean)\n\t * @param thisArg - Value to use as `this` when executing function\n\t * @example\n\t * ```ts\n\t * collection.filter(user => user.username === 'Bob');\n\t * ```\n\t */\n\tpublic filter<K2 extends K>(\n\t\tfn: (value: V, key: K, collection: this) => key is K2,\n\t): Collection<K2, V>;\n\n\tpublic filter<V2 extends V>(\n\t\tfn: (value: V, key: K, collection: this) => value is V2,\n\t): Collection<K, V2>;\n\n\tpublic filter(\n\t\tfn: (value: V, key: K, collection: this) => unknown,\n\t): Collection<K, V>;\n\n\tpublic filter<This, K2 extends K>(\n\t\tfn: (this: This, value: V, key: K, collection: this) => key is K2,\n\t\tthisArg: This,\n\t): Collection<K2, V>;\n\n\tpublic filter<This, V2 extends V>(\n\t\tfn: (this: This, value: V, key: K, collection: this) => value is V2,\n\t\tthisArg: This,\n\t): Collection<K, V2>;\n\n\tpublic filter<This>(\n\t\tfn: (this: This, value: V, key: K, collection: this) => unknown,\n\t\tthisArg: This,\n\t): Collection<K, V>;\n\n\tpublic filter(\n\t\tfn: (value: V, key: K, collection: this) => unknown,\n\t\tthisArg?: unknown,\n\t): Collection<K, V> {\n\t\tif (typeof fn !== \"function\") {\n\t\t\tthrow new TypeError(`${fn} is not a function`);\n\t\t}\n\n\t\tif (typeof thisArg !== \"undefined\") {\n\t\t\tfn = fn.bind(thisArg);\n\t\t}\n\n\t\tconst results = new this.constructor[Symbol.species]<K, V>();\n\t\tfor (const [key, val] of this) {\n\t\t\tif (fn(val, key, this)) results.set(key, val);\n\t\t}\n\n\t\treturn results;\n\t}\n\n\t/**\n\t * Maps each item to another value into an array. Identical in behavior to\n\t * {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/map Array.map()}.\n\t *\n\t * @param fn - Function that produces an element of the new array, taking three arguments\n\t * @param thisArg - Value to use as `this` when executing function\n\t * @example\n\t * ```ts\n\t * collection.map(user => user.name);\n\t * ```\n\t */\n\tpublic map<T>(fn: (value: V, key: K, collection: this) => T): T[];\n\tpublic map<This, T>(\n\t\tfn: (this: This, value: V, key: K, collection: this) => T,\n\t\tthisArg: This,\n\t): T[];\n\n\tpublic map<T>(\n\t\tfn: (value: V, key: K, collection: this) => T,\n\t\tthisArg?: unknown,\n\t): T[] {\n\t\tif (typeof fn !== \"function\") {\n\t\t\tthrow new TypeError(`${fn} is not a function`);\n\t\t}\n\n\t\tif (typeof thisArg !== \"undefined\") {\n\t\t\tfn = fn.bind(thisArg);\n\t\t}\n\n\t\treturn Array.from({ length: this.size }, (): T => {\n\t\t\tconst [key, value] = this.entries().next().value;\n\t\t\treturn fn(value, key, this);\n\t\t});\n\t}\n\n\t/**\n\t * Checks if there exists an item that passes a test. Identical in behavior to\n\t * {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/some Array.some()}.\n\t *\n\t * @param fn - Function used to test (should return a boolean)\n\t * @param thisArg - Value to use as `this` when executing function\n\t * @example\n\t * ```ts\n\t * collection.some(user => user.discriminator === '0000');\n\t * ```\n\t */\n\tpublic some(fn: (value: V, key: K, collection: this) => unknown): boolean;\n\tpublic some<T>(\n\t\tfn: (this: T, value: V, key: K, collection: this) => unknown,\n\t\tthisArg: T,\n\t): boolean;\n\n\tpublic some(\n\t\tfn: (value: V, key: K, collection: this) => unknown,\n\t\tthisArg?: unknown,\n\t): boolean {\n\t\tif (typeof fn !== \"function\") {\n\t\t\tthrow new TypeError(`${fn} is not a function`);\n\t\t}\n\n\t\tif (typeof thisArg !== \"undefined\") {\n\t\t\tfn = fn.bind(thisArg);\n\t\t}\n\n\t\tfor (const [key, val] of this) {\n\t\t\tif (fn(val, key, this)) return true;\n\t\t}\n\n\t\treturn false;\n\t}\n\n\t/**\n\t * Checks if all items passes a test. Identical in behavior to\n\t * {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/every Array.every()}.\n\t *\n\t * @param fn - Function used to test (should return a boolean)\n\t * @param thisArg - Value to use as `this` when executing function\n\t * @example\n\t * ```ts\n\t * collection.every(user => !user.bot);\n\t * ```\n\t */\n\tpublic every<K2 extends K>(\n\t\tfn: (value: V, key: K, collection: this) => key is K2,\n\t): this is Collection<K2, V>;\n\n\tpublic every<V2 extends V>(\n\t\tfn: (value: V, key: K, collection: this) => value is V2,\n\t): this is Collection<K, V2>;\n\n\tpublic every(fn: (value: V, key: K, collection: this) => unknown): boolean;\n\tpublic every<This, K2 extends K>(\n\t\tfn: (this: This, value: V, key: K, collection: this) => key is K2,\n\t\tthisArg: This,\n\t): this is Collection<K2, V>;\n\n\tpublic every<This, V2 extends V>(\n\t\tfn: (this: This, value: V, key: K, collection: this) => value is V2,\n\t\tthisArg: This,\n\t): this is Collection<K, V2>;\n\n\tpublic every<This>(\n\t\tfn: (this: This, value: V, key: K, collection: this) => unknown,\n\t\tthisArg: This,\n\t): boolean;\n\n\tpublic every(\n\t\tfn: (value: V, key: K, collection: this) => unknown,\n\t\tthisArg?: unknown,\n\t): boolean {\n\t\tif (typeof fn !== \"function\") {\n\t\t\tthrow new TypeError(`${fn} is not a function`);\n\t\t}\n\n\t\tif (typeof thisArg !== \"undefined\") {\n\t\t\tfn = fn.bind(thisArg);\n\t\t}\n\n\t\tfor (const [key, val] of this) {\n\t\t\tif (!fn(val, key, this)) return false;\n\t\t}\n\n\t\treturn true;\n\t}\n\n\t/**\n\t * Applies a function to produce a single value. Identical in behavior to\n\t * {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/reduce Array.reduce()}.\n\t *\n\t * @param fn - Function used to reduce, taking four arguments; `accumulator`, `currentValue`, `currentKey`,\n\t * and `collection`\n\t * @param initialValue - Starting value for the accumulator\n\t * @example\n\t * ```ts\n\t * collection.reduce((acc, guild) => acc + guild.memberCount, 0);\n\t * ```\n\t */\n\tpublic reduce<T>(\n\t\tfn: (accumulator: T, value: V, key: K, collection: this) => T,\n\t\tinitialValue?: T,\n\t): T {\n\t\tif (typeof fn !== \"function\") {\n\t\t\tthrow new TypeError(`${fn} is not a function`);\n\t\t}\n\t\tlet accumulator!: T;\n\n\t\tif (typeof initialValue !== \"undefined\") {\n\t\t\taccumulator = initialValue;\n\t\t\tfor (const [key, val] of this) {\n\t\t\t\taccumulator = fn(accumulator, val, key, this);\n\t\t\t}\n\t\t\treturn accumulator;\n\t\t}\n\n\t\tlet first = true;\n\t\tfor (const [key, val] of this) {\n\t\t\tif (first) {\n\t\t\t\taccumulator = val as unknown as T;\n\t\t\t\tfirst = false;\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\taccumulator = fn(accumulator, val, key, this);\n\t\t}\n\n\t\tif (first) {\n\t\t\tthrow new TypeError(\"Reduce of empty collection with no initial value\");\n\t\t}\n\n\t\treturn accumulator;\n\t}\n\n\t/**\n\t * Identical to\n\t * {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Map/forEach Map.forEach()},\n\t * but returns the collection instead of undefined.\n\t *\n\t * @param fn - Function to execute for each element\n\t * @param thisArg - Value to use as `this` when executing function\n\t * @example\n\t * ```ts\n\t * collection\n\t * .each(user => console.log(user.username))\n\t * .filter(user => user.bot)\n\t * .each(user => console.log(user.username));\n\t * ```\n\t */\n\tpublic each(fn: (value: V, key: K, collection: this) => void): this;\n\tpublic each<T>(\n\t\tfn: (this: T, value: V, key: K, collection: this) => void,\n\t\tthisArg: T,\n\t): this;\n\n\tpublic each(\n\t\tfn: (value: V, key: K, collection: this) => void,\n\t\tthisArg?: unknown,\n\t): this {\n\t\tif (typeof fn !== \"function\") {\n\t\t\tthrow new TypeError(`${fn} is not a function`);\n\t\t}\n\n\t\tthis.forEach(fn as (value: V, key: K, map: Map<K, V>) => void, thisArg);\n\t\treturn this;\n\t}\n\n\t/**\n\t * Creates an identical shallow copy of this collection.\n\t *\n\t * @example\n\t * ```ts\n\t * const newColl = someColl.clone();\n\t * ```\n\t */\n\tpublic clone(): Collection<K, V> {\n\t\treturn new this.constructor[Symbol.species](this);\n\t}\n\n\tpublic toJSON() {\n\t\treturn [...this.values()];\n\t}\n}\n"],"mappings":"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","names":[]}