@wix/fed-cli-i18next 1.6.39 → 1.6.41

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/dist/icu.js CHANGED
@@ -1,2 +1,2 @@
1
- import e from"intl-messageformat";function t(){return{memoize:!0,memoizeFallback:!1,maxCacheSize:1e3,maxFormatterCacheSize:100,bindI18n:``,bindI18nStore:`added removed`,parseErrorHandler:(e,t,n)=>n}}var n=class{options;formats;type;cacheRoot=/* @__PURE__ */ new Map;formatterCache=/* @__PURE__ */ new Map;unbindEvents;formatters={getNumberFormat:(...e)=>this.getFormatter(`number`,Intl.NumberFormat,e),getDateTimeFormat:(...e)=>this.getFormatter(`dateTime`,Intl.DateTimeFormat,e),getPluralRules:(...e)=>this.getFormatter(`pluralRules`,Intl.PluralRules,e)};constructor(e){this.type=`i18nFormat`,this.init(null,e)}init(n,i){let a=n&&n.options&&n.options.i18nFormat||{};this.options=r(a,i,this.options||{},t());for(let e of[`maxCacheSize`,`maxFormatterCacheSize`]){let t=this.options[e];if(t!==1/0&&(!Number.isSafeInteger(t)||t<0))throw RangeError(`${e} must be a non-negative safe integer or Infinity`)}if(this.formats=this.options?.formats,this.unbindEvents?.(),this.unbindEvents=void 0,this.clearCache(),n){let{bindI18n:t,bindI18nStore:r}=this.options;n.IntlMessageFormat=e,n.ICU=this;let i=()=>this.clearMessages(),a=(e,t)=>this.clearNamespace(e,t),o=n.store,s=t?t.split(` `):[],c=r?r.split(` `):[];for(let e of s)n.on(e,i);for(let e of c)o.on(e,a);this.unbindEvents=()=>{for(let e of s)n.off(e,i);for(let e of c)o.off(e,a)}}this.options?.localeData&&(Object.prototype.toString.apply(this.options.localeData)===`[object Array]`?this.options.localeData.forEach(e=>this.addLocaleData(e)):this.addLocaleData(this.options.localeData))}addLocaleData(t){(Array.isArray(t)?t:[t]).forEach(t=>{t&&t.locale&&e.__addLocaleData(t)})}addUserDefinedFormats(e){this.formats=this.formats?{...this.formats,...e}:e,this.clearMessages()}parse(t,n,r,i,a,o){let s=this.options?.memoize&&this.options.maxCacheSize>0?JSON.stringify([r,i,a]):void 0,c;if(s!==void 0){let e=this.cacheRoot.get(s);e?.source===t&&(c=e.fc,this.touch(s,e))}try{return c||(c=new e(t,r,this.formats,{formatters:this.formatters}),s!==void 0&&(this.options.memoizeFallback||!o||o.resolved?.res)&&(this.touch(s,{lng:r,ns:i,source:t,fc:c}),this.cacheRoot.size>this.options.maxCacheSize&&this.cacheRoot.delete(this.cacheRoot.keys().next().value))),c.format(n)}catch(e){return this.options?.parseErrorHandler?.(e,a,t,n)}}addLookupKeys(e){return e}clearMessages(){this.cacheRoot.clear()}clearCache(){this.clearMessages(),this.formatterCache.clear()}clearNamespace(e,t){for(let[n,r]of this.cacheRoot)r.lng===e&&r.ns===t&&this.cacheRoot.delete(n)}touch(e,t){this.cacheRoot.delete(e),this.cacheRoot.set(e,t)}getFormatter(e,t,n){if(!this.options?.memoize||this.options.maxFormatterCacheSize===0)return new t(...n);let[r,i]=n,a=JSON.stringify([e,r,Object.entries(i??{}).sort(([e],[t])=>e<t?-1:+(e>t))]),o=this.formatterCache.get(a);if(o)return this.formatterCache.delete(a),this.formatterCache.set(a,o),o;let s=new t(...n);return this.formatterCache.set(a,s),this.formatterCache.size>this.options.maxFormatterCacheSize&&this.formatterCache.delete(this.formatterCache.keys().next().value),s}};n.type=`i18nFormat`;function r(e,...t){let n=e;for(let e of t)if(e)for(let[t,r]of Object.entries(e))n[t]===void 0&&(n[t]=r);return e}export{n as default};
1
+ import{IntlMessageFormat as e}from"intl-messageformat";function t(){return{memoize:!0,memoizeFallback:!1,maxCacheSize:1e3,maxFormatterCacheSize:100,bindI18n:``,bindI18nStore:`added removed`,parseErrorHandler:(e,t,n)=>n}}var n=class{options;formats;type;cacheRoot=/* @__PURE__ */ new Map;formatterCache=/* @__PURE__ */ new Map;unbindEvents;formatters={getNumberFormat:(...e)=>this.getFormatter(`number`,Intl.NumberFormat,e),getDateTimeFormat:(...e)=>this.getFormatter(`dateTime`,Intl.DateTimeFormat,e),getPluralRules:(...e)=>this.getFormatter(`pluralRules`,Intl.PluralRules,e)};constructor(e){this.type=`i18nFormat`,this.init(null,e)}init(n,i){let a=n&&n.options&&n.options.i18nFormat||{};this.options=r(a,i,this.options||{},t());for(let e of[`maxCacheSize`,`maxFormatterCacheSize`]){let t=this.options[e];if(t!==1/0&&(!Number.isSafeInteger(t)||t<0))throw RangeError(`${e} must be a non-negative safe integer or Infinity`)}if(this.formats=this.options?.formats,this.unbindEvents?.(),this.unbindEvents=void 0,this.clearCache(),n){let{bindI18n:t,bindI18nStore:r}=this.options;n.IntlMessageFormat=e,n.ICU=this;let i=()=>this.clearMessages(),a=(e,t)=>this.clearNamespace(e,t),o=n.store,s=t?t.split(` `):[],c=r?r.split(` `):[];for(let e of s)n.on(e,i);for(let e of c)o.on(e,a);this.unbindEvents=()=>{for(let e of s)n.off(e,i);for(let e of c)o.off(e,a)}}this.options?.localeData&&(Object.prototype.toString.apply(this.options.localeData)===`[object Array]`?this.options.localeData.forEach(e=>this.addLocaleData(e)):this.addLocaleData(this.options.localeData))}addLocaleData(t){(Array.isArray(t)?t:[t]).forEach(t=>{t&&t.locale&&e.__addLocaleData(t)})}addUserDefinedFormats(e){this.formats=this.formats?{...this.formats,...e}:e,this.clearMessages()}parse(t,n,r,i,a,o){let s=this.options?.memoize&&this.options.maxCacheSize>0?JSON.stringify([r,i,a]):void 0,c;if(s!==void 0){let e=this.cacheRoot.get(s);e?.source===t&&(c=e.fc,this.touch(s,e))}try{return c||(c=new e(t,r,this.formats,{formatters:this.formatters}),s!==void 0&&(this.options.memoizeFallback||!o||o.resolved?.res)&&(this.touch(s,{lng:r,ns:i,source:t,fc:c}),this.cacheRoot.size>this.options.maxCacheSize&&this.cacheRoot.delete(this.cacheRoot.keys().next().value))),c.format(n)}catch(e){return this.options?.parseErrorHandler?.(e,a,t,n)}}addLookupKeys(e){return e}clearMessages(){this.cacheRoot.clear()}clearCache(){this.clearMessages(),this.formatterCache.clear()}clearNamespace(e,t){for(let[n,r]of this.cacheRoot)r.lng===e&&r.ns===t&&this.cacheRoot.delete(n)}touch(e,t){this.cacheRoot.delete(e),this.cacheRoot.set(e,t)}getFormatter(e,t,n){if(!this.options?.memoize||this.options.maxFormatterCacheSize===0)return new t(...n);let[r,i]=n,a=JSON.stringify([e,r,Object.entries(i??{}).sort(([e],[t])=>e<t?-1:+(e>t))]),o=this.formatterCache.get(a);if(o)return this.formatterCache.delete(a),this.formatterCache.set(a,o),o;let s=new t(...n);return this.formatterCache.set(a,s),this.formatterCache.size>this.options.maxFormatterCacheSize&&this.formatterCache.delete(this.formatterCache.keys().next().value),s}};n.type=`i18nFormat`;function r(e,...t){let n=e;for(let e of t)if(e)for(let[t,r]of Object.entries(e))n[t]===void 0&&(n[t]=r);return e}export{n as default};
2
2
  //# sourceMappingURL=icu.js.map
package/dist/icu.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"icu.js","names":[],"sources":["../src/icu.ts"],"sourcesContent":["import IntlMessageFormat from 'intl-messageformat';\nimport type { Formatters } from 'intl-messageformat';\nimport type { i18n } from 'i18next';\n\ninterface IcuFormats {\n number?: {\n [styleName: string]: Intl.NumberFormatOptions;\n };\n date?: {\n [styleName: string]: Intl.DateTimeFormatOptions;\n };\n time?: {\n [styleName: string]: Intl.DateTimeFormatOptions;\n };\n}\n\ntype StoreEvent = 'added' | 'removed';\n\ninterface CachedMessage {\n lng: string;\n ns: string;\n source: string;\n fc: IntlMessageFormat;\n}\n\nexport interface IcuConfig {\n memoize?: boolean;\n memoizeFallback?: boolean;\n /** Maximum compiled messages per instance. Defaults to 1000; 0 disables this cache, Infinity disables eviction. */\n maxCacheSize?: number;\n /** Maximum shared Intl formatters per instance. Defaults to 100; 0 disables this cache, Infinity disables eviction. */\n maxFormatterCacheSize?: number;\n formats?: IcuFormats;\n bindI18n?: string;\n /** Space-separated resource-store events. Defaults to 'added removed'. */\n bindI18nStore?: '' | StoreEvent | 'added removed' | 'removed added';\n localeData?: any;\n parseErrorHandler?: (err: Error, key: string, res: string, options: object) => string;\n parseLngForICU?: (lng: string) => string;\n}\n\nfunction getDefaults(): IcuConfig {\n return {\n memoize: true,\n memoizeFallback: false,\n maxCacheSize: 1000,\n maxFormatterCacheSize: 100,\n bindI18n: '',\n bindI18nStore: 'added removed',\n parseErrorHandler: (_err, _key, res) => {\n return res;\n },\n };\n}\n\n/**\n * Copied from original ICU source code.\n * @source https://github.com/i18next/i18next-icu/blob/7809547c821a7ef3b2bb9ab2610cdbbcfedcb2f9/src/index.js\n *\n * It's done in order to support `IntlMessageFormat` out of the box.\n * `IntlMessageFormat` is adding formatters that are not provided by i18n.\n * For example, `select` formatter - https://formatjs.io/docs/core-concepts/icu-syntax#select-format\n * It allows to use following translation value: 'Welcome back{inputData, select, 0 {} 1 {, John}}'\n * See example in tests: __tests__/i18n.spec.tsx\n */\nclass ICU {\n options: IcuConfig | undefined;\n formats: IcuFormats | undefined;\n type: string;\n private cacheRoot = new Map<string, CachedMessage>();\n private formatterCache = new Map<\n string,\n Intl.NumberFormat | Intl.DateTimeFormat | Intl.PluralRules\n >();\n private unbindEvents?: () => void;\n private formatters: Formatters = {\n getNumberFormat: (...args) => this.getFormatter('number', Intl.NumberFormat, args),\n getDateTimeFormat: (...args) => this.getFormatter('dateTime', Intl.DateTimeFormat, args),\n getPluralRules: (...args) => this.getFormatter('pluralRules', Intl.PluralRules, args),\n };\n\n constructor(options: IcuConfig) {\n this.type = 'i18nFormat';\n\n this.init(null, options);\n }\n\n init(i18next: i18n | null, options: IcuConfig) {\n const i18nextOptions = (i18next && i18next.options && i18next.options.i18nFormat) || {};\n this.options = defaults(i18nextOptions, options, this.options || {}, getDefaults());\n for (const name of ['maxCacheSize', 'maxFormatterCacheSize'] as const) {\n const limit = this.options![name]!;\n if (limit !== Infinity && (!Number.isSafeInteger(limit) || limit < 0)) {\n throw new RangeError(`${name} must be a non-negative safe integer or Infinity`);\n }\n }\n this.formats = this.options?.formats;\n this.unbindEvents?.();\n this.unbindEvents = undefined;\n this.clearCache();\n\n if (i18next) {\n const { bindI18n, bindI18nStore } = this.options!;\n\n // @ts-expect-error fix later\n i18next.IntlMessageFormat = IntlMessageFormat;\n // @ts-expect-error fix later\n i18next.ICU = this;\n\n // Resources can only stale compiled messages, never the shared Intl formatters.\n const clearAll = () => this.clearMessages();\n // Store events report the (lng, ns) that changed, so only that much needs dropping.\n const clearChanged = (lng: string, ns: string) => this.clearNamespace(lng, ns);\n const store = i18next.store;\n const i18nEvents = bindI18n ? bindI18n.split(' ') : [];\n const storeEvents = bindI18nStore ? (bindI18nStore.split(' ') as StoreEvent[]) : [];\n for (const event of i18nEvents) i18next.on(event, clearAll);\n for (const event of storeEvents) store.on(event, clearChanged);\n this.unbindEvents = () => {\n for (const event of i18nEvents) i18next.off(event, clearAll);\n for (const event of storeEvents) store.off(event, clearChanged);\n };\n }\n\n if (this.options?.localeData) {\n if (Object.prototype.toString.apply(this.options.localeData) === '[object Array]') {\n this.options.localeData.forEach((ld: any) => this.addLocaleData(ld));\n } else {\n this.addLocaleData(this.options.localeData);\n }\n }\n }\n\n addLocaleData(data: any) {\n const locales = Array.isArray(data) ? data : [data];\n\n locales.forEach((localeData) => {\n if (localeData && localeData.locale) {\n // Undeclared legacy escape hatch on IntlMessageFormat.\n (IntlMessageFormat as any)['__addLocaleData'](localeData);\n }\n });\n }\n\n addUserDefinedFormats(formats: IcuFormats) {\n this.formats = this.formats ? { ...this.formats, ...formats } : formats;\n // Compiled messages capture `formats`; formatters are keyed by their resolved options.\n this.clearMessages();\n }\n\n parse(\n res: string,\n options: Record<string, any>,\n lng: string,\n ns: string,\n key: string,\n info: any,\n ) {\n // An undefined key means caching is off.\n const cacheKey =\n this.options?.memoize && this.options.maxCacheSize! > 0\n ? JSON.stringify([lng, ns, key])\n : undefined;\n\n let fc: IntlMessageFormat | undefined;\n if (cacheKey !== undefined) {\n const cached = this.cacheRoot.get(cacheKey);\n // A changed source must be recompiled even when no invalidation event fired.\n if (cached?.source === res) {\n fc = cached.fc;\n this.touch(cacheKey, cached);\n }\n }\n\n try {\n if (!fc) {\n fc = new IntlMessageFormat(res, lng, this.formats, { formatters: this.formatters });\n if (\n cacheKey !== undefined &&\n (this.options!.memoizeFallback || !info || info.resolved?.res)\n ) {\n this.touch(cacheKey, { lng, ns, source: res, fc });\n if (this.cacheRoot.size > this.options!.maxCacheSize!) {\n this.cacheRoot.delete(this.cacheRoot.keys().next().value!);\n }\n }\n }\n\n return fc.format(options);\n } catch (err) {\n return this.options?.parseErrorHandler?.(err as Error, key, res, options);\n }\n }\n\n addLookupKeys(finalKeys: any) {\n // no additional keys needed for select or plural\n // so there is no need to add keys to that finalKeys array\n return finalKeys;\n }\n\n /** Drops compiled messages, keeping the shared Intl formatters. */\n clearMessages() {\n this.cacheRoot.clear();\n }\n\n /** Drops compiled messages and the shared Intl formatters. */\n clearCache() {\n this.clearMessages();\n this.formatterCache.clear();\n }\n\n private clearNamespace(lng: string, ns: string) {\n for (const [cacheKey, entry] of this.cacheRoot) {\n if (entry.lng === lng && entry.ns === ns) this.cacheRoot.delete(cacheKey);\n }\n }\n\n /** Re-inserts to mark most recently used: Map.set keeps an existing key's position. */\n private touch(cacheKey: string, entry: CachedMessage) {\n this.cacheRoot.delete(cacheKey);\n this.cacheRoot.set(cacheKey, entry);\n }\n\n private getFormatter<\n T extends Intl.NumberFormat | Intl.DateTimeFormat | Intl.PluralRules,\n Args extends unknown[],\n >(type: string, Formatter: new (...args: Args) => T, args: Args): T {\n if (!this.options?.memoize || this.options.maxFormatterCacheSize === 0) {\n return new Formatter(...args);\n }\n\n const [locales, options] = args;\n // Equivalent option objects should share a formatter regardless of property order.\n const key = JSON.stringify([\n type,\n locales,\n // oxlint-disable-next-line no-array-sort -- Object.entries already returns a fresh array\n Object.entries(options ?? {}).sort(([a], [b]) => (a < b ? -1 : a > b ? 1 : 0)),\n ]);\n const cached = this.formatterCache.get(key);\n if (cached) {\n this.formatterCache.delete(key);\n this.formatterCache.set(key, cached);\n return cached as T;\n }\n\n const formatter = new Formatter(...args);\n this.formatterCache.set(key, formatter);\n if (this.formatterCache.size > this.options!.maxFormatterCacheSize!) {\n this.formatterCache.delete(this.formatterCache.keys().next().value!);\n }\n return formatter;\n }\n}\n\n// @ts-expect-error fix it later\nICU.type = 'i18nFormat';\n\nexport default ICU;\n\n/** Fills only the keys `obj` leaves undefined, so explicit `undefined` never clobbers a default. */\nfunction defaults(obj: IcuConfig, ...sources: (IcuConfig | undefined)[]): IcuConfig {\n const target = obj as Record<string, unknown>;\n for (const source of sources) {\n if (!source) continue;\n for (const [key, value] of Object.entries(source)) {\n if (target[key] === undefined) target[key] = value;\n }\n }\n return obj;\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"icu.js","names":[],"sources":["../src/icu.ts"],"sourcesContent":["import { IntlMessageFormat } from 'intl-messageformat';\nimport type { Formatters } from 'intl-messageformat';\nimport type { i18n } from 'i18next';\n\ninterface IcuFormats {\n number?: {\n [styleName: string]: Intl.NumberFormatOptions;\n };\n date?: {\n [styleName: string]: Intl.DateTimeFormatOptions;\n };\n time?: {\n [styleName: string]: Intl.DateTimeFormatOptions;\n };\n}\n\ntype StoreEvent = 'added' | 'removed';\n\ninterface CachedMessage {\n lng: string;\n ns: string;\n source: string;\n fc: IntlMessageFormat;\n}\n\nexport interface IcuConfig {\n memoize?: boolean;\n memoizeFallback?: boolean;\n /** Maximum compiled messages per instance. Defaults to 1000; 0 disables this cache, Infinity disables eviction. */\n maxCacheSize?: number;\n /** Maximum shared Intl formatters per instance. Defaults to 100; 0 disables this cache, Infinity disables eviction. */\n maxFormatterCacheSize?: number;\n formats?: IcuFormats;\n bindI18n?: string;\n /** Space-separated resource-store events. Defaults to 'added removed'. */\n bindI18nStore?: '' | StoreEvent | 'added removed' | 'removed added';\n localeData?: any;\n parseErrorHandler?: (err: Error, key: string, res: string, options: object) => string;\n parseLngForICU?: (lng: string) => string;\n}\n\nfunction getDefaults(): IcuConfig {\n return {\n memoize: true,\n memoizeFallback: false,\n maxCacheSize: 1000,\n maxFormatterCacheSize: 100,\n bindI18n: '',\n bindI18nStore: 'added removed',\n parseErrorHandler: (_err, _key, res) => {\n return res;\n },\n };\n}\n\n/**\n * Copied from original ICU source code.\n * @source https://github.com/i18next/i18next-icu/blob/7809547c821a7ef3b2bb9ab2610cdbbcfedcb2f9/src/index.js\n *\n * It's done in order to support `IntlMessageFormat` out of the box.\n * `IntlMessageFormat` is adding formatters that are not provided by i18n.\n * For example, `select` formatter - https://formatjs.io/docs/core-concepts/icu-syntax#select-format\n * It allows to use following translation value: 'Welcome back{inputData, select, 0 {} 1 {, John}}'\n * See example in tests: __tests__/i18n.spec.tsx\n */\nclass ICU {\n options: IcuConfig | undefined;\n formats: IcuFormats | undefined;\n type: string;\n private cacheRoot = new Map<string, CachedMessage>();\n private formatterCache = new Map<\n string,\n Intl.NumberFormat | Intl.DateTimeFormat | Intl.PluralRules\n >();\n private unbindEvents?: () => void;\n private formatters: Formatters = {\n getNumberFormat: (...args) => this.getFormatter('number', Intl.NumberFormat, args),\n getDateTimeFormat: (...args) => this.getFormatter('dateTime', Intl.DateTimeFormat, args),\n getPluralRules: (...args) => this.getFormatter('pluralRules', Intl.PluralRules, args),\n };\n\n constructor(options: IcuConfig) {\n this.type = 'i18nFormat';\n\n this.init(null, options);\n }\n\n init(i18next: i18n | null, options: IcuConfig) {\n const i18nextOptions = (i18next && i18next.options && i18next.options.i18nFormat) || {};\n this.options = defaults(i18nextOptions, options, this.options || {}, getDefaults());\n for (const name of ['maxCacheSize', 'maxFormatterCacheSize'] as const) {\n const limit = this.options![name]!;\n if (limit !== Infinity && (!Number.isSafeInteger(limit) || limit < 0)) {\n throw new RangeError(`${name} must be a non-negative safe integer or Infinity`);\n }\n }\n this.formats = this.options?.formats;\n this.unbindEvents?.();\n this.unbindEvents = undefined;\n this.clearCache();\n\n if (i18next) {\n const { bindI18n, bindI18nStore } = this.options!;\n\n // @ts-expect-error fix later\n i18next.IntlMessageFormat = IntlMessageFormat;\n // @ts-expect-error fix later\n i18next.ICU = this;\n\n // Resources can only stale compiled messages, never the shared Intl formatters.\n const clearAll = () => this.clearMessages();\n // Store events report the (lng, ns) that changed, so only that much needs dropping.\n const clearChanged = (lng: string, ns: string) => this.clearNamespace(lng, ns);\n const store = i18next.store;\n const i18nEvents = bindI18n ? bindI18n.split(' ') : [];\n const storeEvents = bindI18nStore ? (bindI18nStore.split(' ') as StoreEvent[]) : [];\n for (const event of i18nEvents) i18next.on(event, clearAll);\n for (const event of storeEvents) store.on(event, clearChanged);\n this.unbindEvents = () => {\n for (const event of i18nEvents) i18next.off(event, clearAll);\n for (const event of storeEvents) store.off(event, clearChanged);\n };\n }\n\n if (this.options?.localeData) {\n if (Object.prototype.toString.apply(this.options.localeData) === '[object Array]') {\n this.options.localeData.forEach((ld: any) => this.addLocaleData(ld));\n } else {\n this.addLocaleData(this.options.localeData);\n }\n }\n }\n\n addLocaleData(data: any) {\n const locales = Array.isArray(data) ? data : [data];\n\n locales.forEach((localeData) => {\n if (localeData && localeData.locale) {\n // Undeclared legacy escape hatch on IntlMessageFormat.\n (IntlMessageFormat as any)['__addLocaleData'](localeData);\n }\n });\n }\n\n addUserDefinedFormats(formats: IcuFormats) {\n this.formats = this.formats ? { ...this.formats, ...formats } : formats;\n // Compiled messages capture `formats`; formatters are keyed by their resolved options.\n this.clearMessages();\n }\n\n parse(\n res: string,\n options: Record<string, any>,\n lng: string,\n ns: string,\n key: string,\n info: any,\n ) {\n // An undefined key means caching is off.\n const cacheKey =\n this.options?.memoize && this.options.maxCacheSize! > 0\n ? JSON.stringify([lng, ns, key])\n : undefined;\n\n let fc: IntlMessageFormat | undefined;\n if (cacheKey !== undefined) {\n const cached = this.cacheRoot.get(cacheKey);\n // A changed source must be recompiled even when no invalidation event fired.\n if (cached?.source === res) {\n fc = cached.fc;\n this.touch(cacheKey, cached);\n }\n }\n\n try {\n if (!fc) {\n fc = new IntlMessageFormat(res, lng, this.formats, { formatters: this.formatters });\n if (\n cacheKey !== undefined &&\n (this.options!.memoizeFallback || !info || info.resolved?.res)\n ) {\n this.touch(cacheKey, { lng, ns, source: res, fc });\n if (this.cacheRoot.size > this.options!.maxCacheSize!) {\n this.cacheRoot.delete(this.cacheRoot.keys().next().value!);\n }\n }\n }\n\n return fc.format(options);\n } catch (err) {\n return this.options?.parseErrorHandler?.(err as Error, key, res, options);\n }\n }\n\n addLookupKeys(finalKeys: any) {\n // no additional keys needed for select or plural\n // so there is no need to add keys to that finalKeys array\n return finalKeys;\n }\n\n /** Drops compiled messages, keeping the shared Intl formatters. */\n clearMessages() {\n this.cacheRoot.clear();\n }\n\n /** Drops compiled messages and the shared Intl formatters. */\n clearCache() {\n this.clearMessages();\n this.formatterCache.clear();\n }\n\n private clearNamespace(lng: string, ns: string) {\n for (const [cacheKey, entry] of this.cacheRoot) {\n if (entry.lng === lng && entry.ns === ns) this.cacheRoot.delete(cacheKey);\n }\n }\n\n /** Re-inserts to mark most recently used: Map.set keeps an existing key's position. */\n private touch(cacheKey: string, entry: CachedMessage) {\n this.cacheRoot.delete(cacheKey);\n this.cacheRoot.set(cacheKey, entry);\n }\n\n private getFormatter<\n T extends Intl.NumberFormat | Intl.DateTimeFormat | Intl.PluralRules,\n Args extends unknown[],\n >(type: string, Formatter: new (...args: Args) => T, args: Args): T {\n if (!this.options?.memoize || this.options.maxFormatterCacheSize === 0) {\n return new Formatter(...args);\n }\n\n const [locales, options] = args;\n // Equivalent option objects should share a formatter regardless of property order.\n const key = JSON.stringify([\n type,\n locales,\n // oxlint-disable-next-line no-array-sort -- Object.entries already returns a fresh array\n Object.entries(options ?? {}).sort(([a], [b]) => (a < b ? -1 : a > b ? 1 : 0)),\n ]);\n const cached = this.formatterCache.get(key);\n if (cached) {\n this.formatterCache.delete(key);\n this.formatterCache.set(key, cached);\n return cached as T;\n }\n\n const formatter = new Formatter(...args);\n this.formatterCache.set(key, formatter);\n if (this.formatterCache.size > this.options!.maxFormatterCacheSize!) {\n this.formatterCache.delete(this.formatterCache.keys().next().value!);\n }\n return formatter;\n }\n}\n\n// @ts-expect-error fix it later\nICU.type = 'i18nFormat';\n\nexport default ICU;\n\n/** Fills only the keys `obj` leaves undefined, so explicit `undefined` never clobbers a default. */\nfunction defaults(obj: IcuConfig, ...sources: (IcuConfig | undefined)[]): IcuConfig {\n const target = obj as Record<string, unknown>;\n for (const source of sources) {\n if (!source) continue;\n for (const [key, value] of Object.entries(source)) {\n if (target[key] === undefined) target[key] = value;\n }\n }\n return obj;\n}\n"],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@wix/fed-cli-i18next",
3
- "version": "1.6.39",
3
+ "version": "1.6.41",
4
4
  "files": [
5
5
  "dist"
6
6
  ],
@@ -39,13 +39,13 @@
39
39
  "@wix/fed-cli-oxlint": "1.0.0",
40
40
  "@wix/fed-cli-rolldown": "1.0.0",
41
41
  "oxfmt": "^0.58.0",
42
- "oxlint": "^1.83.0",
42
+ "oxlint": "^1.85.0",
43
43
  "react": "^18.3.1",
44
44
  "react-dom": "^18.3.1",
45
- "rolldown": "^1.2.8",
45
+ "rolldown": "^1.2.9",
46
46
  "typescript": "^6.0.3",
47
47
  "vite": "^8.3.0",
48
- "vitest": "^5.0.1"
48
+ "vitest": "^5.0.3"
49
49
  },
50
50
  "peerDependencies": {
51
51
  "react": "^16 || ^17 || ^18 || ^19",
@@ -63,5 +63,5 @@
63
63
  ]
64
64
  }
65
65
  },
66
- "falconPackageHash": "7c42d4636b98d37c7df2db317a06976a220ca263845980c2c63d12d0"
66
+ "falconPackageHash": "9bd5e204f34041135d4c23169eb61a382acc3c708819935b56070f63"
67
67
  }