@lou.codes/iterables
Version:
🔁 Iterable and AsyncIterable utils
41 lines (40 loc) • 1.28 kB
JavaScript
import { cryptoNumber } from "@lou.codes/utils";
import { createIterableIterator } from "./createIterableIterator.js";
/**
* Deterministic pseudo-random number generator.
*
* **⚠️ IMPORTANT:** This only works in secure contexts (HTTPS/Node).
*
* @category Asynchronous Generators
* @example
* ```typescript
* const seededRandom = random("some seed");
* const random0To10 = seededRandom(0)(10);
*
* [...pick(2)(random0To10)]; // Two "random" values between 0 and 10
* [...pick(2)(random0To10)]; // Same two "random" values between 0 and 10
* ```
* @see [SubtleCrypto#digest](https://mdn.io/SubtleCrypto.digest)
* @see [cryptoNumber](https://lou.codes/libraries/lou_codes_utils/#cryptonumber)
* @param seed Seed to be used to generate random numbers.
* @returns Curried generator function with `seed` set in context.
*/
export const random = seed => from => to =>
createIterableIterator(async function* () {
let state = seed;
const min = from < to ? from : to;
const max = from > to ? from : to;
// eslint-disable-next-line functional/no-loop-statements
for (;;) {
yield Math.min(
Math.max(
(state =
(await cryptoNumber(`${state}(${min}-${max})`)) *
(max + 2 - min) +
(min - 1)),
min,
),
max,
);
}
});