@xtia/alea-rc 0.0.8 → 0.0.10
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +20 -13
- package/entry/browser.js +2 -2
- package/entry/common.d.ts +1 -1
- package/entry/common.js +1 -1
- package/entry/node.js +2 -2
- package/internal/alea.d.ts +3 -3
- package/internal/alea.js +13 -9
- package/internal/factories.d.ts +3 -3
- package/internal/factories.js +3 -3
- package/internal/util.js +0 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -7,8 +7,8 @@ Alea is a utility wrapper for turning random numbers into useful values. Give it
|
|
|
7
7
|
* Fully typed
|
|
8
8
|
* Crypto-safe and seeded algorithms out-of-the-box
|
|
9
9
|
* No dependencies
|
|
10
|
-
* ~2.
|
|
11
|
-
* Ranged int, array shuffling, dice roll, weighted sampling, phrase generation, UUID, bytes and many more
|
|
10
|
+
* ~2.6kb minified core
|
|
11
|
+
* Ranged int, array shuffling, dice roll, weighted sampling, recursive template phrase generation, UUID, bytes and many more
|
|
12
12
|
|
|
13
13
|
## Brief:
|
|
14
14
|
|
|
@@ -21,31 +21,38 @@ import { alea, cryptoAlea } from "@xtia/alea";
|
|
|
21
21
|
const damage = alea.roll(2, 6); // 2d6
|
|
22
22
|
const duration = alea.between(1000, 1500);
|
|
23
23
|
const loot = alea.chance(0.125) ? "epic" : "common";
|
|
24
|
-
const id = alea.string(5);
|
|
24
|
+
const id = alea.string(5, "abcdef0123456789");
|
|
25
25
|
const npcName = alea.sample(["Alice", "Bob", "Charlie"]);
|
|
26
26
|
|
|
27
27
|
// secure source (driven by environment's crypto)
|
|
28
28
|
const key = cryptoAlea.string(16);
|
|
29
29
|
```
|
|
30
|
-
|
|
31
|
-
## Custom sources
|
|
30
|
+
# Custom sources
|
|
32
31
|
|
|
33
32
|
Use any provider as RNG source:
|
|
34
33
|
|
|
35
34
|
```ts
|
|
36
35
|
import {
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
36
|
+
aleaFromFunc,
|
|
37
|
+
aleaFromSeed,
|
|
38
|
+
aleaFromByteSource,
|
|
40
39
|
} from "@xtia/alea";
|
|
41
40
|
|
|
42
|
-
|
|
43
|
-
const
|
|
44
|
-
|
|
41
|
+
// deterministic, with seed (uses Mulberry32 PRNG):
|
|
42
|
+
const seededRng = aleaFromSeed("abc123");
|
|
43
|
+
|
|
44
|
+
// custom source of randomness:
|
|
45
|
+
const xkcdRng = aleaFromFunc(() => 4/6); // https://xkcd.com/221/
|
|
46
|
+
|
|
47
|
+
// from random byte providers:
|
|
48
|
+
const secureRng = aleaFromByteSource(
|
|
45
49
|
buf => hardwareRNG.fillRandomBytes(buf)
|
|
46
50
|
);
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
Or use a provided PRNG algorithm:
|
|
47
54
|
|
|
48
|
-
|
|
55
|
+
```ts
|
|
49
56
|
import {
|
|
50
57
|
mulberry32,
|
|
51
58
|
sfc32,
|
|
@@ -57,5 +64,5 @@ const fast = mulberry32("my-seed");
|
|
|
57
64
|
const varied = sfc32(1, 2, 3, 4);
|
|
58
65
|
const strong = xoshiro128pp(5, 6, 7, 8);
|
|
59
66
|
|
|
60
|
-
const
|
|
67
|
+
const reproducibleRoll = varied.roll(3, 6);
|
|
61
68
|
```
|
package/entry/browser.js
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { aleaFromByteSource } from "../internal/factories.js";
|
|
2
2
|
export * from "./common.js";
|
|
3
|
-
export const cryptoAlea =
|
|
3
|
+
export const cryptoAlea = aleaFromByteSource((arr) => globalThis.crypto.getRandomValues(arr));
|
package/entry/common.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { Alea } from "../internal/alea.js";
|
|
2
2
|
export type { Alea };
|
|
3
|
-
export {
|
|
3
|
+
export { aleaFromByteSource, aleaFromSeed, aleaFromFunc, } from "../internal/factories.js";
|
|
4
4
|
export { charsets } from "../internal/charsets.js";
|
|
5
5
|
export { alea } from "../internal/mathalea.js";
|
package/entry/common.js
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
export {
|
|
1
|
+
export { aleaFromByteSource, aleaFromSeed, aleaFromFunc, } from "../internal/factories.js";
|
|
2
2
|
export { charsets } from "../internal/charsets.js";
|
|
3
3
|
export { alea } from "../internal/mathalea.js";
|
package/entry/node.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { aleaFromByteSource } from "../internal/factories.js";
|
|
2
2
|
import { randomBytes } from 'node:crypto';
|
|
3
3
|
export * from "./common.js";
|
|
4
|
-
export const cryptoAlea =
|
|
4
|
+
export const cryptoAlea = aleaFromByteSource(arr => {
|
|
5
5
|
randomBytes(arr.length).copy(arr);
|
|
6
6
|
});
|
package/internal/alea.d.ts
CHANGED
|
@@ -103,12 +103,12 @@ export declare class Alea {
|
|
|
103
103
|
*/
|
|
104
104
|
round(n: number): number;
|
|
105
105
|
/**
|
|
106
|
-
* Get a random
|
|
106
|
+
* Get a random normal pair using Box-Muller transform
|
|
107
107
|
* @param mean
|
|
108
108
|
* @param deviation
|
|
109
|
-
* @returns
|
|
109
|
+
* @returns Gaussian normal pair
|
|
110
110
|
*/
|
|
111
|
-
normal(mean
|
|
111
|
+
normal(mean?: number, deviation?: number): [number, number];
|
|
112
112
|
/**
|
|
113
113
|
* Get a random integer value between `min` and `max`, inclusive.
|
|
114
114
|
* @param min Minimum value, **inclusive**
|
package/internal/alea.js
CHANGED
|
@@ -77,10 +77,10 @@ export class Alea {
|
|
|
77
77
|
string(length, charset) {
|
|
78
78
|
if (!Number.isInteger(length) || length < 0)
|
|
79
79
|
throw new RangeError("length must be a non-negative integer");
|
|
80
|
-
|
|
80
|
+
const pool = [...charset];
|
|
81
|
+
if (pool.length === 0)
|
|
81
82
|
throw new RangeError("charset must not be empty");
|
|
82
|
-
|
|
83
|
-
return chars.join("");
|
|
83
|
+
return Array.from({ length }, () => this.sample(pool)).join("");
|
|
84
84
|
}
|
|
85
85
|
/**
|
|
86
86
|
* Generate a phrase from a table and a root string
|
|
@@ -180,20 +180,24 @@ export class Alea {
|
|
|
180
180
|
return this.chance(n - floor) ? floor + 1 : floor;
|
|
181
181
|
}
|
|
182
182
|
/**
|
|
183
|
-
* Get a random
|
|
183
|
+
* Get a random normal pair using Box-Muller transform
|
|
184
184
|
* @param mean
|
|
185
185
|
* @param deviation
|
|
186
|
-
* @returns
|
|
186
|
+
* @returns Gaussian normal pair
|
|
187
187
|
*/
|
|
188
|
-
normal(mean, deviation) {
|
|
188
|
+
normal(mean = 0, deviation = 1) {
|
|
189
189
|
let u1 = this.next();
|
|
190
|
-
while (u1 <= Number.EPSILON)
|
|
190
|
+
while (u1 <= Number.EPSILON)
|
|
191
191
|
u1 = this.next();
|
|
192
|
-
}
|
|
193
192
|
const u2 = this.next();
|
|
194
193
|
const mag = Math.sqrt(-2 * Math.log(u1));
|
|
195
194
|
const angle = 2 * Math.PI * u2;
|
|
196
|
-
|
|
195
|
+
const z0 = mag * Math.cos(angle);
|
|
196
|
+
const z1 = mag * Math.sin(angle);
|
|
197
|
+
return [
|
|
198
|
+
mean + z0 * deviation,
|
|
199
|
+
mean + z1 * deviation
|
|
200
|
+
];
|
|
197
201
|
}
|
|
198
202
|
/**
|
|
199
203
|
* Get a random integer value between `min` and `max`, inclusive.
|
package/internal/factories.d.ts
CHANGED
|
@@ -10,7 +10,7 @@ import { Alea } from "./alea.js";
|
|
|
10
10
|
* @param applyBytes A callback that fills a Uint8Array with random bytes
|
|
11
11
|
* @returns A byte generator-sourced Alea instance
|
|
12
12
|
*/
|
|
13
|
-
export declare function
|
|
13
|
+
export declare function aleaFromByteSource(applyBytes: (buffer: Uint8Array) => void): Alea;
|
|
14
14
|
/**
|
|
15
15
|
* Create an Alea instance using a Mulberry32 source
|
|
16
16
|
*
|
|
@@ -20,7 +20,7 @@ export declare function createAleaFromByteSource(applyBytes: (buffer: Uint8Array
|
|
|
20
20
|
* @param seed
|
|
21
21
|
* @returns Alea instance using Mulberry32
|
|
22
22
|
*/
|
|
23
|
-
export declare function
|
|
23
|
+
export declare function aleaFromSeed(seed: number | string): Alea;
|
|
24
24
|
/**
|
|
25
25
|
* Create an Alea instance using a custom function as an RNG source
|
|
26
26
|
* @example
|
|
@@ -31,4 +31,4 @@ export declare function createAleaFromSeed(seed: number | string): Alea;
|
|
|
31
31
|
* @param fn Source RNG; a function that returns a value >= 0 and < 1
|
|
32
32
|
* @returns Custom function-sourced Alea instance
|
|
33
33
|
*/
|
|
34
|
-
export declare function
|
|
34
|
+
export declare function aleaFromFunc(fn: () => number): Alea;
|
package/internal/factories.js
CHANGED
|
@@ -11,7 +11,7 @@ import { Alea } from "./alea.js";
|
|
|
11
11
|
* @param applyBytes A callback that fills a Uint8Array with random bytes
|
|
12
12
|
* @returns A byte generator-sourced Alea instance
|
|
13
13
|
*/
|
|
14
|
-
export function
|
|
14
|
+
export function aleaFromByteSource(applyBytes) {
|
|
15
15
|
const buffer = new ArrayBuffer(4);
|
|
16
16
|
const view = new Uint8Array(buffer);
|
|
17
17
|
const uint32View = new Uint32Array(buffer);
|
|
@@ -29,7 +29,7 @@ export function createAleaFromByteSource(applyBytes) {
|
|
|
29
29
|
* @param seed
|
|
30
30
|
* @returns Alea instance using Mulberry32
|
|
31
31
|
*/
|
|
32
|
-
export function
|
|
32
|
+
export function aleaFromSeed(seed) {
|
|
33
33
|
return mulberry32(seed);
|
|
34
34
|
}
|
|
35
35
|
/**
|
|
@@ -42,7 +42,7 @@ export function createAleaFromSeed(seed) {
|
|
|
42
42
|
* @param fn Source RNG; a function that returns a value >= 0 and < 1
|
|
43
43
|
* @returns Custom function-sourced Alea instance
|
|
44
44
|
*/
|
|
45
|
-
export function
|
|
45
|
+
export function aleaFromFunc(fn) {
|
|
46
46
|
return new Alea(fn);
|
|
47
47
|
}
|
|
48
48
|
// const xkcdAlea = createAleaFromFunc(() => 4/6); // decided by die roll
|
package/internal/util.js
CHANGED