@digitaldefiance/i18n-lib 1.3.13 → 1.3.15

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.
Files changed (243) hide show
  1. package/README.md +143 -87
  2. package/package.json +4 -3
  3. package/src/active-context.d.ts +30 -0
  4. package/src/active-context.d.ts.map +1 -0
  5. package/src/active-context.js +3 -0
  6. package/src/active-context.js.map +1 -0
  7. package/src/component-definition.d.ts +12 -0
  8. package/src/component-definition.d.ts.map +1 -0
  9. package/src/component-definition.js +3 -0
  10. package/src/component-definition.js.map +1 -0
  11. package/src/component-registration.d.ts +10 -0
  12. package/src/component-registration.d.ts.map +1 -0
  13. package/src/component-registration.js +3 -0
  14. package/src/component-registration.js.map +1 -0
  15. package/src/component-registry.d.ts +69 -0
  16. package/src/component-registry.d.ts.map +1 -0
  17. package/src/component-registry.js +248 -0
  18. package/src/component-registry.js.map +1 -0
  19. package/src/context-error-type.d.ts +4 -0
  20. package/src/context-error-type.d.ts.map +1 -0
  21. package/src/context-error-type.js +8 -0
  22. package/src/context-error-type.js.map +1 -0
  23. package/src/context-error.d.ts +7 -0
  24. package/src/context-error.d.ts.map +1 -0
  25. package/src/context-error.js +18 -0
  26. package/src/context-error.js.map +1 -0
  27. package/src/context-manager.d.ts +34 -0
  28. package/src/context-manager.d.ts.map +1 -0
  29. package/src/context-manager.js +60 -0
  30. package/src/context-manager.js.map +1 -0
  31. package/src/context.d.ts +45 -0
  32. package/src/context.d.ts.map +1 -0
  33. package/src/context.js +70 -0
  34. package/src/context.js.map +1 -0
  35. package/src/core-i18n.d.ts +63 -0
  36. package/src/core-i18n.d.ts.map +1 -0
  37. package/src/core-i18n.js +478 -0
  38. package/src/core-i18n.js.map +1 -0
  39. package/src/core-string-key.d.ts +43 -0
  40. package/src/core-string-key.d.ts.map +1 -0
  41. package/src/core-string-key.js +51 -0
  42. package/src/core-string-key.js.map +1 -0
  43. package/src/create-translation-adapter.d.ts +21 -0
  44. package/src/create-translation-adapter.d.ts.map +1 -0
  45. package/src/create-translation-adapter.js +37 -0
  46. package/src/create-translation-adapter.js.map +1 -0
  47. package/src/currency-code.d.ts +20 -0
  48. package/src/currency-code.d.ts.map +1 -0
  49. package/src/currency-code.js +37 -0
  50. package/src/currency-code.js.map +1 -0
  51. package/src/{currency-format.ts → currency-format.d.ts} +5 -5
  52. package/src/currency-format.d.ts.map +1 -0
  53. package/src/currency-format.js +3 -0
  54. package/src/currency-format.js.map +1 -0
  55. package/src/currency.d.ts +12 -0
  56. package/src/currency.d.ts.map +1 -0
  57. package/src/currency.js +49 -0
  58. package/src/currency.js.map +1 -0
  59. package/src/default-config.d.ts +33 -0
  60. package/src/default-config.d.ts.map +1 -0
  61. package/src/default-config.js +102 -0
  62. package/src/default-config.js.map +1 -0
  63. package/src/enum-registry.d.ts +45 -0
  64. package/src/enum-registry.d.ts.map +1 -0
  65. package/src/enum-registry.js +103 -0
  66. package/src/enum-registry.js.map +1 -0
  67. package/src/global-active-context.d.ts +51 -0
  68. package/src/global-active-context.d.ts.map +1 -0
  69. package/src/global-active-context.js +179 -0
  70. package/src/global-active-context.js.map +1 -0
  71. package/src/handleable.d.ts +14 -0
  72. package/src/handleable.d.ts.map +1 -0
  73. package/src/handleable.js +66 -0
  74. package/src/handleable.js.map +1 -0
  75. package/src/i-global-active-context.d.ts +23 -0
  76. package/src/i-global-active-context.d.ts.map +1 -0
  77. package/src/i-global-active-context.js +3 -0
  78. package/src/i-global-active-context.js.map +1 -0
  79. package/src/i-handleable-error-options.d.ts +7 -0
  80. package/src/i-handleable-error-options.d.ts.map +1 -0
  81. package/src/i-handleable-error-options.js +3 -0
  82. package/src/i-handleable-error-options.js.map +1 -0
  83. package/src/i-handleable.d.ts +6 -0
  84. package/src/i-handleable.d.ts.map +1 -0
  85. package/src/i-handleable.js +3 -0
  86. package/src/i-handleable.js.map +1 -0
  87. package/src/i18n-config.d.ts +21 -0
  88. package/src/i18n-config.d.ts.map +1 -0
  89. package/src/i18n-config.js +3 -0
  90. package/src/i18n-config.js.map +1 -0
  91. package/src/{i18n-context.ts → i18n-context.d.ts} +7 -7
  92. package/src/i18n-context.d.ts.map +1 -0
  93. package/src/i18n-context.js +3 -0
  94. package/src/i18n-context.js.map +1 -0
  95. package/src/i18n-engine.d.ts +179 -0
  96. package/src/i18n-engine.d.ts.map +1 -0
  97. package/src/i18n-engine.js +355 -0
  98. package/src/i18n-engine.js.map +1 -0
  99. package/src/{index.ts → index.d.ts} +2 -10
  100. package/src/index.d.ts.map +1 -0
  101. package/src/index.js +71 -0
  102. package/src/index.js.map +1 -0
  103. package/src/{language-codes.ts → language-codes.d.ts} +12 -23
  104. package/src/language-codes.d.ts.map +1 -0
  105. package/src/language-codes.js +32 -0
  106. package/src/language-codes.js.map +1 -0
  107. package/src/language-definition.d.ts +14 -0
  108. package/src/language-definition.d.ts.map +1 -0
  109. package/src/language-definition.js +3 -0
  110. package/src/language-definition.js.map +1 -0
  111. package/src/language-registry.d.ts +114 -0
  112. package/src/language-registry.d.ts.map +1 -0
  113. package/src/language-registry.js +217 -0
  114. package/src/language-registry.js.map +1 -0
  115. package/src/plugin-i18n-engine.d.ts +151 -0
  116. package/src/plugin-i18n-engine.d.ts.map +1 -0
  117. package/src/plugin-i18n-engine.js +380 -0
  118. package/src/plugin-i18n-engine.js.map +1 -0
  119. package/src/plugin-translatable-generic-error.d.ts +30 -0
  120. package/src/plugin-translatable-generic-error.d.ts.map +1 -0
  121. package/src/plugin-translatable-generic-error.js +72 -0
  122. package/src/plugin-translatable-generic-error.js.map +1 -0
  123. package/src/plugin-translatable-handleable-generic.d.ts +29 -0
  124. package/src/plugin-translatable-handleable-generic.d.ts.map +1 -0
  125. package/src/plugin-translatable-handleable-generic.js +44 -0
  126. package/src/plugin-translatable-handleable-generic.js.map +1 -0
  127. package/src/plugin-typed-handleable.d.ts +15 -0
  128. package/src/plugin-typed-handleable.d.ts.map +1 -0
  129. package/src/plugin-typed-handleable.js +51 -0
  130. package/src/plugin-typed-handleable.js.map +1 -0
  131. package/src/registry-config.d.ts +15 -0
  132. package/src/registry-config.d.ts.map +1 -0
  133. package/src/registry-config.js +3 -0
  134. package/src/registry-config.js.map +1 -0
  135. package/src/registry-error-type.d.ts +13 -0
  136. package/src/registry-error-type.d.ts.map +1 -0
  137. package/src/registry-error-type.js +17 -0
  138. package/src/registry-error-type.js.map +1 -0
  139. package/src/registry-error.d.ts +19 -0
  140. package/src/registry-error.d.ts.map +1 -0
  141. package/src/registry-error.js +48 -0
  142. package/src/registry-error.js.map +1 -0
  143. package/src/strict-types.d.ts +19 -0
  144. package/src/strict-types.d.ts.map +1 -0
  145. package/src/strict-types.js +18 -0
  146. package/src/strict-types.js.map +1 -0
  147. package/src/template.d.ts +13 -0
  148. package/src/template.d.ts.map +1 -0
  149. package/src/template.js +31 -0
  150. package/src/template.js.map +1 -0
  151. package/src/timezone.d.ts +12 -0
  152. package/src/timezone.d.ts.map +1 -0
  153. package/src/timezone.js +24 -0
  154. package/src/timezone.js.map +1 -0
  155. package/src/translatable.d.ts +6 -0
  156. package/src/translatable.d.ts.map +1 -0
  157. package/src/translatable.js +12 -0
  158. package/src/translatable.js.map +1 -0
  159. package/src/translation-engine.d.ts +9 -0
  160. package/src/translation-engine.d.ts.map +1 -0
  161. package/src/translation-engine.js +3 -0
  162. package/src/translation-engine.js.map +1 -0
  163. package/src/translation-request.d.ts +10 -0
  164. package/src/translation-request.d.ts.map +1 -0
  165. package/src/translation-request.js +3 -0
  166. package/src/translation-request.js.map +1 -0
  167. package/src/translation-response.d.ts +9 -0
  168. package/src/translation-response.d.ts.map +1 -0
  169. package/src/translation-response.js +3 -0
  170. package/src/translation-response.js.map +1 -0
  171. package/src/typed-error.d.ts +73 -0
  172. package/src/typed-error.d.ts.map +1 -0
  173. package/src/typed-error.js +267 -0
  174. package/src/typed-error.js.map +1 -0
  175. package/src/typed-handleable.d.ts +15 -0
  176. package/src/typed-handleable.d.ts.map +1 -0
  177. package/src/typed-handleable.js +46 -0
  178. package/src/typed-handleable.js.map +1 -0
  179. package/src/{types.ts → types.d.ts} +21 -75
  180. package/src/types.d.ts.map +1 -0
  181. package/src/types.js +19 -0
  182. package/src/types.js.map +1 -0
  183. package/src/unified-translator.d.ts +31 -0
  184. package/src/unified-translator.d.ts.map +1 -0
  185. package/src/unified-translator.js +71 -0
  186. package/src/unified-translator.js.map +1 -0
  187. package/src/utils.d.ts +65 -0
  188. package/src/utils.d.ts.map +1 -0
  189. package/src/utils.js +129 -0
  190. package/src/utils.js.map +1 -0
  191. package/src/validation-config.d.ts +12 -0
  192. package/src/validation-config.d.ts.map +1 -0
  193. package/src/validation-config.js +3 -0
  194. package/src/validation-config.js.map +1 -0
  195. package/src/validation-result.d.ts +13 -0
  196. package/src/validation-result.d.ts.map +1 -0
  197. package/src/validation-result.js +3 -0
  198. package/src/validation-result.js.map +1 -0
  199. package/LICENSE +0 -21
  200. package/src/active-context.ts +0 -30
  201. package/src/component-definition.ts +0 -11
  202. package/src/component-registration.ts +0 -13
  203. package/src/component-registry.ts +0 -392
  204. package/src/context-error-type.ts +0 -3
  205. package/src/context-error.ts +0 -16
  206. package/src/context-manager.ts +0 -71
  207. package/src/context.ts +0 -90
  208. package/src/core-i18n.ts +0 -609
  209. package/src/core-string-key.ts +0 -49
  210. package/src/create-translation-adapter.ts +0 -47
  211. package/src/currency-code.ts +0 -35
  212. package/src/currency.ts +0 -52
  213. package/src/default-config.ts +0 -199
  214. package/src/enum-registry.ts +0 -138
  215. package/src/global-active-context.ts +0 -255
  216. package/src/handleable.ts +0 -79
  217. package/src/i-global-active-context.ts +0 -59
  218. package/src/i-handleable-error-options.ts +0 -6
  219. package/src/i-handleable.ts +0 -5
  220. package/src/i18n-config.ts +0 -29
  221. package/src/i18n-engine.ts +0 -491
  222. package/src/language-definition.ts +0 -13
  223. package/src/language-registry.ts +0 -292
  224. package/src/plugin-i18n-engine.ts +0 -520
  225. package/src/plugin-translatable-generic-error.ts +0 -106
  226. package/src/plugin-translatable-handleable-generic.ts +0 -60
  227. package/src/plugin-typed-handleable.ts +0 -77
  228. package/src/registry-config.ts +0 -15
  229. package/src/registry-error-type.ts +0 -12
  230. package/src/registry-error.ts +0 -74
  231. package/src/strict-types.ts +0 -35
  232. package/src/template.ts +0 -63
  233. package/src/timezone.ts +0 -20
  234. package/src/translatable.ts +0 -15
  235. package/src/translation-engine.ts +0 -8
  236. package/src/translation-request.ts +0 -12
  237. package/src/translation-response.ts +0 -8
  238. package/src/typed-error.ts +0 -384
  239. package/src/typed-handleable.ts +0 -70
  240. package/src/unified-translator.ts +0 -96
  241. package/src/utils.ts +0 -213
  242. package/src/validation-config.ts +0 -11
  243. package/src/validation-result.ts +0 -12
package/README.md CHANGED
@@ -125,58 +125,71 @@ yarn add @digitaldefiance/i18n-lib
125
125
  ## Quick Start
126
126
 
127
127
  ```typescript
128
- import { I18nEngine, I18nConfig, createContext, CurrencyCode, Timezone } from '@digitaldefiance/i18n-lib';
128
+ import {
129
+ PluginI18nEngine,
130
+ ComponentDefinition,
131
+ ComponentRegistration,
132
+ LanguageDefinition,
133
+ CurrencyCode,
134
+ Timezone,
135
+ } from '@digitaldefiance/i18n-lib';
129
136
 
130
- // Define your string keys
131
- enum MyStrings {
137
+ enum MyStringKey {
132
138
  Welcome = 'welcome',
133
- UserGreetingTemplate = 'userGreetingTemplate'
139
+ UserGreetingTemplate = 'userGreetingTemplate',
134
140
  }
135
141
 
136
- // Define your language codes (or use string literals)
137
142
  type MyLanguages = 'en-US' | 'es';
138
143
 
139
- // Configure the engine
140
- const config: I18nConfig<MyStrings, MyLanguages> = {
141
- stringNames: Object.values(MyStrings),
144
+ const languages: ReadonlyArray<LanguageDefinition> = [
145
+ { id: 'en-US', name: 'English (US)', code: 'en-US', isDefault: true },
146
+ { id: 'es', name: 'Español', code: 'es' },
147
+ ];
148
+
149
+ const engine = new PluginI18nEngine<MyLanguages>(languages, {
150
+ defaultCurrencyCode: new CurrencyCode('USD'),
151
+ timezone: new Timezone('UTC'),
152
+ adminTimezone: new Timezone('UTC'),
153
+ });
154
+
155
+ const MyComponent: ComponentDefinition<MyStringKey> = {
156
+ id: 'my-component',
157
+ name: 'My Component',
158
+ stringKeys: Object.values(MyStringKey),
159
+ };
160
+
161
+ const registration: ComponentRegistration<MyStringKey, MyLanguages> = {
162
+ component: MyComponent,
142
163
  strings: {
143
164
  'en-US': {
144
- [MyStrings.Welcome]: 'Welcome!',
145
- [MyStrings.UserGreetingTemplate]: 'Hello, {name}!'
165
+ [MyStringKey.Welcome]: 'Welcome!',
166
+ [MyStringKey.UserGreetingTemplate]: 'Hello, {name}!'
146
167
  },
147
168
  'es': {
148
- [MyStrings.Welcome]: '¡Bienvenido!',
149
- [MyStrings.UserGreetingTemplate]: '¡Hola, {name}!'
169
+ [MyStringKey.Welcome]: '¡Bienvenido!',
170
+ [MyStringKey.UserGreetingTemplate]: '¡Hola, {name}!'
150
171
  }
151
- },
152
- defaultLanguage: 'en-US',
153
- defaultTranslationContext: 'user',
154
- defaultCurrencyCode: new CurrencyCode('USD'),
155
- languageCodes: {
156
- 'en-US': 'en-US',
157
- 'es': 'es'
158
- },
159
- languages: ['en-US', 'es'],
160
- timezone: new Timezone('UTC'),
161
- adminTimezone: new Timezone('UTC')
172
+ }
162
173
  };
163
174
 
164
- // Create engine
165
- const i18n = new I18nEngine(config);
175
+ engine.registerComponent(registration);
166
176
 
167
- // Translate strings
168
- const welcome = i18n.translate(MyStrings.Welcome);
177
+ const welcome = engine.translate('my-component', MyStringKey.Welcome);
169
178
  // "Welcome!"
170
179
 
171
- const greeting = i18n.translate(MyStrings.UserGreetingTemplate, { name: 'John' });
180
+ const greeting = engine.translate('my-component', MyStringKey.UserGreetingTemplate, { name: 'John' });
172
181
  // "Hello, John!"
173
182
 
174
- // Change language
175
- i18n.context = { language: 'es' };
176
- const spanishGreeting = i18n.translate(MyStrings.UserGreetingTemplate, { name: 'Juan' });
183
+ engine.setLanguage('es');
184
+ const spanishGreeting = engine.translate('my-component', MyStringKey.UserGreetingTemplate, { name: 'Juan' });
177
185
  // "¡Hola, Juan!"
186
+
187
+ const templated = engine.t('User: {name} → {{my-component.UserGreetingTemplate}}', 'es', { name: 'Laura' });
188
+ // "User: Laura → ¡Hola, Laura!"
178
189
  ```
179
190
 
191
+ The constructor automatically registers the provided languages, seeds the global context (language, currency, timezone), and makes the instance discoverable through `PluginI18nEngine.getInstance()`. Prefer `setLanguage` or `updateContext({ language: 'es' })` instead of mutating context objects directly.
192
+
180
193
  ## Core Components
181
194
 
182
195
  The library is built around several key components that work together to provide comprehensive i18n support:
@@ -427,7 +440,7 @@ const i18n = createCoreI18nEngine('myapp');
427
440
  const lang: CoreLanguageCode = LanguageCodes.FR; // Type-checked!
428
441
 
429
442
  // Get supported language codes from registry (runtime)
430
- const supportedLanguages = i18n.getLanguageRegistry().getLanguageIds();
443
+ const supportedLanguages = i18n.getLanguages().map((lang) => lang.id);
431
444
  // ['en-US', 'en-GB', 'fr', 'es', 'de', 'zh-CN', 'ja', 'uk']
432
445
 
433
446
  // Use core translations with type safety
@@ -1040,6 +1053,13 @@ const strictEngine = new PluginI18nEngine(languages, {
1040
1053
  fallbackLanguageId: 'en-US'
1041
1054
  }
1042
1055
  });
1056
+
1057
+ // Optional instance registration overrides (third constructor argument)
1058
+ const reportingEngine = new PluginI18nEngine(languages, {}, {
1059
+ instanceKey: 'reporting',
1060
+ registerInstance: false,
1061
+ setAsDefault: false
1062
+ });
1043
1063
  ```
1044
1064
 
1045
1065
  #### Multi-Instance Support
@@ -1052,6 +1072,10 @@ const userI18n = PluginI18nEngine.createInstance('user', languages);
1052
1072
  // Register different components for each
1053
1073
  adminI18n.registerComponent(adminComponentRegistration);
1054
1074
  userI18n.registerComponent(userComponentRegistration);
1075
+
1076
+ // Create an isolated instance without touching the global registry (handy for tests)
1077
+ const detachedI18n = new PluginI18nEngine(languages, {}, { registerInstance: false });
1078
+ detachedI18n.registerComponent(myTestRegistration);
1055
1079
  ```
1056
1080
 
1057
1081
  For complete documentation on the plugin architecture, see [PLUGIN_ARCHITECTURE.md](./PLUGIN_ARCHITECTURE.md).
@@ -1178,51 +1202,60 @@ const statusText = i18n.translateEnum(Status, Status.Active, MyLanguages.Spanish
1178
1202
  ### Template Processing
1179
1203
 
1180
1204
  ```typescript
1181
- enum AppStrings {
1182
- WelcomeMessage = 'welcomeMessage',
1183
- UserGreetingTemplate = 'userGreetingTemplate'
1184
- }
1185
-
1186
- const config: I18nConfig<AppStrings, MyLanguages> = {
1187
- // ... other config
1188
- enumName: 'AppStrings',
1189
- enumObj: AppStrings,
1190
- strings: {
1191
- [MyLanguages.English]: {
1192
- [AppStrings.WelcomeMessage]: 'Welcome to our app!',
1193
- [AppStrings.UserGreetingTemplate]: 'Hello, {name}!'
1194
- }
1195
- }
1196
- };
1205
+ import { PluginI18nEngine } from '@digitaldefiance/i18n-lib';
1197
1206
 
1198
- const i18n = new I18nEngine(config);
1207
+ const engine = PluginI18nEngine.getInstance<'en-US' | 'es'>();
1199
1208
 
1200
- // Use template processor
1201
- const message = i18n.t('{{AppStrings.WelcomeMessage}} {{AppStrings.UserGreetingTemplate}}',
1202
- MyLanguages.English,
1209
+ // Component placeholders are resolved before variable replacement
1210
+ const message = engine.t(
1211
+ '{{core.System_Welcome}} {name}! {{core.System_PleaseWait}}',
1212
+ 'en-US',
1203
1213
  { name: 'John' }
1204
1214
  );
1205
- // "Welcome to our app! Hello, John!"
1215
+ // "Welcome John! Please wait..."
1216
+
1217
+ // Templates ending with "Template" automatically receive the first var map
1218
+ const greeting = engine.t(
1219
+ '{{my-component.UserGreetingTemplate}}',
1220
+ 'es',
1221
+ { name: 'Laura' },
1222
+ { fallbackName: 'Usuario' }
1223
+ );
1224
+ // "¡Hola, Laura!"
1225
+
1226
+ // Additional variable objects are merged left→right
1227
+ const merged = engine.t(
1228
+ 'User {username} has {count} notifications',
1229
+ 'en-US',
1230
+ { username: 'alice' },
1231
+ { count: 5 }
1232
+ );
1233
+ // "User alice has 5 notifications"
1206
1234
  ```
1207
1235
 
1208
1236
  ### Context Management
1209
1237
 
1210
1238
  ```typescript
1211
- import { createContext, setLanguage, setAdminLanguage, setContext } from '@digitaldefiance/i18n-lib';
1239
+ import { PluginI18nEngine, CurrencyCode, Timezone } from '@digitaldefiance/i18n-lib';
1240
+
1241
+ const engine = PluginI18nEngine.getInstance<'en-US' | 'es'>();
1212
1242
 
1213
- // Create and manage context
1214
- const context = createContext(MyLanguages.English, 'user');
1243
+ engine.updateContext({
1244
+ language: 'es',
1245
+ adminLanguage: 'en-US',
1246
+ currencyCode: new CurrencyCode('EUR'),
1247
+ timezone: new Timezone('Europe/Madrid'),
1248
+ adminTimezone: new Timezone('UTC'),
1249
+ });
1215
1250
 
1216
- // Set different languages for user and admin contexts
1217
- setLanguage(context, MyLanguages.Spanish);
1218
- setAdminLanguage(context, MyLanguages.English);
1251
+ engine.updateContext({ currentContext: 'admin' });
1219
1252
 
1220
- // Switch between contexts
1221
- setContext(context, 'admin'); // Uses admin language
1222
- setContext(context, 'user'); // Uses user language
1253
+ const context = engine.getContext();
1254
+ console.log(context.currentContext); // 'admin'
1255
+ console.log(context.language); // 'es'
1223
1256
 
1224
- // Apply context to engine
1225
- i18n.context = context;
1257
+ engine.updateContext({ currentContext: 'user' });
1258
+ engine.setLanguage('en-US');
1226
1259
  ```
1227
1260
 
1228
1261
  ### Context Change Monitoring
@@ -1266,16 +1299,23 @@ const eurFormat = getCurrencyFormat('de-DE', 'EUR');
1266
1299
  ### Instance Management
1267
1300
 
1268
1301
  ```typescript
1302
+ import { PluginI18nEngine, LanguageDefinition } from '@digitaldefiance/i18n-lib';
1303
+
1304
+ const languages: ReadonlyArray<LanguageDefinition> = [
1305
+ { id: 'en-US', name: 'English (US)', code: 'en-US', isDefault: true },
1306
+ { id: 'fr', name: 'Français', code: 'fr' },
1307
+ ];
1308
+
1269
1309
  // Create named instances
1270
- const mainI18n = new I18nEngine(config, 'main');
1271
- const adminI18n = new I18nEngine(adminConfig, 'admin');
1310
+ const mainI18n = PluginI18nEngine.createInstance('main', languages);
1311
+ const adminI18n = PluginI18nEngine.createInstance('admin', languages);
1272
1312
 
1273
1313
  // Get instances by key
1274
- const instance = I18nEngine.getInstance('main');
1314
+ const instance = PluginI18nEngine.getInstance('main');
1275
1315
 
1276
1316
  // Clean up instances (useful for testing)
1277
- I18nEngine.clearInstances();
1278
- I18nEngine.removeInstance('main');
1317
+ PluginI18nEngine.removeInstance('main');
1318
+ PluginI18nEngine.resetAll();
1279
1319
  ```
1280
1320
 
1281
1321
  ## Supported Languages
@@ -1355,7 +1395,7 @@ const lang3: MyLanguageCode = 'invalid'; // ✗ Type error!
1355
1395
  Extract language codes from the registry (single source of truth):
1356
1396
 
1357
1397
  ```typescript
1358
- import { PluginI18nEngine, getCoreLanguageCodes, LanguageCodes } from '@digitaldefiance/i18n-lib';
1398
+ import { PluginI18nEngine, LanguageRegistry, getCoreLanguageCodes, LanguageCodes } from '@digitaldefiance/i18n-lib';
1359
1399
  import { Schema } from 'mongoose';
1360
1400
 
1361
1401
  // Static approach: Get core language codes as array
@@ -1364,8 +1404,9 @@ const coreLanguageCodes = getCoreLanguageCodes();
1364
1404
 
1365
1405
  // Dynamic approach: Get from engine instance (includes custom languages)
1366
1406
  const engine = PluginI18nEngine.getInstance<string>();
1367
- const languageIds = engine.getLanguageRegistry().getLanguageIds();
1368
- const isoCodes = engine.getLanguageRegistry().getLanguageCodes();
1407
+ const languageDefinitions = engine.getLanguages();
1408
+ const languageIds = languageDefinitions.map((lang) => lang.id);
1409
+ const isoCodes = languageDefinitions.map((lang) => lang.code);
1369
1410
 
1370
1411
  // Use in Mongoose schema
1371
1412
  const userSchema = new Schema({
@@ -1382,7 +1423,7 @@ const userSchema = new Schema({
1382
1423
  });
1383
1424
 
1384
1425
  // Get display names for validation messages
1385
- const displayNames = engine.getLanguageRegistry().getLanguageDisplayNames();
1426
+ const displayNames = LanguageRegistry.getLanguageDisplayNames();
1386
1427
  // { 'en-US': 'English (US)', 'fr': 'Français', ... }
1387
1428
  ```
1388
1429
 
@@ -1424,10 +1465,16 @@ The core component provides 40+ system strings organized by category:
1424
1465
 
1425
1466
  **Constructor**
1426
1467
 
1427
- - `new PluginI18nEngine<TLanguages>(languages, config?)` - Create new plugin engine
1468
+ - `new PluginI18nEngine<TLanguages>(languages, config?, options?)` - Create new plugin engine
1428
1469
  - `PluginI18nEngine.createInstance<TLanguages>(key, languages, config?)` - Create named instance
1429
1470
  - `PluginI18nEngine.getInstance<TLanguages>(key?)` - Get existing instance (throws error if not found)
1430
1471
 
1472
+ `options` enables fine-grained control over how the engine participates in the static registry:
1473
+
1474
+ - `instanceKey` – Override the implicit registry key when instantiating directly (defaults to `'default'`).
1475
+ - `registerInstance` – Set to `false` to keep the engine out of the shared instance map (useful for tests or short-lived contexts).
1476
+ - `setAsDefault` – Force this instance to become the default lookup target even if another default exists.
1477
+
1431
1478
  **Component Management**
1432
1479
 
1433
1480
  - `registerComponent<TStringKeys>(registration)` - Register component with translations
@@ -1451,11 +1498,14 @@ The core component provides 40+ system strings organized by category:
1451
1498
  - `getLanguageByCode(code)` - Get language by ISO code
1452
1499
  - `getMatchingLanguageCode(requestedCode?, userDefaultCode?)` - Get matching language code with fallback logic
1453
1500
 
1454
- **Validation**
1501
+ **Context & Validation**
1455
1502
 
1503
+ - `getContext()` - Read the active context (language, adminLanguage, currency, timezone)
1504
+ - `updateContext(updates)` - Apply partial context updates
1456
1505
  - `validateAllComponents()` - Validate all registered components
1457
- - `getLanguageRegistry()` - Access language registry directly
1458
1506
  - `getComponentRegistry()` - Access component registry directly
1507
+ - `getEnumRegistry()` - Access enum registry directly
1508
+ - Use `LanguageRegistry` statics (e.g. `LanguageRegistry.getLanguageIds()`) for low-level language metadata
1459
1509
 
1460
1510
  #### Core I18n Functions
1461
1511
 
@@ -2021,15 +2071,13 @@ export const User = model('User', userSchema);
2021
2071
  ### Dynamic Language Enum from Engine
2022
2072
 
2023
2073
  ```typescript
2024
- import { PluginI18nEngine } from '@digitaldefiance/i18n-lib';
2074
+ import { PluginI18nEngine, LanguageRegistry } from '@digitaldefiance/i18n-lib';
2025
2075
 
2026
- // Get languages from engine instance
2076
+ // Ensure the engine has registered its languages
2027
2077
  const engine = PluginI18nEngine.getInstance();
2028
- const registry = engine.getLanguageRegistry();
2029
-
2030
- // Extract for Mongoose
2031
- const languageEnum = registry.getLanguageIds();
2032
- const defaultLanguage = registry.getDefaultLanguageId();
2078
+ const languageEnum = LanguageRegistry.getLanguageIds();
2079
+ const defaultLanguage =
2080
+ LanguageRegistry.getDefaultLanguageId() ?? engine.getContext().language;
2033
2081
 
2034
2082
  const contentSchema = new Schema({
2035
2083
  language: {
@@ -2043,10 +2091,9 @@ const contentSchema = new Schema({
2043
2091
  ### Validation with Display Names
2044
2092
 
2045
2093
  ```typescript
2046
- import { PluginI18nEngine } from '@digitaldefiance/i18n-lib';
2094
+ import { LanguageRegistry } from '@digitaldefiance/i18n-lib';
2047
2095
 
2048
- const engine = PluginI18nEngine.getInstance();
2049
- const displayNames = engine.getLanguageRegistry().getLanguageDisplayNames();
2096
+ const displayNames = LanguageRegistry.getLanguageDisplayNames();
2050
2097
 
2051
2098
  const settingsSchema = new Schema({
2052
2099
  language: {
@@ -2274,6 +2321,15 @@ For issues, questions, or contributions:
2274
2321
 
2275
2322
  ## ChangeLog
2276
2323
 
2324
+ ### Version 1.3.15
2325
+
2326
+ - Improve constructor for default instances
2327
+ - Update README
2328
+
2329
+ ### Version 1.3.14
2330
+
2331
+ - Re-export with js again
2332
+
2277
2333
  ### Version 1.3.13
2278
2334
 
2279
2335
  - Migrate to es2022/nx monorepo
@@ -2327,7 +2383,7 @@ For issues, questions, or contributions:
2327
2383
  ### Version 1.3.1
2328
2384
 
2329
2385
  - **Changed**: `CoreLanguageCode` is now `string` - Language Registry is single source of truth
2330
- - Use `engine.getLanguageRegistry().getLanguageIds()` for runtime validation
2386
+ - Use `LanguageRegistry.getLanguageIds()` for runtime validation
2331
2387
  - Use `getCoreLanguageCodes()` for static arrays (Mongoose schemas, etc.)
2332
2388
  - Runtime validation via registry, not compile-time types
2333
2389
  - **Added**: `getCoreLanguageCodes()` - Get core language codes as runtime array
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@digitaldefiance/i18n-lib",
3
- "version": "1.3.13",
3
+ "version": "1.3.15",
4
4
  "description": "i18n library with enum translation support",
5
5
  "main": "src/index.js",
6
6
  "types": "src/index.d.ts",
@@ -33,5 +33,6 @@
33
33
  "dependencies": {
34
34
  "moment": "^2.30.1",
35
35
  "moment-timezone": "^0.6.0"
36
- }
37
- }
36
+ },
37
+ "type": "commonjs"
38
+ }
@@ -0,0 +1,30 @@
1
+ import { CurrencyCode } from './currency-code';
2
+ import { Timezone } from './timezone';
3
+ import { LanguageContextSpace } from './types';
4
+ export interface IActiveContext<TLanguage extends string> {
5
+ /**
6
+ * The default language for the user facing application
7
+ */
8
+ language: TLanguage;
9
+ /**
10
+ * The default language for the admin interface
11
+ */
12
+ adminLanguage: TLanguage;
13
+ /**
14
+ * The default currency code for the user facing application
15
+ */
16
+ currencyCode: CurrencyCode;
17
+ /**
18
+ * The default language context for the current context
19
+ */
20
+ currentContext: LanguageContextSpace;
21
+ /**
22
+ * The default timezone for the user facing application
23
+ */
24
+ timezone: Timezone;
25
+ /**
26
+ * The default timezone for the admin interface
27
+ */
28
+ adminTimezone: Timezone;
29
+ }
30
+ //# sourceMappingURL=active-context.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"active-context.d.ts","sourceRoot":"","sources":["../../../../packages/digitaldefiance-i18n-lib/src/active-context.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAC;AAC/C,OAAO,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AACtC,OAAO,EAAE,oBAAoB,EAAE,MAAM,SAAS,CAAC;AAE/C,MAAM,WAAW,cAAc,CAAC,SAAS,SAAS,MAAM;IACtD;;OAEG;IACH,QAAQ,EAAE,SAAS,CAAC;IACpB;;OAEG;IACH,aAAa,EAAE,SAAS,CAAC;IACzB;;OAEG;IACH,YAAY,EAAE,YAAY,CAAC;IAC3B;;OAEG;IACH,cAAc,EAAE,oBAAoB,CAAC;IACrC;;OAEG;IACH,QAAQ,EAAE,QAAQ,CAAC;IACnB;;OAEG;IACH,aAAa,EAAE,QAAQ,CAAC;CACzB"}
@@ -0,0 +1,3 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ //# sourceMappingURL=active-context.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"active-context.js","sourceRoot":"","sources":["../../../../packages/digitaldefiance-i18n-lib/src/active-context.ts"],"names":[],"mappings":""}
@@ -0,0 +1,12 @@
1
+ /**
2
+ * Component definition with its string keys
3
+ */
4
+ export interface ComponentDefinition<TStringKeys extends string> {
5
+ /** Unique identifier for the component */
6
+ readonly id: string;
7
+ /** Human-readable name for the component */
8
+ readonly name: string;
9
+ /** Array of all string keys this component requires */
10
+ readonly stringKeys: readonly TStringKeys[];
11
+ }
12
+ //# sourceMappingURL=component-definition.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"component-definition.d.ts","sourceRoot":"","sources":["../../../../packages/digitaldefiance-i18n-lib/src/component-definition.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,MAAM,WAAW,mBAAmB,CAAC,WAAW,SAAS,MAAM;IAC7D,0CAA0C;IAC1C,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;IACpB,4CAA4C;IAC5C,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,uDAAuD;IACvD,QAAQ,CAAC,UAAU,EAAE,SAAS,WAAW,EAAE,CAAC;CAC7C"}
@@ -0,0 +1,3 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ //# sourceMappingURL=component-definition.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"component-definition.js","sourceRoot":"","sources":["../../../../packages/digitaldefiance-i18n-lib/src/component-definition.ts"],"names":[],"mappings":""}
@@ -0,0 +1,10 @@
1
+ import { ComponentDefinition } from './component-definition';
2
+ import { PartialComponentLanguageStrings } from './types';
3
+ /**
4
+ * Registration payload for a component with its strings
5
+ */
6
+ export interface ComponentRegistration<TStringKeys extends string, TLanguages extends string> {
7
+ readonly component: ComponentDefinition<TStringKeys>;
8
+ readonly strings: PartialComponentLanguageStrings<TStringKeys, TLanguages>;
9
+ }
10
+ //# sourceMappingURL=component-registration.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"component-registration.d.ts","sourceRoot":"","sources":["../../../../packages/digitaldefiance-i18n-lib/src/component-registration.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,mBAAmB,EAAE,MAAM,wBAAwB,CAAC;AAC7D,OAAO,EAAE,+BAA+B,EAAE,MAAM,SAAS,CAAC;AAE1D;;GAEG;AACH,MAAM,WAAW,qBAAqB,CACpC,WAAW,SAAS,MAAM,EAC1B,UAAU,SAAS,MAAM;IAEzB,QAAQ,CAAC,SAAS,EAAE,mBAAmB,CAAC,WAAW,CAAC,CAAC;IACrD,QAAQ,CAAC,OAAO,EAAE,+BAA+B,CAAC,WAAW,EAAE,UAAU,CAAC,CAAC;CAC5E"}
@@ -0,0 +1,3 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ //# sourceMappingURL=component-registration.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"component-registration.js","sourceRoot":"","sources":["../../../../packages/digitaldefiance-i18n-lib/src/component-registration.ts"],"names":[],"mappings":""}
@@ -0,0 +1,69 @@
1
+ /**
2
+ * Component registry for managing internationalization components and their string translations
3
+ */
4
+ import { ComponentDefinition } from './component-definition';
5
+ import { ComponentRegistration } from './component-registration';
6
+ import { TranslationRequest } from './translation-request';
7
+ import { TranslationResponse } from './translation-response';
8
+ import { ComponentLanguageStrings, PartialComponentLanguageStrings } from './types';
9
+ import { ValidationConfig } from './validation-config';
10
+ import { ValidationResult } from './validation-result';
11
+ /**
12
+ * Registry for managing components and their translations
13
+ */
14
+ export declare class ComponentRegistry<TLanguages extends string> {
15
+ private readonly components;
16
+ private readonly componentStrings;
17
+ private readonly validationConfig;
18
+ private readonly registeredLanguages;
19
+ constructor(languages: readonly TLanguages[], validationConfig: ValidationConfig);
20
+ /**
21
+ * Update the set of registered languages (for dynamic language addition)
22
+ */
23
+ updateRegisteredLanguages(languages: readonly TLanguages[]): void;
24
+ /**
25
+ * Register a new component with its translations
26
+ */
27
+ registerComponent<TStringKeys extends string>(registration: ComponentRegistration<TStringKeys, TLanguages>): ValidationResult;
28
+ /**
29
+ * Update strings for an existing component
30
+ */
31
+ updateComponentStrings<TStringKeys extends string>(componentId: string, strings: PartialComponentLanguageStrings<TStringKeys, TLanguages>): ValidationResult;
32
+ /**
33
+ * Get a translation for a specific component, string key, and language
34
+ */
35
+ getTranslation<TStringKeys extends string>(request: TranslationRequest<TStringKeys, TLanguages>): TranslationResponse;
36
+ /**
37
+ * Get all registered components
38
+ */
39
+ getComponents(): ReadonlyArray<ComponentDefinition<any>>;
40
+ /**
41
+ * Get a specific component by ID
42
+ */
43
+ getComponent<TStringKeys extends string>(componentId: string): ComponentDefinition<TStringKeys> | undefined;
44
+ /**
45
+ * Check if a component is registered
46
+ */
47
+ hasComponent(componentId: string): boolean;
48
+ /**
49
+ * Get all strings for a component in all languages
50
+ */
51
+ getComponentStrings<TStringKeys extends string>(componentId: string): ComponentLanguageStrings<TStringKeys, TLanguages> | undefined;
52
+ /**
53
+ * Validate a component registration
54
+ */
55
+ private validateComponentRegistration;
56
+ /**
57
+ * Complete missing strings with fallbacks
58
+ */
59
+ private completeStringsWithFallbacks;
60
+ /**
61
+ * Merge existing strings with new strings
62
+ */
63
+ private mergeStrings;
64
+ /**
65
+ * Clear all components and their strings (useful for testing)
66
+ */
67
+ clearAllComponents(): void;
68
+ }
69
+ //# sourceMappingURL=component-registry.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"component-registry.d.ts","sourceRoot":"","sources":["../../../../packages/digitaldefiance-i18n-lib/src/component-registry.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,mBAAmB,EAAE,MAAM,wBAAwB,CAAC;AAC7D,OAAO,EAAE,qBAAqB,EAAE,MAAM,0BAA0B,CAAC;AAGjE,OAAO,EAAE,kBAAkB,EAAE,MAAM,uBAAuB,CAAC;AAC3D,OAAO,EAAE,mBAAmB,EAAE,MAAM,wBAAwB,CAAC;AAC7D,OAAO,EACL,wBAAwB,EAExB,+BAA+B,EAEhC,MAAM,SAAS,CAAC;AAEjB,OAAO,EAAE,gBAAgB,EAAE,MAAM,qBAAqB,CAAC;AACvD,OAAO,EAAE,gBAAgB,EAAE,MAAM,qBAAqB,CAAC;AAEvD;;GAEG;AACH,qBAAa,iBAAiB,CAAC,UAAU,SAAS,MAAM;IACtD,OAAO,CAAC,QAAQ,CAAC,UAAU,CAA+C;IAC1E,OAAO,CAAC,QAAQ,CAAC,gBAAgB,CAG7B;IACJ,OAAO,CAAC,QAAQ,CAAC,gBAAgB,CAAmB;IACpD,OAAO,CAAC,QAAQ,CAAC,mBAAmB,CAAkB;gBAGpD,SAAS,EAAE,SAAS,UAAU,EAAE,EAChC,gBAAgB,EAAE,gBAAgB;IAMpC;;OAEG;IACI,yBAAyB,CAAC,SAAS,EAAE,SAAS,UAAU,EAAE,GAAG,IAAI;IAKxE;;OAEG;IACI,iBAAiB,CAAC,WAAW,SAAS,MAAM,EACjD,YAAY,EAAE,qBAAqB,CAAC,WAAW,EAAE,UAAU,CAAC,GAC3D,gBAAgB;IA6CnB;;OAEG;IACI,sBAAsB,CAAC,WAAW,SAAS,MAAM,EACtD,WAAW,EAAE,MAAM,EACnB,OAAO,EAAE,+BAA+B,CAAC,WAAW,EAAE,UAAU,CAAC,GAChE,gBAAgB;IAoCnB;;OAEG;IACI,cAAc,CAAC,WAAW,SAAS,MAAM,EAC9C,OAAO,EAAE,kBAAkB,CAAC,WAAW,EAAE,UAAU,CAAC,GACnD,mBAAmB;IAwEtB;;OAEG;IACI,aAAa,IAAI,aAAa,CAAC,mBAAmB,CAAC,GAAG,CAAC,CAAC;IAI/D;;OAEG;IACI,YAAY,CAAC,WAAW,SAAS,MAAM,EAC5C,WAAW,EAAE,MAAM,GAClB,mBAAmB,CAAC,WAAW,CAAC,GAAG,SAAS;IAM/C;;OAEG;IACI,YAAY,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO;IAIjD;;OAEG;IACI,mBAAmB,CAAC,WAAW,SAAS,MAAM,EACnD,WAAW,EAAE,MAAM,GAClB,wBAAwB,CAAC,WAAW,EAAE,UAAU,CAAC,GAAG,SAAS;IAMhE;;OAEG;IACH,OAAO,CAAC,6BAA6B;IAyDrC;;OAEG;IACH,OAAO,CAAC,4BAA4B;IAkCpC;;OAEG;IACH,OAAO,CAAC,YAAY;IA+BpB;;OAEG;IACI,kBAAkB,IAAI,IAAI;CAIlC"}