roll-parser 2.3.2 → 3.0.0-beta.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 (109) hide show
  1. package/CHANGELOG.md +91 -0
  2. package/README.md +175 -170
  3. package/dist/cli/args.d.ts +35 -0
  4. package/dist/cli/args.d.ts.map +1 -0
  5. package/dist/cli/format.d.ts +20 -0
  6. package/dist/cli/format.d.ts.map +1 -0
  7. package/dist/cli/index.d.ts +8 -0
  8. package/dist/cli/index.d.ts.map +1 -0
  9. package/dist/cli.js +2608 -0
  10. package/dist/cli.js.map +28 -0
  11. package/dist/errors.d.ts +42 -0
  12. package/dist/errors.d.ts.map +1 -0
  13. package/dist/evaluator/evaluator.d.ts +121 -0
  14. package/dist/evaluator/evaluator.d.ts.map +1 -0
  15. package/dist/evaluator/index.d.ts +8 -0
  16. package/dist/evaluator/index.d.ts.map +1 -0
  17. package/dist/evaluator/modifiers/compare.d.ts +15 -0
  18. package/dist/evaluator/modifiers/compare.d.ts.map +1 -0
  19. package/dist/evaluator/modifiers/crit-threshold.d.ts +28 -0
  20. package/dist/evaluator/modifiers/crit-threshold.d.ts.map +1 -0
  21. package/dist/evaluator/modifiers/explode.d.ts +48 -0
  22. package/dist/evaluator/modifiers/explode.d.ts.map +1 -0
  23. package/dist/evaluator/modifiers/keep-drop.d.ts +44 -0
  24. package/dist/evaluator/modifiers/keep-drop.d.ts.map +1 -0
  25. package/dist/evaluator/modifiers/reroll.d.ts +33 -0
  26. package/dist/evaluator/modifiers/reroll.d.ts.map +1 -0
  27. package/dist/evaluator/modifiers/sort.d.ts +23 -0
  28. package/dist/evaluator/modifiers/sort.d.ts.map +1 -0
  29. package/dist/evaluator/modifiers/success-count.d.ts +28 -0
  30. package/dist/evaluator/modifiers/success-count.d.ts.map +1 -0
  31. package/dist/index.d.ts +20 -0
  32. package/dist/index.d.ts.map +1 -0
  33. package/dist/index.js +2560 -0
  34. package/dist/index.js.map +26 -0
  35. package/dist/lexer/lexer.d.ts +90 -0
  36. package/dist/lexer/lexer.d.ts.map +1 -0
  37. package/dist/lexer/tokens.d.ts +107 -0
  38. package/dist/lexer/tokens.d.ts.map +1 -0
  39. package/dist/parser/ast.d.ts +368 -0
  40. package/dist/parser/ast.d.ts.map +1 -0
  41. package/dist/parser/parser.d.ts +145 -0
  42. package/dist/parser/parser.d.ts.map +1 -0
  43. package/dist/rng/index.d.ts +8 -0
  44. package/dist/rng/index.d.ts.map +1 -0
  45. package/dist/rng/mock.d.ts +36 -0
  46. package/dist/rng/mock.d.ts.map +1 -0
  47. package/dist/rng/seeded.d.ts +40 -0
  48. package/dist/rng/seeded.d.ts.map +1 -0
  49. package/dist/rng/types.d.ts +24 -0
  50. package/dist/rng/types.d.ts.map +1 -0
  51. package/dist/roll.d.ts +51 -0
  52. package/dist/roll.d.ts.map +1 -0
  53. package/dist/testing.d.ts +11 -0
  54. package/dist/testing.d.ts.map +1 -0
  55. package/dist/testing.js +41 -0
  56. package/dist/testing.js.map +11 -0
  57. package/dist/types.d.ts +246 -0
  58. package/dist/types.d.ts.map +1 -0
  59. package/package.json +66 -43
  60. package/src/cli/args.ts +73 -0
  61. package/src/cli/format.ts +49 -0
  62. package/src/cli/index.ts +92 -0
  63. package/src/errors.ts +90 -0
  64. package/src/evaluator/evaluator.ts +1552 -0
  65. package/src/evaluator/index.ts +14 -0
  66. package/src/evaluator/modifiers/compare.ts +29 -0
  67. package/src/evaluator/modifiers/crit-threshold.ts +59 -0
  68. package/src/evaluator/modifiers/explode.ts +219 -0
  69. package/src/evaluator/modifiers/keep-drop.ts +151 -0
  70. package/src/evaluator/modifiers/reroll.ts +165 -0
  71. package/src/evaluator/modifiers/sort.ts +30 -0
  72. package/src/evaluator/modifiers/success-count.ts +59 -0
  73. package/src/index.ts +90 -0
  74. package/src/lexer/lexer.ts +374 -0
  75. package/src/lexer/tokens.ts +187 -0
  76. package/src/parser/ast.ts +628 -0
  77. package/src/parser/parser.ts +1239 -0
  78. package/src/rng/index.ts +8 -0
  79. package/src/rng/mock.ts +65 -0
  80. package/src/rng/seeded.ts +157 -0
  81. package/src/rng/types.ts +25 -0
  82. package/src/roll.ts +74 -0
  83. package/src/testing.ts +16 -0
  84. package/src/types.ts +237 -0
  85. package/bin/help.txt +0 -19
  86. package/bin/roll-parser.js +0 -23
  87. package/dist/roll-parser.js +0 -697
  88. package/dist/roll-parser.min.js +0 -1
  89. package/index.js +0 -24
  90. package/src/complex/parse.js +0 -37
  91. package/src/complex/parseAndRoll.js +0 -21
  92. package/src/complex/parseAndRollClassic.js +0 -20
  93. package/src/complex/parseAndRollSimple.js +0 -19
  94. package/src/complex/parseAndRollWod.js +0 -20
  95. package/src/complex/parseClassicRoll.js +0 -22
  96. package/src/complex/parseSimpleRoll.js +0 -21
  97. package/src/complex/parseWodRoll.js +0 -21
  98. package/src/converter.js +0 -45
  99. package/src/grammar.js +0 -14
  100. package/src/mapper.js +0 -50
  101. package/src/normalizer.js +0 -51
  102. package/src/object/Result.js +0 -23
  103. package/src/object/Roll.js +0 -26
  104. package/src/object/Type.js +0 -5
  105. package/src/object/WodRoll.js +0 -29
  106. package/src/parser.js +0 -43
  107. package/src/random.js +0 -22
  108. package/src/roller.js +0 -106
  109. package/src/stringifier.js +0 -33
@@ -0,0 +1,42 @@
1
+ /**
2
+ * Common error base class and error codes for roll-parser.
3
+ *
4
+ * @module errors
5
+ */
6
+ /**
7
+ * All known roll-parser error codes. Single source of truth — the
8
+ * `RollParserErrorCode` type and the runtime `VALID_CODES` set are
9
+ * both derived from this array.
10
+ *
11
+ * Lexer: `UNEXPECTED_CHARACTER`, `UNEXPECTED_IDENTIFIER`
12
+ * Parser: `UNEXPECTED_TOKEN`, `UNEXPECTED_END`, `EXPECTED_TOKEN`,
13
+ * `INVALID_MODIFIER_TARGET`, `INVALID_EXPLODE_TARGET`, `INVALID_REROLL_TARGET`,
14
+ * `INVALID_SUCCESS_COUNT_TARGET`, `INVALID_SORT_TARGET`,
15
+ * `INVALID_CRIT_THRESHOLD_TARGET`, `NESTED_VERSUS`, `INVALID_FUNCTION_ARITY`,
16
+ * `AMBIGUOUS_DICE_CHAIN`, `MAX_DEPTH_EXCEEDED`
17
+ * Evaluator: `INVALID_DICE_COUNT`, `INVALID_DICE_SIDES`, `DICE_LIMIT_EXCEEDED`,
18
+ * `DIVISION_BY_ZERO`, `MODULO_BY_ZERO`, `UNKNOWN_OPERATOR`, `UNKNOWN_NODE_TYPE`,
19
+ * `INVALID_MODIFIER_COUNT`, `EXPLODE_LIMIT_EXCEEDED`, `REROLL_LIMIT_EXCEEDED`,
20
+ * `INVALID_THRESHOLD`, `NESTED_VERSUS`, `UNKNOWN_FUNCTION`, `UNDEFINED_VARIABLE`,
21
+ * `INVALID_VARIABLE_VALUE`, `NON_FINITE_RESULT`
22
+ */
23
+ declare const ROLL_PARSER_ERROR_CODES: readonly ["UNEXPECTED_CHARACTER", "UNEXPECTED_IDENTIFIER", "UNEXPECTED_TOKEN", "UNEXPECTED_END", "EXPECTED_TOKEN", "INVALID_DICE_COUNT", "INVALID_DICE_SIDES", "DICE_LIMIT_EXCEEDED", "DIVISION_BY_ZERO", "MODULO_BY_ZERO", "UNKNOWN_OPERATOR", "UNKNOWN_NODE_TYPE", "INVALID_MODIFIER_COUNT", "INVALID_MODIFIER_TARGET", "EXPLODE_LIMIT_EXCEEDED", "INVALID_EXPLODE_TARGET", "REROLL_LIMIT_EXCEEDED", "INVALID_REROLL_TARGET", "INVALID_SUCCESS_COUNT_TARGET", "INVALID_SORT_TARGET", "INVALID_CRIT_THRESHOLD_TARGET", "INVALID_THRESHOLD", "NESTED_VERSUS", "INVALID_FUNCTION_ARITY", "UNKNOWN_FUNCTION", "UNDEFINED_VARIABLE", "INVALID_VARIABLE_VALUE", "AMBIGUOUS_DICE_CHAIN", "MAX_DEPTH_EXCEEDED", "NON_FINITE_RESULT"];
24
+ export type RollParserErrorCode = (typeof ROLL_PARSER_ERROR_CODES)[number];
25
+ /**
26
+ * Base error class for all roll-parser errors.
27
+ *
28
+ * Provides a typed `code` field for programmatic error handling.
29
+ * All library errors (`LexerError`, `ParseError`, `EvaluatorError`)
30
+ * extend this class.
31
+ */
32
+ export declare class RollParserError extends Error {
33
+ readonly code: RollParserErrorCode;
34
+ constructor(message: string, code: RollParserErrorCode);
35
+ }
36
+ /**
37
+ * Type guard for roll-parser errors. Checks `instanceof` first, then
38
+ * falls back to duck-typing for cross-realm safety.
39
+ */
40
+ export declare function isRollParserError(value: unknown): value is RollParserError;
41
+ export {};
42
+ //# sourceMappingURL=errors.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../src/errors.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH;;;;;;;;;;;;;;;;GAgBG;AACH,QAAA,MAAM,uBAAuB,gsBA+BnB,CAAC;AAEX,MAAM,MAAM,mBAAmB,GAAG,CAAC,OAAO,uBAAuB,CAAC,CAAC,MAAM,CAAC,CAAC;AAE3E;;;;;;GAMG;AACH,qBAAa,eAAgB,SAAQ,KAAK;IACxC,QAAQ,CAAC,IAAI,EAAE,mBAAmB,CAAC;gBAEvB,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,mBAAmB;CAKvD;AAID;;;GAGG;AACH,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,OAAO,GAAG,KAAK,IAAI,eAAe,CAQ1E"}
@@ -0,0 +1,121 @@
1
+ /**
2
+ * AST evaluator - transforms parsed AST into roll results.
3
+ *
4
+ * @module evaluator/evaluator
5
+ */
6
+ import type { RollParserErrorCode } from '../errors.js';
7
+ import { RollParserError } from '../errors.js';
8
+ import type { ASTNode } from '../parser/ast.js';
9
+ import type { RNG } from '../rng/types.js';
10
+ import type { DieResult, EvaluateOptions, RollResult } from '../types.js';
11
+ import { DegreeOfSuccess } from '../types.js';
12
+ import { DEFAULT_MAX_EXPLODE_ITERATIONS } from './modifiers/explode.js';
13
+ import { DEFAULT_MAX_REROLL_ITERATIONS } from './modifiers/reroll.js';
14
+ /**
15
+ * Error thrown during AST evaluation.
16
+ */
17
+ export declare class EvaluatorError extends RollParserError {
18
+ readonly nodeType: string | undefined;
19
+ /**
20
+ * Source span of the tightest AST node that was being evaluated when the
21
+ * error was thrown — stamped by `evalNode` on the way up, so the innermost
22
+ * node wins. `undefined` when the AST was built without parser spans.
23
+ */
24
+ start: number | undefined;
25
+ end: number | undefined;
26
+ constructor(message: string, code: RollParserErrorCode, nodeType?: string);
27
+ }
28
+ /** Default maximum total dice allowed per evaluation. */
29
+ export declare const DEFAULT_MAX_DICE = 10000;
30
+ export { DEFAULT_MAX_EXPLODE_ITERATIONS, DEFAULT_MAX_REROLL_ITERATIONS };
31
+ /**
32
+ * Per-evaluation shared environment (created once, shared across all branches).
33
+ *
34
+ * Exported for use by modifier implementations under `./modifiers/*`. Not part
35
+ * of the public library API.
36
+ */
37
+ export type EvalEnv = {
38
+ readonly maxDice: number;
39
+ readonly maxExplodeIterations: number;
40
+ readonly maxRerollIterations: number;
41
+ totalDiceRolled: number;
42
+ /**
43
+ * Set to `true` by `evalSuccessCount`. Propagates through the shared env
44
+ * so `evaluate()` can include `successes`/`failures` fields even when no
45
+ * die was tagged (impossible threshold).
46
+ */
47
+ hasSuccessCount: boolean;
48
+ /**
49
+ * `true` while the evaluator is inside a `VersusNode`'s roll or DC
50
+ * sub-evaluation. `evalVersus` rejects nesting via this flag — catches
51
+ * paren-nested versus (`1d20 vs (5 vs 3)`) that slip past the parser's
52
+ * left-chain check.
53
+ */
54
+ insideVersus: boolean;
55
+ /**
56
+ * User-supplied variable map for `@name` / `@{name}` references. Always
57
+ * defined — `evaluate()` defaults to an empty object so lookups can be
58
+ * branch-free on presence.
59
+ */
60
+ readonly context: Readonly<Record<string, number>>;
61
+ /**
62
+ * Behavior when a referenced variable is missing from `context`. Always
63
+ * defined — `evaluate()` defaults to `'throw'`.
64
+ */
65
+ readonly onMissingVariable: 'throw' | 'zero';
66
+ };
67
+ /**
68
+ * Per-branch mutable accumulator for tracking rolls and output during recursion.
69
+ *
70
+ * @internal exported for targeted `mergeMetaRolls` tests only; not a public API.
71
+ */
72
+ export type EvalContext = {
73
+ rolls: DieResult[];
74
+ expressionParts: string[];
75
+ renderedParts: string[];
76
+ /**
77
+ * Populated by `evalVersus` with the resolved degree and natural value.
78
+ * `evaluate()` reads this from the top-level ctx to surface `degree` and
79
+ * `natural` on the final `RollResult`. Only populated when `vs` is the
80
+ * root of the expression.
81
+ */
82
+ versusMetadata?: {
83
+ degree: DegreeOfSuccess;
84
+ natural: number | undefined;
85
+ dcTotal: number;
86
+ };
87
+ };
88
+ /**
89
+ * Forwards rolls from a throwaway sub-expression context into the parent
90
+ * audit trail, tagging them as `'meta'` + `'dropped'`. Meta dice are dice
91
+ * rolled to compute parameters (dice count, sides, threshold, modifier
92
+ * count) — they consume RNG and count against `maxDice`, so they must be
93
+ * inspectable. Tagging them `'dropped'` keeps totals correct via
94
+ * `sumKeptDice`; `'meta'` lets renderers hide them and lets callers
95
+ * distinguish them from ordinary pool dice.
96
+ *
97
+ * `'success'`/`'failure'` tags are stripped here as defense-in-depth against
98
+ * a SuccessCount leaking into a meta sub-expression (parser rejects all such
99
+ * wrappings; this strip ensures a future parse regression cannot leak tags
100
+ * into the top-level `successes`/`failures` scan).
101
+ */
102
+ /** @internal exported for targeted defense-in-depth tests only. */
103
+ export declare function mergeMetaRolls(parent: EvalContext, source: EvalContext): void;
104
+ /**
105
+ * Evaluates a parsed AST and returns the roll result.
106
+ *
107
+ * @param ast - The parsed AST node
108
+ * @param rng - Random number generator to use for dice rolls
109
+ * @param options - Optional evaluation options
110
+ * @returns Complete roll result with total and metadata
111
+ *
112
+ * @example
113
+ * ```typescript
114
+ * const ast = parse('2d6+3');
115
+ * const rng = new SeededRNG('test');
116
+ * const result = evaluate(ast, rng);
117
+ * console.log(result.total); // Sum of dice plus 3
118
+ * ```
119
+ */
120
+ export declare function evaluate(ast: ASTNode, rng: RNG, options?: EvaluateOptions): RollResult;
121
+ //# sourceMappingURL=evaluator.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"evaluator.d.ts","sourceRoot":"","sources":["../../src/evaluator/evaluator.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,cAAc,CAAC;AACxD,OAAO,EAAE,eAAe,EAAE,MAAM,cAAc,CAAC;AAC/C,OAAO,KAAK,EACV,OAAO,EAkBR,MAAM,kBAAkB,CAAC;AAE1B,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,iBAAiB,CAAC;AAC3C,OAAO,KAAK,EAEV,SAAS,EACT,eAAe,EAGf,UAAU,EACX,MAAM,aAAa,CAAC;AACrB,OAAO,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAE9C,OAAO,EAKL,8BAA8B,EAC/B,MAAM,wBAAwB,CAAC;AAShC,OAAO,EAGL,6BAA6B,EAC9B,MAAM,uBAAuB,CAAC;AAI/B;;GAEG;AACH,qBAAa,cAAe,SAAQ,eAAe;IACjD,QAAQ,CAAC,QAAQ,EAAE,MAAM,GAAG,SAAS,CAAC;IACtC;;;;OAIG;IACH,KAAK,EAAE,MAAM,GAAG,SAAS,CAAC;IAC1B,GAAG,EAAE,MAAM,GAAG,SAAS,CAAC;gBAEZ,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,mBAAmB,EAAE,QAAQ,CAAC,EAAE,MAAM;CAO1E;AAED,yDAAyD;AACzD,eAAO,MAAM,gBAAgB,QAAS,CAAC;AAEvC,OAAO,EAAE,8BAA8B,EAAE,6BAA6B,EAAE,CAAC;AAEzE;;;;;GAKG;AACH,MAAM,MAAM,OAAO,GAAG;IACpB,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,oBAAoB,EAAE,MAAM,CAAC;IACtC,QAAQ,CAAC,mBAAmB,EAAE,MAAM,CAAC;IACrC,eAAe,EAAE,MAAM,CAAC;IACxB;;;;OAIG;IACH,eAAe,EAAE,OAAO,CAAC;IACzB;;;;;OAKG;IACH,YAAY,EAAE,OAAO,CAAC;IACtB;;;;OAIG;IACH,QAAQ,CAAC,OAAO,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC;IACnD;;;OAGG;IACH,QAAQ,CAAC,iBAAiB,EAAE,OAAO,GAAG,MAAM,CAAC;CAC9C,CAAC;AAEF;;;;GAIG;AACH,MAAM,MAAM,WAAW,GAAG;IACxB,KAAK,EAAE,SAAS,EAAE,CAAC;IACnB,eAAe,EAAE,MAAM,EAAE,CAAC;IAC1B,aAAa,EAAE,MAAM,EAAE,CAAC;IACxB;;;;;OAKG;IACH,cAAc,CAAC,EAAE;QACf,MAAM,EAAE,eAAe,CAAC;QACxB,OAAO,EAAE,MAAM,GAAG,SAAS,CAAC;QAC5B,OAAO,EAAE,MAAM,CAAC;KACjB,CAAC;CACH,CAAC;AA+FF;;;;;;;;;;;;;GAaG;AACH,mEAAmE;AACnE,wBAAgB,cAAc,CAAC,MAAM,EAAE,WAAW,EAAE,MAAM,EAAE,WAAW,GAAG,IAAI,CAa7E;AA8pCD;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,QAAQ,CAAC,GAAG,EAAE,OAAO,EAAE,GAAG,EAAE,GAAG,EAAE,OAAO,GAAE,eAAoB,GAAG,UAAU,CAmF1F"}
@@ -0,0 +1,8 @@
1
+ /**
2
+ * Evaluator module - AST to roll result transformation.
3
+ *
4
+ * @module evaluator
5
+ */
6
+ export { DEFAULT_MAX_DICE, evaluate, EvaluatorError } from './evaluator.js';
7
+ export { applyDropHighest, applyDropLowest, applyKeepHighest, applyKeepLowest, sumKeptDice, } from './modifiers/keep-drop.js';
8
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/evaluator/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,gBAAgB,EAAE,QAAQ,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAC;AAC5E,OAAO,EACL,gBAAgB,EAChB,eAAe,EACf,gBAAgB,EAChB,eAAe,EACf,WAAW,GACZ,MAAM,0BAA0B,CAAC"}
@@ -0,0 +1,15 @@
1
+ /**
2
+ * Shared comparison helper for dice-pool modifiers.
3
+ *
4
+ * Both reroll and success-counting modifiers compare a die result against a
5
+ * fixed threshold. Extracting the comparison keeps those modules free of
6
+ * duplicated logic.
7
+ *
8
+ * @module evaluator/modifiers/compare
9
+ */
10
+ import type { CompareOp } from '../../types.js';
11
+ /**
12
+ * Compares a die result against a fixed comparison threshold.
13
+ */
14
+ export declare function matchesCondition(result: number, operator: CompareOp, value: number): boolean;
15
+ //# sourceMappingURL=compare.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"compare.d.ts","sourceRoot":"","sources":["../../../src/evaluator/modifiers/compare.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAEhD;;GAEG;AACH,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,MAAM,EAAE,QAAQ,EAAE,SAAS,EAAE,KAAK,EAAE,MAAM,GAAG,OAAO,CAa5F"}
@@ -0,0 +1,28 @@
1
+ /**
2
+ * Critical / fumble threshold modifier.
3
+ *
4
+ * Overrides the default `critical`/`fumble` flag logic for a dice pool.
5
+ * `cs` and `cf` are independent (Roll20 semantics): the evaluator passes
6
+ * `['default']` for a side with no explicit thresholds, so overriding one
7
+ * side never wipes the other. An empty threshold array (not produced by the
8
+ * evaluator) would force the corresponding flag to `false` on every die.
9
+ * Meta dice (rolled to compute counts/sides/modifier args) are skipped so
10
+ * their bookkeeping stays untouched.
11
+ *
12
+ * Display-only: does not alter `total`, explosion triggers, success
13
+ * counting, or any other modifier flag. Dropped dice still participate —
14
+ * their `critical`/`fumble` metadata reflects what they rolled, not
15
+ * whether they contributed to the total.
16
+ *
17
+ * @module evaluator/modifiers/crit-threshold
18
+ */
19
+ import type { DieResult, ResolvedCritThreshold } from '../../types.js';
20
+ export type { ResolvedCritThreshold } from '../../types.js';
21
+ /**
22
+ * Applies success/fail threshold arrays to a dice pool, overriding each
23
+ * die's `critical` and `fumble` flags in place. A die matches `'default'`
24
+ * on the success side when `result === sides && sides > 1`, and on the
25
+ * fail side when `result === 1`. Meta dice are skipped.
26
+ */
27
+ export declare function applyCritThresholds(dice: DieResult[], successThresholds: ResolvedCritThreshold[], failThresholds: ResolvedCritThreshold[]): void;
28
+ //# sourceMappingURL=crit-threshold.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"crit-threshold.d.ts","sourceRoot":"","sources":["../../../src/evaluator/modifiers/crit-threshold.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AAEH,OAAO,KAAK,EAAE,SAAS,EAAE,qBAAqB,EAAE,MAAM,gBAAgB,CAAC;AAKvE,YAAY,EAAE,qBAAqB,EAAE,MAAM,gBAAgB,CAAC;AAE5D;;;;;GAKG;AACH,wBAAgB,mBAAmB,CACjC,IAAI,EAAE,SAAS,EAAE,EACjB,iBAAiB,EAAE,qBAAqB,EAAE,EAC1C,cAAc,EAAE,qBAAqB,EAAE,GACtC,IAAI,CAON"}
@@ -0,0 +1,48 @@
1
+ /**
2
+ * Exploding dice modifier implementations.
3
+ *
4
+ * Standard (`!`): re-roll on match, append each new die to the pool.
5
+ * Compound (`!!`): re-roll on match, accumulate into the original die's `result`.
6
+ * Penetrating (`!p`): re-roll on match, append with `result = rawRoll - 1`.
7
+ *
8
+ * @module evaluator/modifiers/explode
9
+ */
10
+ import type { RNG } from '../../rng/types.js';
11
+ import type { CompareOp } from '../../types.js';
12
+ import type { DieResult } from '../../types.js';
13
+ import { type EvalEnv } from '../evaluator.js';
14
+ /** Default maximum explosion iterations per die. */
15
+ export declare const DEFAULT_MAX_EXPLODE_ITERATIONS = 1000;
16
+ /**
17
+ * Predicate deciding whether a die with the given latest raw roll continues
18
+ * to explode. `sides` is passed separately because the default predicate
19
+ * ("explode on max face") uses `result === sides`.
20
+ */
21
+ export type ShouldExplode = (rawResult: number, sides: number) => boolean;
22
+ /**
23
+ * Builds an explosion predicate from an optional ComparePoint. When no
24
+ * threshold is given, explode when the raw result equals the die's max face.
25
+ */
26
+ export declare function buildShouldExplode(operator: CompareOp | undefined, thresholdValue: number | undefined): ShouldExplode;
27
+ /**
28
+ * Standard explode: append each new die to the pool. The original die keeps
29
+ * its modifiers untouched; new dice carry `['exploded', 'kept']`.
30
+ */
31
+ export declare function applyStandardExplode(pool: DieResult[], shouldExplode: ShouldExplode, rng: RNG, env: EvalEnv): DieResult[];
32
+ /**
33
+ * Compound explode: pool length stays the same. Each original die's `result`
34
+ * accumulates every explosion roll, and gains the `'exploded'` modifier once
35
+ * it actually exploded at least once.
36
+ *
37
+ * Mutates exploded dice in place — the same `DieResult` objects are shared
38
+ * between `RollResult.rolls` and the `RollPart` tree, and both must reflect
39
+ * post-explosion state.
40
+ */
41
+ export declare function applyCompoundExplode(pool: DieResult[], shouldExplode: ShouldExplode, rng: RNG, env: EvalEnv): DieResult[];
42
+ /**
43
+ * Penetrating explode: like standard, but each appended die stores
44
+ * `result = rawRoll - 1`. The explosion predicate runs on the RAW roll
45
+ * (pre-decrement), matching rpg-dice-roller convention.
46
+ */
47
+ export declare function applyPenetratingExplode(pool: DieResult[], shouldExplode: ShouldExplode, rng: RNG, env: EvalEnv): DieResult[];
48
+ //# sourceMappingURL=explode.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"explode.d.ts","sourceRoot":"","sources":["../../../src/evaluator/modifiers/explode.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,oBAAoB,CAAC;AAC9C,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAChD,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAChD,OAAO,EAAkB,KAAK,OAAO,EAAE,MAAM,iBAAiB,CAAC;AAE/D,oDAAoD;AACpD,eAAO,MAAM,8BAA8B,OAAQ,CAAC;AAEpD;;;;GAIG;AACH,MAAM,MAAM,aAAa,GAAG,CAAC,SAAS,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,KAAK,OAAO,CAAC;AAE1E;;;GAGG;AACH,wBAAgB,kBAAkB,CAChC,QAAQ,EAAE,SAAS,GAAG,SAAS,EAC/B,cAAc,EAAE,MAAM,GAAG,SAAS,GACjC,aAAa,CAgBf;AAyCD;;;GAGG;AACH,wBAAgB,oBAAoB,CAClC,IAAI,EAAE,SAAS,EAAE,EACjB,aAAa,EAAE,aAAa,EAC5B,GAAG,EAAE,GAAG,EACR,GAAG,EAAE,OAAO,GACX,SAAS,EAAE,CA6Bb;AAED;;;;;;;;GAQG;AACH,wBAAgB,oBAAoB,CAClC,IAAI,EAAE,SAAS,EAAE,EACjB,aAAa,EAAE,aAAa,EAC5B,GAAG,EAAE,GAAG,EACR,GAAG,EAAE,OAAO,GACX,SAAS,EAAE,CAiCb;AAED;;;;GAIG;AACH,wBAAgB,uBAAuB,CACrC,IAAI,EAAE,SAAS,EAAE,EACjB,aAAa,EAAE,aAAa,EAC5B,GAAG,EAAE,GAAG,EACR,GAAG,EAAE,OAAO,GACX,SAAS,EAAE,CA8Bb"}
@@ -0,0 +1,44 @@
1
+ /**
2
+ * Keep/drop modifier implementations for dice pools.
3
+ *
4
+ * @module evaluator/modifiers/keep-drop
5
+ */
6
+ import type { DieResult } from '../../types.js';
7
+ /**
8
+ * Marks all eligible dice as `'kept'`. Dice that already carry `'dropped'`
9
+ * (e.g., intermediate rerolls, or the loser of a prior modifier) are left
10
+ * untouched so those drops cannot be silently revived.
11
+ */
12
+ export declare function markAllKept(dice: DieResult[]): DieResult[];
13
+ /**
14
+ * Applies keep highest modifier - keeps the N highest eligible dice, marks
15
+ * others as dropped. Dice already marked `'dropped'` are left unchanged.
16
+ *
17
+ * @param dice - Array of die results
18
+ * @param count - Number of dice to keep
19
+ * @returns New array with appropriate modifiers applied
20
+ */
21
+ export declare function applyKeepHighest(dice: DieResult[], count: number): DieResult[];
22
+ /**
23
+ * Applies keep lowest modifier - keeps the N lowest eligible dice, marks
24
+ * others as dropped. Dice already marked `'dropped'` are left unchanged.
25
+ */
26
+ export declare function applyKeepLowest(dice: DieResult[], count: number): DieResult[];
27
+ /**
28
+ * Applies drop highest modifier - drops the N highest eligible dice, keeps
29
+ * the rest. Dice already marked `'dropped'` are left unchanged.
30
+ */
31
+ export declare function applyDropHighest(dice: DieResult[], count: number): DieResult[];
32
+ /**
33
+ * Applies drop lowest modifier - drops the N lowest eligible dice, keeps
34
+ * the rest. Dice already marked `'dropped'` are left unchanged.
35
+ */
36
+ export declare function applyDropLowest(dice: DieResult[], count: number): DieResult[];
37
+ /**
38
+ * Calculates total from dice, excluding dropped dice.
39
+ *
40
+ * @param dice - Array of die results
41
+ * @returns Sum of non-dropped dice
42
+ */
43
+ export declare function sumKeptDice(dice: DieResult[]): number;
44
+ //# sourceMappingURL=keep-drop.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"keep-drop.d.ts","sourceRoot":"","sources":["../../../src/evaluator/modifiers/keep-drop.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAEhD;;;;GAIG;AACH,wBAAgB,WAAW,CAAC,IAAI,EAAE,SAAS,EAAE,GAAG,SAAS,EAAE,CAQ1D;AAmDD;;;;;;;GAOG;AACH,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,SAAS,EAAE,EAAE,KAAK,EAAE,MAAM,GAAG,SAAS,EAAE,CAU9E;AAED;;;GAGG;AACH,wBAAgB,eAAe,CAAC,IAAI,EAAE,SAAS,EAAE,EAAE,KAAK,EAAE,MAAM,GAAG,SAAS,EAAE,CAU7E;AAED;;;GAGG;AACH,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,SAAS,EAAE,EAAE,KAAK,EAAE,MAAM,GAAG,SAAS,EAAE,CAU9E;AAED;;;GAGG;AACH,wBAAgB,eAAe,CAAC,IAAI,EAAE,SAAS,EAAE,EAAE,KAAK,EAAE,MAAM,GAAG,SAAS,EAAE,CAU7E;AAED;;;;;GAKG;AACH,wBAAgB,WAAW,CAAC,IAAI,EAAE,SAAS,EAAE,GAAG,MAAM,CAIrD"}
@@ -0,0 +1,33 @@
1
+ /**
2
+ * Reroll modifier implementations.
3
+ *
4
+ * Recursive (`r`): re-roll matching dice until the condition no longer holds,
5
+ * or the per-die iteration limit is reached.
6
+ * Reroll-once (`ro`): re-roll matching dice exactly once, keeping the second
7
+ * result regardless of whether it matches.
8
+ *
9
+ * @module evaluator/modifiers/reroll
10
+ */
11
+ import type { RNG } from '../../rng/types.js';
12
+ import type { CompareOp, DieResult } from '../../types.js';
13
+ import { type EvalEnv } from '../evaluator.js';
14
+ import { matchesCondition } from './compare.js';
15
+ /** Default maximum reroll iterations per die. */
16
+ export declare const DEFAULT_MAX_REROLL_ITERATIONS = 1000;
17
+ export { matchesCondition };
18
+ /**
19
+ * Applies recursive reroll: re-roll each matching die until it no longer
20
+ * matches or the per-die iteration limit is reached. Intermediate dice are
21
+ * appended to the output pool with `['rerolled', 'dropped']` so they:
22
+ * 1. Render as strikethrough (via `renderDice`'s `'dropped'` check).
23
+ * 2. Are excluded from `sumKeptDice`.
24
+ * 3. Are ignored by subsequent keep/drop modifiers.
25
+ */
26
+ export declare function applyRecursiveReroll(pool: DieResult[], operator: CompareOp, value: number, rng: RNG, env: EvalEnv): DieResult[];
27
+ /**
28
+ * Applies reroll-once: re-roll each matching die exactly once, keeping the
29
+ * second result regardless of whether it matches. Non-matching dice pass
30
+ * through with the `'kept'` slot flag.
31
+ */
32
+ export declare function applyRerollOnce(pool: DieResult[], operator: CompareOp, value: number, rng: RNG, env: EvalEnv): DieResult[];
33
+ //# sourceMappingURL=reroll.d.ts.map
@@ -0,0 +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,oBAAoB,CAAC;AAC9C,OAAO,KAAK,EAAE,SAAS,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAC3D,OAAO,EAAkB,KAAK,OAAO,EAAE,MAAM,iBAAiB,CAAC;AAC/D,OAAO,EAAE,gBAAgB,EAAE,MAAM,cAAc,CAAC;AAEhD,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,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,23 @@
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
+ * @module evaluator/modifiers/sort
11
+ */
12
+ import type { DieResult } from '../../types.js';
13
+ /**
14
+ * Returns a sorted copy of `dice` in the given order, preserving every die's
15
+ * original flags and metadata. Comparison is on `.result` — the raw face
16
+ * value is what the user sees in rendered output, so ordering by raw value
17
+ * matches the visual intent regardless of any `kept`/`dropped` flagging.
18
+ *
19
+ * Relies on `Array.prototype.sort` being stable — equal-valued dice retain
20
+ * their original insertion order.
21
+ */
22
+ export declare function sortDice(dice: DieResult[], order: 'ascending' | 'descending'): DieResult[];
23
+ //# 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;;;;;;;;;;GAUG;AAEH,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAEhD;;;;;;;;GAQG;AACH,wBAAgB,QAAQ,CAAC,IAAI,EAAE,SAAS,EAAE,EAAE,KAAK,EAAE,WAAW,GAAG,YAAY,GAAG,SAAS,EAAE,CAM1F"}
@@ -0,0 +1,28 @@
1
+ /**
2
+ * Success counting modifier.
3
+ *
4
+ * Transforms a dice pool into a signed success count: each die matching the
5
+ * success `threshold` contributes +1, each die matching the optional
6
+ * `failThreshold` contributes -1. When a single die matches both thresholds,
7
+ * success wins (checked first).
8
+ *
9
+ * Dropped dice (from a preceding keep/drop or intermediate reroll) are
10
+ * excluded from counting and are never tagged.
11
+ *
12
+ * Mutates the input pool in place to add `'success'` / `'failure'` modifier
13
+ * flags — mirrors the mutation pattern of explode and reroll modifiers.
14
+ *
15
+ * @module evaluator/modifiers/success-count
16
+ */
17
+ import type { CompareOp, DieResult } from '../../types.js';
18
+ export type ResolvedThreshold = {
19
+ operator: CompareOp;
20
+ value: number;
21
+ };
22
+ export type SuccessCountResult = {
23
+ total: number;
24
+ successes: number;
25
+ failures: number;
26
+ };
27
+ export declare function countSuccesses(dice: DieResult[], threshold: ResolvedThreshold, failThreshold?: ResolvedThreshold): SuccessCountResult;
28
+ //# sourceMappingURL=success-count.d.ts.map
@@ -0,0 +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,gBAAgB,CAAC;AAG3D,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"}
@@ -0,0 +1,20 @@
1
+ /**
2
+ * Roll Parser - Dice notation parser for tabletop RPGs.
3
+ *
4
+ * @module roll-parser
5
+ */
6
+ export { RollParserError, isRollParserError } from './errors.js';
7
+ export type { RollParserErrorCode } from './errors.js';
8
+ export { LexerError } from './lexer/lexer.js';
9
+ export { parse, ParseError } from './parser/parser.js';
10
+ export type { ASTNode, BinaryOpNode, DiceNode, NodeSpan, ExplodeNode, FateDiceNode, FunctionCallNode, GroupedNode, LiteralNode, ModifierNode, RerollNode, SuccessCountNode, SortNode, CritThresholdNode, GroupNode, UnaryOpNode, VariableNode, VersusNode, } from './parser/ast.js';
11
+ export { isBinaryOp, isCritThreshold, isDice, isExplode, isFateDice, isFunctionCall, isGroup, isGrouped, isLiteral, isModifier, isReroll, isSort, isSuccessCount, isUnaryOp, isVariable, isVersus, } from './parser/ast.js';
12
+ export type { RNG } from './rng/types.js';
13
+ export { SeededRNG } from './rng/seeded.js';
14
+ export { DEFAULT_MAX_DICE, DEFAULT_MAX_EXPLODE_ITERATIONS, DEFAULT_MAX_REROLL_ITERATIONS, evaluate, EvaluatorError, } from './evaluator/evaluator.js';
15
+ export type { CompareOp, ComparePoint, DieModifier, DieResult, EvaluateOptions, ModifierSpec, ResolvedComparePoint, ResolvedCritThreshold, RollPart, RollPartType, RollResult, } from './types.js';
16
+ export { DegreeOfSuccess } from './types.js';
17
+ export { roll } from './roll.js';
18
+ export type { RollOptions } from './roll.js';
19
+ export declare const VERSION: string;
20
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +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,aAAa,CAAC;AACjE,YAAY,EAAE,mBAAmB,EAAE,MAAM,aAAa,CAAC;AAGvD,OAAO,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAG9C,OAAO,EAAE,KAAK,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAC;AACvD,YAAY,EACV,OAAO,EACP,YAAY,EACZ,QAAQ,EACR,QAAQ,EACR,WAAW,EACX,YAAY,EACZ,gBAAgB,EAChB,WAAW,EACX,WAAW,EACX,YAAY,EACZ,UAAU,EACV,gBAAgB,EAChB,QAAQ,EACR,iBAAiB,EACjB,SAAS,EACT,WAAW,EACX,YAAY,EACZ,UAAU,GACX,MAAM,iBAAiB,CAAC;AACzB,OAAO,EACL,UAAU,EACV,eAAe,EACf,MAAM,EACN,SAAS,EACT,UAAU,EACV,cAAc,EACd,OAAO,EACP,SAAS,EACT,SAAS,EACT,UAAU,EACV,QAAQ,EACR,MAAM,EACN,cAAc,EACd,SAAS,EACT,UAAU,EACV,QAAQ,GACT,MAAM,iBAAiB,CAAC;AAGzB,YAAY,EAAE,GAAG,EAAE,MAAM,gBAAgB,CAAC;AAC1C,OAAO,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAG5C,OAAO,EACL,gBAAgB,EAChB,8BAA8B,EAC9B,6BAA6B,EAC7B,QAAQ,EACR,cAAc,GACf,MAAM,0BAA0B,CAAC;AAClC,YAAY,EACV,SAAS,EACT,YAAY,EACZ,WAAW,EACX,SAAS,EACT,eAAe,EACf,YAAY,EACZ,oBAAoB,EACpB,qBAAqB,EACrB,QAAQ,EACR,YAAY,EACZ,UAAU,GACX,MAAM,YAAY,CAAC;AACpB,OAAO,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;AAG7C,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACjC,YAAY,EAAE,WAAW,EAAE,MAAM,WAAW,CAAC;AAM7C,eAAO,MAAM,OAAO,EAAE,MAAgB,CAAC"}