@yipe/dice 0.8.0 → 0.8.1

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.
@@ -3452,6 +3452,10 @@ function d20PMF(rerollOne) {
3452
3452
  }
3453
3453
 
3454
3454
  // src/builder/roll.ts
3455
+ var rollPMFCache = new LRUCache(4e3);
3456
+ function clearRollCache() {
3457
+ rollPMFCache.clear();
3458
+ }
3455
3459
  var defaultConfig = {
3456
3460
  count: 1,
3457
3461
  sides: 0,
@@ -3864,8 +3868,16 @@ var RollBuilder = class _RollBuilder {
3864
3868
  }
3865
3869
  return result.replace(/\+ -/g, "-");
3866
3870
  }
3871
+ // Main AST entry point. Cached by the cheap config key across identical rebuilds; see `rollPMFCache`.
3867
3872
  toPMF(eps = 0) {
3868
- return pmfFromRollBuilder(this, eps);
3873
+ const key = this.cacheKey();
3874
+ if (key === null) return pmfFromRollBuilder(this, eps);
3875
+ const fullKey = `${key}*e${eps}`;
3876
+ const cached = rollPMFCache.get(fullKey);
3877
+ if (cached) return cached;
3878
+ const pmf = pmfFromRollBuilder(this, eps);
3879
+ rollPMFCache.set(fullKey, pmf);
3880
+ return pmf;
3869
3881
  }
3870
3882
  get pmf() {
3871
3883
  return this.toPMF();
@@ -5294,6 +5306,10 @@ RollBuilder.prototype.ac = function(targetAC) {
5294
5306
  };
5295
5307
 
5296
5308
  // src/builder/save.ts
5309
+ var savePMFCache = new LRUCache(4e3);
5310
+ function clearSaveCache() {
5311
+ savePMFCache.clear();
5312
+ }
5297
5313
  var SaveBuilder = class _SaveBuilder {
5298
5314
  constructor(check, failureEffect, saveOutcome = "normal") {
5299
5315
  this.check = check;
@@ -5330,9 +5346,32 @@ var SaveBuilder = class _SaveBuilder {
5330
5346
  weights: { success: psuccess, fail: pfail }
5331
5347
  };
5332
5348
  }
5333
- // By default, create PMF with no pruning
5349
+ /**
5350
+ * A cheap, complete key for this save's resolved PMF, or `null` when it can't be cached soundly.
5351
+ * {@link resolve} reads exactly three things: the DC check (via `resolveProbabilities`), the failure
5352
+ * effect's PMF, and the save outcome — so composing their keys pins it. A `ParsedRollBuilder` failure
5353
+ * effect returns `null`, which correctly forces this uncached.
5354
+ */
5355
+ cacheKey(eps) {
5356
+ const checkKey = this.check.cacheKey();
5357
+ if (checkKey === null) return null;
5358
+ let failKey = "";
5359
+ if (this.failureEffect) {
5360
+ const k = this.failureEffect.cacheKey();
5361
+ if (k === null) return null;
5362
+ failKey = k;
5363
+ }
5364
+ return `${checkKey}*F${failKey}*O${this.saveOutcome}*e${eps}`;
5365
+ }
5366
+ // By default, create PMF with no pruning. Cached by the cheap config key across identical rebuilds.
5334
5367
  toPMF(eps = 0) {
5335
- return this.resolve(eps).pmf;
5368
+ const key = this.cacheKey(eps);
5369
+ if (key === null) return this.resolve(eps).pmf;
5370
+ const cached = savePMFCache.get(key);
5371
+ if (cached) return cached;
5372
+ const pmf = this.resolve(eps).pmf;
5373
+ savePMFCache.set(key, pmf);
5374
+ return pmf;
5336
5375
  }
5337
5376
  get pmf() {
5338
5377
  return this.toPMF();
@@ -5368,6 +5407,10 @@ function resolveProbabilities(check) {
5368
5407
  }
5369
5408
 
5370
5409
  // src/builder/dc.ts
5410
+ var dcPMFCache = new LRUCache(4e3);
5411
+ function clearDCCache() {
5412
+ dcPMFCache.clear();
5413
+ }
5371
5414
  var DCBuilder = class _DCBuilder extends RollBuilder {
5372
5415
  constructor(baseRoll, saveConfig) {
5373
5416
  super(baseRoll.getSubRollConfigs());
@@ -5408,7 +5451,22 @@ var DCBuilder = class _DCBuilder extends RollBuilder {
5408
5451
  const expression = new RollBuilder(allConfigs).toExpression();
5409
5452
  return `(${expression} DC ${this.saveConfig.dc})`;
5410
5453
  }
5454
+ /**
5455
+ * The DC check's PMF is fully determined by the save DC plus everything `toPMF` below reads off the roll
5456
+ * configs (`rollType`, `baseReroll`, `modifier`, bonus dice) — all of which `super.cacheKey()` already
5457
+ * serializes. So extend the base key with the DC, mirroring {@link AlwaysHitBuilder.cacheKey}.
5458
+ */
5459
+ cacheKey() {
5460
+ const base = super.cacheKey();
5461
+ return base === null ? null : `DC|${this.saveConfig.dc}|${base}`;
5462
+ }
5411
5463
  toPMF(eps = 0) {
5464
+ const key = this.cacheKey();
5465
+ const fullKey = key === null ? null : `${key}*e${eps}`;
5466
+ if (fullKey !== null) {
5467
+ const cached = dcPMFCache.get(fullKey);
5468
+ if (cached) return cached;
5469
+ }
5412
5470
  const saveDC = this.saveDC;
5413
5471
  const rollType = this.rollType;
5414
5472
  const rerollOne = this.baseReroll > 0;
@@ -5430,7 +5488,9 @@ var DCBuilder = class _DCBuilder extends RollBuilder {
5430
5488
  [0, psuccess > 0 ? psuccess : 0],
5431
5489
  [1, pfail > 0 ? pfail : 0]
5432
5490
  ]);
5433
- return PMF.fromMap(m, eps);
5491
+ const pmf = PMF.fromMap(m, eps);
5492
+ if (fullKey !== null) dcPMFCache.set(fullKey, pmf);
5493
+ return pmf;
5434
5494
  }
5435
5495
  };
5436
5496
  RollBuilder.prototype.dc = function(saveDC) {
@@ -5438,6 +5498,6 @@ RollBuilder.prototype.dc = function(saveDC) {
5438
5498
  return new DCBuilder(this).dc(saveDC);
5439
5499
  };
5440
5500
 
5441
- export { ACBuilder, AlwaysCritBuilder, AlwaysHitBuilder, AttackBuilder, DCBuilder, HalfRollBuilder, MaxOfRollBuilder, ParsedRollBuilder, PooledRollBuilder, RollBuilder, SaveBuilder, ScaleRollBuilder, builderPMFCache, clearAttackCache, d, d10, d100, d12, d20, d4, d6, d8, defaultConfig, flat, hd20, roll, sumRolls };
5501
+ export { ACBuilder, AlwaysCritBuilder, AlwaysHitBuilder, AttackBuilder, DCBuilder, HalfRollBuilder, MaxOfRollBuilder, ParsedRollBuilder, PooledRollBuilder, RollBuilder, SaveBuilder, ScaleRollBuilder, builderPMFCache, clearAttackCache, clearDCCache, clearRollCache, clearSaveCache, d, d10, d100, d12, d20, d4, d6, d8, defaultConfig, flat, hd20, roll, sumRolls };
5442
5502
  //# sourceMappingURL=index.js.map
5443
5503
  //# sourceMappingURL=index.js.map