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.
- package/CHANGELOG.md +91 -0
- package/README.md +175 -170
- package/dist/cli/args.d.ts +35 -0
- package/dist/cli/args.d.ts.map +1 -0
- package/dist/cli/format.d.ts +20 -0
- package/dist/cli/format.d.ts.map +1 -0
- package/dist/cli/index.d.ts +8 -0
- package/dist/cli/index.d.ts.map +1 -0
- package/dist/cli.js +2608 -0
- package/dist/cli.js.map +28 -0
- package/dist/errors.d.ts +42 -0
- package/dist/errors.d.ts.map +1 -0
- package/dist/evaluator/evaluator.d.ts +121 -0
- package/dist/evaluator/evaluator.d.ts.map +1 -0
- package/dist/evaluator/index.d.ts +8 -0
- package/dist/evaluator/index.d.ts.map +1 -0
- package/dist/evaluator/modifiers/compare.d.ts +15 -0
- package/dist/evaluator/modifiers/compare.d.ts.map +1 -0
- package/dist/evaluator/modifiers/crit-threshold.d.ts +28 -0
- package/dist/evaluator/modifiers/crit-threshold.d.ts.map +1 -0
- package/dist/evaluator/modifiers/explode.d.ts +48 -0
- package/dist/evaluator/modifiers/explode.d.ts.map +1 -0
- package/dist/evaluator/modifiers/keep-drop.d.ts +44 -0
- package/dist/evaluator/modifiers/keep-drop.d.ts.map +1 -0
- package/dist/evaluator/modifiers/reroll.d.ts +33 -0
- package/dist/evaluator/modifiers/reroll.d.ts.map +1 -0
- package/dist/evaluator/modifiers/sort.d.ts +23 -0
- package/dist/evaluator/modifiers/sort.d.ts.map +1 -0
- package/dist/evaluator/modifiers/success-count.d.ts +28 -0
- package/dist/evaluator/modifiers/success-count.d.ts.map +1 -0
- package/dist/index.d.ts +20 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +2560 -0
- package/dist/index.js.map +26 -0
- package/dist/lexer/lexer.d.ts +90 -0
- package/dist/lexer/lexer.d.ts.map +1 -0
- package/dist/lexer/tokens.d.ts +107 -0
- package/dist/lexer/tokens.d.ts.map +1 -0
- package/dist/parser/ast.d.ts +368 -0
- package/dist/parser/ast.d.ts.map +1 -0
- package/dist/parser/parser.d.ts +145 -0
- package/dist/parser/parser.d.ts.map +1 -0
- package/dist/rng/index.d.ts +8 -0
- package/dist/rng/index.d.ts.map +1 -0
- package/dist/rng/mock.d.ts +36 -0
- package/dist/rng/mock.d.ts.map +1 -0
- package/dist/rng/seeded.d.ts +40 -0
- package/dist/rng/seeded.d.ts.map +1 -0
- package/dist/rng/types.d.ts +24 -0
- package/dist/rng/types.d.ts.map +1 -0
- package/dist/roll.d.ts +51 -0
- package/dist/roll.d.ts.map +1 -0
- package/dist/testing.d.ts +11 -0
- package/dist/testing.d.ts.map +1 -0
- package/dist/testing.js +41 -0
- package/dist/testing.js.map +11 -0
- package/dist/types.d.ts +246 -0
- package/dist/types.d.ts.map +1 -0
- package/package.json +66 -43
- package/src/cli/args.ts +73 -0
- package/src/cli/format.ts +49 -0
- package/src/cli/index.ts +92 -0
- package/src/errors.ts +90 -0
- package/src/evaluator/evaluator.ts +1552 -0
- package/src/evaluator/index.ts +14 -0
- package/src/evaluator/modifiers/compare.ts +29 -0
- package/src/evaluator/modifiers/crit-threshold.ts +59 -0
- package/src/evaluator/modifiers/explode.ts +219 -0
- package/src/evaluator/modifiers/keep-drop.ts +151 -0
- package/src/evaluator/modifiers/reroll.ts +165 -0
- package/src/evaluator/modifiers/sort.ts +30 -0
- package/src/evaluator/modifiers/success-count.ts +59 -0
- package/src/index.ts +90 -0
- package/src/lexer/lexer.ts +374 -0
- package/src/lexer/tokens.ts +187 -0
- package/src/parser/ast.ts +628 -0
- package/src/parser/parser.ts +1239 -0
- package/src/rng/index.ts +8 -0
- package/src/rng/mock.ts +65 -0
- package/src/rng/seeded.ts +157 -0
- package/src/rng/types.ts +25 -0
- package/src/roll.ts +74 -0
- package/src/testing.ts +16 -0
- package/src/types.ts +237 -0
- package/bin/help.txt +0 -19
- package/bin/roll-parser.js +0 -23
- package/dist/roll-parser.js +0 -697
- package/dist/roll-parser.min.js +0 -1
- package/index.js +0 -24
- package/src/complex/parse.js +0 -37
- package/src/complex/parseAndRoll.js +0 -21
- package/src/complex/parseAndRollClassic.js +0 -20
- package/src/complex/parseAndRollSimple.js +0 -19
- package/src/complex/parseAndRollWod.js +0 -20
- package/src/complex/parseClassicRoll.js +0 -22
- package/src/complex/parseSimpleRoll.js +0 -21
- package/src/complex/parseWodRoll.js +0 -21
- package/src/converter.js +0 -45
- package/src/grammar.js +0 -14
- package/src/mapper.js +0 -50
- package/src/normalizer.js +0 -51
- package/src/object/Result.js +0 -23
- package/src/object/Roll.js +0 -26
- package/src/object/Type.js +0 -5
- package/src/object/WodRoll.js +0 -29
- package/src/parser.js +0 -43
- package/src/random.js +0 -22
- package/src/roller.js +0 -106
- package/src/stringifier.js +0 -33
|
@@ -0,0 +1,145 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Pratt parser for dice notation.
|
|
3
|
+
*
|
|
4
|
+
* @module parser/parser
|
|
5
|
+
*/
|
|
6
|
+
import type { RollParserErrorCode } from '../errors.js';
|
|
7
|
+
import { RollParserError } from '../errors.js';
|
|
8
|
+
import { type Token } from '../lexer/tokens.js';
|
|
9
|
+
import type { ComparePoint } from '../types.js';
|
|
10
|
+
import type { ASTNode } from './ast.js';
|
|
11
|
+
/**
|
|
12
|
+
* Error thrown when the parser encounters invalid syntax.
|
|
13
|
+
*/
|
|
14
|
+
export declare class ParseError extends RollParserError {
|
|
15
|
+
readonly position: number;
|
|
16
|
+
readonly token: Token | undefined;
|
|
17
|
+
constructor(message: string, code: RollParserErrorCode, position: number, token?: Token);
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* Pratt parser for dice notation.
|
|
21
|
+
*
|
|
22
|
+
* Uses binding power (precedence) to handle operator associativity and
|
|
23
|
+
* precedence without left recursion issues.
|
|
24
|
+
*/
|
|
25
|
+
export declare class Parser {
|
|
26
|
+
private readonly tokens;
|
|
27
|
+
private pos;
|
|
28
|
+
private depth;
|
|
29
|
+
constructor(tokens: Token[]);
|
|
30
|
+
/**
|
|
31
|
+
* Parse the token stream into an AST.
|
|
32
|
+
*/
|
|
33
|
+
parse(): ASTNode;
|
|
34
|
+
/**
|
|
35
|
+
* Parse an expression with minimum binding power.
|
|
36
|
+
*/
|
|
37
|
+
private parseExpression;
|
|
38
|
+
/**
|
|
39
|
+
* NUD - Null Denotation.
|
|
40
|
+
* Handles tokens that appear at the start of an expression (prefix position).
|
|
41
|
+
*/
|
|
42
|
+
private parseNud;
|
|
43
|
+
/**
|
|
44
|
+
* LED - Left Denotation.
|
|
45
|
+
* Handles tokens that appear between expressions (infix/postfix position).
|
|
46
|
+
*/
|
|
47
|
+
private parseLed;
|
|
48
|
+
/**
|
|
49
|
+
* Zero-width span for synthetic nodes (implicit counts, `d%` sides) that
|
|
50
|
+
* have no source text of their own — anchored at the governing token.
|
|
51
|
+
*/
|
|
52
|
+
private static syntheticLiteral;
|
|
53
|
+
private parseLiteral;
|
|
54
|
+
private parseUnaryMinus;
|
|
55
|
+
private parsePrefixDice;
|
|
56
|
+
private parseInfixDice;
|
|
57
|
+
private parsePrefixDicePercent;
|
|
58
|
+
private parseInfixDicePercent;
|
|
59
|
+
private parsePrefixFateDice;
|
|
60
|
+
private parseInfixFateDice;
|
|
61
|
+
private parseGrouped;
|
|
62
|
+
private parseGroup;
|
|
63
|
+
private parseVariable;
|
|
64
|
+
private parseFunctionCall;
|
|
65
|
+
private parseBinaryOp;
|
|
66
|
+
/**
|
|
67
|
+
* Rejects a dice token whose count operand is itself a bare (unparenthesized)
|
|
68
|
+
* dice expression. `4d6d1` would otherwise silently parse as `(4d6)d1` —
|
|
69
|
+
* roll 4d6, then use the result as a count of d1 dice — which is almost
|
|
70
|
+
* never intended: every major dice dialect reads `4d6d1` as "drop lowest 1".
|
|
71
|
+
* Both meanings stay reachable through explicit forms: `4d6dl1` to drop,
|
|
72
|
+
* `(4d6)d1` for nested dice.
|
|
73
|
+
*/
|
|
74
|
+
private rejectBareDiceChain;
|
|
75
|
+
private rejectSuccessCountTarget;
|
|
76
|
+
/**
|
|
77
|
+
* Rejects `GroupNode` (or a wrapper-cloaked group) as the target of `token`.
|
|
78
|
+
* Explode, reroll, and crit-threshold wrap bare dice pools only — a group
|
|
79
|
+
* is a container of sub-expressions, so these modifiers have no defined
|
|
80
|
+
* semantics. Walks `Grouped`/`Modifier`/`Sort`/`CritThreshold` so wrappers
|
|
81
|
+
* cannot smuggle a group past the check (`{1d6}kh1cs>5`, `({1d6})!`,
|
|
82
|
+
* `{1d6}scs>5` all reject the same as `{1d6}!`/`{1d6}cs>5`).
|
|
83
|
+
*
|
|
84
|
+
* `singleSubRollPasses` opts the caller into the Stage 3 single-sub-roll
|
|
85
|
+
* passthrough rule (STAGE3.md "Group Semantics: Single vs Multi Sub-Roll"):
|
|
86
|
+
* a `Group` with one expression is the user's explicit flat-pool escape
|
|
87
|
+
* hatch and is equivalent to its unwrapped form. Currently only
|
|
88
|
+
* `parseCritThreshold` opts in — explode/reroll keep the strict reject so
|
|
89
|
+
* existing notation contracts don't shift.
|
|
90
|
+
*/
|
|
91
|
+
private rejectGroupTarget;
|
|
92
|
+
private rejectVersusTarget;
|
|
93
|
+
private parseModifier;
|
|
94
|
+
private parseExplode;
|
|
95
|
+
private parseReroll;
|
|
96
|
+
private parseSort;
|
|
97
|
+
private parseCritThreshold;
|
|
98
|
+
private parseSuccessCount;
|
|
99
|
+
private parseVersus;
|
|
100
|
+
/**
|
|
101
|
+
* Checks whether the next token is a comparison operator.
|
|
102
|
+
*/
|
|
103
|
+
isComparePointAhead(): boolean;
|
|
104
|
+
/**
|
|
105
|
+
* Parses a comparison operator followed by a value expression.
|
|
106
|
+
* Called by modifier parsers (explode, reroll, success counting).
|
|
107
|
+
*
|
|
108
|
+
* The threshold value is parsed at `BP.DICE_LEFT`, which binds tighter than
|
|
109
|
+
* arithmetic. This keeps the comparison bound to the dice pool on the left
|
|
110
|
+
* rather than letting arithmetic to the right be consumed into the
|
|
111
|
+
* threshold. As a consequence, `1d6>=5+2` parses as `(1d6>=5)+2` with
|
|
112
|
+
* threshold `5` — not `7`. Computed thresholds require parens:
|
|
113
|
+
* `1d6>=(5+2)`. Same binding applies to `parseSuccessCount` below.
|
|
114
|
+
*
|
|
115
|
+
* @returns A ComparePoint with the operator and value AST node
|
|
116
|
+
* @throws {ParseError} If the next token is not a comparison operator
|
|
117
|
+
*/
|
|
118
|
+
parseComparePoint(): ComparePoint;
|
|
119
|
+
private getCompareOp;
|
|
120
|
+
private getOperatorSymbol;
|
|
121
|
+
private getLeftBp;
|
|
122
|
+
private getRightBp;
|
|
123
|
+
private peek;
|
|
124
|
+
private advance;
|
|
125
|
+
private expect;
|
|
126
|
+
private hasTokens;
|
|
127
|
+
}
|
|
128
|
+
/**
|
|
129
|
+
* Parse a dice notation string into an AST.
|
|
130
|
+
*
|
|
131
|
+
* @param notation - The dice notation to parse
|
|
132
|
+
* @returns The root AST node
|
|
133
|
+
* @throws {LexerError} If the input contains invalid characters
|
|
134
|
+
* @throws {ParseError} If the input has invalid syntax
|
|
135
|
+
*
|
|
136
|
+
* @example
|
|
137
|
+
* ```typescript
|
|
138
|
+
* const ast = parse('2d6+3');
|
|
139
|
+
* // { type: 'BinaryOp', operator: '+',
|
|
140
|
+
* // left: { type: 'Dice', count: 2, sides: 6 },
|
|
141
|
+
* // right: { type: 'Literal', value: 3 } }
|
|
142
|
+
* ```
|
|
143
|
+
*/
|
|
144
|
+
export declare function parse(notation: string): ASTNode;
|
|
145
|
+
//# sourceMappingURL=parser.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"parser.d.ts","sourceRoot":"","sources":["../../src/parser/parser.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,cAAc,CAAC;AACxD,OAAO,EAAE,eAAe,EAAE,MAAM,cAAc,CAAC;AAE/C,OAAO,EAAE,KAAK,KAAK,EAAa,MAAM,oBAAoB,CAAC;AAC3D,OAAO,KAAK,EAAa,YAAY,EAAE,MAAM,aAAa,CAAC;AAC3D,OAAO,KAAK,EACV,OAAO,EAkBR,MAAM,UAAU,CAAC;AAYlB;;GAEG;AACH,qBAAa,UAAW,SAAQ,eAAe;IAC7C,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,KAAK,EAAE,KAAK,GAAG,SAAS,CAAC;gBAEtB,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,mBAAmB,EAAE,QAAQ,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,KAAK;CAMxF;AAwED;;;;;GAKG;AACH,qBAAa,MAAM;IACjB,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAU;IACjC,OAAO,CAAC,GAAG,CAAK;IAChB,OAAO,CAAC,KAAK,CAAK;gBAEN,MAAM,EAAE,KAAK,EAAE;IAI3B;;OAEG;IACH,KAAK,IAAI,OAAO;IAqBhB;;OAEG;IACH,OAAO,CAAC,eAAe;IA8BvB;;;OAGG;IACH,OAAO,CAAC,QAAQ;IA4ChB;;;OAGG;IACH,OAAO,CAAC,QAAQ;IAgEhB;;;OAGG;IACH,OAAO,CAAC,MAAM,CAAC,gBAAgB;IAI/B,OAAO,CAAC,YAAY;IASpB,OAAO,CAAC,eAAe;IAYvB,OAAO,CAAC,eAAe;IAcvB,OAAO,CAAC,cAAc;IAiBtB,OAAO,CAAC,sBAAsB;IAW9B,OAAO,CAAC,qBAAqB;IAc7B,OAAO,CAAC,mBAAmB;IAU3B,OAAO,CAAC,kBAAkB;IAe1B,OAAO,CAAC,YAAY;IAMpB,OAAO,CAAC,UAAU;IA4BlB,OAAO,CAAC,aAAa;IAIrB,OAAO,CAAC,iBAAiB;IA0DzB,OAAO,CAAC,aAAa;IAmBrB;;;;;;;OAOG;IACH,OAAO,CAAC,mBAAmB;IAoB3B,OAAO,CAAC,wBAAwB;IAgBhC;;;;;;;;;;;;;;OAcG;IACH,OAAO,CAAC,iBAAiB;IAwBzB,OAAO,CAAC,kBAAkB;IAoC1B,OAAO,CAAC,aAAa;IAqDrB,OAAO,CAAC,YAAY;IA+DpB,OAAO,CAAC,WAAW;IAyCnB,OAAO,CAAC,SAAS;IAgDjB,OAAO,CAAC,kBAAkB;IA+E1B,OAAO,CAAC,iBAAiB;IA8CzB,OAAO,CAAC,WAAW;IA6BnB;;OAEG;IACH,mBAAmB,IAAI,OAAO;IAW9B;;;;;;;;;;;;;OAaG;IACH,iBAAiB,IAAI,YAAY;IAajC,OAAO,CAAC,YAAY;IAwBpB,OAAO,CAAC,iBAAiB;IAwBzB,OAAO,CAAC,SAAS;IA2DjB,OAAO,CAAC,UAAU;IAoBlB,OAAO,CAAC,IAAI;IAMZ,OAAO,CAAC,OAAO;IAMf,OAAO,CAAC,MAAM;IAed,OAAO,CAAC,SAAS;CAGlB;AAED;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,KAAK,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAI/C"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/rng/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,YAAY,EAAE,GAAG,EAAE,MAAM,YAAY,CAAC;AACtC,OAAO,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC"}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Mock RNG for deterministic testing.
|
|
3
|
+
*
|
|
4
|
+
* @module rng/mock
|
|
5
|
+
*/
|
|
6
|
+
import type { RNG } from './types.js';
|
|
7
|
+
/**
|
|
8
|
+
* Error thrown when MockRNG exhausts its predefined values.
|
|
9
|
+
*
|
|
10
|
+
* This is intentional behavior to catch incorrect roll counts in tests.
|
|
11
|
+
* If you see this error, your test is consuming more random values than expected.
|
|
12
|
+
*/
|
|
13
|
+
export declare class MockRNGExhaustedError extends Error {
|
|
14
|
+
readonly consumed: number;
|
|
15
|
+
constructor(consumed: number);
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* Creates a mock RNG that returns predefined values in sequence.
|
|
19
|
+
*
|
|
20
|
+
* IMPORTANT: Throws MockRNGExhaustedError when all values are consumed.
|
|
21
|
+
* This behavior catches incorrect roll counts in tests - it never wraps around.
|
|
22
|
+
*
|
|
23
|
+
* @param values - Array of values to return (dice results for nextInt, floats for next)
|
|
24
|
+
* @returns RNG instance returning predefined values
|
|
25
|
+
*
|
|
26
|
+
* @example
|
|
27
|
+
* ```typescript
|
|
28
|
+
* const rng = createMockRng([4, 2, 6]);
|
|
29
|
+
* rng.nextInt(1, 6); // Returns 4
|
|
30
|
+
* rng.nextInt(1, 6); // Returns 2
|
|
31
|
+
* rng.nextInt(1, 6); // Returns 6
|
|
32
|
+
* rng.nextInt(1, 6); // Throws MockRNGExhaustedError
|
|
33
|
+
* ```
|
|
34
|
+
*/
|
|
35
|
+
export declare function createMockRng(values: number[]): RNG;
|
|
36
|
+
//# sourceMappingURL=mock.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"mock.d.ts","sourceRoot":"","sources":["../../src/rng/mock.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,YAAY,CAAC;AAEtC;;;;;GAKG;AACH,qBAAa,qBAAsB,SAAQ,KAAK;IAC9C,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;gBAEd,QAAQ,EAAE,MAAM;CAK7B;AAED;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAgB,aAAa,CAAC,MAAM,EAAE,MAAM,EAAE,GAAG,GAAG,CAsBnD"}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Seedable RNG using xorshift128 algorithm.
|
|
3
|
+
*
|
|
4
|
+
* @module rng/seeded
|
|
5
|
+
*/
|
|
6
|
+
import type { RNG } from './types.js';
|
|
7
|
+
/**
|
|
8
|
+
* Seedable pseudo-random number generator using xorshift128.
|
|
9
|
+
*
|
|
10
|
+
* Produces reproducible sequences from identical seeds.
|
|
11
|
+
* Period: 2^128 - 1
|
|
12
|
+
*
|
|
13
|
+
* @example
|
|
14
|
+
* ```typescript
|
|
15
|
+
* // Same seed = same sequence
|
|
16
|
+
* const rng1 = new SeededRNG('test-seed');
|
|
17
|
+
* const rng2 = new SeededRNG('test-seed');
|
|
18
|
+
* rng1.nextInt(1, 6) === rng2.nextInt(1, 6); // true
|
|
19
|
+
* ```
|
|
20
|
+
*/
|
|
21
|
+
export declare class SeededRNG implements RNG {
|
|
22
|
+
private s0;
|
|
23
|
+
private s1;
|
|
24
|
+
private s2;
|
|
25
|
+
private s3;
|
|
26
|
+
constructor(seed?: string | number);
|
|
27
|
+
private initState;
|
|
28
|
+
private hashString;
|
|
29
|
+
private nextUint32;
|
|
30
|
+
next(): number;
|
|
31
|
+
nextInt(min: number, max: number): number;
|
|
32
|
+
/**
|
|
33
|
+
* Unbiased sampling in `[0, range)` for ranges above 2^32, built from two
|
|
34
|
+
* uint32 draws combined into a 53-bit integer (the largest width JS numbers
|
|
35
|
+
* represent exactly). Ranges beyond 2^53 cannot be sampled without bias —
|
|
36
|
+
* throw instead of silently degrading.
|
|
37
|
+
*/
|
|
38
|
+
private nextBoundedWide;
|
|
39
|
+
}
|
|
40
|
+
//# sourceMappingURL=seeded.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"seeded.d.ts","sourceRoot":"","sources":["../../src/rng/seeded.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,YAAY,CAAC;AAEtC;;;;;;;;;;;;;GAaG;AACH,qBAAa,SAAU,YAAW,GAAG;IACnC,OAAO,CAAC,EAAE,CAAS;IACnB,OAAO,CAAC,EAAE,CAAS;IACnB,OAAO,CAAC,EAAE,CAAS;IACnB,OAAO,CAAC,EAAE,CAAS;gBAEP,IAAI,CAAC,EAAE,MAAM,GAAG,MAAM;IAelC,OAAO,CAAC,SAAS;IA+BjB,OAAO,CAAC,UAAU;IASlB,OAAO,CAAC,UAAU;IAgBlB,IAAI,IAAI,MAAM;IAKd,OAAO,CAAC,GAAG,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,MAAM;IA6BzC;;;;;OAKG;IACH,OAAO,CAAC,eAAe;CAiBxB"}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Random Number Generator interface.
|
|
3
|
+
*
|
|
4
|
+
* All dice rolling MUST use this interface - never use Math.random() directly.
|
|
5
|
+
*
|
|
6
|
+
* @module rng/types
|
|
7
|
+
*/
|
|
8
|
+
/**
|
|
9
|
+
* Random Number Generator interface for dice rolling.
|
|
10
|
+
*/
|
|
11
|
+
export type RNG = {
|
|
12
|
+
/**
|
|
13
|
+
* Returns a random floating-point number in the range [0, 1).
|
|
14
|
+
*/
|
|
15
|
+
next(): number;
|
|
16
|
+
/**
|
|
17
|
+
* Returns a random integer in the inclusive range [min, max].
|
|
18
|
+
*
|
|
19
|
+
* @param min - Minimum value (inclusive)
|
|
20
|
+
* @param max - Maximum value (inclusive)
|
|
21
|
+
*/
|
|
22
|
+
nextInt(min: number, max: number): number;
|
|
23
|
+
};
|
|
24
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/rng/types.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH;;GAEG;AACH,MAAM,MAAM,GAAG,GAAG;IAChB;;OAEG;IACH,IAAI,IAAI,MAAM,CAAC;IAEf;;;;;OAKG;IACH,OAAO,CAAC,GAAG,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,MAAM,CAAC;CAC3C,CAAC"}
|
package/dist/roll.d.ts
ADDED
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Main public API for rolling dice expressions.
|
|
3
|
+
*
|
|
4
|
+
* @module roll
|
|
5
|
+
*/
|
|
6
|
+
import type { RNG } from './rng/types.js';
|
|
7
|
+
import type { RollResult } from './types.js';
|
|
8
|
+
/**
|
|
9
|
+
* Options for the roll function.
|
|
10
|
+
*/
|
|
11
|
+
export type RollOptions = {
|
|
12
|
+
/** Custom RNG instance (takes precedence over seed) */
|
|
13
|
+
rng?: RNG;
|
|
14
|
+
/** Seed for deterministic rolls (ignored if rng provided) */
|
|
15
|
+
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
|
+
/** Variable context for `@name` / `@{name}` references (default: empty) */
|
|
23
|
+
context?: Record<string, number>;
|
|
24
|
+
/** Behavior when a referenced variable is missing from context (default: 'throw') */
|
|
25
|
+
onMissingVariable?: 'throw' | 'zero';
|
|
26
|
+
};
|
|
27
|
+
/**
|
|
28
|
+
* Parses and evaluates a dice notation string.
|
|
29
|
+
*
|
|
30
|
+
* @param notation - Dice notation (e.g., "2d6+3", "4d6kh3")
|
|
31
|
+
* @param options - Optional configuration (RNG or seed)
|
|
32
|
+
* @returns Complete roll result with total and metadata
|
|
33
|
+
*
|
|
34
|
+
* @example
|
|
35
|
+
* ```typescript
|
|
36
|
+
* // Random roll
|
|
37
|
+
* const result = roll('2d6+3');
|
|
38
|
+
* console.log(result.total); // 5-15
|
|
39
|
+
*
|
|
40
|
+
* // Seeded for reproducibility
|
|
41
|
+
* const r1 = roll('4d6', { seed: 'test' });
|
|
42
|
+
* const r2 = roll('4d6', { seed: 'test' });
|
|
43
|
+
* r1.total === r2.total; // true
|
|
44
|
+
*
|
|
45
|
+
* // Custom RNG for testing
|
|
46
|
+
* const result = roll('1d20', { rng: createMockRng([15]) });
|
|
47
|
+
* result.total; // 15
|
|
48
|
+
* ```
|
|
49
|
+
*/
|
|
50
|
+
export declare function roll(notation: string, options?: RollOptions): RollResult;
|
|
51
|
+
//# sourceMappingURL=roll.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"roll.d.ts","sourceRoot":"","sources":["../src/roll.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,gBAAgB,CAAC;AAC1C,OAAO,KAAK,EAAmB,UAAU,EAAE,MAAM,YAAY,CAAC;AAM9D;;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;IAC7B,2EAA2E;IAC3E,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACjC,qFAAqF;IACrF,iBAAiB,CAAC,EAAE,OAAO,GAAG,MAAM,CAAC;CACtC,CAAC;AAEF;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,wBAAgB,IAAI,CAAC,QAAQ,EAAE,MAAM,EAAE,OAAO,GAAE,WAAgB,GAAG,UAAU,CAiB5E"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Test utilities for roll-parser consumers.
|
|
3
|
+
*
|
|
4
|
+
* Import from `roll-parser/testing` for deterministic dice testing.
|
|
5
|
+
*
|
|
6
|
+
* @module testing
|
|
7
|
+
*/
|
|
8
|
+
import { MockRNGExhaustedError as _MockRNGExhaustedError, createMockRng as _createMockRng } from './rng/mock.js';
|
|
9
|
+
export declare const createMockRng: typeof _createMockRng;
|
|
10
|
+
export declare const MockRNGExhaustedError: typeof _MockRNGExhaustedError;
|
|
11
|
+
//# sourceMappingURL=testing.d.ts.map
|
|
@@ -0,0 +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,eAAe,CAAC;AAEvB,eAAO,MAAM,aAAa,uBAAiB,CAAC;AAC5C,eAAO,MAAM,qBAAqB,+BAAyB,CAAC"}
|
package/dist/testing.js
ADDED
|
@@ -0,0 +1,41 @@
|
|
|
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
|
+
};
|
|
39
|
+
|
|
40
|
+
//# debugId=916ECEA68894E64864756E2164756E21
|
|
41
|
+
//# sourceMappingURL=testing.js.map
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../src/rng/mock.ts", "../src/testing.ts"],
|
|
4
|
+
"sourcesContent": [
|
|
5
|
+
"/**\n * Mock RNG for deterministic testing.\n *\n * @module rng/mock\n */\n\nimport type { RNG } from './types.js';\n\n/**\n * Error thrown when MockRNG exhausts its predefined values.\n *\n * This is intentional behavior to catch incorrect roll counts in tests.\n * If you see this error, your test is consuming more random values than expected.\n */\nexport class MockRNGExhaustedError extends Error {\n readonly consumed: number;\n\n constructor(consumed: number) {\n super(`MockRNG exhausted: consumed ${consumed} values, no more available`);\n this.name = 'MockRNGExhaustedError';\n this.consumed = consumed;\n }\n}\n\n/**\n * Creates a mock RNG that returns predefined values in sequence.\n *\n * IMPORTANT: Throws MockRNGExhaustedError when all values are consumed.\n * This behavior catches incorrect roll counts in tests - it never wraps around.\n *\n * @param values - Array of values to return (dice results for nextInt, floats for next)\n * @returns RNG instance returning predefined values\n *\n * @example\n * ```typescript\n * const rng = createMockRng([4, 2, 6]);\n * rng.nextInt(1, 6); // Returns 4\n * rng.nextInt(1, 6); // Returns 2\n * rng.nextInt(1, 6); // Returns 6\n * rng.nextInt(1, 6); // Throws MockRNGExhaustedError\n * ```\n */\nexport function createMockRng(values: number[]): RNG {\n let index = 0;\n\n const getNext = (): number => {\n const value = values[index];\n if (value === undefined) {\n throw new MockRNGExhaustedError(index);\n }\n index++;\n return value;\n };\n\n return {\n next: getNext,\n nextInt: (min: number, max: number): number => {\n const value = getNext();\n if (value < min || value > max) {\n throw new RangeError(`MockRNG value ${value} is out of bounds [${min}, ${max}]`);\n }\n return value;\n },\n };\n}\n",
|
|
6
|
+
"/**\n * Test utilities for roll-parser consumers.\n *\n * Import from `roll-parser/testing` for deterministic dice testing.\n *\n * @module testing\n */\n\n// Direct value exports force the bundler to inline the code\nimport {\n MockRNGExhaustedError as _MockRNGExhaustedError,\n createMockRng as _createMockRng,\n} from './rng/mock.js';\n\nexport const createMockRng = _createMockRng;\nexport const MockRNGExhaustedError = _MockRNGExhaustedError;\n"
|
|
7
|
+
],
|
|
8
|
+
"mappings": ";AAcO,MAAM,8BAA8B,MAAM;AAAA,EACtC;AAAA,EAET,WAAW,CAAC,UAAkB;AAAA,IAC5B,MAAM,+BAA+B,oCAAoC;AAAA,IACzE,KAAK,OAAO;AAAA,IACZ,KAAK,WAAW;AAAA;AAEpB;AAoBO,SAAS,aAAa,CAAC,QAAuB;AAAA,EACnD,IAAI,QAAQ;AAAA,EAEZ,MAAM,UAAU,MAAc;AAAA,IAC5B,MAAM,QAAQ,OAAO;AAAA,IACrB,IAAI,UAAU,WAAW;AAAA,MACvB,MAAM,IAAI,sBAAsB,KAAK;AAAA,IACvC;AAAA,IACA;AAAA,IACA,OAAO;AAAA;AAAA,EAGT,OAAO;AAAA,IACL,MAAM;AAAA,IACN,SAAS,CAAC,KAAa,QAAwB;AAAA,MAC7C,MAAM,QAAQ,QAAQ;AAAA,MACtB,IAAI,QAAQ,OAAO,QAAQ,KAAK;AAAA,QAC9B,MAAM,IAAI,WAAW,iBAAiB,2BAA2B,QAAQ,MAAM;AAAA,MACjF;AAAA,MACA,OAAO;AAAA;AAAA,EAEX;AAAA;;;ACjDK,IAAM,iBAAgB;AACtB,IAAM,yBAAwB;",
|
|
9
|
+
"debugId": "916ECEA68894E64864756E2164756E21",
|
|
10
|
+
"names": []
|
|
11
|
+
}
|
package/dist/types.d.ts
ADDED
|
@@ -0,0 +1,246 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shared type definitions for roll results and comparison primitives.
|
|
3
|
+
*
|
|
4
|
+
* @module types
|
|
5
|
+
*/
|
|
6
|
+
import type { ASTNode } from './parser/ast.js';
|
|
7
|
+
/**
|
|
8
|
+
* Comparison operator for compare points.
|
|
9
|
+
*/
|
|
10
|
+
export type CompareOp = '>' | '>=' | '<' | '<=' | '=';
|
|
11
|
+
/**
|
|
12
|
+
* A comparison threshold used by exploding dice, reroll, and success counting.
|
|
13
|
+
*
|
|
14
|
+
* The value is an ASTNode to support computed thresholds (e.g., `>=ceil(5)`),
|
|
15
|
+
* matching the pattern used by DiceNode.count and DiceNode.sides.
|
|
16
|
+
*/
|
|
17
|
+
export type ComparePoint = {
|
|
18
|
+
operator: CompareOp;
|
|
19
|
+
value: ASTNode;
|
|
20
|
+
};
|
|
21
|
+
/**
|
|
22
|
+
* A ComparePoint whose value has been evaluated to a number. Used in
|
|
23
|
+
* `RollPart` where meta-expressions are already resolved.
|
|
24
|
+
*/
|
|
25
|
+
export type ResolvedComparePoint = {
|
|
26
|
+
operator: CompareOp;
|
|
27
|
+
value: number;
|
|
28
|
+
};
|
|
29
|
+
/**
|
|
30
|
+
* A resolved crit threshold — `'default'` means the per-die default rule
|
|
31
|
+
* (`result === sides` for critical, `result === 1` for fumble).
|
|
32
|
+
*/
|
|
33
|
+
export type ResolvedCritThreshold = ResolvedComparePoint | 'default';
|
|
34
|
+
/**
|
|
35
|
+
* Modifier flags applied to individual die results.
|
|
36
|
+
*/
|
|
37
|
+
export type DieModifier = 'dropped' | 'kept' | 'exploded' | 'rerolled' | 'success' | 'failure' | 'meta';
|
|
38
|
+
/**
|
|
39
|
+
* PF2e Degree of Success. Produced by the `vs` operator when comparing a
|
|
40
|
+
* roll against a Difficulty Class. Ordering is significant — natural 20
|
|
41
|
+
* upgrades one step and natural 1 downgrades one step.
|
|
42
|
+
*/
|
|
43
|
+
export declare enum DegreeOfSuccess {
|
|
44
|
+
CriticalFailure = 0,
|
|
45
|
+
Failure = 1,
|
|
46
|
+
Success = 2,
|
|
47
|
+
CriticalSuccess = 3
|
|
48
|
+
}
|
|
49
|
+
/**
|
|
50
|
+
* Individual die roll result with metadata.
|
|
51
|
+
*/
|
|
52
|
+
export type DieResult = {
|
|
53
|
+
/**
|
|
54
|
+
* Number of sides on the die. Normal dice use `sides >= 1`. Fate/Fudge
|
|
55
|
+
* dice use `sides = 0` as a sentinel — they have no configurable sides
|
|
56
|
+
* and always produce results in {-1, 0, +1}.
|
|
57
|
+
*/
|
|
58
|
+
sides: number;
|
|
59
|
+
/** The rolled value */
|
|
60
|
+
result: number;
|
|
61
|
+
/**
|
|
62
|
+
* Raw first roll before any mutation (e.g., compound-explode accumulation).
|
|
63
|
+
* Only populated when `result` has been overwritten with a computed value.
|
|
64
|
+
* Consumers that need the original face (nat-20 / nat-1 detection) should
|
|
65
|
+
* read `initialResult ?? result`.
|
|
66
|
+
*/
|
|
67
|
+
initialResult?: number;
|
|
68
|
+
/** Modifiers applied to this die */
|
|
69
|
+
modifiers: DieModifier[];
|
|
70
|
+
/** True if rolled the maximum value (always false for Fate dice) */
|
|
71
|
+
critical: boolean;
|
|
72
|
+
/** True if rolled 1 (always false for Fate dice) */
|
|
73
|
+
fumble: boolean;
|
|
74
|
+
};
|
|
75
|
+
/**
|
|
76
|
+
* Per-spec keep/drop entry inside a flattened modifier chain. Counts are
|
|
77
|
+
* resolved at evaluation time (meta-expressions like `kh(1d2)` become the
|
|
78
|
+
* rolled number).
|
|
79
|
+
*/
|
|
80
|
+
export type ModifierSpec = {
|
|
81
|
+
kind: 'keep' | 'drop';
|
|
82
|
+
selector: 'highest' | 'lowest';
|
|
83
|
+
count: number;
|
|
84
|
+
};
|
|
85
|
+
/**
|
|
86
|
+
* Fields shared by every RollPart variant. `start`/`end` mirror the source
|
|
87
|
+
* span of the AST node the part was evaluated from — present whenever the
|
|
88
|
+
* AST came from `parse()`, absent on hand-built ASTs.
|
|
89
|
+
*/
|
|
90
|
+
type RollPartBase = {
|
|
91
|
+
/** Sub-total this part contributed to its parent. */
|
|
92
|
+
total: number;
|
|
93
|
+
start?: number;
|
|
94
|
+
end?: number;
|
|
95
|
+
};
|
|
96
|
+
/**
|
|
97
|
+
* Structured breakdown of an evaluated expression, mirroring the AST 1:1 —
|
|
98
|
+
* every ASTNode produces exactly one RollPart. Discriminants are lowercase
|
|
99
|
+
* camelCase to distinguish evaluation-tree types from `ASTNode.type`
|
|
100
|
+
* (PascalCase) at a glance.
|
|
101
|
+
*
|
|
102
|
+
* Invariants:
|
|
103
|
+
* - `RollResult.parts.total === RollResult.total`.
|
|
104
|
+
* - `successCount.total === successes - failures`.
|
|
105
|
+
* - `literal.total === value` and `variable.total === value`.
|
|
106
|
+
* - Each part's `rolls[]` shares `DieResult` references with
|
|
107
|
+
* `RollResult.rolls[]`; both reflect post-evaluation state (explode
|
|
108
|
+
* accumulation, reroll flags, keep/drop flags). No deep clone.
|
|
109
|
+
*
|
|
110
|
+
* Meta-expression sub-trees (`4d6kh(1d2)`, `(1+1)d6` counts/sides, computed
|
|
111
|
+
* thresholds) are not surfaced as nested parts — their resolved numbers
|
|
112
|
+
* appear in the owning part, and their dice are inspectable in
|
|
113
|
+
* `RollResult.rolls` via the `'meta'` modifier tag.
|
|
114
|
+
*/
|
|
115
|
+
export type RollPart = (RollPartBase & {
|
|
116
|
+
type: 'literal';
|
|
117
|
+
value: number;
|
|
118
|
+
}) | (RollPartBase & {
|
|
119
|
+
type: 'variable';
|
|
120
|
+
name: string;
|
|
121
|
+
value: number;
|
|
122
|
+
}) | (RollPartBase & {
|
|
123
|
+
type: 'dice';
|
|
124
|
+
count: number;
|
|
125
|
+
sides: number;
|
|
126
|
+
rolls: DieResult[];
|
|
127
|
+
}) | (RollPartBase & {
|
|
128
|
+
type: 'fateDice';
|
|
129
|
+
count: number;
|
|
130
|
+
rolls: DieResult[];
|
|
131
|
+
}) | (RollPartBase & {
|
|
132
|
+
type: 'grouped';
|
|
133
|
+
inner: RollPart;
|
|
134
|
+
}) | (RollPartBase & {
|
|
135
|
+
type: 'binaryOp';
|
|
136
|
+
operator: '+' | '-' | '*' | '/' | '%' | '**';
|
|
137
|
+
left: RollPart;
|
|
138
|
+
right: RollPart;
|
|
139
|
+
}) | (RollPartBase & {
|
|
140
|
+
type: 'unaryOp';
|
|
141
|
+
operator: '-';
|
|
142
|
+
operand: RollPart;
|
|
143
|
+
}) | (RollPartBase & {
|
|
144
|
+
type: 'modifier';
|
|
145
|
+
specs: ModifierSpec[];
|
|
146
|
+
target: RollPart;
|
|
147
|
+
}) | (RollPartBase & {
|
|
148
|
+
type: 'explode';
|
|
149
|
+
variant: 'standard' | 'compound' | 'penetrating';
|
|
150
|
+
threshold?: ResolvedComparePoint;
|
|
151
|
+
target: RollPart;
|
|
152
|
+
}) | (RollPartBase & {
|
|
153
|
+
type: 'reroll';
|
|
154
|
+
once: boolean;
|
|
155
|
+
condition: ResolvedComparePoint;
|
|
156
|
+
target: RollPart;
|
|
157
|
+
}) | (RollPartBase & {
|
|
158
|
+
type: 'successCount';
|
|
159
|
+
threshold: ResolvedComparePoint;
|
|
160
|
+
failThreshold?: ResolvedComparePoint;
|
|
161
|
+
target: RollPart;
|
|
162
|
+
successes: number;
|
|
163
|
+
failures: number;
|
|
164
|
+
}) | (RollPartBase & {
|
|
165
|
+
type: 'versus';
|
|
166
|
+
roll: RollPart;
|
|
167
|
+
dc: RollPart;
|
|
168
|
+
degree: DegreeOfSuccess;
|
|
169
|
+
}) | (RollPartBase & {
|
|
170
|
+
type: 'functionCall';
|
|
171
|
+
name: string;
|
|
172
|
+
args: RollPart[];
|
|
173
|
+
}) | (RollPartBase & {
|
|
174
|
+
type: 'group';
|
|
175
|
+
parts: RollPart[];
|
|
176
|
+
keptIndices?: number[];
|
|
177
|
+
}) | (RollPartBase & {
|
|
178
|
+
type: 'sort';
|
|
179
|
+
order: 'ascending' | 'descending';
|
|
180
|
+
target: RollPart;
|
|
181
|
+
}) | (RollPartBase & {
|
|
182
|
+
type: 'critThreshold';
|
|
183
|
+
successThresholds: ResolvedCritThreshold[];
|
|
184
|
+
failThresholds: ResolvedCritThreshold[];
|
|
185
|
+
target: RollPart;
|
|
186
|
+
});
|
|
187
|
+
/** Convenience alias for consumers writing exhaustive switches. */
|
|
188
|
+
export type RollPartType = RollPart['type'];
|
|
189
|
+
/**
|
|
190
|
+
* Complete roll result with all metadata.
|
|
191
|
+
*/
|
|
192
|
+
export type RollResult = {
|
|
193
|
+
/** Final computed total */
|
|
194
|
+
total: number;
|
|
195
|
+
/** Original input notation */
|
|
196
|
+
notation: string;
|
|
197
|
+
/** Normalized expression */
|
|
198
|
+
expression: string;
|
|
199
|
+
/** Rendered result with individual rolls shown */
|
|
200
|
+
rendered: string;
|
|
201
|
+
/** All individual die results */
|
|
202
|
+
rolls: DieResult[];
|
|
203
|
+
/** Structured breakdown of the evaluated expression, mirroring the AST 1:1. */
|
|
204
|
+
parts: RollPart;
|
|
205
|
+
/**
|
|
206
|
+
* Number of dice tagged as success across the whole expression. Present
|
|
207
|
+
* only when a success-counting modifier was used. Independent of `total` —
|
|
208
|
+
* arithmetic on top of a success count (e.g. `5d6>=5 * 2`) affects `total`
|
|
209
|
+
* but not `successes`.
|
|
210
|
+
*/
|
|
211
|
+
successes?: number;
|
|
212
|
+
/**
|
|
213
|
+
* Number of dice tagged as failure across the whole expression. Present
|
|
214
|
+
* only when a success-counting modifier with a fail threshold was used.
|
|
215
|
+
*/
|
|
216
|
+
failures?: number;
|
|
217
|
+
/**
|
|
218
|
+
* PF2e Degree of Success. Present only when the expression used the `vs`
|
|
219
|
+
* operator at the top level (e.g. `1d20+10 vs 25`).
|
|
220
|
+
*/
|
|
221
|
+
degree?: DegreeOfSuccess;
|
|
222
|
+
/**
|
|
223
|
+
* Natural d20 value used for PF2e upgrade/downgrade — present only when
|
|
224
|
+
* exactly one kept d20 was rolled on the roll side of a `vs` expression.
|
|
225
|
+
*/
|
|
226
|
+
natural?: number;
|
|
227
|
+
};
|
|
228
|
+
/**
|
|
229
|
+
* Options for the evaluate function.
|
|
230
|
+
*/
|
|
231
|
+
export type EvaluateOptions = {
|
|
232
|
+
/** Original notation string (for result metadata) */
|
|
233
|
+
notation?: string;
|
|
234
|
+
/** Maximum total dice allowed per evaluation (default: 10,000) */
|
|
235
|
+
maxDice?: number;
|
|
236
|
+
/** Maximum explosion iterations allowed per die (default: 1,000) */
|
|
237
|
+
maxExplodeIterations?: number;
|
|
238
|
+
/** Maximum reroll iterations allowed per die (default: 1,000) */
|
|
239
|
+
maxRerollIterations?: number;
|
|
240
|
+
/** Variable context for `@name` / `@{name}` references (default: empty) */
|
|
241
|
+
context?: Record<string, number>;
|
|
242
|
+
/** Behavior when a referenced variable is missing from context (default: 'throw') */
|
|
243
|
+
onMissingVariable?: 'throw' | 'zero';
|
|
244
|
+
};
|
|
245
|
+
export {};
|
|
246
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"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"}
|