@formatjs/intl-pluralrules 7.0.0 → 7.0.2

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/polyfill.iife.js CHANGED
@@ -2332,16 +2332,23 @@ function distance(desired, supported) {
2332
2332
  /** ICU language/script/region distance, including fractional explicit-subtag ties. */
2333
2333
  const findMatchingDistance = memoize((desired, supported) => distance(maximal(canonicalize(desired)), maximal(canonicalize(supported))), { serializer: (args) => `${args[0]}|${args[1]}` });
2334
2334
  const supportedCache = /* @__PURE__ */ new WeakMap();
2335
+ const immutableLocaleLists = /* @__PURE__ */ new WeakSet();
2335
2336
  let paradigms;
2337
+ function createLocaleListSnapshot(locales) {
2338
+ const snapshot = Object.freeze(Array.from(locales));
2339
+ immutableLocaleLists.add(snapshot);
2340
+ return snapshot;
2341
+ }
2336
2342
  function equivalentKey(lsr) {
2337
2343
  return `${lsr.language}|${lsr.script}|${lsr.region}`;
2338
2344
  }
2339
2345
  function prepare(locales) {
2346
+ const immutable = immutableLocaleLists.has(locales);
2340
2347
  let result = supportedCache.get(locales);
2341
- if (result && (result.original.length !== locales.length || result.original.some((tag, index) => tag !== locales[index]))) result = void 0;
2348
+ if (result && !immutable && (result.original.length !== locales.length || result.original.some((tag, index) => tag !== locales[index]))) result = void 0;
2342
2349
  if (!result) {
2343
2350
  result = {
2344
- original: Array.from(locales),
2351
+ original: immutable ? locales : Array.from(locales),
2345
2352
  tags: [],
2346
2353
  raw: /* @__PURE__ */ new Map(),
2347
2354
  orders: /* @__PURE__ */ new Map(),
@@ -2847,22 +2854,28 @@ function UnicodeExtensionComponents(extension) {
2847
2854
  };
2848
2855
  }
2849
2856
  const availableLocaleArrays = /* @__PURE__ */ new WeakMap();
2850
- function localeArray(locales) {
2857
+ function localeArray(locales, bestFit) {
2851
2858
  if (Array.isArray(locales)) return locales;
2852
2859
  const available = locales;
2853
- const cached = availableLocaleArrays.get(available);
2854
- if (cached?.length === available.size) {
2860
+ let cached = availableLocaleArrays.get(available);
2861
+ if (cached?.original.length !== available.size) cached = void 0;
2862
+ if (cached) {
2863
+ const original = cached.original;
2855
2864
  let index = 0;
2856
- for (const locale of available) if (cached[index++] !== locale) {
2857
- const result = Array.from(available);
2858
- availableLocaleArrays.set(available, result);
2859
- return result;
2865
+ for (const locale of available) if (original[index++] !== locale) {
2866
+ cached = void 0;
2867
+ break;
2860
2868
  }
2861
- return cached;
2862
2869
  }
2863
- const result = Array.from(available);
2864
- availableLocaleArrays.set(available, result);
2865
- return result;
2870
+ if (!cached) {
2871
+ cached = {
2872
+ original: Array.from(available),
2873
+ snapshot: void 0
2874
+ };
2875
+ availableLocaleArrays.set(available, cached);
2876
+ }
2877
+ if (!bestFit) return cached.original;
2878
+ return cached.snapshot ??= createLocaleListSnapshot(cached.original);
2866
2879
  }
2867
2880
  /**
2868
2881
  * https://tc39.es/ecma402/#sec-resolvelocale
@@ -2870,8 +2883,8 @@ function localeArray(locales) {
2870
2883
  function ResolveLocale(availableLocales, requestedLocales, options, relevantExtensionKeys, localeData, getDefaultLocale) {
2871
2884
  const matcher = options.localeMatcher;
2872
2885
  let r;
2873
- if (matcher === "lookup") r = LookupMatcher(localeArray(availableLocales), requestedLocales, getDefaultLocale);
2874
- else r = BestFitMatcher(localeArray(availableLocales), requestedLocales, getDefaultLocale);
2886
+ if (matcher === "lookup") r = LookupMatcher(localeArray(availableLocales, false), requestedLocales, getDefaultLocale);
2887
+ else r = BestFitMatcher(localeArray(availableLocales, true), requestedLocales, getDefaultLocale);
2875
2888
  if (r == null) r = {
2876
2889
  locale: getDefaultLocale(),
2877
2890
  extension: ""
@@ -3205,7 +3218,10 @@ var BigDecimal = class BigDecimal {
3205
3218
  const negZero = this._isSignNegative() !== other._isSignNegative();
3206
3219
  return BigDecimal._create(0n, 0, 0, negZero);
3207
3220
  }
3208
- const [nm, ne] = removeTrailingZeros(this._mantissa * bigintPow10(DIV_PRECISION) / other._mantissa, this._exponent - other._exponent - DIV_PRECISION);
3221
+ const exponent = this._exponent - other._exponent;
3222
+ const newExponent = exponent - DIV_PRECISION;
3223
+ if ((other._mantissa === 1n || other._mantissa === -1n) && Number.isSafeInteger(exponent) && Number.isSafeInteger(newExponent)) return BigDecimal._create(other._mantissa === 1n ? this._mantissa : -this._mantissa, exponent === 0 ? 0 : exponent, 0, false);
3224
+ const [nm, ne] = removeTrailingZeros(this._mantissa * bigintPow10(DIV_PRECISION) / other._mantissa, newExponent);
3209
3225
  return BigDecimal._create(nm, ne, 0, false);
3210
3226
  }
3211
3227
  plus(y) {
@@ -3408,6 +3424,7 @@ var BigDecimal = class BigDecimal {
3408
3424
  if (this._special === 2) return Infinity;
3409
3425
  if (this._special === 3) return -Infinity;
3410
3426
  if (this._mantissa === 0n) return this._negativeZero ? -0 : 0;
3427
+ if (this._exponent === 0) return Number(this._mantissa);
3411
3428
  return Number(this.toString());
3412
3429
  }
3413
3430
  toString() {
@@ -3816,19 +3833,15 @@ function ApplyUnsignedRoundingMode(x, r1, r2, unsignedRoundingMode) {
3816
3833
  return r2;
3817
3834
  }
3818
3835
  // packages/ecma402-abstract/NumberFormat/decimal-cache.js
3819
- /**
3820
- * Cached function to compute powers of 10 for Decimal.js operations.
3821
- * This cache significantly reduces overhead in ComputeExponent and ToRawFixed
3822
- * by memoizing expensive Decimal.pow(10, n) calculations.
3823
- *
3824
- * Common exponents (e.g., -20 to 20) are used repeatedly in number formatting,
3825
- * so caching provides substantial performance benefits.
3826
- *
3827
- * @param exponent - Can be a number or Decimal. If Decimal, it will be converted to string for cache key.
3828
- */
3829
- const getPowerOf10 = memoize((exponent) => {
3830
- return BigDecimal.pow(10, exponent);
3831
- });
3836
+ const powersOfTen = /* @__PURE__ */ new Map();
3837
+ function getPowerOf10(exponent) {
3838
+ const n = typeof exponent === "number" ? exponent : exponent.toNumber();
3839
+ const cached = powersOfTen.get(n);
3840
+ if (cached !== void 0) return cached;
3841
+ const power = BigDecimal.pow(10, n);
3842
+ if (Number.isInteger(n) && n >= -324 && n <= 324) powersOfTen.set(n, power);
3843
+ return power;
3844
+ }
3832
3845
  // packages/ecma402-abstract/NumberFormat/ToRawFixed.js
3833
3846
  function ToRawFixedFn(n, f) {
3834
3847
  return n.times(getPowerOf10(-f));
@@ -3850,10 +3863,19 @@ function findN2R2(x, f, roundingIncrement) {
3850
3863
  /**
3851
3864
  * https://tc39.es/ecma402/#sec-torawfixed
3852
3865
  * @param x a finite non-negative Number or BigInt
3853
- * @param minFraction an integer between 0 and 20
3854
- * @param maxFraction an integer between 0 and 20
3866
+ * @param minFraction an integer between 0 and 100
3867
+ * @param maxFraction an integer between 0 and 100
3855
3868
  */
3856
3869
  function ToRawFixed(x, minFraction, maxFraction, roundingIncrement, unsignedRoundingMode) {
3870
+ if (roundingIncrement === 1 && x.isInteger()) {
3871
+ const integer = x.toString();
3872
+ return {
3873
+ formattedString: integer + (minFraction === 0 ? "" : "." + repeat("0", minFraction)),
3874
+ roundedNumber: x,
3875
+ integerDigitsCount: integer.length,
3876
+ roundingMagnitude: -maxFraction
3877
+ };
3878
+ }
3857
3879
  const f = maxFraction;
3858
3880
  const { n1, r1 } = findN1R1(x, f, roundingIncrement);
3859
3881
  const { n2, r2 } = findN2R2(x, f, roundingIncrement);
package/polyfill.js CHANGED
@@ -765,19 +765,15 @@ function ApplyUnsignedRoundingMode(x, r1, r2, unsignedRoundingMode) {
765
765
  return r2;
766
766
  }
767
767
  // packages/ecma402-abstract/NumberFormat/decimal-cache.js
768
- /**
769
- * Cached function to compute powers of 10 for Decimal.js operations.
770
- * This cache significantly reduces overhead in ComputeExponent and ToRawFixed
771
- * by memoizing expensive Decimal.pow(10, n) calculations.
772
- *
773
- * Common exponents (e.g., -20 to 20) are used repeatedly in number formatting,
774
- * so caching provides substantial performance benefits.
775
- *
776
- * @param exponent - Can be a number or Decimal. If Decimal, it will be converted to string for cache key.
777
- */
778
- const getPowerOf10 = memoize((exponent) => {
779
- return Decimal.pow(10, exponent);
780
- });
768
+ const powersOfTen = /* @__PURE__ */ new Map();
769
+ function getPowerOf10(exponent) {
770
+ const n = typeof exponent === "number" ? exponent : exponent.toNumber();
771
+ const cached = powersOfTen.get(n);
772
+ if (cached !== void 0) return cached;
773
+ const power = Decimal.pow(10, n);
774
+ if (Number.isInteger(n) && n >= -324 && n <= 324) powersOfTen.set(n, power);
775
+ return power;
776
+ }
781
777
  // packages/ecma402-abstract/NumberFormat/ToRawFixed.js
782
778
  function ToRawFixedFn(n, f) {
783
779
  return n.times(getPowerOf10(-f));
@@ -799,10 +795,19 @@ function findN2R2(x, f, roundingIncrement) {
799
795
  /**
800
796
  * https://tc39.es/ecma402/#sec-torawfixed
801
797
  * @param x a finite non-negative Number or BigInt
802
- * @param minFraction an integer between 0 and 20
803
- * @param maxFraction an integer between 0 and 20
798
+ * @param minFraction an integer between 0 and 100
799
+ * @param maxFraction an integer between 0 and 100
804
800
  */
805
801
  function ToRawFixed(x, minFraction, maxFraction, roundingIncrement, unsignedRoundingMode) {
802
+ if (roundingIncrement === 1 && x.isInteger()) {
803
+ const integer = x.toString();
804
+ return {
805
+ formattedString: integer + (minFraction === 0 ? "" : "." + repeat("0", minFraction)),
806
+ roundedNumber: x,
807
+ integerDigitsCount: integer.length,
808
+ roundingMagnitude: -maxFraction
809
+ };
810
+ }
806
811
  const f = maxFraction;
807
812
  const { n1, r1 } = findN1R1(x, f, roundingIncrement);
808
813
  const { n2, r2 } = findN2R2(x, f, roundingIncrement);