@prosopo/locale 3.2.9 → 3.3.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.
Files changed (93) hide show
  1. package/.turbo/turbo-build$colon$cjs.log +10 -9
  2. package/.turbo/turbo-build$colon$tsc.log +5 -5
  3. package/.turbo/turbo-build.log +17 -16
  4. package/CHANGELOG.md +24 -0
  5. package/dist/cjs/i18SharedOptions.cjs +1 -1
  6. package/dist/cjs/i18nBackend.cjs +4 -1
  7. package/dist/cjs/i18nFrontend.cjs +4 -1
  8. package/dist/cjs/loadI18next.cjs +41 -14
  9. package/dist/cjs/process.cjs +17 -0
  10. package/dist/cjs/translationKey.cjs +2 -0
  11. package/dist/i18SharedOptions.js +2 -1
  12. package/dist/i18SharedOptions.js.map +1 -1
  13. package/dist/i18nBackend.d.ts.map +1 -1
  14. package/dist/i18nBackend.js +4 -1
  15. package/dist/i18nBackend.js.map +1 -1
  16. package/dist/i18nFrontend.d.ts.map +1 -1
  17. package/dist/i18nFrontend.js +4 -1
  18. package/dist/i18nFrontend.js.map +1 -1
  19. package/dist/loadI18next.d.ts +1 -0
  20. package/dist/loadI18next.d.ts.map +1 -1
  21. package/dist/loadI18next.js +41 -15
  22. package/dist/loadI18next.js.map +1 -1
  23. package/dist/process.d.ts +2 -0
  24. package/dist/process.d.ts.map +1 -0
  25. package/dist/process.js +17 -0
  26. package/dist/process.js.map +1 -0
  27. package/dist/tests/i18SharedOptions.unit.test.d.ts +2 -0
  28. package/dist/tests/i18SharedOptions.unit.test.d.ts.map +1 -0
  29. package/dist/tests/i18SharedOptions.unit.test.js +91 -0
  30. package/dist/tests/i18SharedOptions.unit.test.js.map +1 -0
  31. package/dist/tests/i18nBackend.unit.test.d.ts +2 -0
  32. package/dist/tests/i18nBackend.unit.test.d.ts.map +1 -0
  33. package/dist/tests/i18nBackend.unit.test.js +153 -0
  34. package/dist/tests/i18nBackend.unit.test.js.map +1 -0
  35. package/dist/tests/i18nFrontend.unit.test.d.ts +2 -0
  36. package/dist/tests/i18nFrontend.unit.test.d.ts.map +1 -0
  37. package/dist/tests/i18nFrontend.unit.test.js +199 -0
  38. package/dist/tests/i18nFrontend.unit.test.js.map +1 -0
  39. package/dist/tests/i18nMiddleware.unit.test.d.ts +2 -0
  40. package/dist/tests/i18nMiddleware.unit.test.d.ts.map +1 -0
  41. package/dist/tests/i18nMiddleware.unit.test.js +80 -0
  42. package/dist/tests/i18nMiddleware.unit.test.js.map +1 -0
  43. package/dist/tests/loadI18next.unit.test.d.ts +2 -0
  44. package/dist/tests/loadI18next.unit.test.d.ts.map +1 -0
  45. package/dist/tests/loadI18next.unit.test.js +270 -0
  46. package/dist/tests/loadI18next.unit.test.js.map +1 -0
  47. package/dist/tests/locale.test-d.d.ts +2 -0
  48. package/dist/tests/locale.test-d.d.ts.map +1 -0
  49. package/dist/tests/locale.test-d.js +88 -0
  50. package/dist/tests/locale.test-d.js.map +1 -0
  51. package/dist/tests/process.unit.test.d.ts +2 -0
  52. package/dist/tests/process.unit.test.d.ts.map +1 -0
  53. package/dist/tests/process.unit.test.js +14 -0
  54. package/dist/tests/process.unit.test.js.map +1 -0
  55. package/dist/tests/translationKey.unit.test.d.ts +2 -0
  56. package/dist/tests/translationKey.unit.test.d.ts.map +1 -0
  57. package/dist/tests/translationKey.unit.test.js +108 -0
  58. package/dist/tests/translationKey.unit.test.js.map +1 -0
  59. package/dist/tests/translations.unit.test.d.ts +2 -0
  60. package/dist/tests/translations.unit.test.d.ts.map +1 -0
  61. package/dist/tests/translations.unit.test.js +74 -0
  62. package/dist/tests/translations.unit.test.js.map +1 -0
  63. package/dist/tests/useTranslation.unit.test.d.ts +2 -0
  64. package/dist/tests/useTranslation.unit.test.d.ts.map +1 -0
  65. package/dist/tests/useTranslation.unit.test.js +81 -0
  66. package/dist/tests/useTranslation.unit.test.js.map +1 -0
  67. package/dist/tests/util.unit.test.d.ts +2 -0
  68. package/dist/tests/util.unit.test.d.ts.map +1 -0
  69. package/dist/tests/util.unit.test.js +66 -0
  70. package/dist/tests/util.unit.test.js.map +1 -0
  71. package/dist/translationKey.d.ts +4 -0
  72. package/dist/translationKey.d.ts.map +1 -1
  73. package/dist/translationKey.js +2 -1
  74. package/dist/translationKey.js.map +1 -1
  75. package/package.json +1 -1
  76. package/src/i18SharedOptions.ts +4 -4
  77. package/src/i18nBackend.ts +16 -0
  78. package/src/i18nFrontend.ts +16 -0
  79. package/src/loadI18next.ts +83 -15
  80. package/src/process.ts +29 -0
  81. package/src/tests/i18SharedOptions.unit.test.ts +139 -0
  82. package/src/tests/i18nBackend.unit.test.ts +241 -0
  83. package/src/tests/i18nFrontend.unit.test.ts +302 -0
  84. package/src/tests/i18nMiddleware.unit.test.ts +140 -0
  85. package/src/tests/loadI18next.unit.test.ts +443 -0
  86. package/src/tests/locale.test-d.ts +156 -0
  87. package/src/tests/process.unit.test.ts +33 -0
  88. package/src/tests/translationKey.unit.test.ts +166 -0
  89. package/src/tests/translations.unit.test.ts +110 -0
  90. package/src/tests/useTranslation.unit.test.ts +134 -0
  91. package/src/tests/util.unit.test.ts +102 -0
  92. package/src/translationKey.ts +18 -3
  93. package/tsconfig.tsbuildinfo +1 -1
@@ -1,31 +1,32 @@
1
1
 
2
- > @prosopo/locale@3.2.9 build:cjs
2
+ > @prosopo/locale@3.3.0 build:cjs
3
3
  > NODE_ENV=${NODE_ENV:-development}; vite build --config vite.cjs.config.ts --mode $NODE_ENV
4
4
 
5
5
  ViteCommonJSConfig: .
6
6
  { tsConfigPaths: [] }
7
- The plugin "vite-tsconfig-paths" is detected. Vite now supports tsconfig paths resolution natively via the resolve.tsconfigPaths option. You can remove the plugin and set resolve.tsconfigPaths: true in your Vite config instead.
8
7
  { externals: [] }
8
+ The plugin "vite-tsconfig-paths" is detected. Vite now supports tsconfig paths resolution natively via the resolve.tsconfigPaths option. You can remove the plugin and set resolve.tsconfigPaths: true in your Vite config instead.
9
9
  vite v8.1.5 building ssr environment for production...
10
10
  Bundle build started
11
11
  
12
- ✓ 12 modules transformed.
12
+ ✓ 13 modules transformed.
13
13
  rendering chunks...
14
14
  computing gzip size...
15
15
  dist/cjs/util.cjs 0.28 kB │ gzip: 0.17 kB
16
16
  dist/cjs/useTranslation.cjs 0.35 kB │ gzip: 0.20 kB
17
17
  dist/cjs/i18nMiddleware.cjs 0.36 kB │ gzip: 0.21 kB
18
- dist/cjs/i18SharedOptions.cjs 0.42 kB │ gzip: 0.27 kB
19
- dist/cjs/translationKey.cjs 0.64 kB │ gzip: 0.36 kB
18
+ dist/cjs/i18SharedOptions.cjs 0.41 kB │ gzip: 0.25 kB
19
+ dist/cjs/translationKey.cjs 0.74 kB │ gzip: 0.38 kB
20
+ dist/cjs/process.cjs 0.78 kB │ gzip: 0.46 kB
20
21
  dist/cjs/index.cjs 0.83 kB │ gzip: 0.27 kB
21
22
  dist/cjs/translations.cjs 0.86 kB │ gzip: 0.46 kB
22
- dist/cjs/loadI18next.cjs 0.90 kB │ gzip: 0.37 kB
23
23
  dist/cjs/_virtual/_rolldown/runtime.cjs 1.00 kB │ gzip: 0.50 kB
24
- dist/cjs/i18nBackend.cjs 1.36 kB │ gzip: 0.58 kB
25
- dist/cjs/i18nFrontend.cjs 2.35 kB │ gzip: 0.84 kB
24
+ dist/cjs/i18nBackend.cjs 1.47 kB │ gzip: 0.62 kB
25
+ dist/cjs/loadI18next.cjs 2.03 kB │ gzip: 0.84 kB
26
+ dist/cjs/i18nFrontend.cjs 2.47 kB │ gzip: 0.87 kB
26
27
  dist/cjs/locales/en/translation.cjs 15.80 kB │ gzip: 5.62 kB
27
28
 
28
- ✓ built in 90ms
29
+ ✓ built in 86ms
29
30
  [copy-plugin] copying /home/runner/work/captcha/captcha/packages/locale/src/locales/ar/translation.json to /home/runner/work/captcha/captcha/packages/locale/dist/locales/ar/translation.json
30
31
  [copy-plugin] copying /home/runner/work/captcha/captcha/packages/locale/src/locales/az/translation.json to /home/runner/work/captcha/captcha/packages/locale/dist/locales/az/translation.json
31
32
  [copy-plugin] copying /home/runner/work/captcha/captcha/packages/locale/src/locales/cs/translation.json to /home/runner/work/captcha/captcha/packages/locale/dist/locales/cs/translation.json
@@ -1,14 +1,14 @@
1
1
 
2
- > @prosopo/locale@3.2.9 build:tsc
2
+ > @prosopo/locale@3.3.0 build:tsc
3
3
  > tsc --build --verbose
4
4
 
5
- 1:56:36 PM - Projects in this build:
5
+ 7:04:34 AM - Projects in this build:
6
6
  * ../../dev/config/tsconfig.json
7
7
  * tsconfig.json
8
8
 
9
- 1:56:36 PM - Project '../../dev/config/tsconfig.json' is up to date because newest input '../../dev/config/src/webpack/webpack.config.ts' is older than output '../../dev/config/tsconfig.tsbuildinfo'
9
+ 7:04:34 AM - Project '../../dev/config/tsconfig.json' is up to date because newest input '../../dev/config/src/vite/vite-plugin-copy.ts' is older than output '../../dev/config/tsconfig.tsbuildinfo'
10
10
 
11
- 1:56:36 PM - Project 'tsconfig.json' is out of date because output file 'tsconfig.tsbuildinfo' does not exist
11
+ 7:04:34 AM - Project 'tsconfig.json' is out of date because output file 'tsconfig.tsbuildinfo' does not exist
12
12
 
13
- 1:56:36 PM - Building project '/home/runner/work/captcha/captcha/packages/locale/tsconfig.json'...
13
+ 7:04:34 AM - Building project '/home/runner/work/captcha/captcha/packages/locale/tsconfig.json'...
14
14
 
@@ -1,9 +1,9 @@
1
1
 
2
- > @prosopo/locale@3.2.9 build
2
+ > @prosopo/locale@3.3.0 build
3
3
  > npm run build:cross-env -- --mode ${NODE_ENV:-development}
4
4
 
5
5
 
6
- > @prosopo/locale@3.2.9 build:cross-env
6
+ > @prosopo/locale@3.3.0 build:cross-env
7
7
  > vite build --config vite.esm.config.ts --mode production
8
8
 
9
9
  ViteEsmConfig: .
@@ -13,48 +13,49 @@ ViteEsmConfig: .
13
13
  vite v8.1.5 building ssr environment for production...
14
14
  Bundle build started
15
15
  
16
- ✓ 12 modules transformed.
16
+ ✓ 13 modules transformed.
17
17
  rendering chunks...
18
18
  computing gzip size...
19
19
  dist/_virtual/_rolldown/runtime.js 0.04 kB │ gzip: 0.06 kB
20
20
  dist/util.js 0.25 kB │ gzip: 0.16 kB
21
21
  dist/i18nMiddleware.js 0.27 kB │ gzip: 0.18 kB
22
22
  dist/useTranslation.js 0.30 kB │ gzip: 0.19 kB
23
- dist/i18SharedOptions.js 0.37 kB │ gzip: 0.26 kB
23
+ dist/i18SharedOptions.js 0.37 kB │ gzip: 0.25 kB
24
24
  dist/index.js 0.47 kB │ gzip: 0.20 kB
25
- dist/translationKey.js 0.61 kB │ gzip: 0.36 kB
25
+ dist/translationKey.js 0.68 kB │ gzip: 0.37 kB
26
26
  dist/translations.js 0.70 kB │ gzip: 0.39 kB
27
- dist/loadI18next.js 0.84 kB │ gzip: 0.36 kB
28
- dist/i18nBackend.js 0.91 kB │ gzip: 0.49 kB
29
- dist/i18nFrontend.js 1.65 kB │ gzip: 0.74 kB
27
+ dist/process.js 0.77 kB │ gzip: 0.46 kB
28
+ dist/i18nBackend.js 1.01 kB │ gzip: 0.53 kB
29
+ dist/i18nFrontend.js 1.75 kB │ gzip: 0.78 kB
30
+ dist/loadI18next.js 1.93 kB │ gzip: 0.83 kB
30
31
  dist/locales/en/translation.js 15.56 kB │ gzip: 5.59 kB
31
32
 
32
- ✓ built in 80ms
33
+ ✓ built in 74ms
33
34
  [copy-plugin] copying /home/runner/work/captcha/captcha/packages/locale/src/locales/ar/translation.json to /home/runner/work/captcha/captcha/packages/locale/dist/locales/ar/translation.json
34
35
  [copy-plugin] copying /home/runner/work/captcha/captcha/packages/locale/src/locales/az/translation.json to /home/runner/work/captcha/captcha/packages/locale/dist/locales/az/translation.json
35
- [copy-plugin] copying /home/runner/work/captcha/captcha/packages/locale/src/locales/de/translation.json to /home/runner/work/captcha/captcha/packages/locale/dist/locales/de/translation.json
36
36
  [copy-plugin] copying /home/runner/work/captcha/captcha/packages/locale/src/locales/cs/translation.json to /home/runner/work/captcha/captcha/packages/locale/dist/locales/cs/translation.json
37
- [copy-plugin] copying /home/runner/work/captcha/captcha/packages/locale/src/locales/en/translation.json to /home/runner/work/captcha/captcha/packages/locale/dist/locales/en/translation.json
37
+ [copy-plugin] copying /home/runner/work/captcha/captcha/packages/locale/src/locales/de/translation.json to /home/runner/work/captcha/captcha/packages/locale/dist/locales/de/translation.json
38
38
  [copy-plugin] copying /home/runner/work/captcha/captcha/packages/locale/src/locales/el/translation.json to /home/runner/work/captcha/captcha/packages/locale/dist/locales/el/translation.json
39
+ [copy-plugin] copying /home/runner/work/captcha/captcha/packages/locale/src/locales/en/translation.json to /home/runner/work/captcha/captcha/packages/locale/dist/locales/en/translation.json
39
40
  [copy-plugin] copying /home/runner/work/captcha/captcha/packages/locale/src/locales/es/translation.json to /home/runner/work/captcha/captcha/packages/locale/dist/locales/es/translation.json
40
41
  [copy-plugin] copying /home/runner/work/captcha/captcha/packages/locale/src/locales/fi/translation.json to /home/runner/work/captcha/captcha/packages/locale/dist/locales/fi/translation.json
41
- [copy-plugin] copying /home/runner/work/captcha/captcha/packages/locale/src/locales/hi/translation.json to /home/runner/work/captcha/captcha/packages/locale/dist/locales/hi/translation.json
42
42
  [copy-plugin] copying /home/runner/work/captcha/captcha/packages/locale/src/locales/fr/translation.json to /home/runner/work/captcha/captcha/packages/locale/dist/locales/fr/translation.json
43
+ [copy-plugin] copying /home/runner/work/captcha/captcha/packages/locale/src/locales/hi/translation.json to /home/runner/work/captcha/captcha/packages/locale/dist/locales/hi/translation.json
43
44
  [copy-plugin] copying /home/runner/work/captcha/captcha/packages/locale/src/locales/hu/translation.json to /home/runner/work/captcha/captcha/packages/locale/dist/locales/hu/translation.json
44
45
  [copy-plugin] copying /home/runner/work/captcha/captcha/packages/locale/src/locales/id/translation.json to /home/runner/work/captcha/captcha/packages/locale/dist/locales/id/translation.json
45
46
  [copy-plugin] copying /home/runner/work/captcha/captcha/packages/locale/src/locales/it/translation.json to /home/runner/work/captcha/captcha/packages/locale/dist/locales/it/translation.json
46
- [copy-plugin] copying /home/runner/work/captcha/captcha/packages/locale/src/locales/jv/translation.json to /home/runner/work/captcha/captcha/packages/locale/dist/locales/jv/translation.json
47
47
  [copy-plugin] copying /home/runner/work/captcha/captcha/packages/locale/src/locales/ja/translation.json to /home/runner/work/captcha/captcha/packages/locale/dist/locales/ja/translation.json
48
+ [copy-plugin] copying /home/runner/work/captcha/captcha/packages/locale/src/locales/jv/translation.json to /home/runner/work/captcha/captcha/packages/locale/dist/locales/jv/translation.json
48
49
  [copy-plugin] copying /home/runner/work/captcha/captcha/packages/locale/src/locales/ko/translation.json to /home/runner/work/captcha/captcha/packages/locale/dist/locales/ko/translation.json
49
50
  [copy-plugin] copying /home/runner/work/captcha/captcha/packages/locale/src/locales/ml/translation.json to /home/runner/work/captcha/captcha/packages/locale/dist/locales/ml/translation.json
50
- [copy-plugin] copying /home/runner/work/captcha/captcha/packages/locale/src/locales/nl/translation.json to /home/runner/work/captcha/captcha/packages/locale/dist/locales/nl/translation.json
51
51
  [copy-plugin] copying /home/runner/work/captcha/captcha/packages/locale/src/locales/ms/translation.json to /home/runner/work/captcha/captcha/packages/locale/dist/locales/ms/translation.json
52
+ [copy-plugin] copying /home/runner/work/captcha/captcha/packages/locale/src/locales/nl/translation.json to /home/runner/work/captcha/captcha/packages/locale/dist/locales/nl/translation.json
52
53
  [copy-plugin] copying /home/runner/work/captcha/captcha/packages/locale/src/locales/no/translation.json to /home/runner/work/captcha/captcha/packages/locale/dist/locales/no/translation.json
53
54
  [copy-plugin] copying /home/runner/work/captcha/captcha/packages/locale/src/locales/pl/translation.json to /home/runner/work/captcha/captcha/packages/locale/dist/locales/pl/translation.json
54
- [copy-plugin] copying /home/runner/work/captcha/captcha/packages/locale/src/locales/ro/translation.json to /home/runner/work/captcha/captcha/packages/locale/dist/locales/ro/translation.json
55
55
  [copy-plugin] copying /home/runner/work/captcha/captcha/packages/locale/src/locales/pt/translation.json to /home/runner/work/captcha/captcha/packages/locale/dist/locales/pt/translation.json
56
- [copy-plugin] copying /home/runner/work/captcha/captcha/packages/locale/src/locales/ru/translation.json to /home/runner/work/captcha/captcha/packages/locale/dist/locales/ru/translation.json
57
56
  [copy-plugin] copying /home/runner/work/captcha/captcha/packages/locale/src/locales/pt-BR/translation.json to /home/runner/work/captcha/captcha/packages/locale/dist/locales/pt-BR/translation.json
57
+ [copy-plugin] copying /home/runner/work/captcha/captcha/packages/locale/src/locales/ro/translation.json to /home/runner/work/captcha/captcha/packages/locale/dist/locales/ro/translation.json
58
+ [copy-plugin] copying /home/runner/work/captcha/captcha/packages/locale/src/locales/ru/translation.json to /home/runner/work/captcha/captcha/packages/locale/dist/locales/ru/translation.json
58
59
  [copy-plugin] copying /home/runner/work/captcha/captcha/packages/locale/src/locales/sr/translation.json to /home/runner/work/captcha/captcha/packages/locale/dist/locales/sr/translation.json
59
60
  [copy-plugin] copying /home/runner/work/captcha/captcha/packages/locale/src/locales/sv/translation.json to /home/runner/work/captcha/captcha/packages/locale/dist/locales/sv/translation.json
60
61
  [copy-plugin] copying /home/runner/work/captcha/captcha/packages/locale/src/locales/th/translation.json to /home/runner/work/captcha/captcha/packages/locale/dist/locales/th/translation.json
package/CHANGELOG.md CHANGED
@@ -1,5 +1,29 @@
1
1
  # @prosopo/locale
2
2
 
3
+ ## 3.3.0
4
+ ### Minor Changes
5
+
6
+ - 9091a78: test(locale): unit + type tests, fix empty translation-key schema and i18n load hangs
7
+
8
+ - `getLeafFieldPath` never emitted a path, because a string leaf returned `[]`
9
+ and the parent mapped over that empty list. `TranslationKeysSchema` was
10
+ therefore an empty `z.enum`, and mongoose registers its enum validator even
11
+ for an empty list — so every non-null `result.reason` failed validation on the
12
+ three solution schemas in `@prosopo/types-database`.
13
+ - `loadI18next` wrapped its dynamic imports in a synchronous `try/catch`, which
14
+ cannot see a rejected import or a rejected `changeLanguage`. Those paths left
15
+ the returned promise pending forever instead of rejecting.
16
+ - `initializeI18n` only registered its `loaded` listener on the initialisation
17
+ path, so a caller arriving after i18next was already up (or on the client, for
18
+ the backend module) waited on an event that would never fire.
19
+ - `loadI18next` now bounds itself with `I18N_LOAD_TIMEOUT_MS` (10s). Resolution
20
+ is event-driven, so a backend that never answers left the promise pending for
21
+ the lifetime of the process. On timeout it resolves with the degraded instance
22
+ — i18next renders the key itself for a missing resource, and neither caller
23
+ handles a rejection — or rejects if no instance was ever created.
24
+ - The `process.env` read in `i18SharedOptions` goes through a `getProcess()`
25
+ seam so the browser-runtime path is testable.
26
+
3
27
  ## 3.2.9
4
28
  ### Patch Changes
5
29
 
@@ -1,6 +1,6 @@
1
1
  const require_translations = require("./translations.cjs");
2
2
  var i18nSharedOptions = {
3
- debug: (typeof process !== "undefined" ? process.env?.PROSOPO_LOG_LEVEL : void 0) === "debug",
3
+ debug: require("./process.cjs").getProcess()?.env?.PROSOPO_LOG_LEVEL === "debug",
4
4
  fallbackLng: require_translations.LanguageSchema.enum.en,
5
5
  namespace: "translation",
6
6
  supportedLngs: Object.values(require_translations.Languages),
@@ -22,10 +22,13 @@ function initializeI18n(i18nLoadedCallback) {
22
22
  ns: ["translation"],
23
23
  backend: { loadPath }
24
24
  });
25
+ let notified = false;
25
26
  i18next.default.on("loaded", () => {
27
+ if (notified) return;
28
+ notified = true;
26
29
  i18nLoadedCallback?.(i18next.default);
27
30
  });
28
- }
31
+ } else i18nLoadedCallback?.(i18next.default);
29
32
  return i18next.default;
30
33
  }
31
34
  //#endregion
@@ -49,10 +49,13 @@ function initializeI18n(i18nLoadedCallback, lng) {
49
49
  },
50
50
  ...reactOptions
51
51
  });
52
+ let notified = false;
52
53
  i18next.default.on("loaded", () => {
54
+ if (notified) return;
55
+ notified = true;
53
56
  i18nLoadedCallback?.(i18next.default);
54
57
  });
55
- }
58
+ } else i18nLoadedCallback?.(i18next.default);
56
59
  return i18next.default;
57
60
  }
58
61
  //#endregion
@@ -1,26 +1,53 @@
1
1
  //#region src/loadI18next.ts
2
2
  var i18nInstance;
3
+ /**
4
+ * How long to wait for i18next to report `loaded` before giving up on it.
5
+ *
6
+ * Resolution is driven by an event, and events are not guaranteed: a backend
7
+ * that never answers (http backend against a dead CDN, fs backend against a
8
+ * missing locales dir) leaves the listener armed and the promise pending for
9
+ * the lifetime of the process. `cli.ts` calls loadI18next(true).then(...) with
10
+ * nothing to time it out, so a pending promise there is a silent boot hang with
11
+ * no log line to explain it.
12
+ */
13
+ var I18N_LOAD_TIMEOUT_MS = 1e4;
3
14
  var reconcileLanguage = async (instance, lng) => {
4
15
  if (lng && instance.language !== lng) await instance.changeLanguage(lng);
5
16
  return instance;
6
17
  };
7
18
  async function loadI18next(backend, lng) {
8
19
  return new Promise((resolve, reject) => {
9
- try {
10
- if (backend) Promise.resolve().then(() => require("./i18nBackend.cjs")).then(({ default: initializeI18n }) => {
11
- if (!i18nInstance) i18nInstance = initializeI18n(resolve);
12
- else resolve(i18nInstance);
13
- });
14
- else Promise.resolve().then(() => require("./i18nFrontend.cjs")).then(({ default: initializeI18n }) => {
15
- if (!i18nInstance) i18nInstance = initializeI18n((instance) => {
16
- reconcileLanguage(instance, lng).then(resolve);
17
- }, lng);
18
- else reconcileLanguage(i18nInstance, lng).then(resolve);
19
- });
20
- } catch (e) {
21
- reject(e);
22
- }
20
+ let settled = false;
21
+ const timer = setTimeout(() => {
22
+ settled = true;
23
+ if (i18nInstance) resolve(i18nInstance);
24
+ else reject(/* @__PURE__ */ new Error(`i18next did not load within ${I18N_LOAD_TIMEOUT_MS}ms and no instance was created`));
25
+ }, I18N_LOAD_TIMEOUT_MS);
26
+ timer.unref?.();
27
+ const done = (instance) => {
28
+ if (settled) return;
29
+ settled = true;
30
+ clearTimeout(timer);
31
+ resolve(instance);
32
+ };
33
+ const failWith = (error) => {
34
+ if (settled) return;
35
+ settled = true;
36
+ clearTimeout(timer);
37
+ reject(error);
38
+ };
39
+ if (backend) Promise.resolve().then(() => require("./i18nBackend.cjs")).then(({ default: initializeI18n }) => {
40
+ if (!i18nInstance) i18nInstance = initializeI18n(done);
41
+ else done(i18nInstance);
42
+ }).catch(failWith);
43
+ else Promise.resolve().then(() => require("./i18nFrontend.cjs")).then(({ default: initializeI18n }) => {
44
+ if (!i18nInstance) i18nInstance = initializeI18n((instance) => {
45
+ reconcileLanguage(instance, lng).then(done).catch(failWith);
46
+ }, lng);
47
+ else reconcileLanguage(i18nInstance, lng).then(done).catch(failWith);
48
+ }).catch(failWith);
23
49
  });
24
50
  }
25
51
  //#endregion
52
+ exports.I18N_LOAD_TIMEOUT_MS = I18N_LOAD_TIMEOUT_MS;
26
53
  exports.default = loadI18next;
@@ -0,0 +1,17 @@
1
+ //#region src/process.ts
2
+ /**
3
+ * The `process` global, or undefined where there is none.
4
+ *
5
+ * This package is reached transitively from browser bundles, where `process`
6
+ * may be missing entirely or present but stripped down. A bare `process.env`
7
+ * read throws a ReferenceError in that case and takes the whole page down.
8
+ *
9
+ * It is a function, and it lives in its own module, so callers can be tested
10
+ * against a runtime that has no `process` at all. Inlining the `typeof` check
11
+ * at the point of use makes that branch untestable: vitest calls
12
+ * `process.memoryUsage()` between suites, so stubbing the real global away
13
+ * fails the run rather than the module under test.
14
+ */
15
+ var getProcess = () => typeof process !== "undefined" ? process : void 0;
16
+ //#endregion
17
+ exports.getProcess = getProcess;
@@ -6,6 +6,7 @@ function getLeafFieldPath(obj) {
6
6
  return Object.keys(obj).reduce((arr, key) => {
7
7
  const value = obj[key];
8
8
  if (value === void 0) throw new Error(`Undefined value for key ${key}`);
9
+ if (typeof value === "string") return arr.concat(key);
9
10
  const children = getLeafFieldPath(value);
10
11
  return arr.concat(children.map((child) => {
11
12
  return `${key}.${child}`;
@@ -15,3 +16,4 @@ function getLeafFieldPath(obj) {
15
16
  var TranslationKeysSchema = zod.z.enum(getLeafFieldPath(require_translation.default));
16
17
  //#endregion
17
18
  exports.TranslationKeysSchema = TranslationKeysSchema;
19
+ exports.getLeafFieldPath = getLeafFieldPath;
@@ -1,6 +1,7 @@
1
1
  import { LanguageSchema, Languages } from "./translations.js";
2
+ import { getProcess } from "./process.js";
2
3
  var i18nSharedOptions = {
3
- debug: (typeof process !== "undefined" ? process.env?.PROSOPO_LOG_LEVEL : void 0) === "debug",
4
+ debug: getProcess()?.env?.PROSOPO_LOG_LEVEL === "debug",
4
5
  fallbackLng: LanguageSchema.enum.en,
5
6
  namespace: "translation",
6
7
  supportedLngs: Object.values(Languages),
@@ -1 +1 @@
1
- {"version":3,"file":"i18SharedOptions.js","sourceRoot":"","sources":["../src/i18SharedOptions.ts"],"names":[],"mappings":"AAaA,OAAO,EAAE,cAAc,EAAE,SAAS,EAAE,MAAM,mBAAmB,CAAC;AAM9D,MAAM,QAAQ,GACb,OAAO,OAAO,KAAK,WAAW,CAAC,CAAC,CAAC,OAAO,CAAC,GAAG,EAAE,iBAAiB,CAAC,CAAC,CAAC,SAAS,CAAC;AAE7E,MAAM,CAAC,MAAM,iBAAiB,GAAG;IAChC,KAAK,EAAE,QAAQ,KAAK,OAAO;IAC3B,WAAW,EAAE,cAAc,CAAC,IAAI,CAAC,EAAE;IACnC,SAAS,EAAE,aAAa;IACxB,aAAa,EAAE,MAAM,CAAC,MAAM,CAAC,SAAS,CAAC;IACvC,wBAAwB,EAAE,KAAK;CAC/B,CAAC"}
1
+ {"version":3,"file":"i18SharedOptions.js","sourceRoot":"","sources":["../src/i18SharedOptions.ts"],"names":[],"mappings":"AAaA,OAAO,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAC1C,OAAO,EAAE,cAAc,EAAE,SAAS,EAAE,MAAM,mBAAmB,CAAC;AAM9D,MAAM,QAAQ,GAAG,UAAU,EAAE,EAAE,GAAG,EAAE,iBAAiB,CAAC;AAEtD,MAAM,CAAC,MAAM,iBAAiB,GAAG;IAChC,KAAK,EAAE,QAAQ,KAAK,OAAO;IAC3B,WAAW,EAAE,cAAc,CAAC,IAAI,CAAC,EAAE;IACnC,SAAS,EAAE,aAAa;IACxB,aAAa,EAAE,MAAM,CAAC,MAAM,CAAC,SAAS,CAAC;IACvC,wBAAwB,EAAE,KAAK;CAC/B,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"i18nBackend.d.ts","sourceRoot":"","sources":["../src/i18nBackend.ts"],"names":[],"mappings":"AAeA,OAAO,IAAI,MAAM,SAAS,CAAC;AAY3B,wBAAgB,cAAc,CAC7B,kBAAkB,CAAC,EAAE,CAAC,KAAK,EAAE,OAAO,IAAI,KAAK,IAAI,0BAsBjD;AAED,eAAe,cAAc,CAAC"}
1
+ {"version":3,"file":"i18nBackend.d.ts","sourceRoot":"","sources":["../src/i18nBackend.ts"],"names":[],"mappings":"AAeA,OAAO,IAAI,MAAM,SAAS,CAAC;AAY3B,wBAAgB,cAAc,CAC7B,kBAAkB,CAAC,EAAE,CAAC,KAAK,EAAE,OAAO,IAAI,KAAK,IAAI,0BAsCjD;AAED,eAAe,cAAc,CAAC"}
@@ -19,10 +19,13 @@ function initializeI18n(i18nLoadedCallback) {
19
19
  ns: ["translation"],
20
20
  backend: { loadPath }
21
21
  });
22
+ let notified = false;
22
23
  i18n.on("loaded", () => {
24
+ if (notified) return;
25
+ notified = true;
23
26
  i18nLoadedCallback?.(i18n);
24
27
  });
25
- }
28
+ } else i18nLoadedCallback?.(i18n);
26
29
  return i18n;
27
30
  }
28
31
  //#endregion
@@ -1 +1 @@
1
- {"version":3,"file":"i18nBackend.js","sourceRoot":"","sources":["../src/i18nBackend.ts"],"names":[],"mappings":"AAcA,OAAO,IAAI,MAAM,WAAW,CAAC;AAC7B,OAAO,IAAI,MAAM,SAAS,CAAC;AAC3B,OAAO,SAAS,MAAM,wBAAwB,CAAC;AAC/C,OAAO,EAAE,gBAAgB,IAAI,0BAA0B,EAAE,MAAM,yBAAyB,CAAC;AACzF,OAAO,EAAE,iBAAiB,EAAE,MAAM,uBAAuB,CAAC;AAC1D,OAAO,EAAE,YAAY,EAAE,MAAM,WAAW,CAAC;AAEzC,MAAM,QAAQ,GACb,GAAG,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,8BAA8B,CAAC,OAAO,CACrE,SAAS,EACT,EAAE,CACF,CAAC;AAEH,MAAM,UAAU,cAAc,CAC7B,kBAAiD;IAEjD,IAAI,CAAC,IAAI,CAAC,aAAa,IAAI,YAAY,EAAE,EAAE,CAAC;QAC3C,MAAM,WAAW,GAAG,IAAI,0BAA0B,CAAC,IAAI,EAAE;YACxD,KAAK,EAAE,CAAC,QAAQ,EAAE,OAAO,EAAE,QAAQ,CAAC;SACpC,CAAC,CAAC;QACH,IAAI;aAEF,GAAG,CAAC,SAAS,CAAC;aACd,GAAG,CAAC,WAAW,CAAC;aAChB,IAAI,CAAC;YACL,GAAG,iBAAiB;YACpB,EAAE,EAAE,CAAC,aAAa,CAAC;YACnB,OAAO,EAAE;gBACR,QAAQ;aACR;SACD,CAAC,CAAC;QACJ,IAAI,CAAC,EAAE,CAAC,QAAQ,EAAE,GAAG,EAAE;YACtB,kBAAkB,EAAE,CAAC,IAAI,CAAC,CAAC;QAC5B,CAAC,CAAC,CAAC;IACJ,CAAC;IACD,OAAO,IAAI,CAAC;AACb,CAAC;AAED,eAAe,cAAc,CAAC"}
1
+ {"version":3,"file":"i18nBackend.js","sourceRoot":"","sources":["../src/i18nBackend.ts"],"names":[],"mappings":"AAcA,OAAO,IAAI,MAAM,WAAW,CAAC;AAC7B,OAAO,IAAI,MAAM,SAAS,CAAC;AAC3B,OAAO,SAAS,MAAM,wBAAwB,CAAC;AAC/C,OAAO,EAAE,gBAAgB,IAAI,0BAA0B,EAAE,MAAM,yBAAyB,CAAC;AACzF,OAAO,EAAE,iBAAiB,EAAE,MAAM,uBAAuB,CAAC;AAC1D,OAAO,EAAE,YAAY,EAAE,MAAM,WAAW,CAAC;AAEzC,MAAM,QAAQ,GACb,GAAG,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,8BAA8B,CAAC,OAAO,CACrE,SAAS,EACT,EAAE,CACF,CAAC;AAEH,MAAM,UAAU,cAAc,CAC7B,kBAAiD;IAEjD,IAAI,CAAC,IAAI,CAAC,aAAa,IAAI,YAAY,EAAE,EAAE,CAAC;QAC3C,MAAM,WAAW,GAAG,IAAI,0BAA0B,CAAC,IAAI,EAAE;YACxD,KAAK,EAAE,CAAC,QAAQ,EAAE,OAAO,EAAE,QAAQ,CAAC;SACpC,CAAC,CAAC;QACH,IAAI;aAEF,GAAG,CAAC,SAAS,CAAC;aACd,GAAG,CAAC,WAAW,CAAC;aAChB,IAAI,CAAC;YACL,GAAG,iBAAiB;YACpB,EAAE,EAAE,CAAC,aAAa,CAAC;YACnB,OAAO,EAAE;gBACR,QAAQ;aACR;SACD,CAAC,CAAC;QAKJ,IAAI,QAAQ,GAAG,KAAK,CAAC;QACrB,IAAI,CAAC,EAAE,CAAC,QAAQ,EAAE,GAAG,EAAE;YACtB,IAAI,QAAQ,EAAE,CAAC;gBACd,OAAO;YACR,CAAC;YACD,QAAQ,GAAG,IAAI,CAAC;YAChB,kBAAkB,EAAE,CAAC,IAAI,CAAC,CAAC;QAC5B,CAAC,CAAC,CAAC;IACJ,CAAC;SAAM,CAAC;QAMP,kBAAkB,EAAE,CAAC,IAAI,CAAC,CAAC;IAC5B,CAAC;IACD,OAAO,IAAI,CAAC;AACb,CAAC;AAED,eAAe,cAAc,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"i18nFrontend.d.ts","sourceRoot":"","sources":["../src/i18nFrontend.ts"],"names":[],"mappings":"AAcA,OAAO,IAA0B,MAAM,SAAS,CAAC;AAuBjD,wBAAgB,cAAc,CAC7B,kBAAkB,CAAC,EAAE,CAAC,KAAK,EAAE,OAAO,IAAI,KAAK,IAAI,EACjD,GAAG,CAAC,EAAE,MAAM,0BA+CZ;AAED,eAAe,cAAc,CAAC"}
1
+ {"version":3,"file":"i18nFrontend.d.ts","sourceRoot":"","sources":["../src/i18nFrontend.ts"],"names":[],"mappings":"AAcA,OAAO,IAA0B,MAAM,SAAS,CAAC;AAuBjD,wBAAgB,cAAc,CAC7B,kBAAkB,CAAC,EAAE,CAAC,KAAK,EAAE,OAAO,IAAI,KAAK,IAAI,EACjD,GAAG,CAAC,EAAE,MAAM,0BA+DZ;AAED,eAAe,cAAc,CAAC"}
@@ -44,10 +44,13 @@ function initializeI18n(i18nLoadedCallback, lng) {
44
44
  },
45
45
  ...reactOptions
46
46
  });
47
+ let notified = false;
47
48
  i18n.on("loaded", () => {
49
+ if (notified) return;
50
+ notified = true;
48
51
  i18nLoadedCallback?.(i18n);
49
52
  });
50
- }
53
+ } else i18nLoadedCallback?.(i18n);
51
54
  return i18n;
52
55
  }
53
56
  //#endregion
@@ -1 +1 @@
1
- {"version":3,"file":"i18nFrontend.js","sourceRoot":"","sources":["../src/i18nFrontend.ts"],"names":[],"mappings":"AAcA,OAAO,IAA0B,MAAM,SAAS,CAAC;AACjD,OAAO,8BAA8B,MAAM,kCAAkC,CAAC;AAC9E,OAAO,cAAc,MAAM,yBAAyB,CAAC;AACrD,OAAO,WAAW,MAAM,sBAAsB,CAAC;AAC/C,OAAO,kBAAkB,MAAM,8BAA8B,CAAC;AAC9D,OAAO,EAAE,gBAAgB,EAAE,MAAM,eAAe,CAAC;AACjD,OAAO,EAAE,iBAAiB,EAAE,MAAM,uBAAuB,CAAC;AAE1D,MAAM,YAAY,GAAgB;IACjC,KAAK,EAAE;QACN,WAAW,EAAE,IAAI;KACjB;IACD,SAAS,EAAE;QACV,KAAK,EAAE,CAAC,WAAW,EAAE,SAAS,EAAE,MAAM,EAAE,WAAW,CAAC;QACpD,MAAM,EAAE,CAAC,cAAc,EAAE,QAAQ,CAAC;KAClC;CACD,CAAC;AAEF,MAAM,WAAW,GAAG,CAAC,QAAgB,EAAE,SAAiB,EAAE,EAAE;IAC3D,MAAM,QAAQ,GAAG,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,CAAC;IAClD,OAAO,GAAG,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,OAAO,CAAC,IAAI,QAAQ,EAAE,EAAE,EAAE,CAAC,YAAY,QAAQ,IAAI,SAAS,OAAO,CAAC;AAC/F,CAAC,CAAC;AAEF,MAAM,UAAU,cAAc,CAC7B,kBAAiD,EACjD,GAAY;IAEZ,IAAI,CAAC,IAAI,CAAC,aAAa,EAAE,CAAC;QACzB,IAAI;aAEF,GAAG,CAAC,cAAc,CAAC;aACnB,GAAG,CACH,IAAI,8BAA8B,CAAC,IAAI,EAAE;YACxC,KAAK,EAAE,CAAC,QAAQ,EAAE,cAAc,EAAE,WAAW,CAAC;YAC9C,iBAAiB,EAAE,KAAK;YACxB,YAAY,EAAE,SAAS;YACvB,kBAAkB,EAAE,YAAY;YAChC,MAAM,EAAE,CAAC,cAAc,EAAE,QAAQ,CAAC;SAClC,CAAC,CACF;aACA,GAAG,CAAC,gBAAgB,CAAC;aACrB,IAAI,CAAC;YACL,GAAG,iBAAiB;YAOpB,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,GAAG,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;YACvB,OAAO,EAAE;gBACR,QAAQ,EAAE;oBACT,WAAW;oBAEX,kBAAkB,CACjB,CAAC,QAAgB,EAAE,SAAiB,EAAE,EAAE,CACvC,MAAM,CAAC,WAAW,CAAC,QAAQ,EAAE,SAAS,CAAC,CAAC,CACzC;iBACD;gBACD,cAAc,EAAE;oBACf;wBACC,QAAQ,EAAE,WAAW,CAAC,SAAS,EAAE,QAAQ,CAAC;qBAC1C;iBACD;aACD;YACD,GAAG,YAAY;SACA,CAAC,CAAC;QACnB,IAAI,CAAC,EAAE,CAAC,QAAQ,EAAE,GAAG,EAAE;YACtB,kBAAkB,EAAE,CAAC,IAAI,CAAC,CAAC;QAC5B,CAAC,CAAC,CAAC;IACJ,CAAC;IACD,OAAO,IAAI,CAAC;AACb,CAAC;AAED,eAAe,cAAc,CAAC"}
1
+ {"version":3,"file":"i18nFrontend.js","sourceRoot":"","sources":["../src/i18nFrontend.ts"],"names":[],"mappings":"AAcA,OAAO,IAA0B,MAAM,SAAS,CAAC;AACjD,OAAO,8BAA8B,MAAM,kCAAkC,CAAC;AAC9E,OAAO,cAAc,MAAM,yBAAyB,CAAC;AACrD,OAAO,WAAW,MAAM,sBAAsB,CAAC;AAC/C,OAAO,kBAAkB,MAAM,8BAA8B,CAAC;AAC9D,OAAO,EAAE,gBAAgB,EAAE,MAAM,eAAe,CAAC;AACjD,OAAO,EAAE,iBAAiB,EAAE,MAAM,uBAAuB,CAAC;AAE1D,MAAM,YAAY,GAAgB;IACjC,KAAK,EAAE;QACN,WAAW,EAAE,IAAI;KACjB;IACD,SAAS,EAAE;QACV,KAAK,EAAE,CAAC,WAAW,EAAE,SAAS,EAAE,MAAM,EAAE,WAAW,CAAC;QACpD,MAAM,EAAE,CAAC,cAAc,EAAE,QAAQ,CAAC;KAClC;CACD,CAAC;AAEF,MAAM,WAAW,GAAG,CAAC,QAAgB,EAAE,SAAiB,EAAE,EAAE;IAC3D,MAAM,QAAQ,GAAG,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,CAAC;IAClD,OAAO,GAAG,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,OAAO,CAAC,IAAI,QAAQ,EAAE,EAAE,EAAE,CAAC,YAAY,QAAQ,IAAI,SAAS,OAAO,CAAC;AAC/F,CAAC,CAAC;AAEF,MAAM,UAAU,cAAc,CAC7B,kBAAiD,EACjD,GAAY;IAEZ,IAAI,CAAC,IAAI,CAAC,aAAa,EAAE,CAAC;QACzB,IAAI;aAEF,GAAG,CAAC,cAAc,CAAC;aACnB,GAAG,CACH,IAAI,8BAA8B,CAAC,IAAI,EAAE;YACxC,KAAK,EAAE,CAAC,QAAQ,EAAE,cAAc,EAAE,WAAW,CAAC;YAC9C,iBAAiB,EAAE,KAAK;YACxB,YAAY,EAAE,SAAS;YACvB,kBAAkB,EAAE,YAAY;YAChC,MAAM,EAAE,CAAC,cAAc,EAAE,QAAQ,CAAC;SAClC,CAAC,CACF;aACA,GAAG,CAAC,gBAAgB,CAAC;aACrB,IAAI,CAAC;YACL,GAAG,iBAAiB;YAOpB,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,GAAG,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;YACvB,OAAO,EAAE;gBACR,QAAQ,EAAE;oBACT,WAAW;oBAEX,kBAAkB,CACjB,CAAC,QAAgB,EAAE,SAAiB,EAAE,EAAE,CACvC,MAAM,CAAC,WAAW,CAAC,QAAQ,EAAE,SAAS,CAAC,CAAC,CACzC;iBACD;gBACD,cAAc,EAAE;oBACf;wBACC,QAAQ,EAAE,WAAW,CAAC,SAAS,EAAE,QAAQ,CAAC;qBAC1C;iBACD;aACD;YACD,GAAG,YAAY;SACA,CAAC,CAAC;QAKnB,IAAI,QAAQ,GAAG,KAAK,CAAC;QACrB,IAAI,CAAC,EAAE,CAAC,QAAQ,EAAE,GAAG,EAAE;YACtB,IAAI,QAAQ,EAAE,CAAC;gBACd,OAAO;YACR,CAAC;YACD,QAAQ,GAAG,IAAI,CAAC;YAChB,kBAAkB,EAAE,CAAC,IAAI,CAAC,CAAC;QAC5B,CAAC,CAAC,CAAC;IACJ,CAAC;SAAM,CAAC;QAMP,kBAAkB,EAAE,CAAC,IAAI,CAAC,CAAC;IAC5B,CAAC;IACD,OAAO,IAAI,CAAC;AACb,CAAC;AAED,eAAe,cAAc,CAAC"}
@@ -1,4 +1,5 @@
1
1
  import type { i18n } from "i18next";
2
+ export declare const I18N_LOAD_TIMEOUT_MS = 10000;
2
3
  declare function loadI18next(backend: boolean, lng?: string): Promise<i18n>;
3
4
  export type { i18n as Ti18n };
4
5
  export default loadI18next;
@@ -1 +1 @@
1
- {"version":3,"file":"loadI18next.d.ts","sourceRoot":"","sources":["../src/loadI18next.ts"],"names":[],"mappings":"AAcA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,SAAS,CAAC;AAapC,iBAAe,WAAW,CAAC,OAAO,EAAE,OAAO,EAAE,GAAG,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAqCxE;AAED,YAAY,EAAE,IAAI,IAAI,KAAK,EAAE,CAAC;AAE9B,eAAe,WAAW,CAAC"}
1
+ {"version":3,"file":"loadI18next.d.ts","sourceRoot":"","sources":["../src/loadI18next.ts"],"names":[],"mappings":"AAcA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,SAAS,CAAC;AAapC,eAAO,MAAM,oBAAoB,QAAS,CAAC;AAY3C,iBAAe,WAAW,CAAC,OAAO,EAAE,OAAO,EAAE,GAAG,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CA6FxE;AAED,YAAY,EAAE,IAAI,IAAI,KAAK,EAAE,CAAC;AAE9B,eAAe,WAAW,CAAC"}
@@ -1,26 +1,52 @@
1
1
  //#region src/loadI18next.ts
2
2
  var i18nInstance;
3
+ /**
4
+ * How long to wait for i18next to report `loaded` before giving up on it.
5
+ *
6
+ * Resolution is driven by an event, and events are not guaranteed: a backend
7
+ * that never answers (http backend against a dead CDN, fs backend against a
8
+ * missing locales dir) leaves the listener armed and the promise pending for
9
+ * the lifetime of the process. `cli.ts` calls loadI18next(true).then(...) with
10
+ * nothing to time it out, so a pending promise there is a silent boot hang with
11
+ * no log line to explain it.
12
+ */
13
+ var I18N_LOAD_TIMEOUT_MS = 1e4;
3
14
  var reconcileLanguage = async (instance, lng) => {
4
15
  if (lng && instance.language !== lng) await instance.changeLanguage(lng);
5
16
  return instance;
6
17
  };
7
18
  async function loadI18next(backend, lng) {
8
19
  return new Promise((resolve, reject) => {
9
- try {
10
- if (backend) import("./i18nBackend.js").then(({ default: initializeI18n }) => {
11
- if (!i18nInstance) i18nInstance = initializeI18n(resolve);
12
- else resolve(i18nInstance);
13
- });
14
- else import("./i18nFrontend.js").then(({ default: initializeI18n }) => {
15
- if (!i18nInstance) i18nInstance = initializeI18n((instance) => {
16
- reconcileLanguage(instance, lng).then(resolve);
17
- }, lng);
18
- else reconcileLanguage(i18nInstance, lng).then(resolve);
19
- });
20
- } catch (e) {
21
- reject(e);
22
- }
20
+ let settled = false;
21
+ const timer = setTimeout(() => {
22
+ settled = true;
23
+ if (i18nInstance) resolve(i18nInstance);
24
+ else reject(/* @__PURE__ */ new Error(`i18next did not load within ${I18N_LOAD_TIMEOUT_MS}ms and no instance was created`));
25
+ }, I18N_LOAD_TIMEOUT_MS);
26
+ timer.unref?.();
27
+ const done = (instance) => {
28
+ if (settled) return;
29
+ settled = true;
30
+ clearTimeout(timer);
31
+ resolve(instance);
32
+ };
33
+ const failWith = (error) => {
34
+ if (settled) return;
35
+ settled = true;
36
+ clearTimeout(timer);
37
+ reject(error);
38
+ };
39
+ if (backend) import("./i18nBackend.js").then(({ default: initializeI18n }) => {
40
+ if (!i18nInstance) i18nInstance = initializeI18n(done);
41
+ else done(i18nInstance);
42
+ }).catch(failWith);
43
+ else import("./i18nFrontend.js").then(({ default: initializeI18n }) => {
44
+ if (!i18nInstance) i18nInstance = initializeI18n((instance) => {
45
+ reconcileLanguage(instance, lng).then(done).catch(failWith);
46
+ }, lng);
47
+ else reconcileLanguage(i18nInstance, lng).then(done).catch(failWith);
48
+ }).catch(failWith);
23
49
  });
24
50
  }
25
51
  //#endregion
26
- export { loadI18next as default };
52
+ export { I18N_LOAD_TIMEOUT_MS, loadI18next as default };
@@ -1 +1 @@
1
- {"version":3,"file":"loadI18next.js","sourceRoot":"","sources":["../src/loadI18next.ts"],"names":[],"mappings":"AAeA,IAAI,YAAkB,CAAC;AAEvB,MAAM,iBAAiB,GAAG,KAAK,EAC9B,QAAc,EACd,GAAuB,EACP,EAAE;IAClB,IAAI,GAAG,IAAI,QAAQ,CAAC,QAAQ,KAAK,GAAG,EAAE,CAAC;QACtC,MAAM,QAAQ,CAAC,cAAc,CAAC,GAAG,CAAC,CAAC;IACpC,CAAC;IACD,OAAO,QAAQ,CAAC;AACjB,CAAC,CAAC;AAEF,KAAK,UAAU,WAAW,CAAC,OAAgB,EAAE,GAAY;IACxD,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;QACtC,IAAI,CAAC;YACJ,IAAI,OAAO,EAAE,CAAC;gBACb,MAAM,CAAC,kBAAkB,CAAC,CAAC,IAAI,CAAC,CAAC,EAAE,OAAO,EAAE,cAAc,EAAE,EAAE,EAAE;oBAC/D,IAAI,CAAC,YAAY,EAAE,CAAC;wBAEnB,YAAY,GAAG,cAAc,CAAC,OAAO,CAAC,CAAC;oBACxC,CAAC;yBAAM,CAAC;wBAEP,OAAO,CAAC,YAAY,CAAC,CAAC;oBACvB,CAAC;gBACF,CAAC,CAAC,CAAC;YACJ,CAAC;iBAAM,CAAC;gBACP,MAAM,CAAC,mBAAmB,CAAC,CAAC,IAAI,CAAC,CAAC,EAAE,OAAO,EAAE,cAAc,EAAE,EAAE,EAAE;oBAChE,IAAI,CAAC,YAAY,EAAE,CAAC;wBAKnB,YAAY,GAAG,cAAc,CAAC,CAAC,QAAQ,EAAE,EAAE;4BAC1C,KAAK,iBAAiB,CAAC,QAAQ,EAAE,GAAG,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;wBACrD,CAAC,EAAE,GAAG,CAAC,CAAC;oBACT,CAAC;yBAAM,CAAC;wBAMP,KAAK,iBAAiB,CAAC,YAAY,EAAE,GAAG,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;oBACzD,CAAC;gBACF,CAAC,CAAC,CAAC;YACJ,CAAC;QACF,CAAC;QAAC,OAAO,CAAC,EAAE,CAAC;YACZ,MAAM,CAAC,CAAC,CAAC,CAAC;QACX,CAAC;IACF,CAAC,CAAC,CAAC;AACJ,CAAC;AAID,eAAe,WAAW,CAAC"}
1
+ {"version":3,"file":"loadI18next.js","sourceRoot":"","sources":["../src/loadI18next.ts"],"names":[],"mappings":"AAeA,IAAI,YAAkB,CAAC;AAYvB,MAAM,CAAC,MAAM,oBAAoB,GAAG,MAAM,CAAC;AAE3C,MAAM,iBAAiB,GAAG,KAAK,EAC9B,QAAc,EACd,GAAuB,EACP,EAAE;IAClB,IAAI,GAAG,IAAI,QAAQ,CAAC,QAAQ,KAAK,GAAG,EAAE,CAAC;QACtC,MAAM,QAAQ,CAAC,cAAc,CAAC,GAAG,CAAC,CAAC;IACpC,CAAC;IACD,OAAO,QAAQ,CAAC;AACjB,CAAC,CAAC;AAEF,KAAK,UAAU,WAAW,CAAC,OAAgB,EAAE,GAAY;IACxD,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;QAQtC,IAAI,OAAO,GAAG,KAAK,CAAC;QAGpB,MAAM,KAAK,GAAG,UAAU,CAAC,GAAG,EAAE;YAC7B,OAAO,GAAG,IAAI,CAAC;YACf,IAAI,YAAY,EAAE,CAAC;gBAClB,OAAO,CAAC,YAAY,CAAC,CAAC;YACvB,CAAC;iBAAM,CAAC;gBACP,MAAM,CACL,IAAI,KAAK,CACR,+BAA+B,oBAAoB,gCAAgC,CACnF,CACD,CAAC;YACH,CAAC;QACF,CAAC,EAAE,oBAAoB,CAAC,CAAC;QAIzB,KAAK,CAAC,KAAK,EAAE,EAAE,CAAC;QAKhB,MAAM,IAAI,GAAG,CAAC,QAAc,EAAQ,EAAE;YACrC,IAAI,OAAO,EAAE,CAAC;gBACb,OAAO;YACR,CAAC;YACD,OAAO,GAAG,IAAI,CAAC;YACf,YAAY,CAAC,KAAK,CAAC,CAAC;YACpB,OAAO,CAAC,QAAQ,CAAC,CAAC;QACnB,CAAC,CAAC;QACF,MAAM,QAAQ,GAAG,CAAC,KAAc,EAAQ,EAAE;YACzC,IAAI,OAAO,EAAE,CAAC;gBACb,OAAO;YACR,CAAC;YACD,OAAO,GAAG,IAAI,CAAC;YACf,YAAY,CAAC,KAAK,CAAC,CAAC;YACpB,MAAM,CAAC,KAAK,CAAC,CAAC;QACf,CAAC,CAAC;QAQF,IAAI,OAAO,EAAE,CAAC;YACb,MAAM,CAAC,kBAAkB,CAAC;iBACxB,IAAI,CAAC,CAAC,EAAE,OAAO,EAAE,cAAc,EAAE,EAAE,EAAE;gBACrC,IAAI,CAAC,YAAY,EAAE,CAAC;oBAGnB,YAAY,GAAG,cAAc,CAAC,IAAI,CAAC,CAAC;gBACrC,CAAC;qBAAM,CAAC;oBAEP,IAAI,CAAC,YAAY,CAAC,CAAC;gBACpB,CAAC;YACF,CAAC,CAAC;iBACD,KAAK,CAAC,QAAQ,CAAC,CAAC;QACnB,CAAC;aAAM,CAAC;YACP,MAAM,CAAC,mBAAmB,CAAC;iBACzB,IAAI,CAAC,CAAC,EAAE,OAAO,EAAE,cAAc,EAAE,EAAE,EAAE;gBACrC,IAAI,CAAC,YAAY,EAAE,CAAC;oBAKnB,YAAY,GAAG,cAAc,CAAC,CAAC,QAAQ,EAAE,EAAE;wBAC1C,KAAK,iBAAiB,CAAC,QAAQ,EAAE,GAAG,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC;oBAClE,CAAC,EAAE,GAAG,CAAC,CAAC;gBACT,CAAC;qBAAM,CAAC;oBAMP,KAAK,iBAAiB,CAAC,YAAY,EAAE,GAAG,CAAC;yBACvC,IAAI,CAAC,IAAI,CAAC;yBACV,KAAK,CAAC,QAAQ,CAAC,CAAC;gBACnB,CAAC;YACF,CAAC,CAAC;iBACD,KAAK,CAAC,QAAQ,CAAC,CAAC;QACnB,CAAC;IACF,CAAC,CAAC,CAAC;AACJ,CAAC;AAID,eAAe,WAAW,CAAC"}
@@ -0,0 +1,2 @@
1
+ export declare const getProcess: () => NodeJS.Process | undefined;
2
+ //# sourceMappingURL=process.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"process.d.ts","sourceRoot":"","sources":["../src/process.ts"],"names":[],"mappings":"AA2BA,eAAO,MAAM,UAAU,QAAO,MAAM,CAAC,OAAO,GAAG,SACM,CAAC"}
@@ -0,0 +1,17 @@
1
+ //#region src/process.ts
2
+ /**
3
+ * The `process` global, or undefined where there is none.
4
+ *
5
+ * This package is reached transitively from browser bundles, where `process`
6
+ * may be missing entirely or present but stripped down. A bare `process.env`
7
+ * read throws a ReferenceError in that case and takes the whole page down.
8
+ *
9
+ * It is a function, and it lives in its own module, so callers can be tested
10
+ * against a runtime that has no `process` at all. Inlining the `typeof` check
11
+ * at the point of use makes that branch untestable: vitest calls
12
+ * `process.memoryUsage()` between suites, so stubbing the real global away
13
+ * fails the run rather than the module under test.
14
+ */
15
+ var getProcess = () => typeof process !== "undefined" ? process : void 0;
16
+ //#endregion
17
+ export { getProcess };
@@ -0,0 +1 @@
1
+ {"version":3,"file":"process.js","sourceRoot":"","sources":["../src/process.ts"],"names":[],"mappings":"AA2BA,MAAM,CAAC,MAAM,UAAU,GAAG,GAA+B,EAAE,CAC1D,OAAO,OAAO,KAAK,WAAW,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,SAAS,CAAC"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=i18SharedOptions.unit.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"i18SharedOptions.unit.test.d.ts","sourceRoot":"","sources":["../../src/tests/i18SharedOptions.unit.test.ts"],"names":[],"mappings":""}