inline-i18n-multi 0.16.0 → 0.18.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.
package/README.md CHANGED
@@ -87,6 +87,8 @@ See "Hello" in your app? Just search for "Hello" in your codebase. **Done.**
87
87
  - **Raw Template Access** -- `tRaw(key, locale?)` returns raw template string without interpolation (v0.14.0)
88
88
  - **Batch Translation** -- `tBatch(keys, vars?, locale?)` translates multiple keys at once (v0.15.0)
89
89
  - **Missing Locales Detection** -- `getMissingLocales(key)` returns locales where a key is absent (v0.16.0)
90
+ - **Translation Completeness Ratio** -- `getCompletenessRatio(locale, baseLocale?, namespace?)` returns the fraction of base-locale keys present in a target locale (v0.17.0)
91
+ - **Missing Key Listener** -- `onMissingKey(callback)` subscribes to missing translation events with `(key, locale)` (v0.18.0)
90
92
 
91
93
  ---
92
94
 
@@ -1027,6 +1029,8 @@ Available helpers:
1027
1029
  | `tRaw(key, locale?)` | Get raw template string without interpolation |
1028
1030
  | `tBatch(keys, vars?, locale?)` | Translate multiple keys at once |
1029
1031
  | `getMissingLocales(key)` | List locales missing a translation key |
1032
+ | `getCompletenessRatio(locale, baseLocale?, namespace?)` | Get translation completeness ratio (0-1) |
1033
+ | `onMissingKey(callback)` | Subscribe to missing translation key events |
1030
1034
 
1031
1035
  ### Custom Formatters
1032
1036
 
package/dist/index.d.mts CHANGED
@@ -279,6 +279,22 @@ declare function getDictionary(locale: Locale, namespace?: string): Dictionary |
279
279
  * Get all loaded namespaces
280
280
  */
281
281
  declare function getLoadedNamespaces(): string[];
282
+ /**
283
+ * Get translation completeness ratio of a locale relative to a base locale (v0.17.0)
284
+ * Returns a value between 0 and 1 representing the fraction of base locale keys
285
+ * that exist in the target locale.
286
+ *
287
+ * @param locale - Target locale to measure
288
+ * @param baseLocale - Reference locale (defaults to config.defaultLocale)
289
+ * @param namespace - Optional namespace to scope the comparison
290
+ * @returns Ratio in [0, 1]; 1 if base has no keys or locale === base
291
+ *
292
+ * @example
293
+ * loadDictionaries({ en: { a: '1', b: '2', c: '3' }, ko: { a: '가' } })
294
+ * getCompletenessRatio('ko') // → 0.333... (1 of 3 keys translated)
295
+ * getCompletenessRatio('en') // → 1 (same as base)
296
+ */
297
+ declare function getCompletenessRatio(locale: Locale, baseLocale?: Locale, namespace?: string): number;
282
298
  /**
283
299
  * Get the display name of a locale using Intl.DisplayNames (v0.11.0)
284
300
  * @param locale - Locale code to get display name for (e.g., 'ko', 'ja', 'en-US')
@@ -302,6 +318,27 @@ declare function getLocaleDisplayName(locale: Locale, displayLocale?: Locale): s
302
318
  * getTranslationKeys('en', 'common') // → ['hello', 'goodbye']
303
319
  */
304
320
  declare function getTranslationKeys(locale?: Locale, namespace?: string): string[];
321
+ type MissingKeyCallback = (key: string, locale: Locale) => void;
322
+ /**
323
+ * Subscribe to missing translation key events (v0.18.0)
324
+ * Callback fires every time `t()` encounters a key with no translation
325
+ * (independent of `trackMissingKeys`).
326
+ *
327
+ * @param callback - Receives `(key, requestedLocale)` for each missing key
328
+ * @returns Unsubscribe function
329
+ *
330
+ * @example
331
+ * const off = onMissingKey((key, locale) => {
332
+ * reportToMonitoring({ key, locale })
333
+ * })
334
+ * t('missing.key') // callback fires with ('missing.key', 'en')
335
+ * off() // stop listening
336
+ */
337
+ declare function onMissingKey(callback: MissingKeyCallback): () => void;
338
+ /**
339
+ * Remove all missing-key listeners (for testing) (v0.18.0)
340
+ */
341
+ declare function clearMissingKeyListeners(): void;
305
342
  /**
306
343
  * Enable or disable missing translation tracking (v0.11.0)
307
344
  * When enabled, all missing translation keys encountered via t() are recorded.
@@ -460,4 +497,4 @@ interface RichTextSegment {
460
497
  */
461
498
  declare function parseRichText(template: string, componentNames: string[]): RichTextSegment[];
462
499
 
463
- export { type Config, type CustomFormatter, type DebugModeOptions, type DetectLocaleOptions, type DetectSource, type Dictionaries, type Dictionary, type Locale, type PluralRules, type RichTextSegment, type TranslationVars, type TranslationWarning, type Translations, type WarningHandler, __i18n_lookup, clearDictionaries, clearFormatters, clearICUCache, clearLocaleListeners, clearMissingKeys, configure, createScope, detectLocale, en_de, en_es, en_fr, en_ja, en_zh, formatDate, formatList, formatNumber, getConfig, getDictionary, getLoadedLocales, getLoadedNamespaces, getLocale, getLocaleDisplayName, getMissingKeys, getMissingLocales, getTranslationKeys, hasTranslation, isLoaded, it, it_de, it_es, it_fr, it_ja, it_zh, ja_es, ja_zh, loadAsync, loadDictionaries, loadDictionary, onLocaleChange, parseRichText, registerFormatter, resetConfig, restoreLocale, setLocale, t, tBatch, tRaw, trackMissingKeys, zh_es };
500
+ export { type Config, type CustomFormatter, type DebugModeOptions, type DetectLocaleOptions, type DetectSource, type Dictionaries, type Dictionary, type Locale, type PluralRules, type RichTextSegment, type TranslationVars, type TranslationWarning, type Translations, type WarningHandler, __i18n_lookup, clearDictionaries, clearFormatters, clearICUCache, clearLocaleListeners, clearMissingKeyListeners, clearMissingKeys, configure, createScope, detectLocale, en_de, en_es, en_fr, en_ja, en_zh, formatDate, formatList, formatNumber, getCompletenessRatio, getConfig, getDictionary, getLoadedLocales, getLoadedNamespaces, getLocale, getLocaleDisplayName, getMissingKeys, getMissingLocales, getTranslationKeys, hasTranslation, isLoaded, it, it_de, it_es, it_fr, it_ja, it_zh, ja_es, ja_zh, loadAsync, loadDictionaries, loadDictionary, onLocaleChange, onMissingKey, parseRichText, registerFormatter, resetConfig, restoreLocale, setLocale, t, tBatch, tRaw, trackMissingKeys, zh_es };
package/dist/index.d.ts CHANGED
@@ -279,6 +279,22 @@ declare function getDictionary(locale: Locale, namespace?: string): Dictionary |
279
279
  * Get all loaded namespaces
280
280
  */
281
281
  declare function getLoadedNamespaces(): string[];
282
+ /**
283
+ * Get translation completeness ratio of a locale relative to a base locale (v0.17.0)
284
+ * Returns a value between 0 and 1 representing the fraction of base locale keys
285
+ * that exist in the target locale.
286
+ *
287
+ * @param locale - Target locale to measure
288
+ * @param baseLocale - Reference locale (defaults to config.defaultLocale)
289
+ * @param namespace - Optional namespace to scope the comparison
290
+ * @returns Ratio in [0, 1]; 1 if base has no keys or locale === base
291
+ *
292
+ * @example
293
+ * loadDictionaries({ en: { a: '1', b: '2', c: '3' }, ko: { a: '가' } })
294
+ * getCompletenessRatio('ko') // → 0.333... (1 of 3 keys translated)
295
+ * getCompletenessRatio('en') // → 1 (same as base)
296
+ */
297
+ declare function getCompletenessRatio(locale: Locale, baseLocale?: Locale, namespace?: string): number;
282
298
  /**
283
299
  * Get the display name of a locale using Intl.DisplayNames (v0.11.0)
284
300
  * @param locale - Locale code to get display name for (e.g., 'ko', 'ja', 'en-US')
@@ -302,6 +318,27 @@ declare function getLocaleDisplayName(locale: Locale, displayLocale?: Locale): s
302
318
  * getTranslationKeys('en', 'common') // → ['hello', 'goodbye']
303
319
  */
304
320
  declare function getTranslationKeys(locale?: Locale, namespace?: string): string[];
321
+ type MissingKeyCallback = (key: string, locale: Locale) => void;
322
+ /**
323
+ * Subscribe to missing translation key events (v0.18.0)
324
+ * Callback fires every time `t()` encounters a key with no translation
325
+ * (independent of `trackMissingKeys`).
326
+ *
327
+ * @param callback - Receives `(key, requestedLocale)` for each missing key
328
+ * @returns Unsubscribe function
329
+ *
330
+ * @example
331
+ * const off = onMissingKey((key, locale) => {
332
+ * reportToMonitoring({ key, locale })
333
+ * })
334
+ * t('missing.key') // callback fires with ('missing.key', 'en')
335
+ * off() // stop listening
336
+ */
337
+ declare function onMissingKey(callback: MissingKeyCallback): () => void;
338
+ /**
339
+ * Remove all missing-key listeners (for testing) (v0.18.0)
340
+ */
341
+ declare function clearMissingKeyListeners(): void;
305
342
  /**
306
343
  * Enable or disable missing translation tracking (v0.11.0)
307
344
  * When enabled, all missing translation keys encountered via t() are recorded.
@@ -460,4 +497,4 @@ interface RichTextSegment {
460
497
  */
461
498
  declare function parseRichText(template: string, componentNames: string[]): RichTextSegment[];
462
499
 
463
- export { type Config, type CustomFormatter, type DebugModeOptions, type DetectLocaleOptions, type DetectSource, type Dictionaries, type Dictionary, type Locale, type PluralRules, type RichTextSegment, type TranslationVars, type TranslationWarning, type Translations, type WarningHandler, __i18n_lookup, clearDictionaries, clearFormatters, clearICUCache, clearLocaleListeners, clearMissingKeys, configure, createScope, detectLocale, en_de, en_es, en_fr, en_ja, en_zh, formatDate, formatList, formatNumber, getConfig, getDictionary, getLoadedLocales, getLoadedNamespaces, getLocale, getLocaleDisplayName, getMissingKeys, getMissingLocales, getTranslationKeys, hasTranslation, isLoaded, it, it_de, it_es, it_fr, it_ja, it_zh, ja_es, ja_zh, loadAsync, loadDictionaries, loadDictionary, onLocaleChange, parseRichText, registerFormatter, resetConfig, restoreLocale, setLocale, t, tBatch, tRaw, trackMissingKeys, zh_es };
500
+ export { type Config, type CustomFormatter, type DebugModeOptions, type DetectLocaleOptions, type DetectSource, type Dictionaries, type Dictionary, type Locale, type PluralRules, type RichTextSegment, type TranslationVars, type TranslationWarning, type Translations, type WarningHandler, __i18n_lookup, clearDictionaries, clearFormatters, clearICUCache, clearLocaleListeners, clearMissingKeyListeners, clearMissingKeys, configure, createScope, detectLocale, en_de, en_es, en_fr, en_ja, en_zh, formatDate, formatList, formatNumber, getCompletenessRatio, getConfig, getDictionary, getLoadedLocales, getLoadedNamespaces, getLocale, getLocaleDisplayName, getMissingKeys, getMissingLocales, getTranslationKeys, hasTranslation, isLoaded, it, it_de, it_es, it_fr, it_ja, it_zh, ja_es, ja_zh, loadAsync, loadDictionaries, loadDictionary, onLocaleChange, onMissingKey, parseRichText, registerFormatter, resetConfig, restoreLocale, setLocale, t, tBatch, tRaw, trackMissingKeys, zh_es };
package/dist/index.js CHANGED
@@ -938,7 +938,7 @@ function t(key, vars, locale) {
938
938
  }
939
939
  }
940
940
  if (!template) {
941
- recordMissingKey(key);
941
+ recordMissingKey(key, currentLocale2);
942
942
  emitWarning({
943
943
  type: "missing_translation",
944
944
  key,
@@ -1039,6 +1039,18 @@ function getDictionary(locale, namespace) {
1039
1039
  function getLoadedNamespaces() {
1040
1040
  return Object.keys(namespacedDictionaries);
1041
1041
  }
1042
+ function getCompletenessRatio(locale, baseLocale, namespace) {
1043
+ const base = baseLocale ?? getConfig().defaultLocale;
1044
+ if (locale === base) return 1;
1045
+ const baseKeys = getTranslationKeys(base, namespace);
1046
+ if (baseKeys.length === 0) return 1;
1047
+ const localeKeys = new Set(getTranslationKeys(locale, namespace));
1048
+ let matched = 0;
1049
+ for (const k of baseKeys) {
1050
+ if (localeKeys.has(k)) matched++;
1051
+ }
1052
+ return matched / baseKeys.length;
1053
+ }
1042
1054
  function getLocaleDisplayName(locale, displayLocale) {
1043
1055
  const dl = displayLocale ?? getLocale();
1044
1056
  try {
@@ -1077,6 +1089,16 @@ function getTranslationKeys(locale, namespace) {
1077
1089
  }
1078
1090
  var missingKeys = /* @__PURE__ */ new Set();
1079
1091
  var trackMissing = false;
1092
+ var missingKeyListeners = /* @__PURE__ */ new Set();
1093
+ function onMissingKey(callback) {
1094
+ missingKeyListeners.add(callback);
1095
+ return () => {
1096
+ missingKeyListeners.delete(callback);
1097
+ };
1098
+ }
1099
+ function clearMissingKeyListeners() {
1100
+ missingKeyListeners.clear();
1101
+ }
1080
1102
  function trackMissingKeys(enabled) {
1081
1103
  trackMissing = enabled;
1082
1104
  if (!enabled) {
@@ -1089,10 +1111,16 @@ function getMissingKeys() {
1089
1111
  function clearMissingKeys() {
1090
1112
  missingKeys = /* @__PURE__ */ new Set();
1091
1113
  }
1092
- function recordMissingKey(key) {
1114
+ function recordMissingKey(key, locale) {
1093
1115
  if (trackMissing) {
1094
1116
  missingKeys.add(key);
1095
1117
  }
1118
+ if (missingKeyListeners.size > 0) {
1119
+ const loc = locale ?? getLocale();
1120
+ for (const cb of missingKeyListeners) {
1121
+ cb(key, loc);
1122
+ }
1123
+ }
1096
1124
  }
1097
1125
 
1098
1126
  // src/detect.ts
@@ -1241,6 +1269,7 @@ exports.clearDictionaries = clearDictionaries;
1241
1269
  exports.clearFormatters = clearFormatters;
1242
1270
  exports.clearICUCache = clearICUCache;
1243
1271
  exports.clearLocaleListeners = clearLocaleListeners;
1272
+ exports.clearMissingKeyListeners = clearMissingKeyListeners;
1244
1273
  exports.clearMissingKeys = clearMissingKeys;
1245
1274
  exports.configure = configure;
1246
1275
  exports.createScope = createScope;
@@ -1253,6 +1282,7 @@ exports.en_zh = en_zh;
1253
1282
  exports.formatDate = formatDate;
1254
1283
  exports.formatList = formatList;
1255
1284
  exports.formatNumber = formatNumber;
1285
+ exports.getCompletenessRatio = getCompletenessRatio;
1256
1286
  exports.getConfig = getConfig;
1257
1287
  exports.getDictionary = getDictionary;
1258
1288
  exports.getLoadedLocales = getLoadedLocales;
@@ -1276,6 +1306,7 @@ exports.loadAsync = loadAsync;
1276
1306
  exports.loadDictionaries = loadDictionaries;
1277
1307
  exports.loadDictionary = loadDictionary;
1278
1308
  exports.onLocaleChange = onLocaleChange;
1309
+ exports.onMissingKey = onMissingKey;
1279
1310
  exports.parseRichText = parseRichText;
1280
1311
  exports.registerFormatter = registerFormatter;
1281
1312
  exports.resetConfig = resetConfig;