UNPKG

@byloth/core

Version:

An unopinionated collection of useful functions and classes that I use widely in all my projects. 🔧

1,652 lines (1,650 loc) • 170 kB
var Ke = Object.defineProperty; var Qe = (i, n, e) => n in i ? Ke(i, n, { enumerable: !0, configurable: !0, writable: !0, value: e }) : i[n] = e; var a = (i, n, e) => Qe(i, typeof n != "symbol" ? n + "" : n, e); const Ye = typeof window < "u" && typeof window.document < "u"; var A; const ot = typeof process < "u" && !!((A = process.versions) != null && A.node); var N; const at = typeof self == "object" && ((N = self.constructor) == null ? void 0 : N.name) === "DedicatedWorkerGlobalScope"; var O, q; class c extends (q = Error, O = Symbol.toStringTag, q) { /** * Initializes a new instance of the {@link Exception} class. * * --- * * @example * ```ts * throw new Exception("An error occurred while processing the request."); * ``` * * --- * * @param message The message that describes the error. * @param cause The previous caught error that caused this one, if any. * @param name The name of the exception. Default is `"Exception"`. */ constructor(e, t, s = "Exception") { super(e); a(this, O, "Exception"); this.cause = t, this.name = s, t && (t instanceof Error ? this.stack += ` Caused by ${t.stack}` : this.stack += ` Caused by ${t}`); } /** * A static method to convert a generic caught error, ensuring it's an instance of the {@link Exception} class. * * --- * * @example * ```ts * try { [...] } * catch (error) * { * const exc = Exception.FromUnknown(error); * * [...] * } * ``` * * --- * * @param error The caught error to convert. * * @returns An instance of the {@link Exception} class. */ static FromUnknown(e) { if (e instanceof c) return e; if (e instanceof Error) { const t = new c(e.message); return t.stack = e.stack, t.name = e.name, t; } return new c(`${e}`); } } var $, z; class g extends (z = c, $ = Symbol.toStringTag, z) { /** * Initializes a new instance of the {@link FatalErrorException} class. * * --- * * @example * ```ts * throw new FatalErrorException("This error should never happen. Please, contact the support team."); * ``` * * --- * * @param message The message that describes the error. * @param cause The previous caught error that caused this one, if any. * @param name The name of the exception. Default is `"FatalErrorException"`. */ constructor(e, t, s = "FatalErrorException") { e === void 0 && (e = "The program has encountered an unrecoverable error and cannot continue as expected. Please, try again later. If the problem persists, contact the support team."); super(e, t, s); a(this, $, "FatalErrorException"); } } var D, B; class He extends (B = g, D = Symbol.toStringTag, B) { /** * Initializes a new instance of the {@link NotImplementedException} class. * * --- * * @example * ```ts * throw new NotImplementedException("This method hasn't been implemented yet. Check back later."); * ``` * * --- * * @param message The message that describes the error. * @param cause The previous caught error that caused this one, if any. * @param name The name of the exception. Default is `"NotImplementedException"`. */ constructor(e, t, s = "NotImplementedException") { e === void 0 && (e = "This feature isn't implemented yet. Please, try again later."); super(e, t, s); a(this, D, "NotImplementedException"); } } var J, Y; class Le extends (Y = c, J = Symbol.toStringTag, Y) { /** * Initializes a new instance of the {@link FileException} class. * * --- * * @example * ```ts * throw new FileException("An error occurred while trying to read the file."); * ``` * * --- * * @param message The message that describes the error. * @param cause The previous caught error that caused this one, if any. * @param name The name of the exception. Default is `"FileException"`. */ constructor(e, t, s = "FileException") { super(e, t, s); a(this, J, "FileException"); } } var L, V; class lt extends (V = Le, L = Symbol.toStringTag, V) { /** * Initializes a new instance of the {@link FileExistsException} class. * * --- * * @example * ```ts * throw new FileExistsException("The file named 'data.json' already exists on the server."); * ``` * * --- * * @param message The message that describes the error. * @param cause The previous caught error that caused this one, if any. * @param name The name of the exception. Default is `"FileExistsException"`. */ constructor(e, t, s = "FileExistsException") { super(e, t, s); a(this, L, "FileExistsException"); } } var G, K; class ut extends (K = Le, G = Symbol.toStringTag, K) { /** * Initializes a new instance of the {@link FileNotFoundException} class. * * --- * * @example * ```ts * throw new FileNotFoundException("The file named 'data.json' wasn't found on the server."); * ``` * * --- * * @param message The message that describes the error. * @param cause The previous caught error that caused this one, if any. * @param name The name of the exception. Default is `"FileNotFoundException"`. */ constructor(e, t, s = "FileNotFoundException") { super(e, t, s); a(this, G, "FileNotFoundException"); } } var Q, H; class _ extends (H = c, Q = Symbol.toStringTag, H) { /** * Initializes a new instance of the {@link KeyException} class. * * --- * * @example * ```ts * throw new KeyException("The 'id' key wasn't found in the dictionary."); * ``` * * --- * * @param message The message that describes the error. * @param cause The previous caught error that caused this one, if any. * @param name The name of the exception. Default is `"KeyException"`. */ constructor(e, t, s = "KeyException") { super(e, t, s); a(this, Q, "KeyException"); } } var X, Z; class ct extends (Z = c, X = Symbol.toStringTag, Z) { /** * Initializes a new instance of the {@link NetworkException} class. * * --- * * @example * ```ts * throw new NetworkException("Couldn't connect to the server. Please, try again later."); * ``` * * --- * * @param message The message that describes the error. * @param cause The previous caught error that caused this one, if any. * @param name The name of the exception. Default is `"NetworkException"`. */ constructor(e, t, s = "NetworkException") { super(e, t, s); a(this, X, "NetworkException"); } } var W, U; class ht extends (U = c, W = Symbol.toStringTag, U) { /** * Initializes a new instance of the {@link PermissionException} class. * * --- * * @example * ```ts * throw new PermissionException("You don't have permission to access this resource."); * ``` * * --- * * @param message The message that describes the error. * @param cause The previous caught error that caused this one, if any. * @param name The name of the exception. Default is `"PermissionException"`. */ constructor(e, t, s = "PermissionException") { super(e, t, s); a(this, W, "PermissionException"); } } var ee, te; class E extends (te = c, ee = Symbol.toStringTag, te) { /** * Initializes a new instance of the {@link ReferenceException} class. * * --- * * @example * ```ts * throw new ReferenceException("The 'canvas' element wasn't found in the document."); * ``` * * --- * * @param message The message that describes the error. * @param cause The previous caught error that caused this one, if any. * @param name The name of the exception. Default is `"ReferenceException"`. */ constructor(e, t, s = "ReferenceException") { super(e, t, s); a(this, ee, "ReferenceException"); } } var ne, se; class p extends (se = c, ne = Symbol.toStringTag, se) { /** * Initializes a new instance of the {@link RuntimeException} class. * * --- * * @example * ```ts * throw new RuntimeException("The received input seems to be malformed or corrupted."); * ``` * * --- * * @param message The message that describes the error. * @param cause The previous caught error that caused this one, if any. * @param name The name of the exception. Default is `"RuntimeException"`. */ constructor(e, t, s = "RuntimeException") { super(e, t, s); a(this, ne, "RuntimeException"); } } var re, ie; class Xe extends (ie = p, re = Symbol.toStringTag, ie) { /** * Initializes a new instance of the {@link EnvironmentException} class. * * --- * * @example * ```ts * throw new EnvironmentException("The required environment variable 'API_KEY' isn't set."); * ``` * * --- * * @param message The message that describes the error. * @param cause The previous caught error that caused this one, if any. * @param name The name of the exception. Default is `"EnvironmentException"`. */ constructor(e, t, s = "EnvironmentException") { super(e, t, s); a(this, re, "EnvironmentException"); } } var oe, ae; class Ze extends (ae = c, oe = Symbol.toStringTag, ae) { /** * Initializes a new instance of the {@link TimeoutException} class. * * --- * * @example * ```ts * throw new TimeoutException("The task took too long to complete."); * ``` * * --- * * @param message The message that describes the error. * @param cause The previous caught error that caused this one, if any. * @param name The name of the exception. Default is `"TimeoutException"`. */ constructor(e, t, s = "TimeoutException") { super(e, t, s); a(this, oe, "TimeoutException"); } } var le, ue; class ft extends (ue = c, le = Symbol.toStringTag, ue) { /** * Initializes a new instance of the {@link TypeException} class. * * --- * * @example * ```ts * throw new TypeException("The 'username' argument must be a valid string."); * ``` * * --- * * @param message The message that describes the error. * @param cause The previous caught error that caused this one, if any. * @param name The name of the exception. Default is `"TypeException"`. */ constructor(e, t, s = "TypeException") { super(e, t, s); a(this, le, "TypeException"); } } var ce, he; class f extends (he = c, ce = Symbol.toStringTag, he) { /** * Initializes a new instance of the {@link ValueException} class. * * --- * * @example * ```ts * throw new ValueException("The 'grade' argument cannot be negative."); * ``` * * --- * * @param message The message that describes the error. * @param cause The previous caught error that caused this one, if any. * @param name The name of the exception. Default is `"ValueException"`. */ constructor(e, t, s = "ValueException") { super(e, t, s); a(this, ce, "ValueException"); } } var fe, de; class b extends (de = f, fe = Symbol.toStringTag, de) { /** * Initializes a new instance of the {@link RangeException} class. * * --- * * @example * ```ts * throw new RangeException("The 'percentage' argument must be between 0 and 100."); * ``` * * --- * * @param message The message that describes the error. * @param cause The previous caught error that caused this one, if any. * @param name The name of the exception. Default is `"RangeException"`. */ constructor(e, t, s = "RangeException") { super(e, t, s); a(this, fe, "RangeException"); } } var we; class u { constructor(n) { /** * The native {@link Iterator} object that is being wrapped by this instance. */ a(this, "_iterator"); a(this, we, "SmartIterator"); n instanceof Function ? this._iterator = n() : Symbol.iterator in n ? this._iterator = n[Symbol.iterator]() : this._iterator = n; } /** * Determines whether all elements of the iterator satisfy a given condition. * See also {@link SmartIterator.some}. * * This method will iterate over all elements of the iterator checking if they satisfy the condition. * Once a single element doesn't satisfy the condition, the method will return `false` immediately. * * This may lead to an unknown final state of the iterator, which may be entirely or partially consumed. * For this reason, it's recommended to consider it as consumed in any case and to not use it anymore. * Consider using {@link SmartIterator.find} instead. * * If the iterator is infinite and every element satisfies the condition, the method will never return. * * --- * * @example * ```ts * const iterator = new SmartIterator<number>([-2, -1, 0, 1, 2]); * const result = iterator.every((value) => value < 0); * * console.log(result); // false * ``` * * --- * * @param predicate The condition to check for each element of the iterator. * * @returns `true` if all elements satisfy the condition, `false` otherwise. */ every(n) { let e = 0; for (; ; ) { const t = this._iterator.next(); if (t.done) return !0; if (!n(t.value, e)) return !1; e += 1; } } /** * Determines whether any element of the iterator satisfies a given condition. * See also {@link SmartIterator.every}. * * This method will iterate over all elements of the iterator checking if they satisfy the condition. * Once a single element satisfies the condition, the method will return `true` immediately. * * This may lead to an unknown final state of the iterator, which may be entirely or partially consumed. * For this reason, it's recommended to consider it as consumed in any case and to not use it anymore. * Consider using {@link SmartIterator.find} instead. * * If the iterator is infinite and no element satisfies the condition, the method will never return. * * --- * * @example * ```ts * const iterator = new SmartIterator<number>([-2, -1, 0, 1, 2]); * const result = iterator.some((value) => value < 0); * * console.log(result); // true * ``` * * --- * * @param predicate The condition to check for each element of the iterator. * * @returns `true` if any element satisfies the condition, `false` otherwise. */ some(n) { let e = 0; for (; ; ) { const t = this._iterator.next(); if (t.done) return !1; if (n(t.value, e)) return !0; e += 1; } } filter(n) { const e = this._iterator; return new u(function* () { let t = 0; for (; ; ) { const s = e.next(); if (s.done) return s.value; n(s.value, t) && (yield s.value), t += 1; } }); } /** * Maps the elements of the iterator using a given transformation function. * * This method will iterate over all elements of the iterator applying the transformation function. * The result of each transformation will be included in the new iterator. * * Since the iterator is lazy, the mapping process will * be executed once the resulting iterator is materialized. * * A new iterator will be created, holding the reference to the original one. * This means that the original iterator won't be consumed until the * new one is and that consuming one of them will consume the other as well. * * --- * * @example * ```ts * const iterator = new SmartIterator<number>([-2, -1, 0, 1, 2]); * const result = iterator.map((value) => Math.abs(value)); * * console.log(result.toArray()); // [2, 1, 0, 1, 2] * ``` * * --- * * @template V The type of the elements after the transformation. * * @param iteratee The transformation function to apply to each element of the iterator. * * @returns A new {@link SmartIterator} containing the transformed elements. */ map(n) { const e = this._iterator; return new u(function* () { let t = 0; for (; ; ) { const s = e.next(); if (s.done) return s.value; yield n(s.value, t), t += 1; } }); } reduce(n, e) { let t = 0, s = e; if (s === void 0) { const r = this._iterator.next(); if (r.done) throw new f("Cannot reduce an empty iterator without an initial value."); s = r.value, t += 1; } for (; ; ) { const r = this._iterator.next(); if (r.done) return s; s = n(s, r.value, t), t += 1; } } /** * Flattens the elements of the iterator using a given transformation function. * * This method will iterate over all elements of the iterator applying the transformation function. * The result of each transformation will be flattened into the new iterator. * * Since the iterator is lazy, the flattening process will * be executed once the resulting iterator is materialized. * * A new iterator will be created, holding the reference to the original one. * This means that the original iterator won't be consumed until the * new one is and that consuming one of them will consume the other as well. * * --- * * @example * ```ts * const iterator = new SmartIterator<number[]>([[-2, -1], 0, 1, 2, [3, 4, 5]]); * const result = iterator.flatMap((value) => value); * * console.log(result.toArray()); // [-2, -1, 0, 1, 2, 3, 4, 5] * ``` * * --- * * @template V The type of the elements after the transformation. * * @param iteratee The transformation function to apply to each element of the iterator. * * @returns A new {@link SmartIterator} containing the flattened elements. */ flatMap(n) { const e = this._iterator; return new u(function* () { let t = 0; for (; ; ) { const s = e.next(); if (s.done) return s.value; const r = n(s.value, t); if (r instanceof Array) for (const o of r) yield o; else yield r; t += 1; } }); } /** * Drops a given number of elements at the beginning of the iterator. * The remaining elements will be included in a new iterator. * See also {@link SmartIterator.take}. * * Since the iterator is lazy, the dropping process will * be executed once the resulting iterator is materialized. * * A new iterator will be created, holding the reference to the original one. * This means that the original iterator won't be consumed until the * new one is and that consuming one of them will consume the other as well. * * Only the dropped elements will be consumed in the process. * The rest of the iterator will be consumed only once the new one is. * * --- * * @example * ```ts * const iterator = new SmartIterator<number>([-2, -1, 0, 1, 2]); * const result = iterator.drop(3); * * console.log(result.toArray()); // [1, 2] * ``` * * --- * * @param count The number of elements to drop. * * @returns A new {@link SmartIterator} containing the remaining elements. */ drop(n) { const e = this._iterator; return new u(function* () { let t = 0; for (; t < n; ) { if (e.next().done) return; t += 1; } for (; ; ) { const s = e.next(); if (s.done) return s.value; yield s.value; } }); } /** * Takes a given number of elements at the beginning of the iterator. * These elements will be included in a new iterator. * See also {@link SmartIterator.drop}. * * Since the iterator is lazy, the taking process will * be executed once the resulting iterator is materialized. * * A new iterator will be created, holding the reference to the original one. * This means that the original iterator won't be consumed until the * new one is and that consuming one of them will consume the other as well. * * Only the taken elements will be consumed from the original iterator. * The rest of the original iterator will be available for further consumption. * * --- * * @example * ```ts * const iterator = new SmartIterator<number>([-2, -1, 0, 1, 2]); * const result = iterator.take(3); * * console.log(result.toArray()); // [-2, -1, 0] * console.log(iterator.toArray()); // [1, 2] * ``` * * --- * * @param limit The number of elements to take. * * @returns A new {@link SmartIterator} containing the taken elements. */ take(n) { const e = this._iterator; return new u(function* () { let t = 0; for (; t < n; ) { const s = e.next(); if (s.done) return s.value; yield s.value, t += 1; } }); } find(n) { let e = 0; for (; ; ) { const t = this._iterator.next(); if (t.done) return; if (n(t.value, e)) return t.value; e += 1; } } /** * Enumerates the elements of the iterator. * Each element is be paired with its index in a new iterator. * * Since the iterator is lazy, the enumeration process will * be executed once the resulting iterator is materialized. * * A new iterator will be created, holding the reference to the original one. * This means that the original iterator won't be consumed until the * new one is and that consuming one of them will consume the other as well. * * --- * * @example * ```ts * const iterator = new SmartIterator<string>(["A", "M", "N", "Z"]); * const result = iterator.enumerate(); * * console.log(result.toArray()); // [[0, "A"], [1, "M"], [2, "N"], [3, "Z"]] * ``` * * --- * * @returns A new {@link SmartIterator} containing the enumerated elements. */ enumerate() { return this.map((n, e) => [e, n]); } /** * Removes all duplicate elements from the iterator. * The first occurrence of each element will be kept. * * Since the iterator is lazy, the deduplication process will * be executed once the resulting iterator is materialized. * * A new iterator will be created, holding the reference to the original one. * This means that the original iterator won't be consumed until the * new one is and that consuming one of them will consume the other as well. * * --- * * @example * ```ts * const iterator = new SmartIterator<number>([1, 1, 2, 3, 2, 3, 4, 5, 5, 4]); * const result = iterator.unique(); * * console.log(result.toArray()); // [1, 2, 3, 4, 5] * ``` * * --- * * @returns A new {@link SmartIterator} containing only the unique elements. */ unique() { const n = this._iterator; return new u(function* () { const e = /* @__PURE__ */ new Set(); for (; ; ) { const t = n.next(); if (t.done) return t.value; e.has(t.value) || (e.add(t.value), yield t.value); } }); } /** * Counts the number of elements in the iterator. * This method will consume the entire iterator in the process. * * If the iterator is infinite, the method will never return. * * --- * * @example * ```ts * const iterator = new SmartIterator<number>([1, 2, 3, 4, 5]); * const result = iterator.count(); * * console.log(result); // 5 * ``` * * --- * * @returns The number of elements in the iterator. */ count() { let n = 0; for (; ; ) { if (this._iterator.next().done) return n; n += 1; } } /** * Iterates over all elements of the iterator. * The elements are passed to the function along with their index. * * This method will consume the entire iterator in the process. * If the iterator is infinite, the method will never return. * * --- * * @example * ```ts * const iterator = new SmartIterator<number>(["A", "M", "N", "Z"]); * iterator.forEach((value, index) => * { * console.log(`${index}: ${value}`); // "0: A", "1: M", "2: N", "3: Z" * } * ``` * * --- * * @param iteratee The function to apply to each element of the iterator. */ forEach(n) { let e = 0; for (; ; ) { const t = this._iterator.next(); if (t.done) return; n(t.value, e), e += 1; } } /** * Advances the iterator to the next element and returns the result. * If the iterator requires it, a value must be provided to be passed to the next element. * * Once the iterator is done, the method will return an object with the `done` property set to `true`. * * --- * * @example * ```ts * const iterator = new SmartIterator<number>([1, 2, 3, 4, 5]); * * let result = iterator.next(); * while (!result.done) * { * console.log(result.value); // 1, 2, 3, 4, 5 * * result = iterator.next(); * } * * console.log(result); // { done: true, value: undefined } * ``` * * --- * * @param values The value to pass to the next element, if required. * * @returns The result of the iteration, containing the value of the operation. */ next(...n) { return this._iterator.next(...n); } /** * An utility method that may be used to close the iterator gracefully, * free the resources and perform any cleanup operation. * It may also be used to signal the end or to compute a specific final result of the iteration process. * * --- * * @example * ```ts * const iterator = new SmartIterator<number>({ * _index: 0, * next: function() * { * return { done: false, value: this._index += 1 }; * }, * return: function() { console.log("Closing the iterator..."); } * }); * * for (const value of iterator) * { * if (value > 5) { break; } // "Closing the iterator..." * * console.log(value); // 1, 2, 3, 4, 5 * } * ``` * * --- * * @param value The final value of the iterator. * * @returns The result of the iterator. */ return(n) { return this._iterator.return ? this._iterator.return(n) : { done: !0, value: n }; } /** * An utility method that may be used to close the iterator due to an error, * free the resources and perform any cleanup operation. * It may also be used to signal that an error occurred during the iteration process or to handle it. * * --- * * @example * ```ts * const iterator = new SmartIterator<number>({ * _index: 0, * next: function() * { * return { done: this._index > 10, value: this._index += 1 }; * }, * throw: function(error) * { * console.warn(error.message); * * this._index = 0; * } * }); * * for (const value of iterator) // 1, 2, 3, 4, 5, "The index is too high.", 1, 2, 3, 4, 5, ... * { * try * { * if (value > 5) { throw new Error("The index is too high."); } * * console.log(value); // 1, 2, 3, 4, 5 * } * catch (error) { iterator.throw(error); } * } * ``` * * --- * * @param error The error to throw into the iterator. * * @returns The final result of the iterator. */ throw(n) { if (this._iterator.throw) return this._iterator.throw(n); throw n; } /** * An utility method that aggregates the elements of the iterator using a given key function. * The elements will be grouped by the resulting keys in a new specialized iterator. * See {@link AggregatedIterator}. * * Since the iterator is lazy, the grouping process will * be executed once the resulting iterator is materialized. * * A new iterator will be created, holding the reference to the original one. * This means that the original iterator won't be consumed until the * the new one is and that consuming one of them will consume the other as well. * * --- * * @example * ```ts * const iterator = new SmartIterator<number>([1, 2, 3, 4, 5, 6, 7, 8, 9, 10]); * const result = iterator.groupBy<string>((value) => value % 2 === 0 ? "even" : "odd"); * * console.log(result.toObject()); // { odd: [1, 3, 5, 7, 9], even: [2, 4, 6, 8, 10] } * ``` * * --- * * @template K The type of the keys used to group the elements. * * @param iteratee The key function to apply to each element of the iterator. * * @returns A new instance of the {@link AggregatedIterator} class containing the grouped elements. */ groupBy(n) { return new x(this.map((e, t) => [n(e, t), e])); } /** * Materializes the iterator into an array. * This method will consume the entire iterator in the process. * * If the iterator is infinite, the method will never return. * * --- * * @example * ```ts * const iterator = new SmartIterator(function* () * { * for (let i = 0; i < 5; i += 1) { yield i; } * }); * const result = iterator.toArray(); * * console.log(result); // [0, 1, 2, 3, 4] * ``` * * --- * * @returns The {@link Array} containing all elements of the iterator. */ toArray() { return Array.from(this); } [(we = Symbol.toStringTag, Symbol.iterator)]() { return this; } } var me; me = Symbol.toStringTag; const y = class y { constructor(n) { /** * The internal {@link SmartIterator} object that holds the reduced elements. */ a(this, "_elements"); a(this, me, "ReducedIterator"); this._elements = new u(n); } /** * Determines whether all elements of the reduced iterator satisfy the given condition. * See also {@link ReducedIterator.some}. * * This method will iterate over all the elements of the iterator checking if they satisfy the condition. * Once a single element doesn't satisfy the condition, the method will return `false` immediately. * * This may lead to an unknown final state of the iterator, which may be entirely or partially consumed. * For this reason, it's recommended to consider it as consumed in any case and to not use it anymore. * Consider using {@link ReducedIterator.find} instead. * * If the iterator is infinite and every element satisfies the condition, the method will never return. * * --- * * @example * ```ts * const results = new SmartIterator<number>([-3, -1, 0, 2, 3, 5, 6, 8]) * .groupBy((value) => value % 2 === 0 ? "even" : "odd") * .reduce((key, accumulator, value) => accumulator + value) * .every((key, value) => value > 0); * * console.log(results); // true * ``` * * --- * * @param predicate The condition to check for each element of the iterator. * * @returns `true` if all elements satisfy the condition, `false` otherwise. */ every(n) { for (const [e, [t, s]] of this._elements.enumerate()) if (!n(t, s, e)) return !1; return !0; } /** * Determines whether any element of the reduced iterator satisfies the given condition. * See also {@link ReducedIterator.every}. * * This method will iterate over all the elements of the iterator checking if they satisfy the condition. * Once a single element satisfies the condition, the method will return `true` immediately. * * This may lead to an unknown final state of the iterator, which may be entirely or partially consumed. * For this reason, it's recommended to consider it as consumed in any case and to not use it anymore. * Consider using {@link ReducedIterator.find} instead. * * If the iterator is infinite and no element satisfies the condition, the method will never return. * * --- * * @example * ```ts * const results = new SmartIterator<number>([-3, -1, 0, 2, 3, 5, 6, 8]) * .groupBy((value) => value % 2 === 0 ? "even" : "odd") * .reduce((key, accumulator, value) => accumulator + value) * .some((key, value) => value > 0); * * console.log(results); // true * ``` * * --- * * @param predicate The condition to check for each element of the iterator. * * @returns `true` if any element satisfies the condition, `false` otherwise. */ some(n) { for (const [e, [t, s]] of this._elements.enumerate()) if (n(t, s, e)) return !0; return !1; } filter(n) { const e = this._elements.enumerate(); return new y(function* () { for (const [t, [s, r]] of e) n(s, r, t) && (yield [s, r]); }); } /** * Maps the elements of the reduced iterator using a given transformation function. * * This method will iterate over all the elements of the iterator applying the transformation function. * The result of the transformation will be included in the new iterator. * * Since the iterator is lazy, the mapping process will * be executed once the resulting iterator is materialized. * * A new iterator will be created, holding the reference to the original one. * This means that the original iterator won't be consumed until the * new one is and that consuming one of them will consume the other as well. * * --- * * @example * ```ts * const results = new SmartIterator<number>([-3, -1, 0, 2, 3, 5, 6, 8]) * .groupBy((value) => value % 2 === 0 ? "even" : "odd") * .reduce((key, accumulator, value) => accumulator + value) * .map((key, value) => value * 2); * * console.log(results.toObject()); // { odd: 8, even: 32 } * ``` * * --- * * @template V The type of the elements after the transformation. * * @param iteratee The transformation function to apply to each element of the iterator. * * @returns A new {@link ReducedIterator} containing the transformed elements. */ map(n) { const e = this._elements.enumerate(); return new y(function* () { for (const [t, [s, r]] of e) yield [s, n(s, r, t)]; }); } reduce(n, e) { let t = 0, s = e; if (s === void 0) { const r = this._elements.next(); if (r.done) throw new f("Cannot reduce an empty iterator without an initial value."); s = r.value[1], t += 1; } for (const [r, o] of this._elements) s = n(r, s, o, t), t += 1; return s; } /** * Flattens the elements of the reduced iterator using a given transformation function. * * This method will iterate over all the elements of the iterator applying the transformation function. * The result of each transformation will be flattened into the new iterator. * * Since the iterator is lazy, the flattening process will * be executed once the resulting iterator is materialized. * * A new iterator will be created, holding the reference to the original one. * This means that the original iterator won't be consumed until the * new one is and that consuming one of them will consume the other as well. * * --- * * @example * ```ts * const results = new SmartIterator<number>([-3, -1, 0, 2, 3, 5, 6, 8]) * .groupBy((value) => value % 2 === 0 ? "even" : "odd") * .reduce((key, accumulator, value) => accumulator.concat([value]), () => []) * .flatMap((key, value) => value); * * console.log(results.toObject()); // { odd: [-3, -1, 3, 5], even: [0, 2, 6, 8] } * ``` * * --- * * @template V The type of the elements after the transformation. * * @param iteratee The transformation function to apply to each element of the iterator. * * @returns A new {@link AggregatedIterator} containing the flattened elements. */ flatMap(n) { const e = this._elements.enumerate(); return new x(function* () { for (const [t, [s, r]] of e) { const o = n(s, r, t); if (o instanceof Array) for (const l of o) yield [s, l]; else yield [s, o]; } }); } /** * Drops a given number of elements at the beginning of the reduced iterator. * The remaining elements will be included in the new iterator. * See also {@link ReducedIterator.take}. * * Since the iterator is lazy, the dropping process will * be executed once the resulting iterator is materialized. * * A new iterator will be created, holding the reference to the original one. * This means that the original iterator won't be consumed until the * new one is and that consuming one of them will consume the other as well. * * Only the dropped elements will be consumed in the process. * The rest of the iterator will be consumed once the new iterator is. * * --- * * @example * ```ts * const results = new SmartIterator<number>([-3, -1, 0, 2, 3, 5, 6, 8]) * .groupBy((value) => value % 2 === 0 ? "even" : "odd") * .reduce((key, accumulator, value) => accumulator.concat(value), () => []) * .drop(1); * * console.log(results.toObject()); // { even: [0, 2, 6, 8] } * ``` * * --- * * @param count The number of elements to drop. * * @returns A new {@link ReducedIterator} containing the remaining elements. */ drop(n) { const e = this._elements.enumerate(); return new y(function* () { for (const [t, [s, r]] of e) t >= n && (yield [s, r]); }); } /** * Takes a given number of elements at the beginning of the reduced iterator. * The elements will be included in the new iterator. * See also {@link ReducedIterator.drop}. * * Since the iterator is lazy, the taking process will * be executed once the resulting iterator is materialized. * * A new iterator will be created, holding the reference to the original one. * This means that the original iterator won't be consumed until the * new one is and that consuming one of them will consume the other as well. * * Only the taken elements will be consumed from the original reduced iterator. * The rest of the original reduced iterator will be available for further consumption. * * --- * * @example * ```ts * const reduced = new SmartIterator<number>([-3, -1, 0, 2, 3, 5, 6, 8]) * .groupBy((value) => value % 2 === 0 ? "even" : "odd") * .reduce((key, accumulator, value) => accumulator.concat(value), () => []); * * const results = iterator.take(1); * * console.log(results.toObject()); // { odd: [-3, -1, 3, 5] } * console.log(reduced.toObject()); // { even: [0, 2, 6, 8] } * ``` * * --- * * @param limit The number of elements to take. * * @returns A new {@link ReducedIterator} containing the taken elements. */ take(n) { const e = this._elements.enumerate(); return new y(function* () { for (const [t, [s, r]] of e) { if (t >= n) break; yield [s, r]; } }); } find(n) { for (const [e, [t, s]] of this._elements.enumerate()) if (n(t, s, e)) return s; } /** * Enumerates the elements of the reduced iterator. * Each element is paired with its index in a new iterator. * * Since the iterator is lazy, the enumeration process will * be executed once the resulting iterator is materialized. * * A new iterator will be created, holding the reference to the original one. * This means that the original iterator won't be consumed until the * new one is and that consuming one of them will consume the other as well. * * --- * * @example * ```ts * const results = new ReducedIterator<number>([-3, -1, 0, 2, 3, 5, 6, 8]) * .groupBy((value) => value % 2 === 0 ? "even" : "odd") * .reduce((key, accumulator, value) => accumulator + value) * .enumerate(); * * console.log(results.toObject()); // [[0, 4], [1, 16]] * ``` * * --- * * @returns A new {@link ReducedIterator} object containing the enumerated elements. */ enumerate() { return this.map((n, e, t) => [t, e]); } /** * Removes all duplicate elements from the reduced iterator. * The first occurrence of each element will be kept. * * Since the iterator is lazy, the deduplication process will * be executed once the resulting iterator is materialized. * * A new iterator will be created, holding the reference to the original one. * This means that the original iterator won't be consumed until the * new one is and that consuming one of them will consume the other as well. * * --- * * @example * ```ts * const results = new ReducedIterator<number>([-3, -1, 0, 2, 3, 6, -3, -1, 1, 5, 6, 8, 7, 2]) * .groupBy((value) => value % 2 === 0 ? "even" : "odd") * .map((key, value) => Math.abs(value)) * .reduce((key, accumulator, value) => accumulator + value) * .unique(); * * console.log(results.toObject()); // { odd: 24 } * * @returns A new {@link ReducedIterator} containing only the unique elements. */ unique() { const n = this._elements; return new y(function* () { const e = /* @__PURE__ */ new Set(); for (const [t, s] of n) e.has(s) || (e.add(s), yield [t, s]); }); } /** * Counts the number of elements in the reduced iterator. * This method will consume the entire iterator in the process. * * If the iterator is infinite, the method will never return. * * --- * * @example * ```ts * const results = new SmartIterator<number>([-3, -1, 0, 2, 3, 5, 6, 8]) * .groupBy((value) => value % 2 === 0 ? "even" : "odd") * .reduce((key, accumulator, value) => accumulator + value) * .count(); * * console.log(results); // 2 * ``` * * --- * * @returns The number of elements in the iterator. */ count() { let n = 0; for (const e of this._elements) n += 1; return n; } /** * Iterates over all elements of the reduced iterator. * The elements are passed to the function along with their key and index. * * This method will consume the entire iterator in the process. * If the iterator is infinite, the method will never return. * * --- * * @example * ```ts * const reduced = new SmartIterator<number>([-3, -1, 0, 2, 3, 5, 6, 8]) * .groupBy((value) => value % 2 === 0 ? "even" : "odd") * .reduce((key, accumulator, value) => accumulator + value); * * reduced.forEach((key, value, index) => * { * console.log(`#${index} - ${key}: ${value}`); // "#0 - odd: 4", "#1 - even: 16" * }); * ``` * * --- * * @param iteratee The function to apply to each element of the reduced iterator. */ forEach(n) { for (const [e, [t, s]] of this._elements.enumerate()) n(t, s, e); } /** * Reaggregates the elements of the reduced iterator. * The elements are grouped by a new key computed by the given iteratee function. * * Since the iterator is lazy, the reorganizing process will * be executed once the resulting iterator is materialized. * * A new iterator will be created, holding the reference to the original one. * This means that the original iterator won't be consumed until the * new one is and that consuming one of them will consume the other as well. * * --- * * @example * ```ts * const results = new SmartIterator<number>([-3, -1, 0, 2, 3, 5, -6, -8]) * .groupBy((value) => value % 2 === 0 ? "even" : "odd") * .reduce((key, accumulator, value) => accumulator + value) * .reorganizeBy((key, value) => value > 0 ? "positive" : "negative"); * * console.log(results.toObject()); // { positive: 4, negative: -12 } * ``` * * --- * * @template J The type of the new keys used to group the elements. * * @param iteratee The function to determine the new key of each element of the iterator. * * @returns A new {@link AggregatedIterator} containing the elements reorganized by the new keys. */ reorganizeBy(n) { const e = this._elements.enumerate(); return new x(function* () { for (const [t, [s, r]] of e) yield [n(s, r, t), r]; }); } /** * An utility method that returns a new {@link SmartIterator} * object containing all the keys of the iterator. * * Since the iterator is lazy, the keys will be extracted * be executed once the resulting iterator is materialized. * * A new iterator will be created, holding the reference to the original one. * This means that the original iterator won't be consumed until the * new one is and that consuming one of them will consume the other as well. * * --- * * @example * ```ts * const keys = new SmartIterator<number>([-3, -1, 0, 2, 3, 5, 6, 8]) * .groupBy((value) => value % 2 === 0 ? "even" : "odd") * .reduce((key, accumulator, value) => accumulator + value) * .keys(); * * console.log(keys.toArray()); // ["odd", "even"] * ``` * * --- * * @returns A new {@link SmartIterator} containing all the keys of the iterator. */ keys() { const n = this._elements; return new u(function* () { for (const [e] of n) yield e; }); } /** * An utility method that returns a new {@link SmartIterator} * object containing all the entries of the iterator. * Each entry is a tuple containing the key and the element. * * Since the iterator is lazy, the entries will be extracted * be executed once the resulting iterator is materialized. * * A new iterator will be created, holding the reference to the original one. * This means that the original iterator won't be consumed until the * new one is and that consuming one of them will consume the other as well. * * --- * * @example * ```ts * const entries = new SmartIterator<number>([-3, -1, 0, 2, 3, 5, 6, 8]) * .groupBy((value) => value % 2 === 0 ? "even" : "odd") * .reduce((key, accumulator, value) => accumulator + value) * .entries(); * * console.log(entries.toArray()); // [["odd", 4], ["even", 16]] * ``` * * --- * * @returns A new {@link SmartIterator} containing all the entries of the iterator. */ entries() { return this._elements; } /** * An utility method that returns a new {@link SmartIterator} * object containing all the values of the iterator. * * Since the iterator is lazy, the values will be extracted * be executed once the resulting iterator is materialized. * * A new iterator will be created, holding the reference to the original one. * This means that the original iterator won't be consumed until the * new one is and that consuming one of them will consume the other as well. * * --- * * @example * ```ts * const values = new SmartIterator<number>([-3, -1, 0, 2, 3, 5, 6, 8]) * .groupBy((value) => value % 2 === 0 ? "even" : "odd") * .reduce((key, accumulator, value) => accumulator + value) * .values(); * * console.log(values.toArray()); // [4, 16] * ``` * * --- * * @returns A new {@link SmartIterator} containing all the values of the iterator. */ values() { const n = this._elements; return new u(function* () { for (const [e, t] of n) yield t; }); } /** * Materializes the iterator into an array. * This method will consume the entire iterator in the process. * * If the iterator is infinite, the method will never return. * * --- * * @example * ```ts * const reduced = new SmartIterator<number>([-3, -1, 0, 2, 3, 5, 6, 8]) * .groupBy((value) => value % 2 === 0 ? "even" : "odd") * .reduce((key, accumulator, value) => accumulator + value); * * console.log(reduced.toArray()); // [4, 16] * ``` * * --- * * @returns The {@link Array} containing all elements of the iterator. */ toArray() { return Array.from(this.values()); } /** * Materializes the iterator into a map. * This method will consume the entire iterator in the process. * * If the iterator is infinite, the method will never return. * * --- * * @example * ```ts * const reduced = new SmartIterator<number>([-3, -1, 0, 2, 3, 5, 6, 8]) * .groupBy((value) => value % 2 === 0 ? "even" : "odd") * .reduce((key, accumulator, value) => accumulator + value); * * console.log(reduced.toMap()); // Map(2) { "odd" => 4, "even" => 16 } * ``` * * --- * * @returns The {@link Map} containing all elements of the iterator. */ toMap() { return new Map(this.entries()); } /** * Materializes the iterator into an object. * This method will consume the entire iterator in the process. * * If the iterator is infinite, the method will never return. * * --- * * @example * ```ts * const reduced = new SmartIterator<number>([-3, -1, 0, 2, 3, 5, 6, 8]) * .groupBy((value) => value % 2 === 0 ? "even" : "odd") * .reduce((key, accumulator, value) => accumulator + value); * * console.log(reduced.toObject()); // { odd: 4, even: 16 } * ``` * * --- * * @returns The {@link Object} containing all elements of the iterator. */ toObject() { return Object.fromEntries(this.entries()); } }; let h = y; var pe; pe = Symbol.toStringTag; const w = class w { constructor(n) { /** * The internal {@link SmartAsyncIterator} object that holds the elements to aggregate. */ a(this, "_elements"); a(this, pe, "AggregatedAsyncIterator"); this._elements = new d(n); } /** * Determines whether all elements of each group of the iterator satisfy a given condition. * See also {@link AggregatedAsyncIterator.some}. * This method will consume t