File tree Expand file tree Collapse file tree 4 files changed +78
-0
lines changed
packages/vue-intlayer/src/client Expand file tree Collapse file tree 4 files changed +78
-0
lines changed Original file line number Diff line number Diff line change 1
1
export * from './installIntlayer' ;
2
2
export * from './useDictionary' ;
3
+ export * from './useDictionaryDynamic' ;
3
4
export * from './useIntlayer' ;
5
+ export * from './useLoadDynamic' ;
4
6
export * from './useLocale' ;
Original file line number Diff line number Diff line change @@ -15,6 +15,7 @@ export const useDictionary = <T extends Dictionary>(
15
15
const localeTarget = computed ( ( ) => locale ?? intlayer ?. locale ?. value ) ;
16
16
17
17
/** a *stable* reactive dictionary object */
18
+ // @ts -expect-error - Fix Type instantiation is excessively deep and possibly infinite
18
19
const content = reactive ( { } ) as DeepTransformContent < T [ 'content' ] > ;
19
20
20
21
/** whenever `key` or `locale` change, refresh the dictionary */
Original file line number Diff line number Diff line change
1
+ 'use client' ;
2
+
3
+ import type { LocalesValues } from '@intlayer/config/client' ;
4
+ import type {
5
+ Dictionary ,
6
+ DictionaryKeys ,
7
+ LanguageContent ,
8
+ } from '@intlayer/core' ;
9
+ import { computed , inject } from 'vue' ;
10
+ import { INTLAYER_SYMBOL , IntlayerProvider } from './installIntlayer' ;
11
+ import { useDictionary } from './useDictionary' ;
12
+ import { useLoadDynamic } from './useLoadDynamic' ;
13
+
14
+ /**
15
+ * On the server side, Hook that transform a dictionary and return the content
16
+ *
17
+ * If the locale is not provided, it will use the locale from the client context
18
+ */
19
+ export const useDictionaryDynamic = <
20
+ T extends Dictionary ,
21
+ K extends DictionaryKeys ,
22
+ > (
23
+ dictionaryPromise : LanguageContent < ( ) => Promise < T > > ,
24
+ key : K ,
25
+ locale ?: LocalesValues
26
+ ) => {
27
+ const intlayer = inject < IntlayerProvider > ( INTLAYER_SYMBOL ) ;
28
+
29
+ const localeTarget = computed ( ( ) => locale ?? intlayer ?. locale ?. value ) ;
30
+
31
+ const dictionary = useLoadDynamic < T > (
32
+ `${ String ( key ) } .${ localeTarget . value } ` ,
33
+ dictionaryPromise [ localeTarget . value ] ! ( )
34
+ ) as T ;
35
+
36
+ return useDictionary ( dictionary , localeTarget as any ) ;
37
+ } ;
Original file line number Diff line number Diff line change
1
+ import { reactive } from 'vue' ;
2
+
3
+ /**
4
+ * A "synchronous" loader for a dynamically‐imported JSON (or anything).
5
+ *
6
+ * - Immediately returns a reactive object so that Vue can properly track changes.
7
+ * - When the Promise resolves, it replaces the object's properties with the real data.
8
+ */
9
+ export const useLoadDynamic = < T extends Record < string , any > > (
10
+ key : string ,
11
+ promise : Promise < T >
12
+ ) : T => {
13
+ // A module‐level cache of Promises, so we only import once per key.
14
+ const cache : Map < string , Promise < T > > = ( useLoadDynamic as any ) . _cache ||
15
+ ( ( useLoadDynamic as any ) . _cache = new Map ( ) ) ;
16
+
17
+ // Hold the "current" value as a reactive object
18
+ // This starts as an empty object but Vue can track changes to it
19
+ const container = reactive ( { } as T ) ;
20
+
21
+ if ( ! cache . has ( key ) ) {
22
+ // Kick off the dynamic import & cache it
23
+ const p = promise . then ( ( real ) => {
24
+ // As soon as the import resolves, populate the container with the real data
25
+ Object . assign ( container , real ) ;
26
+ return real ;
27
+ } ) ;
28
+ cache . set ( key , p ) ;
29
+ } else {
30
+ // If it's already in flight (or done), hook into it so that the container still updates
31
+ cache . get ( key ) ! . then ( ( real ) => {
32
+ Object . assign ( container , real ) ;
33
+ } ) ;
34
+ }
35
+
36
+ // Return the reactive container directly - Vue can track all changes to it
37
+ return container as T ;
38
+ } ;
You can’t perform that action at this time.
0 commit comments