@jsarc/intl 0.0.1-beta.0.3 → 0.0.1-beta.0.4

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.
@@ -1,8 +1,104 @@
1
1
  import React from "react";
2
- import { createContext, useContext, useState, useEffect, useCallback } from 'react';
2
+ import { createContext, useContext, useState, useEffect, useMemo, useCallback } from 'react';
3
3
  import { TranslationService } from '../core/TranslationService';
4
4
  import { getSavedLocale, saveLocale, SUPPORTED_LOCALES } from '../config';
5
5
  const ArcIntlContext = createContext(null);
6
+ export const ArcIntlProvider = ({
7
+ translations,
8
+ supportedLocales,
9
+ children
10
+ }) => {
11
+ const finalSupportedLocales = useMemo(() => {
12
+ return typeof supportedLocales === 'object' && !!Array.isArray(supportedLocales) && supportedLocales.length > 0 ? supportedLocales : SUPPORTED_LOCALES;
13
+ }, [supportedLocales]);
14
+ const [service] = useState(() => new TranslationService(finalSupportedLocales, translations));
15
+ const [currentLocale, setCurrentLocale] = useState(() => getSavedLocale(finalSupportedLocales));
16
+ const [isLoading, setIsLoading] = useState(true);
17
+ const [initialized, setInitialized] = useState(false);
18
+ useEffect(() => {
19
+ const initialize = async () => {
20
+ setIsLoading(true);
21
+ try {
22
+ if (!initialized) {
23
+ await service.initialize(currentLocale);
24
+ setInitialized(true);
25
+ } else {
26
+ await service.initialize(currentLocale);
27
+ }
28
+ } catch (error) {
29
+ console.error('❌ Failed to initialize translations:', error);
30
+ } finally {
31
+ setIsLoading(false);
32
+ }
33
+ };
34
+ const timer = setTimeout(() => {
35
+ initialize();
36
+ }, 0);
37
+ return () => clearTimeout(timer);
38
+ }, [currentLocale, service, initialized]);
39
+ useEffect(() => {
40
+ if (!initialized || isLoading || !translations.modules) return;
41
+ const loadAllModules = async () => {
42
+ const moduleNames = Object.keys(translations.modules || {});
43
+ for (const moduleName of moduleNames) {
44
+ try {
45
+ await service.loadModule(moduleName);
46
+ } catch (error) {
47
+ console.error(`❌ Failed to load module ${moduleName}:`, error);
48
+ }
49
+ }
50
+ };
51
+ loadAllModules();
52
+ }, [initialized, translations.modules, service, isLoading]);
53
+ const changeLocale = useCallback(async locale => {
54
+ if (!finalSupportedLocales.includes(locale)) {
55
+ console.warn(`⚠️ Locale ${locale} is not supported`);
56
+ return;
57
+ }
58
+ if (locale === currentLocale) return;
59
+ setIsLoading(true);
60
+ try {
61
+ await service.initialize(locale);
62
+ setCurrentLocale(locale);
63
+ saveLocale(locale);
64
+ } catch (error) {
65
+ console.error('❌ Failed to change locale:', error);
66
+ } finally {
67
+ setIsLoading(false);
68
+ }
69
+ }, [currentLocale, finalSupportedLocales, service]);
70
+ const loadModuleTranslations = useCallback(async moduleName => {
71
+ setIsLoading(true);
72
+ try {
73
+ await service.loadModule(moduleName);
74
+ } catch (error) {
75
+ console.error(`❌ Failed to load module ${moduleName}:`, error);
76
+ throw error;
77
+ } finally {
78
+ setIsLoading(false);
79
+ }
80
+ }, [service]);
81
+ const t = useCallback((key, params, options) => {
82
+ const result = service.t(key, params || {}, options || {});
83
+ return result;
84
+ }, [service]);
85
+ const contextValue = useMemo(() => ({
86
+ t,
87
+ changeLocale,
88
+ currentLocale,
89
+ isLoading,
90
+ loadModuleTranslations,
91
+ isInitialized: initialized
92
+ }), [t, changeLocale, currentLocale, isLoading, loadModuleTranslations, initialized]);
93
+ return React.createElement(ArcIntlContext.Provider, {
94
+ value: contextValue
95
+ }, children);
96
+ };
97
+ export const useArcIntl = () => {
98
+ const context = useContext(ArcIntlContext);
99
+ if (!context) throw new Error('useArcIntl must be used within an ArcIntlProvider');
100
+ return context;
101
+ };
6
102
  const useArcIntlValue = (translationsConfig, supportedLocales = SUPPORTED_LOCALES) => {
7
103
  const [service] = useState(() => new TranslationService(supportedLocales, translationsConfig));
8
104
  const [currentLocale, setCurrentLocale] = useState(getSavedLocale(supportedLocales));
@@ -84,23 +180,7 @@ const useArcIntlValue = (translationsConfig, supportedLocales = SUPPORTED_LOCALE
84
180
  isInitialized: initialized
85
181
  };
86
182
  };
87
- export const ArcIntlProvider = ({
88
- translations,
89
- supportedLocales,
90
- children
91
- }) => {
92
- const value = useArcIntlValue(translations, typeof supportedLocales === 'object' && !!Array.isArray(supportedLocales) && supportedLocales.length > 0 ? supportedLocales : SUPPORTED_LOCALES);
93
- return React.createElement(ArcIntlContext.Provider, {
94
- value: value
95
- }, children);
96
- };
97
- export const useArcIntl = () => {
98
- const context = useContext(ArcIntlContext);
99
- if (!context) throw new Error('useArcIntl must be used within an ArcIntlProvider');
100
- return context;
101
- };
102
183
  export default {
103
- useArcIntlValue,
104
184
  ArcIntlProvider,
105
185
  useArcIntl
106
186
  };
package/package.json CHANGED
@@ -3,7 +3,7 @@
3
3
  "publishConfig": {
4
4
  "access": "public"
5
5
  },
6
- "version": "0.0.1-beta.0.3",
6
+ "version": "0.0.1-beta.0.4",
7
7
  "description": "INTL est un système de gestion d'internationalisation (i18n) modulaire et performant pour les applications React avec TypeScript/JavaScript. Il fournit une gestion avancée des traductions, un chargement dynamique des modules, et une intégration transparente avec l'écosystème Arc.",
8
8
  "main": "index.ts",
9
9
  "keywords": [],
@@ -3,7 +3,127 @@ import { TranslationService } from '../core/TranslationService';
3
3
  import { getSavedLocale, saveLocale, SUPPORTED_LOCALES, type TranslationsConfig } from '../config';
4
4
  import type { Locale } from '../config';
5
5
 
6
- const ArcIntlContext = createContext<ReturnType<typeof useArcIntlValue> | null>(null);
6
+ const ArcIntlContext = createContext<any | null>(null);
7
+
8
+ export const ArcIntlProvider: React.FC<{
9
+ children: React.ReactNode
10
+ translations: TranslationsConfig
11
+ supportedLocales?: string[];
12
+ }> = ({
13
+ translations,
14
+ supportedLocales,
15
+ children,
16
+ }) => {
17
+ const finalSupportedLocales = useMemo(() => {
18
+ return (typeof supportedLocales === 'object' &&
19
+ !!Array.isArray(supportedLocales) &&
20
+ supportedLocales.length > 0)
21
+ ? supportedLocales
22
+ : SUPPORTED_LOCALES;
23
+ }, [supportedLocales]);
24
+
25
+ const [service] = useState(() => new TranslationService(finalSupportedLocales, translations));
26
+
27
+ const [currentLocale, setCurrentLocale] = useState<Locale>(() => getSavedLocale(finalSupportedLocales));
28
+ const [isLoading, setIsLoading] = useState(true);
29
+ const [initialized, setInitialized] = useState(false);
30
+
31
+ useEffect(() => {
32
+ const initialize = async () => {
33
+ setIsLoading(true);
34
+ try {
35
+ if (!initialized) {
36
+ await service.initialize(currentLocale);
37
+ setInitialized(true);
38
+ } else {
39
+ await service.initialize(currentLocale);
40
+ }
41
+ } catch (error) {
42
+ console.error('❌ Failed to initialize translations:', error);
43
+ } finally {
44
+ setIsLoading(false);
45
+ }
46
+ };
47
+
48
+ const timer = setTimeout(() => {
49
+ initialize();
50
+ }, 0);
51
+
52
+ return () => clearTimeout(timer);
53
+ }, [currentLocale, service, initialized]);
54
+
55
+ useEffect(() => {
56
+ if (!initialized || isLoading || !translations.modules) return;
57
+
58
+ const loadAllModules = async () => {
59
+ const moduleNames = Object.keys(translations.modules || {});
60
+
61
+ for (const moduleName of moduleNames) {
62
+ try {
63
+ await service.loadModule(moduleName);
64
+ } catch (error) {
65
+ console.error(`❌ Failed to load module ${moduleName}:`, error);
66
+ }
67
+ }
68
+ };
69
+
70
+ loadAllModules();
71
+ }, [initialized, translations.modules, service, isLoading]);
72
+
73
+ const changeLocale = useCallback(async (locale: Locale) => {
74
+ if (!finalSupportedLocales.includes(locale)) {
75
+ console.warn(`⚠️ Locale ${locale} is not supported`);
76
+ return;
77
+ }
78
+
79
+ if (locale === currentLocale) return;
80
+
81
+ setIsLoading(true);
82
+ try {
83
+ await service.initialize(locale);
84
+ setCurrentLocale(locale);
85
+ saveLocale(locale);
86
+ } catch (error) {
87
+ console.error('❌ Failed to change locale:', error);
88
+ } finally {
89
+ setIsLoading(false);
90
+ }
91
+ }, [currentLocale, finalSupportedLocales, service]);
92
+
93
+ const loadModuleTranslations = useCallback(async (moduleName: string) => {
94
+ setIsLoading(true);
95
+ try {
96
+ await service.loadModule(moduleName);
97
+ } catch (error) {
98
+ console.error(`❌ Failed to load module ${moduleName}:`, error);
99
+ throw error;
100
+ } finally {
101
+ setIsLoading(false);
102
+ }
103
+ }, [service]);
104
+
105
+ const t = useCallback((key: string, params?: Record<string, any>, options?: any) => {
106
+ const result = service.t(key, params || {}, options || {});
107
+ return result;
108
+ }, [service]);
109
+
110
+ const contextValue = useMemo(() => ({
111
+ t,
112
+ changeLocale,
113
+ currentLocale,
114
+ isLoading,
115
+ loadModuleTranslations,
116
+ isInitialized: initialized,
117
+ }), [t, changeLocale, currentLocale, isLoading, loadModuleTranslations, initialized]);
118
+
119
+ return <ArcIntlContext.Provider value={contextValue}>{children}</ArcIntlContext.Provider>;
120
+ };
121
+
122
+ export const useArcIntl = () => {
123
+ const context = useContext(ArcIntlContext);
124
+ if (!context) throw new Error('useArcIntl must be used within an ArcIntlProvider');
125
+ return context;
126
+ };
7
127
 
8
128
  const useArcIntlValue = (
9
129
  translationsConfig: TranslationsConfig,
@@ -13,7 +133,7 @@ const useArcIntlValue = (
13
133
  const [currentLocale, setCurrentLocale] = useState<Locale>(getSavedLocale(supportedLocales));
14
134
  const [isLoading, setIsLoading] = useState(true);
15
135
  const [initialized, setInitialized] = useState(false);
16
-
136
+
17
137
  useEffect(() => {
18
138
  const initialize = async () => {
19
139
  setIsLoading(true);
@@ -30,14 +150,14 @@ const useArcIntlValue = (
30
150
  setIsLoading(false);
31
151
  }
32
152
  };
33
-
153
+
34
154
  const timer = setTimeout(() => {
35
155
  initialize();
36
156
  }, 0);
37
157
 
38
158
  return () => clearTimeout(timer);
39
159
  }, [currentLocale, service, initialized]);
40
-
160
+
41
161
  useEffect(() => {
42
162
  if (!initialized || isLoading || !translationsConfig.modules) return;
43
163
 
@@ -103,36 +223,7 @@ const useArcIntlValue = (
103
223
  };
104
224
  };
105
225
 
106
- export const ArcIntlProvider: React.FC<{
107
- children: React.ReactNode
108
- translations: TranslationsConfig
109
- supportedLocales?: string[];
110
- }> = ({
111
- translations,
112
- supportedLocales,
113
- children,
114
- }) => {
115
-
116
- const value = useArcIntlValue(
117
- translations,
118
- (typeof supportedLocales === 'object' &&
119
- !!Array.isArray(supportedLocales) &&
120
- supportedLocales.length > 0)
121
- ? supportedLocales
122
- : SUPPORTED_LOCALES
123
- );
124
-
125
- return <ArcIntlContext.Provider value={value}>{children}</ArcIntlContext.Provider>;
126
- };
127
-
128
- export const useArcIntl = () => {
129
- const context = useContext(ArcIntlContext);
130
- if (!context) throw new Error('useArcIntl must be used within an ArcIntlProvider');
131
- return context;
132
- };
133
-
134
226
  export default {
135
- useArcIntlValue,
136
227
  ArcIntlProvider,
137
228
  useArcIntl,
138
- }
229
+ };