@kopynator/core 1.0.8 → 1.0.10

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.
package/dist/index.d.mts CHANGED
@@ -2,6 +2,8 @@ interface KopyConfig {
2
2
  apiKey: string;
3
3
  projectId?: string;
4
4
  baseUrl?: string;
5
+ /** Base URL for local assets (e.g. https://yoursite.com). Required for SSR so the server can fetch /assets/i18n/*.json */
6
+ localBaseUrl?: string;
5
7
  defaultLocale?: string;
6
8
  mode?: 'local' | 'live' | 'hybrid';
7
9
  languages?: string[];
@@ -55,6 +57,7 @@ declare class Kopynator {
55
57
  constructor(config: KopyConfig);
56
58
  /**
57
59
  * Initialize the SDK and load initial translations.
60
+ * Only one request: the current locale (default or saved). Selector uses config.languages if provided.
58
61
  */
59
62
  init(): Promise<void>;
60
63
  /**
@@ -65,7 +68,9 @@ declare class Kopynator {
65
68
  getCurrentLocale(): string;
66
69
  /**
67
70
  * Load translations for a specific locale.
68
- * Priority: Local Assets (Base) -> API (Override)
71
+ * - local: only from /assets/i18n
72
+ * - live: only from API (no local fetch)
73
+ * - hybrid: local as base, then API as override
69
74
  */
70
75
  loadLocale(locale: string): Promise<void>;
71
76
  /**
package/dist/index.d.ts CHANGED
@@ -2,6 +2,8 @@ interface KopyConfig {
2
2
  apiKey: string;
3
3
  projectId?: string;
4
4
  baseUrl?: string;
5
+ /** Base URL for local assets (e.g. https://yoursite.com). Required for SSR so the server can fetch /assets/i18n/*.json */
6
+ localBaseUrl?: string;
5
7
  defaultLocale?: string;
6
8
  mode?: 'local' | 'live' | 'hybrid';
7
9
  languages?: string[];
@@ -55,6 +57,7 @@ declare class Kopynator {
55
57
  constructor(config: KopyConfig);
56
58
  /**
57
59
  * Initialize the SDK and load initial translations.
60
+ * Only one request: the current locale (default or saved). Selector uses config.languages if provided.
58
61
  */
59
62
  init(): Promise<void>;
60
63
  /**
@@ -65,7 +68,9 @@ declare class Kopynator {
65
68
  getCurrentLocale(): string;
66
69
  /**
67
70
  * Load translations for a specific locale.
68
- * Priority: Local Assets (Base) -> API (Override)
71
+ * - local: only from /assets/i18n
72
+ * - live: only from API (no local fetch)
73
+ * - hybrid: local as base, then API as override
69
74
  */
70
75
  loadLocale(locale: string): Promise<void>;
71
76
  /**
package/dist/index.js CHANGED
@@ -79,7 +79,9 @@ var KopyFetcher = class {
79
79
  }
80
80
  async fetchLocal(locale) {
81
81
  try {
82
- const url = `/assets/i18n/${locale}.json`;
82
+ const base = (this.config.localBaseUrl || "").replace(/\/$/, "");
83
+ const path = `/assets/i18n/${locale}.json`;
84
+ const url = base ? `${base}${path}` : path;
83
85
  const response = await fetch(url);
84
86
  if (!response.ok) {
85
87
  throw new Error(`Local translations not found: ${response.statusText}`);
@@ -173,13 +175,13 @@ var Kopynator = class {
173
175
  availableLanguages = [];
174
176
  /**
175
177
  * Initialize the SDK and load initial translations.
178
+ * Only one request: the current locale (default or saved). Selector uses config.languages if provided.
176
179
  */
177
180
  async init() {
178
- const tasks = [this.loadLocale(this.currentLocale)];
179
- if (this.config.mode !== "local") {
180
- tasks.push(this.refreshAvailableLanguages());
181
+ await this.loadLocale(this.currentLocale);
182
+ if (this.config.mode !== "local" && (!this.config.languages || this.config.languages.length === 0)) {
183
+ await this.refreshAvailableLanguages();
181
184
  }
182
- await Promise.all(tasks);
183
185
  }
184
186
  /**
185
187
  * Fetch and update the list of available languages from the API.
@@ -202,28 +204,39 @@ var Kopynator = class {
202
204
  }
203
205
  /**
204
206
  * Load translations for a specific locale.
205
- * Priority: Local Assets (Base) -> API (Override)
207
+ * - local: only from /assets/i18n
208
+ * - live: only from API (no local fetch)
209
+ * - hybrid: local as base, then API as override
206
210
  */
207
211
  async loadLocale(locale) {
208
212
  if (this.translations[locale] && Object.keys(this.translations[locale]).length > 0) {
209
213
  return;
210
214
  }
211
215
  this.translations[locale] = {};
212
- try {
213
- const localData = await this.fetcher.fetchLocal(locale);
214
- if (localData && Object.keys(localData).length > 0) {
215
- this.translations[locale] = { ...localData };
216
+ if (this.config.mode === "live") {
217
+ try {
218
+ const remoteData = await this.fetcher.fetchTranslations(locale);
219
+ if (remoteData && Object.keys(remoteData).length > 0) {
220
+ this.translations[locale] = { ...remoteData };
221
+ }
222
+ } catch (e) {
223
+ }
224
+ return;
225
+ }
226
+ if (this.config.mode === "local" || this.config.mode === "hybrid") {
227
+ try {
228
+ const localData = await this.fetcher.fetchLocal(locale);
229
+ if (localData && Object.keys(localData).length > 0) {
230
+ this.translations[locale] = { ...localData };
231
+ }
232
+ } catch (e) {
216
233
  }
217
- } catch (e) {
218
234
  }
219
- if (this.config.mode !== "local") {
235
+ if (this.config.mode === "hybrid") {
220
236
  try {
221
237
  const remoteData = await this.fetcher.fetchTranslations(locale);
222
238
  if (remoteData && Object.keys(remoteData).length > 0) {
223
- this.translations[locale] = {
224
- ...this.translations[locale],
225
- ...remoteData
226
- };
239
+ this.translations[locale] = { ...this.translations[locale], ...remoteData };
227
240
  }
228
241
  } catch (e) {
229
242
  }
package/dist/index.mjs CHANGED
@@ -48,7 +48,9 @@ var KopyFetcher = class {
48
48
  }
49
49
  async fetchLocal(locale) {
50
50
  try {
51
- const url = `/assets/i18n/${locale}.json`;
51
+ const base = (this.config.localBaseUrl || "").replace(/\/$/, "");
52
+ const path = `/assets/i18n/${locale}.json`;
53
+ const url = base ? `${base}${path}` : path;
52
54
  const response = await fetch(url);
53
55
  if (!response.ok) {
54
56
  throw new Error(`Local translations not found: ${response.statusText}`);
@@ -142,13 +144,13 @@ var Kopynator = class {
142
144
  availableLanguages = [];
143
145
  /**
144
146
  * Initialize the SDK and load initial translations.
147
+ * Only one request: the current locale (default or saved). Selector uses config.languages if provided.
145
148
  */
146
149
  async init() {
147
- const tasks = [this.loadLocale(this.currentLocale)];
148
- if (this.config.mode !== "local") {
149
- tasks.push(this.refreshAvailableLanguages());
150
+ await this.loadLocale(this.currentLocale);
151
+ if (this.config.mode !== "local" && (!this.config.languages || this.config.languages.length === 0)) {
152
+ await this.refreshAvailableLanguages();
150
153
  }
151
- await Promise.all(tasks);
152
154
  }
153
155
  /**
154
156
  * Fetch and update the list of available languages from the API.
@@ -171,28 +173,39 @@ var Kopynator = class {
171
173
  }
172
174
  /**
173
175
  * Load translations for a specific locale.
174
- * Priority: Local Assets (Base) -> API (Override)
176
+ * - local: only from /assets/i18n
177
+ * - live: only from API (no local fetch)
178
+ * - hybrid: local as base, then API as override
175
179
  */
176
180
  async loadLocale(locale) {
177
181
  if (this.translations[locale] && Object.keys(this.translations[locale]).length > 0) {
178
182
  return;
179
183
  }
180
184
  this.translations[locale] = {};
181
- try {
182
- const localData = await this.fetcher.fetchLocal(locale);
183
- if (localData && Object.keys(localData).length > 0) {
184
- this.translations[locale] = { ...localData };
185
+ if (this.config.mode === "live") {
186
+ try {
187
+ const remoteData = await this.fetcher.fetchTranslations(locale);
188
+ if (remoteData && Object.keys(remoteData).length > 0) {
189
+ this.translations[locale] = { ...remoteData };
190
+ }
191
+ } catch (e) {
192
+ }
193
+ return;
194
+ }
195
+ if (this.config.mode === "local" || this.config.mode === "hybrid") {
196
+ try {
197
+ const localData = await this.fetcher.fetchLocal(locale);
198
+ if (localData && Object.keys(localData).length > 0) {
199
+ this.translations[locale] = { ...localData };
200
+ }
201
+ } catch (e) {
185
202
  }
186
- } catch (e) {
187
203
  }
188
- if (this.config.mode !== "local") {
204
+ if (this.config.mode === "hybrid") {
189
205
  try {
190
206
  const remoteData = await this.fetcher.fetchTranslations(locale);
191
207
  if (remoteData && Object.keys(remoteData).length > 0) {
192
- this.translations[locale] = {
193
- ...this.translations[locale],
194
- ...remoteData
195
- };
208
+ this.translations[locale] = { ...this.translations[locale], ...remoteData };
196
209
  }
197
210
  } catch (e) {
198
211
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@kopynator/core",
3
- "version": "1.0.8",
3
+ "version": "1.0.10",
4
4
  "description": "Core agnostic logic for Kopynator SDKs",
5
5
  "main": "./dist/index.js",
6
6
  "module": "./dist/index.mjs",