The Go client for OwnLate. A port of
@globalart/ownlate-nestjs-translator:
translations are pulled from an OTA bundle or from the translations map of a
project, kept in memory, refreshed in the background and resolved by namespace,
key and locale.
go get github.com/OwnLate/go-clientclient, err := ownlate.New(ownlate.Config{
Source: ownlate.OTASource{Bundles: []ownlate.OTABundle{{AccessKey: accessKey}}},
Locale: "ru",
})
if err != nil {
return err
}
defer client.Close()
client.Start(ctx) // refresh in the background every five minutes
<-client.Ready() // the first successful load
client.T("notification.title", "en_US")
client.Translate("emails", "greeting", map[string]any{"name": "Roman"}, "ru")If the background refresh is not needed, a single client.Load(ctx) replaces
Start: it returns the load error, whereas Start logs it and retries.
OTA — published bundles addressed by access key:
ownlate.OTASource{Bundles: []ownlate.OTABundle{
{AccessKey: emailsKey, Prefix: "emails"},
{AccessKey: pushKey, Prefix: "push"},
}}A bundle without a Prefix lands in the __ota__ namespace (the
ownlate.OTANamespace constant); client.T(key, locale) is the shorthand for
that case. Several bundles sharing a prefix are merged into one namespace, and
the last one wins on colliding keys.
Map — the translations map of a project:
ownlate.MapSource{
ProjectID: "42",
APIKey: apiKey,
FilesMap: map[string]string{"emails.json": "emails"},
}The file name becomes the namespace: either through FilesMap or as the name
itself without the .json suffix.
- The locale comes from the argument, otherwise from
Config.Locale. - The namespace is looked up; for an OTA source an unknown namespace falls back
to
__ota__. - If the requested locale is missing, a locale of the same language is used
(
en_USreachesenand the other way round); failing that, the first locale in alphabetical order, which keeps the choice stable between calls. - An unknown key is returned as is, so a missing translation never leaves an empty string behind.
- Placeholders written as
{{name}}are replaced with the values fromplaceholders.
Config field |
Default | Purpose |
|---|---|---|
Source |
— | OTASource or MapSource, required |
Locale |
empty | the locale Translate uses when the call site passes none |
BaseURL |
https://api.ownlate.com/public/v1 |
API address |
PollInterval |
5 minutes | background refresh period |
RetryInterval |
5 seconds | pause after a failed load |
HTTPClient |
30 second timeout | HTTP client |
Logger |
slog.Default() |
where load failures are reported |
The client is safe for concurrent use: Translate reads a snapshot under an
RWMutex and a refresh replaces that snapshot as a whole.