ngx-kit 9.0.0 → 9.1.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.
@@ -17,21 +17,22 @@ Flat keys, route-level scopes, pipe, directives, fallbacks and a key extractor C
17
17
 
18
18
  1. [Install](#install)
19
19
  2. [Quick start](#quick-start)
20
- 3. [Concepts](#concepts)
21
- 4. [Using translations](#using-translations)
22
- 5. [Scopes and routing](#scopes-and-routing)
23
- 6. [Language switching](#language-switching)
24
- 7. [Fallbacks and missing keys](#fallbacks-and-missing-keys)
25
- 8. [Interpolation, plurals and ICU](#interpolation-plurals-and-icu)
26
- 9. [Loaders](#loaders)
27
- 10. [Key extractor CLI](#key-extractor-cli)
28
- 11. [Configuration reference](#configuration-reference)
29
- 12. [API reference](#api-reference)
30
- 13. [Testing your app](#testing-your-app)
31
- 14. [Performance notes](#performance-notes)
32
- 15. [Migrating from Transloco](#migrating-from-transloco)
33
- 16. [Limitations](#limitations)
34
- 17. [Developing this library](#developing-this-library)
20
+ 3. [Deferred configuration (languages from the backend)](#deferred-configuration-languages-from-the-backend)
21
+ 4. [Concepts](#concepts)
22
+ 5. [Using translations](#using-translations)
23
+ 6. [Scopes and routing](#scopes-and-routing)
24
+ 7. [Language switching](#language-switching)
25
+ 8. [Fallbacks and missing keys](#fallbacks-and-missing-keys)
26
+ 9. [Interpolation, plurals and ICU](#interpolation-plurals-and-icu)
27
+ 10. [Loaders](#loaders)
28
+ 11. [Key extractor CLI](#key-extractor-cli)
29
+ 12. [Configuration reference](#configuration-reference)
30
+ 13. [API reference](#api-reference)
31
+ 14. [Testing your app](#testing-your-app)
32
+ 15. [Performance notes](#performance-notes)
33
+ 16. [Migrating from Transloco](#migrating-from-transloco)
34
+ 17. [Limitations](#limitations)
35
+ 18. [Developing this library](#developing-this-library)
35
36
 
36
37
  ---
37
38
 
@@ -116,6 +117,62 @@ export class RequestsComponent {
116
117
  }
117
118
  ```
118
119
 
120
+ ## Deferred configuration (languages from the backend)
121
+
122
+ Often the list of languages, the default language and the user's saved language only exist **after** your own
123
+ `APP_INITIALIZER` has talked to the backend. Do not try to build the config earlier (no `setTimeout`, no mutating
124
+ the config token, no async `useFactory`): provide the library **without** languages and finish the setup with
125
+ `I18nService.init()` when you know them.
126
+
127
+ ```ts
128
+ // app.config.ts
129
+ provideHttpClient(),
130
+ provideI18n({ fallbackLangs: ['fa'] }), // no langs/defaultLang -> no automatic initializer
131
+ provideAppInitializer(() => AppInitializer()),
132
+ ```
133
+
134
+ ```ts
135
+ // app-initializer.ts
136
+ export async function AppInitializer(): Promise<void> {
137
+ const http = inject(HttpClient);
138
+ const platformLocation = inject(PlatformLocation);
139
+ const i18n = inject(I18nService);
140
+ inject(ColorSchemaService).load();
141
+
142
+ // 1) appconfig.json 2) /api/Common/InitialApp (as you do today)
143
+ const config = await firstValueFrom(http.get<any>(configUrl(platformLocation)));
144
+ AppConst.apiUrl = config.apiUrl; /* … */
145
+ const resp = await firstValueFrom(http.get<InitialAppDto>(AppConst.apiUrl + '/api/Common/InitialApp'));
146
+ AppConst.languageList = resp.languages ?? [];
147
+ AppConst.defaultLang = resp.defaultLang ?? 'fa';
148
+
149
+ // 3) finish the i18n setup and load the first language. AWAIT it: the app starts when translations are ready.
150
+ await i18n.init({
151
+ langs: AppConst.languageList.map((l) => l.culture),
152
+ defaultLang: AppConst.defaultLang,
153
+ baseUrl: AppConst.apiUrl, // read at request time, so a value known only now is fine
154
+ lang: AppConst.currentLanguage, // optional: user's saved language; ignored if not in `langs`
155
+ });
156
+ }
157
+ ```
158
+
159
+ What `init()` does: merges the options into the live config (`configure()`), picks the language
160
+ (`lang` if supported, otherwise stored > browser (opt-in) > `defaultLang`), downloads the global file, every scope
161
+ registered so far and the fallback languages, and only then activates the language. It rejects if loading fails, so
162
+ you can catch it in the initializer and show an error page.
163
+
164
+ Notes:
165
+
166
+ - `loader` and `autoInit` can only be set in `provideI18n()`. Everything else can be changed later with
167
+ `i18n.configure({...})`; files that are already downloaded stay cached.
168
+ - When `langs` **and** `defaultLang` are given to `provideI18n()`, an initializer is added automatically
169
+ (`autoInit` defaults to `true`). Use `autoInit: false` if you prefer to call `init()` yourself.
170
+ - `i18n.langs` is a **signal** (`i18n.langs()`) because the list can arrive after startup. `i18n.ready()` becomes
171
+ `true` after the first language is active.
172
+ - Scopes registered before `init()` (for example by an early service) are remembered and loaded by `init()`.
173
+ `whenReady()` and `i18nReadyGuard` also wait for an in-flight `init()` / `use()`.
174
+ - Do not call `use()` without awaiting it inside an initializer: the app would start before the files arrive.
175
+
119
176
  ## Concepts
120
177
 
121
178
  | Term | Meaning |
@@ -250,6 +307,11 @@ Use a real ICU library (for example `intl-messageformat`) inside `transpile` for
250
307
 
251
308
  The default `HttpI18nLoader` uses `HttpClient`, so your interceptors (auth, base URL, retry) apply.
252
309
 
310
+ URLs are built as `{baseUrl}/{scope}/{lang}{fileExtension}` (global file: `{baseUrl}/{lang}{fileExtension}`).
311
+ The builder is safe by construction: a missing scope never becomes `undefined`, repeated or trailing slashes
312
+ are collapsed (`'https://api.x.com/'` + no scope -> `https://api.x.com/fa.json`), and the extension may be written
313
+ with or without the dot. `buildI18nUrl()` is exported if you need the same logic in a custom loader.
314
+
253
315
  ```ts
254
316
  provideI18n({
255
317
  …,
@@ -333,15 +395,16 @@ Add to `package.json` scripts: `"i18n": "ngx-lazy-i18n-extract"`, `"i18n:check":
333
395
 
334
396
  | Option | Type | Default | Description |
335
397
  |---|---|---|---|
336
- | `langs` | `string[]` | required | Supported languages. |
337
- | `defaultLang` | `string` | required | Used when nothing is stored or detected. |
398
+ | `langs` | `string[]` | required before first activation | Supported languages. May be supplied later with `init()`. |
399
+ | `defaultLang` | `string` | required before first activation | Used when nothing is stored or detected. May be supplied later. |
400
+ | `autoInit` | `boolean` | `true` if `langs` and `defaultLang` are given | Add an APP_INITIALIZER that activates the initial language. Provide-time only. |
338
401
  | `fallbackLangs` | `string[]` | `[]` | Languages tried, in order, for missing/empty keys. |
339
402
  | `missing` | `'key' \| 'empty' \| (key, lang) => string` | `'key'` | What to render for a missing key. |
340
403
  | `warnMissing` | `boolean` | `isDevMode()` | Log each missing key once. |
341
404
  | `transpile` | `(value, params, lang) => string` | built-in `{{ }}` | Custom message formatter. |
342
405
  | `loader` | `Type<I18nLoader>` | `HttpI18nLoader` | Custom loader class. |
343
406
  | `baseUrl` | `string` | `'/i18n'` | HTTP loader base. |
344
- | `fileExtension` | `string` | `''` | HTTP loader extension (e.g. `.json`). |
407
+ | `fileExtension` | `string` | `'.json'` | HTTP loader extension; `''` for none. |
345
408
  | `url` | `(lang, scope?) => string` | none | HTTP loader full URL control. |
346
409
  | `retries` | `number` | `1` | Retries per failed request (250 ms delay). |
347
410
  | `storageKey` | `string \| null` | `'lazy-i18n.lang'` | Persist language; `null` disables. |
@@ -363,7 +426,10 @@ Add to `package.json` scripts: `"i18n": "ngx-lazy-i18n-extract"`, `"i18n:check":
363
426
  | `lang: Signal<string>` | Active language. |
364
427
  | `dir: Signal<'rtl' \| 'ltr'>` | Direction for the active language. |
365
428
  | `revision: Signal<number>` | Changes on every language/dictionary change. |
366
- | `langs: readonly string[]` | Supported languages. |
429
+ | `langs: Signal<readonly string[]>` | Supported languages (reactive; may arrive after startup). |
430
+ | `ready: Signal<boolean>` | `true` after the first language is active. |
431
+ | `init({ langs, defaultLang, baseUrl, lang, … })` | Complete the config and activate the first language. Use in your own initializer. |
432
+ | `configure(patch)` | Change options after startup (not `loader`/`autoInit`). |
367
433
  | `t(key, params?)` | Translate (reactive). |
368
434
  | `instant(key, params?)` | Translate (non-reactive). |
369
435
  | `select(key, params?)` | `Signal<string>`; `params` may be a function. |
@@ -371,7 +437,7 @@ Add to `package.json` scripts: `"i18n": "ngx-lazy-i18n-extract"`, `"i18n:check":
371
437
  | `use(lang)` | Load everything, then activate. |
372
438
  | `preload(lang)` | Download without activating. |
373
439
  | `registerScope(scope)` | Register and start loading a scope. |
374
- | `whenReady()` | Resolves when all registered scopes are loaded. Never rejects. |
440
+ | `whenReady()` | Resolves when all registered scopes and any in-flight `init()`/`use()` are done. Never rejects. |
375
441
  | `setTranslation(lang, dict, merge = true)` | Inject translations manually. |
376
442
  | `detectInitialLang()` | Stored, browser (opt-in) or default. |
377
443
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ngx-kit",
3
- "version": "9.0.0",
3
+ "version": "9.1.0",
4
4
  "description": "Angular input components",
5
5
  "author": "Mohammadreza Samani <mr.samani1368@gmail.com>",
6
6
  "license": "MIT",
@@ -268,6 +268,8 @@ declare class DragRef<T = unknown> {
268
268
  private sourceDisplay;
269
269
  private sourcePointerEvents;
270
270
  private sourceTransition;
271
+ private sourceWillChange;
272
+ private sourceTransform;
271
273
  /** True while a drop-list drag (body preview + placeholder) is in progress. Free drag: always false. */
272
274
  private listDrag;
273
275
  private cachedLists;
@@ -399,7 +401,6 @@ declare class NgxDraggable<T = unknown> implements OnInit, OnDestroy, AfterConte
399
401
  readonly dragEnd: _angular_core.OutputEmitterRef<IPosition>;
400
402
  readonly _ref: DragRef<T>;
401
403
  readonly dragging: _angular_core.WritableSignal<boolean>;
402
- private readonly doc;
403
404
  private readonly service;
404
405
  private readonly scroller;
405
406
  private down;
@@ -444,7 +445,7 @@ declare class NgxDraggable<T = unknown> implements OnInit, OnDestroy, AfterConte
444
445
  static ɵdir: _angular_core.ɵɵDirectiveDeclaration<NgxDraggable<any>, "[NgxDraggable],[ngxDraggable]", never, { "disabled": { "alias": "disabled"; "required": false; "isSignal": true; }; "boundary": { "alias": "boundary"; "required": false; "isSignal": true; }; "dragRootElement": { "alias": "dragRootElement"; "required": false; "isSignal": true; }; "dragHandle": { "alias": "dragHandle"; "required": false; "isSignal": true; }; "lockAxis": { "alias": "lockAxis"; "required": false; "isSignal": true; }; "dragThreshold": { "alias": "dragThreshold"; "required": false; "isSignal": true; }; "keyboardStep": { "alias": "keyboardStep"; "required": false; "isSignal": true; }; "autoScroll": { "alias": "autoScroll"; "required": false; "isSignal": true; }; "data": { "alias": "data"; "required": false; }; }, { "disabled": "disabledChange"; "dragRootElement": "dragRootElementChange"; "dragHandle": "dragHandleChange"; "dragStart": "dragStart"; "dragMove": "dragMove"; "dragEnd": "dragEnd"; }, ["customPreview"], never, true, never>;
445
446
  }
446
447
 
447
- declare class NgxResizable {
448
+ declare class NgxResizable implements OnDestroy {
448
449
  private readonly el;
449
450
  disabled: _angular_core.ModelSignal<boolean>;
450
451
  readonly minWidth: _angular_core.ModelSignal<number>;
@@ -472,11 +473,18 @@ declare class NgxResizable {
472
473
  private beforeHeight;
473
474
  private beforeTransform;
474
475
  private pointerId;
476
+ private startWidth;
477
+ private startHeight;
478
+ private removeDocumentListeners;
479
+ private readonly renderer;
475
480
  constructor(el: ElementRef<HTMLElement>);
481
+ ngOnDestroy(): void;
476
482
  onPointerDown(e: PointerEvent): void;
477
483
  onPointerMove(e: PointerEvent): void;
478
484
  onPointerUp(e: PointerEvent): void;
479
485
  onDocumentKeyDown(e: KeyboardEvent): void;
486
+ private onPointerCancel;
487
+ private restoreBeforeResize;
480
488
  onHandleKeyDown(e: KeyboardEvent): void;
481
489
  private calculate;
482
490
  private apply;
@@ -597,9 +605,9 @@ declare function clampResizeWithinBoundary(boundaryRect: DOMRect | undefined, st
597
605
  top: number;
598
606
  };
599
607
  /** Current page zoom level (1 = 100%). Falls back to devicePixelRatio pre visualViewport. */
600
- declare function getPageZoom(): number;
608
+ declare function getPageZoom(element?: HTMLElement): number;
601
609
  /** Adjusts a raw pointer-derived value for the current page zoom level. */
602
- declare function adjustForZoom(value: number): number;
610
+ declare function adjustForZoom(value: number, element?: HTMLElement): number;
603
611
 
604
612
  /**
605
613
  * Auto-scrolls the nearest scrollable ancestor (or window) while the pointer
@@ -609,6 +617,7 @@ declare function adjustForZoom(value: number): number;
609
617
  declare class AutoScroller {
610
618
  private raf;
611
619
  private container;
620
+ private win?;
612
621
  private speed;
613
622
  private onTick?;
614
623
  private readonly edge;
@@ -15,10 +15,16 @@ interface I18nLoader {
15
15
  /** `scope === undefined` means the global file. */
16
16
  load(lang: string, scope?: string): Observable<Dictionary> | Promise<Dictionary>;
17
17
  }
18
- declare class I18nConfig {
19
- /** All supported languages. */
20
- langs: string[];
21
- defaultLang: string;
18
+ /**
19
+ * Every option is optional so the library can be provided at startup and completed later
20
+ * (for example after your own APP_INITIALIZER has fetched the language list from the backend):
21
+ * see `I18nService.init()` / `I18nService.configure()`.
22
+ */
23
+ interface I18nConfig {
24
+ /** All supported languages. Required before the first language is activated. */
25
+ langs?: string[];
26
+ /** Language used when nothing is stored or detected. Required before the first language is activated. */
27
+ defaultLang?: string;
22
28
  /** Looked up (in order) when a key is empty/missing in the active language. */
23
29
  fallbackLangs?: string[];
24
30
  /** Default `'key'` (returns the key itself). */
@@ -27,11 +33,11 @@ declare class I18nConfig {
27
33
  warnMissing?: boolean;
28
34
  /** Replace the default `{{ name }}` interpolation (ICU, plurals, ...). */
29
35
  transpile?: Transpiler;
30
- /** Custom loader class (must be `@Injectable({providedIn:'root'})` or constructible without args). Default: HTTP. */
36
+ /** Custom loader class (must be `@Injectable({providedIn:'root'})` or constructible without args). Default: HTTP. Provide-time only. */
31
37
  loader?: Type<I18nLoader>;
32
- /** Default HTTP loader: base URL. Default `'/i18n'` -> `/i18n/fa`, `/i18n/setting/fa`. */
38
+ /** Default HTTP loader: base URL. Default `'/i18n'` -> `/i18n/fa.json`, `/i18n/setting/fa.json`. Slashes are normalised. */
33
39
  baseUrl?: string;
34
- /** Default HTTP loader: file extension appended to the URL, e.g. `'.json'`. Default `'.json'`. */
40
+ /** Default HTTP loader: file extension appended to the URL, e.g. `'.json'`. Default `'.json'`; use `''` for none. */
35
41
  fileExtension?: string;
36
42
  /** Default HTTP loader: full control over the URL. */
37
43
  url?: (lang: string, scope?: string) => string;
@@ -43,7 +49,23 @@ declare class I18nConfig {
43
49
  detectBrowserLang?: boolean;
44
50
  /** Keep `<html lang dir>` in sync. Default `true`. */
45
51
  manageDocument?: boolean;
52
+ /**
53
+ * Activate the initial language in an APP_INITIALIZER created by `provideI18n()`.
54
+ * Default: `true` when both `langs` and `defaultLang` are given to `provideI18n()`, otherwise `false`
55
+ * (then you call `I18nService.init()` yourself, typically from your own initializer).
56
+ * Provide-time only.
57
+ */
58
+ autoInit?: boolean;
46
59
  }
60
+ /** Options that can be changed after the app has started. */
61
+ type I18nRuntimeConfig = Omit<I18nConfig, 'loader' | 'autoInit'>;
62
+ /** `I18nService.init()` options: runtime config + the language to start with. */
63
+ interface I18nInitOptions extends I18nRuntimeConfig {
64
+ /** Preferred starting language (e.g. the user's saved language from the backend). Ignored if not in `langs`. */
65
+ lang?: string;
66
+ }
67
+ /** Defaults applied by `provideI18n()`. */
68
+ declare const I18N_DEFAULTS: I18nConfig;
47
69
  declare const I18N_CONFIG: InjectionToken<I18nConfig>;
48
70
  declare const I18N_LOADER: InjectionToken<I18nLoader>;
49
71
 
@@ -114,8 +136,21 @@ declare function flatten(dict: Dictionary, target?: Map<string, string>, onConfl
114
136
  declare function interpolate(text: string, params?: Params): string;
115
137
  /** Identity function the extractor recognises: `const k = marker('orders.title')`. */
116
138
  declare function marker<T extends string>(key: T): T;
139
+ /**
140
+ * Build `{base}/{scope}/{lang}{ext}` without ever producing `undefined`, `//` or a trailing slash problem:
141
+ * ("/i18n", undefined, "fa", ".json") -> "/i18n/fa.json"
142
+ * ("https://x.com/", "setting", "fa", "json") -> "https://x.com/setting/fa.json"
143
+ * (undefined | "", undefined, "fa") -> "/fa"
144
+ * The protocol part of `base` ("https://") is left alone.
145
+ */
146
+ declare function buildI18nUrl(base: string | null | undefined, scope: string | null | undefined, lang: string, ext?: string | null | undefined): string;
117
147
 
118
- /** Default loader: GET `{baseUrl}/{lang}` and `{baseUrl}/{scope}/{lang}`. Goes through your HttpClient interceptors. */
148
+ /**
149
+ * Default loader: GET `{baseUrl}/{lang}{ext}` and `{baseUrl}/{scope}/{lang}{ext}`.
150
+ * Goes through your HttpClient interceptors.
151
+ * Config is read on every request, so values supplied later via `I18nService.init()` /
152
+ * `configure()` (for example `baseUrl`) are picked up.
153
+ */
119
154
  declare class HttpI18nLoader implements I18nLoader {
120
155
  private readonly http;
121
156
  private readonly cfg;
@@ -130,14 +165,19 @@ declare class I18nService {
130
165
  private readonly doc;
131
166
  private readonly _lang;
132
167
  private readonly _rev;
168
+ private readonly _langs;
169
+ private readonly _ready;
133
170
  /** Active language (reactive). */
134
171
  readonly lang: Signal<string>;
135
172
  /** Bumps whenever the active language or any dictionary changes. */
136
173
  readonly revision: Signal<number>;
137
174
  readonly dir: Signal<"rtl" | "ltr">;
138
- readonly langs: readonly string[];
139
- private readonly fallbacks;
140
- private readonly warn;
175
+ /** Supported languages (a signal: they may be supplied after startup via `init()` / `configure()`). */
176
+ readonly langs: Signal<readonly string[]>;
177
+ /** `true` once the first language has been activated. Handy for a splash screen. */
178
+ readonly ready: Signal<boolean>;
179
+ private get fallbacks();
180
+ private get warn();
141
181
  private readonly dicts;
142
182
  private readonly loaded;
143
183
  private readonly inflight;
@@ -163,6 +203,24 @@ declare class I18nService {
163
203
  * Nothing renders half-translated and no "missing" flash occurs.
164
204
  */
165
205
  use(lang: string): Promise<void>;
206
+ /**
207
+ * Complete the configuration and activate the first language in one call. Use it from your own
208
+ * APP_INITIALIZER when the language list is only known at runtime (e.g. from the backend):
209
+ *
210
+ * ```ts
211
+ * await i18n.init({ langs: ['fa', 'en'], defaultLang: 'fa', baseUrl: apiUrl, lang: user.lang });
212
+ * ```
213
+ * `lang` is used when it is in `langs`; otherwise stored > browser (opt-in) > `defaultLang`.
214
+ * Rejects when the files cannot be loaded, so the initializer can show an error page.
215
+ */
216
+ init(options?: I18nInitOptions): Promise<void>;
217
+ /**
218
+ * Update options after startup (languages, baseUrl, fallbacks, ...). Already downloaded files stay cached.
219
+ * `loader` and `autoInit` can only be set in `provideI18n()`.
220
+ */
221
+ configure(patch: I18nRuntimeConfig): void;
222
+ private syncLangs;
223
+ private activate;
166
224
  /** Download a language without activating it. */
167
225
  preload(lang: string): Promise<void>;
168
226
  /** Language to start with: stored > browser (opt-in) > default. */
@@ -185,13 +243,23 @@ declare class I18nService {
185
243
  }
186
244
 
187
245
  /**
246
+ * Static configuration (everything known at build time):
188
247
  * ```ts
189
248
  * provideHttpClient(),
190
249
  * provideI18n({ langs: ['fa', 'en'], defaultLang: 'fa', fallbackLangs: ['en'] })
191
250
  * ```
192
- * The global dictionary of the initial language is loaded before the app starts.
251
+ * The global dictionary of the initial language is then loaded before the app starts.
252
+ *
253
+ * Deferred configuration (languages come from your backend): omit `langs`/`defaultLang`
254
+ * and call `await inject(I18nService).init({ langs, defaultLang, baseUrl, lang })`
255
+ * from your own APP_INITIALIZER once you know them:
256
+ * ```ts
257
+ * provideI18n({ fallbackLangs: ['fa'] }), // no automatic initializer
258
+ * provideAppInitializer(() => AppInitializer()), // calls i18n.init(...)
259
+ * ```
260
+ * Pass `autoInit: false` to force this mode even when `langs` is given.
193
261
  */
194
- declare function provideI18n(config: I18nConfig): EnvironmentProviders;
262
+ declare function provideI18n(config?: I18nConfig): EnvironmentProviders;
195
263
 
196
264
  /**
197
265
  * Put in `route.providers`. Runs when the route injector is created (before guards),
@@ -209,5 +277,5 @@ declare function injectT(): TranslateFn;
209
277
  /** `imports: [TR]` brings the pipe and both directives into a standalone component. */
210
278
  declare const TR: readonly [typeof TrPipe, typeof TrDirective, typeof TrKeyDirective];
211
279
 
212
- export { HttpI18nLoader, I18N_CONFIG, I18N_LOADER, I18nConfig, I18nService, TR, TrDirective, TrKeyDirective, TrPipe, flatten, i18nReadyGuard, injectT, interpolate, marker, provideI18n, provideI18nScope, translateSignal };
213
- export type { Dictionary, I18nLoader, MissingHandler, Params, TrContext, TranslateFn, Transpiler };
280
+ export { HttpI18nLoader, I18N_CONFIG, I18N_DEFAULTS, I18N_LOADER, I18nService, TR, TrDirective, TrKeyDirective, TrPipe, buildI18nUrl, flatten, i18nReadyGuard, injectT, interpolate, marker, provideI18n, provideI18nScope, translateSignal };
281
+ export type { Dictionary, I18nConfig, I18nInitOptions, I18nLoader, I18nRuntimeConfig, MissingHandler, Params, TrContext, TranslateFn, Transpiler };