@xxanderwp/translate-module 1.0.4 → 1.0.6

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/README.md CHANGED
@@ -17,6 +17,7 @@ A lightweight, type-safe TypeScript module for managing multi-language translati
17
17
  - Full TypeScript generic type safety — language keys and translation keys are statically inferred
18
18
  - Runtime language switching via a simple setter
19
19
  - String interpolation with indexed placeholders (`{0}`, `{1}`, ...)
20
+ - Language change listeners with automatic unregister support
20
21
  - Zero runtime dependencies
21
22
 
22
23
  ## Installation
@@ -78,7 +79,7 @@ Throws if `data` is empty or `defaultLanguage` is not a key of `data`.
78
79
 
79
80
  Returns the translated string for `key` in the current language, with `{0}`, `{1}`, ... placeholders replaced by the provided `args`.
80
81
 
81
- Returns `null` if the key does not exist or no language is set.
82
+ Returns the key itself as a string if the translation is missing.
82
83
 
83
84
  ---
84
85
 
@@ -102,7 +103,22 @@ Returns the full translations object passed to the constructor.
102
103
 
103
104
  ### `currentLanguageData`
104
105
 
105
- Returns the translation dictionary for the currently active language, or `null` if none is set.
106
+ Returns the translation dictionary for the currently active language.
107
+
108
+ ---
109
+
110
+ ### `onChangeLanguage(cb)`
111
+
112
+ Registers a callback to be invoked whenever the active language changes. Returns an unregister function — call it to remove the listener.
113
+
114
+ ```ts
115
+ const unregister = lang.onChangeLanguage(() => {
116
+ console.log("Language changed to:", lang.currentLanguage);
117
+ });
118
+
119
+ // Later, to stop listening:
120
+ unregister();
121
+ ```
106
122
 
107
123
  ## Development
108
124
 
package/dist/index.d.ts CHANGED
@@ -20,6 +20,11 @@
20
20
  * lc.translate("greeting", "Mundo"); // "¡Hola, Mundo!"
21
21
  */
22
22
  export declare class LanguageCore<T extends Record<string, Record<string, string>>, LangKey extends keyof T = keyof T> {
23
+ private _onChangeLanguage;
24
+ /** Registers a callback to be invoked whenever the active language changes.
25
+ * Returns a function to unregister the callback.
26
+ */
27
+ onChangeLanguage(cb: (newLang: LangKey) => void): () => void;
23
28
  /**
24
29
  * The immutable translations dataset provided at construction time.
25
30
  * Contains all language entries keyed by their language identifier.
@@ -114,12 +119,12 @@ export declare class LanguageCore<T extends Record<string, Record<string, string
114
119
  * @param args - Zero or more values to interpolate into the translated string.
115
120
  * Each value is coerced to a string and replaces the matching `{n}` token.
116
121
  *
117
- * @returns The translated (and interpolated) string, or `null` if the resolved translation is an empty string.
122
+ * @returns The translated (and interpolated) string, or the key itself if the translation is missing.
118
123
  *
119
124
  * @example
120
125
  * lc.translate("greeting", "Alice"); // "Hello, Alice!"
121
126
  * lc.translate("score", "Alice", 42); // "Alice scored 42 points."
122
127
  */
123
- translate<K extends keyof T[LangKey]>(key: K, ...args: (string | number)[]): string | null;
128
+ translate<K extends keyof T[LangKey]>(key: K, ...args: (string | number)[]): string;
124
129
  }
125
130
  export default LanguageCore;
package/dist/index.js CHANGED
@@ -23,6 +23,16 @@ exports.LanguageCore = void 0;
23
23
  * lc.translate("greeting", "Mundo"); // "¡Hola, Mundo!"
24
24
  */
25
25
  class LanguageCore {
26
+ /** Registers a callback to be invoked whenever the active language changes.
27
+ * Returns a function to unregister the callback.
28
+ */
29
+ onChangeLanguage(cb) {
30
+ const id = Math.random();
31
+ this._onChangeLanguage.push({ id, cb });
32
+ return () => {
33
+ this._onChangeLanguage = this._onChangeLanguage.filter(item => item.id !== id);
34
+ };
35
+ }
26
36
  /**
27
37
  * Creates a new `LanguageCore` instance.
28
38
  *
@@ -41,6 +51,7 @@ class LanguageCore {
41
51
  * @throws {Error} If the supplied `defaultLanguage` is not a key of `data`.
42
52
  */
43
53
  constructor(data, defaultLanguage) {
54
+ this._onChangeLanguage = [];
44
55
  this.validateLanguageData(data);
45
56
  this._languages_data = data;
46
57
  if (defaultLanguage) {
@@ -116,7 +127,11 @@ class LanguageCore {
116
127
  if (!this.langKeys.includes(lang)) {
117
128
  throw new Error(`Language ${String(lang)} is not supported.`);
118
129
  }
130
+ if (lang === this._currentLanguage) {
131
+ return;
132
+ }
119
133
  this._currentLanguage = lang;
134
+ this._onChangeLanguage.forEach(item => item.cb(lang));
120
135
  }
121
136
  /**
122
137
  * Returns all language keys available in the translations dataset.
@@ -149,7 +164,7 @@ class LanguageCore {
149
164
  * @param args - Zero or more values to interpolate into the translated string.
150
165
  * Each value is coerced to a string and replaces the matching `{n}` token.
151
166
  *
152
- * @returns The translated (and interpolated) string, or `null` if the resolved translation is an empty string.
167
+ * @returns The translated (and interpolated) string, or the key itself if the translation is missing.
153
168
  *
154
169
  * @example
155
170
  * lc.translate("greeting", "Alice"); // "Hello, Alice!"
@@ -161,7 +176,7 @@ class LanguageCore {
161
176
  args.forEach((arg, index) => {
162
177
  res = res.replace(new RegExp(`\\{${index}\\}`, "g"), String(arg));
163
178
  });
164
- return res || null;
179
+ return res || String(key);
165
180
  }
166
181
  }
167
182
  exports.LanguageCore = LanguageCore;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@xxanderwp/translate-module",
3
- "version": "1.0.4",
3
+ "version": "1.0.6",
4
4
  "description": "",
5
5
  "main": "dist/index.js",
6
6
  "directories": {