LiveSvelteGettext.Runtime (LiveSvelteGettext v0.2.0)

View Source

Runtime translation lookup used by the functions LiveSvelteGettext generates.

The use LiveSvelteGettext macro generates thin all_translations/1 and translation_payload/1 wrappers that delegate here. Keeping the real work in a normal module means it can be tested directly, and that upgrading the library does not require recompiling every consumer's Svelte strings module just to pick up a lookup fix.

Summary

Types

A single translation entry.

Functions

The reserved key carrying payload metadata.

The key a plural message is stored under in the translation map.

Builds the translation map for locale.

Types

entry()

@type entry() :: String.t() | %{required(String.t()) => term()}

A single translation entry.

Singular messages map to a string. Plural messages map to a form map - see translations/3.

Functions

metadata_key()

@spec metadata_key() :: String.t()

The reserved key carrying payload metadata.

Nested under a key rather than wrapping the translations so that older JavaScript clients keep working - see payload/3.

payload(backend, extractions, locale)

@spec payload(module(), [LiveSvelteGettext.Extractor.extraction()], String.t()) :: %{
  required(String.t()) => term()
}

Builds the full payload rendered into the page by LiveSvelteGettext.Components.svelte_translations/1.

This is the translation map with the locale and its plural rules added under the reserved "__lsg__" key:

%{
  "Hello" => "Hola",
  "__lsg__" => %{
    "locale" => "es",
    "plural" => %{"nplurals" => 2, "probes" => [[0, 1], [1, 0], ...]}
  }
}

Why the metadata is nested rather than wrapping

The obvious shape would be %{"locale" => ..., "translations" => %{...}}. That silently breaks older clients: they do translations = {...payload} and then look msgids up directly, so every lookup would miss and every string would fall back to its untranslated form - with no error anywhere.

Keeping the msgids at the top level means an old client reading a new payload still finds them, and simply never looks up the extra key. See LiveSvelteGettext.Plurals for how the probe table is used.

plural_key(msgid, msgid_plural)

@spec plural_key(String.t(), String.t()) :: String.t()

The key a plural message is stored under in the translation map.

translations(backend, extractions, locale)

@spec translations(module(), [LiveSvelteGettext.Extractor.extraction()], String.t()) ::
  %{
    required(String.t()) => entry()
  }

Builds the translation map for locale.

Singular messages map to their translated string with %{...} placeholders left intact - interpolation happens in the browser, with the real values.

Plural messages are keyed "msgid|||msgid_plural" and map to:

%{
  "forms" => ["1 elemento", "%{count} elementos"],
  "one" => "1 elemento",
  "other" => "%{count} elementos"
}

"forms" is ordered by gettext plural form index. "one" and "other" are kept for older versions of the JavaScript client, which only understood a two-form split.

Messages with no translation fall back to the original string.