🔀 Multi-provider Architecture

Translation is no longer coupled to a single endpoint. A TranslateProvider interface now abstracts each backend, making it easy to add or swap providers without touching the UI layer:

  • Providers are registered in a central map and exposed to the UI through TRANSLATE_PROVIDERS.
  • The user selects a provider from a dropdown in the form; the choice persists in localStorage.
  • If a provider fails mid-route, the user can switch to another provider and resume from the failed round without re-running successful steps.
  • Adding a new provider requires only implementing the TranslateProvider interface and registering it in PROVIDERS + TRANSLATE_PROVIDERS.

🆕 MyMemory Provider

A new MyMemory provider is now available alongside Google Translate:

  • Powered by the MyMemory free translation memory API — no API key required and CORS wide open (*).
  • Ideal as a fallback when Google’s free endpoints hit rate limits or region restrictions.
  • Handles the auto source-language case by passing autodetect to the API.
  • Shares the same retry and backoff logic as all providers.

Note: MyMemory has a per-IP daily character quota (~5 000 chars) and translation quality depends on memory hits; less common language pairs may return untranslated or partially translated text. Microsoft/Bing endpoints (require credentials or lack CORS) and Baidu/DeepL (require keys) cannot be called from the browser and are not included.

🛡️ Resilient Translation Pipeline

The shared fetchWithRetry utility now underpins every provider:

  • Exponential backoff with jitter across up to 3 attempts per endpoint.
  • Retryable HTTP status codes: 0 (network), 403, 429, 500, 502, 503, 504.
  • Google’s three endpoint hosts rotate automatically before giving up.
  • Structured TranslateError with machine-readable codes (network_error, api_error, empty_result, unavailable) map to localized UI messages.

⏩ Resume-from-Failure

When a translation round fails:

  • Completed rounds are preserved in the UI.
  • A “Resume” button appears, letting the user switch providers and continue from the exact round that failed.
  • History is only saved on full completion, so partial runs don’t clutter the list.

🌍 UI and Localization

  • A provider selector dropdown has been added to the translation form.
  • New localized message keys: provider.google, provider.mymemory, status.providerFailed, status.providerSwitched.
  • All six supported locales have been updated with the new strings.