SDK i klijenti
Ovde se dve različite stvari zovu SDK i rešavaju različite probleme.
- Klijenti za izvršavanje preuzimaju prevode iz OTA paketa i razrešavaju ključeve u vašoj aplikaciji. Postoje za Go, Rust i NestJS.
- Pregledački SDK ne preuzima ništa: on označava DOM elemente ključem iz kog su nastali, da bi Chrome ekstenzija mogla da prikaže i izmeni prevod preko vašeg proizvoda dok radi.
Klijenti za izvršavanje
heading.anchorLabelSva tri rade isto: uperite ih na izvor, oni ga učitaju u memoriju, osvežavaju u pozadini na svakih pet minuta i razrešavaju ključ po imenskom prostoru i lokalu.
Dostupna su dva izvora:
- OTA — jedan ili više objavljenih paketa, adresiranih pristupnim ključem. Svakom paketu se može dati prefiks, koji postaje njegov imenski prostor; više paketa sa istim prefiksom se spaja, a pri sudaru ključeva poslednji pobeđuje.
- Map — mapa prevoda projekta, adresirana identifikatorom projekta i API ključem. Tu ime fajla postaje imenski prostor.
go get github.com/OwnLate/go-clientclient, err := ownlate.New(ownlate.Config{ Source: ownlate.OTASource{Bundles: []ownlate.OTABundle{{AccessKey: accessKey}}}, Locale: "sr",})if err != nil { return err}defer client.Close()
client.Start(ctx)<-client.Ready()
client.T("notification.title", "en_US")client.Translate("emails", "greeting", map[string]any{"name": "Roman"}, "sr")Start osvežava u pozadini i ponavlja pokušaje pri neuspehu; Load radi jedno učitavanje i vraća grešku.
[dependencies]ownlate = { git = "https://github.com/OwnLate/rust-client" }let client = ownlate::Client::ota(access_key, "en_US")?;
let refresh = client.start();client.ready().await;
client.t("notification.title", "en_US");client.translate("emails", "subject", Some(&json!({ "plan": "Pro" })), "en_US");Client se jeftino klonira — svi klonovi dele iste prevode i isti zadatak osvežavanja. Ako se vraćeni handle odbaci, osvežavanje prestaje.
NestJS
heading.anchorLabelnpm install @globalart/ownlate-nestjs-translatorModul obavija isto ponašanje za Nest aplikaciju: učitava paket pri pokretanju i osvežava ga u pozadini.
Kako se ključ razrešava
heading.anchorLabelKlijenti se slažu oko pravila, i zato je nedostajući prevod bezopasan:
- Lokal dolazi iz poziva, inače iz konfiguracije klijenta.
- Traži se imenski prostor; za OTA izvor nepoznat prostor svodi se na podrazumevani paket.
- Nedostajući lokal zamenjuje se lokalom istog jezika —
en_USdosežeeni obrnuto — a ako ni to ne uspe, prvim po abecedi, pa izbor ostaje stabilan između poziva. - Nepoznat ključ vraća se onakav kakav je zatražen, nikad kao prazan tekst.
- Zamene oblika
{{name}}popunjavaju se prosleđenim vrednostima.
Oba klijenta čitaju snimak pod bravom i pri osvežavanju menjaju ceo snimak, pa ih je bezbedno deliti između gorutina i zadataka.
Pregledački SDK
heading.anchorLabel@ownlate/sdk označava DOM. On je ono što vašu aplikaciju u radu pretvara u nešto što prevodilac može da menja na licu mesta.
npm install @ownlate/sdkimport { init, wrapT } from '@ownlate/sdk'
init({ projectId: 'your-project-id', workspaceId: 'your-workspace-id', apiKey: 'sdk_…', apiUrl: 'https://api.ownlate.com',})Obavijte svoju i18n funkciju jednom i svaki tekst koji ona iscrta biva označen:
import { useTranslation } from 'react-i18next'import { wrapT } from '@ownlate/sdk'
function Title() { const { t: rawT } = useTranslation() const t = wrapT(rawT)
return <h1>{t('home.title')}</h1>}| Izvoz | Potpis | Šta radi |
|---|---|---|
init | (config) => void | Pokreće SDK. Poziva se jednom. |
wrapT | (t) => t | Obavija i18n t() tako da se iscrtani čvorovi označavaju |
annotateElement | (el, key) => void | Ručno označava čvor |
onTranslationUpdate | (cb) => unsubscribe | Reaguje na izmenu napravljenu u ekstenziji |
destroy | () => void | Uklanja slušaoce i vraća početno stanje |
annotateElement koristite tamo gde wrapT ne vidi čvor — placeholder, aria-label, atribut title:
annotateElement(document.querySelector('#search'), 'search.placeholder')I primenjujte izmene uživo, bez osvežavanja:
onTranslationUpdate(({ key, value, lang }) => { i18next.addResource(lang, 'translation', key, value)})Kako se sve uklapa
heading.anchorLabelinit()se javlja prekopostMessage, što hvata content script ekstenzije.wrapT()iannotateElement()postavljaju čvorovima atributdata-ownlate-key.- Ekstenzija čita te atribute i prikazuje odgovarajuće segmente u bočnom panelu.
- Izmena u panelu čuva se kao nacrt na segmentu i šalje nazad na stranicu, pa se interfejs odmah ažurira.
Pošto izmene padaju kao nacrti, uređivanje na licu mesta nikad ne zaobilazi recenziju.
SDK tokeni
heading.anchorLabelPregledački SDK se autentifikuje SDK tokenom, ne API ključem. Tokeni se prave po projektu na kartici SDK, i svaki:
- prikazuje se jednom, pri kreiranju, a posle samo prefiksom;
- doseže tačno jedan projekat — onaj za koji je napravljen;
- ume da čita segmente po ključu i čuva nacrte prevoda, i ništa više;
- beleži kada je poslednji put korišćen i može se opozvati bilo kada.
Ta uskost je poenta: token putuje u pregledačkom paketu, pa ne sme da može ništa što vam ne bi bilo svejedno da uradi neko sa strane.