UNPKG

@dpaskhin/unique

Version:

Ensures unique values by rejecting duplicates.

168 lines (166 loc) 6.68 kB
/** * Configuration options for the unique value generation process. * * @template Value The type of the value being processed for uniqueness. */ type IOptions<Value> = { /** * Optional store to keep track of unique values. */ store?: Set<unknown>; /** * The maximum number of retries allowed to generate a unique value before throwing an error. Defaults to 50. */ maxRetries?: number; /** * The maximum time allowed (in milliseconds) for generating a unique value before throwing an error. Defaults to 50ms. */ maxTime?: number; /** * A list of values to be excluded from the result set. When a stringifier is provided, the list will be stringified. */ exclude?: Value[]; /** * A function to stringify a result value before storing it in the set and checking for uniqueness. Defaults to {@link JSON.stringify}. */ stringifier?: (value: Value) => string; }; /** * Creates a function that generates unique values based on the passed function `fn`. * * @template Fn The type of the function passed to generate values. * * @param {Fn} fn - The function to generate values * @param {IOptions<Fn>} [options={}] - Optional configuration for controlling the uniqueness generation process. * @returns {(args: Parameters<Fn>) => ReturnType<Fn>} A new function that generates unique values based on `fn`. * * @throws {Error} Throws an error if the max retries or max time is exceeded. * * @example * ```ts * import { uniqueFactory } from '@dpaskhin/unique'; * import { faker } from '@faker-js/faker'; * * // Example of generating unique user objects * const createUniqueUser = uniqueFactory(() => ({ * firstName: faker.person.firstName(), * lastName: faker.person.lastName(), * age: faker.number.int({ min: 18, max: 100 }), * })); * * // Outputs a structurally unique user * console.log(createUniqueUser()); * ``` */ declare function uniqueFactory<Fn extends (...args: any[]) => any>(fn: Fn, options?: IOptions<ReturnType<Fn>>): (...args: Parameters<Fn>) => ReturnType<Fn>; /** * A global store to track unique values across the application. * * @example * ```ts * import { GLOBAL_STORE, unique } from '@dpaskhin/unique'; * * // Uses GLOBAL_STORE * const uniqueRandomValue1 = unique(Math.random); * // Uses GLOBAL_STORE * const uniqueRandomValue2 = unique(Math.random); * * // Outputs two unique values * console.log(uniqueRandomValue1, uniqueRandomValue2); * * // Clear the global store when needed * GLOBAL_STORE.clear(); * ``` */ declare const GLOBAL_STORE: Set<unknown>; /** * Generates a unique value using the provided function `fn` that takes no arguments. * * **Note:** The global store is used by default and shared across the application. * For isolated usage, provide a custom `store` in the options. * * **Best Practice:** Use a custom store to avoid shared state and unexpected results. * * @template Fn The type of the function that generates values without arguments. * * @param {Fn} fn - The function to generate values. This function does not accept any arguments. * @param {never[]} [args] - No arguments are passed to functions that do not accept arguments. * @param {IOptions<ReturnType<Fn>>} [options] - Optional configuration for controlling the uniqueness generation process. * @returns {ReturnType<Fn>} The unique value generated by the function `fn`. * * @throws {Error} Throws an error if the max retries or max time is exceeded. * * @example * ```ts * import { unique } from '@dpaskhin/unique'; * import { faker } from '@faker-js/faker'; * * // Outputs a unique city name * console.log(unique(faker.location.city)); * ``` */ declare function unique<Fn extends () => any>(fn: Fn, args?: never[], options?: IOptions<ReturnType<Fn>>): ReturnType<Fn>; /** * Generates a unique value using the provided function `fn` that accepts arguments. * * **Note:** The global store is used by default and shared across the application. * For isolated usage, provide a custom `store` in the options. * * **Best Practice:** Use a custom store to avoid shared state and unexpected results. * * @template Fn The type of the function that generates values and accepts arguments. * * @param {Fn} fn - The function to generate values. This function must accept arguments. * @param {Parameters<Fn>} args - The arguments to be passed to the function `fn`. * @param {IOptions<ReturnType<Fn>>} [options] - Optional configuration for controlling the uniqueness generation process. * @returns {ReturnType<Fn>} The unique value generated by the function `fn`. * * @throws {Error} Throws an error if the max retries or max time is exceeded. * * @example * ```ts * import { unique } from '@dpaskhin/unique'; * import { faker } from '@faker-js/faker'; * * // Example with a function that takes arguments * const uniqueEmail = unique( * faker.internet.email, * [{ firstName: faker.person.firstName(), lastName: faker.person.lastName() }], * { maxRetries: 10 } * ); * * // Outputs a unique user's email * console.log(uniqueEmail); * ``` */ declare function unique<Fn extends (...args: any[]) => any>(fn: Fn, args: Parameters<Fn>, options?: IOptions<ReturnType<Fn>>): ReturnType<Fn>; /** * Ensures a unique value from the provided `value`, which is not a function. * There's only one attempt to check the uniqueness of the `value`. * * **Note:** The global store is used by default and shared across the application. * For isolated usage, provide a custom `store` in the options. * * **Best Practice:** Use a custom store to avoid shared state and unexpected results. * * @template Value The type of the value to ensure uniqueness. * * @param {NotFunction<Value>} value - The plain value to ensure uniqueness for. Must not be a function. * @param {Omit<IOptions<Value>, 'maxRetries' | 'maxTime'>} [options] - Optional configuration for controlling the uniqueness generation process. * @returns {Value} The unique value ensured by the `unique` function. * * @throws {Error} Throws an error if the value already exists in the store. * * @example * ```ts * import { unique } from '@dpaskhin/unique'; * * // Each time outputs a unique ID string or throws an error * console.log(unique(window.crypto.randomUUID())); * console.log(unique(window.crypto.randomUUID())); * console.log(unique(window.crypto.randomUUID())); * ``` */ declare function unique<Value>(value: NotFunction<Value>, options?: Omit<IOptions<Value>, 'maxRetries' | 'maxTime'>): Value; type NotFunction<T> = T extends (...args: any[]) => any ? never : T; export { GLOBAL_STORE, unique, uniqueFactory };