UNPKG

@lazy-random/generators-seedrandom

Version:
175 lines (143 loc) 3.97 kB
import { RNGFunction } from '@lazy-random/generators-function'; import seedrandom from 'seedrandom'; import { PickValueOf } from '@lazy-random/shared-lib'; import { cloneClass } from '@lazy-random/clone-class'; export import RNGSeedRandomOptions = seedrandom.seedRandomOptions; export const defaultOptions: RNGSeedRandomOptions = Object.freeze({ entropy: true, }); export type IRNGSeedRandomLibName = 'alea' | 'tychei' | 'xor128' | 'xor4096' | 'xorshift7' | 'xorwow'; export type IRNGSeedRandomLib = IRNGSeedRandomLibName | string; export type IRNGSeedRandomLibValueOf = PickValueOf<typeof seedrandom, IRNGSeedRandomLibName>; export class RNGSeedRandom extends RNGFunction<seedrandom.prng> { protected _opts: RNGSeedRandomOptions; protected _seedrandom: IRNGSeedRandomGenerator; protected override _seedable = true; constructor(seed?, opts?: RNGSeedRandomOptions, lib?: IRNGSeedRandomLib, ...argv); constructor(seed?, opts?: RNGSeedRandomOptions, ...argv) { super(seed, opts, ...argv); } public static createLib(lib?: IRNGSeedRandomLib, seed?, opts?: RNGSeedRandomOptions, ...argv): RNGSeedRandom; public static createLib(...argv) { return new this(argv[1], argv[2], argv[0], ...argv.slice(3)); } public static override create(seed?, opts?: RNGSeedRandomOptions, lib?: IRNGSeedRandomLib, ...argv): RNGSeedRandom; public static override create(...argv) { return new this(...argv); } // eslint-disable-next-line no-empty-function,@typescript-eslint/no-empty-function protected override _init_check(seed?, opts?, ...argv) {} protected override _init(seed?, opts?, ...argv) { this._opts = this._opts || Object.assign({}, defaultOptions); this._seedrandom = this.__generator(...argv); super._init(seed, opts, ...argv); } protected readonly _NAME = 'seedrandom'; protected _TYPE = null; override get name() { return `${this._NAME}${this._TYPE ? ':' + this._TYPE : ''}`; } protected __generator(fn?: typeof seedrandom | IRNGSeedRandomLib | IRNGSeedRandomLibValueOf): IRNGSeedRandomGenerator { if (fn && typeof fn === 'string') { this._TYPE = null; switch (fn) { case 'alea': case 'tychei': case 'xor128': case 'xor4096': case 'xorshift7': case 'xorwow': fn = seedrandom[fn]; //fn = require(`seedrandom/lib/${fn}`) this._TYPE = fn; break; default: if (!fn.includes('..') && /^[a-z\-\.]+$/i.test(fn)) { this._TYPE = fn; fn = require(`seedrandom/lib/${fn}`); break; } else { throw new RangeError(`unknow seedrandom lib name: ${fn}`); } } } else if (fn) { // @ts-ignore this._TYPE = fn.name; } else { this._TYPE = null; } fn = fn || seedrandom; return fn as IRNGSeedRandomGenerator; /* return (seed?, opts?: RNGSeedRandomOptions, ...argv) => { // @ts-ignore return fn(seed, opts, ...argv) } */ } override get options() { return this._opts; } /** * only when option.state = true */ // eslint-disable-next-line consistent-return,getter-return public get state(): IRNGSeedRandomState { // eslint-disable-next-line @typescript-eslint/unbound-method const fn = this._rng.state; if (typeof fn === 'function') { // @ts-ignore return fn(); } } /** * @todo options for change seeder */ override seed(seed?, opts?: RNGSeedRandomOptions, ...argv) { if (opts === null) { this._opts = void 0; } else { this._opts = opts || this._opts; } this._rng = this._seedrandom(this._seedAuto(seed), this._opts, ...argv); } // @ts-ignore clone(seed?, opts?: RNGSeedRandomOptions, ...argv): RNGSeedRandom { return cloneClass(RNGSeedRandom, this, seed, opts, ...argv); } } export interface IRNGSeedRandomState { i: number, j: number, S: number[], } export interface IRNGSeedRandomGenerator { (seed?: any, opts?: seedrandom.seedRandomOptions, ...argv: any[]): seedrandom.prng } export default RNGSeedRandom;