@httpx/memo-intl
TypeScript icon, indicating that this package has built-in type declarations

1.3.1 • Public • Published

@httpx/memo-intl

LRU-based memoizer for Intl.NumberFormat,Intl.DateFormat and other Intl constructors. Speeds up Intl operations up to 30x.

npm changelog codecov bundles node browserslist size downloads license

Install

$ npm install @httpx/memo-intl
$ yarn add @httpx/memo-intl
$ pnpm add @httpx/memo-intl

Features

  • 👉  Don't re-create the same Intl instance for the same options (memoized).
  • 👉  Keep the Intl api untouched. Just replace new Intl.NumberFormat by MIntl.NumberFormat...
  • 👉  Up to 30x faster than non-memoized Intl constructors.
  • 👉  Decrease memory usage, unwanted memory leaks and garbage collection pressure.
  • 👉  Max out 50 cache instances by default with @httpx/lru.
  • 👉  Lightweight. Node, browser and edge support.

Documentation

👉 Official website or Github Readme

Usage

NumberFormat

MDN: Intl.NumberFormat

import { MIntl } from '@httpx/memo-intl';

// Notice: `new Intl.NumberFormat` vs `MIntl.NumberFormat`
const formattedPrice = MIntl.NumberFormat('fr-FR', {
   style: 'currency',
   currency: 'EUR',
   notation: 'compact',
   minimumFractionDigits: 2,
   maximumFractionDigits: 2,
}).format(row.price);

DateTimeFormat

MDN: Intl.DateTimeFormat

import { MIntl } from '@httpx/memo-intl';

// Notice: `new Intl.DateTimeFormat` vs `MIntl.DateTimeFormat
const formatter = MIntl.DateTimeFormat('fr-FR', {
    dateStyle: 'full',
    timeStyle: 'full',
    timeZone: 'UTC'
});
const date = Date.parse('2024-05-29T07:42:43.230Z');
expect(formatter.format(date)).toBe(
    'mercredi 29 mai 2024 à 07:42:43 temps universel coordonné'
);
expectTypeOf(formatter).toEqualTypeOf<Intl.DateTimeFormat>();

Locale

MDN: Intl.Locale

import { MIntl } from '@httpx/memo-intl';

const locale = MIntl.Locale('fr-FR', { caseFirst: 'lower' });
console.log(locale.language); // "fr"

Collator

MDN: Intl.Collator

import { MIntl } from '@httpx/memo-intl';

const collator = MIntl.Collator('de', { sensitivity: 'base' });
console.log(['Z', 'a', 'z', 'ä'].sort(collator.compare));

RelativeTimeFormat

MDN: Intl.RelativeTimeFormat

import { MIntl } from '@httpx/memo-intl';

const rtf = MIntl.RelativeTimeFormat('en', { style: 'short' });
console.log(rtf.format(3, 'month')); // e.g. "in 3 mos."

ListFormat

MDN: Intl.ListFormat

import { MIntl } from '@httpx/memo-intl';

const listFormatter = MIntl.ListFormat('en', {
  style: 'long',
  type: 'conjunction',
});
console.log(listFormatter.format(['Red', 'Green', 'Blue']));

PluralRules

MDN: Intl.PluralRules

import { MIntl } from '@httpx/memo-intl';

const pr = MIntl.PluralRules('en-US', { type: 'cardinal' });
console.log(pr.select(1)); // "one"

Segmenter

MDN: Intl.Segmenter

import { MIntl } from '@httpx/memo-intl';

const segmenter = MIntl.Segmenter('fr', { granularity: 'word' });
const result = segmenter.segment('Bonjour le monde');
console.log([...result].map(({ segment }) => segment));

Cache

You can clear the cache or check the cache stats.

// Clear the cache
MIntl.cache.clear();

// Check cache stats
console.log(MIntl.cache.stats());

Benchmarks

Performance is monitored with codspeed.io.

CodSpeed Badge

See bench for details.

 RUN  v3.1.1 /home/sebastien/github/httpx/packages/memo-intl


 ✓ bench/m-intl.number-formatter.bench.ts > MIntl NumberFormatter benchmarks (1000 instances) 509ms
     name                                                   hz      min      max     mean      p75      p99     p995     p999      rme  samples
   · With memoization `MIntl.NumberFormatter()`         609.03   1.0427   3.0282   1.6419   2.3901   3.0282   3.0282   3.0282  ±31.97%       10   fastest
   · Without memoization `new Intl.NumberFormatter()`  46.8494  20.1793  25.8985  21.3450  21.6799  25.8985  25.8985  25.8985   ±5.86%       10

 ✓ bench/m-intl.date-formatter.bench.ts > MIntl DateFormatter benchmarks (1000 instances) 1042ms
     name                                                 hz      min      max     mean      p75      p99     p995     p999      rme  samples
   · With memoization `MIntl.DateFormatter()`         714.18   1.2713   1.6793   1.4002   1.5520   1.6793   1.6793   1.6793   ±7.71%       10   fastest
   · Without memoization `new Intl.DateFormatter()`  19.2053  38.3342  85.2885  52.0689  56.6698  85.2885  85.2885  85.2885  ±19.79%       10

 ✓ bench/m-intl.relative-time-format.bench.ts > MIntl RelativeTimeFormat benchmarks (1000 instances) 366ms
     name                                                       hz     min      max     mean      p75      p99     p995     p999      rme  samples
   · With memoization `MIntl.RelativeTimeFormat()`        1,148.10  0.6614   1.2955   0.8710   1.1134   1.2955   1.2955   1.2955  ±18.67%       10   fastest
   · Without memoization `new Intl.RelativeTimeFormat()`   86.5178  8.2824  17.9734  11.5583  16.5455  17.9734  17.9734  17.9734  ±24.10%       10

 ✓ bench/m-intl.locale.bench.ts > MIntl Locale benchmarks (1000 instances)
     name                                           hz     min     max    mean     p75     p99    p995    p999      rme  samples
   · With memoization `MIntl.Locale()`        1,511.86  0.5651  1.0696  0.6614  0.6494  1.0696  1.0696  1.0696  ±16.03%       10   fastest
   · Without memoization `new Intl.Locale()`    300.74  2.9911  3.5926  3.3251  3.4325  3.5926  3.5926  3.5926   ±3.62%       10

 BENCH  Summary

  With memoization `MIntl.DateFormatter()` - bench/m-intl.date-formatter.bench.ts > MIntl DateFormatter benchmarks (1000 instances)
    37.19x faster than Without memoization `new Intl.DateFormatter()`

  With memoization `MIntl.Locale()` - bench/m-intl.locale.bench.ts > MIntl Locale benchmarks (1000 instances)
    5.03x faster than Without memoization `new Intl.Locale()`

  With memoization `MIntl.NumberFormatter()` - bench/m-intl.number-formatter.bench.ts > MIntl NumberFormatter benchmarks (1000 instances)
    13.00x faster than Without memoization `new Intl.NumberFormatter()`

  With memoization `MIntl.RelativeTimeFormat()` - bench/m-intl.relative-time-format.bench.ts > MIntl RelativeTimeFormat benchmarks (1000 instances)
    13.27x faster than Without memoization `new Intl.RelativeTimeFormat()`

Bundle size

Bundle size is tracked by a size-limit configuration

Scenario Size with deps (compressed)
`import { MIntl } from '@httpx/memo-intl' ~ 790B

Note that per-se the library weights less than 300 bytes, the size limit accounts for the @httpx/lru dependency. For CJS usage (not recommended) track the size on bundlephobia.

Compatibility

Level CI Description
Node CI for 18.x, 20.x & 22.x.
Browser Tested with latest chrome (vitest/playwright)
Browserslist > 95% on 01/2025. defaults, chrome >= 96, firefox >= 105, edge >= 113, safari >= 15, ios >= 15, opera >= 103, not dead
Edge Ensured on CI with @vercel/edge-runtime.
Cloudflare Ensured with @cloudflare/vitest-pool-workers (see wrangler.toml
Typescript TS 5.0 + / are-the-type-wrong checks on CI.
ES2022 Dist files checked with es-check
Performance Monitored with with codspeed.io

For older browsers: most frontend frameworks can transpile the library (ie: nextjs...)

Contributors

Contributions are warmly appreciated. Have a look to the CONTRIBUTING document.

Sponsors

If my OSS work brightens your day, let's take it to new heights together! Sponsor, coffee, or star – any gesture of support fuels my passion to improve. Thanks for being awesome! 🙏❤️

Special thanks to

Jetbrains logo Jetbrains logo
JetBrains Embie.be

License

MIT © belgattitude and contributors.

Readme

Keywords

Package Sidebar

Install

npm i @httpx/memo-intl

Weekly Downloads

270

Version

1.3.1

License

MIT

Unpacked Size

52.7 kB

Total Files

9

Last publish

Collaborators

  • s.vanvelthem