{"version":3,"file":"intl.cjs","names":["Locales","instance: InstanceType<T> | undefined"],"sources":["../../../src/utils/intl.ts"],"sourcesContent":["// Cached Intl helper – drop‑in replacement for the global `Intl` object.\n// ‑‑‑\n// • Uses a `Proxy` to lazily wrap every *constructor* hanging off `Intl` (NumberFormat, DateTimeFormat, …).\n// • Each wrapped constructor keeps an in‑memory cache keyed by `[locales, options]` so that identical requests\n// reuse the same heavy instance instead of reparsing CLDR data every time.\n// • A polyfill warning for `Intl.DisplayNames` is emitted only once and only in dev.\n// • The public API is fully type‑safe and mirrors the native `Intl` surface exactly –\n// you can treat `CachedIntl` just like the built‑in `Intl`.\n//\n// Usage examples:\n// ---------------\n// import { CachedIntl } from \"./cached-intl\";\n//\n// const nf = CachedIntl.NumberFormat(\"en-US\", { style: \"currency\", currency: \"USD\" });\n// console.log(nf.format(1234));\n//\n// const dn = CachedIntl.DisplayNames([\"fr\"], { type: \"language\" });\n// console.log(dn.of(\"en\")); // → \"anglais\"\n//\n// You can also spin up an isolated instance with its own caches (handy in test suites):\n// const TestIntl = createCachedIntl();\n//\n// ---------------------------------------------------------------------\n\nimport { Locales, type LocalesValues } from '@intlayer/types';\n\n// Helper type that picks just the constructor members off `typeof Intl`.\n// The \"capital‑letter\" heuristic is 100 % accurate today and keeps the\n// mapping short‑lived, so we don't have to manually list every constructor.\ntype IntlConstructors = {\n  [K in keyof typeof Intl as (typeof Intl)[K] extends new (\n    ...args: any\n  ) => any\n    ? K\n    : never]: (typeof Intl)[K];\n};\n\n// Type wrapper to replace locale arguments with LocalesValues\ntype ReplaceLocaleWithLocalesValues<T> = T extends new (\n  locales: any,\n  options?: infer Options\n) => infer Instance\n  ? new (\n      locales?: LocalesValues,\n      options?: Options\n    ) => Instance\n  : T extends new (\n        locales: any\n      ) => infer Instance\n    ? new (\n        locales?: LocalesValues\n      ) => Instance\n    : T;\n\n// Wrapped Intl type with LocalesValues\ntype WrappedIntl = {\n  [K in keyof typeof Intl]: K extends keyof IntlConstructors\n    ? ReplaceLocaleWithLocalesValues<(typeof Intl)[K]>\n    : (typeof Intl)[K];\n};\n\n// Generic cache key – JSON.stringify is fine because locale strings are short\n// and option objects are small and deterministic.\nconst cacheKey = (locales: LocalesValues, options: unknown) =>\n  JSON.stringify([locales, options]);\n\n// Generic wrapper for any `new Intl.*()` constructor.\n// Returns a constructable function (usable with or without `new`) that\n// pulls instances from a Map cache when possible.\nconst createCachedConstructor = <T extends new (...args: any[]) => any>(\n  Ctor: T\n) => {\n  const cache = new Map<string, InstanceType<T>>();\n\n  function Wrapped(locales?: LocalesValues, options?: any) {\n    // Special case – guard older runtimes missing DisplayNames.\n    if (\n      Ctor.name === 'DisplayNames' &&\n      typeof (Intl as any)?.DisplayNames !== 'function'\n    ) {\n      if (process.env.NODE_ENV === 'development') {\n        console.warn(\n          [\n            `// Intl.DisplayNames is not supported; falling back to raw locale (${locales}). `,\n            `// Consider adding a polyfill as https://formatjs.io/docs/polyfills/intl-displaynames/`,\n            ``,\n            `import 'intl';`,\n            `import '@formatjs/intl-getcanonicallocales/polyfill';`,\n            `import '@formatjs/intl-locale/polyfill';`,\n            `import '@formatjs/intl-pluralrules/polyfill';`,\n            `import '@formatjs/intl-displaynames/polyfill';`,\n            `import '@formatjs/intl-listformat/polyfill';`,\n            `import '@formatjs/intl-numberformat/polyfill';`,\n            `import '@formatjs/intl-relativetimeformat/polyfill';`,\n            `import '@formatjs/intl-datetimeformat/polyfill';`,\n            ``,\n            `// Optionally add locale data`,\n            `import '@formatjs/intl-pluralrules/locale-data/fr';`,\n            `import '@formatjs/intl-numberformat/locale-data/fr';`,\n            `import '@formatjs/intl-datetimeformat/locale-data/fr';`,\n          ].join('\\n')\n        );\n      }\n      return locales as any;\n    }\n\n    const key = cacheKey(locales ?? Locales.ENGLISH, options);\n    let instance: InstanceType<T> | undefined = cache.get(key);\n\n    if (!instance) {\n      instance = new Ctor(locales as never, options as never);\n      cache.set(key, instance as InstanceType<T>);\n    }\n\n    return instance as InstanceType<T>;\n  }\n\n  // Ensure it behaves like a constructor when used with `new`.\n  (Wrapped as any).prototype = (Ctor as any).prototype;\n\n  return Wrapped as unknown as ReplaceLocaleWithLocalesValues<T>;\n};\n\n// Factory that turns the global `Intl` into a cached clone.\nexport const createCachedIntl = (): WrappedIntl =>\n  new Proxy(Intl as IntlConstructors, {\n    get: (target, prop, receiver) => {\n      const value = Reflect.get(target, prop, receiver);\n\n      // Wrap *only* constructor functions (safest heuristic: they start with a capital letter).\n      return typeof value === 'function' && /^[A-Z]/.test(String(prop))\n        ? createCachedConstructor(value)\n        : value;\n    },\n  }) as unknown as WrappedIntl;\n\n// Singleton – import this in application code if you just want shared caches.\nexport const CachedIntl = createCachedIntl();\n\n// new CachedIntl.DisplayNames(Locales.FRENCH, { type: 'language' });\n// new CachedIntl.DisplayNames('fr', { type: 'language' });\n// new CachedIntl.DateTimeFormat('fr', {\n// year: 'numeric',\n// month: 'long',\n// day: 'numeric',\n// });\n// new CachedIntl.NumberFormat('fr', {\n// style: 'currency',\n// currency: 'EUR',\n// });\n// new CachedIntl.Collator('fr', { sensitivity: 'base' });\n// new CachedIntl.PluralRules('fr');\n// new CachedIntl.RelativeTimeFormat('fr', { numeric: 'auto' });\n// new CachedIntl.ListFormat('fr', { type: 'conjunction' });\n\nexport { CachedIntl as Intl };\n"],"mappings":";;;;AA+DA,MAAM,YAAY,SAAwB,YACxC,KAAK,UAAU,CAAC,SAAS,QAAQ,CAAC;AAKpC,MAAM,2BACJ,SACG;CACH,MAAM,wBAAQ,IAAI,KAA8B;CAEhD,SAAS,QAAQ,SAAyB,SAAe;AAEvD,MACE,KAAK,SAAS,kBACd,OAAQ,MAAc,iBAAiB,YACvC;AACA,OAAI,QAAQ,IAAI,aAAa,cAC3B,SAAQ,KACN;IACE,sEAAsE,QAAQ;IAC9E;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACD,CAAC,KAAK,KAAK,CACb;AAEH,UAAO;;EAGT,MAAM,MAAM,SAAS,WAAWA,yBAAQ,SAAS,QAAQ;EACzD,IAAIC,WAAwC,MAAM,IAAI,IAAI;AAE1D,MAAI,CAAC,UAAU;AACb,cAAW,IAAI,KAAK,SAAkB,QAAiB;AACvD,SAAM,IAAI,KAAK,SAA4B;;AAG7C,SAAO;;AAIT,CAAC,QAAgB,YAAa,KAAa;AAE3C,QAAO;;AAIT,MAAa,yBACX,IAAI,MAAM,MAA0B,EAClC,MAAM,QAAQ,MAAM,aAAa;CAC/B,MAAM,QAAQ,QAAQ,IAAI,QAAQ,MAAM,SAAS;AAGjD,QAAO,OAAO,UAAU,cAAc,SAAS,KAAK,OAAO,KAAK,CAAC,GAC7D,wBAAwB,MAAM,GAC9B;GAEP,CAAC;AAGJ,MAAa,aAAa,kBAAkB"}