diff --git a/fluent-bundle/src/bundle.ts b/fluent-bundle/src/bundle.ts index 59d7b81e..c6396e5c 100644 --- a/fluent-bundle/src/bundle.ts +++ b/fluent-bundle/src/bundle.ts @@ -4,6 +4,7 @@ import { FluentResource } from "./resource.js"; import { FluentValue, FluentNone, FluentFunction } from "./types.js"; import { Message, Term, Pattern } from "./ast.js"; import { NUMBER, DATETIME } from "./builtins.js"; +import { getMemoizerForLocale, IntlCache } from "./memoizer.js"; export type TextTransform = (text: string) => string; @@ -22,12 +23,7 @@ export class FluentBundle { public _functions: Record; public _useIsolating: boolean; public _transform: TextTransform; - public _intls = new WeakMap< - | typeof Intl.NumberFormat - | typeof Intl.DateTimeFormat - | typeof Intl.PluralRules, - Record - >(); + public _intls: IntlCache; /** * Create an instance of `FluentBundle`. @@ -78,6 +74,7 @@ export class FluentBundle { }; this._useIsolating = useIsolating; this._transform = transform; + this._intls = getMemoizerForLocale(locales); } /** diff --git a/fluent-bundle/src/memoizer.ts b/fluent-bundle/src/memoizer.ts new file mode 100644 index 00000000..1f9bf204 --- /dev/null +++ b/fluent-bundle/src/memoizer.ts @@ -0,0 +1,19 @@ +export type IntlCache = Map< + | typeof Intl.NumberFormat + | typeof Intl.DateTimeFormat + | typeof Intl.PluralRules, + Record + >; + +const cache = new Map(); + +export function getMemoizerForLocale(locales: string | string[]): IntlCache { + const stringLocale = Array.isArray(locales) ? locales.join(" ") : locales; + let memoizer = cache.get(stringLocale); + if (memoizer === undefined) { + memoizer = new Map(); + cache.set(stringLocale, memoizer); + } + + return memoizer; +} diff --git a/fluent-bundle/test/memoizer_test.js b/fluent-bundle/test/memoizer_test.js new file mode 100644 index 00000000..ecf74e7d --- /dev/null +++ b/fluent-bundle/test/memoizer_test.js @@ -0,0 +1,30 @@ +'use strict'; + +import assert from 'assert'; +import {getMemoizerForLocale} from '../esm/memoizer.js'; + +suite('Memoizer', function() { + test('returns same instance for same locale', function() { + const memoizer1 = getMemoizerForLocale('en') + const memoizer2 = getMemoizerForLocale('en') + assert.strictEqual(memoizer1, memoizer2) + }); + + test('returns different instance for different locale', function() { + const memoizer1 = getMemoizerForLocale('en') + const memoizer2 = getMemoizerForLocale('uk') + assert.notStrictEqual(memoizer1, memoizer2) + }); + + test('works with array of locales', function() { + const memoizer1 = getMemoizerForLocale(['en']) + const memoizer2 = getMemoizerForLocale(['en']) + assert.strictEqual(memoizer1, memoizer2) + }); + + test('works with string and array of locales', function() { + const memoizer1 = getMemoizerForLocale(['en']) + const memoizer2 = getMemoizerForLocale('en') + assert.strictEqual(memoizer1, memoizer2) + }) +})