i18n: optimize performance
* createCurrentLanguage: caching result with memo * createStringResource: use useAppLocale
This commit is contained in:
		
							parent
							
								
									6df5c2e216
								
							
						
					
					
						commit
						b1812392cb
					
				
					 1 changed files with 44 additions and 2 deletions
				
			
		| 
						 | 
				
			
			@ -25,12 +25,22 @@ const DEFAULT_LANG = "en";
 | 
			
		|||
 | 
			
		||||
/**
 | 
			
		||||
 * Decide the using language for the user.
 | 
			
		||||
 *
 | 
			
		||||
 * **Performance**: This function is costy, make sure you cache the result.
 | 
			
		||||
 * In the app, you should use {@link useAppLocale} instead.
 | 
			
		||||
 *
 | 
			
		||||
 * @returns the selected language tag
 | 
			
		||||
 */
 | 
			
		||||
export function autoMatchLangTag() {
 | 
			
		||||
  return match(Array.from(navigator.languages), SUPPORTED_LANGS, DEFAULT_LANG);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Decide the using region for the user.
 | 
			
		||||
 *
 | 
			
		||||
 * **Performance**: This function is costy, make sure you cache the result.
 | 
			
		||||
 * In the app, you should use {@link useAppLocale} instead.
 | 
			
		||||
 */
 | 
			
		||||
export function autoMatchRegion() {
 | 
			
		||||
  const specifiers = navigator.languages.map((x) => x.split("-"));
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -99,7 +109,7 @@ export function useDateFnLocale(): Accessor<Locale> {
 | 
			
		|||
 | 
			
		||||
export function createCurrentLanguage() {
 | 
			
		||||
  const settings = useStore($settings);
 | 
			
		||||
  return () => settings().language || autoMatchLangTag();
 | 
			
		||||
  return createMemo(() => settings().language || autoMatchLangTag());
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
type ImportFn<T> = (name: string) => Promise<{ default: T }>;
 | 
			
		||||
| 
						 | 
				
			
			@ -114,10 +124,30 @@ type MergedImportedModule<T> = T extends []
 | 
			
		|||
      ? ImportedModule<I> & MergedImportedModule<J>
 | 
			
		||||
      : never;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Create a resource that combines all I18N strings into one object.
 | 
			
		||||
 *
 | 
			
		||||
 * The result is combined in the order of the argument functions.
 | 
			
		||||
 * The formers will be overrided by the latter.
 | 
			
		||||
 *
 | 
			
		||||
 * @param importFns a series of functions imports the string modules
 | 
			
		||||
 * based on the specified language code.
 | 
			
		||||
 *
 | 
			
		||||
 * **Context**: This function must be used under {@link AppLocaleProvider}.
 | 
			
		||||
 *
 | 
			
		||||
 * @example ````ts
 | 
			
		||||
 * const [strings] = createStringResource(
 | 
			
		||||
 *   async (code) => await import(`./i18n/${code}.json`), // Vite can handle the bundling
 | 
			
		||||
 *   async () => import("./i18n/generic.json"), // You can also ignore the code.
 | 
			
		||||
 * );
 | 
			
		||||
 * ````
 | 
			
		||||
 *
 | 
			
		||||
 * @see {@link createTranslator} if you need a Translator from "@solid-primitives/i18n"
 | 
			
		||||
 */
 | 
			
		||||
export function createStringResource<
 | 
			
		||||
  T extends ImportFn<Record<string, string | Template<any> | undefined>>[],
 | 
			
		||||
>(...importFns: T) {
 | 
			
		||||
  const language = createCurrentLanguage();
 | 
			
		||||
  const { language } = useAppLocale();
 | 
			
		||||
  const cache: Record<string, MergedImportedModule<T>> = {};
 | 
			
		||||
 | 
			
		||||
  return createResource(
 | 
			
		||||
| 
						 | 
				
			
			@ -140,6 +170,18 @@ export function createStringResource<
 | 
			
		|||
  );
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Create the Translator from "@solid-primitives/i18n" based on
 | 
			
		||||
 * the {@link createStringResource}.
 | 
			
		||||
 *
 | 
			
		||||
 * @param importFns same to {@link createStringResource}
 | 
			
		||||
 *
 | 
			
		||||
 * @returns the first element is the translator, the second is the result from
 | 
			
		||||
 * {@link createStringResource}.
 | 
			
		||||
 *
 | 
			
		||||
 * @see {@link translator} for the translator usage
 | 
			
		||||
 * @see {@link createStringResource} for the raw strings
 | 
			
		||||
 */
 | 
			
		||||
export function createTranslator<
 | 
			
		||||
  T extends ImportFn<Record<string, string | Template<any> | undefined>>[],
 | 
			
		||||
>(...importFns: T) {
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue