@erpg/dicecore 3.1.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 (55) hide show
  1. package/dist/index.cjs +9 -0
  2. package/dist/index.d.cts +1 -0
  3. package/dist/index.d.ts +1 -0
  4. package/dist/index.js +9 -0
  5. package/dist/v3/cache.d.cts +23 -0
  6. package/dist/v3/cache.d.ts +23 -0
  7. package/dist/v3/compiler.d.cts +50 -0
  8. package/dist/v3/compiler.d.ts +50 -0
  9. package/dist/v3/engine.d.cts +7 -0
  10. package/dist/v3/engine.d.ts +7 -0
  11. package/dist/v3/errors.d.cts +37 -0
  12. package/dist/v3/errors.d.ts +37 -0
  13. package/dist/v3/executor.d.cts +11 -0
  14. package/dist/v3/executor.d.ts +11 -0
  15. package/dist/v3/freeze.d.cts +5 -0
  16. package/dist/v3/freeze.d.ts +5 -0
  17. package/dist/v3/index.d.cts +8 -0
  18. package/dist/v3/index.d.ts +8 -0
  19. package/dist/v3/math.d.cts +12 -0
  20. package/dist/v3/math.d.ts +12 -0
  21. package/dist/v3/normalization.d.cts +10 -0
  22. package/dist/v3/normalization.d.ts +10 -0
  23. package/dist/v3/roll-count-expression.d.cts +2 -0
  24. package/dist/v3/roll-count-expression.d.ts +2 -0
  25. package/dist/v3/runtime/budget.d.cts +57 -0
  26. package/dist/v3/runtime/budget.d.ts +57 -0
  27. package/dist/v3/runtime/context.d.cts +27 -0
  28. package/dist/v3/runtime/context.d.ts +27 -0
  29. package/dist/v3/runtime/index.d.cts +7 -0
  30. package/dist/v3/runtime/index.d.ts +7 -0
  31. package/dist/v3/runtime/journal.d.cts +23 -0
  32. package/dist/v3/runtime/journal.d.ts +23 -0
  33. package/dist/v3/runtime/limits.d.cts +25 -0
  34. package/dist/v3/runtime/limits.d.ts +25 -0
  35. package/dist/v3/runtime/mt19937.d.cts +23 -0
  36. package/dist/v3/runtime/mt19937.d.ts +23 -0
  37. package/dist/v3/runtime/replay.d.cts +38 -0
  38. package/dist/v3/runtime/replay.d.ts +38 -0
  39. package/dist/v3/runtime/xoshiro128ss.d.cts +14 -0
  40. package/dist/v3/runtime/xoshiro128ss.d.ts +14 -0
  41. package/dist/v3/syntax/ast.d.cts +132 -0
  42. package/dist/v3/syntax/ast.d.ts +132 -0
  43. package/dist/v3/syntax/index.d.cts +4 -0
  44. package/dist/v3/syntax/index.d.ts +4 -0
  45. package/dist/v3/syntax/parser.d.cts +7 -0
  46. package/dist/v3/syntax/parser.d.ts +7 -0
  47. package/dist/v3/syntax/scanner.d.cts +3 -0
  48. package/dist/v3/syntax/scanner.d.ts +3 -0
  49. package/dist/v3/syntax/tokens.d.cts +38 -0
  50. package/dist/v3/syntax/tokens.d.ts +38 -0
  51. package/dist/v3/types.d.cts +251 -0
  52. package/dist/v3/types.d.ts +251 -0
  53. package/licence.txt +23 -0
  54. package/package.json +105 -0
  55. package/readme.md +255 -0
@@ -0,0 +1,37 @@
1
+ export interface SourceSpan {
2
+ readonly start: number;
3
+ readonly end: number;
4
+ }
5
+ export type JsonPrimitive = boolean | number | string | null;
6
+ export type JsonValue = JsonPrimitive | JsonObject | readonly JsonValue[];
7
+ export interface JsonObject {
8
+ readonly [key: string]: JsonValue;
9
+ }
10
+ export type DiceRollErrorCode = 'DICE_NOTATION_REQUIRED' | 'INPUT_TOO_LONG' | 'AST_TOO_DEEP' | 'TOO_MANY_NODES' | 'TOO_MANY_ROLLS' | 'TOO_MANY_INITIAL_DICE' | 'GENERATED_DICE_LIMIT_EXCEEDED' | 'RANDOM_BUDGET_EXCEEDED' | 'EVENT_LIMIT_EXCEEDED' | 'MODIFIER_STEP_LIMIT_EXCEEDED' | 'RESOLVED_GROUP_LIMIT_EXCEEDED' | 'RESULT_LIMIT_EXCEEDED' | 'OUTPUT_LIMIT_EXCEEDED' | 'DICE_SIDES_LIMIT_EXCEEDED' | 'INVALID_NOTATION' | 'UNSUPPORTED_NOTATION' | 'UNSUPPORTED_GROUP_MODIFIER' | 'NON_TERMINATING_MODIFIER' | 'IMPOSSIBLE_UNIQUE' | 'ROLL_EXECUTION_LIMIT' | 'RNG_UNAVAILABLE' | 'INVALID_SEED' | 'INVALID_REPLAY' | 'REPLAY_PLAN_MISMATCH' | 'INVALID_LIMIT' | 'UNSUPPORTED_REPLAY_VERSION' | 'NON_FINITE_RESULT' | 'INVALID_ERROR_DATA';
11
+ export interface DiceErrorData {
12
+ readonly name: 'DiceRollError';
13
+ readonly code: DiceRollErrorCode;
14
+ readonly message: string;
15
+ readonly span: SourceSpan | null;
16
+ readonly input: string;
17
+ readonly details: JsonObject;
18
+ }
19
+ export interface DiceRollErrorOptions {
20
+ readonly code: DiceRollErrorCode;
21
+ readonly span?: SourceSpan | null;
22
+ readonly input?: string;
23
+ readonly details?: JsonObject;
24
+ }
25
+ /** A stable, JSON-safe error raised by the V3 compiler or executor. */
26
+ export declare class DiceRollError extends Error {
27
+ readonly code: DiceRollErrorCode;
28
+ readonly span: SourceSpan | null;
29
+ readonly input: string;
30
+ readonly details: JsonObject;
31
+ constructor(message: string, options: DiceRollErrorOptions);
32
+ static fromJSON(data: unknown): DiceRollError;
33
+ toJSON(): DiceErrorData;
34
+ }
35
+ export declare function isDiceRollError(error: unknown): error is DiceRollError;
36
+ /** Recognizes JSON-safe dice errors across workers, realms and process boundaries. */
37
+ export declare function isDiceRollErrorData(value: unknown): value is DiceErrorData;
@@ -0,0 +1,37 @@
1
+ export interface SourceSpan {
2
+ readonly start: number;
3
+ readonly end: number;
4
+ }
5
+ export type JsonPrimitive = boolean | number | string | null;
6
+ export type JsonValue = JsonPrimitive | JsonObject | readonly JsonValue[];
7
+ export interface JsonObject {
8
+ readonly [key: string]: JsonValue;
9
+ }
10
+ export type DiceRollErrorCode = 'DICE_NOTATION_REQUIRED' | 'INPUT_TOO_LONG' | 'AST_TOO_DEEP' | 'TOO_MANY_NODES' | 'TOO_MANY_ROLLS' | 'TOO_MANY_INITIAL_DICE' | 'GENERATED_DICE_LIMIT_EXCEEDED' | 'RANDOM_BUDGET_EXCEEDED' | 'EVENT_LIMIT_EXCEEDED' | 'MODIFIER_STEP_LIMIT_EXCEEDED' | 'RESOLVED_GROUP_LIMIT_EXCEEDED' | 'RESULT_LIMIT_EXCEEDED' | 'OUTPUT_LIMIT_EXCEEDED' | 'DICE_SIDES_LIMIT_EXCEEDED' | 'INVALID_NOTATION' | 'UNSUPPORTED_NOTATION' | 'UNSUPPORTED_GROUP_MODIFIER' | 'NON_TERMINATING_MODIFIER' | 'IMPOSSIBLE_UNIQUE' | 'ROLL_EXECUTION_LIMIT' | 'RNG_UNAVAILABLE' | 'INVALID_SEED' | 'INVALID_REPLAY' | 'REPLAY_PLAN_MISMATCH' | 'INVALID_LIMIT' | 'UNSUPPORTED_REPLAY_VERSION' | 'NON_FINITE_RESULT' | 'INVALID_ERROR_DATA';
11
+ export interface DiceErrorData {
12
+ readonly name: 'DiceRollError';
13
+ readonly code: DiceRollErrorCode;
14
+ readonly message: string;
15
+ readonly span: SourceSpan | null;
16
+ readonly input: string;
17
+ readonly details: JsonObject;
18
+ }
19
+ export interface DiceRollErrorOptions {
20
+ readonly code: DiceRollErrorCode;
21
+ readonly span?: SourceSpan | null;
22
+ readonly input?: string;
23
+ readonly details?: JsonObject;
24
+ }
25
+ /** A stable, JSON-safe error raised by the V3 compiler or executor. */
26
+ export declare class DiceRollError extends Error {
27
+ readonly code: DiceRollErrorCode;
28
+ readonly span: SourceSpan | null;
29
+ readonly input: string;
30
+ readonly details: JsonObject;
31
+ constructor(message: string, options: DiceRollErrorOptions);
32
+ static fromJSON(data: unknown): DiceRollError;
33
+ toJSON(): DiceErrorData;
34
+ }
35
+ export declare function isDiceRollError(error: unknown): error is DiceRollError;
36
+ /** Recognizes JSON-safe dice errors across workers, realms and process boundaries. */
37
+ export declare function isDiceRollErrorData(value: unknown): value is DiceErrorData;
@@ -0,0 +1,11 @@
1
+ import type { DiceLimits } from './runtime/limits.cjs';
2
+ import type { RandomAlgorithm, ReplayDescriptor, SeedInput } from './runtime/replay.cjs';
3
+ import type { DiceRollResult, DiceRollSummary, RollPlan } from './types.cjs';
4
+ export interface ExecuteRollPlanOptions {
5
+ readonly limits: DiceLimits;
6
+ readonly seed?: SeedInput;
7
+ readonly replay?: ReplayDescriptor;
8
+ readonly randomAlgorithm?: RandomAlgorithm;
9
+ }
10
+ export declare function executeRollPlan(plan: RollPlan, options: ExecuteRollPlanOptions): DiceRollResult;
11
+ export declare function executeRollPlanSummary(plan: RollPlan, options: ExecuteRollPlanOptions): DiceRollSummary;
@@ -0,0 +1,11 @@
1
+ import type { DiceLimits } from './runtime/limits.js';
2
+ import type { RandomAlgorithm, ReplayDescriptor, SeedInput } from './runtime/replay.js';
3
+ import type { DiceRollResult, DiceRollSummary, RollPlan } from './types.js';
4
+ export interface ExecuteRollPlanOptions {
5
+ readonly limits: DiceLimits;
6
+ readonly seed?: SeedInput;
7
+ readonly replay?: ReplayDescriptor;
8
+ readonly randomAlgorithm?: RandomAlgorithm;
9
+ }
10
+ export declare function executeRollPlan(plan: RollPlan, options: ExecuteRollPlanOptions): DiceRollResult;
11
+ export declare function executeRollPlanSummary(plan: RollPlan, options: ExecuteRollPlanOptions): DiceRollSummary;
@@ -0,0 +1,5 @@
1
+ import type { DiceRollResult, DiceRollSummary, RollPlan } from './types.cjs';
2
+ export declare function freezeRollPlan(plan: RollPlan): RollPlan;
3
+ export declare function freezeDiceRollResult(result: DiceRollResult): DiceRollResult;
4
+ export declare function freezeDiceRollSummary(result: DiceRollSummary): DiceRollSummary;
5
+ export declare function shouldFreezeResults(mode: 'development' | 'always' | 'never'): boolean;
@@ -0,0 +1,5 @@
1
+ import type { DiceRollResult, DiceRollSummary, RollPlan } from './types.js';
2
+ export declare function freezeRollPlan(plan: RollPlan): RollPlan;
3
+ export declare function freezeDiceRollResult(result: DiceRollResult): DiceRollResult;
4
+ export declare function freezeDiceRollSummary(result: DiceRollSummary): DiceRollSummary;
5
+ export declare function shouldFreezeResults(mode: 'development' | 'always' | 'never'): boolean;
@@ -0,0 +1,8 @@
1
+ export { compileRpgDice, createDiceEngine, inspectRpgDiceNotation, rollRpgDice, rollRpgDiceSummary, verifyRpgDiceNotation, } from './engine.cjs';
2
+ export { DiceRollError, isDiceRollError, isDiceRollErrorData, } from './errors.cjs';
3
+ export { normalizeRpgDiceNotation } from './normalization.cjs';
4
+ export { DEFAULT_DICE_LIMITS } from './runtime/limits.cjs';
5
+ export type { DiceErrorData, DiceRollErrorCode, JsonObject, JsonPrimitive, JsonValue, SourceSpan, } from './errors.cjs';
6
+ export type { DiceLimits } from './runtime/limits.cjs';
7
+ export type { RandomAlgorithm, ReplayDescriptor, SeedInput, SeedOrigin, } from './runtime/replay.cjs';
8
+ export type { ClassifyDiceEvent, CompileOptions, DiceCacheOptions, DiceCacheStats, DiceEngine, DiceEngineOptions, DiceEvent, DiceInspectionCost, DiceNotationInspection, DiceRollResult, DiceRollSummary, DiceSides, DiceState, EntityRange, ExcludeDiceEvent, ExcludeGroupEvent, ExplodeDiceEvent, FreezeResultsMode, GroupState, IncludeDiceEvent, IncludeGroupEvent, ExecutionStats, PoolSummary, RerollDiceEvent, ResolvedDie, ResolvedGroup, ResolvedRoll, ResolvedRollSummary, RollDiceEvent, RollOptions, RollPlan, RollPlanGroup, TransformDiceEvent, TransformGroupEvent, } from './types.cjs';
@@ -0,0 +1,8 @@
1
+ export { compileRpgDice, createDiceEngine, inspectRpgDiceNotation, rollRpgDice, rollRpgDiceSummary, verifyRpgDiceNotation, } from './engine.js';
2
+ export { DiceRollError, isDiceRollError, isDiceRollErrorData, } from './errors.js';
3
+ export { normalizeRpgDiceNotation } from './normalization.js';
4
+ export { DEFAULT_DICE_LIMITS } from './runtime/limits.js';
5
+ export type { DiceErrorData, DiceRollErrorCode, JsonObject, JsonPrimitive, JsonValue, SourceSpan, } from './errors.js';
6
+ export type { DiceLimits } from './runtime/limits.js';
7
+ export type { RandomAlgorithm, ReplayDescriptor, SeedInput, SeedOrigin, } from './runtime/replay.js';
8
+ export type { ClassifyDiceEvent, CompileOptions, DiceCacheOptions, DiceCacheStats, DiceEngine, DiceEngineOptions, DiceEvent, DiceInspectionCost, DiceNotationInspection, DiceRollResult, DiceRollSummary, DiceSides, DiceState, EntityRange, ExcludeDiceEvent, ExcludeGroupEvent, ExplodeDiceEvent, FreezeResultsMode, GroupState, IncludeDiceEvent, IncludeGroupEvent, ExecutionStats, PoolSummary, RerollDiceEvent, ResolvedDie, ResolvedGroup, ResolvedRoll, ResolvedRollSummary, RollDiceEvent, RollOptions, RollPlan, RollPlanGroup, TransformDiceEvent, TransformGroupEvent, } from './types.js';
@@ -0,0 +1,12 @@
1
+ export type BinaryOperator = '+' | '-' | '*' | '/' | '%' | '^';
2
+ export type UnaryMathFunction = 'abs' | 'ceil' | 'cos' | 'exp' | 'floor' | 'log' | 'round' | 'sign' | 'sin' | 'sqrt' | 'tan';
3
+ export type BinaryMathFunction = 'max' | 'min' | 'pow';
4
+ export type MathProfile = 'decimal12-v1';
5
+ export declare const MATH_PROFILE: MathProfile;
6
+ /** Applies the V3 cross-runtime numeric profile after every math operation. */
7
+ export declare function normalizeMathValue(value: number, input: string): number;
8
+ export declare function evaluateBinary(operator: BinaryOperator, left: number, right: number, input: string): number;
9
+ export declare function evaluateUnaryFunction(name: UnaryMathFunction, value: number, input: string): number;
10
+ export declare function evaluateBinaryFunction(name: BinaryMathFunction, left: number, right: number, input: string): number;
11
+ export declare function compareValues(operator: '=' | '!=' | '<>' | '<' | '>' | '<=' | '>=', left: number, right: number): boolean;
12
+ export declare function roundResult(value: number): number;
@@ -0,0 +1,12 @@
1
+ export type BinaryOperator = '+' | '-' | '*' | '/' | '%' | '^';
2
+ export type UnaryMathFunction = 'abs' | 'ceil' | 'cos' | 'exp' | 'floor' | 'log' | 'round' | 'sign' | 'sin' | 'sqrt' | 'tan';
3
+ export type BinaryMathFunction = 'max' | 'min' | 'pow';
4
+ export type MathProfile = 'decimal12-v1';
5
+ export declare const MATH_PROFILE: MathProfile;
6
+ /** Applies the V3 cross-runtime numeric profile after every math operation. */
7
+ export declare function normalizeMathValue(value: number, input: string): number;
8
+ export declare function evaluateBinary(operator: BinaryOperator, left: number, right: number, input: string): number;
9
+ export declare function evaluateUnaryFunction(name: UnaryMathFunction, value: number, input: string): number;
10
+ export declare function evaluateBinaryFunction(name: BinaryMathFunction, left: number, right: number, input: string): number;
11
+ export declare function compareValues(operator: '=' | '!=' | '<>' | '<' | '>' | '<=' | '>=', left: number, right: number): boolean;
12
+ export declare function roundResult(value: number): number;
@@ -0,0 +1,10 @@
1
+ export interface NormalizedDiceInput {
2
+ readonly input: string;
3
+ readonly comment: string;
4
+ readonly notation: string;
5
+ readonly normalizedNotation: string;
6
+ readonly rollCount: number;
7
+ readonly isMultiRoll: boolean;
8
+ }
9
+ export declare function normalizeRpgDiceNotation(input: string): string;
10
+ export declare function parseNormalizedDiceInput(input: string): NormalizedDiceInput;
@@ -0,0 +1,10 @@
1
+ export interface NormalizedDiceInput {
2
+ readonly input: string;
3
+ readonly comment: string;
4
+ readonly notation: string;
5
+ readonly normalizedNotation: string;
6
+ readonly rollCount: number;
7
+ readonly isMultiRoll: boolean;
8
+ }
9
+ export declare function normalizeRpgDiceNotation(input: string): string;
10
+ export declare function parseNormalizedDiceInput(input: string): NormalizedDiceInput;
@@ -0,0 +1,2 @@
1
+ /** Resolves a deterministic expression used before the multi-roll `#` marker. */
2
+ export declare function resolveRollCountExpression(expression: string): number | null;
@@ -0,0 +1,2 @@
1
+ /** Resolves a deterministic expression used before the multi-roll `#` marker. */
2
+ export declare function resolveRollCountExpression(expression: string): number | null;
@@ -0,0 +1,57 @@
1
+ import type { DiceLimits } from './limits.cjs';
2
+ export interface ExecutionBudgetSnapshot {
3
+ readonly astNodes: number;
4
+ readonly rolls: number;
5
+ readonly initialDice: number;
6
+ readonly generatedDice: number;
7
+ readonly randomCalls: number;
8
+ readonly modifierSteps: number;
9
+ readonly events: number;
10
+ readonly resolvedGroups: number;
11
+ readonly resultItems: number;
12
+ }
13
+ export interface ExecutionStats {
14
+ readonly rolls: number;
15
+ readonly initialDice: number;
16
+ readonly generatedDice: number;
17
+ readonly randomCalls: number;
18
+ readonly modifierSteps: number;
19
+ readonly events: number;
20
+ readonly resolvedGroups: number;
21
+ readonly resultItems: number;
22
+ }
23
+ export interface RandomCallBudget {
24
+ consumeRandomCalls(count?: number): void;
25
+ }
26
+ export interface EventBudget {
27
+ consumeEvents(count?: number): void;
28
+ consumeResultItems(count?: number): void;
29
+ }
30
+ export declare class ExecutionBudget implements RandomCallBudget, EventBudget {
31
+ readonly limits: DiceLimits;
32
+ private astNodes;
33
+ private rolls;
34
+ private initialDice;
35
+ private generatedDice;
36
+ private randomCalls;
37
+ private modifierSteps;
38
+ private events;
39
+ private resolvedGroups;
40
+ private resultItems;
41
+ constructor(limits: DiceLimits);
42
+ assertInputLength(input: string): void;
43
+ consumeAstNode(depth: number): void;
44
+ consumeRolls(count?: number): void;
45
+ consumeInitialDice(count?: number): void;
46
+ consumeGeneratedDice(count?: number): void;
47
+ consumeRandomCalls(count?: number): void;
48
+ consumeEvents(count?: number): void;
49
+ consumeModifierSteps(count?: number): void;
50
+ consumeResolvedGroups(count?: number): void;
51
+ consumeResultItems(count?: number): void;
52
+ assertOutputLength(length: number): void;
53
+ snapshot(): ExecutionBudgetSnapshot;
54
+ stats(): ExecutionStats;
55
+ private consume;
56
+ private throwLimit;
57
+ }
@@ -0,0 +1,57 @@
1
+ import type { DiceLimits } from './limits.js';
2
+ export interface ExecutionBudgetSnapshot {
3
+ readonly astNodes: number;
4
+ readonly rolls: number;
5
+ readonly initialDice: number;
6
+ readonly generatedDice: number;
7
+ readonly randomCalls: number;
8
+ readonly modifierSteps: number;
9
+ readonly events: number;
10
+ readonly resolvedGroups: number;
11
+ readonly resultItems: number;
12
+ }
13
+ export interface ExecutionStats {
14
+ readonly rolls: number;
15
+ readonly initialDice: number;
16
+ readonly generatedDice: number;
17
+ readonly randomCalls: number;
18
+ readonly modifierSteps: number;
19
+ readonly events: number;
20
+ readonly resolvedGroups: number;
21
+ readonly resultItems: number;
22
+ }
23
+ export interface RandomCallBudget {
24
+ consumeRandomCalls(count?: number): void;
25
+ }
26
+ export interface EventBudget {
27
+ consumeEvents(count?: number): void;
28
+ consumeResultItems(count?: number): void;
29
+ }
30
+ export declare class ExecutionBudget implements RandomCallBudget, EventBudget {
31
+ readonly limits: DiceLimits;
32
+ private astNodes;
33
+ private rolls;
34
+ private initialDice;
35
+ private generatedDice;
36
+ private randomCalls;
37
+ private modifierSteps;
38
+ private events;
39
+ private resolvedGroups;
40
+ private resultItems;
41
+ constructor(limits: DiceLimits);
42
+ assertInputLength(input: string): void;
43
+ consumeAstNode(depth: number): void;
44
+ consumeRolls(count?: number): void;
45
+ consumeInitialDice(count?: number): void;
46
+ consumeGeneratedDice(count?: number): void;
47
+ consumeRandomCalls(count?: number): void;
48
+ consumeEvents(count?: number): void;
49
+ consumeModifierSteps(count?: number): void;
50
+ consumeResolvedGroups(count?: number): void;
51
+ consumeResultItems(count?: number): void;
52
+ assertOutputLength(length: number): void;
53
+ snapshot(): ExecutionBudgetSnapshot;
54
+ stats(): ExecutionStats;
55
+ private consume;
56
+ private throwLimit;
57
+ }
@@ -0,0 +1,27 @@
1
+ import type { DiceEventSink } from './journal.cjs';
2
+ import { ExecutionBudget } from './budget.cjs';
3
+ import { type DiceLimitOverrides, type DiceLimits } from './limits.cjs';
4
+ import { type RandomSource } from './mt19937.cjs';
5
+ import { type CryptoSource, type RandomAlgorithm, type ReplayDescriptor, type SeedInput } from './replay.cjs';
6
+ export interface ExecutionContextOptions {
7
+ readonly limits?: DiceLimits | DiceLimitOverrides;
8
+ /** Already resolved immutable limits used by the engine hot path. */
9
+ readonly resolvedLimits?: DiceLimits;
10
+ readonly seed?: SeedInput;
11
+ readonly replay?: ReplayDescriptor;
12
+ readonly randomAlgorithm?: RandomAlgorithm;
13
+ readonly planFingerprint?: string;
14
+ readonly collectEvents?: boolean;
15
+ /** Intended for platform adapters and deterministic tests. */
16
+ readonly cryptoSource?: CryptoSource | null;
17
+ }
18
+ /** All mutable state for exactly one compilation/execution. */
19
+ export declare class ExecutionContext {
20
+ readonly limits: DiceLimits;
21
+ readonly budget: ExecutionBudget;
22
+ readonly random: RandomSource;
23
+ readonly journal: DiceEventSink;
24
+ readonly replay: ReplayDescriptor;
25
+ constructor(options?: ExecutionContextOptions);
26
+ }
27
+ export declare function createExecutionContext(options?: ExecutionContextOptions): ExecutionContext;
@@ -0,0 +1,27 @@
1
+ import type { DiceEventSink } from './journal.js';
2
+ import { ExecutionBudget } from './budget.js';
3
+ import { type DiceLimitOverrides, type DiceLimits } from './limits.js';
4
+ import { type RandomSource } from './mt19937.js';
5
+ import { type CryptoSource, type RandomAlgorithm, type ReplayDescriptor, type SeedInput } from './replay.js';
6
+ export interface ExecutionContextOptions {
7
+ readonly limits?: DiceLimits | DiceLimitOverrides;
8
+ /** Already resolved immutable limits used by the engine hot path. */
9
+ readonly resolvedLimits?: DiceLimits;
10
+ readonly seed?: SeedInput;
11
+ readonly replay?: ReplayDescriptor;
12
+ readonly randomAlgorithm?: RandomAlgorithm;
13
+ readonly planFingerprint?: string;
14
+ readonly collectEvents?: boolean;
15
+ /** Intended for platform adapters and deterministic tests. */
16
+ readonly cryptoSource?: CryptoSource | null;
17
+ }
18
+ /** All mutable state for exactly one compilation/execution. */
19
+ export declare class ExecutionContext {
20
+ readonly limits: DiceLimits;
21
+ readonly budget: ExecutionBudget;
22
+ readonly random: RandomSource;
23
+ readonly journal: DiceEventSink;
24
+ readonly replay: ReplayDescriptor;
25
+ constructor(options?: ExecutionContextOptions);
26
+ }
27
+ export declare function createExecutionContext(options?: ExecutionContextOptions): ExecutionContext;
@@ -0,0 +1,7 @@
1
+ export * from './budget.cjs';
2
+ export * from './context.cjs';
3
+ export * from './journal.cjs';
4
+ export * from './limits.cjs';
5
+ export * from './mt19937.cjs';
6
+ export * from './replay.cjs';
7
+ export * from './xoshiro128ss.cjs';
@@ -0,0 +1,7 @@
1
+ export * from './budget.js';
2
+ export * from './context.js';
3
+ export * from './journal.js';
4
+ export * from './limits.js';
5
+ export * from './mt19937.js';
6
+ export * from './replay.js';
7
+ export * from './xoshiro128ss.js';
@@ -0,0 +1,23 @@
1
+ import type { ClassifyDiceEvent, DiceEvent, ExcludeDiceEvent, ExcludeGroupEvent, ExplodeDiceEvent, IncludeDiceEvent, IncludeGroupEvent, RerollDiceEvent, RollDiceEvent, TransformDiceEvent, TransformGroupEvent } from '../types.cjs';
2
+ import type { EventBudget } from './budget.cjs';
3
+ type WithoutSequence<T extends DiceEvent> = Omit<T, 'sequence'>;
4
+ export type DiceEventInput = WithoutSequence<RollDiceEvent> | WithoutSequence<RerollDiceEvent> | WithoutSequence<ExplodeDiceEvent> | WithoutSequence<TransformDiceEvent> | WithoutSequence<TransformGroupEvent> | WithoutSequence<IncludeDiceEvent> | WithoutSequence<IncludeGroupEvent> | WithoutSequence<ExcludeDiceEvent> | WithoutSequence<ExcludeGroupEvent> | WithoutSequence<ClassifyDiceEvent>;
5
+ export interface DiceEventSink {
6
+ readonly length: number;
7
+ record(event: DiceEventInput): DiceEvent | null;
8
+ slice(start: number, end?: number): readonly DiceEvent[];
9
+ toArray(): readonly DiceEvent[];
10
+ }
11
+ /** Counts every logical event and optionally materializes the public journal. */
12
+ export declare class ExecutionJournal implements DiceEventSink {
13
+ private readonly journal;
14
+ private readonly budget;
15
+ private readonly materialize;
16
+ private eventCount;
17
+ constructor(budget?: EventBudget | null, materialize?: boolean);
18
+ get length(): number;
19
+ record(input: DiceEventInput): DiceEvent | null;
20
+ slice(start: number, end?: number): readonly DiceEvent[];
21
+ toArray(): readonly DiceEvent[];
22
+ }
23
+ export {};
@@ -0,0 +1,23 @@
1
+ import type { ClassifyDiceEvent, DiceEvent, ExcludeDiceEvent, ExcludeGroupEvent, ExplodeDiceEvent, IncludeDiceEvent, IncludeGroupEvent, RerollDiceEvent, RollDiceEvent, TransformDiceEvent, TransformGroupEvent } from '../types.js';
2
+ import type { EventBudget } from './budget.js';
3
+ type WithoutSequence<T extends DiceEvent> = Omit<T, 'sequence'>;
4
+ export type DiceEventInput = WithoutSequence<RollDiceEvent> | WithoutSequence<RerollDiceEvent> | WithoutSequence<ExplodeDiceEvent> | WithoutSequence<TransformDiceEvent> | WithoutSequence<TransformGroupEvent> | WithoutSequence<IncludeDiceEvent> | WithoutSequence<IncludeGroupEvent> | WithoutSequence<ExcludeDiceEvent> | WithoutSequence<ExcludeGroupEvent> | WithoutSequence<ClassifyDiceEvent>;
5
+ export interface DiceEventSink {
6
+ readonly length: number;
7
+ record(event: DiceEventInput): DiceEvent | null;
8
+ slice(start: number, end?: number): readonly DiceEvent[];
9
+ toArray(): readonly DiceEvent[];
10
+ }
11
+ /** Counts every logical event and optionally materializes the public journal. */
12
+ export declare class ExecutionJournal implements DiceEventSink {
13
+ private readonly journal;
14
+ private readonly budget;
15
+ private readonly materialize;
16
+ private eventCount;
17
+ constructor(budget?: EventBudget | null, materialize?: boolean);
18
+ get length(): number;
19
+ record(input: DiceEventInput): DiceEvent | null;
20
+ slice(start: number, end?: number): readonly DiceEvent[];
21
+ toArray(): readonly DiceEvent[];
22
+ }
23
+ export {};
@@ -0,0 +1,25 @@
1
+ export interface DiceLimits {
2
+ readonly maxInputLength: number;
3
+ readonly maxAstDepth: number;
4
+ readonly maxAstNodes: number;
5
+ readonly maxRolls: number;
6
+ readonly maxInitialDice: number;
7
+ readonly maxGeneratedDice: number;
8
+ readonly maxRandomCalls: number;
9
+ readonly maxEvents: number;
10
+ readonly maxSides: number;
11
+ readonly maxSeedLength: number;
12
+ readonly maxModifierSteps: number;
13
+ readonly maxResolvedGroups: number;
14
+ readonly maxResultItems: number;
15
+ readonly maxOutputLength: number;
16
+ }
17
+ export type DiceLimitOverrides = Partial<DiceLimits>;
18
+ export declare const DEFAULT_DICE_LIMITS: DiceLimits;
19
+ /** Creates the immutable caps owned by a DiceEngine instance. */
20
+ export declare function createDiceLimits(overrides?: unknown): DiceLimits;
21
+ /**
22
+ * Resolves per-call limits against immutable engine caps.
23
+ * A call may lower a cap, but attempting to raise one is a configuration error.
24
+ */
25
+ export declare function resolveDiceLimits(engineLimits: DiceLimits, callOverrides?: unknown): DiceLimits;
@@ -0,0 +1,25 @@
1
+ export interface DiceLimits {
2
+ readonly maxInputLength: number;
3
+ readonly maxAstDepth: number;
4
+ readonly maxAstNodes: number;
5
+ readonly maxRolls: number;
6
+ readonly maxInitialDice: number;
7
+ readonly maxGeneratedDice: number;
8
+ readonly maxRandomCalls: number;
9
+ readonly maxEvents: number;
10
+ readonly maxSides: number;
11
+ readonly maxSeedLength: number;
12
+ readonly maxModifierSteps: number;
13
+ readonly maxResolvedGroups: number;
14
+ readonly maxResultItems: number;
15
+ readonly maxOutputLength: number;
16
+ }
17
+ export type DiceLimitOverrides = Partial<DiceLimits>;
18
+ export declare const DEFAULT_DICE_LIMITS: DiceLimits;
19
+ /** Creates the immutable caps owned by a DiceEngine instance. */
20
+ export declare function createDiceLimits(overrides?: unknown): DiceLimits;
21
+ /**
22
+ * Resolves per-call limits against immutable engine caps.
23
+ * A call may lower a cap, but attempting to raise one is a configuration error.
24
+ */
25
+ export declare function resolveDiceLimits(engineLimits: DiceLimits, callOverrides?: unknown): DiceLimits;
@@ -0,0 +1,23 @@
1
+ import type { RandomCallBudget } from './budget.cjs';
2
+ export interface RandomSource {
3
+ nextUint32(): number;
4
+ integer(min: number, max: number): number;
5
+ real(): number;
6
+ }
7
+ /** A dependency-free implementation of the original 32-bit MT19937 algorithm. */
8
+ export declare class MersenneTwister19937 implements RandomSource {
9
+ private readonly state;
10
+ private index;
11
+ private readonly budget;
12
+ constructor(seed: number | ArrayLike<number>, budget?: RandomCallBudget | null);
13
+ nextUint32(): number;
14
+ integer(min: number, max: number): number;
15
+ real(): number;
16
+ private readState;
17
+ private writeState;
18
+ private initializeSeed;
19
+ private initializeSeedArray;
20
+ private restoreCachedSeedArray;
21
+ private cacheSeedArray;
22
+ private twist;
23
+ }
@@ -0,0 +1,23 @@
1
+ import type { RandomCallBudget } from './budget.js';
2
+ export interface RandomSource {
3
+ nextUint32(): number;
4
+ integer(min: number, max: number): number;
5
+ real(): number;
6
+ }
7
+ /** A dependency-free implementation of the original 32-bit MT19937 algorithm. */
8
+ export declare class MersenneTwister19937 implements RandomSource {
9
+ private readonly state;
10
+ private index;
11
+ private readonly budget;
12
+ constructor(seed: number | ArrayLike<number>, budget?: RandomCallBudget | null);
13
+ nextUint32(): number;
14
+ integer(min: number, max: number): number;
15
+ real(): number;
16
+ private readState;
17
+ private writeState;
18
+ private initializeSeed;
19
+ private initializeSeedArray;
20
+ private restoreCachedSeedArray;
21
+ private cacheSeedArray;
22
+ private twist;
23
+ }
@@ -0,0 +1,38 @@
1
+ import { type MathProfile } from '../math.cjs';
2
+ export type SeedInput = number | string;
3
+ export type SeedOrigin = 'provided-number' | 'provided-string' | 'crypto';
4
+ export type RandomAlgorithm = 'mt19937' | 'xoshiro128ss';
5
+ export interface ReplayDescriptor {
6
+ readonly schemaVersion: 2;
7
+ readonly algorithm: RandomAlgorithm;
8
+ readonly algorithmVersion: 1;
9
+ readonly executionVersion: 1;
10
+ readonly mathProfile: MathProfile;
11
+ readonly origin: SeedOrigin;
12
+ readonly seedMaterial: string;
13
+ readonly planFingerprint: string;
14
+ }
15
+ export interface SeedMaterial {
16
+ /** Internal namespaced representation. Never included in ReplayDescriptor. */
17
+ readonly canonicalSeed: string;
18
+ readonly seedMaterial: string;
19
+ readonly origin: SeedOrigin;
20
+ readonly words: readonly number[];
21
+ }
22
+ export interface CryptoSource {
23
+ getRandomValues(array: Uint32Array): Uint32Array;
24
+ }
25
+ export interface ReplayDescriptorOptions {
26
+ readonly algorithm?: RandomAlgorithm;
27
+ readonly planFingerprint?: string;
28
+ }
29
+ export declare function isReplayDescriptor(value: unknown): value is ReplayDescriptor;
30
+ /** Validates all replay fields and optionally binds it to an expected plan. */
31
+ export declare function validateReplayDescriptor(value: unknown, expectedPlanFingerprint?: string): ReplayDescriptor;
32
+ export declare function canonicalizeSeed(seed: SeedInput, maxSeedLength?: number): string;
33
+ export declare function createProvidedSeed(seed: SeedInput, maxSeedLength?: number): SeedMaterial;
34
+ export declare function createAutomaticSeed(cryptoSource?: CryptoSource | null): SeedMaterial;
35
+ /** Restores the fixed 128-bit seed represented by a public replay descriptor. */
36
+ export declare function createReplaySeed(descriptor: unknown, expectedPlanFingerprint?: string): SeedMaterial;
37
+ export declare function createSeedMaterial(seed: SeedInput | undefined, cryptoSource?: CryptoSource | null, maxSeedLength?: number): SeedMaterial;
38
+ export declare function createReplayDescriptor(seed: SeedMaterial, options?: ReplayDescriptorOptions): ReplayDescriptor;
@@ -0,0 +1,38 @@
1
+ import { type MathProfile } from '../math.js';
2
+ export type SeedInput = number | string;
3
+ export type SeedOrigin = 'provided-number' | 'provided-string' | 'crypto';
4
+ export type RandomAlgorithm = 'mt19937' | 'xoshiro128ss';
5
+ export interface ReplayDescriptor {
6
+ readonly schemaVersion: 2;
7
+ readonly algorithm: RandomAlgorithm;
8
+ readonly algorithmVersion: 1;
9
+ readonly executionVersion: 1;
10
+ readonly mathProfile: MathProfile;
11
+ readonly origin: SeedOrigin;
12
+ readonly seedMaterial: string;
13
+ readonly planFingerprint: string;
14
+ }
15
+ export interface SeedMaterial {
16
+ /** Internal namespaced representation. Never included in ReplayDescriptor. */
17
+ readonly canonicalSeed: string;
18
+ readonly seedMaterial: string;
19
+ readonly origin: SeedOrigin;
20
+ readonly words: readonly number[];
21
+ }
22
+ export interface CryptoSource {
23
+ getRandomValues(array: Uint32Array): Uint32Array;
24
+ }
25
+ export interface ReplayDescriptorOptions {
26
+ readonly algorithm?: RandomAlgorithm;
27
+ readonly planFingerprint?: string;
28
+ }
29
+ export declare function isReplayDescriptor(value: unknown): value is ReplayDescriptor;
30
+ /** Validates all replay fields and optionally binds it to an expected plan. */
31
+ export declare function validateReplayDescriptor(value: unknown, expectedPlanFingerprint?: string): ReplayDescriptor;
32
+ export declare function canonicalizeSeed(seed: SeedInput, maxSeedLength?: number): string;
33
+ export declare function createProvidedSeed(seed: SeedInput, maxSeedLength?: number): SeedMaterial;
34
+ export declare function createAutomaticSeed(cryptoSource?: CryptoSource | null): SeedMaterial;
35
+ /** Restores the fixed 128-bit seed represented by a public replay descriptor. */
36
+ export declare function createReplaySeed(descriptor: unknown, expectedPlanFingerprint?: string): SeedMaterial;
37
+ export declare function createSeedMaterial(seed: SeedInput | undefined, cryptoSource?: CryptoSource | null, maxSeedLength?: number): SeedMaterial;
38
+ export declare function createReplayDescriptor(seed: SeedMaterial, options?: ReplayDescriptorOptions): ReplayDescriptor;
@@ -0,0 +1,14 @@
1
+ import type { RandomCallBudget } from './budget.cjs';
2
+ import type { RandomSource } from './mt19937.cjs';
3
+ /** The public-domain xoshiro128** 1.1 generator by Blackman and Vigna. */
4
+ export declare class Xoshiro128StarStar implements RandomSource {
5
+ private state0;
6
+ private state1;
7
+ private state2;
8
+ private state3;
9
+ private readonly budget;
10
+ constructor(seed: ArrayLike<number>, budget?: RandomCallBudget | null);
11
+ nextUint32(): number;
12
+ integer(min: number, max: number): number;
13
+ real(): number;
14
+ }