@dpaskhin/unique
Version:
Ensures unique values by rejecting duplicates.
265 lines (187 loc) • 8.18 kB
Markdown
**@dpaskhin/unique** is a TypeScript library for generating unique values. It ensures no duplicates by rejecting repeats
and retrying until a new result is found. Ideal for ensuring non-repeated random values.
To install **@dpaskhin/unique**, run:
```shell
npm install --save-dev @dpaskhin/unique
```
- Generate unique values based on the output of any function or plain value.
- Supports `custom` stores or `global` storage for uniqueness tracking.
- Configurable `retry` and `timeout` options.
- `stringifier` support for custom handling of complex objects during uniqueness checks.
- [~600B gzipped.](https://bundlephobia.com/package/@dpaskhin/unique)
Here’s a quick example using **@dpaskhin/unique**:
```ts
import { unique } from '@dpaskhin/unique';
// Outputs a unique random number each time
console.log(unique(Math.random));
console.log(unique(Math.random));
console.log(unique(Math.random));
```
**@dpaskhin/unique** works well with libraries like [Faker.js](https://github.com/faker-js/faker) for generating unique
random data.
```ts
import { unique, uniqueFactory } from '@dpaskhin/unique';
import { faker } from '@faker-js/faker';
// Outputs a unique first name each time
console.log(unique(faker.person.firstName));
console.log(unique(faker.person.firstName));
console.log(unique(faker.person.firstName));
// ----------------------------------------
const createUniqueUser = uniqueFactory(() => ({
firstName: faker.person.firstName(),
lastName: faker.person.lastName(),
age: faker.number.int({ min: 18, max: 100 }),
}));
// Each output user is structurally unique
console.log(createUniqueUser());
console.log(createUniqueUser());
console.log(createUniqueUser());
```
You can provide your own store to isolate uniqueness checks. This ensures that uniqueness is tracked within the scope of
your application.
```ts
import { unique } from '@dpaskhin/unique';
const scopedStore = new Set();
// Outputs a unique random number
console.log(unique(Math.random, [], { store: scopedStore }));
```
If you don’t provide a custom store, the library will use the **GLOBAL_STORE** by default. This can be useful if you
want to track unique values across different parts of your application.
```ts
import { unique, GLOBAL_STORE } from '@dpaskhin/unique';
// Use the global store for uniqueness checks
const uniqueRandomValue1 = unique(Math.random);
const uniqueRandomValue2 = unique(Math.random);
// Outputs two unique random values
console.log(uniqueRandomValue1, uniqueRandomValue2);
// Clear the global store when needed
GLOBAL_STORE.clear();
```
You can also provide an exclude list to prevent specific values from being considered during uniqueness checks.
```ts
import { uniqueFactory } from '@dpaskhin/unique';
const createUniqueRandom = uniqueFactory(Math.random, {
// Prevents these values from being returned
exclude: [0.5, 0.6],
});
// Outputs a unique random number, excluding 0.5 and 0.6
console.log(createUniqueRandom());
```
The **stringifier** option allows you to handle complex objects by converting them into strings for uniqueness checks.
_By default, `JSON.stringify` is used as the stringifier._
```ts
import { uniqueFactory } from '@dpaskhin/unique';
import { faker } from '@faker-js/faker';
import JsonMarshal from 'json-marshal';
const createUniqueUser = uniqueFactory(
() => ({
name: faker.person.firstName(),
age: faker.number.int({ min: 18, max: 100 }),
}),
{
// Here can be any function that takes the return value of the function provided above and converts it to a string.
// Or just omit it, JSON.stringify will be used instead.
stringifier: JsonMarshal.stringify,
}
);
const user1 = createUniqueUser();
const user2 = createUniqueUser();
// Outputs two unique users
console.log(user1, user2);
```
Creates a function that ensures unique results based on the provided function fn.
- fn - The function used to generate values.
- options - Optional. An object containing configuration options:
- **store** (Set): A custom store to track unique values. Defaults to a **new Set**.
- **maxRetries** (number): The maximum number of retries to generate a unique value before throwing an error.
Defaults to 50.
- **maxTime** (number): The maximum time (in milliseconds) to attempt generating a unique value before throwing an
error. Defaults to 50ms.
- **exclude** (Array): A list of values to exclude from the result set. These values will not be
returned by the unique generator.
- **stringifier** (function): A function to stringify a result before storing it. Defaults to JSON.stringify.
#### Returns
A function that generates unique values based on fn with the same signature.
#### Example
```ts
import { uniqueFactory } from '@dpaskhin/unique';
import { faker } from '@faker-js/faker';
const createUniqueUser = uniqueFactory(() => ({
name: faker.person.firstName(),
age: faker.number.int({ min: 18, max: 100 }),
}));
// Outputs a unique user each time
console.log(createUniqueUser());
console.log(createUniqueUser());
console.log(createUniqueUser());
```
Generates a unique value by running fn and ensuring uniqueness via either a provided or global store.
- fn - The function used to generate values.
- args - Optional. An array of arguments to be passed to fn.
- options - Optional. An object containing configuration options:
- **store** (Set): A custom store to track unique values. By default, the **GLOBAL_STORE** is used.
- **maxRetries** (number): The maximum number of retries to generate a unique value before throwing an error.
Defaults to 50.
- **maxTime** (number): The maximum time (in milliseconds) to attempt generating a unique value before throwing an
error. Defaults to 50ms.
- **exclude** (Array): A list of values to exclude from the result set. These values will not be
returned by the unique generator.
- **stringifier** (function): A function to stringify a result before storing it. Defaults to JSON.stringify.
#### Returns
A unique value generated by fn.
#### Example
```ts
import { unique } from '@dpaskhin/unique';
import { faker } from '@faker-js/faker';
const uniqueEmail = unique(faker.internet.email, [
{
firstName: faker.person.firstName(),
lastName: faker.person.lastName(),
},
]);
// Outputs a unique email
console.log(uniqueEmail);
```
Ensures a plain value is unique by checking against either a provided or global store.
- value - The plain value (non-functional) to ensure uniqueness for.
- options - Optional. An object containing configuration options:
- **store** (Set): A custom store to track unique values. By default, the **GLOBAL_STORE** is used.
- **exclude** (Array): A list of values to exclude. These values will not be added to the store or returned.
- **stringifier** (function): A function to stringify the value before storing it. Defaults to JSON.stringify.
#### Returns
The unique value provided.
#### 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()));
```
- Avoid using the global store when local uniqueness is required, as it may lead to unexpected results
due to shared state.
- Configure Max Retries and Timeouts: Customize maxRetries and maxTime based on the expected uniqueness and complexity
of generated values.
- Avoid using plain values and prefer generating functions for flexibility and retries.
**@dpaskhin/unique** is licensed under the MIT License.
Contributions are welcome! If you have ideas or improvements, feel free to submit a pull request.