import { R as Register, B as BhashaConfig, a as BhashaKey, N as NumberFormatOptions, C as CurrencyFormatOptions, D as DateFormatOptions } from './server-C5oZ0yN_.mjs'; export { b as BhashaKeyRegistry, L as LANGUAGES, c as LangInfo, d as REGION_OVERRIDES, f as formatCurrency, e as formatDate, g as formatNumber, h as getFallbackChain, i as getLangInfo, j as getPluralCategory, r as resolveRegion } from './server-C5oZ0yN_.mjs'; type ClientOptions = { persistCache?: boolean; }; declare class TranslationClient { private projectId; private apiUrl; private apiToken; private projectKey; private persistCache; private onBundleUpdate?; /** * Cache structure: keyed by `${lang}:${register}`, mapping to a flat * Record. So: * cache["hi:default"] = { "hero.title": "स्वागत" } * cache["hi:casual"] = { "hero.title": "Welcome है" } * Once a (lang, register) bundle is fetched, it stays in the cache for the * lifetime of the app. */ private cache; /** * Voice cache, parallel to `cache` but per-(lang, register, key) holding * { ipa, ssml }. Populated lazily by `fetchVoice` — populated only when * the developer enables voice mode or calls `formatPhonetic` / `formatSSML` * before the first paint. */ private voiceCache; /** * Tracks which (lang, register) bundles are currently being fetched. * Prevents duplicate API calls if a component renders twice * before the first fetch completes (React Strict Mode does this). */ private fetchPromises; /** In-flight voice-bundle fetches, indexed the same way as fetchPromises. */ private voiceFetchPromises; /** List of supported languages, fetched from the project endpoint */ private supportedLangs; constructor(projectId: string, apiUrl: string, apiToken: string, projectKey?: string, options?: ClientOptions); /** Whether this client uses the public SDK endpoints (API key auth) */ private get usePublicEndpoints(); /** * Load preloaded translations into the cache. * Accepts both shapes for backwards compat: * 1. Flat (legacy): { "hi": { "hero.title": "स्वागत" } } * → loaded into the "default" register. * 2. Nested: { "hi": { "default": { "hero.title": "स्वागत" }, * "casual": { "hero.title": "Welcome है" } } } */ preload(translations: Record | Partial>>>): void; /** * Set the list of supported languages. * Called by the provider after fetching project info. */ setSupportedLangs(langs: string[]): void; setOnBundleUpdate(fn?: (() => void) | null): void; getSupportedLangs(): string[]; /** * Fetch translations for a specific (language, register) bundle from the API. * * HOW IT WORKS: * 1. Check if the bundle is already in cache → return immediately * 2. Check if a fetch is already in progress → wait for that one * 3. Otherwise, make the API call, cache the result, return it * * The API endpoint GET /api/sdk/translations?lang=hi®ister=casual * returns flat JSON: { "hero.title": "Welcome है" } — already collapsed * server-side with default-register fallback baked in. */ fetchTranslations(lang: string, register?: Register): Promise>; private refreshTranslationsInBackground; private persistedStorageKey; private persistedLangsKey; private readPersistedLangs; private writePersistedLangs; private readPersistedBundle; private writePersistedBundle; /** * Fetch the voice bundle for a (lang, register). Same auth model as * `fetchTranslations`, separate endpoint. Cached so future calls are * instant. Errors propagate so the provider can expose them. */ fetchVoice(lang: string, register?: Register): Promise>; /** * Look up voice data for a key, walking the same fallback chain as * `translate()` — register-then-language. Returns undefined if no voice * bundle has been loaded for any matching (lang, register). */ getVoice(key: string, lang: string, register?: Register): { ipa: string; ssml: string; } | undefined; /** * Preload voice data into the cache. Useful for SSR or bundling voice with * the app. Accepts the same shape as the API response. */ preloadVoice(voice: Record>>>): void; /** * Fetch project info to get the list of supported languages. * Throws on auth/network failure so the provider can surface the error. */ fetchProjectInfo(): Promise; /** * THE CORE FUNCTION — Translate a key. * * How fallback works: * 1. Try the requested (lang, register) bundle. * 2. If empty, try the same lang at "default" register. * 3. If still empty, walk the language fallback chain at "default". * First match wins. * * PLURALIZATION: * If params contains a "count" key, we automatically resolve the * correct plural form using CLDR rules for the language. * * @param key - The translation key (e.g. "hero.title") * @param lang - The current language code (e.g. "bn") * @param register - The current register ("default" | "formal" | "casual") * @param params - Optional interpolation values (e.g. { name: "Rohan" }) */ translate(key: string, lang: string, register?: Register, params?: Record): string; } interface BhashaState { /** Active language code (e.g. "hi", "bn", "ne-Latn"). */ lang: string; /** Active register ("default" | "formal" | "casual"). */ register: Register; /** Languages this project supports. */ supportedLangs: string[]; /** True while a (lang, register) bundle is being fetched. */ isLoading: boolean; /** Error message from the last failed init/switch, or null. */ error: string | null; /** Active user segment label, if set. */ segment?: string; } type Unsubscribe = () => void; type Listener = (state: BhashaState) => void; declare class BhashaStore { private client; private state; private listeners; private region?; private voiceEnabled; private segmentRules?; private applyDocument; private onLanguageChange?; private localeReq; private pendingLang; private pendingRegister; constructor(config?: BhashaConfig & { applyDocument?: boolean; }); /** Current state snapshot. Returns a shallow copy so a consumer (or a * framework adapter) mutating it can't poison canonical state — all real * changes must go through `emit`. */ getState(): BhashaState; /** Escape hatch to the underlying client (cache, voice, preload). */ getClient(): TranslationClient; /** Subscribe to state changes. Returns an unsubscribe function. */ subscribe(fn: Listener): Unsubscribe; private emit; /** * Fetch project info (unless preloaded) and the initial (lang, register) * bundle. Call this exactly once, before any setLang/setRegister — init() is * not request-guarded, so a switch racing the initial load is undefined. */ init(): Promise; /** Translate a key in the current (lang, register). */ t(key: BhashaKey, params?: Record): string; /** * Fetch and commit the CURRENT pending (lang, register) target atomically. * * Every switch sets `pendingLang`/`pendingRegister` first, then calls this. * We snapshot the pending pair, fetch THAT exact bundle (+ the English and * default-register fallbacks + voice), and — guarded by the single shared * counter — commit both dimensions together. Because the snapshot is taken * from the pending target (not committed state), an interleaved * setLang+setRegister fetches the real final pair, never a stale half-state. * Last-requested wins; superseded requests bail without touching state. */ private applyLocale; /** Switch language. Updates the pending target, then applies the locale. */ setLang(newLang: string): Promise; /** Switch register. Updates the pending target, then applies the locale. */ setRegister(newRegister: Register): Promise; /** Set the user segment; flips register (via the same atomic path) if a * segmentRule matches. */ setSegment(newSegment: string): Promise; formatNumber(value: number, options?: NumberFormatOptions): string; formatCurrency(value: number, options?: CurrencyFormatOptions): string; formatDate(date: Date | string | number, options?: DateFormatOptions): string; formatPhonetic(key: string): string; formatSSML(key: string): string; } /** Convenience: construct a store and run init() before resolving. */ declare function createBhashaStore(config?: BhashaConfig & { applyDocument?: boolean; }): Promise; /** * Load the appropriate Google Font for a language. * Does nothing if the font is already loaded. * * @param lang - Language code (e.g. "hi", "bn", "ur") */ declare function loadFontForLang(lang: string): void; /** * Preload fonts for multiple languages at once. * Call this at app startup if you know which languages you'll need. */ declare function preloadFonts(langs: string[]): void; export { BhashaConfig, BhashaKey, type BhashaState, BhashaStore, CurrencyFormatOptions, DateFormatOptions, NumberFormatOptions, Register, TranslationClient, type Unsubscribe, createBhashaStore, loadFontForLang, preloadFonts };