roll-parser 3.0.0-alpha.0 → 3.0.0

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.
Files changed (163) hide show
  1. package/CHANGELOG.md +189 -0
  2. package/MIGRATION.md +147 -0
  3. package/README.md +985 -43
  4. package/dist/cli/args.d.ts +1 -0
  5. package/dist/cli/args.d.ts.map +1 -1
  6. package/dist/cli/args.js +81 -0
  7. package/dist/cli/args.js.map +1 -0
  8. package/dist/cli/format.d.ts +16 -4
  9. package/dist/cli/format.d.ts.map +1 -1
  10. package/dist/cli/format.js +17 -0
  11. package/dist/cli/format.js.map +1 -0
  12. package/dist/cli/index.d.ts +3 -0
  13. package/dist/cli/index.d.ts.map +1 -1
  14. package/dist/cli/index.js +14 -0
  15. package/dist/cli/index.js.map +1 -0
  16. package/dist/cli/main.d.ts +36 -0
  17. package/dist/cli/main.d.ts.map +1 -0
  18. package/dist/cli/main.js +83 -0
  19. package/dist/cli/main.js.map +1 -0
  20. package/dist/errors.d.ts +332 -14
  21. package/dist/errors.d.ts.map +1 -1
  22. package/dist/errors.js +141 -0
  23. package/dist/errors.js.map +1 -0
  24. package/dist/evaluator/die.d.ts +26 -0
  25. package/dist/evaluator/die.d.ts.map +1 -0
  26. package/dist/evaluator/die.js +19 -0
  27. package/dist/evaluator/die.js.map +1 -0
  28. package/dist/evaluator/env.d.ts +58 -0
  29. package/dist/evaluator/env.d.ts.map +1 -0
  30. package/dist/evaluator/env.js +11 -0
  31. package/dist/evaluator/env.js.map +1 -0
  32. package/dist/evaluator/evaluator.d.ts +62 -40
  33. package/dist/evaluator/evaluator.d.ts.map +1 -1
  34. package/dist/evaluator/evaluator.js +906 -0
  35. package/dist/evaluator/evaluator.js.map +1 -0
  36. package/dist/evaluator/modifiers/compare.d.ts +1 -1
  37. package/dist/evaluator/modifiers/compare.d.ts.map +1 -1
  38. package/dist/evaluator/modifiers/compare.js +15 -0
  39. package/dist/evaluator/modifiers/compare.js.map +1 -0
  40. package/dist/evaluator/modifiers/crit-threshold.d.ts +27 -0
  41. package/dist/evaluator/modifiers/crit-threshold.d.ts.map +1 -0
  42. package/dist/evaluator/modifiers/crit-threshold.js +23 -0
  43. package/dist/evaluator/modifiers/crit-threshold.js.map +1 -0
  44. package/dist/evaluator/modifiers/die-bound.d.ts +26 -0
  45. package/dist/evaluator/modifiers/die-bound.d.ts.map +1 -0
  46. package/dist/evaluator/modifiers/die-bound.js +14 -0
  47. package/dist/evaluator/modifiers/die-bound.js.map +1 -0
  48. package/dist/evaluator/modifiers/explode.d.ts +18 -6
  49. package/dist/evaluator/modifiers/explode.d.ts.map +1 -1
  50. package/dist/evaluator/modifiers/explode.js +103 -0
  51. package/dist/evaluator/modifiers/explode.js.map +1 -0
  52. package/dist/evaluator/modifiers/flags.d.ts +37 -0
  53. package/dist/evaluator/modifiers/flags.d.ts.map +1 -0
  54. package/dist/evaluator/modifiers/flags.js +18 -0
  55. package/dist/evaluator/modifiers/flags.js.map +1 -0
  56. package/dist/evaluator/modifiers/keep-drop.d.ts +12 -28
  57. package/dist/evaluator/modifiers/keep-drop.d.ts.map +1 -1
  58. package/dist/evaluator/modifiers/keep-drop.js +82 -0
  59. package/dist/evaluator/modifiers/keep-drop.js.map +1 -0
  60. package/dist/evaluator/modifiers/reroll.d.ts +14 -6
  61. package/dist/evaluator/modifiers/reroll.d.ts.map +1 -1
  62. package/dist/evaluator/modifiers/reroll.js +62 -0
  63. package/dist/evaluator/modifiers/reroll.js.map +1 -0
  64. package/dist/evaluator/modifiers/sort.d.ts +27 -0
  65. package/dist/evaluator/modifiers/sort.d.ts.map +1 -0
  66. package/dist/evaluator/modifiers/sort.js +13 -0
  67. package/dist/evaluator/modifiers/sort.js.map +1 -0
  68. package/dist/evaluator/modifiers/success-count.d.ts +2 -6
  69. package/dist/evaluator/modifiers/success-count.d.ts.map +1 -1
  70. package/dist/evaluator/modifiers/success-count.js +24 -0
  71. package/dist/evaluator/modifiers/success-count.js.map +1 -0
  72. package/dist/index.d.ts +35 -13
  73. package/dist/index.d.ts.map +1 -1
  74. package/dist/index.js +12 -1723
  75. package/dist/index.js.map +1 -0
  76. package/dist/lexer/lexer.d.ts +68 -8
  77. package/dist/lexer/lexer.d.ts.map +1 -1
  78. package/dist/lexer/lexer.js +260 -0
  79. package/dist/lexer/lexer.js.map +1 -0
  80. package/dist/lexer/tokens.d.ts +52 -7
  81. package/dist/lexer/tokens.d.ts.map +1 -1
  82. package/dist/lexer/tokens.js +42 -0
  83. package/dist/lexer/tokens.js.map +1 -0
  84. package/dist/parser/ast.d.ts +419 -80
  85. package/dist/parser/ast.d.ts.map +1 -1
  86. package/dist/parser/ast.js +52 -0
  87. package/dist/parser/ast.js.map +1 -0
  88. package/dist/parser/guards.d.ts +106 -0
  89. package/dist/parser/guards.d.ts.map +1 -0
  90. package/dist/parser/guards.js +121 -0
  91. package/dist/parser/guards.js.map +1 -0
  92. package/dist/parser/parser.d.ts +162 -15
  93. package/dist/parser/parser.d.ts.map +1 -1
  94. package/dist/parser/parser.js +751 -0
  95. package/dist/parser/parser.js.map +1 -0
  96. package/dist/rng/mock.d.ts +74 -13
  97. package/dist/rng/mock.d.ts.map +1 -1
  98. package/dist/rng/mock.js +30 -0
  99. package/dist/rng/mock.js.map +1 -0
  100. package/dist/rng/seeded.d.ts +149 -10
  101. package/dist/rng/seeded.d.ts.map +1 -1
  102. package/dist/rng/seeded.js +138 -0
  103. package/dist/rng/seeded.js.map +1 -0
  104. package/dist/rng/types.d.ts +57 -0
  105. package/dist/rng/types.d.ts.map +1 -1
  106. package/dist/rng/types.js +2 -0
  107. package/dist/rng/types.js.map +1 -0
  108. package/dist/roll.d.ts +59 -25
  109. package/dist/roll.d.ts.map +1 -1
  110. package/dist/roll.js +8 -0
  111. package/dist/roll.js.map +1 -0
  112. package/dist/testing.d.ts +5 -4
  113. package/dist/testing.d.ts.map +1 -1
  114. package/dist/testing.js +2 -38
  115. package/dist/testing.js.map +1 -0
  116. package/dist/types.d.ts +427 -24
  117. package/dist/types.d.ts.map +1 -1
  118. package/dist/types.js +8 -0
  119. package/dist/types.js.map +1 -0
  120. package/dist/version.d.ts +2 -0
  121. package/dist/version.d.ts.map +1 -0
  122. package/dist/version.js +2 -0
  123. package/dist/version.js.map +1 -0
  124. package/package.json +93 -40
  125. package/src/cli/args.ts +66 -9
  126. package/src/cli/format.ts +30 -7
  127. package/src/cli/index.ts +27 -67
  128. package/src/cli/main.ts +129 -0
  129. package/src/errors.ts +488 -23
  130. package/src/evaluator/die.ts +50 -0
  131. package/src/evaluator/env.ts +73 -0
  132. package/src/evaluator/evaluator.ts +1296 -349
  133. package/src/evaluator/modifiers/compare.ts +1 -1
  134. package/src/evaluator/modifiers/crit-threshold.ts +56 -0
  135. package/src/evaluator/modifiers/die-bound.ts +39 -0
  136. package/src/evaluator/modifiers/explode.ts +82 -76
  137. package/src/evaluator/modifiers/flags.ts +61 -0
  138. package/src/evaluator/modifiers/keep-drop.ts +124 -126
  139. package/src/evaluator/modifiers/reroll.ts +36 -64
  140. package/src/evaluator/modifiers/sort.ts +43 -0
  141. package/src/evaluator/modifiers/success-count.ts +6 -9
  142. package/src/index.ts +73 -34
  143. package/src/lexer/lexer.ts +201 -35
  144. package/src/lexer/tokens.ts +72 -7
  145. package/src/parser/ast.ts +453 -104
  146. package/src/parser/guards.ts +248 -0
  147. package/src/parser/parser.ts +835 -135
  148. package/src/rng/mock.ts +75 -14
  149. package/src/rng/seeded.ts +323 -58
  150. package/src/rng/types.ts +57 -0
  151. package/src/roll.ts +66 -41
  152. package/src/testing.ts +5 -9
  153. package/src/types.ts +416 -24
  154. package/src/version.ts +2 -0
  155. package/dist/cli.js +0 -1775
  156. package/dist/evaluator/index.d.ts +0 -8
  157. package/dist/evaluator/index.d.ts.map +0 -1
  158. package/dist/index.mjs +0 -1724
  159. package/dist/rng/index.d.ts +0 -8
  160. package/dist/rng/index.d.ts.map +0 -1
  161. package/dist/testing.mjs +0 -39
  162. package/src/evaluator/index.ts +0 -14
  163. package/src/rng/index.ts +0 -8
package/dist/roll.d.ts CHANGED
@@ -3,45 +3,79 @@
3
3
  *
4
4
  * @module roll
5
5
  */
6
- import type { RNG } from './rng/types';
7
- import type { RollResult } from './types';
6
+ import type { RNG } from './rng/types.js';
7
+ import type { EvaluationOptions, RollResult } from './types.js';
8
8
  /**
9
- * Options for the roll function.
9
+ * Everything {@link roll} accepts on top of the shared {@link EvaluationOptions}:
10
+ * a randomness source, given either as a ready-made {@link RNG} or as a seed.
11
+ *
12
+ * @category Core
13
+ *
14
+ * @example
15
+ * ```typescript
16
+ * import { roll, SeededRNG } from 'roll-parser';
17
+ *
18
+ * roll('4d6', { seed: 'character-1' }); // reproducible
19
+ * roll('4d6', { rng: new SeededRNG(42) }); // rng wins over seed
20
+ * roll('1d20+@str', { context: { str: 4 } });
21
+ * ```
10
22
  */
11
- export type RollOptions = {
12
- /** Custom RNG instance (takes precedence over seed) */
23
+ export type RollOptions = EvaluationOptions & {
24
+ /**
25
+ * Randomness source. Takes precedence over `seed` — when both are given,
26
+ * `seed` is ignored.
27
+ */
13
28
  rng?: RNG;
14
- /** Seed for deterministic rolls (ignored if rng provided) */
29
+ /**
30
+ * Seed for a fresh `SeededRNG`. Equal seeds replay the same die sequence for
31
+ * the same notation. Ignored when `rng` is set.
32
+ */
15
33
  seed?: string | number;
16
- /** Maximum total dice allowed per evaluation (default: 10,000) */
17
- maxDice?: number;
18
- /** Maximum explosion iterations allowed per die (default: 1,000) */
19
- maxExplodeIterations?: number;
20
- /** Maximum reroll iterations allowed per die (default: 1,000) */
21
- maxRerollIterations?: number;
22
34
  };
23
35
  /**
24
- * Parses and evaluates a dice notation string.
36
+ * Parses and evaluates a dice notation string in one call — the main entry
37
+ * point of the library.
25
38
  *
26
- * @param notation - Dice notation (e.g., "2d6+3", "4d6kh3")
27
- * @param options - Optional configuration (RNG or seed)
28
- * @returns Complete roll result with total and metadata
39
+ * Equivalent to `evaluate(parse(notation), rng, { notation })`. Each call
40
+ * builds a fresh `SeededRNG` unless `options.rng` is supplied, so reuse
41
+ * {@link parse} + {@link evaluate} directly when rolling the same notation in
42
+ * a loop.
43
+ *
44
+ * @param notation - Dice notation, e.g. `'2d6+3'` or `'4d6kh3'`
45
+ * @param options - RNG or seed, plus the shared {@link EvaluationOptions}
46
+ * @returns Complete {@link RollResult} with total, per-die results and the
47
+ * structured `parts` tree
48
+ * @throws {LexerError} On an invalid character
49
+ * @throws {ParseError} On invalid syntax
50
+ * @throws {EvaluatorError} On a limit breach or an impossible expression
51
+ * @throws {RollParserError} `INVALID_EVALUATION_LIMIT` when a supplied limit is
52
+ * not an integer in range — raised before any die is rolled
53
+ * @throws {RollParserError} `INVALID_NOTATION_TYPE` when `notation` is not a
54
+ * string, so `isRollParserError` still filters untrusted input completely
29
55
  *
30
56
  * @example
31
57
  * ```typescript
58
+ * import { roll } from 'roll-parser';
59
+ *
32
60
  * // Random roll
33
- * const result = roll('2d6+3');
34
- * console.log(result.total); // 5-15
61
+ * roll('2d6+3').total; // 5..15
62
+ *
63
+ * // Seeded — same seed, same sequence
64
+ * roll('2d6+3', { seed: 'demo' }).rendered; // '2d6[1, 6] + 3 = 10'
65
+ * roll('2d6+3', { seed: 'demo' }).total; // 10
66
+ * ```
35
67
  *
36
- * // Seeded for reproducibility
37
- * const r1 = roll('4d6', { seed: 'test' });
38
- * const r2 = roll('4d6', { seed: 'test' });
39
- * r1.total === r2.total; // true
68
+ * @example Deterministic tests with the testing mock
69
+ * ```typescript
70
+ * import { roll } from 'roll-parser';
71
+ * import { createMockRng } from 'roll-parser/testing';
40
72
  *
41
- * // Custom RNG for testing
42
- * const result = roll('1d20', { rng: createMockRng([15]) });
43
- * result.total; // 15
73
+ * const result = roll('4d6kh3', { rng: createMockRng([3, 6, 2, 5]) });
74
+ * result.total; // 14
75
+ * result.rendered; // '4d6[3, 6, ~~2~~, 5] = 14'
44
76
  * ```
77
+ *
78
+ * @category Core
45
79
  */
46
80
  export declare function roll(notation: string, options?: RollOptions): RollResult;
47
81
  //# sourceMappingURL=roll.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"roll.d.ts","sourceRoot":"","sources":["../src/roll.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,aAAa,CAAC;AACvC,OAAO,KAAK,EAAmB,UAAU,EAAE,MAAM,SAAS,CAAC;AAM3D;;GAEG;AACH,MAAM,MAAM,WAAW,GAAG;IACxB,uDAAuD;IACvD,GAAG,CAAC,EAAE,GAAG,CAAC;IACV,6DAA6D;IAC7D,IAAI,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;IACvB,kEAAkE;IAClE,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,oEAAoE;IACpE,oBAAoB,CAAC,EAAE,MAAM,CAAC;IAC9B,iEAAiE;IACjE,mBAAmB,CAAC,EAAE,MAAM,CAAC;CAC9B,CAAC;AAEF;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,wBAAgB,IAAI,CAAC,QAAQ,EAAE,MAAM,EAAE,OAAO,GAAE,WAAgB,GAAG,UAAU,CAa5E"}
1
+ {"version":3,"file":"roll.d.ts","sourceRoot":"","sources":["../src/roll.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAKH,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,gBAAgB,CAAC;AAC1C,OAAO,KAAK,EAAE,iBAAiB,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAEhE;;;;;;;;;;;;;;GAcG;AACH,MAAM,MAAM,WAAW,GAAG,iBAAiB,GAAG;IAC5C;;;OAGG;IACH,GAAG,CAAC,EAAE,GAAG,CAAC;IACV;;;OAGG;IACH,IAAI,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;CACxB,CAAC;AAEF;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4CG;AACH,wBAAgB,IAAI,CAAC,QAAQ,EAAE,MAAM,EAAE,OAAO,GAAE,WAAgB,GAAG,UAAU,CAK5E"}
package/dist/roll.js ADDED
@@ -0,0 +1,8 @@
1
+ import { evaluate } from './evaluator/evaluator.js';
2
+ import { parse } from './parser/parser.js';
3
+ import { SeededRNG } from './rng/seeded.js';
4
+ export function roll(notation, options = {}) {
5
+ const { rng, seed, ...limits } = options;
6
+ return evaluate(parse(notation), rng ?? new SeededRNG(seed), { ...limits, notation });
7
+ }
8
+ //# sourceMappingURL=roll.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"roll.js","sourceRoot":"","sources":["../src/roll.ts"],"names":[],"mappings":"AAMA,OAAO,EAAE,QAAQ,EAAE,MAAM,0BAA0B,CAAC;AACpD,OAAO,EAAE,KAAK,EAAE,MAAM,oBAAoB,CAAC;AAC3C,OAAO,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AA6E5C,MAAM,UAAU,IAAI,CAAC,QAAgB,EAAE,OAAO,GAAgB,EAAE;IAE9D,MAAM,EAAE,GAAG,EAAE,IAAI,EAAE,GAAG,MAAM,EAAE,GAAG,OAAO,CAAC;IAEzC,OAAO,QAAQ,CAAC,KAAK,CAAC,QAAQ,CAAC,EAAE,GAAG,IAAI,IAAI,SAAS,CAAC,IAAI,CAAC,EAAE,EAAE,GAAG,MAAM,EAAE,QAAQ,EAAE,CAAC,CAAC;AACxF,CAAC"}
package/dist/testing.d.ts CHANGED
@@ -1,11 +1,12 @@
1
1
  /**
2
2
  * Test utilities for roll-parser consumers.
3
3
  *
4
- * Import from `roll-parser/testing` for deterministic dice testing.
4
+ * Import from `roll-parser/testing` for deterministic dice testing. The full
5
+ * TSDoc lives on the implementations in `./rng/mock.ts`; this entry point is
6
+ * a plain re-export barrel.
5
7
  *
6
8
  * @module testing
7
9
  */
8
- import { MockRNGExhaustedError as _MockRNGExhaustedError, createMockRng as _createMockRng } from './rng/mock';
9
- export declare const createMockRng: typeof _createMockRng;
10
- export declare const MockRNGExhaustedError: typeof _MockRNGExhaustedError;
10
+ export { createMockRng, MockRNGExhaustedError } from './rng/mock.js';
11
+ export type { RNG } from './rng/types.js';
11
12
  //# sourceMappingURL=testing.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"testing.d.ts","sourceRoot":"","sources":["../src/testing.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAGH,OAAO,EACL,qBAAqB,IAAI,sBAAsB,EAC/C,aAAa,IAAI,cAAc,EAChC,MAAM,YAAY,CAAC;AAEpB,eAAO,MAAM,aAAa,uBAAiB,CAAC;AAC5C,eAAO,MAAM,qBAAqB,+BAAyB,CAAC"}
1
+ {"version":3,"file":"testing.d.ts","sourceRoot":"","sources":["../src/testing.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,EAAE,aAAa,EAAE,qBAAqB,EAAE,MAAM,eAAe,CAAC;AACrE,YAAY,EAAE,GAAG,EAAE,MAAM,gBAAgB,CAAC"}
package/dist/testing.js CHANGED
@@ -1,38 +1,2 @@
1
- // src/rng/mock.ts
2
- class MockRNGExhaustedError extends Error {
3
- consumed;
4
- constructor(consumed) {
5
- super(`MockRNG exhausted: consumed ${consumed} values, no more available`);
6
- this.name = "MockRNGExhaustedError";
7
- this.consumed = consumed;
8
- }
9
- }
10
- function createMockRng(values) {
11
- let index = 0;
12
- const getNext = () => {
13
- const value = values[index];
14
- if (value === undefined) {
15
- throw new MockRNGExhaustedError(index);
16
- }
17
- index++;
18
- return value;
19
- };
20
- return {
21
- next: getNext,
22
- nextInt: (min, max) => {
23
- const value = getNext();
24
- if (value < min || value > max) {
25
- throw new RangeError(`MockRNG value ${value} is out of bounds [${min}, ${max}]`);
26
- }
27
- return value;
28
- }
29
- };
30
- }
31
-
32
- // src/testing.ts
33
- var createMockRng2 = createMockRng;
34
- var MockRNGExhaustedError2 = MockRNGExhaustedError;
35
- export {
36
- createMockRng2 as createMockRng,
37
- MockRNGExhaustedError2 as MockRNGExhaustedError
38
- };
1
+ export { createMockRng, MockRNGExhaustedError } from './rng/mock.js';
2
+ //# sourceMappingURL=testing.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"testing.js","sourceRoot":"","sources":["../src/testing.ts"],"names":[],"mappings":"AAUA,OAAO,EAAE,aAAa,EAAE,qBAAqB,EAAE,MAAM,eAAe,CAAC"}