@better-i18n/expo 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,37 @@
1
+ import type { BackendModule, InitOptions, ReadCallback, Services } from "i18next";
2
+ import type { BetterI18nBackendOptions } from "./types";
3
+ /**
4
+ * i18next backend plugin for better-i18n CDN with offline caching.
5
+ *
6
+ * Implements a network-first strategy:
7
+ * 1. Check in-memory cache (TtlCache) — avoids redundant fetches within a session
8
+ * 2. Fetch from CDN — always get fresh translations
9
+ * 3. On CDN failure, fall back to persistent cache (AsyncStorage)
10
+ *
11
+ * @example
12
+ * ```ts
13
+ * import i18n from 'i18next';
14
+ * import { BetterI18nBackend } from '@better-i18n/expo';
15
+ *
16
+ * i18n.use(BetterI18nBackend).init({
17
+ * backend: { project: 'acme/my-app' },
18
+ * lng: 'en',
19
+ * fallbackLng: 'en',
20
+ * });
21
+ * ```
22
+ */
23
+ export declare class BetterI18nBackend implements BackendModule<BetterI18nBackendOptions> {
24
+ static type: "backend";
25
+ type: "backend";
26
+ private core;
27
+ private storage;
28
+ private memoryCache;
29
+ private cacheExpiration;
30
+ private project;
31
+ private debug;
32
+ init(_services: Services, backendOptions: BetterI18nBackendOptions, _i18nextOptions: InitOptions): void;
33
+ read(language: string, namespace: string, callback: ReadCallback): void;
34
+ private loadTranslations;
35
+ private log;
36
+ }
37
+ //# sourceMappingURL=backend.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"backend.d.ts","sourceRoot":"","sources":["../src/backend.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EACV,aAAa,EAEb,WAAW,EACX,YAAY,EACZ,QAAQ,EACT,MAAM,SAAS,CAAC;AAEjB,OAAO,KAAK,EAAE,wBAAwB,EAAsB,MAAM,SAAS,CAAC;AA8C5E;;;;;;;;;;;;;;;;;;;GAmBG;AACH,qBAAa,iBAAkB,YAAW,aAAa,CAAC,wBAAwB,CAAC;IAC/E,MAAM,CAAC,IAAI,EAAG,SAAS,CAAU;IACjC,IAAI,EAAG,SAAS,CAAU;IAE1B,OAAO,CAAC,IAAI,CAAY;IACxB,OAAO,CAAC,OAAO,CAAsB;IACrC,OAAO,CAAC,WAAW,CAA4B;IAC/C,OAAO,CAAC,eAAe,CAA+B;IACtD,OAAO,CAAC,OAAO,CAAM;IACrB,OAAO,CAAC,KAAK,CAAS;IAEtB,IAAI,CACF,SAAS,EAAE,QAAQ,EACnB,cAAc,EAAE,wBAAwB,EACxC,eAAe,EAAE,WAAW,GAC3B,IAAI;IAwBP,IAAI,CAAC,QAAQ,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,QAAQ,EAAE,YAAY,GAAG,IAAI;YAgBzD,gBAAgB;IA2C9B,OAAO,CAAC,GAAG;CAKZ"}
@@ -0,0 +1,131 @@
1
+ import { createI18nCore, TtlCache } from "@better-i18n/core";
2
+ import { readCache, resolveStorage, writeCache } from "./storage";
3
+ const DEFAULT_CACHE_EXPIRATION_MS = 24 * 60 * 60 * 1000; // 24 hours
4
+ /**
5
+ * Extract keys for a specific namespace from the flat CDN response.
6
+ *
7
+ * CDN returns: `{ "common.hero.title": "Welcome", "common.nav.home": "Home" }`
8
+ * i18next expects for namespace "common": `{ "hero.title": "Welcome", "nav.home": "Home" }`
9
+ *
10
+ * If keys are already nested (no namespace prefix), returns the namespace
11
+ * subtree or the full object if namespace doesn't exist as a top-level key.
12
+ */
13
+ function extractNamespace(data, namespace) {
14
+ // Case 1: Data is already nested with namespace as a top-level key
15
+ // e.g. { "common": { "hero": { "title": "..." } } }
16
+ if (namespace in data &&
17
+ typeof data[namespace] === "object" &&
18
+ data[namespace] !== null) {
19
+ return data[namespace];
20
+ }
21
+ // Case 2: Flat keys with namespace prefix ("common.hero.title")
22
+ const prefix = `${namespace}.`;
23
+ const result = {};
24
+ let foundAny = false;
25
+ for (const key in data) {
26
+ if (key.startsWith(prefix)) {
27
+ result[key.slice(prefix.length)] = data[key];
28
+ foundAny = true;
29
+ }
30
+ }
31
+ if (foundAny)
32
+ return result;
33
+ // Case 3: No namespace structure found — return everything as-is
34
+ // (single-namespace projects or default namespace)
35
+ return data;
36
+ }
37
+ /**
38
+ * i18next backend plugin for better-i18n CDN with offline caching.
39
+ *
40
+ * Implements a network-first strategy:
41
+ * 1. Check in-memory cache (TtlCache) — avoids redundant fetches within a session
42
+ * 2. Fetch from CDN — always get fresh translations
43
+ * 3. On CDN failure, fall back to persistent cache (AsyncStorage)
44
+ *
45
+ * @example
46
+ * ```ts
47
+ * import i18n from 'i18next';
48
+ * import { BetterI18nBackend } from '@better-i18n/expo';
49
+ *
50
+ * i18n.use(BetterI18nBackend).init({
51
+ * backend: { project: 'acme/my-app' },
52
+ * lng: 'en',
53
+ * fallbackLng: 'en',
54
+ * });
55
+ * ```
56
+ */
57
+ export class BetterI18nBackend {
58
+ static type = "backend";
59
+ type = "backend";
60
+ core;
61
+ storage;
62
+ memoryCache = new TtlCache();
63
+ cacheExpiration = DEFAULT_CACHE_EXPIRATION_MS;
64
+ project = "";
65
+ debug = false;
66
+ init(_services, backendOptions, _i18nextOptions) {
67
+ if (!backendOptions.project) {
68
+ throw new Error("[better-i18n/expo] `project` is required in backend options");
69
+ }
70
+ this.project = backendOptions.project;
71
+ this.debug = backendOptions.debug ?? false;
72
+ this.cacheExpiration =
73
+ backendOptions.cacheExpiration ?? DEFAULT_CACHE_EXPIRATION_MS;
74
+ this.storage = resolveStorage(backendOptions.storage);
75
+ this.core = createI18nCore({
76
+ project: backendOptions.project,
77
+ defaultLocale: backendOptions.defaultLocale ?? "en",
78
+ cdnBaseUrl: backendOptions.cdnBaseUrl,
79
+ debug: this.debug,
80
+ fetch: backendOptions.fetch,
81
+ ...backendOptions.coreOptions,
82
+ });
83
+ }
84
+ read(language, namespace, callback) {
85
+ this.loadTranslations(language)
86
+ .then((allData) => {
87
+ const nsData = extractNamespace(allData, namespace);
88
+ this.log("namespace", namespace, "→", Object.keys(nsData).length, "keys");
89
+ callback(null, nsData);
90
+ })
91
+ .catch((err) => callback(err, null));
92
+ }
93
+ async loadTranslations(locale) {
94
+ const memoryCacheKey = `${this.project}:${locale}`;
95
+ // 1. In-memory cache — skip redundant fetches within the same session
96
+ const memoryHit = this.memoryCache.get(memoryCacheKey);
97
+ if (memoryHit) {
98
+ this.log("memory cache hit", locale);
99
+ return memoryHit;
100
+ }
101
+ // 2. Network-first: always try CDN, fall back to persistent cache
102
+ try {
103
+ this.log("fetching from CDN", locale);
104
+ const data = (await this.core.getMessages(locale));
105
+ // Persist to both caches
106
+ this.memoryCache.set(memoryCacheKey, data, this.cacheExpiration);
107
+ writeCache(this.storage, this.project, locale, data).catch((err) => {
108
+ this.log("failed to write persistent cache", err);
109
+ });
110
+ return data;
111
+ }
112
+ catch (err) {
113
+ this.log("CDN fetch failed, checking persistent cache", locale, err);
114
+ // 3. CDN down — fall back to persistent cache
115
+ const cached = await readCache(this.storage, this.project, locale);
116
+ if (cached) {
117
+ this.log("serving from persistent cache (offline fallback)", locale);
118
+ this.memoryCache.set(memoryCacheKey, cached.data, this.cacheExpiration);
119
+ return cached.data;
120
+ }
121
+ // 4. No cache, no CDN — nothing we can do
122
+ throw err;
123
+ }
124
+ }
125
+ log(...args) {
126
+ if (this.debug) {
127
+ console.debug("[better-i18n/expo]", ...args);
128
+ }
129
+ }
130
+ }
131
+ //# sourceMappingURL=backend.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"backend.js","sourceRoot":"","sources":["../src/backend.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,39 @@
1
+ import type { i18n } from "i18next";
2
+ import type { TranslationStorage } from "./types";
3
+ /**
4
+ * Options for the `initBetterI18n` convenience helper
5
+ */
6
+ export interface InitBetterI18nOptions {
7
+ /** Project identifier in "org/project" format */
8
+ project: string;
9
+ /** i18next instance to configure */
10
+ i18n: i18n;
11
+ /** Default/fallback locale @default "en" */
12
+ defaultLocale?: string;
13
+ /** Cache TTL in ms @default 86400000 (24h) */
14
+ cacheExpiration?: number;
15
+ /** Custom storage adapter */
16
+ storage?: TranslationStorage;
17
+ /** Auto-detect device locale via expo-localization @default false */
18
+ useDeviceLocale?: boolean;
19
+ /** Enable debug logging @default false */
20
+ debug?: boolean;
21
+ }
22
+ /**
23
+ * One-liner setup helper that configures i18next with the BetterI18nBackend.
24
+ *
25
+ * @example
26
+ * ```ts
27
+ * import i18n from 'i18next';
28
+ * import { initReactI18next } from 'react-i18next';
29
+ * import { initBetterI18n } from '@better-i18n/expo';
30
+ *
31
+ * await initBetterI18n({
32
+ * project: 'acme/my-app',
33
+ * i18n: i18n.use(initReactI18next),
34
+ * useDeviceLocale: true,
35
+ * });
36
+ * ```
37
+ */
38
+ export declare const initBetterI18n: (options: InitBetterI18nOptions) => Promise<void>;
39
+ //# sourceMappingURL=helpers.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"helpers.d.ts","sourceRoot":"","sources":["../src/helpers.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,SAAS,CAAC;AAGpC,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,SAAS,CAAC;AAElD;;GAEG;AACH,MAAM,WAAW,qBAAqB;IACpC,iDAAiD;IACjD,OAAO,EAAE,MAAM,CAAC;IAEhB,oCAAoC;IACpC,IAAI,EAAE,IAAI,CAAC;IAEX,4CAA4C;IAC5C,aAAa,CAAC,EAAE,MAAM,CAAC;IAEvB,8CAA8C;IAC9C,eAAe,CAAC,EAAE,MAAM,CAAC;IAEzB,6BAA6B;IAC7B,OAAO,CAAC,EAAE,kBAAkB,CAAC;IAE7B,qEAAqE;IACrE,eAAe,CAAC,EAAE,OAAO,CAAC;IAE1B,0CAA0C;IAC1C,KAAK,CAAC,EAAE,OAAO,CAAC;CACjB;AAED;;;;;;;;;;;;;;;GAeG;AACH,eAAO,MAAM,cAAc,GACzB,SAAS,qBAAqB,KAC7B,OAAO,CAAC,IAAI,CA2Bd,CAAC"}
@@ -0,0 +1,37 @@
1
+ import { BetterI18nBackend } from "./backend";
2
+ import { getDeviceLocale } from "./locale";
3
+ /**
4
+ * One-liner setup helper that configures i18next with the BetterI18nBackend.
5
+ *
6
+ * @example
7
+ * ```ts
8
+ * import i18n from 'i18next';
9
+ * import { initReactI18next } from 'react-i18next';
10
+ * import { initBetterI18n } from '@better-i18n/expo';
11
+ *
12
+ * await initBetterI18n({
13
+ * project: 'acme/my-app',
14
+ * i18n: i18n.use(initReactI18next),
15
+ * useDeviceLocale: true,
16
+ * });
17
+ * ```
18
+ */
19
+ export const initBetterI18n = async (options) => {
20
+ const { project, i18n: i18nInstance, defaultLocale = "en", cacheExpiration, storage, useDeviceLocale = false, debug = false, } = options;
21
+ const lng = useDeviceLocale
22
+ ? getDeviceLocale({ fallback: defaultLocale })
23
+ : defaultLocale;
24
+ await i18nInstance.use(BetterI18nBackend).init({
25
+ backend: {
26
+ project,
27
+ defaultLocale,
28
+ cacheExpiration,
29
+ storage,
30
+ debug,
31
+ },
32
+ lng,
33
+ fallbackLng: defaultLocale,
34
+ interpolation: { escapeValue: false },
35
+ });
36
+ };
37
+ //# sourceMappingURL=helpers.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"helpers.js","sourceRoot":"","sources":["../src/helpers.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,iBAAiB,EAAE,MAAM,WAAW,CAAC;AAC9C,OAAO,EAAE,eAAe,EAAE,MAAM,UAAU,CAAC;AA6B3C;;;;;;;;;;;;;;;GAeG;AACH,MAAM,CAAC,MAAM,cAAc,GAAG,KAAK,EACjC,OAA8B,EACf,EAAE;IACjB,MAAM,EACJ,OAAO,EACP,IAAI,EAAE,YAAY,EAClB,aAAa,GAAG,IAAI,EACpB,eAAe,EACf,OAAO,EACP,eAAe,GAAG,KAAK,EACvB,KAAK,GAAG,KAAK,GACd,GAAG,OAAO,CAAC;IAEZ,MAAM,GAAG,GAAG,eAAe;QACzB,CAAC,CAAC,eAAe,CAAC,EAAE,QAAQ,EAAE,aAAa,EAAE,CAAC;QAC9C,CAAC,CAAC,aAAa,CAAC;IAElB,MAAM,YAAY,CAAC,GAAG,CAAC,iBAAiB,CAAC,CAAC,IAAI,CAAC;QAC7C,OAAO,EAAE;YACP,OAAO;YACP,aAAa;YACb,eAAe;YACf,OAAO;YACP,KAAK;SACN;QACD,GAAG;QACH,WAAW,EAAE,aAAa;QAC1B,aAAa,EAAE,EAAE,WAAW,EAAE,KAAK,EAAE;KACtC,CAAC,CAAC;AACL,CAAC,CAAC"}
@@ -0,0 +1,9 @@
1
+ export { BetterI18nBackend } from "./backend";
2
+ export { createMemoryStorage, resolveStorage } from "./storage";
3
+ export { getDeviceLocale, getDeviceLocales } from "./locale";
4
+ export { initBetterI18n } from "./helpers";
5
+ export { createI18nCore } from "@better-i18n/core";
6
+ export type { LanguageOption, ManifestResponse } from "@better-i18n/core";
7
+ export type { BetterI18nBackendOptions, TranslationStorage, CacheMeta, } from "./types";
8
+ export type { InitBetterI18nOptions } from "./helpers";
9
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,iBAAiB,EAAE,MAAM,WAAW,CAAC;AAG9C,OAAO,EAAE,mBAAmB,EAAE,cAAc,EAAE,MAAM,WAAW,CAAC;AAGhE,OAAO,EAAE,eAAe,EAAE,gBAAgB,EAAE,MAAM,UAAU,CAAC;AAG7D,OAAO,EAAE,cAAc,EAAE,MAAM,WAAW,CAAC;AAG3C,OAAO,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAC;AACnD,YAAY,EAAE,cAAc,EAAE,gBAAgB,EAAE,MAAM,mBAAmB,CAAC;AAG1E,YAAY,EACV,wBAAwB,EACxB,kBAAkB,EAClB,SAAS,GACV,MAAM,SAAS,CAAC;AACjB,YAAY,EAAE,qBAAqB,EAAE,MAAM,WAAW,CAAC"}
package/dist/index.js ADDED
@@ -0,0 +1,11 @@
1
+ // Backend plugin (main API)
2
+ export { BetterI18nBackend } from "./backend";
3
+ // Storage
4
+ export { createMemoryStorage, resolveStorage } from "./storage";
5
+ // Locale detection
6
+ export { getDeviceLocale, getDeviceLocales } from "./locale";
7
+ // Convenience helper
8
+ export { initBetterI18n } from "./helpers";
9
+ // Re-export core utilities for manifest/language fetching
10
+ export { createI18nCore } from "@better-i18n/core";
11
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,4BAA4B;AAC5B,OAAO,EAAE,iBAAiB,EAAE,MAAM,WAAW,CAAC;AAE9C,UAAU;AACV,OAAO,EAAE,mBAAmB,EAAE,cAAc,EAAE,MAAM,WAAW,CAAC;AAEhE,mBAAmB;AACnB,OAAO,EAAE,eAAe,EAAE,gBAAgB,EAAE,MAAM,UAAU,CAAC;AAE7D,qBAAqB;AACrB,OAAO,EAAE,cAAc,EAAE,MAAM,WAAW,CAAC;AAE3C,0DAA0D;AAC1D,OAAO,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAC"}
@@ -0,0 +1,28 @@
1
+ /**
2
+ * Get the device's primary locale using expo-localization.
3
+ *
4
+ * Falls back to the provided default if expo-localization is not installed
5
+ * or if no locale can be detected.
6
+ *
7
+ * @example
8
+ * ```ts
9
+ * const locale = getDeviceLocale({ fallback: 'en' });
10
+ * // "tr" (on a Turkish device)
11
+ * ```
12
+ */
13
+ export declare const getDeviceLocale: (options?: {
14
+ fallback?: string;
15
+ }) => string;
16
+ /**
17
+ * Get all device locales as language codes.
18
+ *
19
+ * Returns an empty array if expo-localization is not installed.
20
+ *
21
+ * @example
22
+ * ```ts
23
+ * const locales = getDeviceLocales();
24
+ * // ["tr", "en", "de"]
25
+ * ```
26
+ */
27
+ export declare const getDeviceLocales: () => string[];
28
+ //# sourceMappingURL=locale.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"locale.d.ts","sourceRoot":"","sources":["../src/locale.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AACH,eAAO,MAAM,eAAe,GAC1B,UAAS;IAAE,QAAQ,CAAC,EAAE,MAAM,CAAA;CAAO,KAClC,MAaF,CAAC;AAEF;;;;;;;;;;GAUG;AACH,eAAO,MAAM,gBAAgB,QAAO,MAAM,EAazC,CAAC"}
package/dist/locale.js ADDED
@@ -0,0 +1,51 @@
1
+ /**
2
+ * Get the device's primary locale using expo-localization.
3
+ *
4
+ * Falls back to the provided default if expo-localization is not installed
5
+ * or if no locale can be detected.
6
+ *
7
+ * @example
8
+ * ```ts
9
+ * const locale = getDeviceLocale({ fallback: 'en' });
10
+ * // "tr" (on a Turkish device)
11
+ * ```
12
+ */
13
+ export const getDeviceLocale = (options = {}) => {
14
+ const { fallback = "en" } = options;
15
+ try {
16
+ // eslint-disable-next-line @typescript-eslint/no-require-imports
17
+ const localization = require("expo-localization");
18
+ const getLocales = localization.getLocales;
19
+ const locales = getLocales();
20
+ return locales[0]?.languageCode ?? fallback;
21
+ }
22
+ catch {
23
+ return fallback;
24
+ }
25
+ };
26
+ /**
27
+ * Get all device locales as language codes.
28
+ *
29
+ * Returns an empty array if expo-localization is not installed.
30
+ *
31
+ * @example
32
+ * ```ts
33
+ * const locales = getDeviceLocales();
34
+ * // ["tr", "en", "de"]
35
+ * ```
36
+ */
37
+ export const getDeviceLocales = () => {
38
+ try {
39
+ // eslint-disable-next-line @typescript-eslint/no-require-imports
40
+ const localization = require("expo-localization");
41
+ const getLocales = localization.getLocales;
42
+ const locales = getLocales();
43
+ return locales
44
+ .map((l) => l.languageCode)
45
+ .filter((code) => code != null);
46
+ }
47
+ catch {
48
+ return [];
49
+ }
50
+ };
51
+ //# sourceMappingURL=locale.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"locale.js","sourceRoot":"","sources":["../src/locale.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AACH,MAAM,CAAC,MAAM,eAAe,GAAG,CAC7B,UAAiC,EAAE,EAC3B,EAAE;IACV,MAAM,EAAE,QAAQ,GAAG,IAAI,EAAE,GAAG,OAAO,CAAC;IAEpC,IAAI,CAAC;QACH,iEAAiE;QACjE,MAAM,YAAY,GAAG,OAAO,CAAC,mBAAmB,CAAC,CAAC;QAClD,MAAM,UAAU,GACd,YAAY,CAAC,UAAU,CAAC;QAC1B,MAAM,OAAO,GAAG,UAAU,EAAE,CAAC;QAC7B,OAAO,OAAO,CAAC,CAAC,CAAC,EAAE,YAAY,IAAI,QAAQ,CAAC;IAC9C,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,QAAQ,CAAC;IAClB,CAAC;AACH,CAAC,CAAC;AAEF;;;;;;;;;;GAUG;AACH,MAAM,CAAC,MAAM,gBAAgB,GAAG,GAAa,EAAE;IAC7C,IAAI,CAAC;QACH,iEAAiE;QACjE,MAAM,YAAY,GAAG,OAAO,CAAC,mBAAmB,CAAC,CAAC;QAClD,MAAM,UAAU,GACd,YAAY,CAAC,UAAU,CAAC;QAC1B,MAAM,OAAO,GAAG,UAAU,EAAE,CAAC;QAC7B,OAAO,OAAO;aACX,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,YAAY,CAAC;aAC1B,MAAM,CAAC,CAAC,IAAI,EAAkB,EAAE,CAAC,IAAI,IAAI,IAAI,CAAC,CAAC;IACpD,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,EAAE,CAAC;IACZ,CAAC;AACH,CAAC,CAAC"}
@@ -0,0 +1,37 @@
1
+ import type { CacheMeta, TranslationStorage } from "./types";
2
+ /**
3
+ * Build the storage key for cached translations
4
+ */
5
+ export declare const buildStorageKey: (project: string, locale: string) => string;
6
+ /**
7
+ * Build the storage key for cache metadata
8
+ */
9
+ export declare const buildMetaKey: (project: string, locale: string) => string;
10
+ /**
11
+ * Create an in-memory storage adapter.
12
+ * Used as fallback when no persistent storage is available.
13
+ */
14
+ export declare const createMemoryStorage: () => TranslationStorage;
15
+ /**
16
+ * Auto-detect the best available storage. Zero config.
17
+ *
18
+ * Priority:
19
+ * 1. User-provided custom storage
20
+ * 2. react-native-mmkv (fastest, sync I/O)
21
+ * 3. @react-native-async-storage/async-storage (most common)
22
+ * 4. In-memory Map (no persistence, works everywhere)
23
+ */
24
+ export declare const resolveStorage: (userStorage?: TranslationStorage) => TranslationStorage;
25
+ /**
26
+ * Read cached translations from storage.
27
+ * Meta is optional — if only translations exist, they are still returned.
28
+ */
29
+ export declare const readCache: (storage: TranslationStorage, project: string, locale: string) => Promise<{
30
+ data: Record<string, unknown>;
31
+ meta: CacheMeta;
32
+ } | null>;
33
+ /**
34
+ * Write translations to persistent storage with metadata
35
+ */
36
+ export declare const writeCache: (storage: TranslationStorage, project: string, locale: string, data: Record<string, unknown>) => Promise<void>;
37
+ //# sourceMappingURL=storage.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"storage.d.ts","sourceRoot":"","sources":["../src/storage.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,kBAAkB,EAAE,MAAM,SAAS,CAAC;AAI7D;;GAEG;AACH,eAAO,MAAM,eAAe,GAAI,SAAS,MAAM,EAAE,QAAQ,MAAM,KAAG,MACb,CAAC;AAEtD;;GAEG;AACH,eAAO,MAAM,YAAY,GAAI,SAAS,MAAM,EAAE,QAAQ,MAAM,KAAG,MAClB,CAAC;AAE9C;;;GAGG;AACH,eAAO,MAAM,mBAAmB,QAAO,kBAWtC,CAAC;AAEF;;;;;;;;GAQG;AACH,eAAO,MAAM,cAAc,GACzB,cAAc,kBAAkB,KAC/B,kBAiCF,CAAC;AAEF;;;GAGG;AACH,eAAO,MAAM,SAAS,GACpB,SAAS,kBAAkB,EAC3B,SAAS,MAAM,EACf,QAAQ,MAAM,KACb,OAAO,CAAC;IAAE,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAAC,IAAI,EAAE,SAAS,CAAA;CAAE,GAAG,IAAI,CAoBnE,CAAC;AAEF;;GAEG;AACH,eAAO,MAAM,UAAU,GACrB,SAAS,kBAAkB,EAC3B,SAAS,MAAM,EACf,QAAQ,MAAM,EACd,MAAM,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,KAC5B,OAAO,CAAC,IAAI,CAMd,CAAC"}
@@ -0,0 +1,105 @@
1
+ const CACHE_PREFIX = "@better-i18n";
2
+ /**
3
+ * Build the storage key for cached translations
4
+ */
5
+ export const buildStorageKey = (project, locale) => `${CACHE_PREFIX}:${project}:${locale}:translations`;
6
+ /**
7
+ * Build the storage key for cache metadata
8
+ */
9
+ export const buildMetaKey = (project, locale) => `${CACHE_PREFIX}:${project}:${locale}:meta`;
10
+ /**
11
+ * Create an in-memory storage adapter.
12
+ * Used as fallback when no persistent storage is available.
13
+ */
14
+ export const createMemoryStorage = () => {
15
+ const store = new Map();
16
+ return {
17
+ getItem: async (key) => store.get(key) ?? null,
18
+ setItem: async (key, value) => {
19
+ store.set(key, value);
20
+ },
21
+ removeItem: async (key) => {
22
+ store.delete(key);
23
+ },
24
+ };
25
+ };
26
+ /**
27
+ * Auto-detect the best available storage. Zero config.
28
+ *
29
+ * Priority:
30
+ * 1. User-provided custom storage
31
+ * 2. react-native-mmkv (fastest, sync I/O)
32
+ * 3. @react-native-async-storage/async-storage (most common)
33
+ * 4. In-memory Map (no persistence, works everywhere)
34
+ */
35
+ export const resolveStorage = (userStorage) => {
36
+ if (userStorage)
37
+ return userStorage;
38
+ // 1. Try MMKV — fastest persistent storage for RN
39
+ try {
40
+ // eslint-disable-next-line @typescript-eslint/no-require-imports
41
+ const { MMKV } = require("react-native-mmkv");
42
+ const mmkv = new MMKV({ id: "better-i18n" });
43
+ return {
44
+ getItem: async (key) => mmkv.getString(key) ?? null,
45
+ setItem: async (key, value) => { mmkv.set(key, value); },
46
+ removeItem: async (key) => { mmkv.delete(key); },
47
+ };
48
+ }
49
+ catch {
50
+ // not installed
51
+ }
52
+ // 2. Try AsyncStorage
53
+ try {
54
+ // eslint-disable-next-line @typescript-eslint/no-require-imports
55
+ const asyncStorage = require("@react-native-async-storage/async-storage");
56
+ const mod = asyncStorage.default ?? asyncStorage;
57
+ return {
58
+ getItem: (key) => mod.getItem(key),
59
+ setItem: (key, value) => mod.setItem(key, value),
60
+ removeItem: (key) => mod.removeItem(key),
61
+ };
62
+ }
63
+ catch {
64
+ // not installed
65
+ }
66
+ // 3. Fallback — in-memory (no persistence across restarts)
67
+ return createMemoryStorage();
68
+ };
69
+ /**
70
+ * Read cached translations from storage.
71
+ * Meta is optional — if only translations exist, they are still returned.
72
+ */
73
+ export const readCache = async (storage, project, locale) => {
74
+ try {
75
+ const raw = await storage.getItem(buildStorageKey(project, locale));
76
+ if (!raw)
77
+ return null;
78
+ const data = JSON.parse(raw);
79
+ // Meta is best-effort — default to epoch if missing/corrupt
80
+ let meta = { cachedAt: 0 };
81
+ try {
82
+ const rawMeta = await storage.getItem(buildMetaKey(project, locale));
83
+ if (rawMeta)
84
+ meta = JSON.parse(rawMeta);
85
+ }
86
+ catch {
87
+ // meta is non-critical
88
+ }
89
+ return { data, meta };
90
+ }
91
+ catch {
92
+ return null;
93
+ }
94
+ };
95
+ /**
96
+ * Write translations to persistent storage with metadata
97
+ */
98
+ export const writeCache = async (storage, project, locale, data) => {
99
+ const meta = { cachedAt: Date.now() };
100
+ await Promise.all([
101
+ storage.setItem(buildStorageKey(project, locale), JSON.stringify(data)),
102
+ storage.setItem(buildMetaKey(project, locale), JSON.stringify(meta)),
103
+ ]);
104
+ };
105
+ //# sourceMappingURL=storage.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"storage.js","sourceRoot":"","sources":["../src/storage.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,67 @@
1
+ import type { I18nCoreConfig } from "@better-i18n/core";
2
+ /**
3
+ * Pluggable storage interface for persistent translation caching.
4
+ *
5
+ * Compatible with AsyncStorage, MMKV, or any custom key-value store.
6
+ */
7
+ export interface TranslationStorage {
8
+ getItem(key: string): Promise<string | null>;
9
+ setItem(key: string, value: string): Promise<void>;
10
+ removeItem(key: string): Promise<void>;
11
+ }
12
+ /**
13
+ * Metadata stored alongside cached translations
14
+ */
15
+ export interface CacheMeta {
16
+ /** Timestamp when translations were cached */
17
+ cachedAt: number;
18
+ }
19
+ /**
20
+ * Configuration options for the BetterI18nBackend plugin.
21
+ *
22
+ * Passed via i18next's `backend` option:
23
+ * ```ts
24
+ * i18n.init({ backend: { project: 'acme/my-app' } })
25
+ * ```
26
+ */
27
+ export interface BetterI18nBackendOptions {
28
+ /**
29
+ * Project identifier in "org/project" format (e.g., "acme/dashboard")
30
+ */
31
+ project: string;
32
+ /**
33
+ * Default/fallback locale
34
+ * @default "en"
35
+ */
36
+ defaultLocale?: string;
37
+ /**
38
+ * Custom CDN base URL
39
+ * @default "https://cdn.better-i18n.com"
40
+ */
41
+ cdnBaseUrl?: string;
42
+ /**
43
+ * In-memory cache TTL in milliseconds. Controls how long translations
44
+ * are kept in memory before the next CDN fetch within the same session.
45
+ * @default 86400000 (24 hours)
46
+ */
47
+ cacheExpiration?: number;
48
+ /**
49
+ * Pluggable storage adapter for persistent caching.
50
+ * Defaults to AsyncStorage if installed, otherwise in-memory.
51
+ */
52
+ storage?: TranslationStorage;
53
+ /**
54
+ * Enable debug logging
55
+ * @default false
56
+ */
57
+ debug?: boolean;
58
+ /**
59
+ * Custom fetch function (useful for testing)
60
+ */
61
+ fetch?: typeof fetch;
62
+ /**
63
+ * Additional options forwarded to `@better-i18n/core`
64
+ */
65
+ coreOptions?: Partial<Omit<I18nCoreConfig, "project" | "defaultLocale">>;
66
+ }
67
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAC;AAExD;;;;GAIG;AACH,MAAM,WAAW,kBAAkB;IACjC,OAAO,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAAC;IAC7C,OAAO,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACnD,UAAU,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;CACxC;AAED;;GAEG;AACH,MAAM,WAAW,SAAS;IACxB,8CAA8C;IAC9C,QAAQ,EAAE,MAAM,CAAC;CAClB;AAED;;;;;;;GAOG;AACH,MAAM,WAAW,wBAAwB;IACvC;;OAEG;IACH,OAAO,EAAE,MAAM,CAAC;IAEhB;;;OAGG;IACH,aAAa,CAAC,EAAE,MAAM,CAAC;IAEvB;;;OAGG;IACH,UAAU,CAAC,EAAE,MAAM,CAAC;IAEpB;;;;OAIG;IACH,eAAe,CAAC,EAAE,MAAM,CAAC;IAEzB;;;OAGG;IACH,OAAO,CAAC,EAAE,kBAAkB,CAAC;IAE7B;;;OAGG;IACH,KAAK,CAAC,EAAE,OAAO,CAAC;IAEhB;;OAEG;IACH,KAAK,CAAC,EAAE,OAAO,KAAK,CAAC;IAErB;;OAEG;IACH,WAAW,CAAC,EAAE,OAAO,CAAC,IAAI,CAAC,cAAc,EAAE,SAAS,GAAG,eAAe,CAAC,CAAC,CAAC;CAC1E"}
package/dist/types.js ADDED
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":""}
package/package.json ADDED
@@ -0,0 +1,85 @@
1
+ {
2
+ "name": "@better-i18n/expo",
3
+ "version": "0.2.0",
4
+ "description": "Better i18n backend plugin for i18next in Expo/React Native",
5
+ "license": "MIT",
6
+ "repository": {
7
+ "type": "git",
8
+ "url": "https://github.com/better-i18n/better-i18n.git",
9
+ "directory": "packages/expo"
10
+ },
11
+ "bugs": {
12
+ "url": "https://github.com/better-i18n/better-i18n/issues"
13
+ },
14
+ "homepage": "https://github.com/better-i18n/better-i18n/tree/main/packages/expo",
15
+ "type": "module",
16
+ "main": "./src/index.ts",
17
+ "types": "./src/index.ts",
18
+ "exports": {
19
+ ".": "./src/index.ts",
20
+ "./package.json": "./package.json"
21
+ },
22
+ "files": [
23
+ "dist",
24
+ "package.json",
25
+ "README.md"
26
+ ],
27
+ "publishConfig": {
28
+ "access": "public",
29
+ "main": "./dist/index.js",
30
+ "types": "./dist/index.d.ts",
31
+ "exports": {
32
+ ".": {
33
+ "types": "./dist/index.d.ts",
34
+ "default": "./dist/index.js"
35
+ },
36
+ "./package.json": "./package.json"
37
+ }
38
+ },
39
+ "keywords": [
40
+ "i18n",
41
+ "localization",
42
+ "internationalization",
43
+ "expo",
44
+ "react-native",
45
+ "i18next",
46
+ "cdn",
47
+ "translations",
48
+ "offline"
49
+ ],
50
+ "scripts": {
51
+ "build": "tsc",
52
+ "typecheck": "tsc --noEmit",
53
+ "clean": "rm -rf dist",
54
+ "prepublishOnly": "bun run build"
55
+ },
56
+ "dependencies": {
57
+ "@better-i18n/core": "0.1.7"
58
+ },
59
+ "peerDependencies": {
60
+ "i18next": ">=23.0.0",
61
+ "react-i18next": ">=14.0.0",
62
+ "expo-localization": ">=15.0.0",
63
+ "react-native-mmkv": ">=3.0.0",
64
+ "@react-native-async-storage/async-storage": ">=1.19.0"
65
+ },
66
+ "peerDependenciesMeta": {
67
+ "react-i18next": {
68
+ "optional": true
69
+ },
70
+ "expo-localization": {
71
+ "optional": true
72
+ },
73
+ "react-native-mmkv": {
74
+ "optional": true
75
+ },
76
+ "@react-native-async-storage/async-storage": {
77
+ "optional": true
78
+ }
79
+ },
80
+ "devDependencies": {
81
+ "@types/node": "^20.0.0",
82
+ "i18next": "^23.0.0",
83
+ "typescript": "~5.9.2"
84
+ }
85
+ }