@fluenti/react 0.2.1 → 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.
- package/dist/components/DateTime.d.ts +2 -2
- package/dist/components/DateTime.d.ts.map +1 -1
- package/dist/components/Number.d.ts +2 -2
- package/dist/components/Number.d.ts.map +1 -1
- package/dist/components/Plural.d.ts +2 -2
- package/dist/components/Plural.d.ts.map +1 -1
- package/dist/components/Select.d.ts +5 -3
- package/dist/components/Select.d.ts.map +1 -1
- package/dist/components/Trans.d.ts +4 -2
- package/dist/components/Trans.d.ts.map +1 -1
- package/dist/components/icu-rich.d.ts +2 -9
- package/dist/components/icu-rich.d.ts.map +1 -1
- package/dist/components/plural-core.d.ts +2 -2
- package/dist/components/plural-core.d.ts.map +1 -1
- package/dist/components/trans-core.d.ts +1 -2
- package/dist/components/trans-core.d.ts.map +1 -1
- package/dist/context.d.ts +2 -2
- package/dist/context.d.ts.map +1 -1
- package/dist/create-fluenti.d.ts +87 -0
- package/dist/create-fluenti.d.ts.map +1 -0
- package/dist/global-registry.d.ts +4 -4
- package/dist/global-registry.d.ts.map +1 -1
- package/dist/hooks/__useI18n.d.ts +2 -2
- package/dist/hooks/__useI18n.d.ts.map +1 -1
- package/dist/hooks/useI18n.d.ts +2 -2
- package/dist/hooks/useI18n.d.ts.map +1 -1
- package/dist/icu-rich-BOtj4Oxu.js +71 -0
- package/dist/icu-rich-BOtj4Oxu.js.map +1 -0
- package/dist/icu-rich-vPU-0wGQ.cjs +2 -0
- package/dist/icu-rich-vPU-0wGQ.cjs.map +1 -0
- package/dist/index.cjs +1 -1
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.ts +8 -6
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +252 -107
- package/dist/index.js.map +1 -1
- package/dist/provider.d.ts +2 -2
- package/dist/provider.d.ts.map +1 -1
- package/dist/react-runtime.d.ts.map +1 -1
- package/dist/server.cjs +1 -1
- package/dist/server.cjs.map +1 -1
- package/dist/server.d.ts +13 -3
- package/dist/server.d.ts.map +1 -1
- package/dist/server.js +24 -13
- package/dist/server.js.map +1 -1
- package/dist/types.d.ts +17 -10
- package/dist/types.d.ts.map +1 -1
- package/dist/vite-plugin.cjs +1 -109
- package/dist/vite-plugin.cjs.map +1 -1
- package/dist/vite-plugin.js +13 -119
- package/dist/vite-plugin.js.map +1 -1
- package/llms-full.txt +185 -0
- package/llms-migration.txt +272 -0
- package/llms.txt +62 -0
- package/package.json +7 -5
- package/dist/icu-rich-DBeWY1k6.js +0 -108
- package/dist/icu-rich-DBeWY1k6.js.map +0 -1
- package/dist/icu-rich-XY1SdM5K.cjs +0 -2
- package/dist/icu-rich-XY1SdM5K.cjs.map +0 -1
package/dist/types.d.ts
CHANGED
|
@@ -1,19 +1,17 @@
|
|
|
1
1
|
import { ReactNode } from 'react';
|
|
2
|
-
import { Locale, Messages, AllMessages, MessageDescriptor, CompileTimeMessageDescriptor, CompileTimeT, DateFormatOptions, NumberFormatOptions,
|
|
3
|
-
export interface
|
|
4
|
-
/** The underlying Fluent instance (escape hatch for advanced use) */
|
|
5
|
-
i18n: FluentInstanceExtended;
|
|
2
|
+
import { Locale, LocalizedString, Messages, AllMessages, CompiledMessage, MessageDescriptor, CompileTimeMessageDescriptor, CompileTimeT, DateFormatOptions, NumberFormatOptions, DiagnosticsConfig } from '@fluenti/core';
|
|
3
|
+
export interface FluentiContext {
|
|
6
4
|
/** Translate a message by id with optional interpolation values */
|
|
7
5
|
t: {
|
|
8
|
-
(id: string | MessageDescriptor, values?: Record<string, unknown>):
|
|
9
|
-
(strings: TemplateStringsArray, ...exprs: unknown[]):
|
|
6
|
+
(id: string | MessageDescriptor, values?: Record<string, unknown>): LocalizedString;
|
|
7
|
+
(strings: TemplateStringsArray, ...exprs: unknown[]): LocalizedString;
|
|
10
8
|
};
|
|
11
9
|
/** Format a date value for the current locale */
|
|
12
|
-
d: (value: Date | number, style?: string) =>
|
|
10
|
+
d: (value: Date | number, style?: string) => LocalizedString;
|
|
13
11
|
/** Format a number value for the current locale */
|
|
14
|
-
n: (value: number, style?: string) =>
|
|
12
|
+
n: (value: number, style?: string) => LocalizedString;
|
|
15
13
|
/** Format an ICU message string directly (no catalog lookup) */
|
|
16
|
-
format: (message: string, values?: Record<string, unknown>) =>
|
|
14
|
+
format: (message: string, values?: Record<string, unknown>) => LocalizedString;
|
|
17
15
|
/** Merge additional messages into a locale catalog at runtime */
|
|
18
16
|
loadMessages: (locale: string, messages: Messages) => void;
|
|
19
17
|
/** Return all locale codes that have loaded messages */
|
|
@@ -28,6 +26,10 @@ export interface I18nContextValue {
|
|
|
28
26
|
loadedLocales: string[];
|
|
29
27
|
/** Preload a locale in the background without switching to it */
|
|
30
28
|
preloadLocale: (locale: string) => Promise<void>;
|
|
29
|
+
/** Check if a translation key exists for the given or current locale */
|
|
30
|
+
te: (key: string, locale?: string) => boolean;
|
|
31
|
+
/** Get the raw compiled message for a key without interpolation */
|
|
32
|
+
tm: (key: string, locale?: string) => CompiledMessage | undefined;
|
|
31
33
|
}
|
|
32
34
|
export interface I18nProviderProps {
|
|
33
35
|
/** Active locale code */
|
|
@@ -48,8 +50,13 @@ export interface I18nProviderProps {
|
|
|
48
50
|
numberFormats?: NumberFormatOptions;
|
|
49
51
|
/** Missing message handler */
|
|
50
52
|
missing?: (locale: Locale, id: string) => string | undefined;
|
|
53
|
+
/** Runtime diagnostics configuration */
|
|
54
|
+
diagnostics?: DiagnosticsConfig;
|
|
51
55
|
/** App content */
|
|
52
56
|
children: ReactNode;
|
|
57
|
+
/** Pre-created FluentiInstance (alternative to inline config) */
|
|
58
|
+
instance?: import('./create-fluenti').FluentiInstance;
|
|
53
59
|
}
|
|
54
|
-
export type
|
|
60
|
+
export type FluentiProviderProps = I18nProviderProps;
|
|
61
|
+
export type { Locale, LocalizedString, Messages, AllMessages, MessageDescriptor, CompileTimeMessageDescriptor, CompileTimeT, DateFormatOptions, NumberFormatOptions, };
|
|
55
62
|
//# sourceMappingURL=types.d.ts.map
|
package/dist/types.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAA;AACtC,OAAO,KAAK,EACV,MAAM,EACN,QAAQ,EACR,WAAW,EACX,iBAAiB,EACjB,4BAA4B,EAC5B,YAAY,EACZ,iBAAiB,EACjB,mBAAmB,EACnB,
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAA;AACtC,OAAO,KAAK,EACV,MAAM,EACN,eAAe,EACf,QAAQ,EACR,WAAW,EACX,eAAe,EACf,iBAAiB,EACjB,4BAA4B,EAC5B,YAAY,EACZ,iBAAiB,EACjB,mBAAmB,EACnB,iBAAiB,EAClB,MAAM,eAAe,CAAA;AAEtB,MAAM,WAAW,cAAc;IAC7B,mEAAmE;IACnE,CAAC,EAAE;QACD,CAAC,EAAE,EAAE,MAAM,GAAG,iBAAiB,EAAE,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,eAAe,CAAA;QACnF,CAAC,OAAO,EAAE,oBAAoB,EAAE,GAAG,KAAK,EAAE,OAAO,EAAE,GAAG,eAAe,CAAA;KACtE,CAAA;IACD,iDAAiD;IACjD,CAAC,EAAE,CAAC,KAAK,EAAE,IAAI,GAAG,MAAM,EAAE,KAAK,CAAC,EAAE,MAAM,KAAK,eAAe,CAAA;IAC5D,mDAAmD;IACnD,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,MAAM,KAAK,eAAe,CAAA;IACrD,gEAAgE;IAChE,MAAM,EAAE,CAAC,OAAO,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,KAAK,eAAe,CAAA;IAC9E,iEAAiE;IACjE,YAAY,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,QAAQ,EAAE,QAAQ,KAAK,IAAI,CAAA;IAC1D,wDAAwD;IACxD,UAAU,EAAE,MAAM,MAAM,EAAE,CAAA;IAC1B,qBAAqB;IACrB,MAAM,EAAE,MAAM,CAAA;IACd,yDAAyD;IACzD,SAAS,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAA;IAC5C,iDAAiD;IACjD,SAAS,EAAE,OAAO,CAAA;IAClB,qDAAqD;IACrD,aAAa,EAAE,MAAM,EAAE,CAAA;IACvB,iEAAiE;IACjE,aAAa,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAA;IAChD,wEAAwE;IACxE,EAAE,EAAE,CAAC,GAAG,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,MAAM,KAAK,OAAO,CAAA;IAC7C,mEAAmE;IACnE,EAAE,EAAE,CAAC,GAAG,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,MAAM,KAAK,eAAe,GAAG,SAAS,CAAA;CAClE;AAED,MAAM,WAAW,iBAAiB;IAChC,yBAAyB;IACzB,MAAM,EAAE,MAAM,CAAA;IACd,kDAAkD;IAClD,cAAc,CAAC,EAAE,MAAM,CAAA;IACvB,8BAA8B;IAC9B,QAAQ,CAAC,EAAE,WAAW,CAAA;IACtB,oCAAoC;IACpC,YAAY,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,OAAO,CAAC,QAAQ,GAAG;QAAE,OAAO,EAAE,QAAQ,CAAA;KAAE,CAAC,CAAA;IAC5E,wCAAwC;IACxC,aAAa,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,EAAE,CAAC,CAAA;IACxC,yBAAyB;IACzB,WAAW,CAAC,EAAE,iBAAiB,CAAA;IAC/B,2BAA2B;IAC3B,aAAa,CAAC,EAAE,mBAAmB,CAAA;IACnC,8BAA8B;IAC9B,OAAO,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,KAAK,MAAM,GAAG,SAAS,CAAA;IAC5D,wCAAwC;IACxC,WAAW,CAAC,EAAE,iBAAiB,CAAA;IAC/B,kBAAkB;IAClB,QAAQ,EAAE,SAAS,CAAA;IACnB,iEAAiE;IACjE,QAAQ,CAAC,EAAE,OAAO,kBAAkB,EAAE,eAAe,CAAA;CACtD;AAED,MAAM,MAAM,oBAAoB,GAAG,iBAAiB,CAAA;AAEpD,YAAY,EACV,MAAM,EACN,eAAe,EACf,QAAQ,EACR,WAAW,EACX,iBAAiB,EACjB,4BAA4B,EAC5B,YAAY,EACZ,iBAAiB,EACjB,mBAAmB,GACpB,CAAA"}
|
package/dist/vite-plugin.cjs
CHANGED
|
@@ -1,110 +1,2 @@
|
|
|
1
|
-
let e=require(`@fluenti/vite-plugin`)
|
|
2
|
-
import __defaultMsgs from '${s}/${o}.js'
|
|
3
|
-
|
|
4
|
-
const __catalog = { ...__defaultMsgs }
|
|
5
|
-
let __currentLocale = '${o}'
|
|
6
|
-
const __loadedLocales = new Set(['${o}'])
|
|
7
|
-
let __loading = false
|
|
8
|
-
const __cache = new Map()
|
|
9
|
-
const __normalizeMessages = (mod) => mod.default ?? mod
|
|
10
|
-
|
|
11
|
-
const __loaders = {
|
|
12
|
-
${r.filter(e=>e!==o).map(e=>` '${e}': () => import('${s}/${e}.js'),`).join(`
|
|
13
|
-
`)}
|
|
14
|
-
}
|
|
15
|
-
|
|
16
|
-
async function __switchLocale(locale) {
|
|
17
|
-
if (__loadedLocales.has(locale)) {
|
|
18
|
-
Object.assign(__catalog, __cache.get(locale) || __defaultMsgs)
|
|
19
|
-
__currentLocale = locale
|
|
20
|
-
return
|
|
21
|
-
}
|
|
22
|
-
__loading = true
|
|
23
|
-
try {
|
|
24
|
-
const mod = __normalizeMessages(await __loaders[locale]())
|
|
25
|
-
__cache.set(locale, mod)
|
|
26
|
-
__loadedLocales.add(locale)
|
|
27
|
-
Object.assign(__catalog, mod)
|
|
28
|
-
__currentLocale = locale
|
|
29
|
-
} finally {
|
|
30
|
-
__loading = false
|
|
31
|
-
}
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
async function __preloadLocale(locale) {
|
|
35
|
-
if (__loadedLocales.has(locale) || !__loaders[locale]) return
|
|
36
|
-
try {
|
|
37
|
-
const mod = __normalizeMessages(await __loaders[locale]())
|
|
38
|
-
__cache.set(locale, mod)
|
|
39
|
-
__loadedLocales.add(locale)
|
|
40
|
-
} catch (e) { console.warn('[fluenti] preload failed:', locale, e) }
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
globalThis[Symbol.for('fluenti.runtime.react')] = { __switchLocale, __preloadLocale }
|
|
44
|
-
|
|
45
|
-
export { __catalog, __switchLocale, __preloadLocale, __currentLocale, __loading, __loadedLocales }
|
|
46
|
-
`},generateRouteRuntime(e){let{catalogDir:n,locales:r,sourceLocale:i,defaultBuildLocale:a}=e,o=a||i,s=(0,t.resolve)(process.cwd(),n);return`
|
|
47
|
-
import __defaultMsgs from '${s}/${o}.js'
|
|
48
|
-
|
|
49
|
-
const __catalog = { ...__defaultMsgs }
|
|
50
|
-
let __currentLocale = '${o}'
|
|
51
|
-
const __loadedLocales = new Set(['${o}'])
|
|
52
|
-
let __loading = false
|
|
53
|
-
const __cache = new Map()
|
|
54
|
-
const __loadedRoutes = new Set()
|
|
55
|
-
const __normalizeMessages = (mod) => mod.default ?? mod
|
|
56
|
-
|
|
57
|
-
const __loaders = {
|
|
58
|
-
${r.filter(e=>e!==o).map(e=>` '${e}': () => import('${s}/${e}.js'),`).join(`
|
|
59
|
-
`)}
|
|
60
|
-
}
|
|
61
|
-
|
|
62
|
-
const __routeLoaders = {}
|
|
63
|
-
|
|
64
|
-
function __registerRouteLoader(routeId, locale, loader) {
|
|
65
|
-
const key = routeId + ':' + locale
|
|
66
|
-
__routeLoaders[key] = loader
|
|
67
|
-
}
|
|
68
|
-
|
|
69
|
-
async function __loadRoute(routeId, locale) {
|
|
70
|
-
const key = routeId + ':' + (locale || __currentLocale)
|
|
71
|
-
if (__loadedRoutes.has(key)) return
|
|
72
|
-
const loader = __routeLoaders[key]
|
|
73
|
-
if (!loader) return
|
|
74
|
-
const mod = __normalizeMessages(await loader())
|
|
75
|
-
Object.assign(__catalog, mod)
|
|
76
|
-
__loadedRoutes.add(key)
|
|
77
|
-
}
|
|
78
|
-
|
|
79
|
-
async function __switchLocale(locale) {
|
|
80
|
-
if (locale === __currentLocale) return
|
|
81
|
-
__loading = true
|
|
82
|
-
try {
|
|
83
|
-
if (__cache.has(locale)) {
|
|
84
|
-
Object.assign(__catalog, __cache.get(locale))
|
|
85
|
-
} else {
|
|
86
|
-
const mod = __normalizeMessages(await __loaders[locale]())
|
|
87
|
-
__cache.set(locale, mod)
|
|
88
|
-
Object.assign(__catalog, mod)
|
|
89
|
-
}
|
|
90
|
-
__loadedLocales.add(locale)
|
|
91
|
-
__currentLocale = locale
|
|
92
|
-
} finally {
|
|
93
|
-
__loading = false
|
|
94
|
-
}
|
|
95
|
-
}
|
|
96
|
-
|
|
97
|
-
async function __preloadLocale(locale) {
|
|
98
|
-
if (__cache.has(locale) || !__loaders[locale]) return
|
|
99
|
-
try {
|
|
100
|
-
const mod = __normalizeMessages(await __loaders[locale]())
|
|
101
|
-
__cache.set(locale, mod)
|
|
102
|
-
__loadedLocales.add(locale)
|
|
103
|
-
} catch (e) { console.warn('[fluenti] preload failed:', locale, e) }
|
|
104
|
-
}
|
|
105
|
-
|
|
106
|
-
globalThis[Symbol.for('fluenti.runtime.react')] = { __switchLocale, __preloadLocale }
|
|
107
|
-
|
|
108
|
-
export { __catalog, __switchLocale, __preloadLocale, __loadRoute, __registerRouteLoader, __currentLocale, __loading, __loadedLocales }
|
|
109
|
-
`}};function r(t){return(0,e.createFluentiPlugins)({...t,framework:`react`},[],n)}module.exports=r;
|
|
1
|
+
let e=require(`@fluenti/vite-plugin`);var t=(0,e.createRuntimeGenerator)({imports:``,catalogInit:`const __catalog = { ...__defaultMsgs }`,localeInit:e=>`let __currentLocale = '${e}'`,loadingInit:`let __loading = false`,catalogUpdate:e=>`Object.assign(__catalog, ${e})`,localeUpdate:e=>`__currentLocale = ${e}`,loadingUpdate:e=>`__loading = ${e}`,localeRead:`__currentLocale`,runtimeKey:`fluenti.runtime.react.v1`});function n(n){return(0,e.createFluentiPlugins)({...n?.config===void 0?{}:{config:n.config},framework:`react`},[],t)}module.exports=n;
|
|
110
2
|
//# sourceMappingURL=vite-plugin.cjs.map
|
package/dist/vite-plugin.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"vite-plugin.cjs","names":[],"sources":["../src/react-runtime.ts","../src/vite-plugin.ts"],"sourcesContent":["import {
|
|
1
|
+
{"version":3,"file":"vite-plugin.cjs","names":[],"sources":["../src/react-runtime.ts","../src/vite-plugin.ts"],"sourcesContent":["import { createRuntimeGenerator } from '@fluenti/vite-plugin'\nimport type { RuntimeGenerator } from '@fluenti/vite-plugin'\n\nexport const reactRuntimeGenerator: RuntimeGenerator = createRuntimeGenerator({\n imports: '',\n catalogInit: 'const __catalog = { ...__defaultMsgs }',\n localeInit: (defaultLocale) => `let __currentLocale = '${defaultLocale}'`,\n loadingInit: 'let __loading = false',\n catalogUpdate: (msgs) => `Object.assign(__catalog, ${msgs})`,\n localeUpdate: (locale) => `__currentLocale = ${locale}`,\n loadingUpdate: (value) => `__loading = ${value}`,\n localeRead: '__currentLocale',\n runtimeKey: 'fluenti.runtime.react.v1',\n})\n","import type { Plugin } from 'vite'\nimport type { FluentiPluginOptions } from '@fluenti/vite-plugin'\nimport { createFluentiPlugins } from '@fluenti/vite-plugin'\nimport { reactRuntimeGenerator } from './react-runtime'\n\nexport type { FluentiPluginOptions as FluentiReactOptions } from '@fluenti/vite-plugin'\n\nexport default function fluentiReact(options?: FluentiPluginOptions): Plugin[] {\n return createFluentiPlugins(\n { ...(options?.config !== undefined ? { config: options.config } : {}), framework: 'react' },\n [],\n reactRuntimeGenerator,\n )\n}\n"],"mappings":"sCAGA,IAAa,GAAA,EAAA,EAAA,wBAAiE,CAC5E,QAAS,GACT,YAAa,yCACb,WAAa,GAAkB,0BAA0B,EAAc,GACvE,YAAa,wBACb,cAAgB,GAAS,4BAA4B,EAAK,GAC1D,aAAe,GAAW,qBAAqB,IAC/C,cAAgB,GAAU,eAAe,IACzC,WAAY,kBACZ,WAAY,2BACb,CAAC,CCNF,SAAwB,EAAa,EAA0C,CAC7E,OAAA,EAAA,EAAA,sBACE,CAAE,GAAI,GAAS,SAAW,IAAA,GAAyC,EAAE,CAA/B,CAAE,OAAQ,EAAQ,OAAQ,CAAQ,UAAW,QAAS,CAC5F,EAAE,CACF,EACD"}
|
package/dist/vite-plugin.js
CHANGED
|
@@ -1,127 +1,21 @@
|
|
|
1
|
-
import { createFluentiPlugins as e } from "@fluenti/vite-plugin";
|
|
2
|
-
import { resolve as t } from "node:path";
|
|
1
|
+
import { createFluentiPlugins as e, createRuntimeGenerator as t } from "@fluenti/vite-plugin";
|
|
3
2
|
//#region src/react-runtime.ts
|
|
4
|
-
var n = {
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
const __normalizeMessages = (mod) => mod.default ?? mod
|
|
16
|
-
|
|
17
|
-
const __loaders = {
|
|
18
|
-
${r.filter((e) => e !== o).map((e) => ` '${e}': () => import('${s}/${e}.js'),`).join("\n")}
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
async function __switchLocale(locale) {
|
|
22
|
-
if (__loadedLocales.has(locale)) {
|
|
23
|
-
Object.assign(__catalog, __cache.get(locale) || __defaultMsgs)
|
|
24
|
-
__currentLocale = locale
|
|
25
|
-
return
|
|
26
|
-
}
|
|
27
|
-
__loading = true
|
|
28
|
-
try {
|
|
29
|
-
const mod = __normalizeMessages(await __loaders[locale]())
|
|
30
|
-
__cache.set(locale, mod)
|
|
31
|
-
__loadedLocales.add(locale)
|
|
32
|
-
Object.assign(__catalog, mod)
|
|
33
|
-
__currentLocale = locale
|
|
34
|
-
} finally {
|
|
35
|
-
__loading = false
|
|
36
|
-
}
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
async function __preloadLocale(locale) {
|
|
40
|
-
if (__loadedLocales.has(locale) || !__loaders[locale]) return
|
|
41
|
-
try {
|
|
42
|
-
const mod = __normalizeMessages(await __loaders[locale]())
|
|
43
|
-
__cache.set(locale, mod)
|
|
44
|
-
__loadedLocales.add(locale)
|
|
45
|
-
} catch (e) { console.warn('[fluenti] preload failed:', locale, e) }
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
globalThis[Symbol.for('fluenti.runtime.react')] = { __switchLocale, __preloadLocale }
|
|
49
|
-
|
|
50
|
-
export { __catalog, __switchLocale, __preloadLocale, __currentLocale, __loading, __loadedLocales }
|
|
51
|
-
`;
|
|
52
|
-
},
|
|
53
|
-
generateRouteRuntime(e) {
|
|
54
|
-
let { catalogDir: n, locales: r, sourceLocale: i, defaultBuildLocale: a } = e, o = a || i, s = t(process.cwd(), n);
|
|
55
|
-
return `
|
|
56
|
-
import __defaultMsgs from '${s}/${o}.js'
|
|
57
|
-
|
|
58
|
-
const __catalog = { ...__defaultMsgs }
|
|
59
|
-
let __currentLocale = '${o}'
|
|
60
|
-
const __loadedLocales = new Set(['${o}'])
|
|
61
|
-
let __loading = false
|
|
62
|
-
const __cache = new Map()
|
|
63
|
-
const __loadedRoutes = new Set()
|
|
64
|
-
const __normalizeMessages = (mod) => mod.default ?? mod
|
|
65
|
-
|
|
66
|
-
const __loaders = {
|
|
67
|
-
${r.filter((e) => e !== o).map((e) => ` '${e}': () => import('${s}/${e}.js'),`).join("\n")}
|
|
68
|
-
}
|
|
69
|
-
|
|
70
|
-
const __routeLoaders = {}
|
|
71
|
-
|
|
72
|
-
function __registerRouteLoader(routeId, locale, loader) {
|
|
73
|
-
const key = routeId + ':' + locale
|
|
74
|
-
__routeLoaders[key] = loader
|
|
75
|
-
}
|
|
76
|
-
|
|
77
|
-
async function __loadRoute(routeId, locale) {
|
|
78
|
-
const key = routeId + ':' + (locale || __currentLocale)
|
|
79
|
-
if (__loadedRoutes.has(key)) return
|
|
80
|
-
const loader = __routeLoaders[key]
|
|
81
|
-
if (!loader) return
|
|
82
|
-
const mod = __normalizeMessages(await loader())
|
|
83
|
-
Object.assign(__catalog, mod)
|
|
84
|
-
__loadedRoutes.add(key)
|
|
85
|
-
}
|
|
86
|
-
|
|
87
|
-
async function __switchLocale(locale) {
|
|
88
|
-
if (locale === __currentLocale) return
|
|
89
|
-
__loading = true
|
|
90
|
-
try {
|
|
91
|
-
if (__cache.has(locale)) {
|
|
92
|
-
Object.assign(__catalog, __cache.get(locale))
|
|
93
|
-
} else {
|
|
94
|
-
const mod = __normalizeMessages(await __loaders[locale]())
|
|
95
|
-
__cache.set(locale, mod)
|
|
96
|
-
Object.assign(__catalog, mod)
|
|
97
|
-
}
|
|
98
|
-
__loadedLocales.add(locale)
|
|
99
|
-
__currentLocale = locale
|
|
100
|
-
} finally {
|
|
101
|
-
__loading = false
|
|
102
|
-
}
|
|
103
|
-
}
|
|
104
|
-
|
|
105
|
-
async function __preloadLocale(locale) {
|
|
106
|
-
if (__cache.has(locale) || !__loaders[locale]) return
|
|
107
|
-
try {
|
|
108
|
-
const mod = __normalizeMessages(await __loaders[locale]())
|
|
109
|
-
__cache.set(locale, mod)
|
|
110
|
-
__loadedLocales.add(locale)
|
|
111
|
-
} catch (e) { console.warn('[fluenti] preload failed:', locale, e) }
|
|
112
|
-
}
|
|
113
|
-
|
|
114
|
-
globalThis[Symbol.for('fluenti.runtime.react')] = { __switchLocale, __preloadLocale }
|
|
115
|
-
|
|
116
|
-
export { __catalog, __switchLocale, __preloadLocale, __loadRoute, __registerRouteLoader, __currentLocale, __loading, __loadedLocales }
|
|
117
|
-
`;
|
|
118
|
-
}
|
|
119
|
-
};
|
|
3
|
+
var n = t({
|
|
4
|
+
imports: "",
|
|
5
|
+
catalogInit: "const __catalog = { ...__defaultMsgs }",
|
|
6
|
+
localeInit: (e) => `let __currentLocale = '${e}'`,
|
|
7
|
+
loadingInit: "let __loading = false",
|
|
8
|
+
catalogUpdate: (e) => `Object.assign(__catalog, ${e})`,
|
|
9
|
+
localeUpdate: (e) => `__currentLocale = ${e}`,
|
|
10
|
+
loadingUpdate: (e) => `__loading = ${e}`,
|
|
11
|
+
localeRead: "__currentLocale",
|
|
12
|
+
runtimeKey: "fluenti.runtime.react.v1"
|
|
13
|
+
});
|
|
120
14
|
//#endregion
|
|
121
15
|
//#region src/vite-plugin.ts
|
|
122
16
|
function r(t) {
|
|
123
17
|
return e({
|
|
124
|
-
...t,
|
|
18
|
+
...t?.config === void 0 ? {} : { config: t.config },
|
|
125
19
|
framework: "react"
|
|
126
20
|
}, [], n);
|
|
127
21
|
}
|
package/dist/vite-plugin.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"vite-plugin.js","names":[],"sources":["../src/react-runtime.ts","../src/vite-plugin.ts"],"sourcesContent":["import {
|
|
1
|
+
{"version":3,"file":"vite-plugin.js","names":[],"sources":["../src/react-runtime.ts","../src/vite-plugin.ts"],"sourcesContent":["import { createRuntimeGenerator } from '@fluenti/vite-plugin'\nimport type { RuntimeGenerator } from '@fluenti/vite-plugin'\n\nexport const reactRuntimeGenerator: RuntimeGenerator = createRuntimeGenerator({\n imports: '',\n catalogInit: 'const __catalog = { ...__defaultMsgs }',\n localeInit: (defaultLocale) => `let __currentLocale = '${defaultLocale}'`,\n loadingInit: 'let __loading = false',\n catalogUpdate: (msgs) => `Object.assign(__catalog, ${msgs})`,\n localeUpdate: (locale) => `__currentLocale = ${locale}`,\n loadingUpdate: (value) => `__loading = ${value}`,\n localeRead: '__currentLocale',\n runtimeKey: 'fluenti.runtime.react.v1',\n})\n","import type { Plugin } from 'vite'\nimport type { FluentiPluginOptions } from '@fluenti/vite-plugin'\nimport { createFluentiPlugins } from '@fluenti/vite-plugin'\nimport { reactRuntimeGenerator } from './react-runtime'\n\nexport type { FluentiPluginOptions as FluentiReactOptions } from '@fluenti/vite-plugin'\n\nexport default function fluentiReact(options?: FluentiPluginOptions): Plugin[] {\n return createFluentiPlugins(\n { ...(options?.config !== undefined ? { config: options.config } : {}), framework: 'react' },\n [],\n reactRuntimeGenerator,\n )\n}\n"],"mappings":";;AAGA,IAAa,IAA0C,EAAuB;CAC5E,SAAS;CACT,aAAa;CACb,aAAa,MAAkB,0BAA0B,EAAc;CACvE,aAAa;CACb,gBAAgB,MAAS,4BAA4B,EAAK;CAC1D,eAAe,MAAW,qBAAqB;CAC/C,gBAAgB,MAAU,eAAe;CACzC,YAAY;CACZ,YAAY;CACb,CAAC;;;ACNF,SAAwB,EAAa,GAA0C;AAC7E,QAAO,EACL;EAAE,GAAI,GAAS,WAAW,KAAA,IAAyC,EAAE,GAA/B,EAAE,QAAQ,EAAQ,QAAQ;EAAQ,WAAW;EAAS,EAC5F,EAAE,EACF,EACD"}
|
package/llms-full.txt
ADDED
|
@@ -0,0 +1,185 @@
|
|
|
1
|
+
# @fluenti/react
|
|
2
|
+
|
|
3
|
+
> React bindings for Fluenti — compile-time `t`, runtime-capable components, and client/server i18n helpers.
|
|
4
|
+
|
|
5
|
+
@fluenti/react is the React runtime layer for Fluenti. It supports:
|
|
6
|
+
|
|
7
|
+
- compile-time authoring with `import { t } from '@fluenti/react'`
|
|
8
|
+
- runtime lookup and imperative access with `useI18n()`
|
|
9
|
+
- async locale loading through `I18nProvider`
|
|
10
|
+
- request-scoped server helpers through `@fluenti/react/server`
|
|
11
|
+
|
|
12
|
+
## Install
|
|
13
|
+
|
|
14
|
+
```bash
|
|
15
|
+
pnpm add @fluenti/core @fluenti/react
|
|
16
|
+
pnpm add -D @fluenti/cli @fluenti/vite-plugin
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
## Main entry: `@fluenti/react`
|
|
20
|
+
|
|
21
|
+
### Public exports
|
|
22
|
+
|
|
23
|
+
- `I18nProvider`
|
|
24
|
+
- `useI18n`
|
|
25
|
+
- `t`
|
|
26
|
+
- `Trans`
|
|
27
|
+
- `Plural`
|
|
28
|
+
- `Select`
|
|
29
|
+
- `DateTime`
|
|
30
|
+
- `NumberFormat`
|
|
31
|
+
- `msg`
|
|
32
|
+
- `I18nContext`
|
|
33
|
+
|
|
34
|
+
Types:
|
|
35
|
+
|
|
36
|
+
- `FluentiContext`
|
|
37
|
+
- `I18nProviderProps`
|
|
38
|
+
- `FluentiTransProps`
|
|
39
|
+
- `FluentiPluralProps`
|
|
40
|
+
- `FluentiSelectProps`
|
|
41
|
+
- `FluentiDateTimeProps`
|
|
42
|
+
- `NumberFormatProps`
|
|
43
|
+
- `CompileTimeT`
|
|
44
|
+
|
|
45
|
+
### `I18nProvider`
|
|
46
|
+
|
|
47
|
+
Wraps a client React subtree with one Fluenti runtime instance.
|
|
48
|
+
|
|
49
|
+
Important props:
|
|
50
|
+
|
|
51
|
+
- `locale`
|
|
52
|
+
- `messages`
|
|
53
|
+
- `fallbackLocale`
|
|
54
|
+
- `fallbackChain`
|
|
55
|
+
- `loadMessages`
|
|
56
|
+
- `dateFormats`
|
|
57
|
+
- `numberFormats`
|
|
58
|
+
- `missing`
|
|
59
|
+
|
|
60
|
+
`loadMessages(locale)` is the public lazy-loading hook for async locale chunks.
|
|
61
|
+
|
|
62
|
+
### `useI18n()`
|
|
63
|
+
|
|
64
|
+
Returns the full client runtime API:
|
|
65
|
+
|
|
66
|
+
- `t(idOrDescriptor, values?)`
|
|
67
|
+
- tagged-template `t\`\``
|
|
68
|
+
- `d(value, style?)`
|
|
69
|
+
- `n(value, style?)`
|
|
70
|
+
- `format(message, values?)`
|
|
71
|
+
- `loadMessages(locale, messages)`
|
|
72
|
+
- `getLocales()`
|
|
73
|
+
- `locale`
|
|
74
|
+
- `setLocale(locale)`
|
|
75
|
+
- `isLoading`
|
|
76
|
+
- `loadedLocales`
|
|
77
|
+
- `preloadLocale(locale)`
|
|
78
|
+
- `te(id)` — check if a translation key exists
|
|
79
|
+
- `tm(id)` — get the raw compiled message without interpolation
|
|
80
|
+
|
|
81
|
+
## Compile-time `t`
|
|
82
|
+
|
|
83
|
+
Imported `t` is compile-time only:
|
|
84
|
+
|
|
85
|
+
```tsx
|
|
86
|
+
import { t } from '@fluenti/react'
|
|
87
|
+
|
|
88
|
+
const headline = t`Hello ${name}` // ✅ Preferred
|
|
89
|
+
const label = t({ message: 'Hello {name}', context: 'home.hero' }, { name }) // ✅ Preferred
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
Use `useI18n().t()` for runtime ID lookup or other imperative code:
|
|
93
|
+
|
|
94
|
+
```tsx
|
|
95
|
+
const { t } = useI18n()
|
|
96
|
+
return <p>{t('dashboard.greeting')}</p> // ⚠️ Runtime fallback — use only for dynamic keys
|
|
97
|
+
```
|
|
98
|
+
|
|
99
|
+
If imported `t` runs at runtime without the build plugin, it throws a clear error.
|
|
100
|
+
|
|
101
|
+
## Runtime-capable components
|
|
102
|
+
|
|
103
|
+
These continue to work without the build plugin:
|
|
104
|
+
|
|
105
|
+
- `Trans`
|
|
106
|
+
- `Plural`
|
|
107
|
+
- `Select`
|
|
108
|
+
- `DateTime`
|
|
109
|
+
- `NumberFormat`
|
|
110
|
+
|
|
111
|
+
Cross-framework contract highlights:
|
|
112
|
+
|
|
113
|
+
- `Plural` supports `id`, `context`, `comment`, and `offset`
|
|
114
|
+
- `zero` maps to exact `=0`
|
|
115
|
+
- `#` uses the adjusted count
|
|
116
|
+
- `Select` supports `options`, which take precedence over direct case props
|
|
117
|
+
|
|
118
|
+
## Example
|
|
119
|
+
|
|
120
|
+
```tsx
|
|
121
|
+
import { I18nProvider, t, useI18n, Trans, Plural, Select } from '@fluenti/react'
|
|
122
|
+
|
|
123
|
+
function Home() {
|
|
124
|
+
const name = 'Fluenti'
|
|
125
|
+
const headline = t`Hello ${name}`
|
|
126
|
+
const { setLocale, preloadLocale } = useI18n()
|
|
127
|
+
|
|
128
|
+
return (
|
|
129
|
+
<>
|
|
130
|
+
<h1>{headline}</h1>
|
|
131
|
+
<Trans>Read the <a href="/docs">documentation</a></Trans>
|
|
132
|
+
<Plural value={3} one="# item" other="# items" />
|
|
133
|
+
<Select value="admin" admin="Administrator" other="User" />
|
|
134
|
+
<button onMouseEnter={() => void preloadLocale('ja')} onClick={() => void setLocale('ja')}>
|
|
135
|
+
日本語
|
|
136
|
+
</button>
|
|
137
|
+
</>
|
|
138
|
+
)
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
export default function App() {
|
|
142
|
+
return (
|
|
143
|
+
<I18nProvider
|
|
144
|
+
locale="en"
|
|
145
|
+
fallbackLocale="en"
|
|
146
|
+
messages={{ en }}
|
|
147
|
+
loadMessages={(locale) => import(`./locales/compiled/${locale}.js`)}
|
|
148
|
+
>
|
|
149
|
+
<Home />
|
|
150
|
+
</I18nProvider>
|
|
151
|
+
)
|
|
152
|
+
}
|
|
153
|
+
```
|
|
154
|
+
|
|
155
|
+
## Server entry: `@fluenti/react/server`
|
|
156
|
+
|
|
157
|
+
### `createServerI18n(config)`
|
|
158
|
+
|
|
159
|
+
Creates request-scoped runtime helpers for server rendering.
|
|
160
|
+
|
|
161
|
+
Config:
|
|
162
|
+
|
|
163
|
+
- `loadMessages(locale)`
|
|
164
|
+
- `fallbackLocale`
|
|
165
|
+
- `resolveLocale`
|
|
166
|
+
- `fallbackChain`
|
|
167
|
+
- `dateFormats`
|
|
168
|
+
- `numberFormats`
|
|
169
|
+
- `missing`
|
|
170
|
+
|
|
171
|
+
Returns:
|
|
172
|
+
|
|
173
|
+
- `setLocale(locale)`
|
|
174
|
+
- `getI18n()`
|
|
175
|
+
- `Trans`
|
|
176
|
+
- `Plural`
|
|
177
|
+
- `Select`
|
|
178
|
+
- `DateTime`
|
|
179
|
+
- `NumberFormat`
|
|
180
|
+
|
|
181
|
+
Use this for server-side runtime access. It is distinct from imported compile-time `t`.
|
|
182
|
+
|
|
183
|
+
## Build plugin relationship
|
|
184
|
+
|
|
185
|
+
`@fluenti/react` is the runtime layer. `@fluenti/vite-plugin` and `@fluenti/next` provide compile-time transforms for imported `t` and component optimizations.
|