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
@@ -8,13 +8,21 @@
8
8
  *
9
9
  * @module evaluator/modifiers/reroll
10
10
  */
11
- import type { RNG } from '../../rng/types';
12
- import type { CompareOp, DieResult } from '../../types';
13
- import { type EvalEnv } from '../evaluator';
14
- import { matchesCondition } from './compare';
15
- /** Default maximum reroll iterations per die. */
11
+ import type { RNG } from '../../rng/types.js';
12
+ import type { CompareOp, DieResult } from '../../types.js';
13
+ import { type EvalEnv } from '../env.js';
14
+ /**
15
+ * Default value of `EvaluationOptions.maxRerollIterations`: how many times a
16
+ * single die may be re-rolled by `r` before `REROLL_LIMIT_EXCEEDED` is
17
+ * thrown.
18
+ *
19
+ * Per die, not per pool — it bounds notations like `1d1r<2`, whose reroll
20
+ * condition can never stop matching. `ro` re-rolls exactly once and is
21
+ * unaffected.
22
+ *
23
+ * @category Limits
24
+ */
16
25
  export declare const DEFAULT_MAX_REROLL_ITERATIONS = 1000;
17
- export { matchesCondition };
18
26
  /**
19
27
  * Applies recursive reroll: re-roll each matching die until it no longer
20
28
  * matches or the per-die iteration limit is reached. Intermediate dice are
@@ -1 +1 @@
1
- {"version":3,"file":"reroll.d.ts","sourceRoot":"","sources":["../../../src/evaluator/modifiers/reroll.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,iBAAiB,CAAC;AAC3C,OAAO,KAAK,EAAE,SAAS,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AACxD,OAAO,EAAkB,KAAK,OAAO,EAAE,MAAM,cAAc,CAAC;AAC5D,OAAO,EAAE,gBAAgB,EAAE,MAAM,WAAW,CAAC;AAE7C,iDAAiD;AACjD,eAAO,MAAM,6BAA6B,OAAQ,CAAC;AAEnD,OAAO,EAAE,gBAAgB,EAAE,CAAC;AA8D5B;;;;;;;GAOG;AACH,wBAAgB,oBAAoB,CAClC,IAAI,EAAE,SAAS,EAAE,EACjB,QAAQ,EAAE,SAAS,EACnB,KAAK,EAAE,MAAM,EACb,GAAG,EAAE,GAAG,EACR,GAAG,EAAE,OAAO,GACX,SAAS,EAAE,CAiCb;AAED;;;;GAIG;AACH,wBAAgB,eAAe,CAC7B,IAAI,EAAE,SAAS,EAAE,EACjB,QAAQ,EAAE,SAAS,EACnB,KAAK,EAAE,MAAM,EACb,GAAG,EAAE,GAAG,EACR,GAAG,EAAE,OAAO,GACX,SAAS,EAAE,CA8Bb"}
1
+ {"version":3,"file":"reroll.d.ts","sourceRoot":"","sources":["../../../src/evaluator/modifiers/reroll.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAGH,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,oBAAoB,CAAC;AAC9C,OAAO,KAAK,EAAE,SAAS,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAE3D,OAAO,EAAa,KAAK,OAAO,EAAE,MAAM,WAAW,CAAC;AAIpD;;;;;;;;;;GAUG;AACH,eAAO,MAAM,6BAA6B,OAAQ,CAAC;AA8BnD;;;;;;;GAOG;AACH,wBAAgB,oBAAoB,CAClC,IAAI,EAAE,SAAS,EAAE,EACjB,QAAQ,EAAE,SAAS,EACnB,KAAK,EAAE,MAAM,EACb,GAAG,EAAE,GAAG,EACR,GAAG,EAAE,OAAO,GACX,SAAS,EAAE,CA+Bb;AAED;;;;GAIG;AACH,wBAAgB,eAAe,CAC7B,IAAI,EAAE,SAAS,EAAE,EACjB,QAAQ,EAAE,SAAS,EACnB,KAAK,EAAE,MAAM,EACb,GAAG,EAAE,GAAG,EACR,GAAG,EAAE,OAAO,GACX,SAAS,EAAE,CAyBb"}
@@ -0,0 +1,62 @@
1
+ import { EvaluatorError } from '../../errors.js';
2
+ import { createDieResult, createFateDieResult } from '../die.js';
3
+ import { chargeDie } from '../env.js';
4
+ import { matchesCondition } from './compare.js';
5
+ import { isVersusDc, REROLL_SLOT_FLAGS, rewriteFlags } from './flags.js';
6
+ export const DEFAULT_MAX_REROLL_ITERATIONS = 1_000;
7
+ function rollReplacement(sides, rng, env) {
8
+ chargeDie(env, 'Reroll');
9
+ if (sides === 0)
10
+ return createFateDieResult(rng.nextInt(-1, 1), []);
11
+ return createDieResult(sides, rng.nextInt(1, sides), []);
12
+ }
13
+ function rerollLimitError(maxIterations) {
14
+ return new EvaluatorError(`Reroll iteration limit of ${maxIterations} exceeded`, 'REROLL_LIMIT_EXCEEDED', 'Reroll');
15
+ }
16
+ function canReroll(die) {
17
+ return !die.modifiers.includes('dropped') && !isVersusDc(die);
18
+ }
19
+ export function applyRecursiveReroll(pool, operator, value, rng, env) {
20
+ const result = [];
21
+ for (const original of pool) {
22
+ if (!canReroll(original)) {
23
+ result.push(original);
24
+ continue;
25
+ }
26
+ let current = original;
27
+ let iterations = 0;
28
+ while (matchesCondition(current.result, operator, value)) {
29
+ if (iterations >= env.maxRerollIterations) {
30
+ throw rerollLimitError(env.maxRerollIterations);
31
+ }
32
+ current.modifiers = rewriteFlags(current.modifiers, REROLL_SLOT_FLAGS, 'rerolled', 'dropped');
33
+ result.push(current);
34
+ current = rollReplacement(current.sides, rng, env);
35
+ iterations += 1;
36
+ }
37
+ current.modifiers = rewriteFlags(current.modifiers, REROLL_SLOT_FLAGS, 'kept');
38
+ result.push(current);
39
+ }
40
+ return result;
41
+ }
42
+ export function applyRerollOnce(pool, operator, value, rng, env) {
43
+ const result = [];
44
+ for (const original of pool) {
45
+ if (!canReroll(original)) {
46
+ result.push(original);
47
+ continue;
48
+ }
49
+ if (!matchesCondition(original.result, operator, value)) {
50
+ original.modifiers = rewriteFlags(original.modifiers, REROLL_SLOT_FLAGS, 'kept');
51
+ result.push(original);
52
+ continue;
53
+ }
54
+ original.modifiers = rewriteFlags(original.modifiers, REROLL_SLOT_FLAGS, 'rerolled', 'dropped');
55
+ result.push(original);
56
+ const replacement = rollReplacement(original.sides, rng, env);
57
+ replacement.modifiers = rewriteFlags(replacement.modifiers, REROLL_SLOT_FLAGS, 'kept');
58
+ result.push(replacement);
59
+ }
60
+ return result;
61
+ }
62
+ //# sourceMappingURL=reroll.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"reroll.js","sourceRoot":"","sources":["../../../src/evaluator/modifiers/reroll.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,27 @@
1
+ /**
2
+ * Sort modifier implementation.
3
+ *
4
+ * Sort is purely cosmetic — it reorders the dice produced by its target in
5
+ * ascending or descending order of `result` without touching any flag
6
+ * (`kept`, `dropped`, `critical`, `fumble`, `rerolled`, `meta`) or the total.
7
+ * Dropped dice stay in the pool and sort alongside kept dice so readers can
8
+ * see where the dropped value landed in the ordered sequence.
9
+ *
10
+ * DC dice are the exception: they hold their positions rather than sorting,
11
+ * so a `vs` comparison's DC faces never appear shuffled into the roll-side
12
+ * pool they are not a member of.
13
+ *
14
+ * @module evaluator/modifiers/sort
15
+ */
16
+ import type { DieResult } from '../../types.js';
17
+ /**
18
+ * Returns a sorted copy of `dice` in the given order, preserving every die's
19
+ * original flags and metadata. Comparison is on `.result` — the raw face
20
+ * value is what the user sees in rendered output, so ordering by raw value
21
+ * matches the visual intent regardless of any `kept`/`dropped` flagging.
22
+ *
23
+ * Relies on `Array.prototype.sort` being stable — equal-valued dice retain
24
+ * their original insertion order.
25
+ */
26
+ export declare function sortDice(dice: DieResult[], order: 'ascending' | 'descending'): DieResult[];
27
+ //# sourceMappingURL=sort.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sort.d.ts","sourceRoot":"","sources":["../../../src/evaluator/modifiers/sort.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAEH,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAGhD;;;;;;;;GAQG;AACH,wBAAgB,QAAQ,CAAC,IAAI,EAAE,SAAS,EAAE,EAAE,KAAK,EAAE,WAAW,GAAG,YAAY,GAAG,SAAS,EAAE,CAc1F"}
@@ -0,0 +1,13 @@
1
+ import { isVersusDc } from './flags.js';
2
+ export function sortDice(dice, order) {
3
+ const cmp = order === 'ascending'
4
+ ? (a, b) => a.result - b.result
5
+ : (a, b) => b.result - a.result;
6
+ const sortable = dice.filter((die) => !isVersusDc(die));
7
+ if (sortable.length === dice.length)
8
+ return [...dice].sort(cmp);
9
+ sortable.sort(cmp);
10
+ let next = 0;
11
+ return dice.map((die) => (isVersusDc(die) ? die : sortable[next++]));
12
+ }
13
+ //# sourceMappingURL=sort.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sort.js","sourceRoot":"","sources":["../../../src/evaluator/modifiers/sort.ts"],"names":[],"mappings":"AAiBA,OAAO,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAWxC,MAAM,UAAU,QAAQ,CAAC,IAAiB,EAAE,KAAiC;IAC3E,MAAM,GAAG,GACP,KAAK,KAAK,WAAW;QACnB,CAAC,CAAC,CAAC,CAAY,EAAE,CAAY,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,GAAG,CAAC,CAAC,MAAM;QACrD,CAAC,CAAC,CAAC,CAAY,EAAE,CAAY,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,GAAG,CAAC,CAAC,MAAM,CAAC;IAE1D,MAAM,QAAQ,GAAG,IAAI,CAAC,MAAM,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC,CAAC;IACxD,IAAI,QAAQ,CAAC,MAAM,KAAK,IAAI,CAAC,MAAM;QAAE,OAAO,CAAC,GAAG,IAAI,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;IAIhE,QAAQ,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;IACnB,IAAI,IAAI,GAAG,CAAC,CAAC;IACb,OAAO,IAAI,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAE,QAAQ,CAAC,IAAI,EAAE,CAAe,CAAC,CAAC,CAAC;AACtF,CAAC"}
@@ -14,15 +14,11 @@
14
14
  *
15
15
  * @module evaluator/modifiers/success-count
16
16
  */
17
- import type { CompareOp, DieResult } from '../../types';
18
- export type ResolvedThreshold = {
19
- operator: CompareOp;
20
- value: number;
21
- };
17
+ import type { DieResult, ResolvedComparePoint } from '../../types.js';
22
18
  export type SuccessCountResult = {
23
19
  total: number;
24
20
  successes: number;
25
21
  failures: number;
26
22
  };
27
- export declare function countSuccesses(dice: DieResult[], threshold: ResolvedThreshold, failThreshold?: ResolvedThreshold): SuccessCountResult;
23
+ export declare function countSuccesses(dice: DieResult[], threshold: ResolvedComparePoint, failThreshold?: ResolvedComparePoint): SuccessCountResult;
28
24
  //# sourceMappingURL=success-count.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"success-count.d.ts","sourceRoot":"","sources":["../../../src/evaluator/modifiers/success-count.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAEH,OAAO,KAAK,EAAE,SAAS,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AAGxD,MAAM,MAAM,iBAAiB,GAAG;IAC9B,QAAQ,EAAE,SAAS,CAAC;IACpB,KAAK,EAAE,MAAM,CAAC;CACf,CAAC;AAEF,MAAM,MAAM,kBAAkB,GAAG;IAC/B,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,EAAE,MAAM,CAAC;IAClB,QAAQ,EAAE,MAAM,CAAC;CAClB,CAAC;AAEF,wBAAgB,cAAc,CAC5B,IAAI,EAAE,SAAS,EAAE,EACjB,SAAS,EAAE,iBAAiB,EAC5B,aAAa,CAAC,EAAE,iBAAiB,GAChC,kBAAkB,CAuBpB"}
1
+ {"version":3,"file":"success-count.d.ts","sourceRoot":"","sources":["../../../src/evaluator/modifiers/success-count.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAEH,OAAO,KAAK,EAAE,SAAS,EAAE,oBAAoB,EAAE,MAAM,gBAAgB,CAAC;AAItE,MAAM,MAAM,kBAAkB,GAAG;IAC/B,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,EAAE,MAAM,CAAC;IAClB,QAAQ,EAAE,MAAM,CAAC;CAClB,CAAC;AAEF,wBAAgB,cAAc,CAC5B,IAAI,EAAE,SAAS,EAAE,EACjB,SAAS,EAAE,oBAAoB,EAC/B,aAAa,CAAC,EAAE,oBAAoB,GACnC,kBAAkB,CAwBpB"}
@@ -0,0 +1,24 @@
1
+ import { matchesCondition } from './compare.js';
2
+ import { isVersusDc } from './flags.js';
3
+ export function countSuccesses(dice, threshold, failThreshold) {
4
+ let successes = 0;
5
+ let failures = 0;
6
+ for (const die of dice) {
7
+ if (isVersusDc(die))
8
+ continue;
9
+ if (die.modifiers.includes('dropped'))
10
+ continue;
11
+ if (matchesCondition(die.result, threshold.operator, threshold.value)) {
12
+ die.modifiers.push('success');
13
+ successes += 1;
14
+ continue;
15
+ }
16
+ if (failThreshold != null &&
17
+ matchesCondition(die.result, failThreshold.operator, failThreshold.value)) {
18
+ die.modifiers.push('failure');
19
+ failures += 1;
20
+ }
21
+ }
22
+ return { total: successes - failures, successes, failures };
23
+ }
24
+ //# sourceMappingURL=success-count.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"success-count.js","sourceRoot":"","sources":["../../../src/evaluator/modifiers/success-count.ts"],"names":[],"mappings":"AAkBA,OAAO,EAAE,gBAAgB,EAAE,MAAM,cAAc,CAAC;AAChD,OAAO,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAQxC,MAAM,UAAU,cAAc,CAC5B,IAAiB,EACjB,SAA+B,EAC/B,aAAoC;IAEpC,IAAI,SAAS,GAAG,CAAC,CAAC;IAClB,IAAI,QAAQ,GAAG,CAAC,CAAC;IAEjB,KAAK,MAAM,GAAG,IAAI,IAAI,EAAE,CAAC;QACvB,IAAI,UAAU,CAAC,GAAG,CAAC;YAAE,SAAS;QAC9B,IAAI,GAAG,CAAC,SAAS,CAAC,QAAQ,CAAC,SAAS,CAAC;YAAE,SAAS;QAEhD,IAAI,gBAAgB,CAAC,GAAG,CAAC,MAAM,EAAE,SAAS,CAAC,QAAQ,EAAE,SAAS,CAAC,KAAK,CAAC,EAAE,CAAC;YACtE,GAAG,CAAC,SAAS,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;YAC9B,SAAS,IAAI,CAAC,CAAC;YACf,SAAS;QACX,CAAC;QAED,IACE,aAAa,IAAI,IAAI;YACrB,gBAAgB,CAAC,GAAG,CAAC,MAAM,EAAE,aAAa,CAAC,QAAQ,EAAE,aAAa,CAAC,KAAK,CAAC,EACzE,CAAC;YACD,GAAG,CAAC,SAAS,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;YAC9B,QAAQ,IAAI,CAAC,CAAC;QAChB,CAAC;IACH,CAAC;IAED,OAAO,EAAE,KAAK,EAAE,SAAS,GAAG,QAAQ,EAAE,SAAS,EAAE,QAAQ,EAAE,CAAC;AAC9D,CAAC"}
package/dist/index.d.ts CHANGED
@@ -3,18 +3,40 @@
3
3
  *
4
4
  * @module roll-parser
5
5
  */
6
- export { RollParserError, isRollParserError } from './errors';
7
- export type { RollParserErrorCode } from './errors';
8
- export { LexerError } from './lexer/lexer';
9
- export { parse, ParseError } from './parser/parser';
10
- export type { ASTNode, BinaryOpNode, DiceNode, ExplodeNode, FateDiceNode, FunctionCallNode, LiteralNode, ModifierNode, RerollNode, SuccessCountNode, UnaryOpNode, VersusNode, } from './parser/ast';
11
- export { isBinaryOp, isDice, isExplode, isFateDice, isFunctionCall, isLiteral, isModifier, isReroll, isSuccessCount, isUnaryOp, isVersus, } from './parser/ast';
12
- export type { RNG } from './rng/types';
13
- export { SeededRNG } from './rng/seeded';
14
- export { DEFAULT_MAX_DICE, DEFAULT_MAX_EXPLODE_ITERATIONS, DEFAULT_MAX_REROLL_ITERATIONS, evaluate, EvaluatorError, } from './evaluator/evaluator';
15
- export type { CompareOp, ComparePoint, DieModifier, DieResult, EvaluateOptions, RollResult, } from './types';
16
- export { DegreeOfSuccess } from './types';
17
- export { roll } from './roll';
18
- export type { RollOptions } from './roll';
6
+ export type { ErrorSpan, NotationErrorCode, RollParserErrorCode } from './errors.js';
7
+ export { getErrorSpan, isNotationError, isRollParserError, NOTATION_ERROR_CODES, ROLL_PARSER_ERROR_CODES, RollParserError, } from './errors.js';
8
+ export { DEFAULT_MAX_DICE, DEFAULT_MAX_EXPLODE_ITERATIONS, DEFAULT_MAX_REROLL_ITERATIONS, EvaluatorError, evaluate, } from './evaluator/evaluator.js';
9
+ export { LexerError, lex } from './lexer/lexer.js';
10
+ export type { Token } from './lexer/tokens.js';
11
+ export { TokenType } from './lexer/tokens.js';
12
+ export type { ASTNode, BinaryOpNode, CritThreshold, CritThresholdNode, DiceNode, DieBoundNode, ExplodeNode, FateDiceNode, FunctionCallNode, GroupedNode, GroupNode, KeepDropNode, LiteralNode, NodeSpan, RerollNode, SortNode, SuccessCountNode, UnaryOpNode, VariableNode, VersusNode, } from './parser/ast.js';
13
+ export { isBinaryOp, isCritThreshold, isDice, isDieBound, isExplode, isFateDice, isFunctionCall, isGroup, isGrouped, isKeepDrop, isLiteral, isReroll, isSort, isSuccessCount, isUnaryOp, isVariable, isVersus, } from './parser/ast.js';
14
+ export { MAX_PARSE_DEPTH, ParseError, parse } from './parser/parser.js';
15
+ export type { RngState } from './rng/seeded.js';
16
+ export { SeededRNG } from './rng/seeded.js';
17
+ export type { RNG } from './rng/types.js';
18
+ export type { RollOptions } from './roll.js';
19
+ export { roll } from './roll.js';
20
+ export type { CompareOp, ComparePoint, DieModifier, DieResult, EvaluateOptions, EvaluationOptions, KeepDropSpec, ResolvedComparePoint, ResolvedCritThreshold, RollPart, RollPartBase, RollPartType, RollResult, } from './types.js';
21
+ export { DegreeOfSuccess } from './types.js';
22
+ /**
23
+ * Installed roll-parser version — the exact string in `package.json`, so
24
+ * pre-releases keep their suffix (`'3.0.0-beta.0'`). Sourced from the
25
+ * generated `src/version.ts`, kept in sync with the manifest by
26
+ * `bun run generate:version` and gated by `check:version` and CI.
27
+ *
28
+ * Useful in bug reports and for feature-gating against a minimum version. The
29
+ * CLI prints it for `--version` and in the `--help` header.
30
+ *
31
+ * @example
32
+ * ```typescript
33
+ * import { VERSION } from 'roll-parser';
34
+ *
35
+ * VERSION; // e.g. '3.0.0', or '3.1.0-beta.0' on a pre-release
36
+ * VERSION.startsWith('3.'); // true
37
+ * ```
38
+ *
39
+ * @category Core
40
+ */
19
41
  export declare const VERSION: string;
20
42
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAGH,OAAO,EAAE,eAAe,EAAE,iBAAiB,EAAE,MAAM,UAAU,CAAC;AAC9D,YAAY,EAAE,mBAAmB,EAAE,MAAM,UAAU,CAAC;AAGpD,OAAO,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AAG3C,OAAO,EAAE,KAAK,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AACpD,YAAY,EACV,OAAO,EACP,YAAY,EACZ,QAAQ,EACR,WAAW,EACX,YAAY,EACZ,gBAAgB,EAChB,WAAW,EACX,YAAY,EACZ,UAAU,EACV,gBAAgB,EAChB,WAAW,EACX,UAAU,GACX,MAAM,cAAc,CAAC;AACtB,OAAO,EACL,UAAU,EACV,MAAM,EACN,SAAS,EACT,UAAU,EACV,cAAc,EACd,SAAS,EACT,UAAU,EACV,QAAQ,EACR,cAAc,EACd,SAAS,EACT,QAAQ,GACT,MAAM,cAAc,CAAC;AAGtB,YAAY,EAAE,GAAG,EAAE,MAAM,aAAa,CAAC;AACvC,OAAO,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AAGzC,OAAO,EACL,gBAAgB,EAChB,8BAA8B,EAC9B,6BAA6B,EAC7B,QAAQ,EACR,cAAc,GACf,MAAM,uBAAuB,CAAC;AAC/B,YAAY,EACV,SAAS,EACT,YAAY,EACZ,WAAW,EACX,SAAS,EACT,eAAe,EACf,UAAU,GACX,MAAM,SAAS,CAAC;AACjB,OAAO,EAAE,eAAe,EAAE,MAAM,SAAS,CAAC;AAG1C,OAAO,EAAE,IAAI,EAAE,MAAM,QAAQ,CAAC;AAC9B,YAAY,EAAE,WAAW,EAAE,MAAM,QAAQ,CAAC;AAI1C,eAAO,MAAM,OAAO,EAAE,MAAoB,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAIH,YAAY,EAAE,SAAS,EAAE,iBAAiB,EAAE,mBAAmB,EAAE,MAAM,aAAa,CAAC;AACrF,OAAO,EACL,YAAY,EACZ,eAAe,EACf,iBAAiB,EACjB,oBAAoB,EACpB,uBAAuB,EACvB,eAAe,GAChB,MAAM,aAAa,CAAC;AACrB,OAAO,EACL,gBAAgB,EAChB,8BAA8B,EAC9B,6BAA6B,EAC7B,cAAc,EACd,QAAQ,GACT,MAAM,0BAA0B,CAAC;AAClC,OAAO,EAAE,UAAU,EAAE,GAAG,EAAE,MAAM,kBAAkB,CAAC;AACnD,YAAY,EAAE,KAAK,EAAE,MAAM,mBAAmB,CAAC;AAC/C,OAAO,EAAE,SAAS,EAAE,MAAM,mBAAmB,CAAC;AAC9C,YAAY,EACV,OAAO,EACP,YAAY,EACZ,aAAa,EACb,iBAAiB,EACjB,QAAQ,EACR,YAAY,EACZ,WAAW,EACX,YAAY,EACZ,gBAAgB,EAChB,WAAW,EACX,SAAS,EACT,YAAY,EACZ,WAAW,EACX,QAAQ,EACR,UAAU,EACV,QAAQ,EACR,gBAAgB,EAChB,WAAW,EACX,YAAY,EACZ,UAAU,GACX,MAAM,iBAAiB,CAAC;AACzB,OAAO,EACL,UAAU,EACV,eAAe,EACf,MAAM,EACN,UAAU,EACV,SAAS,EACT,UAAU,EACV,cAAc,EACd,OAAO,EACP,SAAS,EACT,UAAU,EACV,SAAS,EACT,QAAQ,EACR,MAAM,EACN,cAAc,EACd,SAAS,EACT,UAAU,EACV,QAAQ,GACT,MAAM,iBAAiB,CAAC;AACzB,OAAO,EAAE,eAAe,EAAE,UAAU,EAAE,KAAK,EAAE,MAAM,oBAAoB,CAAC;AACxE,YAAY,EAAE,QAAQ,EAAE,MAAM,iBAAiB,CAAC;AAChD,OAAO,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAC5C,YAAY,EAAE,GAAG,EAAE,MAAM,gBAAgB,CAAC;AAC1C,YAAY,EAAE,WAAW,EAAE,MAAM,WAAW,CAAC;AAC7C,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACjC,YAAY,EACV,SAAS,EACT,YAAY,EACZ,WAAW,EACX,SAAS,EACT,eAAe,EACf,iBAAiB,EACjB,YAAY,EACZ,oBAAoB,EACpB,qBAAqB,EACrB,QAAQ,EACR,YAAY,EACZ,YAAY,EACZ,UAAU,GACX,MAAM,YAAY,CAAC;AACpB,OAAO,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;AAE7C;;;;;;;;;;;;;;;;;;GAkBG;AACH,eAAO,MAAM,OAAO,EAAE,MAAgB,CAAC"}