@fluenti/vue 0.2.0 → 0.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 (40) hide show
  1. package/README.md +5 -5
  2. package/dist/components/DateTime.d.ts +1 -1
  3. package/dist/components/DateTime.d.ts.map +1 -1
  4. package/dist/components/NumberFormat.d.ts +1 -1
  5. package/dist/components/NumberFormat.d.ts.map +1 -1
  6. package/dist/components/Plural.d.ts +12 -13
  7. package/dist/components/Plural.d.ts.map +1 -1
  8. package/dist/components/Select.d.ts +12 -13
  9. package/dist/components/Select.d.ts.map +1 -1
  10. package/dist/components/Trans.d.ts +7 -7
  11. package/dist/components/Trans.d.ts.map +1 -1
  12. package/dist/components/rich-text.d.ts +0 -6
  13. package/dist/components/rich-text.d.ts.map +1 -1
  14. package/dist/hooks/__useI18n.d.ts +2 -2
  15. package/dist/hooks/__useI18n.d.ts.map +1 -1
  16. package/dist/index.cjs +1 -1
  17. package/dist/index.cjs.map +1 -1
  18. package/dist/index.d.ts +7 -7
  19. package/dist/index.d.ts.map +1 -1
  20. package/dist/index.js +155 -169
  21. package/dist/index.js.map +1 -1
  22. package/dist/plugin.d.ts +25 -14
  23. package/dist/plugin.d.ts.map +1 -1
  24. package/dist/server.cjs +2 -0
  25. package/dist/server.cjs.map +1 -0
  26. package/dist/server.d.ts +33 -13
  27. package/dist/server.d.ts.map +1 -1
  28. package/dist/server.js +54 -0
  29. package/dist/server.js.map +1 -0
  30. package/dist/use-i18n.d.ts +3 -3
  31. package/dist/use-i18n.d.ts.map +1 -1
  32. package/dist/vite-plugin.cjs +1 -111
  33. package/dist/vite-plugin.cjs.map +1 -1
  34. package/dist/vite-plugin.js +18 -126
  35. package/dist/vite-plugin.js.map +1 -1
  36. package/dist/vue-runtime.d.ts.map +1 -1
  37. package/llms-full.txt +220 -0
  38. package/llms-migration.txt +199 -0
  39. package/llms.txt +82 -0
  40. package/package.json +17 -5
@@ -1,112 +1,2 @@
1
- let e=require(`@fluenti/vite-plugin`),t=require(`@fluenti/vite-plugin/sfc-transform`),n=require(`node:path`);var r={generateRuntime(e){let{catalogDir:t,locales:r,sourceLocale:i,defaultBuildLocale:a}=e,o=a||i,s=(0,n.resolve)(process.cwd(),t);return`
2
- import { shallowReactive, ref } from 'vue'
3
- import __defaultMsgs from '${s}/${o}.js'
4
-
5
- const __catalog = shallowReactive({ ...__defaultMsgs })
6
- const __currentLocale = ref('${o}')
7
- const __loadedLocales = new Set(['${o}'])
8
- const __loading = ref(false)
9
- const __cache = new Map()
10
- const __normalizeMessages = (mod) => mod.default ?? mod
11
-
12
- const __loaders = {
13
- ${r.filter(e=>e!==o).map(e=>` '${e}': () => import('${s}/${e}.js'),`).join(`
14
- `)}
15
- }
16
-
17
- async function __switchLocale(locale) {
18
- if (__loadedLocales.has(locale)) {
19
- Object.assign(__catalog, __cache.get(locale) || __defaultMsgs)
20
- __currentLocale.value = locale
21
- return
22
- }
23
- __loading.value = true
24
- try {
25
- const mod = __normalizeMessages(await __loaders[locale]())
26
- __cache.set(locale, mod)
27
- __loadedLocales.add(locale)
28
- Object.assign(__catalog, mod)
29
- __currentLocale.value = locale
30
- } finally {
31
- __loading.value = false
32
- }
33
- }
34
-
35
- async function __preloadLocale(locale) {
36
- if (__loadedLocales.has(locale) || !__loaders[locale]) return
37
- try {
38
- const mod = __normalizeMessages(await __loaders[locale]())
39
- __cache.set(locale, mod)
40
- __loadedLocales.add(locale)
41
- } catch (e) { console.warn('[fluenti] preload failed:', locale, e) }
42
- }
43
-
44
- globalThis[Symbol.for('fluenti.runtime.vue')] = { __switchLocale, __preloadLocale }
45
-
46
- export { __catalog, __switchLocale, __preloadLocale, __currentLocale, __loading, __loadedLocales }
47
- `},generateRouteRuntime(e){let{catalogDir:t,locales:r,sourceLocale:i,defaultBuildLocale:a}=e,o=a||i,s=(0,n.resolve)(process.cwd(),t);return`
48
- import { shallowReactive, ref } from 'vue'
49
- import __defaultMsgs from '${s}/${o}.js'
50
-
51
- const __catalog = shallowReactive({ ...__defaultMsgs })
52
- const __currentLocale = ref('${o}')
53
- const __loadedLocales = new Set(['${o}'])
54
- const __loading = ref(false)
55
- const __cache = new Map()
56
- const __loadedRoutes = new Set()
57
- const __normalizeMessages = (mod) => mod.default ?? mod
58
-
59
- const __loaders = {
60
- ${r.filter(e=>e!==o).map(e=>` '${e}': () => import('${s}/${e}.js'),`).join(`
61
- `)}
62
- }
63
-
64
- const __routeLoaders = {}
65
-
66
- function __registerRouteLoader(routeId, locale, loader) {
67
- const key = routeId + ':' + locale
68
- __routeLoaders[key] = loader
69
- }
70
-
71
- async function __loadRoute(routeId, locale) {
72
- const key = routeId + ':' + (locale || __currentLocale.value)
73
- if (__loadedRoutes.has(key)) return
74
- const loader = __routeLoaders[key]
75
- if (!loader) return
76
- const mod = __normalizeMessages(await loader())
77
- Object.assign(__catalog, mod)
78
- __loadedRoutes.add(key)
79
- }
80
-
81
- async function __switchLocale(locale) {
82
- if (locale === __currentLocale.value) return
83
- __loading.value = true
84
- try {
85
- if (__cache.has(locale)) {
86
- Object.assign(__catalog, __cache.get(locale))
87
- } else {
88
- const mod = __normalizeMessages(await __loaders[locale]())
89
- __cache.set(locale, mod)
90
- Object.assign(__catalog, mod)
91
- }
92
- __loadedLocales.add(locale)
93
- __currentLocale.value = locale
94
- } finally {
95
- __loading.value = false
96
- }
97
- }
98
-
99
- async function __preloadLocale(locale) {
100
- if (__cache.has(locale) || !__loaders[locale]) return
101
- try {
102
- const mod = __normalizeMessages(await __loaders[locale]())
103
- __cache.set(locale, mod)
104
- __loadedLocales.add(locale)
105
- } catch (e) { console.warn('[fluenti] preload failed:', locale, e) }
106
- }
107
-
108
- globalThis[Symbol.for('fluenti.runtime.vue')] = { __switchLocale, __preloadLocale }
109
-
110
- export { __catalog, __switchLocale, __preloadLocale, __loadRoute, __registerRouteLoader, __currentLocale, __loading, __loadedLocales }
111
- `}};function i(n){let i={name:`fluenti:vue-template`,enforce:`pre`,transform(e,n){if(!n.endsWith(`.vue`)||!/\bv-t\b/.test(e)&&!/<Trans[\s>]/.test(e)&&!/<Plural[\s/>]/.test(e))return;let r=(0,t.transformVtDirectives)(e);if(r!==e)return{code:r,map:null}}};return(0,e.createFluentiPlugins)({...n,framework:`vue`},[i],r)}module.exports=i;
1
+ let e=require(`@fluenti/vite-plugin`),t=require(`@fluenti/vite-plugin/sfc-transform`);var n=(0,e.createRuntimeGenerator)({imports:`import { shallowReactive, ref } from 'vue'`,catalogInit:`const __catalog = shallowReactive({ ...__defaultMsgs })`,localeInit:e=>`const __currentLocale = ref('${e}')`,loadingInit:`const __loading = ref(false)`,catalogUpdate:e=>`Object.assign(__catalog, ${e})`,localeUpdate:e=>`__currentLocale.value = ${e}`,loadingUpdate:e=>`__loading.value = ${e}`,localeRead:`__currentLocale.value`,runtimeKey:`fluenti.runtime.vue.v1`});function r(r){let i={name:`fluenti:vue-template`,enforce:`pre`,transform(e,n){if(!n.endsWith(`.vue`)||!/\bv-t\b/.test(e)&&!/<Trans[\s>]/.test(e)&&!/<Plural[\s/>]/.test(e))return;let r=(0,t.transformVtDirectives)(e);if(r!==e)return{code:r,map:null}}};return(0,e.createFluentiPlugins)({...r?.config===void 0?{}:{config:r.config},framework:`vue`},[i],n)}module.exports=r;
112
2
  //# sourceMappingURL=vite-plugin.cjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"vite-plugin.cjs","names":[],"sources":["../src/vue-runtime.ts","../src/vite-plugin.ts"],"sourcesContent":["import { resolve } from 'node:path'\nimport type { RuntimeGenerator, RuntimeGeneratorOptions } from '@fluenti/vite-plugin'\n\nexport const vueRuntimeGenerator: RuntimeGenerator = {\n generateRuntime(options: RuntimeGeneratorOptions): string {\n const { catalogDir, locales, sourceLocale, defaultBuildLocale } = options\n const defaultLocale = defaultBuildLocale || sourceLocale\n const absoluteCatalogDir = resolve(process.cwd(), catalogDir)\n const runtimeKey = 'fluenti.runtime.vue'\n const lazyLocales = locales.filter((locale) => locale !== defaultLocale)\n\n return `\nimport { shallowReactive, ref } from 'vue'\nimport __defaultMsgs from '${absoluteCatalogDir}/${defaultLocale}.js'\n\nconst __catalog = shallowReactive({ ...__defaultMsgs })\nconst __currentLocale = ref('${defaultLocale}')\nconst __loadedLocales = new Set(['${defaultLocale}'])\nconst __loading = ref(false)\nconst __cache = new Map()\nconst __normalizeMessages = (mod) => mod.default ?? mod\n\nconst __loaders = {\n${lazyLocales.map((l) => ` '${l}': () => import('${absoluteCatalogDir}/${l}.js'),`).join('\\n')}\n}\n\nasync function __switchLocale(locale) {\n if (__loadedLocales.has(locale)) {\n Object.assign(__catalog, __cache.get(locale) || __defaultMsgs)\n __currentLocale.value = locale\n return\n }\n __loading.value = true\n try {\n const mod = __normalizeMessages(await __loaders[locale]())\n __cache.set(locale, mod)\n __loadedLocales.add(locale)\n Object.assign(__catalog, mod)\n __currentLocale.value = locale\n } finally {\n __loading.value = false\n }\n}\n\nasync function __preloadLocale(locale) {\n if (__loadedLocales.has(locale) || !__loaders[locale]) return\n try {\n const mod = __normalizeMessages(await __loaders[locale]())\n __cache.set(locale, mod)\n __loadedLocales.add(locale)\n } catch (e) { console.warn('[fluenti] preload failed:', locale, e) }\n}\n\nglobalThis[Symbol.for('${runtimeKey}')] = { __switchLocale, __preloadLocale }\n\nexport { __catalog, __switchLocale, __preloadLocale, __currentLocale, __loading, __loadedLocales }\n`\n },\n\n generateRouteRuntime(options: RuntimeGeneratorOptions): string {\n const { catalogDir, locales, sourceLocale, defaultBuildLocale } = options\n const defaultLocale = defaultBuildLocale || sourceLocale\n const absoluteCatalogDir = resolve(process.cwd(), catalogDir)\n const runtimeKey = 'fluenti.runtime.vue'\n const lazyLocales = locales.filter((locale) => locale !== defaultLocale)\n\n return `\nimport { shallowReactive, ref } from 'vue'\nimport __defaultMsgs from '${absoluteCatalogDir}/${defaultLocale}.js'\n\nconst __catalog = shallowReactive({ ...__defaultMsgs })\nconst __currentLocale = ref('${defaultLocale}')\nconst __loadedLocales = new Set(['${defaultLocale}'])\nconst __loading = ref(false)\nconst __cache = new Map()\nconst __loadedRoutes = new Set()\nconst __normalizeMessages = (mod) => mod.default ?? mod\n\nconst __loaders = {\n${lazyLocales.map((l) => ` '${l}': () => import('${absoluteCatalogDir}/${l}.js'),`).join('\\n')}\n}\n\nconst __routeLoaders = {}\n\nfunction __registerRouteLoader(routeId, locale, loader) {\n const key = routeId + ':' + locale\n __routeLoaders[key] = loader\n}\n\nasync function __loadRoute(routeId, locale) {\n const key = routeId + ':' + (locale || __currentLocale.value)\n if (__loadedRoutes.has(key)) return\n const loader = __routeLoaders[key]\n if (!loader) return\n const mod = __normalizeMessages(await loader())\n Object.assign(__catalog, mod)\n __loadedRoutes.add(key)\n}\n\nasync function __switchLocale(locale) {\n if (locale === __currentLocale.value) return\n __loading.value = true\n try {\n if (__cache.has(locale)) {\n Object.assign(__catalog, __cache.get(locale))\n } else {\n const mod = __normalizeMessages(await __loaders[locale]())\n __cache.set(locale, mod)\n Object.assign(__catalog, mod)\n }\n __loadedLocales.add(locale)\n __currentLocale.value = locale\n } finally {\n __loading.value = false\n }\n}\n\nasync function __preloadLocale(locale) {\n if (__cache.has(locale) || !__loaders[locale]) return\n try {\n const mod = __normalizeMessages(await __loaders[locale]())\n __cache.set(locale, mod)\n __loadedLocales.add(locale)\n } catch (e) { console.warn('[fluenti] preload failed:', locale, e) }\n}\n\nglobalThis[Symbol.for('${runtimeKey}')] = { __switchLocale, __preloadLocale }\n\nexport { __catalog, __switchLocale, __preloadLocale, __loadRoute, __registerRouteLoader, __currentLocale, __loading, __loadedLocales }\n`\n },\n}\n","import type { Plugin } from 'vite'\nimport type { FluentiPluginOptions } from '@fluenti/vite-plugin'\nimport { createFluentiPlugins } from '@fluenti/vite-plugin'\nimport { transformVtDirectives } from '@fluenti/vite-plugin/sfc-transform'\nimport { vueRuntimeGenerator } from './vue-runtime'\n\nexport type { FluentiPluginOptions as FluentiVueOptions } from '@fluenti/vite-plugin'\n\nexport default function fluentiVue(options?: FluentiPluginOptions): Plugin[] {\n const vueTemplatePlugin: Plugin = {\n name: 'fluenti:vue-template',\n enforce: 'pre',\n transform(code, id) {\n if (!id.endsWith('.vue')) return undefined\n if (!/\\bv-t\\b/.test(code) && !/<Trans[\\s>]/.test(code) && !/<Plural[\\s/>]/.test(code)) return undefined\n\n const transformed = transformVtDirectives(code)\n if (transformed === code) return undefined\n\n return { code: transformed, map: null }\n },\n }\n\n return createFluentiPlugins(\n { ...options, framework: 'vue' },\n [vueTemplatePlugin],\n vueRuntimeGenerator,\n )\n}\n"],"mappings":"6GAGA,IAAa,EAAwC,CACnD,gBAAgB,EAA0C,CACxD,GAAM,CAAE,aAAY,UAAS,eAAc,sBAAuB,EAC5D,EAAgB,GAAsB,EACtC,GAAA,EAAA,EAAA,SAA6B,QAAQ,KAAK,CAAE,EAAW,CAI7D,MAAO;;6BAEkB,EAAmB,GAAG,EAAc;;;+BAGlC,EAAc;oCACT,EAAc;;;;;;EAR1B,EAAQ,OAAQ,GAAW,IAAW,EAAc,CAc9D,IAAK,GAAM,MAAM,EAAE,mBAAmB,EAAmB,GAAG,EAAE,QAAQ,CAAC,KAAK;EAAK,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAoC9F,qBAAqB,EAA0C,CAC7D,GAAM,CAAE,aAAY,UAAS,eAAc,sBAAuB,EAC5D,EAAgB,GAAsB,EACtC,GAAA,EAAA,EAAA,SAA6B,QAAQ,KAAK,CAAE,EAAW,CAI7D,MAAO;;6BAEkB,EAAmB,GAAG,EAAc;;;+BAGlC,EAAc;oCACT,EAAc;;;;;;;EAR1B,EAAQ,OAAQ,GAAW,IAAW,EAAc,CAe9D,IAAK,GAAM,MAAM,EAAE,mBAAmB,EAAmB,GAAG,EAAE,QAAQ,CAAC,KAAK;EAAK,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAoD/F,CC3HD,SAAwB,EAAW,EAA0C,CAC3E,IAAM,EAA4B,CAChC,KAAM,uBACN,QAAS,MACT,UAAU,EAAM,EAAI,CAElB,GADI,CAAC,EAAG,SAAS,OAAO,EACpB,CAAC,UAAU,KAAK,EAAK,EAAI,CAAC,cAAc,KAAK,EAAK,EAAI,CAAC,gBAAgB,KAAK,EAAK,CAAE,OAEvF,IAAM,GAAA,EAAA,EAAA,uBAAoC,EAAK,CAC3C,OAAgB,EAEpB,MAAO,CAAE,KAAM,EAAa,IAAK,KAAM,EAE1C,CAED,OAAA,EAAA,EAAA,sBACE,CAAE,GAAG,EAAS,UAAW,MAAO,CAChC,CAAC,EAAkB,CACnB,EACD"}
1
+ {"version":3,"file":"vite-plugin.cjs","names":[],"sources":["../src/vue-runtime.ts","../src/vite-plugin.ts"],"sourcesContent":["import { createRuntimeGenerator } from '@fluenti/vite-plugin'\nimport type { RuntimeGenerator } from '@fluenti/vite-plugin'\n\nexport const vueRuntimeGenerator: RuntimeGenerator = createRuntimeGenerator({\n imports: `import { shallowReactive, ref } from 'vue'`,\n catalogInit: 'const __catalog = shallowReactive({ ...__defaultMsgs })',\n localeInit: (defaultLocale) => `const __currentLocale = ref('${defaultLocale}')`,\n loadingInit: 'const __loading = ref(false)',\n catalogUpdate: (msgs) => `Object.assign(__catalog, ${msgs})`,\n localeUpdate: (locale) => `__currentLocale.value = ${locale}`,\n loadingUpdate: (value) => `__loading.value = ${value}`,\n localeRead: '__currentLocale.value',\n runtimeKey: 'fluenti.runtime.vue.v1',\n})\n","import type { Plugin } from 'vite'\nimport type { FluentiPluginOptions } from '@fluenti/vite-plugin'\nimport { createFluentiPlugins } from '@fluenti/vite-plugin'\nimport { transformVtDirectives } from '@fluenti/vite-plugin/sfc-transform'\nimport { vueRuntimeGenerator } from './vue-runtime'\n\nexport type { FluentiPluginOptions as FluentiVueOptions } from '@fluenti/vite-plugin'\n\nexport default function fluentiVue(options?: FluentiPluginOptions): Plugin[] {\n const vueTemplatePlugin: Plugin = {\n name: 'fluenti:vue-template',\n enforce: 'pre',\n transform(code, id) {\n if (!id.endsWith('.vue')) return undefined\n if (!/\\bv-t\\b/.test(code) && !/<Trans[\\s>]/.test(code) && !/<Plural[\\s/>]/.test(code)) return undefined\n\n const transformed = transformVtDirectives(code)\n if (transformed === code) return undefined\n\n return { code: transformed, map: null }\n },\n }\n\n return createFluentiPlugins(\n { ...(options?.config !== undefined ? { config: options.config } : {}), framework: 'vue' },\n [vueTemplatePlugin],\n vueRuntimeGenerator,\n )\n}\n"],"mappings":"sFAGA,IAAa,GAAA,EAAA,EAAA,wBAA+D,CAC1E,QAAS,6CACT,YAAa,0DACb,WAAa,GAAkB,gCAAgC,EAAc,IAC7E,YAAa,+BACb,cAAgB,GAAS,4BAA4B,EAAK,GAC1D,aAAe,GAAW,2BAA2B,IACrD,cAAgB,GAAU,qBAAqB,IAC/C,WAAY,wBACZ,WAAY,yBACb,CAAC,CCLF,SAAwB,EAAW,EAA0C,CAC3E,IAAM,EAA4B,CAChC,KAAM,uBACN,QAAS,MACT,UAAU,EAAM,EAAI,CAElB,GADI,CAAC,EAAG,SAAS,OAAO,EACpB,CAAC,UAAU,KAAK,EAAK,EAAI,CAAC,cAAc,KAAK,EAAK,EAAI,CAAC,gBAAgB,KAAK,EAAK,CAAE,OAEvF,IAAM,GAAA,EAAA,EAAA,uBAAoC,EAAK,CAC3C,OAAgB,EAEpB,MAAO,CAAE,KAAM,EAAa,IAAK,KAAM,EAE1C,CAED,OAAA,EAAA,EAAA,sBACE,CAAE,GAAI,GAAS,SAAW,IAAA,GAAyC,EAAE,CAA/B,CAAE,OAAQ,EAAQ,OAAQ,CAAQ,UAAW,MAAO,CAC1F,CAAC,EAAkB,CACnB,EACD"}
@@ -1,134 +1,26 @@
1
- import { createFluentiPlugins as e } from "@fluenti/vite-plugin";
2
- import { transformVtDirectives as t } from "@fluenti/vite-plugin/sfc-transform";
3
- import { resolve as n } from "node:path";
1
+ import { createFluentiPlugins as e, createRuntimeGenerator as t } from "@fluenti/vite-plugin";
2
+ import { transformVtDirectives as n } from "@fluenti/vite-plugin/sfc-transform";
4
3
  //#region src/vue-runtime.ts
5
- var r = {
6
- generateRuntime(e) {
7
- let { catalogDir: t, locales: r, sourceLocale: i, defaultBuildLocale: a } = e, o = a || i, s = n(process.cwd(), t);
8
- return `
9
- import { shallowReactive, ref } from 'vue'
10
- import __defaultMsgs from '${s}/${o}.js'
11
-
12
- const __catalog = shallowReactive({ ...__defaultMsgs })
13
- const __currentLocale = ref('${o}')
14
- const __loadedLocales = new Set(['${o}'])
15
- const __loading = ref(false)
16
- const __cache = new Map()
17
- const __normalizeMessages = (mod) => mod.default ?? mod
18
-
19
- const __loaders = {
20
- ${r.filter((e) => e !== o).map((e) => ` '${e}': () => import('${s}/${e}.js'),`).join("\n")}
21
- }
22
-
23
- async function __switchLocale(locale) {
24
- if (__loadedLocales.has(locale)) {
25
- Object.assign(__catalog, __cache.get(locale) || __defaultMsgs)
26
- __currentLocale.value = locale
27
- return
28
- }
29
- __loading.value = true
30
- try {
31
- const mod = __normalizeMessages(await __loaders[locale]())
32
- __cache.set(locale, mod)
33
- __loadedLocales.add(locale)
34
- Object.assign(__catalog, mod)
35
- __currentLocale.value = locale
36
- } finally {
37
- __loading.value = false
38
- }
39
- }
40
-
41
- async function __preloadLocale(locale) {
42
- if (__loadedLocales.has(locale) || !__loaders[locale]) return
43
- try {
44
- const mod = __normalizeMessages(await __loaders[locale]())
45
- __cache.set(locale, mod)
46
- __loadedLocales.add(locale)
47
- } catch (e) { console.warn('[fluenti] preload failed:', locale, e) }
48
- }
49
-
50
- globalThis[Symbol.for('fluenti.runtime.vue')] = { __switchLocale, __preloadLocale }
51
-
52
- export { __catalog, __switchLocale, __preloadLocale, __currentLocale, __loading, __loadedLocales }
53
- `;
54
- },
55
- generateRouteRuntime(e) {
56
- let { catalogDir: t, locales: r, sourceLocale: i, defaultBuildLocale: a } = e, o = a || i, s = n(process.cwd(), t);
57
- return `
58
- import { shallowReactive, ref } from 'vue'
59
- import __defaultMsgs from '${s}/${o}.js'
60
-
61
- const __catalog = shallowReactive({ ...__defaultMsgs })
62
- const __currentLocale = ref('${o}')
63
- const __loadedLocales = new Set(['${o}'])
64
- const __loading = ref(false)
65
- const __cache = new Map()
66
- const __loadedRoutes = new Set()
67
- const __normalizeMessages = (mod) => mod.default ?? mod
68
-
69
- const __loaders = {
70
- ${r.filter((e) => e !== o).map((e) => ` '${e}': () => import('${s}/${e}.js'),`).join("\n")}
71
- }
72
-
73
- const __routeLoaders = {}
74
-
75
- function __registerRouteLoader(routeId, locale, loader) {
76
- const key = routeId + ':' + locale
77
- __routeLoaders[key] = loader
78
- }
79
-
80
- async function __loadRoute(routeId, locale) {
81
- const key = routeId + ':' + (locale || __currentLocale.value)
82
- if (__loadedRoutes.has(key)) return
83
- const loader = __routeLoaders[key]
84
- if (!loader) return
85
- const mod = __normalizeMessages(await loader())
86
- Object.assign(__catalog, mod)
87
- __loadedRoutes.add(key)
88
- }
89
-
90
- async function __switchLocale(locale) {
91
- if (locale === __currentLocale.value) return
92
- __loading.value = true
93
- try {
94
- if (__cache.has(locale)) {
95
- Object.assign(__catalog, __cache.get(locale))
96
- } else {
97
- const mod = __normalizeMessages(await __loaders[locale]())
98
- __cache.set(locale, mod)
99
- Object.assign(__catalog, mod)
100
- }
101
- __loadedLocales.add(locale)
102
- __currentLocale.value = locale
103
- } finally {
104
- __loading.value = false
105
- }
106
- }
107
-
108
- async function __preloadLocale(locale) {
109
- if (__cache.has(locale) || !__loaders[locale]) return
110
- try {
111
- const mod = __normalizeMessages(await __loaders[locale]())
112
- __cache.set(locale, mod)
113
- __loadedLocales.add(locale)
114
- } catch (e) { console.warn('[fluenti] preload failed:', locale, e) }
115
- }
116
-
117
- globalThis[Symbol.for('fluenti.runtime.vue')] = { __switchLocale, __preloadLocale }
118
-
119
- export { __catalog, __switchLocale, __preloadLocale, __loadRoute, __registerRouteLoader, __currentLocale, __loading, __loadedLocales }
120
- `;
121
- }
122
- };
4
+ var r = t({
5
+ imports: "import { shallowReactive, ref } from 'vue'",
6
+ catalogInit: "const __catalog = shallowReactive({ ...__defaultMsgs })",
7
+ localeInit: (e) => `const __currentLocale = ref('${e}')`,
8
+ loadingInit: "const __loading = ref(false)",
9
+ catalogUpdate: (e) => `Object.assign(__catalog, ${e})`,
10
+ localeUpdate: (e) => `__currentLocale.value = ${e}`,
11
+ loadingUpdate: (e) => `__loading.value = ${e}`,
12
+ localeRead: "__currentLocale.value",
13
+ runtimeKey: "fluenti.runtime.vue.v1"
14
+ });
123
15
  //#endregion
124
16
  //#region src/vite-plugin.ts
125
- function i(n) {
17
+ function i(t) {
126
18
  let i = {
127
19
  name: "fluenti:vue-template",
128
20
  enforce: "pre",
129
- transform(e, n) {
130
- if (!n.endsWith(".vue") || !/\bv-t\b/.test(e) && !/<Trans[\s>]/.test(e) && !/<Plural[\s/>]/.test(e)) return;
131
- let r = t(e);
21
+ transform(e, t) {
22
+ if (!t.endsWith(".vue") || !/\bv-t\b/.test(e) && !/<Trans[\s>]/.test(e) && !/<Plural[\s/>]/.test(e)) return;
23
+ let r = n(e);
132
24
  if (r !== e) return {
133
25
  code: r,
134
26
  map: null
@@ -136,7 +28,7 @@ function i(n) {
136
28
  }
137
29
  };
138
30
  return e({
139
- ...n,
31
+ ...t?.config === void 0 ? {} : { config: t.config },
140
32
  framework: "vue"
141
33
  }, [i], r);
142
34
  }
@@ -1 +1 @@
1
- {"version":3,"file":"vite-plugin.js","names":[],"sources":["../src/vue-runtime.ts","../src/vite-plugin.ts"],"sourcesContent":["import { resolve } from 'node:path'\nimport type { RuntimeGenerator, RuntimeGeneratorOptions } from '@fluenti/vite-plugin'\n\nexport const vueRuntimeGenerator: RuntimeGenerator = {\n generateRuntime(options: RuntimeGeneratorOptions): string {\n const { catalogDir, locales, sourceLocale, defaultBuildLocale } = options\n const defaultLocale = defaultBuildLocale || sourceLocale\n const absoluteCatalogDir = resolve(process.cwd(), catalogDir)\n const runtimeKey = 'fluenti.runtime.vue'\n const lazyLocales = locales.filter((locale) => locale !== defaultLocale)\n\n return `\nimport { shallowReactive, ref } from 'vue'\nimport __defaultMsgs from '${absoluteCatalogDir}/${defaultLocale}.js'\n\nconst __catalog = shallowReactive({ ...__defaultMsgs })\nconst __currentLocale = ref('${defaultLocale}')\nconst __loadedLocales = new Set(['${defaultLocale}'])\nconst __loading = ref(false)\nconst __cache = new Map()\nconst __normalizeMessages = (mod) => mod.default ?? mod\n\nconst __loaders = {\n${lazyLocales.map((l) => ` '${l}': () => import('${absoluteCatalogDir}/${l}.js'),`).join('\\n')}\n}\n\nasync function __switchLocale(locale) {\n if (__loadedLocales.has(locale)) {\n Object.assign(__catalog, __cache.get(locale) || __defaultMsgs)\n __currentLocale.value = locale\n return\n }\n __loading.value = true\n try {\n const mod = __normalizeMessages(await __loaders[locale]())\n __cache.set(locale, mod)\n __loadedLocales.add(locale)\n Object.assign(__catalog, mod)\n __currentLocale.value = locale\n } finally {\n __loading.value = false\n }\n}\n\nasync function __preloadLocale(locale) {\n if (__loadedLocales.has(locale) || !__loaders[locale]) return\n try {\n const mod = __normalizeMessages(await __loaders[locale]())\n __cache.set(locale, mod)\n __loadedLocales.add(locale)\n } catch (e) { console.warn('[fluenti] preload failed:', locale, e) }\n}\n\nglobalThis[Symbol.for('${runtimeKey}')] = { __switchLocale, __preloadLocale }\n\nexport { __catalog, __switchLocale, __preloadLocale, __currentLocale, __loading, __loadedLocales }\n`\n },\n\n generateRouteRuntime(options: RuntimeGeneratorOptions): string {\n const { catalogDir, locales, sourceLocale, defaultBuildLocale } = options\n const defaultLocale = defaultBuildLocale || sourceLocale\n const absoluteCatalogDir = resolve(process.cwd(), catalogDir)\n const runtimeKey = 'fluenti.runtime.vue'\n const lazyLocales = locales.filter((locale) => locale !== defaultLocale)\n\n return `\nimport { shallowReactive, ref } from 'vue'\nimport __defaultMsgs from '${absoluteCatalogDir}/${defaultLocale}.js'\n\nconst __catalog = shallowReactive({ ...__defaultMsgs })\nconst __currentLocale = ref('${defaultLocale}')\nconst __loadedLocales = new Set(['${defaultLocale}'])\nconst __loading = ref(false)\nconst __cache = new Map()\nconst __loadedRoutes = new Set()\nconst __normalizeMessages = (mod) => mod.default ?? mod\n\nconst __loaders = {\n${lazyLocales.map((l) => ` '${l}': () => import('${absoluteCatalogDir}/${l}.js'),`).join('\\n')}\n}\n\nconst __routeLoaders = {}\n\nfunction __registerRouteLoader(routeId, locale, loader) {\n const key = routeId + ':' + locale\n __routeLoaders[key] = loader\n}\n\nasync function __loadRoute(routeId, locale) {\n const key = routeId + ':' + (locale || __currentLocale.value)\n if (__loadedRoutes.has(key)) return\n const loader = __routeLoaders[key]\n if (!loader) return\n const mod = __normalizeMessages(await loader())\n Object.assign(__catalog, mod)\n __loadedRoutes.add(key)\n}\n\nasync function __switchLocale(locale) {\n if (locale === __currentLocale.value) return\n __loading.value = true\n try {\n if (__cache.has(locale)) {\n Object.assign(__catalog, __cache.get(locale))\n } else {\n const mod = __normalizeMessages(await __loaders[locale]())\n __cache.set(locale, mod)\n Object.assign(__catalog, mod)\n }\n __loadedLocales.add(locale)\n __currentLocale.value = locale\n } finally {\n __loading.value = false\n }\n}\n\nasync function __preloadLocale(locale) {\n if (__cache.has(locale) || !__loaders[locale]) return\n try {\n const mod = __normalizeMessages(await __loaders[locale]())\n __cache.set(locale, mod)\n __loadedLocales.add(locale)\n } catch (e) { console.warn('[fluenti] preload failed:', locale, e) }\n}\n\nglobalThis[Symbol.for('${runtimeKey}')] = { __switchLocale, __preloadLocale }\n\nexport { __catalog, __switchLocale, __preloadLocale, __loadRoute, __registerRouteLoader, __currentLocale, __loading, __loadedLocales }\n`\n },\n}\n","import type { Plugin } from 'vite'\nimport type { FluentiPluginOptions } from '@fluenti/vite-plugin'\nimport { createFluentiPlugins } from '@fluenti/vite-plugin'\nimport { transformVtDirectives } from '@fluenti/vite-plugin/sfc-transform'\nimport { vueRuntimeGenerator } from './vue-runtime'\n\nexport type { FluentiPluginOptions as FluentiVueOptions } from '@fluenti/vite-plugin'\n\nexport default function fluentiVue(options?: FluentiPluginOptions): Plugin[] {\n const vueTemplatePlugin: Plugin = {\n name: 'fluenti:vue-template',\n enforce: 'pre',\n transform(code, id) {\n if (!id.endsWith('.vue')) return undefined\n if (!/\\bv-t\\b/.test(code) && !/<Trans[\\s>]/.test(code) && !/<Plural[\\s/>]/.test(code)) return undefined\n\n const transformed = transformVtDirectives(code)\n if (transformed === code) return undefined\n\n return { code: transformed, map: null }\n },\n }\n\n return createFluentiPlugins(\n { ...options, framework: 'vue' },\n [vueTemplatePlugin],\n vueRuntimeGenerator,\n )\n}\n"],"mappings":";;;;AAGA,IAAa,IAAwC;CACnD,gBAAgB,GAA0C;EACxD,IAAM,EAAE,eAAY,YAAS,iBAAc,0BAAuB,GAC5D,IAAgB,KAAsB,GACtC,IAAqB,EAAQ,QAAQ,KAAK,EAAE,EAAW;AAI7D,SAAO;;6BAEkB,EAAmB,GAAG,EAAc;;;+BAGlC,EAAc;oCACT,EAAc;;;;;;EAR1B,EAAQ,QAAQ,MAAW,MAAW,EAAc,CAc9D,KAAK,MAAM,MAAM,EAAE,mBAAmB,EAAmB,GAAG,EAAE,QAAQ,CAAC,KAAK,KAAK,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAoC9F,qBAAqB,GAA0C;EAC7D,IAAM,EAAE,eAAY,YAAS,iBAAc,0BAAuB,GAC5D,IAAgB,KAAsB,GACtC,IAAqB,EAAQ,QAAQ,KAAK,EAAE,EAAW;AAI7D,SAAO;;6BAEkB,EAAmB,GAAG,EAAc;;;+BAGlC,EAAc;oCACT,EAAc;;;;;;;EAR1B,EAAQ,QAAQ,MAAW,MAAW,EAAc,CAe9D,KAAK,MAAM,MAAM,EAAE,mBAAmB,EAAmB,GAAG,EAAE,QAAQ,CAAC,KAAK,KAAK,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAoD/F;;;AC3HD,SAAwB,EAAW,GAA0C;CAC3E,IAAM,IAA4B;EAChC,MAAM;EACN,SAAS;EACT,UAAU,GAAM,GAAI;AAElB,OADI,CAAC,EAAG,SAAS,OAAO,IACpB,CAAC,UAAU,KAAK,EAAK,IAAI,CAAC,cAAc,KAAK,EAAK,IAAI,CAAC,gBAAgB,KAAK,EAAK,CAAE;GAEvF,IAAM,IAAc,EAAsB,EAAK;AAC3C,aAAgB,EAEpB,QAAO;IAAE,MAAM;IAAa,KAAK;IAAM;;EAE1C;AAED,QAAO,EACL;EAAE,GAAG;EAAS,WAAW;EAAO,EAChC,CAAC,EAAkB,EACnB,EACD"}
1
+ {"version":3,"file":"vite-plugin.js","names":[],"sources":["../src/vue-runtime.ts","../src/vite-plugin.ts"],"sourcesContent":["import { createRuntimeGenerator } from '@fluenti/vite-plugin'\nimport type { RuntimeGenerator } from '@fluenti/vite-plugin'\n\nexport const vueRuntimeGenerator: RuntimeGenerator = createRuntimeGenerator({\n imports: `import { shallowReactive, ref } from 'vue'`,\n catalogInit: 'const __catalog = shallowReactive({ ...__defaultMsgs })',\n localeInit: (defaultLocale) => `const __currentLocale = ref('${defaultLocale}')`,\n loadingInit: 'const __loading = ref(false)',\n catalogUpdate: (msgs) => `Object.assign(__catalog, ${msgs})`,\n localeUpdate: (locale) => `__currentLocale.value = ${locale}`,\n loadingUpdate: (value) => `__loading.value = ${value}`,\n localeRead: '__currentLocale.value',\n runtimeKey: 'fluenti.runtime.vue.v1',\n})\n","import type { Plugin } from 'vite'\nimport type { FluentiPluginOptions } from '@fluenti/vite-plugin'\nimport { createFluentiPlugins } from '@fluenti/vite-plugin'\nimport { transformVtDirectives } from '@fluenti/vite-plugin/sfc-transform'\nimport { vueRuntimeGenerator } from './vue-runtime'\n\nexport type { FluentiPluginOptions as FluentiVueOptions } from '@fluenti/vite-plugin'\n\nexport default function fluentiVue(options?: FluentiPluginOptions): Plugin[] {\n const vueTemplatePlugin: Plugin = {\n name: 'fluenti:vue-template',\n enforce: 'pre',\n transform(code, id) {\n if (!id.endsWith('.vue')) return undefined\n if (!/\\bv-t\\b/.test(code) && !/<Trans[\\s>]/.test(code) && !/<Plural[\\s/>]/.test(code)) return undefined\n\n const transformed = transformVtDirectives(code)\n if (transformed === code) return undefined\n\n return { code: transformed, map: null }\n },\n }\n\n return createFluentiPlugins(\n { ...(options?.config !== undefined ? { config: options.config } : {}), framework: 'vue' },\n [vueTemplatePlugin],\n vueRuntimeGenerator,\n )\n}\n"],"mappings":";;;AAGA,IAAa,IAAwC,EAAuB;CAC1E,SAAS;CACT,aAAa;CACb,aAAa,MAAkB,gCAAgC,EAAc;CAC7E,aAAa;CACb,gBAAgB,MAAS,4BAA4B,EAAK;CAC1D,eAAe,MAAW,2BAA2B;CACrD,gBAAgB,MAAU,qBAAqB;CAC/C,YAAY;CACZ,YAAY;CACb,CAAC;;;ACLF,SAAwB,EAAW,GAA0C;CAC3E,IAAM,IAA4B;EAChC,MAAM;EACN,SAAS;EACT,UAAU,GAAM,GAAI;AAElB,OADI,CAAC,EAAG,SAAS,OAAO,IACpB,CAAC,UAAU,KAAK,EAAK,IAAI,CAAC,cAAc,KAAK,EAAK,IAAI,CAAC,gBAAgB,KAAK,EAAK,CAAE;GAEvF,IAAM,IAAc,EAAsB,EAAK;AAC3C,aAAgB,EAEpB,QAAO;IAAE,MAAM;IAAa,KAAK;IAAM;;EAE1C;AAED,QAAO,EACL;EAAE,GAAI,GAAS,WAAW,KAAA,IAAyC,EAAE,GAA/B,EAAE,QAAQ,EAAQ,QAAQ;EAAQ,WAAW;EAAO,EAC1F,CAAC,EAAkB,EACnB,EACD"}
@@ -1 +1 @@
1
- {"version":3,"file":"vue-runtime.d.ts","sourceRoot":"","sources":["../src/vue-runtime.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,gBAAgB,EAA2B,MAAM,sBAAsB,CAAA;AAErF,eAAO,MAAM,mBAAmB,EAAE,gBAgIjC,CAAA"}
1
+ {"version":3,"file":"vue-runtime.d.ts","sourceRoot":"","sources":["../src/vue-runtime.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,sBAAsB,CAAA;AAE5D,eAAO,MAAM,mBAAmB,EAAE,gBAUhC,CAAA"}
package/llms-full.txt ADDED
@@ -0,0 +1,220 @@
1
+ # @fluenti/vue
2
+
3
+ > Vue 3 bindings for Fluenti — compile-time `t`, `v-t`, runtime-capable components, and a `useI18n()` composable.
4
+
5
+ @fluenti/vue is the Vue runtime layer for Fluenti. It combines:
6
+
7
+ - compile-time authoring via `import { t } from '@fluenti/vue'`
8
+ - template authoring via `v-t`
9
+ - runtime access via `useI18n()`
10
+ - runtime-capable components such as `<Trans>`, `<Plural>`, and `<Select>`
11
+
12
+ The recommended public path is:
13
+
14
+ - compile-time authoring: `t`
15
+ - runtime lookup / imperative APIs: `useI18n()`
16
+ - locale loading: `lazyLocaleLoading + chunkLoader`
17
+
18
+ ## Install
19
+
20
+ ```bash
21
+ pnpm add @fluenti/core @fluenti/vue @fluenti/vite-plugin
22
+ ```
23
+
24
+ ## Setup
25
+
26
+ ```ts
27
+ import { createApp } from 'vue'
28
+ import { createFluenti } from '@fluenti/vue'
29
+ import App from './App.vue'
30
+
31
+ const fluent = createFluenti({
32
+ locale: 'en',
33
+ fallbackLocale: 'en',
34
+ messages: { en, ja },
35
+ })
36
+
37
+ createApp(App).use(fluent).mount('#app')
38
+ ```
39
+
40
+ ## Public Exports
41
+
42
+ - `createFluenti`
43
+ - `useI18n`
44
+ - `t`
45
+ - `Trans`
46
+ - `Plural`
47
+ - `Select`
48
+ - `DateTime`
49
+ - `NumberFormat`
50
+ - `msg`
51
+ - `FLUENTI_KEY`
52
+
53
+ Types:
54
+
55
+ - `FluentiConfig`
56
+ - `FluentiPlugin`
57
+ - `FluentiContext`
58
+ - `FluentiTransProps`
59
+ - `FluentiPluralProps`
60
+ - `FluentiSelectProps`
61
+ - `FluentiDateTimeProps`
62
+ - `FluentiNumberFormatProps`
63
+
64
+ ## `createFluenti(options)`
65
+
66
+ Creates one Vue plugin instance with isolated state. This is SSR-safe and intended to be called once per app instance or once per request.
67
+
68
+ ### Options
69
+
70
+ ```ts
71
+ createFluenti({
72
+ locale: 'en',
73
+ messages: { en, ja },
74
+ fallbackLocale: 'en',
75
+ fallbackChain: { 'zh-TW': ['zh-CN', 'en'], '*': ['en'] },
76
+ dateFormats: {
77
+ short: { year: 'numeric', month: 'short', day: 'numeric' },
78
+ relative: 'relative',
79
+ },
80
+ numberFormats: {
81
+ currency: { style: 'currency', currency: 'USD' },
82
+ },
83
+ missing: (locale, id) => `[missing:${id}]`,
84
+ componentPrefix: 'I18n',
85
+ lazyLocaleLoading: true,
86
+ chunkLoader: (locale) => import(`./locales/compiled/${locale}.js`),
87
+ })
88
+ ```
89
+
90
+ Key behavior:
91
+
92
+ - `lazyLocaleLoading` controls async locale loading
93
+ - `chunkLoader` is only used when `lazyLocaleLoading` is enabled
94
+ - `componentPrefix` changes the globally registered component names
95
+ - fallback order follows Fluenti core semantics
96
+
97
+ ## `useI18n()`
98
+
99
+ Returns the full reactive Vue context.
100
+
101
+ ```vue
102
+ <script setup lang="ts">
103
+ import { t, useI18n } from '@fluenti/vue'
104
+
105
+ const name = 'Fluenti'
106
+ const headline = t`Hello ${name}`
107
+
108
+ const { setLocale, preloadLocale, isLoading } = useI18n()
109
+ </script>
110
+
111
+ <template>
112
+ <h1>{{ headline }}</h1>
113
+ <button @mouseenter="preloadLocale('ja')" @click="setLocale('ja')">
114
+ {{ isLoading ? 'Loading…' : '日本語' }}
115
+ </button>
116
+ </template>
117
+ ```
118
+
119
+ ### Context API
120
+
121
+ - `t(idOrDescriptor, values?)`
122
+ - tagged-template `t\`\``
123
+ - `d(value, style?)`
124
+ - `n(value, style?)`
125
+ - `format(message, values?)`
126
+ - `te(key, locale?)`
127
+ - `tm(key, locale?)`
128
+ - `locale: Readonly<Ref<string>>`
129
+ - `setLocale(locale): Promise<void>`
130
+ - `loadMessages(locale, messages): void`
131
+ - `getLocales(): string[]`
132
+ - `preloadLocale(locale): void`
133
+ - `isLoading: Readonly<Ref<boolean>>`
134
+ - `loadedLocales: Readonly<Ref<ReadonlySet<string>>>`
135
+
136
+ `useI18n().t()` is the full runtime API. It supports string ID lookup, descriptors, and tagged templates.
137
+
138
+ ## Compile-time `t`
139
+
140
+ `import { t } from '@fluenti/vue'` is a compile-time authoring API.
141
+
142
+ Supported forms:
143
+
144
+ ```ts
145
+ t`Hello ${name}` // ✅ Preferred
146
+ t({ message: 'Hello {name}', context: 'home.hero' }, { name }) // ✅ Preferred
147
+ ```
148
+
149
+ Not supported as the main direct-import surface:
150
+
151
+ ```ts
152
+ t('message.id') // ⚠️ Not supported as direct import — use useI18n().t() for runtime lookup
153
+ t('Hello {name}', { name }) // ⚠️ Not supported as direct import
154
+ ```
155
+
156
+ If the build plugin is missing and the imported `t` function executes at runtime, it throws a clear error.
157
+
158
+ ## `v-t`
159
+
160
+ `v-t` is primarily a compile-time feature handled by `@fluenti/vite-plugin`.
161
+
162
+ Supported authoring shapes include:
163
+
164
+ - plain text translation
165
+ - translated attributes such as `.alt`, `.placeholder`, `.title`
166
+ - `v-t.plural`
167
+
168
+ The runtime component layer still works without compile-time optimization, but the plugin path is the recommended authoring experience.
169
+
170
+ ## Runtime-capable components
171
+
172
+ These components continue to work even without the build plugin:
173
+
174
+ - `<Trans>`
175
+ - `<Plural>`
176
+ - `<Select>`
177
+ - `<DateTime>`
178
+ - `<NumberFormat>`
179
+
180
+ Cross-framework contract highlights:
181
+
182
+ - `Plural` supports `id`, `context`, `comment`, and `offset`
183
+ - `zero` maps to exact `=0`
184
+ - `#` uses the adjusted value
185
+ - `Select` supports `options` plus direct case props, with `options` taking precedence
186
+
187
+ ## Async locale loading
188
+
189
+ ```ts
190
+ const fluent = createFluenti({
191
+ locale: 'en',
192
+ messages: { en },
193
+ lazyLocaleLoading: true,
194
+ chunkLoader: (locale) => import(`./locales/compiled/${locale}.js`),
195
+ })
196
+ ```
197
+
198
+ Behavior:
199
+
200
+ - the default locale can be bundled eagerly
201
+ - other locales load on demand through `chunkLoader`
202
+ - `setLocale()` becomes async when loading is required
203
+ - `preloadLocale()` fetches a locale without switching
204
+
205
+ ## Server Subpath: `@fluenti/vue/server`
206
+
207
+ Server-side utilities for SSR:
208
+
209
+ - `createServerI18n(config)` — creates request-scoped runtime helpers for server rendering
210
+ - Re-exports from `@fluenti/core`: `detectLocale`, `getSSRLocaleScript`, `getHydratedLocale`, `isRTL`, `getDirection`
211
+
212
+ ## Build plugin relationship
213
+
214
+ `@fluenti/vue` is the runtime layer. `@fluenti/vite-plugin` provides compile-time transforms for:
215
+
216
+ - direct-import `t`
217
+ - `v-t`
218
+ - template component optimization
219
+
220
+ The components themselves remain runtime-capable, so correctness does not depend on the plugin.