UNPKG

everything-dev

Version:

A consolidated product package for building Module Federation apps with oRPC APIs.

1 lines • 9.6 kB
{"version":3,"file":"i18n.cjs","names":["createContext","resolveLocale","matchLocale","useContext","useMemo","useSyncExternalStore","setupI18n","serializeLocaleCookie","useCallback","I18nProvider","useLingui"],"sources":["../../src/ui/i18n.tsx"],"sourcesContent":["import { type Messages, setupI18n } from \"@lingui/core\";\nimport { I18nProvider, useLingui } from \"@lingui/react\";\nimport {\n createContext,\n type ReactNode,\n useCallback,\n useContext,\n useEffect,\n useMemo,\n useSyncExternalStore,\n} from \"react\";\nimport { matchLocale, resolveLocale, serializeLocaleCookie } from \"./locale\";\n\nexport { Trans } from \"@lingui/react\";\nexport type { LocaleOptions } from \"./locale\";\nexport {\n matchLocale,\n readAcceptLanguage,\n readLocaleCookie,\n resolveLocale,\n serializeLocaleCookie,\n} from \"./locale\";\nexport { createMessageCatalogs } from \"./message-catalogs\";\n\ntype SharedLocaleState = {\n cookieName: string;\n locale: string;\n selectLocale: (locale: string) => Promise<void>;\n};\n\nconst SharedLocaleContext = createContext<SharedLocaleState | null>(null);\n\ntype LocaleStore = {\n get: () => string;\n set: (locale: string) => void;\n subscribe: (listener: () => void) => () => void;\n};\n\nconst browserStores = new Map<string, LocaleStore>();\n\nfunction createLocaleStore(initialLocale: string): LocaleStore {\n let locale = initialLocale;\n const listeners = new Set<() => void>();\n return {\n get: () => locale,\n set: (nextLocale) => {\n if (nextLocale === locale) return;\n locale = nextLocale;\n for (const listener of listeners) listener();\n },\n subscribe: (listener) => {\n listeners.add(listener);\n return () => listeners.delete(listener);\n },\n };\n}\n\nexport function createLocaleRuntime<const Locale extends string>({\n locales,\n defaultLocale,\n cookieName,\n}: {\n locales: readonly Locale[];\n defaultLocale: Locale;\n cookieName: string;\n}) {\n type ContextValue = {\n locale: Locale;\n selectLocale: (locale: Locale) => Promise<void>;\n };\n\n const LocaleContext = createContext<ContextValue | null>(null);\n\n const getBrowserLocales = (): readonly string[] => {\n if (typeof navigator === \"undefined\") return [];\n if (Array.isArray(navigator.languages)) return navigator.languages;\n return navigator.language ? [navigator.language] : [];\n };\n\n const detectLocale = (preferredLocale?: string | null): Locale =>\n resolveLocale({\n preferredLocale,\n cookie: typeof document === \"undefined\" ? \"\" : document.cookie,\n browserLocales: getBrowserLocales(),\n locales,\n defaultLocale,\n cookieName,\n });\n\n const getStore = (initialLocale?: string | null) => {\n const initial = matchLocale(initialLocale, locales) ?? detectLocale();\n if (typeof window === \"undefined\") return createLocaleStore(initial);\n const existing = browserStores.get(cookieName);\n if (existing) return existing;\n const store = createLocaleStore(initial);\n browserStores.set(cookieName, store);\n return store;\n };\n\n function LocaleProvider({\n children,\n messages,\n initialLocale,\n preferredLocale,\n onLocaleChange,\n }: {\n children: ReactNode;\n messages: (locale: Locale) => Messages;\n initialLocale?: string | null;\n preferredLocale?: string | null;\n onLocaleChange?: (locale: Locale) => void | Promise<void>;\n }) {\n const parent = useContext(SharedLocaleContext);\n const sharedParent = parent?.cookieName === cookieName ? parent : null;\n const resolvedInitial =\n matchLocale(preferredLocale, locales) ??\n matchLocale(initialLocale, locales) ??\n matchLocale(sharedParent?.locale, locales);\n const serverLocale = resolvedInitial ?? defaultLocale;\n const store = useMemo(() => getStore(resolvedInitial), []);\n const locale = useSyncExternalStore(store.subscribe, store.get, () => serverLocale) as Locale;\n const i18n = useMemo(\n () => setupI18n({ locale, messages: { [locale]: messages(locale) } }),\n [locale, messages],\n );\n\n useEffect(() => {\n if (sharedParent) return;\n const resolved = matchLocale(preferredLocale, locales);\n if (resolved) {\n Reflect.set(\n document,\n \"cookie\",\n serializeLocaleCookie(cookieName, resolved, window.location.protocol === \"https:\"),\n );\n store.set(resolved);\n }\n }, [preferredLocale, sharedParent, store]);\n\n useEffect(() => {\n if (sharedParent) return;\n const previousLocale = document.documentElement.lang;\n document.documentElement.lang = locale;\n return () => {\n document.documentElement.lang = previousLocale;\n };\n }, [locale, sharedParent]);\n\n const selectLocale = useCallback(\n async (nextLocale: Locale) => {\n if (!locales.includes(nextLocale)) return;\n if (sharedParent && !onLocaleChange) {\n await sharedParent.selectLocale(nextLocale);\n return;\n }\n if (onLocaleChange) await onLocaleChange(nextLocale);\n if (typeof document !== \"undefined\") {\n Reflect.set(\n document,\n \"cookie\",\n serializeLocaleCookie(\n cookieName,\n nextLocale,\n typeof window !== \"undefined\" && window.location.protocol === \"https:\",\n ),\n );\n }\n store.set(nextLocale);\n },\n [onLocaleChange, sharedParent, store],\n );\n\n const value = useMemo(() => ({ locale, selectLocale }), [locale, selectLocale]);\n const sharedValue = useMemo(\n () => ({\n cookieName,\n locale,\n selectLocale: async (next: string) => {\n const matched = matchLocale(next, locales);\n if (matched) await selectLocale(matched);\n },\n }),\n [locale, selectLocale],\n );\n return (\n <SharedLocaleContext.Provider value={sharedValue}>\n <LocaleContext.Provider value={value}>\n <I18nProvider i18n={i18n}>{children}</I18nProvider>\n </LocaleContext.Provider>\n </SharedLocaleContext.Provider>\n );\n }\n\n function useLocale(): ContextValue {\n const value = useContext(LocaleContext);\n if (!value) throw new Error(\"useLocale must be used within LocaleProvider\");\n return value;\n }\n\n function useTranslation<MessageId extends string>() {\n const { _ } = useLingui();\n return useCallback(\n (id: MessageId, values?: Record<string, string | number>) => _(id, values),\n [_],\n );\n }\n\n const getLocale = (): Locale =>\n matchLocale(browserStores.get(cookieName)?.get(), locales) ?? detectLocale();\n\n return { LocaleProvider, useLocale, useTranslation, detectLocale, getLocale };\n}\n"],"mappings":"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"}