@fluenti/vue 0.4.0-rc.2 → 0.4.0-rc.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,2 +1,2 @@
1
- Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=require(`./use-i18n-CQQp9bxG.cjs`);let t=require(`vue`),n=require(`@fluenti/core/internal`);function r(e){let i=[],a=``;function o(e){if(e==null||typeof e==`boolean`)return;if(Array.isArray(e)){for(let t of e)o(t);return}if(typeof e==`string`||typeof e==`number`){a+=String(e);return}if(!(0,t.isVNode)(e)||e.type===t.Comment)return;if(e.type===t.Text){a+=typeof e.children==`string`?e.children:``;return}let s=i.length,c=r(e.children);i.push(e),i.push(...c.components),a+=`<${s}>${(0,n.offsetIndices)(c.message,s+1)}</${s}>`}return o(e),{message:a,components:i}}function i(e,n){let r=/<(\d+)>([\s\S]*?)<\/\1>/g,a=[],o=0,s;for(r.lastIndex=0,s=r.exec(e);s!==null;){s.index>o&&a.push(e.slice(o,s.index));let c=n[Number(s[1])],l=i(s[2],n);c?a.push((0,t.h)(c.type,c.props??{},Array.isArray(l)?l:[l])):a.push(s[2]),o=r.lastIndex,s=r.exec(e)}return o<e.length&&a.push(e.slice(o)),a.length<=1?a[0]??``:a}function a(e,t){let i={},a=[];for(let o of e){let e=t[o];if(e===void 0)continue;let s=r(e);i[o]=(0,n.offsetIndices)(s.message,a.length),a.push(...s.components)}for(let[o,s]of Object.entries(t)){if(e.includes(o)||s===void 0)continue;let t=r(s);i[o]=(0,n.offsetIndices)(t.message,a.length),a.push(...t.components)}return{messages:i,components:a}}var o={id:String,context:String,comment:String,tag:{type:String,default:void 0}},s=(0,t.defineComponent)({name:`Trans`,props:o,setup(n,{slots:a}){let{t:o}=e.t();return()=>{let e=a.default?.();if(!e)return null;let{message:s,components:c}=r(e),l=o({...n.id===void 0?{}:{id:n.id},message:s,...n.context===void 0?{}:{context:n.context},...n.comment===void 0?{}:{comment:n.comment}}),u=c.length>0?i(l,c):l;return Array.isArray(u)?u.length===1?u[0]:n.tag?(0,t.h)(n.tag,null,u):u:u}}}),c={value:{type:Number,required:!0},id:String,context:String,comment:String,zero:String,one:String,two:String,few:String,many:String,other:{type:String,required:!0},offset:Number,tag:{type:String,default:void 0}},l=(0,t.defineComponent)({name:`Plural`,props:c,setup(r,{slots:o}){let{t:s}=e.t();return()=>{let e={zero:r.zero,one:r.one,two:r.two,few:r.few,many:r.many,other:r.other};for(let t of n.PLURAL_CATEGORIES){let n=o[t];n&&(e[t]=n({count:`#`}))}let{messages:c,components:l}=a(n.PLURAL_CATEGORIES,e),u=(0,n.buildICUPluralMessage)({...c.zero!==void 0&&{zero:c.zero},...c.one!==void 0&&{one:c.one},...c.two!==void 0&&{two:c.two},...c.few!==void 0&&{few:c.few},...c.many!==void 0&&{many:c.many},other:c.other??``},r.offset),d=s({id:r.id??(r.context===void 0?u:(0,n.hashMessage)(u,r.context)),message:u,...r.context===void 0?{}:{context:r.context},...r.comment===void 0?{}:{comment:r.comment}},{count:r.value}),f=l.length>0?i(d,l):d;return r.tag?(0,t.h)(r.tag,void 0,f??void 0):f??null}}}),u={value:{type:String,required:!0},id:String,context:String,comment:String,other:{type:String,required:!0},options:{type:Object,default:void 0},tag:{type:String,default:void 0}},d=(0,t.defineComponent)({name:`Select`,inheritAttrs:!1,props:u,setup(r,{attrs:o,slots:s}){let{t:c}=e.t();return()=>{let e={};if(r.options!==void 0){for(let[t,n]of Object.entries(r.options))e[t]=n;e.other=r.other}else{for(let[t,n]of Object.entries(o))typeof n==`string`&&(e[t]=n);e.other=r.other}for(let[t,n]of Object.entries(s))t===`default`||!n||(e[t]=n({value:`{value}`}));let l=[...Object.keys(e).filter(e=>e!==`other`),`other`],{messages:u,components:d}=a(l,e),f=(0,n.normalizeSelectForms)(Object.fromEntries([...l].map(e=>[e,u[e]??``]))),p=(0,n.buildICUSelectMessage)(f.forms),m=c({id:r.id??(r.context===void 0?p:(0,n.hashMessage)(p,r.context)),message:p,...r.context===void 0?{}:{context:r.context},...r.comment===void 0?{}:{comment:r.comment}},{value:f.valueMap[r.value]??`other`}),h=d.length>0?i(m,d):m;return r.tag?(0,t.h)(r.tag,void 0,h??void 0):h??null}}}),f={value:{type:[Date,Number],required:!0},format:{type:String,default:void 0},tag:{type:String,default:`span`}},p=(0,t.defineComponent)({name:`DateTime`,props:f,setup(n){let{d:r}=e.t();return()=>(0,t.h)(n.tag,r(n.value,n.format))}}),m={value:{type:Number,required:!0},format:{type:String,default:void 0},tag:{type:String,default:`span`}},h=(0,t.defineComponent)({name:`NumberFormat`,props:m,setup(n){let{n:r}=e.t();return()=>(0,t.h)(n.tag,r(n.value,n.format))}});exports.DateTime=p,exports.NumberFormat=h,exports.Plural=l,exports.Select=d,exports.Trans=s,Object.defineProperty(exports,`interpolate`,{enumerable:!0,get:function(){return n.interpolate}});
1
+ Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=require(`./use-i18n-D6iu0pGX.cjs`);let t=require(`vue`),n=require(`@fluenti/core/internal`);function r(e){let i=[],a=``;function o(e){if(e==null||typeof e==`boolean`)return;if(Array.isArray(e)){for(let t of e)o(t);return}if(typeof e==`string`||typeof e==`number`){a+=String(e);return}if(!(0,t.isVNode)(e)||e.type===t.Comment)return;if(e.type===t.Text){a+=typeof e.children==`string`?e.children:``;return}let s=i.length,c=r(e.children);i.push(e),i.push(...c.components),a+=`<${s}>${(0,n.offsetIndices)(c.message,s+1)}</${s}>`}return o(e),{message:a,components:i}}function i(e,n){let r=/<(\d+)>([\s\S]*?)<\/\1>/g,a=[],o=0,s;for(r.lastIndex=0,s=r.exec(e);s!==null;){s.index>o&&a.push(e.slice(o,s.index));let c=n[Number(s[1])],l=i(s[2],n);c?a.push((0,t.h)(c.type,c.props??{},Array.isArray(l)?l:[l])):a.push(s[2]),o=r.lastIndex,s=r.exec(e)}return o<e.length&&a.push(e.slice(o)),a.length<=1?a[0]??``:a}function a(e,t){let i={},a=[];for(let o of e){let e=t[o];if(e===void 0)continue;let s=r(e);i[o]=(0,n.offsetIndices)(s.message,a.length),a.push(...s.components)}for(let[o,s]of Object.entries(t)){if(e.includes(o)||s===void 0)continue;let t=r(s);i[o]=(0,n.offsetIndices)(t.message,a.length),a.push(...t.components)}return{messages:i,components:a}}var o={id:String,context:String,comment:String,tag:{type:String,default:void 0}},s=(0,t.defineComponent)({name:`Trans`,props:o,setup(n,{slots:a}){let{t:o}=e.t();return()=>{let e=a.default?.();if(!e)return null;let{message:s,components:c}=r(e),l=o({...n.id===void 0?{}:{id:n.id},message:s,...n.context===void 0?{}:{context:n.context},...n.comment===void 0?{}:{comment:n.comment}}),u=c.length>0?i(l,c):l;return Array.isArray(u)?u.length===1?u[0]:n.tag?(0,t.h)(n.tag,null,u):u:u}}}),c={value:{type:Number,required:!0},id:String,context:String,comment:String,zero:String,one:String,two:String,few:String,many:String,other:{type:String,required:!0},offset:Number,tag:{type:String,default:void 0}},l=(0,t.defineComponent)({name:`Plural`,props:c,setup(r,{slots:o}){let{t:s}=e.t();return()=>{let e={zero:r.zero,one:r.one,two:r.two,few:r.few,many:r.many,other:r.other};for(let t of n.PLURAL_CATEGORIES){let n=o[t];n&&(e[t]=n({count:`#`}))}let{messages:c,components:l}=a(n.PLURAL_CATEGORIES,e),u=(0,n.buildICUPluralMessage)({...c.zero!==void 0&&{zero:c.zero},...c.one!==void 0&&{one:c.one},...c.two!==void 0&&{two:c.two},...c.few!==void 0&&{few:c.few},...c.many!==void 0&&{many:c.many},other:c.other??``},r.offset),d=s({id:r.id??(r.context===void 0?u:(0,n.hashMessage)(u,r.context)),message:u,...r.context===void 0?{}:{context:r.context},...r.comment===void 0?{}:{comment:r.comment}},{count:r.value}),f=l.length>0?i(d,l):d;return r.tag?(0,t.h)(r.tag,void 0,f??void 0):f??null}}}),u={value:{type:String,required:!0},id:String,context:String,comment:String,other:{type:String,required:!0},options:{type:Object,default:void 0},tag:{type:String,default:void 0}},d=(0,t.defineComponent)({name:`Select`,inheritAttrs:!1,props:u,setup(r,{attrs:o,slots:s}){let{t:c}=e.t();return()=>{let e={};if(r.options!==void 0){for(let[t,n]of Object.entries(r.options))e[t]=n;e.other=r.other}else{for(let[t,n]of Object.entries(o))typeof n==`string`&&(e[t]=n);e.other=r.other}for(let[t,n]of Object.entries(s))t===`default`||!n||(e[t]=n({value:`{value}`}));let l=[...Object.keys(e).filter(e=>e!==`other`),`other`],{messages:u,components:d}=a(l,e),f=(0,n.normalizeSelectForms)(Object.fromEntries([...l].map(e=>[e,u[e]??``]))),p=(0,n.buildICUSelectMessage)(f.forms),m=c({id:r.id??(r.context===void 0?p:(0,n.hashMessage)(p,r.context)),message:p,...r.context===void 0?{}:{context:r.context},...r.comment===void 0?{}:{comment:r.comment}},{value:f.valueMap[r.value]??`other`}),h=d.length>0?i(m,d):m;return r.tag?(0,t.h)(r.tag,void 0,h??void 0):h??null}}}),f={value:{type:[Date,Number],required:!0},format:{type:String,default:void 0},tag:{type:String,default:`span`}},p=(0,t.defineComponent)({name:`DateTime`,props:f,setup(n){let{d:r}=e.t();return()=>(0,t.h)(n.tag,r(n.value,n.format))}}),m={value:{type:Number,required:!0},format:{type:String,default:void 0},tag:{type:String,default:`span`}},h=(0,t.defineComponent)({name:`NumberFormat`,props:m,setup(n){let{n:r}=e.t();return()=>(0,t.h)(n.tag,r(n.value,n.format))}});exports.DateTime=p,exports.NumberFormat=h,exports.Plural=l,exports.Select=d,exports.Trans=s,Object.defineProperty(exports,`interpolate`,{enumerable:!0,get:function(){return n.interpolate}});
2
2
  //# sourceMappingURL=components-entry.cjs.map
@@ -1,4 +1,4 @@
1
- import { t as e } from "./use-i18n-DrhdlExQ.js";
1
+ import { t as e } from "./use-i18n-DV-MXUZc.js";
2
2
  import { Comment as t, Text as n, defineComponent as r, h as i, isVNode as a } from "vue";
3
3
  import { PLURAL_CATEGORIES as o, buildICUPluralMessage as s, buildICUSelectMessage as c, hashMessage as l, interpolate as u, normalizeSelectForms as d, offsetIndices as f } from "@fluenti/core/internal";
4
4
  //#region src/components/rich-text.ts
package/dist/index.cjs CHANGED
@@ -1,2 +1,2 @@
1
- Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=require(`./use-i18n-CQQp9bxG.cjs`);let t=require(`vue`),n=require(`@fluenti/core`);function r(e){return e.replace(/&/g,`&amp;`).replace(/"/g,`&quot;`).replace(/'/g,`&#39;`).replace(/</g,`&lt;`).replace(/>/g,`&gt;`)}var i=Symbol.for(`fluenti.runtime.vue.v1`);function a(){let e=globalThis[i];return typeof e==`object`&&e?e:null}function o(e){return typeof e==`object`&&e&&`default`in e?e.default:e}function s(e){let t=Object.keys(e).filter(e=>e!==`plural`);return t.length>0?t[0]:void 0}function c(i){let c=i.lazyLocaleLoading??i.splitting??!1,l={locale:i.locale,messages:i.messages??{}};i.fallbackLocale!==void 0&&(l.fallbackLocale=i.fallbackLocale),i.fallbackChain!==void 0&&(l.fallbackChain=i.fallbackChain),i.dateFormats!==void 0&&(l.dateFormats=i.dateFormats),i.numberFormats!==void 0&&(l.numberFormats=i.numberFormats),i.missing!==void 0&&(l.missing=i.missing),i.diagnostics!==void 0&&(l.diagnostics=i.diagnostics),i.interpolate!==void 0&&(l.interpolate=i.interpolate);let u=(0,n.createFluentiCore)(l),d=(0,t.ref)(i.locale),f=(0,t.shallowReactive)({...i.messages}),p=(0,t.ref)(!1),m=new Set([i.locale]),h=(0,t.ref)(new Set(m));function g(e,t){let n=f[e];if(n)return n[t]}function _(){u.locale!==d.value&&(u.locale=d.value)}function v(e,...t){return f[d.value],_(),Array.isArray(e)&&`raw`in e?u.t(e,...t):u.t(e,t[0])}let y=0;async function b(e){if(!c||!i.chunkLoader){u.locale=e,d.value=e;return}let t=a();if(m.has(e)){try{t?.__switchLocale&&await t.__switchLocale(e)}catch(t){console.warn(`[fluenti] split runtime switch failed for locale "${e}"`,t)}u.locale=e,d.value=e;return}let n=++y;p.value=!0;try{let r=o(await i.chunkLoader(e));if(n!==y)return;f[e]={...f[e],...r},u.loadMessages(e,r),m.add(e),h.value=new Set(m);try{t?.__switchLocale&&await t.__switchLocale(e)}catch(t){console.warn(`[fluenti] split runtime switch failed for locale "${e}"`,t)}if(n!==y)return;u.locale=e,d.value=e}finally{n===y&&(p.value=!1)}}function x(e,t){f[e]={...f[e],...t},u.loadMessages(e,t),m.add(e),h.value=new Set(m)}let S=new Set;function C(e){if(!c||m.has(e)||!i.chunkLoader||S.has(e))return;S.add(e);let t=a();i.chunkLoader(e).then(async n=>{let r=o(n);f[e]={...f[e],...r},u.loadMessages(e,r),m.add(e),h.value=new Set(m),t?.__preloadLocale&&await t.__preloadLocale(e)}).catch(t=>{console.warn(`[fluenti] preload failed:`,e,t)}).finally(()=>{S.delete(e)})}function w(){return _(),u.getLocales()}function T(e,t){return d.value,_(),u.d(e,t)}function E(e,t){return d.value,_(),u.n(e,t)}function D(e,t){return d.value,_(),u.format(e,t)}function O(e,t,n){let i=r(n?v(e,n):v(e));function a(e){if(e.rawAttrs!=null&&e.rawAttrs!==``){let t=[],n=/([\w:@.!-]+)(?:\s*=\s*(?:"([^"]*)"|'([^']*)'))?/g,i;for(;(i=n.exec(e.rawAttrs))!==null;){let e=r(i[1]),n=i[2]??i[3];t.push(n===void 0?e:`${e}="${r(n)}"`)}return t.join(` `)}return e.attrs?Object.entries(e.attrs).map(([e,t])=>t?`${r(e)}="${r(t)}"`:r(e)).join(` `):``}let o=i.replace(/&lt;(\d+)\/&gt;/g,(e,n)=>{let i=t[Number(n)];if(!i)return``;let o=r(i.tag),s=a(i);return`<${o}${s?` `+s:``} />`});return o=o.replace(/&lt;(\d+)&gt;([\s\S]*?)&lt;\/\1&gt;/g,(e,n,i)=>{let o=t[Number(n)];if(!o)return i;let s=r(o.tag),c=a(o);return`<${s}${c?` `+c:``}>${i}</${s}>`}),o}function k(e,t){return g(t??d.value,e)!==void 0}function A(e,t){return g(t??d.value,e)}let j={t:v,locale:d,setLocale:b,loadMessages:x,getLocales:w,d:T,n:E,format:D,isLoading:p,loadedLocales:h,preloadLocale:C,te:k,tm:A};return{install(t){if(t.provide(e.n,j),i.components){let e=i.componentPrefix??``,n=i.components;n.Trans&&t.component(`${e}Trans`,n.Trans),n.Plural&&t.component(`${e}Plural`,n.Plural),n.Select&&t.component(`${e}Select`,n.Select),n.DateTime&&t.component(`${e}DateTime`,n.DateTime),n.NumberFormat&&t.component(`${e}NumberFormat`,n.NumberFormat)}i.injectGlobalProperties!==!1&&(t.config.globalProperties.$t=v,t.config.globalProperties.$d=T,t.config.globalProperties.$n=E,t.config.globalProperties.$vtRich=O);let n=new WeakMap;t.directive(`t`,{mounted(e,t){let r=s(t.modifiers);if(r){let t=e.getAttribute(r)??``;n.set(e,t),e.setAttribute(r,v(t))}else{let r=t.arg??e.textContent??``;n.set(e,r.trim()),e.textContent=v(r.trim(),t.value==null?void 0:{...t.value})}},updated(e,t){let r=s(t.modifiers);if(r){let t=n.get(e)??e.getAttribute(r)??``;e.setAttribute(r,v(t))}else e.textContent=v((t.arg??n.get(e)??``).trim(),t.value==null?void 0:{...t.value})}})},global:j}}var l=((...e)=>{throw Error("[fluenti] `t` imported from '@fluenti/vue' is a compile-time API. Use it only with the Fluenti build transform inside <script setup> or setup(). For runtime lookups, use useI18n().t(...).")});exports.FLUENTI_KEY=e.n,exports.createFluenti=c,Object.defineProperty(exports,`msg`,{enumerable:!0,get:function(){return n.msg}}),exports.t=l,exports.useI18n=e.t;
1
+ Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=require(`./use-i18n-D6iu0pGX.cjs`);let t=require(`vue`),n=require(`@fluenti/core`);function r(e){return e.replace(/&/g,`&amp;`).replace(/"/g,`&quot;`).replace(/'/g,`&#39;`).replace(/</g,`&lt;`).replace(/>/g,`&gt;`)}var i=Symbol.for(`fluenti.runtime.vue.v1`);function a(){let e=globalThis[i];return typeof e==`object`&&e?e:null}function o(e){return typeof e==`object`&&e&&`default`in e?e.default:e}function s(e){let t=Object.keys(e).filter(e=>e!==`plural`);return t.length>0?t[0]:void 0}function c(i){let c=i.lazyLocaleLoading??i.splitting??!1,l={locale:i.locale,messages:i.messages??{}};i.fallbackLocale!==void 0&&(l.fallbackLocale=i.fallbackLocale),i.fallbackChain!==void 0&&(l.fallbackChain=i.fallbackChain),i.dateFormats!==void 0&&(l.dateFormats=i.dateFormats),i.numberFormats!==void 0&&(l.numberFormats=i.numberFormats),i.missing!==void 0&&(l.missing=i.missing),i.diagnostics!==void 0&&(l.diagnostics=i.diagnostics),i.interpolate!==void 0&&(l.interpolate=i.interpolate),l.devWarnings=l.devWarnings??(typeof process<`u`&&process.env.NODE_ENV===`development`);let u=(0,n.createFluentiCore)(l),d=(0,t.ref)(i.locale),f=(0,t.shallowReactive)({...i.messages}),p=(0,t.ref)(!1),m=new Set([i.locale]),h=(0,t.ref)(new Set(m));function g(e,t){let n=f[e];if(n)return n[t]}function _(){u.locale!==d.value&&(u.locale=d.value)}function v(e,...t){return f[d.value],_(),Array.isArray(e)&&`raw`in e?u.t(e,...t):u.t(e,t[0])}let y=0;async function b(e){if(!c||!i.chunkLoader){u.locale=e,d.value=e;return}let t=a();if(m.has(e)){try{t?.__switchLocale&&await t.__switchLocale(e)}catch(t){console.warn(`[fluenti] split runtime switch failed for locale "${e}"`,t)}u.locale=e,d.value=e;return}let n=++y;p.value=!0;try{let r=o(await i.chunkLoader(e));if(n!==y)return;f[e]={...f[e],...r},u.loadMessages(e,r),m.add(e),h.value=new Set(m);try{t?.__switchLocale&&await t.__switchLocale(e)}catch(t){console.warn(`[fluenti] split runtime switch failed for locale "${e}"`,t)}if(n!==y)return;u.locale=e,d.value=e}finally{n===y&&(p.value=!1)}}function x(e,t){f[e]={...f[e],...t},u.loadMessages(e,t),m.add(e),h.value=new Set(m)}let S=new Set;function C(e){if(!c||m.has(e)||!i.chunkLoader||S.has(e))return;S.add(e);let t=a();i.chunkLoader(e).then(async n=>{let r=o(n);f[e]={...f[e],...r},u.loadMessages(e,r),m.add(e),h.value=new Set(m),t?.__preloadLocale&&await t.__preloadLocale(e)}).catch(t=>{console.warn(`[fluenti] preload failed:`,e,t)}).finally(()=>{S.delete(e)})}function w(){return _(),u.getLocales()}function T(e,t){return d.value,_(),u.d(e,t)}function E(e,t){return d.value,_(),u.n(e,t)}function D(e,t){return d.value,_(),u.format(e,t)}function O(e,t,n){let i=r(n?v(e,n):v(e));function a(e){if(e.rawAttrs!=null&&e.rawAttrs!==``){let t=[],n=/([\w:@.!-]+)(?:\s*=\s*(?:"([^"]*)"|'([^']*)'))?/g,i;for(;(i=n.exec(e.rawAttrs))!==null;){let e=r(i[1]),n=i[2]??i[3];t.push(n===void 0?e:`${e}="${r(n)}"`)}return t.join(` `)}return e.attrs?Object.entries(e.attrs).map(([e,t])=>t?`${r(e)}="${r(t)}"`:r(e)).join(` `):``}let o=i.replace(/&lt;(\d+)\/&gt;/g,(e,n)=>{let i=t[Number(n)];if(!i)return``;let o=r(i.tag),s=a(i);return`<${o}${s?` `+s:``} />`});return o=o.replace(/&lt;(\d+)&gt;([\s\S]*?)&lt;\/\1&gt;/g,(e,n,i)=>{let o=t[Number(n)];if(!o)return i;let s=r(o.tag),c=a(o);return`<${s}${c?` `+c:``}>${i}</${s}>`}),o}function k(e,t){return g(t??d.value,e)!==void 0}function A(e,t){return g(t??d.value,e)}let j={t:v,locale:d,setLocale:b,loadMessages:x,getLocales:w,d:T,n:E,format:D,isLoading:p,loadedLocales:h,preloadLocale:C,te:k,tm:A};return{install(t){if(t.provide(e.r,j),i.components){let e=i.componentPrefix??``,n=i.components;n.Trans&&t.component(`${e}Trans`,n.Trans),n.Plural&&t.component(`${e}Plural`,n.Plural),n.Select&&t.component(`${e}Select`,n.Select),n.DateTime&&t.component(`${e}DateTime`,n.DateTime),n.NumberFormat&&t.component(`${e}NumberFormat`,n.NumberFormat)}i.injectGlobalProperties!==!1&&(t.config.globalProperties.$t=v,t.config.globalProperties.$d=T,t.config.globalProperties.$n=E,t.config.globalProperties.$vtRich=O);let n=new WeakMap;t.directive(`t`,{mounted(e,t){let r=s(t.modifiers);if(r){let t=e.getAttribute(r)??``;n.set(e,t),e.setAttribute(r,v(t))}else{let r=t.arg??e.textContent??``;n.set(e,r.trim()),e.textContent=v(r.trim(),t.value==null?void 0:{...t.value})}},updated(e,t){let r=s(t.modifiers);if(r){let t=n.get(e)??e.getAttribute(r)??``;e.setAttribute(r,v(t))}else e.textContent=v((t.arg??n.get(e)??``).trim(),t.value==null?void 0:{...t.value})}})},global:j}}var l=((...e)=>{throw Error("[fluenti] `t` imported from '@fluenti/vue' is a compile-time API. Use it only with the Fluenti build transform inside <script setup> or setup(). For runtime lookups, use useI18n().t(...).")});exports.FLUENTI_KEY=e.r,exports.createFluenti=c,Object.defineProperty(exports,`msg`,{enumerable:!0,get:function(){return n.msg}}),exports.t=l,exports.useI18n=e.t,exports.useLocale=e.n;
2
2
  //# sourceMappingURL=index.cjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.cjs","names":[],"sources":["../src/plugin.ts","../src/compile-time-t.ts"],"sourcesContent":["import { type App, type Ref, ref, shallowReactive } from 'vue'\nimport type { AllMessages, Locale, LocalizedString, Messages, CompiledMessage, MessageDescriptor, DiagnosticsConfig, CustomFormatter } from '@fluenti/core'\nimport { createFluentiCore } from '@fluenti/core'\nimport { FLUENTI_KEY } from './injection-key'\n// Components are in @fluenti/vue/components subpath.\n// Global component registration is opt-in via `components` config option.\n\n/** Escape HTML special characters to prevent XSS. @internal */\nfunction escapeHtml(str: string): string {\n return str.replace(/&/g, '&amp;').replace(/\"/g, '&quot;').replace(/'/g, '&#39;').replace(/</g, '&lt;').replace(/>/g, '&gt;')\n}\n\n/** Compiled message chunk loader for lazy locale loading */\nexport type ChunkLoader = (\n locale: string,\n) => Promise<Record<string, CompiledMessage> | { default: Record<string, CompiledMessage> }>\n\ninterface SplitRuntimeModule {\n __switchLocale?: (locale: string) => Promise<void>\n __preloadLocale?: (locale: string) => Promise<void>\n}\n\nconst SPLIT_RUNTIME_KEY = Symbol.for('fluenti.runtime.vue.v1')\n\nfunction getSplitRuntimeModule(): SplitRuntimeModule | null {\n const runtime = (globalThis as Record<PropertyKey, unknown>)[SPLIT_RUNTIME_KEY]\n return typeof runtime === 'object' && runtime !== null\n ? runtime as SplitRuntimeModule\n : null\n}\n\nfunction resolveChunkMessages(\n loaded: Record<string, CompiledMessage> | { default: Record<string, CompiledMessage> },\n): Record<string, CompiledMessage> {\n return typeof loaded === 'object' && loaded !== null && 'default' in loaded\n ? (loaded as { default: Record<string, CompiledMessage> }).default\n : loaded\n}\n\n/** Context object returned by `useI18n()` and available as `$t` etc. on globalProperties */\nexport interface FluentiContext {\n /** Translate a message by id or MessageDescriptor, with optional interpolation values */\n t(id: string | MessageDescriptor, values?: Record<string, unknown>): LocalizedString\n /** Tagged template form: t`Hello ${name}` */\n t(strings: TemplateStringsArray, ...exprs: unknown[]): LocalizedString\n /** Reactive ref for current locale */\n locale: Readonly<Ref<Locale>>\n /** Change the active locale (async when lazy locale loading is enabled) */\n setLocale(locale: Locale): Promise<void>\n /** Dynamically load messages for a locale */\n loadMessages(locale: Locale, messages: Messages): void\n /** Get all locales that have loaded messages */\n getLocales(): Locale[]\n /** Format a date value according to locale */\n d(value: Date | number, style?: string): LocalizedString\n /** Format a number according to locale */\n n(value: number, style?: string): LocalizedString\n /** Format an ICU message string directly (no catalog lookup) */\n format(message: string, values?: Record<string, unknown>): LocalizedString\n /** Whether a locale chunk is currently being loaded */\n isLoading: Readonly<Ref<boolean>>\n /** Set of locales whose messages have been loaded */\n loadedLocales: Readonly<Ref<ReadonlySet<string>>>\n /** Preload a locale in the background without switching to it */\n preloadLocale(locale: string): void\n /** Check if a translation key exists in the catalog */\n te(key: string, locale?: string): boolean\n /** Get the raw compiled message without interpolation */\n tm(key: string, locale?: string): CompiledMessage | undefined\n}\n\n/** Injection key for providing/injecting fluenti context */\nexport { FLUENTI_KEY } from './injection-key'\n\n/** Options for creating the Fluenti Vue plugin */\nexport interface FluentiConfig {\n locale: string\n fallbackLocale?: string\n messages: AllMessages\n missing?: (locale: string, id: string) => string | undefined\n dateFormats?: Record<string, Intl.DateTimeFormatOptions | 'relative'>\n numberFormats?: Record<string, Intl.NumberFormatOptions | ((locale: string) => Intl.NumberFormatOptions)>\n fallbackChain?: Record<string, string[]>\n /** Async chunk loader for lazy locale loading */\n chunkLoader?: ChunkLoader\n /** Enable lazy locale loading through chunkLoader */\n lazyLocaleLoading?: boolean\n /**\n * Prefix for globally registered components (Trans, Plural, Select).\n *\n * Set this to avoid naming conflicts with other libraries.\n *\n * @example\n * componentPrefix: 'I18n'\n * // Registers: I18nTrans, I18nPlural, I18nSelect\n *\n * @example\n * componentPrefix: 'Fluenti'\n * // Registers: FluentiTrans, FluentiPlural, FluentiSelect\n *\n * @default '' (no prefix — Trans, Plural, Select)\n */\n componentPrefix?: string\n /**\n * Whether to inject `$t`, `$d`, `$n`, `$vtRich` onto `app.config.globalProperties`.\n *\n * Set to `false` to avoid polluting the global namespace (e.g. when migrating from vue-i18n\n * or when using composition API exclusively via `useI18n()`).\n *\n * @default true\n */\n injectGlobalProperties?: boolean\n /** Runtime diagnostics configuration or pre-created instance */\n diagnostics?: DiagnosticsConfig | { missingKey: (locale: string, id: string) => void; fallbackUsed: (locale: string, fallbackLocale: string, id: string) => void; enabled: boolean }\n /**\n * Custom message interpolation function.\n *\n * By default, the runtime uses a lightweight `{key}` replacer.\n * Pass the full `interpolate` from `@fluenti/core/internal` for\n * runtime ICU MessageFormat parsing (adds ~2.5 KB gzip).\n *\n * @example\n * ```ts\n * import { interpolate } from '@fluenti/core/internal'\n * createFluenti({ interpolate, ... })\n * ```\n */\n interpolate?: (\n message: string,\n values: Record<string, unknown> | undefined,\n locale: string,\n formatters?: Record<string, CustomFormatter>,\n ) => string\n /**\n * Components to register globally via `app.component()`.\n *\n * Import from `@fluenti/vue/components` and pass here to enable global\n * component registration without bloating the default bundle.\n *\n * @example\n * ```ts\n * import * as components from '@fluenti/vue/components'\n * app.use(createFluenti({ components, ... }))\n * ```\n */\n components?: Record<string, unknown>\n}\n\n/** Return value of `createFluenti()` */\nexport interface FluentiPlugin {\n /** Vue plugin install method */\n install(app: App): void\n /** The global fluenti context (same as what useI18n returns) */\n global: FluentiContext\n}\n\n/** Extract the attribute name from v-t modifiers (e.g., v-t.alt → 'alt') */\nfunction getModifierAttr(modifiers: Partial<Record<string, boolean>>): string | undefined {\n const keys = Object.keys(modifiers).filter((k) => k !== 'plural')\n return keys.length > 0 ? keys[0] : undefined\n}\n\n/**\n * Create a Fluenti Vue plugin (SSR-safe, per-request instance).\n *\n * Each invocation creates entirely fresh state — no module-level singletons —\n * so it is safe to call once per SSR request.\n *\n * @example\n * ```ts\n * import { createFluenti } from '@fluenti/vue'\n * import messages from './locales/compiled/en.js'\n *\n * const fluenti = createFluenti({\n * locale: 'en',\n * messages: { en: messages },\n * })\n *\n * app.use(fluenti)\n * ```\n */\nexport function createFluenti(options: FluentiConfig): FluentiPlugin {\n const lazyLocaleLoading = options.lazyLocaleLoading\n ?? (options as FluentiConfig & { splitting?: boolean }).splitting\n ?? false\n\n // Create the core i18n instance — delegates t/d/n/format/loadMessages/getLocales\n // Build config incrementally to satisfy exactOptionalPropertyTypes —\n // optional properties must not receive `undefined` as a value.\n const coreConfig: Parameters<typeof createFluentiCore>[0] = {\n locale: options.locale,\n messages: options.messages ?? {},\n }\n if (options.fallbackLocale !== undefined) coreConfig.fallbackLocale = options.fallbackLocale\n if (options.fallbackChain !== undefined) coreConfig.fallbackChain = options.fallbackChain\n if (options.dateFormats !== undefined) coreConfig.dateFormats = options.dateFormats\n if (options.numberFormats !== undefined) coreConfig.numberFormats = options.numberFormats\n if (options.missing !== undefined) coreConfig.missing = options.missing\n if (options.diagnostics !== undefined) coreConfig.diagnostics = options.diagnostics as Parameters<typeof createFluentiCore>[0]['diagnostics']\n if (options.interpolate !== undefined) coreConfig.interpolate = options.interpolate\n const i18n = createFluentiCore(coreConfig)\n\n const locale = ref(options.locale)\n // Intentional mutation: Vue's shallowReactive API requires in-place property assignment for reactivity\n const catalogs = shallowReactive<AllMessages>({ ...options.messages })\n const isLoading = ref(false)\n const loadedLocalesSet = new Set<string>([options.locale])\n const loadedLocales = ref<ReadonlySet<string>>(new Set(loadedLocalesSet))\n\n /** Local catalog lookup for te/tm (core doesn't expose raw catalog access) */\n function lookup(\n loc: Locale,\n id: string,\n ): CompiledMessage | undefined {\n const msgs = catalogs[loc]\n if (!msgs) return undefined\n return msgs[id]\n }\n\n /** Sync Vue reactive locale to core before delegation */\n function syncLocale(): void {\n if (i18n.locale !== locale.value) {\n i18n.locale = locale.value\n }\n }\n\n function t(strings: TemplateStringsArray, ...exprs: unknown[]): LocalizedString\n function t(id: string | MessageDescriptor, values?: Record<string, unknown>): LocalizedString\n function t(idOrStrings: string | MessageDescriptor | TemplateStringsArray, ...rest: unknown[]): LocalizedString {\n // Read locale.value and catalogs to register Vue reactive dependencies\n // so components re-render when locale or messages change\n const currentLocale = locale.value\n void catalogs[currentLocale]\n syncLocale()\n // Dispatch to the correct overload based on input type\n if (Array.isArray(idOrStrings) && 'raw' in idOrStrings) {\n return i18n.t(idOrStrings as TemplateStringsArray, ...rest)\n }\n return i18n.t(idOrStrings as string | MessageDescriptor, rest[0] as Record<string, unknown> | undefined)\n }\n\n let _localeRequestId = 0\n\n async function setLocale(newLocale: Locale): Promise<void> {\n if (!lazyLocaleLoading || !options.chunkLoader) {\n i18n.locale = newLocale\n locale.value = newLocale\n return\n }\n\n const splitRuntime = getSplitRuntimeModule()\n\n if (loadedLocalesSet.has(newLocale)) {\n // Already loaded, instant switch\n try {\n if (splitRuntime?.__switchLocale) {\n await splitRuntime.__switchLocale(newLocale)\n }\n } catch (e) {\n console.warn(`[fluenti] split runtime switch failed for locale \"${newLocale}\"`, e)\n }\n i18n.locale = newLocale\n locale.value = newLocale\n return\n }\n\n // Race-condition protection: track request ID\n const thisRequest = ++_localeRequestId\n isLoading.value = true\n try {\n const messages = resolveChunkMessages(await options.chunkLoader(newLocale))\n // Stale request — a newer setLocale call superseded this one\n if (thisRequest !== _localeRequestId) return\n // Intentional mutation: Vue's shallowReactive API requires in-place property assignment for reactivity\n catalogs[newLocale] = { ...catalogs[newLocale], ...messages }\n i18n.loadMessages(newLocale, messages)\n loadedLocalesSet.add(newLocale)\n loadedLocales.value = new Set(loadedLocalesSet)\n try {\n if (splitRuntime?.__switchLocale) {\n await splitRuntime.__switchLocale(newLocale)\n }\n } catch (e) {\n console.warn(`[fluenti] split runtime switch failed for locale \"${newLocale}\"`, e)\n }\n // Re-check after async __switchLocale — a newer setLocale() may have superseded this one\n if (thisRequest !== _localeRequestId) return\n i18n.locale = newLocale\n locale.value = newLocale\n } finally {\n if (thisRequest === _localeRequestId) {\n isLoading.value = false\n }\n }\n }\n\n function loadMessages(loc: Locale, messages: Messages): void {\n // Intentional mutation: Vue's shallowReactive API requires in-place property assignment for reactivity\n catalogs[loc] = { ...catalogs[loc], ...messages }\n i18n.loadMessages(loc, messages)\n loadedLocalesSet.add(loc)\n loadedLocales.value = new Set(loadedLocalesSet)\n }\n\n const _preloadInFlight = new Set<string>()\n\n function preloadLocale(loc: string): void {\n if (!lazyLocaleLoading || loadedLocalesSet.has(loc) || !options.chunkLoader || _preloadInFlight.has(loc)) return\n _preloadInFlight.add(loc)\n const splitRuntime = getSplitRuntimeModule()\n options.chunkLoader(loc).then(async (loaded) => {\n const messages = resolveChunkMessages(loaded)\n // Intentional mutation: Vue's shallowReactive API requires in-place property assignment for reactivity\n catalogs[loc] = { ...catalogs[loc], ...messages }\n i18n.loadMessages(loc, messages)\n loadedLocalesSet.add(loc)\n loadedLocales.value = new Set(loadedLocalesSet)\n if (splitRuntime?.__preloadLocale) {\n await splitRuntime.__preloadLocale(loc)\n }\n }).catch((e: unknown) => {\n console.warn('[fluenti] preload failed:', loc, e)\n }).finally(() => {\n _preloadInFlight.delete(loc)\n })\n }\n\n function getLocales(): Locale[] {\n syncLocale()\n return i18n.getLocales()\n }\n\n function d(value: Date | number, style?: string): LocalizedString {\n // Read locale.value to register a Vue reactive dependency\n void locale.value\n syncLocale()\n return i18n.d(value, style)\n }\n\n function n(value: number, style?: string): LocalizedString {\n // Read locale.value to register a Vue reactive dependency\n void locale.value\n syncLocale()\n return i18n.n(value, style)\n }\n\n function format(message: string, values?: Record<string, unknown>): LocalizedString {\n // Read locale.value to register a Vue reactive dependency\n void locale.value\n syncLocale()\n return i18n.format(message, values)\n }\n\n /**\n * Rich text helper for v-t with child elements.\n * Translates the message (which contains `<0>content</0>` placeholders),\n * then replaces each placeholder with the original HTML element.\n * Used via `v-html=\"$vtRich('msg', elements)\"` in compile-time transforms.\n * @internal\n */\n function vtRich(\n message: string | MessageDescriptor,\n elements: Array<{ tag: string; attrs?: Record<string, string>; rawAttrs?: string }>,\n values?: Record<string, unknown>,\n ): string {\n const translated = values ? t(message, values) : t(message)\n // Escape the entire translated string first to neutralise any injected HTML\n const escaped = escapeHtml(translated)\n\n // Helper to build attribute string from element.\n // Both rawAttrs and attrs are escaped to prevent XSS — even though rawAttrs\n // originates from compile-time transforms, $vtRich is exposed on globalProperties\n // so we apply defence-in-depth.\n function buildAttrs(el: { attrs?: Record<string, string>; rawAttrs?: string }): string {\n if (el.rawAttrs != null && el.rawAttrs !== '') {\n // Parse rawAttrs back into key/value pairs and escape each one.\n // Handles: key=\"val\", key='val', and bare key (boolean attribute).\n const parts: string[] = []\n const attrRe = /([\\w:@.!-]+)(?:\\s*=\\s*(?:\"([^\"]*)\"|'([^']*)'))?/g\n let m: RegExpExecArray | null\n while ((m = attrRe.exec(el.rawAttrs)) !== null) {\n const key = escapeHtml(m[1]!)\n const val = m[2] ?? m[3]\n parts.push(val !== undefined ? `${key}=\"${escapeHtml(val)}\"` : key)\n }\n return parts.join(' ')\n }\n if (!el.attrs) return ''\n return Object.entries(el.attrs)\n .map(([k, v]) => v ? `${escapeHtml(k)}=\"${escapeHtml(v)}\"` : escapeHtml(k))\n .join(' ')\n }\n\n // First: handle self-closing <idx/> (escaped as &lt;idx/&gt;)\n let result = escaped.replace(/&lt;(\\d+)\\/&gt;/g, (_match, idxStr: string) => {\n const el = elements[Number(idxStr)]\n if (!el) return ''\n const tag = escapeHtml(el.tag)\n const attrs = buildAttrs(el)\n return `<${tag}${attrs ? ' ' + attrs : ''} />`\n })\n\n // Then: handle paired <idx>content</idx>\n result = result.replace(/&lt;(\\d+)&gt;([\\s\\S]*?)&lt;\\/\\1&gt;/g, (_match, idxStr: string, content: string) => {\n const el = elements[Number(idxStr)]\n if (!el) return content\n const tag = escapeHtml(el.tag)\n const attrs = buildAttrs(el)\n return `<${tag}${attrs ? ' ' + attrs : ''}>${content}</${tag}>`\n })\n\n return result\n }\n\n function te(key: string, loc?: string): boolean {\n const targetLocale = loc ?? locale.value\n return lookup(targetLocale, key) !== undefined\n }\n\n function tm(key: string, loc?: string): CompiledMessage | undefined {\n const targetLocale = loc ?? locale.value\n return lookup(targetLocale, key)\n }\n\n const context: FluentiContext = {\n t,\n locale,\n setLocale,\n loadMessages,\n getLocales,\n d,\n n,\n format,\n isLoading,\n loadedLocales,\n preloadLocale,\n te,\n tm,\n }\n\n return {\n install(app: App) {\n app.provide(FLUENTI_KEY, context)\n // Register components globally if provided via config\n if (options.components) {\n const prefix = options.componentPrefix ?? ''\n const comps = options.components as Record<string, unknown>\n if (comps['Trans']) app.component(`${prefix}Trans`, comps['Trans'] as any)\n if (comps['Plural']) app.component(`${prefix}Plural`, comps['Plural'] as any)\n if (comps['Select']) app.component(`${prefix}Select`, comps['Select'] as any)\n if (comps['DateTime']) app.component(`${prefix}DateTime`, comps['DateTime'] as any)\n if (comps['NumberFormat']) app.component(`${prefix}NumberFormat`, comps['NumberFormat'] as any)\n }\n if (options.injectGlobalProperties !== false) {\n app.config.globalProperties['$t'] = t\n app.config.globalProperties['$d'] = d\n app.config.globalProperties['$n'] = n\n app.config.globalProperties['$vtRich'] = vtRich\n }\n\n // Runtime v-t directive (fallback when compile-time transform is not used)\n const vtOriginalIds = new WeakMap<HTMLElement, string>()\n app.directive('t', {\n mounted(el, binding) {\n const attrName = getModifierAttr(binding.modifiers)\n if (attrName) {\n // v-t.alt, v-t.placeholder, etc. — translate the attribute\n const original = el.getAttribute(attrName) ?? ''\n vtOriginalIds.set(el, original)\n el.setAttribute(attrName, t(original))\n } else {\n // v-t or v-t:id — translate text content\n const id = binding.arg ?? el.textContent ?? ''\n vtOriginalIds.set(el, id.trim())\n el.textContent = t(id.trim(), binding.value != null ? { ...binding.value } : undefined)\n }\n },\n updated(el, binding) {\n const attrName = getModifierAttr(binding.modifiers)\n if (attrName) {\n const original = vtOriginalIds.get(el) ?? el.getAttribute(attrName) ?? ''\n el.setAttribute(attrName, t(original))\n } else {\n const id = binding.arg ?? vtOriginalIds.get(el) ?? ''\n el.textContent = t(id.trim(), binding.value != null ? { ...binding.value } : undefined)\n }\n },\n })\n },\n global: context,\n }\n}\n","import type { CompileTimeT } from '@fluenti/core'\n\nexport const t: CompileTimeT = ((..._args: unknown[]) => {\n throw new Error(\n \"[fluenti] `t` imported from '@fluenti/vue' is a compile-time API. \" +\n 'Use it only with the Fluenti build transform inside <script setup> or setup(). ' +\n 'For runtime lookups, use useI18n().t(...).',\n )\n}) as CompileTimeT\n"],"mappings":"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"}
1
+ {"version":3,"file":"index.cjs","names":[],"sources":["../src/plugin.ts","../src/compile-time-t.ts"],"sourcesContent":["import { type App, type Ref, ref, shallowReactive } from 'vue'\nimport type { AllMessages, Locale, LocalizedString, Messages, CompiledMessage, MessageDescriptor, DiagnosticsConfig, CustomFormatter } from '@fluenti/core'\nimport { createFluentiCore } from '@fluenti/core'\nimport { FLUENTI_KEY } from './injection-key'\n// Components are in @fluenti/vue/components subpath.\n// Global component registration is opt-in via `components` config option.\n\n/** Escape HTML special characters to prevent XSS. @internal */\nfunction escapeHtml(str: string): string {\n return str.replace(/&/g, '&amp;').replace(/\"/g, '&quot;').replace(/'/g, '&#39;').replace(/</g, '&lt;').replace(/>/g, '&gt;')\n}\n\n/** Compiled message chunk loader for lazy locale loading */\nexport type ChunkLoader = (\n locale: string,\n) => Promise<Record<string, CompiledMessage> | { default: Record<string, CompiledMessage> }>\n\ninterface SplitRuntimeModule {\n __switchLocale?: (locale: string) => Promise<void>\n __preloadLocale?: (locale: string) => Promise<void>\n}\n\nconst SPLIT_RUNTIME_KEY = Symbol.for('fluenti.runtime.vue.v1')\n\nfunction getSplitRuntimeModule(): SplitRuntimeModule | null {\n const runtime = (globalThis as Record<PropertyKey, unknown>)[SPLIT_RUNTIME_KEY]\n return typeof runtime === 'object' && runtime !== null\n ? runtime as SplitRuntimeModule\n : null\n}\n\nfunction resolveChunkMessages(\n loaded: Record<string, CompiledMessage> | { default: Record<string, CompiledMessage> },\n): Record<string, CompiledMessage> {\n return typeof loaded === 'object' && loaded !== null && 'default' in loaded\n ? (loaded as { default: Record<string, CompiledMessage> }).default\n : loaded\n}\n\n/** Context object returned by `useI18n()` and available as `$t` etc. on globalProperties */\nexport interface FluentiContext {\n /** Translate a message by id or MessageDescriptor, with optional interpolation values */\n t(id: string | MessageDescriptor, values?: Record<string, unknown>): LocalizedString\n /** Tagged template form: t`Hello ${name}` */\n t(strings: TemplateStringsArray, ...exprs: unknown[]): LocalizedString\n /** Reactive ref for current locale */\n locale: Readonly<Ref<Locale>>\n /** Change the active locale (async when lazy locale loading is enabled) */\n setLocale(locale: Locale): Promise<void>\n /** Dynamically load messages for a locale */\n loadMessages(locale: Locale, messages: Messages): void\n /** Get all locales that have loaded messages */\n getLocales(): Locale[]\n /** Format a date value according to locale */\n d(value: Date | number, style?: string): LocalizedString\n /** Format a number according to locale */\n n(value: number, style?: string): LocalizedString\n /** Format an ICU message string directly (no catalog lookup) */\n format(message: string, values?: Record<string, unknown>): LocalizedString\n /** Whether a locale chunk is currently being loaded */\n isLoading: Readonly<Ref<boolean>>\n /** Set of locales whose messages have been loaded */\n loadedLocales: Readonly<Ref<ReadonlySet<string>>>\n /** Preload a locale in the background without switching to it */\n preloadLocale(locale: string): void\n /** Check if a translation key exists in the catalog */\n te(key: string, locale?: string): boolean\n /** Get the raw compiled message without interpolation */\n tm(key: string, locale?: string): CompiledMessage | undefined\n}\n\n/** Injection key for providing/injecting fluenti context */\nexport { FLUENTI_KEY } from './injection-key'\n\n/** Options for creating the Fluenti Vue plugin */\nexport interface FluentiConfig {\n locale: string\n fallbackLocale?: string\n messages: AllMessages\n missing?: (locale: string, id: string) => string | undefined\n dateFormats?: Record<string, Intl.DateTimeFormatOptions | 'relative'>\n numberFormats?: Record<string, Intl.NumberFormatOptions | ((locale: string) => Intl.NumberFormatOptions)>\n fallbackChain?: Record<string, string[]>\n /** Async chunk loader for lazy locale loading */\n chunkLoader?: ChunkLoader\n /** Enable lazy locale loading through chunkLoader */\n lazyLocaleLoading?: boolean\n /**\n * Prefix for globally registered components (Trans, Plural, Select).\n *\n * Set this to avoid naming conflicts with other libraries.\n *\n * @example\n * componentPrefix: 'I18n'\n * // Registers: I18nTrans, I18nPlural, I18nSelect\n *\n * @example\n * componentPrefix: 'Fluenti'\n * // Registers: FluentiTrans, FluentiPlural, FluentiSelect\n *\n * @default '' (no prefix — Trans, Plural, Select)\n */\n componentPrefix?: string\n /**\n * Whether to inject `$t`, `$d`, `$n`, `$vtRich` onto `app.config.globalProperties`.\n *\n * Set to `false` to avoid polluting the global namespace (e.g. when migrating from vue-i18n\n * or when using composition API exclusively via `useI18n()`).\n *\n * @default true\n */\n injectGlobalProperties?: boolean\n /** Runtime diagnostics configuration or pre-created instance */\n diagnostics?: DiagnosticsConfig | { missingKey: (locale: string, id: string) => void; fallbackUsed: (locale: string, fallbackLocale: string, id: string) => void; enabled: boolean }\n /**\n * Custom message interpolation function.\n *\n * By default, the runtime uses a lightweight `{key}` replacer.\n * Pass the full `interpolate` from `@fluenti/core/internal` for\n * runtime ICU MessageFormat parsing (adds ~2.5 KB gzip).\n *\n * @example\n * ```ts\n * import { interpolate } from '@fluenti/core/internal'\n * createFluenti({ interpolate, ... })\n * ```\n */\n interpolate?: (\n message: string,\n values: Record<string, unknown> | undefined,\n locale: string,\n formatters?: Record<string, CustomFormatter>,\n ) => string\n /**\n * Components to register globally via `app.component()`.\n *\n * Import from `@fluenti/vue/components` and pass here to enable global\n * component registration without bloating the default bundle.\n *\n * @example\n * ```ts\n * import * as components from '@fluenti/vue/components'\n * app.use(createFluenti({ components, ... }))\n * ```\n */\n components?: Record<string, unknown>\n}\n\n/** Return value of `createFluenti()` */\nexport interface FluentiPlugin {\n /** Vue plugin install method */\n install(app: App): void\n /** The global fluenti context (same as what useI18n returns) */\n global: FluentiContext\n}\n\n/** Extract the attribute name from v-t modifiers (e.g., v-t.alt → 'alt') */\nfunction getModifierAttr(modifiers: Partial<Record<string, boolean>>): string | undefined {\n const keys = Object.keys(modifiers).filter((k) => k !== 'plural')\n return keys.length > 0 ? keys[0] : undefined\n}\n\n/**\n * Create a Fluenti Vue plugin (SSR-safe, per-request instance).\n *\n * Each invocation creates entirely fresh state — no module-level singletons —\n * so it is safe to call once per SSR request.\n *\n * @example\n * ```ts\n * import { createFluenti } from '@fluenti/vue'\n * import messages from './locales/compiled/en.js'\n *\n * const fluenti = createFluenti({\n * locale: 'en',\n * messages: { en: messages },\n * })\n *\n * app.use(fluenti)\n * ```\n */\nexport function createFluenti(options: FluentiConfig): FluentiPlugin {\n const lazyLocaleLoading = options.lazyLocaleLoading\n ?? (options as FluentiConfig & { splitting?: boolean }).splitting\n ?? false\n\n // Create the core i18n instance — delegates t/d/n/format/loadMessages/getLocales\n // Build config incrementally to satisfy exactOptionalPropertyTypes —\n // optional properties must not receive `undefined` as a value.\n const coreConfig: Parameters<typeof createFluentiCore>[0] = {\n locale: options.locale,\n messages: options.messages ?? {},\n }\n if (options.fallbackLocale !== undefined) coreConfig.fallbackLocale = options.fallbackLocale\n if (options.fallbackChain !== undefined) coreConfig.fallbackChain = options.fallbackChain\n if (options.dateFormats !== undefined) coreConfig.dateFormats = options.dateFormats\n if (options.numberFormats !== undefined) coreConfig.numberFormats = options.numberFormats\n if (options.missing !== undefined) coreConfig.missing = options.missing\n if (options.diagnostics !== undefined) coreConfig.diagnostics = options.diagnostics as Parameters<typeof createFluentiCore>[0]['diagnostics']\n if (options.interpolate !== undefined) coreConfig.interpolate = options.interpolate\n coreConfig.devWarnings = coreConfig.devWarnings ?? (typeof process !== 'undefined' && process.env?.['NODE_ENV'] === 'development')\n const i18n = createFluentiCore(coreConfig)\n\n const locale = ref(options.locale)\n // Intentional mutation: Vue's shallowReactive API requires in-place property assignment for reactivity\n const catalogs = shallowReactive<AllMessages>({ ...options.messages })\n const isLoading = ref(false)\n const loadedLocalesSet = new Set<string>([options.locale])\n const loadedLocales = ref<ReadonlySet<string>>(new Set(loadedLocalesSet))\n\n /** Local catalog lookup for te/tm (core doesn't expose raw catalog access) */\n function lookup(\n loc: Locale,\n id: string,\n ): CompiledMessage | undefined {\n const msgs = catalogs[loc]\n if (!msgs) return undefined\n return msgs[id]\n }\n\n /** Sync Vue reactive locale to core before delegation */\n function syncLocale(): void {\n if (i18n.locale !== locale.value) {\n i18n.locale = locale.value\n }\n }\n\n function t(strings: TemplateStringsArray, ...exprs: unknown[]): LocalizedString\n function t(id: string | MessageDescriptor, values?: Record<string, unknown>): LocalizedString\n function t(idOrStrings: string | MessageDescriptor | TemplateStringsArray, ...rest: unknown[]): LocalizedString {\n // Read locale.value and catalogs to register Vue reactive dependencies\n // so components re-render when locale or messages change\n const currentLocale = locale.value\n void catalogs[currentLocale]\n syncLocale()\n // Dispatch to the correct overload based on input type\n if (Array.isArray(idOrStrings) && 'raw' in idOrStrings) {\n return i18n.t(idOrStrings as TemplateStringsArray, ...rest)\n }\n return i18n.t(idOrStrings as string | MessageDescriptor, rest[0] as Record<string, unknown> | undefined)\n }\n\n let _localeRequestId = 0\n\n async function setLocale(newLocale: Locale): Promise<void> {\n if (!lazyLocaleLoading || !options.chunkLoader) {\n i18n.locale = newLocale\n locale.value = newLocale\n return\n }\n\n const splitRuntime = getSplitRuntimeModule()\n\n if (loadedLocalesSet.has(newLocale)) {\n // Already loaded, instant switch\n try {\n if (splitRuntime?.__switchLocale) {\n await splitRuntime.__switchLocale(newLocale)\n }\n } catch (e) {\n console.warn(`[fluenti] split runtime switch failed for locale \"${newLocale}\"`, e)\n }\n i18n.locale = newLocale\n locale.value = newLocale\n return\n }\n\n // Race-condition protection: track request ID\n const thisRequest = ++_localeRequestId\n isLoading.value = true\n try {\n const messages = resolveChunkMessages(await options.chunkLoader(newLocale))\n // Stale request — a newer setLocale call superseded this one\n if (thisRequest !== _localeRequestId) return\n // Intentional mutation: Vue's shallowReactive API requires in-place property assignment for reactivity\n catalogs[newLocale] = { ...catalogs[newLocale], ...messages }\n i18n.loadMessages(newLocale, messages)\n loadedLocalesSet.add(newLocale)\n loadedLocales.value = new Set(loadedLocalesSet)\n try {\n if (splitRuntime?.__switchLocale) {\n await splitRuntime.__switchLocale(newLocale)\n }\n } catch (e) {\n console.warn(`[fluenti] split runtime switch failed for locale \"${newLocale}\"`, e)\n }\n // Re-check after async __switchLocale — a newer setLocale() may have superseded this one\n if (thisRequest !== _localeRequestId) return\n i18n.locale = newLocale\n locale.value = newLocale\n } finally {\n if (thisRequest === _localeRequestId) {\n isLoading.value = false\n }\n }\n }\n\n function loadMessages(loc: Locale, messages: Messages): void {\n // Intentional mutation: Vue's shallowReactive API requires in-place property assignment for reactivity\n catalogs[loc] = { ...catalogs[loc], ...messages }\n i18n.loadMessages(loc, messages)\n loadedLocalesSet.add(loc)\n loadedLocales.value = new Set(loadedLocalesSet)\n }\n\n const _preloadInFlight = new Set<string>()\n\n function preloadLocale(loc: string): void {\n if (!lazyLocaleLoading || loadedLocalesSet.has(loc) || !options.chunkLoader || _preloadInFlight.has(loc)) return\n _preloadInFlight.add(loc)\n const splitRuntime = getSplitRuntimeModule()\n options.chunkLoader(loc).then(async (loaded) => {\n const messages = resolveChunkMessages(loaded)\n // Intentional mutation: Vue's shallowReactive API requires in-place property assignment for reactivity\n catalogs[loc] = { ...catalogs[loc], ...messages }\n i18n.loadMessages(loc, messages)\n loadedLocalesSet.add(loc)\n loadedLocales.value = new Set(loadedLocalesSet)\n if (splitRuntime?.__preloadLocale) {\n await splitRuntime.__preloadLocale(loc)\n }\n }).catch((e: unknown) => {\n console.warn('[fluenti] preload failed:', loc, e)\n }).finally(() => {\n _preloadInFlight.delete(loc)\n })\n }\n\n function getLocales(): Locale[] {\n syncLocale()\n return i18n.getLocales()\n }\n\n function d(value: Date | number, style?: string): LocalizedString {\n // Read locale.value to register a Vue reactive dependency\n void locale.value\n syncLocale()\n return i18n.d(value, style)\n }\n\n function n(value: number, style?: string): LocalizedString {\n // Read locale.value to register a Vue reactive dependency\n void locale.value\n syncLocale()\n return i18n.n(value, style)\n }\n\n function format(message: string, values?: Record<string, unknown>): LocalizedString {\n // Read locale.value to register a Vue reactive dependency\n void locale.value\n syncLocale()\n return i18n.format(message, values)\n }\n\n /**\n * Rich text helper for v-t with child elements.\n * Translates the message (which contains `<0>content</0>` placeholders),\n * then replaces each placeholder with the original HTML element.\n * Used via `v-html=\"$vtRich('msg', elements)\"` in compile-time transforms.\n * @internal\n */\n function vtRich(\n message: string | MessageDescriptor,\n elements: Array<{ tag: string; attrs?: Record<string, string>; rawAttrs?: string }>,\n values?: Record<string, unknown>,\n ): string {\n const translated = values ? t(message, values) : t(message)\n // Escape the entire translated string first to neutralise any injected HTML\n const escaped = escapeHtml(translated)\n\n // Helper to build attribute string from element.\n // Both rawAttrs and attrs are escaped to prevent XSS — even though rawAttrs\n // originates from compile-time transforms, $vtRich is exposed on globalProperties\n // so we apply defence-in-depth.\n function buildAttrs(el: { attrs?: Record<string, string>; rawAttrs?: string }): string {\n if (el.rawAttrs != null && el.rawAttrs !== '') {\n // Parse rawAttrs back into key/value pairs and escape each one.\n // Handles: key=\"val\", key='val', and bare key (boolean attribute).\n const parts: string[] = []\n const attrRe = /([\\w:@.!-]+)(?:\\s*=\\s*(?:\"([^\"]*)\"|'([^']*)'))?/g\n let m: RegExpExecArray | null\n while ((m = attrRe.exec(el.rawAttrs)) !== null) {\n const key = escapeHtml(m[1]!)\n const val = m[2] ?? m[3]\n parts.push(val !== undefined ? `${key}=\"${escapeHtml(val)}\"` : key)\n }\n return parts.join(' ')\n }\n if (!el.attrs) return ''\n return Object.entries(el.attrs)\n .map(([k, v]) => v ? `${escapeHtml(k)}=\"${escapeHtml(v)}\"` : escapeHtml(k))\n .join(' ')\n }\n\n // First: handle self-closing <idx/> (escaped as &lt;idx/&gt;)\n let result = escaped.replace(/&lt;(\\d+)\\/&gt;/g, (_match, idxStr: string) => {\n const el = elements[Number(idxStr)]\n if (!el) return ''\n const tag = escapeHtml(el.tag)\n const attrs = buildAttrs(el)\n return `<${tag}${attrs ? ' ' + attrs : ''} />`\n })\n\n // Then: handle paired <idx>content</idx>\n result = result.replace(/&lt;(\\d+)&gt;([\\s\\S]*?)&lt;\\/\\1&gt;/g, (_match, idxStr: string, content: string) => {\n const el = elements[Number(idxStr)]\n if (!el) return content\n const tag = escapeHtml(el.tag)\n const attrs = buildAttrs(el)\n return `<${tag}${attrs ? ' ' + attrs : ''}>${content}</${tag}>`\n })\n\n return result\n }\n\n function te(key: string, loc?: string): boolean {\n const targetLocale = loc ?? locale.value\n return lookup(targetLocale, key) !== undefined\n }\n\n function tm(key: string, loc?: string): CompiledMessage | undefined {\n const targetLocale = loc ?? locale.value\n return lookup(targetLocale, key)\n }\n\n const context: FluentiContext = {\n t,\n locale,\n setLocale,\n loadMessages,\n getLocales,\n d,\n n,\n format,\n isLoading,\n loadedLocales,\n preloadLocale,\n te,\n tm,\n }\n\n return {\n install(app: App) {\n app.provide(FLUENTI_KEY, context)\n // Register components globally if provided via config\n if (options.components) {\n const prefix = options.componentPrefix ?? ''\n const comps = options.components as Record<string, unknown>\n if (comps['Trans']) app.component(`${prefix}Trans`, comps['Trans'] as any)\n if (comps['Plural']) app.component(`${prefix}Plural`, comps['Plural'] as any)\n if (comps['Select']) app.component(`${prefix}Select`, comps['Select'] as any)\n if (comps['DateTime']) app.component(`${prefix}DateTime`, comps['DateTime'] as any)\n if (comps['NumberFormat']) app.component(`${prefix}NumberFormat`, comps['NumberFormat'] as any)\n }\n if (options.injectGlobalProperties !== false) {\n app.config.globalProperties['$t'] = t\n app.config.globalProperties['$d'] = d\n app.config.globalProperties['$n'] = n\n app.config.globalProperties['$vtRich'] = vtRich\n }\n\n // Runtime v-t directive (fallback when compile-time transform is not used)\n const vtOriginalIds = new WeakMap<HTMLElement, string>()\n app.directive('t', {\n mounted(el, binding) {\n const attrName = getModifierAttr(binding.modifiers)\n if (attrName) {\n // v-t.alt, v-t.placeholder, etc. — translate the attribute\n const original = el.getAttribute(attrName) ?? ''\n vtOriginalIds.set(el, original)\n el.setAttribute(attrName, t(original))\n } else {\n // v-t or v-t:id — translate text content\n const id = binding.arg ?? el.textContent ?? ''\n vtOriginalIds.set(el, id.trim())\n el.textContent = t(id.trim(), binding.value != null ? { ...binding.value } : undefined)\n }\n },\n updated(el, binding) {\n const attrName = getModifierAttr(binding.modifiers)\n if (attrName) {\n const original = vtOriginalIds.get(el) ?? el.getAttribute(attrName) ?? ''\n el.setAttribute(attrName, t(original))\n } else {\n const id = binding.arg ?? vtOriginalIds.get(el) ?? ''\n el.textContent = t(id.trim(), binding.value != null ? { ...binding.value } : undefined)\n }\n },\n })\n },\n global: context,\n }\n}\n","import type { CompileTimeT } from '@fluenti/core'\n\nexport const t: CompileTimeT = ((..._args: unknown[]) => {\n throw new Error(\n \"[fluenti] `t` imported from '@fluenti/vue' is a compile-time API. \" +\n 'Use it only with the Fluenti build transform inside <script setup> or setup(). ' +\n 'For runtime lookups, use useI18n().t(...).',\n )\n}) as CompileTimeT\n"],"mappings":"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"}
package/dist/index.d.ts CHANGED
@@ -1,6 +1,6 @@
1
1
  export { createFluenti, FLUENTI_KEY } from './plugin';
2
2
  export type { FluentiConfig, FluentiPlugin, FluentiContext } from './plugin';
3
- export { useI18n } from './use-i18n';
3
+ export { useI18n, useLocale } from './use-i18n';
4
4
  export { t } from './compile-time-t';
5
5
  export { msg } from './msg';
6
6
  export type { FluentiTransProps } from './components/Trans';
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,WAAW,EAAE,MAAM,UAAU,CAAA;AACrD,YAAY,EAAE,aAAa,EAAE,aAAa,EAAE,cAAc,EAAE,MAAM,UAAU,CAAA;AAC5E,OAAO,EAAE,OAAO,EAAE,MAAM,YAAY,CAAA;AACpC,OAAO,EAAE,CAAC,EAAE,MAAM,kBAAkB,CAAA;AACpC,OAAO,EAAE,GAAG,EAAE,MAAM,OAAO,CAAA;AAI3B,YAAY,EAAE,iBAAiB,EAAE,MAAM,oBAAoB,CAAA;AAC3D,YAAY,EAAE,kBAAkB,EAAE,MAAM,qBAAqB,CAAA;AAC7D,YAAY,EAAE,kBAAkB,EAAE,MAAM,qBAAqB,CAAA;AAC7D,YAAY,EAAE,oBAAoB,EAAE,MAAM,uBAAuB,CAAA;AACjE,YAAY,EAAE,wBAAwB,EAAE,MAAM,2BAA2B,CAAA"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,WAAW,EAAE,MAAM,UAAU,CAAA;AACrD,YAAY,EAAE,aAAa,EAAE,aAAa,EAAE,cAAc,EAAE,MAAM,UAAU,CAAA;AAC5E,OAAO,EAAE,OAAO,EAAE,SAAS,EAAE,MAAM,YAAY,CAAA;AAC/C,OAAO,EAAE,CAAC,EAAE,MAAM,kBAAkB,CAAA;AACpC,OAAO,EAAE,GAAG,EAAE,MAAM,OAAO,CAAA;AAI3B,YAAY,EAAE,iBAAiB,EAAE,MAAM,oBAAoB,CAAA;AAC3D,YAAY,EAAE,kBAAkB,EAAE,MAAM,qBAAqB,CAAA;AAC7D,YAAY,EAAE,kBAAkB,EAAE,MAAM,qBAAqB,CAAA;AAC7D,YAAY,EAAE,oBAAoB,EAAE,MAAM,uBAAuB,CAAA;AACjE,YAAY,EAAE,wBAAwB,EAAE,MAAM,2BAA2B,CAAA"}
package/dist/index.js CHANGED
@@ -1,134 +1,134 @@
1
- import { n as e, t } from "./use-i18n-DrhdlExQ.js";
2
- import { ref as n, shallowReactive as r } from "vue";
3
- import { createFluentiCore as i, msg as a } from "@fluenti/core";
1
+ import { n as e, r as t, t as n } from "./use-i18n-DV-MXUZc.js";
2
+ import { ref as r, shallowReactive as i } from "vue";
3
+ import { createFluentiCore as a, msg as o } from "@fluenti/core";
4
4
  //#region src/plugin.ts
5
- function o(e) {
5
+ function s(e) {
6
6
  return e.replace(/&/g, "&amp;").replace(/"/g, "&quot;").replace(/'/g, "&#39;").replace(/</g, "&lt;").replace(/>/g, "&gt;");
7
7
  }
8
- var s = Symbol.for("fluenti.runtime.vue.v1");
9
- function c() {
10
- let e = globalThis[s];
8
+ var c = Symbol.for("fluenti.runtime.vue.v1");
9
+ function l() {
10
+ let e = globalThis[c];
11
11
  return typeof e == "object" && e ? e : null;
12
12
  }
13
- function l(e) {
13
+ function u(e) {
14
14
  return typeof e == "object" && e && "default" in e ? e.default : e;
15
15
  }
16
- function u(e) {
16
+ function d(e) {
17
17
  let t = Object.keys(e).filter((e) => e !== "plural");
18
18
  return t.length > 0 ? t[0] : void 0;
19
19
  }
20
- function d(t) {
21
- let a = t.lazyLocaleLoading ?? t.splitting ?? !1, s = {
22
- locale: t.locale,
23
- messages: t.messages ?? {}
20
+ function f(e) {
21
+ let n = e.lazyLocaleLoading ?? e.splitting ?? !1, o = {
22
+ locale: e.locale,
23
+ messages: e.messages ?? {}
24
24
  };
25
- t.fallbackLocale !== void 0 && (s.fallbackLocale = t.fallbackLocale), t.fallbackChain !== void 0 && (s.fallbackChain = t.fallbackChain), t.dateFormats !== void 0 && (s.dateFormats = t.dateFormats), t.numberFormats !== void 0 && (s.numberFormats = t.numberFormats), t.missing !== void 0 && (s.missing = t.missing), t.diagnostics !== void 0 && (s.diagnostics = t.diagnostics), t.interpolate !== void 0 && (s.interpolate = t.interpolate);
26
- let d = i(s), f = n(t.locale), p = r({ ...t.messages }), m = n(!1), h = new Set([t.locale]), g = n(new Set(h));
25
+ e.fallbackLocale !== void 0 && (o.fallbackLocale = e.fallbackLocale), e.fallbackChain !== void 0 && (o.fallbackChain = e.fallbackChain), e.dateFormats !== void 0 && (o.dateFormats = e.dateFormats), e.numberFormats !== void 0 && (o.numberFormats = e.numberFormats), e.missing !== void 0 && (o.missing = e.missing), e.diagnostics !== void 0 && (o.diagnostics = e.diagnostics), e.interpolate !== void 0 && (o.interpolate = e.interpolate), o.devWarnings = o.devWarnings ?? (typeof process < "u" && process.env.NODE_ENV === "development");
26
+ let c = a(o), f = r(e.locale), p = i({ ...e.messages }), m = r(!1), h = new Set([e.locale]), g = r(new Set(h));
27
27
  function _(e, t) {
28
28
  let n = p[e];
29
29
  if (n) return n[t];
30
30
  }
31
31
  function v() {
32
- d.locale !== f.value && (d.locale = f.value);
32
+ c.locale !== f.value && (c.locale = f.value);
33
33
  }
34
34
  function y(e, ...t) {
35
- return p[f.value], v(), Array.isArray(e) && "raw" in e ? d.t(e, ...t) : d.t(e, t[0]);
35
+ return p[f.value], v(), Array.isArray(e) && "raw" in e ? c.t(e, ...t) : c.t(e, t[0]);
36
36
  }
37
37
  let b = 0;
38
- async function x(e) {
39
- if (!a || !t.chunkLoader) {
40
- d.locale = e, f.value = e;
38
+ async function x(t) {
39
+ if (!n || !e.chunkLoader) {
40
+ c.locale = t, f.value = t;
41
41
  return;
42
42
  }
43
- let n = c();
44
- if (h.has(e)) {
43
+ let r = l();
44
+ if (h.has(t)) {
45
45
  try {
46
- n?.__switchLocale && await n.__switchLocale(e);
47
- } catch (t) {
48
- console.warn(`[fluenti] split runtime switch failed for locale "${e}"`, t);
46
+ r?.__switchLocale && await r.__switchLocale(t);
47
+ } catch (e) {
48
+ console.warn(`[fluenti] split runtime switch failed for locale "${t}"`, e);
49
49
  }
50
- d.locale = e, f.value = e;
50
+ c.locale = t, f.value = t;
51
51
  return;
52
52
  }
53
- let r = ++b;
53
+ let i = ++b;
54
54
  m.value = !0;
55
55
  try {
56
- let i = l(await t.chunkLoader(e));
57
- if (r !== b) return;
58
- p[e] = {
59
- ...p[e],
60
- ...i
61
- }, d.loadMessages(e, i), h.add(e), g.value = new Set(h);
56
+ let n = u(await e.chunkLoader(t));
57
+ if (i !== b) return;
58
+ p[t] = {
59
+ ...p[t],
60
+ ...n
61
+ }, c.loadMessages(t, n), h.add(t), g.value = new Set(h);
62
62
  try {
63
- n?.__switchLocale && await n.__switchLocale(e);
64
- } catch (t) {
65
- console.warn(`[fluenti] split runtime switch failed for locale "${e}"`, t);
63
+ r?.__switchLocale && await r.__switchLocale(t);
64
+ } catch (e) {
65
+ console.warn(`[fluenti] split runtime switch failed for locale "${t}"`, e);
66
66
  }
67
- if (r !== b) return;
68
- d.locale = e, f.value = e;
67
+ if (i !== b) return;
68
+ c.locale = t, f.value = t;
69
69
  } finally {
70
- r === b && (m.value = !1);
70
+ i === b && (m.value = !1);
71
71
  }
72
72
  }
73
73
  function S(e, t) {
74
74
  p[e] = {
75
75
  ...p[e],
76
76
  ...t
77
- }, d.loadMessages(e, t), h.add(e), g.value = new Set(h);
77
+ }, c.loadMessages(e, t), h.add(e), g.value = new Set(h);
78
78
  }
79
79
  let C = /* @__PURE__ */ new Set();
80
- function w(e) {
81
- if (!a || h.has(e) || !t.chunkLoader || C.has(e)) return;
82
- C.add(e);
83
- let n = c();
84
- t.chunkLoader(e).then(async (t) => {
85
- let r = l(t);
86
- p[e] = {
87
- ...p[e],
88
- ...r
89
- }, d.loadMessages(e, r), h.add(e), g.value = new Set(h), n?.__preloadLocale && await n.__preloadLocale(e);
90
- }).catch((t) => {
91
- console.warn("[fluenti] preload failed:", e, t);
80
+ function w(t) {
81
+ if (!n || h.has(t) || !e.chunkLoader || C.has(t)) return;
82
+ C.add(t);
83
+ let r = l();
84
+ e.chunkLoader(t).then(async (e) => {
85
+ let n = u(e);
86
+ p[t] = {
87
+ ...p[t],
88
+ ...n
89
+ }, c.loadMessages(t, n), h.add(t), g.value = new Set(h), r?.__preloadLocale && await r.__preloadLocale(t);
90
+ }).catch((e) => {
91
+ console.warn("[fluenti] preload failed:", t, e);
92
92
  }).finally(() => {
93
- C.delete(e);
93
+ C.delete(t);
94
94
  });
95
95
  }
96
96
  function T() {
97
- return v(), d.getLocales();
97
+ return v(), c.getLocales();
98
98
  }
99
99
  function E(e, t) {
100
- return f.value, v(), d.d(e, t);
100
+ return f.value, v(), c.d(e, t);
101
101
  }
102
102
  function D(e, t) {
103
- return f.value, v(), d.n(e, t);
103
+ return f.value, v(), c.n(e, t);
104
104
  }
105
105
  function O(e, t) {
106
- return f.value, v(), d.format(e, t);
106
+ return f.value, v(), c.format(e, t);
107
107
  }
108
108
  function k(e, t, n) {
109
- let r = o(n ? y(e, n) : y(e));
109
+ let r = s(n ? y(e, n) : y(e));
110
110
  function i(e) {
111
111
  if (e.rawAttrs != null && e.rawAttrs !== "") {
112
112
  let t = [], n = /([\w:@.!-]+)(?:\s*=\s*(?:"([^"]*)"|'([^']*)'))?/g, r;
113
113
  for (; (r = n.exec(e.rawAttrs)) !== null;) {
114
- let e = o(r[1]), n = r[2] ?? r[3];
115
- t.push(n === void 0 ? e : `${e}="${o(n)}"`);
114
+ let e = s(r[1]), n = r[2] ?? r[3];
115
+ t.push(n === void 0 ? e : `${e}="${s(n)}"`);
116
116
  }
117
117
  return t.join(" ");
118
118
  }
119
- return e.attrs ? Object.entries(e.attrs).map(([e, t]) => t ? `${o(e)}="${o(t)}"` : o(e)).join(" ") : "";
119
+ return e.attrs ? Object.entries(e.attrs).map(([e, t]) => t ? `${s(e)}="${s(t)}"` : s(e)).join(" ") : "";
120
120
  }
121
121
  let a = r.replace(/&lt;(\d+)\/&gt;/g, (e, n) => {
122
122
  let r = t[Number(n)];
123
123
  if (!r) return "";
124
- let a = o(r.tag), s = i(r);
125
- return `<${a}${s ? " " + s : ""} />`;
124
+ let a = s(r.tag), o = i(r);
125
+ return `<${a}${o ? " " + o : ""} />`;
126
126
  });
127
127
  return a = a.replace(/&lt;(\d+)&gt;([\s\S]*?)&lt;\/\1&gt;/g, (e, n, r) => {
128
128
  let a = t[Number(n)];
129
129
  if (!a) return r;
130
- let s = o(a.tag), c = i(a);
131
- return `<${s}${c ? " " + c : ""}>${r}</${s}>`;
130
+ let o = s(a.tag), c = i(a);
131
+ return `<${o}${c ? " " + c : ""}>${r}</${o}>`;
132
132
  }), a;
133
133
  }
134
134
  function A(e, t) {
@@ -154,15 +154,15 @@ function d(t) {
154
154
  };
155
155
  return {
156
156
  install(n) {
157
- if (n.provide(e, M), t.components) {
158
- let e = t.componentPrefix ?? "", r = t.components;
159
- r.Trans && n.component(`${e}Trans`, r.Trans), r.Plural && n.component(`${e}Plural`, r.Plural), r.Select && n.component(`${e}Select`, r.Select), r.DateTime && n.component(`${e}DateTime`, r.DateTime), r.NumberFormat && n.component(`${e}NumberFormat`, r.NumberFormat);
157
+ if (n.provide(t, M), e.components) {
158
+ let t = e.componentPrefix ?? "", r = e.components;
159
+ r.Trans && n.component(`${t}Trans`, r.Trans), r.Plural && n.component(`${t}Plural`, r.Plural), r.Select && n.component(`${t}Select`, r.Select), r.DateTime && n.component(`${t}DateTime`, r.DateTime), r.NumberFormat && n.component(`${t}NumberFormat`, r.NumberFormat);
160
160
  }
161
- t.injectGlobalProperties !== !1 && (n.config.globalProperties.$t = y, n.config.globalProperties.$d = E, n.config.globalProperties.$n = D, n.config.globalProperties.$vtRich = k);
161
+ e.injectGlobalProperties !== !1 && (n.config.globalProperties.$t = y, n.config.globalProperties.$d = E, n.config.globalProperties.$n = D, n.config.globalProperties.$vtRich = k);
162
162
  let r = /* @__PURE__ */ new WeakMap();
163
163
  n.directive("t", {
164
164
  mounted(e, t) {
165
- let n = u(t.modifiers);
165
+ let n = d(t.modifiers);
166
166
  if (n) {
167
167
  let t = e.getAttribute(n) ?? "";
168
168
  r.set(e, t), e.setAttribute(n, y(t));
@@ -172,7 +172,7 @@ function d(t) {
172
172
  }
173
173
  },
174
174
  updated(e, t) {
175
- let n = u(t.modifiers);
175
+ let n = d(t.modifiers);
176
176
  if (n) {
177
177
  let t = r.get(e) ?? e.getAttribute(n) ?? "";
178
178
  e.setAttribute(n, y(t));
@@ -185,10 +185,10 @@ function d(t) {
185
185
  }
186
186
  //#endregion
187
187
  //#region src/compile-time-t.ts
188
- var f = ((...e) => {
188
+ var p = ((...e) => {
189
189
  throw Error("[fluenti] `t` imported from '@fluenti/vue' is a compile-time API. Use it only with the Fluenti build transform inside <script setup> or setup(). For runtime lookups, use useI18n().t(...).");
190
190
  });
191
191
  //#endregion
192
- export { e as FLUENTI_KEY, d as createFluenti, a as msg, f as t, t as useI18n };
192
+ export { t as FLUENTI_KEY, f as createFluenti, o as msg, p as t, n as useI18n, e as useLocale };
193
193
 
194
194
  //# sourceMappingURL=index.js.map
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","names":[],"sources":["../src/plugin.ts","../src/compile-time-t.ts"],"sourcesContent":["import { type App, type Ref, ref, shallowReactive } from 'vue'\nimport type { AllMessages, Locale, LocalizedString, Messages, CompiledMessage, MessageDescriptor, DiagnosticsConfig, CustomFormatter } from '@fluenti/core'\nimport { createFluentiCore } from '@fluenti/core'\nimport { FLUENTI_KEY } from './injection-key'\n// Components are in @fluenti/vue/components subpath.\n// Global component registration is opt-in via `components` config option.\n\n/** Escape HTML special characters to prevent XSS. @internal */\nfunction escapeHtml(str: string): string {\n return str.replace(/&/g, '&amp;').replace(/\"/g, '&quot;').replace(/'/g, '&#39;').replace(/</g, '&lt;').replace(/>/g, '&gt;')\n}\n\n/** Compiled message chunk loader for lazy locale loading */\nexport type ChunkLoader = (\n locale: string,\n) => Promise<Record<string, CompiledMessage> | { default: Record<string, CompiledMessage> }>\n\ninterface SplitRuntimeModule {\n __switchLocale?: (locale: string) => Promise<void>\n __preloadLocale?: (locale: string) => Promise<void>\n}\n\nconst SPLIT_RUNTIME_KEY = Symbol.for('fluenti.runtime.vue.v1')\n\nfunction getSplitRuntimeModule(): SplitRuntimeModule | null {\n const runtime = (globalThis as Record<PropertyKey, unknown>)[SPLIT_RUNTIME_KEY]\n return typeof runtime === 'object' && runtime !== null\n ? runtime as SplitRuntimeModule\n : null\n}\n\nfunction resolveChunkMessages(\n loaded: Record<string, CompiledMessage> | { default: Record<string, CompiledMessage> },\n): Record<string, CompiledMessage> {\n return typeof loaded === 'object' && loaded !== null && 'default' in loaded\n ? (loaded as { default: Record<string, CompiledMessage> }).default\n : loaded\n}\n\n/** Context object returned by `useI18n()` and available as `$t` etc. on globalProperties */\nexport interface FluentiContext {\n /** Translate a message by id or MessageDescriptor, with optional interpolation values */\n t(id: string | MessageDescriptor, values?: Record<string, unknown>): LocalizedString\n /** Tagged template form: t`Hello ${name}` */\n t(strings: TemplateStringsArray, ...exprs: unknown[]): LocalizedString\n /** Reactive ref for current locale */\n locale: Readonly<Ref<Locale>>\n /** Change the active locale (async when lazy locale loading is enabled) */\n setLocale(locale: Locale): Promise<void>\n /** Dynamically load messages for a locale */\n loadMessages(locale: Locale, messages: Messages): void\n /** Get all locales that have loaded messages */\n getLocales(): Locale[]\n /** Format a date value according to locale */\n d(value: Date | number, style?: string): LocalizedString\n /** Format a number according to locale */\n n(value: number, style?: string): LocalizedString\n /** Format an ICU message string directly (no catalog lookup) */\n format(message: string, values?: Record<string, unknown>): LocalizedString\n /** Whether a locale chunk is currently being loaded */\n isLoading: Readonly<Ref<boolean>>\n /** Set of locales whose messages have been loaded */\n loadedLocales: Readonly<Ref<ReadonlySet<string>>>\n /** Preload a locale in the background without switching to it */\n preloadLocale(locale: string): void\n /** Check if a translation key exists in the catalog */\n te(key: string, locale?: string): boolean\n /** Get the raw compiled message without interpolation */\n tm(key: string, locale?: string): CompiledMessage | undefined\n}\n\n/** Injection key for providing/injecting fluenti context */\nexport { FLUENTI_KEY } from './injection-key'\n\n/** Options for creating the Fluenti Vue plugin */\nexport interface FluentiConfig {\n locale: string\n fallbackLocale?: string\n messages: AllMessages\n missing?: (locale: string, id: string) => string | undefined\n dateFormats?: Record<string, Intl.DateTimeFormatOptions | 'relative'>\n numberFormats?: Record<string, Intl.NumberFormatOptions | ((locale: string) => Intl.NumberFormatOptions)>\n fallbackChain?: Record<string, string[]>\n /** Async chunk loader for lazy locale loading */\n chunkLoader?: ChunkLoader\n /** Enable lazy locale loading through chunkLoader */\n lazyLocaleLoading?: boolean\n /**\n * Prefix for globally registered components (Trans, Plural, Select).\n *\n * Set this to avoid naming conflicts with other libraries.\n *\n * @example\n * componentPrefix: 'I18n'\n * // Registers: I18nTrans, I18nPlural, I18nSelect\n *\n * @example\n * componentPrefix: 'Fluenti'\n * // Registers: FluentiTrans, FluentiPlural, FluentiSelect\n *\n * @default '' (no prefix — Trans, Plural, Select)\n */\n componentPrefix?: string\n /**\n * Whether to inject `$t`, `$d`, `$n`, `$vtRich` onto `app.config.globalProperties`.\n *\n * Set to `false` to avoid polluting the global namespace (e.g. when migrating from vue-i18n\n * or when using composition API exclusively via `useI18n()`).\n *\n * @default true\n */\n injectGlobalProperties?: boolean\n /** Runtime diagnostics configuration or pre-created instance */\n diagnostics?: DiagnosticsConfig | { missingKey: (locale: string, id: string) => void; fallbackUsed: (locale: string, fallbackLocale: string, id: string) => void; enabled: boolean }\n /**\n * Custom message interpolation function.\n *\n * By default, the runtime uses a lightweight `{key}` replacer.\n * Pass the full `interpolate` from `@fluenti/core/internal` for\n * runtime ICU MessageFormat parsing (adds ~2.5 KB gzip).\n *\n * @example\n * ```ts\n * import { interpolate } from '@fluenti/core/internal'\n * createFluenti({ interpolate, ... })\n * ```\n */\n interpolate?: (\n message: string,\n values: Record<string, unknown> | undefined,\n locale: string,\n formatters?: Record<string, CustomFormatter>,\n ) => string\n /**\n * Components to register globally via `app.component()`.\n *\n * Import from `@fluenti/vue/components` and pass here to enable global\n * component registration without bloating the default bundle.\n *\n * @example\n * ```ts\n * import * as components from '@fluenti/vue/components'\n * app.use(createFluenti({ components, ... }))\n * ```\n */\n components?: Record<string, unknown>\n}\n\n/** Return value of `createFluenti()` */\nexport interface FluentiPlugin {\n /** Vue plugin install method */\n install(app: App): void\n /** The global fluenti context (same as what useI18n returns) */\n global: FluentiContext\n}\n\n/** Extract the attribute name from v-t modifiers (e.g., v-t.alt → 'alt') */\nfunction getModifierAttr(modifiers: Partial<Record<string, boolean>>): string | undefined {\n const keys = Object.keys(modifiers).filter((k) => k !== 'plural')\n return keys.length > 0 ? keys[0] : undefined\n}\n\n/**\n * Create a Fluenti Vue plugin (SSR-safe, per-request instance).\n *\n * Each invocation creates entirely fresh state — no module-level singletons —\n * so it is safe to call once per SSR request.\n *\n * @example\n * ```ts\n * import { createFluenti } from '@fluenti/vue'\n * import messages from './locales/compiled/en.js'\n *\n * const fluenti = createFluenti({\n * locale: 'en',\n * messages: { en: messages },\n * })\n *\n * app.use(fluenti)\n * ```\n */\nexport function createFluenti(options: FluentiConfig): FluentiPlugin {\n const lazyLocaleLoading = options.lazyLocaleLoading\n ?? (options as FluentiConfig & { splitting?: boolean }).splitting\n ?? false\n\n // Create the core i18n instance — delegates t/d/n/format/loadMessages/getLocales\n // Build config incrementally to satisfy exactOptionalPropertyTypes —\n // optional properties must not receive `undefined` as a value.\n const coreConfig: Parameters<typeof createFluentiCore>[0] = {\n locale: options.locale,\n messages: options.messages ?? {},\n }\n if (options.fallbackLocale !== undefined) coreConfig.fallbackLocale = options.fallbackLocale\n if (options.fallbackChain !== undefined) coreConfig.fallbackChain = options.fallbackChain\n if (options.dateFormats !== undefined) coreConfig.dateFormats = options.dateFormats\n if (options.numberFormats !== undefined) coreConfig.numberFormats = options.numberFormats\n if (options.missing !== undefined) coreConfig.missing = options.missing\n if (options.diagnostics !== undefined) coreConfig.diagnostics = options.diagnostics as Parameters<typeof createFluentiCore>[0]['diagnostics']\n if (options.interpolate !== undefined) coreConfig.interpolate = options.interpolate\n const i18n = createFluentiCore(coreConfig)\n\n const locale = ref(options.locale)\n // Intentional mutation: Vue's shallowReactive API requires in-place property assignment for reactivity\n const catalogs = shallowReactive<AllMessages>({ ...options.messages })\n const isLoading = ref(false)\n const loadedLocalesSet = new Set<string>([options.locale])\n const loadedLocales = ref<ReadonlySet<string>>(new Set(loadedLocalesSet))\n\n /** Local catalog lookup for te/tm (core doesn't expose raw catalog access) */\n function lookup(\n loc: Locale,\n id: string,\n ): CompiledMessage | undefined {\n const msgs = catalogs[loc]\n if (!msgs) return undefined\n return msgs[id]\n }\n\n /** Sync Vue reactive locale to core before delegation */\n function syncLocale(): void {\n if (i18n.locale !== locale.value) {\n i18n.locale = locale.value\n }\n }\n\n function t(strings: TemplateStringsArray, ...exprs: unknown[]): LocalizedString\n function t(id: string | MessageDescriptor, values?: Record<string, unknown>): LocalizedString\n function t(idOrStrings: string | MessageDescriptor | TemplateStringsArray, ...rest: unknown[]): LocalizedString {\n // Read locale.value and catalogs to register Vue reactive dependencies\n // so components re-render when locale or messages change\n const currentLocale = locale.value\n void catalogs[currentLocale]\n syncLocale()\n // Dispatch to the correct overload based on input type\n if (Array.isArray(idOrStrings) && 'raw' in idOrStrings) {\n return i18n.t(idOrStrings as TemplateStringsArray, ...rest)\n }\n return i18n.t(idOrStrings as string | MessageDescriptor, rest[0] as Record<string, unknown> | undefined)\n }\n\n let _localeRequestId = 0\n\n async function setLocale(newLocale: Locale): Promise<void> {\n if (!lazyLocaleLoading || !options.chunkLoader) {\n i18n.locale = newLocale\n locale.value = newLocale\n return\n }\n\n const splitRuntime = getSplitRuntimeModule()\n\n if (loadedLocalesSet.has(newLocale)) {\n // Already loaded, instant switch\n try {\n if (splitRuntime?.__switchLocale) {\n await splitRuntime.__switchLocale(newLocale)\n }\n } catch (e) {\n console.warn(`[fluenti] split runtime switch failed for locale \"${newLocale}\"`, e)\n }\n i18n.locale = newLocale\n locale.value = newLocale\n return\n }\n\n // Race-condition protection: track request ID\n const thisRequest = ++_localeRequestId\n isLoading.value = true\n try {\n const messages = resolveChunkMessages(await options.chunkLoader(newLocale))\n // Stale request — a newer setLocale call superseded this one\n if (thisRequest !== _localeRequestId) return\n // Intentional mutation: Vue's shallowReactive API requires in-place property assignment for reactivity\n catalogs[newLocale] = { ...catalogs[newLocale], ...messages }\n i18n.loadMessages(newLocale, messages)\n loadedLocalesSet.add(newLocale)\n loadedLocales.value = new Set(loadedLocalesSet)\n try {\n if (splitRuntime?.__switchLocale) {\n await splitRuntime.__switchLocale(newLocale)\n }\n } catch (e) {\n console.warn(`[fluenti] split runtime switch failed for locale \"${newLocale}\"`, e)\n }\n // Re-check after async __switchLocale — a newer setLocale() may have superseded this one\n if (thisRequest !== _localeRequestId) return\n i18n.locale = newLocale\n locale.value = newLocale\n } finally {\n if (thisRequest === _localeRequestId) {\n isLoading.value = false\n }\n }\n }\n\n function loadMessages(loc: Locale, messages: Messages): void {\n // Intentional mutation: Vue's shallowReactive API requires in-place property assignment for reactivity\n catalogs[loc] = { ...catalogs[loc], ...messages }\n i18n.loadMessages(loc, messages)\n loadedLocalesSet.add(loc)\n loadedLocales.value = new Set(loadedLocalesSet)\n }\n\n const _preloadInFlight = new Set<string>()\n\n function preloadLocale(loc: string): void {\n if (!lazyLocaleLoading || loadedLocalesSet.has(loc) || !options.chunkLoader || _preloadInFlight.has(loc)) return\n _preloadInFlight.add(loc)\n const splitRuntime = getSplitRuntimeModule()\n options.chunkLoader(loc).then(async (loaded) => {\n const messages = resolveChunkMessages(loaded)\n // Intentional mutation: Vue's shallowReactive API requires in-place property assignment for reactivity\n catalogs[loc] = { ...catalogs[loc], ...messages }\n i18n.loadMessages(loc, messages)\n loadedLocalesSet.add(loc)\n loadedLocales.value = new Set(loadedLocalesSet)\n if (splitRuntime?.__preloadLocale) {\n await splitRuntime.__preloadLocale(loc)\n }\n }).catch((e: unknown) => {\n console.warn('[fluenti] preload failed:', loc, e)\n }).finally(() => {\n _preloadInFlight.delete(loc)\n })\n }\n\n function getLocales(): Locale[] {\n syncLocale()\n return i18n.getLocales()\n }\n\n function d(value: Date | number, style?: string): LocalizedString {\n // Read locale.value to register a Vue reactive dependency\n void locale.value\n syncLocale()\n return i18n.d(value, style)\n }\n\n function n(value: number, style?: string): LocalizedString {\n // Read locale.value to register a Vue reactive dependency\n void locale.value\n syncLocale()\n return i18n.n(value, style)\n }\n\n function format(message: string, values?: Record<string, unknown>): LocalizedString {\n // Read locale.value to register a Vue reactive dependency\n void locale.value\n syncLocale()\n return i18n.format(message, values)\n }\n\n /**\n * Rich text helper for v-t with child elements.\n * Translates the message (which contains `<0>content</0>` placeholders),\n * then replaces each placeholder with the original HTML element.\n * Used via `v-html=\"$vtRich('msg', elements)\"` in compile-time transforms.\n * @internal\n */\n function vtRich(\n message: string | MessageDescriptor,\n elements: Array<{ tag: string; attrs?: Record<string, string>; rawAttrs?: string }>,\n values?: Record<string, unknown>,\n ): string {\n const translated = values ? t(message, values) : t(message)\n // Escape the entire translated string first to neutralise any injected HTML\n const escaped = escapeHtml(translated)\n\n // Helper to build attribute string from element.\n // Both rawAttrs and attrs are escaped to prevent XSS — even though rawAttrs\n // originates from compile-time transforms, $vtRich is exposed on globalProperties\n // so we apply defence-in-depth.\n function buildAttrs(el: { attrs?: Record<string, string>; rawAttrs?: string }): string {\n if (el.rawAttrs != null && el.rawAttrs !== '') {\n // Parse rawAttrs back into key/value pairs and escape each one.\n // Handles: key=\"val\", key='val', and bare key (boolean attribute).\n const parts: string[] = []\n const attrRe = /([\\w:@.!-]+)(?:\\s*=\\s*(?:\"([^\"]*)\"|'([^']*)'))?/g\n let m: RegExpExecArray | null\n while ((m = attrRe.exec(el.rawAttrs)) !== null) {\n const key = escapeHtml(m[1]!)\n const val = m[2] ?? m[3]\n parts.push(val !== undefined ? `${key}=\"${escapeHtml(val)}\"` : key)\n }\n return parts.join(' ')\n }\n if (!el.attrs) return ''\n return Object.entries(el.attrs)\n .map(([k, v]) => v ? `${escapeHtml(k)}=\"${escapeHtml(v)}\"` : escapeHtml(k))\n .join(' ')\n }\n\n // First: handle self-closing <idx/> (escaped as &lt;idx/&gt;)\n let result = escaped.replace(/&lt;(\\d+)\\/&gt;/g, (_match, idxStr: string) => {\n const el = elements[Number(idxStr)]\n if (!el) return ''\n const tag = escapeHtml(el.tag)\n const attrs = buildAttrs(el)\n return `<${tag}${attrs ? ' ' + attrs : ''} />`\n })\n\n // Then: handle paired <idx>content</idx>\n result = result.replace(/&lt;(\\d+)&gt;([\\s\\S]*?)&lt;\\/\\1&gt;/g, (_match, idxStr: string, content: string) => {\n const el = elements[Number(idxStr)]\n if (!el) return content\n const tag = escapeHtml(el.tag)\n const attrs = buildAttrs(el)\n return `<${tag}${attrs ? ' ' + attrs : ''}>${content}</${tag}>`\n })\n\n return result\n }\n\n function te(key: string, loc?: string): boolean {\n const targetLocale = loc ?? locale.value\n return lookup(targetLocale, key) !== undefined\n }\n\n function tm(key: string, loc?: string): CompiledMessage | undefined {\n const targetLocale = loc ?? locale.value\n return lookup(targetLocale, key)\n }\n\n const context: FluentiContext = {\n t,\n locale,\n setLocale,\n loadMessages,\n getLocales,\n d,\n n,\n format,\n isLoading,\n loadedLocales,\n preloadLocale,\n te,\n tm,\n }\n\n return {\n install(app: App) {\n app.provide(FLUENTI_KEY, context)\n // Register components globally if provided via config\n if (options.components) {\n const prefix = options.componentPrefix ?? ''\n const comps = options.components as Record<string, unknown>\n if (comps['Trans']) app.component(`${prefix}Trans`, comps['Trans'] as any)\n if (comps['Plural']) app.component(`${prefix}Plural`, comps['Plural'] as any)\n if (comps['Select']) app.component(`${prefix}Select`, comps['Select'] as any)\n if (comps['DateTime']) app.component(`${prefix}DateTime`, comps['DateTime'] as any)\n if (comps['NumberFormat']) app.component(`${prefix}NumberFormat`, comps['NumberFormat'] as any)\n }\n if (options.injectGlobalProperties !== false) {\n app.config.globalProperties['$t'] = t\n app.config.globalProperties['$d'] = d\n app.config.globalProperties['$n'] = n\n app.config.globalProperties['$vtRich'] = vtRich\n }\n\n // Runtime v-t directive (fallback when compile-time transform is not used)\n const vtOriginalIds = new WeakMap<HTMLElement, string>()\n app.directive('t', {\n mounted(el, binding) {\n const attrName = getModifierAttr(binding.modifiers)\n if (attrName) {\n // v-t.alt, v-t.placeholder, etc. — translate the attribute\n const original = el.getAttribute(attrName) ?? ''\n vtOriginalIds.set(el, original)\n el.setAttribute(attrName, t(original))\n } else {\n // v-t or v-t:id — translate text content\n const id = binding.arg ?? el.textContent ?? ''\n vtOriginalIds.set(el, id.trim())\n el.textContent = t(id.trim(), binding.value != null ? { ...binding.value } : undefined)\n }\n },\n updated(el, binding) {\n const attrName = getModifierAttr(binding.modifiers)\n if (attrName) {\n const original = vtOriginalIds.get(el) ?? el.getAttribute(attrName) ?? ''\n el.setAttribute(attrName, t(original))\n } else {\n const id = binding.arg ?? vtOriginalIds.get(el) ?? ''\n el.textContent = t(id.trim(), binding.value != null ? { ...binding.value } : undefined)\n }\n },\n })\n },\n global: context,\n }\n}\n","import type { CompileTimeT } from '@fluenti/core'\n\nexport const t: CompileTimeT = ((..._args: unknown[]) => {\n throw new Error(\n \"[fluenti] `t` imported from '@fluenti/vue' is a compile-time API. \" +\n 'Use it only with the Fluenti build transform inside <script setup> or setup(). ' +\n 'For runtime lookups, use useI18n().t(...).',\n )\n}) as CompileTimeT\n"],"mappings":"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"}
1
+ {"version":3,"file":"index.js","names":[],"sources":["../src/plugin.ts","../src/compile-time-t.ts"],"sourcesContent":["import { type App, type Ref, ref, shallowReactive } from 'vue'\nimport type { AllMessages, Locale, LocalizedString, Messages, CompiledMessage, MessageDescriptor, DiagnosticsConfig, CustomFormatter } from '@fluenti/core'\nimport { createFluentiCore } from '@fluenti/core'\nimport { FLUENTI_KEY } from './injection-key'\n// Components are in @fluenti/vue/components subpath.\n// Global component registration is opt-in via `components` config option.\n\n/** Escape HTML special characters to prevent XSS. @internal */\nfunction escapeHtml(str: string): string {\n return str.replace(/&/g, '&amp;').replace(/\"/g, '&quot;').replace(/'/g, '&#39;').replace(/</g, '&lt;').replace(/>/g, '&gt;')\n}\n\n/** Compiled message chunk loader for lazy locale loading */\nexport type ChunkLoader = (\n locale: string,\n) => Promise<Record<string, CompiledMessage> | { default: Record<string, CompiledMessage> }>\n\ninterface SplitRuntimeModule {\n __switchLocale?: (locale: string) => Promise<void>\n __preloadLocale?: (locale: string) => Promise<void>\n}\n\nconst SPLIT_RUNTIME_KEY = Symbol.for('fluenti.runtime.vue.v1')\n\nfunction getSplitRuntimeModule(): SplitRuntimeModule | null {\n const runtime = (globalThis as Record<PropertyKey, unknown>)[SPLIT_RUNTIME_KEY]\n return typeof runtime === 'object' && runtime !== null\n ? runtime as SplitRuntimeModule\n : null\n}\n\nfunction resolveChunkMessages(\n loaded: Record<string, CompiledMessage> | { default: Record<string, CompiledMessage> },\n): Record<string, CompiledMessage> {\n return typeof loaded === 'object' && loaded !== null && 'default' in loaded\n ? (loaded as { default: Record<string, CompiledMessage> }).default\n : loaded\n}\n\n/** Context object returned by `useI18n()` and available as `$t` etc. on globalProperties */\nexport interface FluentiContext {\n /** Translate a message by id or MessageDescriptor, with optional interpolation values */\n t(id: string | MessageDescriptor, values?: Record<string, unknown>): LocalizedString\n /** Tagged template form: t`Hello ${name}` */\n t(strings: TemplateStringsArray, ...exprs: unknown[]): LocalizedString\n /** Reactive ref for current locale */\n locale: Readonly<Ref<Locale>>\n /** Change the active locale (async when lazy locale loading is enabled) */\n setLocale(locale: Locale): Promise<void>\n /** Dynamically load messages for a locale */\n loadMessages(locale: Locale, messages: Messages): void\n /** Get all locales that have loaded messages */\n getLocales(): Locale[]\n /** Format a date value according to locale */\n d(value: Date | number, style?: string): LocalizedString\n /** Format a number according to locale */\n n(value: number, style?: string): LocalizedString\n /** Format an ICU message string directly (no catalog lookup) */\n format(message: string, values?: Record<string, unknown>): LocalizedString\n /** Whether a locale chunk is currently being loaded */\n isLoading: Readonly<Ref<boolean>>\n /** Set of locales whose messages have been loaded */\n loadedLocales: Readonly<Ref<ReadonlySet<string>>>\n /** Preload a locale in the background without switching to it */\n preloadLocale(locale: string): void\n /** Check if a translation key exists in the catalog */\n te(key: string, locale?: string): boolean\n /** Get the raw compiled message without interpolation */\n tm(key: string, locale?: string): CompiledMessage | undefined\n}\n\n/** Injection key for providing/injecting fluenti context */\nexport { FLUENTI_KEY } from './injection-key'\n\n/** Options for creating the Fluenti Vue plugin */\nexport interface FluentiConfig {\n locale: string\n fallbackLocale?: string\n messages: AllMessages\n missing?: (locale: string, id: string) => string | undefined\n dateFormats?: Record<string, Intl.DateTimeFormatOptions | 'relative'>\n numberFormats?: Record<string, Intl.NumberFormatOptions | ((locale: string) => Intl.NumberFormatOptions)>\n fallbackChain?: Record<string, string[]>\n /** Async chunk loader for lazy locale loading */\n chunkLoader?: ChunkLoader\n /** Enable lazy locale loading through chunkLoader */\n lazyLocaleLoading?: boolean\n /**\n * Prefix for globally registered components (Trans, Plural, Select).\n *\n * Set this to avoid naming conflicts with other libraries.\n *\n * @example\n * componentPrefix: 'I18n'\n * // Registers: I18nTrans, I18nPlural, I18nSelect\n *\n * @example\n * componentPrefix: 'Fluenti'\n * // Registers: FluentiTrans, FluentiPlural, FluentiSelect\n *\n * @default '' (no prefix — Trans, Plural, Select)\n */\n componentPrefix?: string\n /**\n * Whether to inject `$t`, `$d`, `$n`, `$vtRich` onto `app.config.globalProperties`.\n *\n * Set to `false` to avoid polluting the global namespace (e.g. when migrating from vue-i18n\n * or when using composition API exclusively via `useI18n()`).\n *\n * @default true\n */\n injectGlobalProperties?: boolean\n /** Runtime diagnostics configuration or pre-created instance */\n diagnostics?: DiagnosticsConfig | { missingKey: (locale: string, id: string) => void; fallbackUsed: (locale: string, fallbackLocale: string, id: string) => void; enabled: boolean }\n /**\n * Custom message interpolation function.\n *\n * By default, the runtime uses a lightweight `{key}` replacer.\n * Pass the full `interpolate` from `@fluenti/core/internal` for\n * runtime ICU MessageFormat parsing (adds ~2.5 KB gzip).\n *\n * @example\n * ```ts\n * import { interpolate } from '@fluenti/core/internal'\n * createFluenti({ interpolate, ... })\n * ```\n */\n interpolate?: (\n message: string,\n values: Record<string, unknown> | undefined,\n locale: string,\n formatters?: Record<string, CustomFormatter>,\n ) => string\n /**\n * Components to register globally via `app.component()`.\n *\n * Import from `@fluenti/vue/components` and pass here to enable global\n * component registration without bloating the default bundle.\n *\n * @example\n * ```ts\n * import * as components from '@fluenti/vue/components'\n * app.use(createFluenti({ components, ... }))\n * ```\n */\n components?: Record<string, unknown>\n}\n\n/** Return value of `createFluenti()` */\nexport interface FluentiPlugin {\n /** Vue plugin install method */\n install(app: App): void\n /** The global fluenti context (same as what useI18n returns) */\n global: FluentiContext\n}\n\n/** Extract the attribute name from v-t modifiers (e.g., v-t.alt → 'alt') */\nfunction getModifierAttr(modifiers: Partial<Record<string, boolean>>): string | undefined {\n const keys = Object.keys(modifiers).filter((k) => k !== 'plural')\n return keys.length > 0 ? keys[0] : undefined\n}\n\n/**\n * Create a Fluenti Vue plugin (SSR-safe, per-request instance).\n *\n * Each invocation creates entirely fresh state — no module-level singletons —\n * so it is safe to call once per SSR request.\n *\n * @example\n * ```ts\n * import { createFluenti } from '@fluenti/vue'\n * import messages from './locales/compiled/en.js'\n *\n * const fluenti = createFluenti({\n * locale: 'en',\n * messages: { en: messages },\n * })\n *\n * app.use(fluenti)\n * ```\n */\nexport function createFluenti(options: FluentiConfig): FluentiPlugin {\n const lazyLocaleLoading = options.lazyLocaleLoading\n ?? (options as FluentiConfig & { splitting?: boolean }).splitting\n ?? false\n\n // Create the core i18n instance — delegates t/d/n/format/loadMessages/getLocales\n // Build config incrementally to satisfy exactOptionalPropertyTypes —\n // optional properties must not receive `undefined` as a value.\n const coreConfig: Parameters<typeof createFluentiCore>[0] = {\n locale: options.locale,\n messages: options.messages ?? {},\n }\n if (options.fallbackLocale !== undefined) coreConfig.fallbackLocale = options.fallbackLocale\n if (options.fallbackChain !== undefined) coreConfig.fallbackChain = options.fallbackChain\n if (options.dateFormats !== undefined) coreConfig.dateFormats = options.dateFormats\n if (options.numberFormats !== undefined) coreConfig.numberFormats = options.numberFormats\n if (options.missing !== undefined) coreConfig.missing = options.missing\n if (options.diagnostics !== undefined) coreConfig.diagnostics = options.diagnostics as Parameters<typeof createFluentiCore>[0]['diagnostics']\n if (options.interpolate !== undefined) coreConfig.interpolate = options.interpolate\n coreConfig.devWarnings = coreConfig.devWarnings ?? (typeof process !== 'undefined' && process.env?.['NODE_ENV'] === 'development')\n const i18n = createFluentiCore(coreConfig)\n\n const locale = ref(options.locale)\n // Intentional mutation: Vue's shallowReactive API requires in-place property assignment for reactivity\n const catalogs = shallowReactive<AllMessages>({ ...options.messages })\n const isLoading = ref(false)\n const loadedLocalesSet = new Set<string>([options.locale])\n const loadedLocales = ref<ReadonlySet<string>>(new Set(loadedLocalesSet))\n\n /** Local catalog lookup for te/tm (core doesn't expose raw catalog access) */\n function lookup(\n loc: Locale,\n id: string,\n ): CompiledMessage | undefined {\n const msgs = catalogs[loc]\n if (!msgs) return undefined\n return msgs[id]\n }\n\n /** Sync Vue reactive locale to core before delegation */\n function syncLocale(): void {\n if (i18n.locale !== locale.value) {\n i18n.locale = locale.value\n }\n }\n\n function t(strings: TemplateStringsArray, ...exprs: unknown[]): LocalizedString\n function t(id: string | MessageDescriptor, values?: Record<string, unknown>): LocalizedString\n function t(idOrStrings: string | MessageDescriptor | TemplateStringsArray, ...rest: unknown[]): LocalizedString {\n // Read locale.value and catalogs to register Vue reactive dependencies\n // so components re-render when locale or messages change\n const currentLocale = locale.value\n void catalogs[currentLocale]\n syncLocale()\n // Dispatch to the correct overload based on input type\n if (Array.isArray(idOrStrings) && 'raw' in idOrStrings) {\n return i18n.t(idOrStrings as TemplateStringsArray, ...rest)\n }\n return i18n.t(idOrStrings as string | MessageDescriptor, rest[0] as Record<string, unknown> | undefined)\n }\n\n let _localeRequestId = 0\n\n async function setLocale(newLocale: Locale): Promise<void> {\n if (!lazyLocaleLoading || !options.chunkLoader) {\n i18n.locale = newLocale\n locale.value = newLocale\n return\n }\n\n const splitRuntime = getSplitRuntimeModule()\n\n if (loadedLocalesSet.has(newLocale)) {\n // Already loaded, instant switch\n try {\n if (splitRuntime?.__switchLocale) {\n await splitRuntime.__switchLocale(newLocale)\n }\n } catch (e) {\n console.warn(`[fluenti] split runtime switch failed for locale \"${newLocale}\"`, e)\n }\n i18n.locale = newLocale\n locale.value = newLocale\n return\n }\n\n // Race-condition protection: track request ID\n const thisRequest = ++_localeRequestId\n isLoading.value = true\n try {\n const messages = resolveChunkMessages(await options.chunkLoader(newLocale))\n // Stale request — a newer setLocale call superseded this one\n if (thisRequest !== _localeRequestId) return\n // Intentional mutation: Vue's shallowReactive API requires in-place property assignment for reactivity\n catalogs[newLocale] = { ...catalogs[newLocale], ...messages }\n i18n.loadMessages(newLocale, messages)\n loadedLocalesSet.add(newLocale)\n loadedLocales.value = new Set(loadedLocalesSet)\n try {\n if (splitRuntime?.__switchLocale) {\n await splitRuntime.__switchLocale(newLocale)\n }\n } catch (e) {\n console.warn(`[fluenti] split runtime switch failed for locale \"${newLocale}\"`, e)\n }\n // Re-check after async __switchLocale — a newer setLocale() may have superseded this one\n if (thisRequest !== _localeRequestId) return\n i18n.locale = newLocale\n locale.value = newLocale\n } finally {\n if (thisRequest === _localeRequestId) {\n isLoading.value = false\n }\n }\n }\n\n function loadMessages(loc: Locale, messages: Messages): void {\n // Intentional mutation: Vue's shallowReactive API requires in-place property assignment for reactivity\n catalogs[loc] = { ...catalogs[loc], ...messages }\n i18n.loadMessages(loc, messages)\n loadedLocalesSet.add(loc)\n loadedLocales.value = new Set(loadedLocalesSet)\n }\n\n const _preloadInFlight = new Set<string>()\n\n function preloadLocale(loc: string): void {\n if (!lazyLocaleLoading || loadedLocalesSet.has(loc) || !options.chunkLoader || _preloadInFlight.has(loc)) return\n _preloadInFlight.add(loc)\n const splitRuntime = getSplitRuntimeModule()\n options.chunkLoader(loc).then(async (loaded) => {\n const messages = resolveChunkMessages(loaded)\n // Intentional mutation: Vue's shallowReactive API requires in-place property assignment for reactivity\n catalogs[loc] = { ...catalogs[loc], ...messages }\n i18n.loadMessages(loc, messages)\n loadedLocalesSet.add(loc)\n loadedLocales.value = new Set(loadedLocalesSet)\n if (splitRuntime?.__preloadLocale) {\n await splitRuntime.__preloadLocale(loc)\n }\n }).catch((e: unknown) => {\n console.warn('[fluenti] preload failed:', loc, e)\n }).finally(() => {\n _preloadInFlight.delete(loc)\n })\n }\n\n function getLocales(): Locale[] {\n syncLocale()\n return i18n.getLocales()\n }\n\n function d(value: Date | number, style?: string): LocalizedString {\n // Read locale.value to register a Vue reactive dependency\n void locale.value\n syncLocale()\n return i18n.d(value, style)\n }\n\n function n(value: number, style?: string): LocalizedString {\n // Read locale.value to register a Vue reactive dependency\n void locale.value\n syncLocale()\n return i18n.n(value, style)\n }\n\n function format(message: string, values?: Record<string, unknown>): LocalizedString {\n // Read locale.value to register a Vue reactive dependency\n void locale.value\n syncLocale()\n return i18n.format(message, values)\n }\n\n /**\n * Rich text helper for v-t with child elements.\n * Translates the message (which contains `<0>content</0>` placeholders),\n * then replaces each placeholder with the original HTML element.\n * Used via `v-html=\"$vtRich('msg', elements)\"` in compile-time transforms.\n * @internal\n */\n function vtRich(\n message: string | MessageDescriptor,\n elements: Array<{ tag: string; attrs?: Record<string, string>; rawAttrs?: string }>,\n values?: Record<string, unknown>,\n ): string {\n const translated = values ? t(message, values) : t(message)\n // Escape the entire translated string first to neutralise any injected HTML\n const escaped = escapeHtml(translated)\n\n // Helper to build attribute string from element.\n // Both rawAttrs and attrs are escaped to prevent XSS — even though rawAttrs\n // originates from compile-time transforms, $vtRich is exposed on globalProperties\n // so we apply defence-in-depth.\n function buildAttrs(el: { attrs?: Record<string, string>; rawAttrs?: string }): string {\n if (el.rawAttrs != null && el.rawAttrs !== '') {\n // Parse rawAttrs back into key/value pairs and escape each one.\n // Handles: key=\"val\", key='val', and bare key (boolean attribute).\n const parts: string[] = []\n const attrRe = /([\\w:@.!-]+)(?:\\s*=\\s*(?:\"([^\"]*)\"|'([^']*)'))?/g\n let m: RegExpExecArray | null\n while ((m = attrRe.exec(el.rawAttrs)) !== null) {\n const key = escapeHtml(m[1]!)\n const val = m[2] ?? m[3]\n parts.push(val !== undefined ? `${key}=\"${escapeHtml(val)}\"` : key)\n }\n return parts.join(' ')\n }\n if (!el.attrs) return ''\n return Object.entries(el.attrs)\n .map(([k, v]) => v ? `${escapeHtml(k)}=\"${escapeHtml(v)}\"` : escapeHtml(k))\n .join(' ')\n }\n\n // First: handle self-closing <idx/> (escaped as &lt;idx/&gt;)\n let result = escaped.replace(/&lt;(\\d+)\\/&gt;/g, (_match, idxStr: string) => {\n const el = elements[Number(idxStr)]\n if (!el) return ''\n const tag = escapeHtml(el.tag)\n const attrs = buildAttrs(el)\n return `<${tag}${attrs ? ' ' + attrs : ''} />`\n })\n\n // Then: handle paired <idx>content</idx>\n result = result.replace(/&lt;(\\d+)&gt;([\\s\\S]*?)&lt;\\/\\1&gt;/g, (_match, idxStr: string, content: string) => {\n const el = elements[Number(idxStr)]\n if (!el) return content\n const tag = escapeHtml(el.tag)\n const attrs = buildAttrs(el)\n return `<${tag}${attrs ? ' ' + attrs : ''}>${content}</${tag}>`\n })\n\n return result\n }\n\n function te(key: string, loc?: string): boolean {\n const targetLocale = loc ?? locale.value\n return lookup(targetLocale, key) !== undefined\n }\n\n function tm(key: string, loc?: string): CompiledMessage | undefined {\n const targetLocale = loc ?? locale.value\n return lookup(targetLocale, key)\n }\n\n const context: FluentiContext = {\n t,\n locale,\n setLocale,\n loadMessages,\n getLocales,\n d,\n n,\n format,\n isLoading,\n loadedLocales,\n preloadLocale,\n te,\n tm,\n }\n\n return {\n install(app: App) {\n app.provide(FLUENTI_KEY, context)\n // Register components globally if provided via config\n if (options.components) {\n const prefix = options.componentPrefix ?? ''\n const comps = options.components as Record<string, unknown>\n if (comps['Trans']) app.component(`${prefix}Trans`, comps['Trans'] as any)\n if (comps['Plural']) app.component(`${prefix}Plural`, comps['Plural'] as any)\n if (comps['Select']) app.component(`${prefix}Select`, comps['Select'] as any)\n if (comps['DateTime']) app.component(`${prefix}DateTime`, comps['DateTime'] as any)\n if (comps['NumberFormat']) app.component(`${prefix}NumberFormat`, comps['NumberFormat'] as any)\n }\n if (options.injectGlobalProperties !== false) {\n app.config.globalProperties['$t'] = t\n app.config.globalProperties['$d'] = d\n app.config.globalProperties['$n'] = n\n app.config.globalProperties['$vtRich'] = vtRich\n }\n\n // Runtime v-t directive (fallback when compile-time transform is not used)\n const vtOriginalIds = new WeakMap<HTMLElement, string>()\n app.directive('t', {\n mounted(el, binding) {\n const attrName = getModifierAttr(binding.modifiers)\n if (attrName) {\n // v-t.alt, v-t.placeholder, etc. — translate the attribute\n const original = el.getAttribute(attrName) ?? ''\n vtOriginalIds.set(el, original)\n el.setAttribute(attrName, t(original))\n } else {\n // v-t or v-t:id — translate text content\n const id = binding.arg ?? el.textContent ?? ''\n vtOriginalIds.set(el, id.trim())\n el.textContent = t(id.trim(), binding.value != null ? { ...binding.value } : undefined)\n }\n },\n updated(el, binding) {\n const attrName = getModifierAttr(binding.modifiers)\n if (attrName) {\n const original = vtOriginalIds.get(el) ?? el.getAttribute(attrName) ?? ''\n el.setAttribute(attrName, t(original))\n } else {\n const id = binding.arg ?? vtOriginalIds.get(el) ?? ''\n el.textContent = t(id.trim(), binding.value != null ? { ...binding.value } : undefined)\n }\n },\n })\n },\n global: context,\n }\n}\n","import type { CompileTimeT } from '@fluenti/core'\n\nexport const t: CompileTimeT = ((..._args: unknown[]) => {\n throw new Error(\n \"[fluenti] `t` imported from '@fluenti/vue' is a compile-time API. \" +\n 'Use it only with the Fluenti build transform inside <script setup> or setup(). ' +\n 'For runtime lookups, use useI18n().t(...).',\n )\n}) as CompileTimeT\n"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"plugin.d.ts","sourceRoot":"","sources":["../src/plugin.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"plugin.d.ts","sourceRoot":"","sources":["../src/plugin.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,GAAG,EAAE,KAAK,GAAG,EAAwB,MAAM,KAAK,CAAA;AAC9D,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,EAAE,eAAe,EAAE,QAAQ,EAAE,eAAe,EAAE,iBAAiB,EAAE,iBAAiB,EAAE,eAAe,EAAE,MAAM,eAAe,CAAA;AAW3J,4DAA4D;AAC5D,MAAM,MAAM,WAAW,GAAG,CACxB,MAAM,EAAE,MAAM,KACX,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,eAAe,CAAC,GAAG;IAAE,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,eAAe,CAAC,CAAA;CAAE,CAAC,CAAA;AAwB5F,4FAA4F;AAC5F,MAAM,WAAW,cAAc;IAC7B,yFAAyF;IACzF,CAAC,CAAC,EAAE,EAAE,MAAM,GAAG,iBAAiB,EAAE,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,eAAe,CAAA;IACpF,6CAA6C;IAC7C,CAAC,CAAC,OAAO,EAAE,oBAAoB,EAAE,GAAG,KAAK,EAAE,OAAO,EAAE,GAAG,eAAe,CAAA;IACtE,sCAAsC;IACtC,MAAM,EAAE,QAAQ,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,CAAA;IAC7B,2EAA2E;IAC3E,SAAS,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAA;IACxC,6CAA6C;IAC7C,YAAY,CAAC,MAAM,EAAE,MAAM,EAAE,QAAQ,EAAE,QAAQ,GAAG,IAAI,CAAA;IACtD,gDAAgD;IAChD,UAAU,IAAI,MAAM,EAAE,CAAA;IACtB,8CAA8C;IAC9C,CAAC,CAAC,KAAK,EAAE,IAAI,GAAG,MAAM,EAAE,KAAK,CAAC,EAAE,MAAM,GAAG,eAAe,CAAA;IACxD,0CAA0C;IAC1C,CAAC,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,MAAM,GAAG,eAAe,CAAA;IACjD,gEAAgE;IAChE,MAAM,CAAC,OAAO,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,eAAe,CAAA;IAC1E,uDAAuD;IACvD,SAAS,EAAE,QAAQ,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAA;IACjC,qDAAqD;IACrD,aAAa,EAAE,QAAQ,CAAC,GAAG,CAAC,WAAW,CAAC,MAAM,CAAC,CAAC,CAAC,CAAA;IACjD,iEAAiE;IACjE,aAAa,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI,CAAA;IACnC,uDAAuD;IACvD,EAAE,CAAC,GAAG,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,MAAM,GAAG,OAAO,CAAA;IACzC,yDAAyD;IACzD,EAAE,CAAC,GAAG,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,MAAM,GAAG,eAAe,GAAG,SAAS,CAAA;CAC9D;AAED,4DAA4D;AAC5D,OAAO,EAAE,WAAW,EAAE,MAAM,iBAAiB,CAAA;AAE7C,kDAAkD;AAClD,MAAM,WAAW,aAAa;IAC5B,MAAM,EAAE,MAAM,CAAA;IACd,cAAc,CAAC,EAAE,MAAM,CAAA;IACvB,QAAQ,EAAE,WAAW,CAAA;IACrB,OAAO,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,KAAK,MAAM,GAAG,SAAS,CAAA;IAC5D,WAAW,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,IAAI,CAAC,qBAAqB,GAAG,UAAU,CAAC,CAAA;IACrE,aAAa,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,IAAI,CAAC,mBAAmB,GAAG,CAAC,CAAC,MAAM,EAAE,MAAM,KAAK,IAAI,CAAC,mBAAmB,CAAC,CAAC,CAAA;IACzG,aAAa,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,EAAE,CAAC,CAAA;IACxC,iDAAiD;IACjD,WAAW,CAAC,EAAE,WAAW,CAAA;IACzB,qDAAqD;IACrD,iBAAiB,CAAC,EAAE,OAAO,CAAA;IAC3B;;;;;;;;;;;;;;OAcG;IACH,eAAe,CAAC,EAAE,MAAM,CAAA;IACxB;;;;;;;OAOG;IACH,sBAAsB,CAAC,EAAE,OAAO,CAAA;IAChC,gEAAgE;IAChE,WAAW,CAAC,EAAE,iBAAiB,GAAG;QAAE,UAAU,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,KAAK,IAAI,CAAC;QAAC,YAAY,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,cAAc,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,KAAK,IAAI,CAAC;QAAC,OAAO,EAAE,OAAO,CAAA;KAAE,CAAA;IACpL;;;;;;;;;;;;OAYG;IACH,WAAW,CAAC,EAAE,CACZ,OAAO,EAAE,MAAM,EACf,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,SAAS,EAC3C,MAAM,EAAE,MAAM,EACd,UAAU,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,eAAe,CAAC,KACzC,MAAM,CAAA;IACX;;;;;;;;;;;OAWG;IACH,UAAU,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;CACrC;AAED,wCAAwC;AACxC,MAAM,WAAW,aAAa;IAC5B,gCAAgC;IAChC,OAAO,CAAC,GAAG,EAAE,GAAG,GAAG,IAAI,CAAA;IACvB,gEAAgE;IAChE,MAAM,EAAE,cAAc,CAAA;CACvB;AAQD;;;;;;;;;;;;;;;;;;GAkBG;AACH,wBAAgB,aAAa,CAAC,OAAO,EAAE,aAAa,GAAG,aAAa,CAuTnE"}
@@ -0,0 +1,2 @@
1
+ let e=require(`vue`);var t=Symbol(`fluenti`);function n(){let n=(0,e.inject)(t);if(!n)throw Error(`[fluenti] useI18n() requires createFluenti plugin`);return n}function r(){return n().locale}Object.defineProperty(exports,`n`,{enumerable:!0,get:function(){return r}}),Object.defineProperty(exports,`r`,{enumerable:!0,get:function(){return t}}),Object.defineProperty(exports,`t`,{enumerable:!0,get:function(){return n}});
2
+ //# sourceMappingURL=use-i18n-D6iu0pGX.cjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"use-i18n-CQQp9bxG.cjs","names":[],"sources":["../src/injection-key.ts","../src/use-i18n.ts"],"sourcesContent":["import type { InjectionKey } from 'vue'\nimport type { FluentiContext } from './plugin'\n\n/** Injection key for the Fluenti i18n context. @internal */\nexport const FLUENTI_KEY: InjectionKey<FluentiContext> = Symbol('fluenti')\n","import { inject } from 'vue'\nimport { FLUENTI_KEY } from './injection-key'\nimport type { FluentiContext } from './plugin'\n\n/**\n * Composable that returns the Fluenti i18n context.\n *\n * Must be called inside a component whose ancestor app has installed the\n * `createFluenti()` plugin.\n *\n * @throws If the plugin has not been installed\n *\n * @example\n * ```vue\n * <template>\n * <!-- Preferred: v-t directive (compile-time, zero runtime cost) -->\n * <h1 v-t>Welcome to our app</h1>\n * <p v-t>Hello, {name}!</p>\n *\n * <!-- Alternative: tagged template in script -->\n * <p>{{ greeting }}</p>\n * </template>\n *\n * <script setup>\n * import { useI18n } from '@fluenti/vue'\n * const { t, locale, setLocale } = useI18n()\n * const greeting = t`Hello, {name}!`\n * </script>\n * ```\n */\nexport function useI18n(): FluentiContext {\n const ctx = inject(FLUENTI_KEY)\n if (!ctx) {\n throw new Error('[fluenti] useI18n() requires createFluenti plugin')\n }\n return ctx\n}\n"],"mappings":"qBAIA,IAAa,EAA4C,OAAO,UAAU,CC0B1E,SAAgB,GAA0B,CACxC,IAAM,GAAA,EAAA,EAAA,QAAa,EAAY,CAC/B,GAAI,CAAC,EACH,MAAU,MAAM,oDAAoD,CAEtE,OAAO"}
1
+ {"version":3,"file":"use-i18n-D6iu0pGX.cjs","names":[],"sources":["../src/injection-key.ts","../src/use-i18n.ts"],"sourcesContent":["import type { InjectionKey } from 'vue'\nimport type { FluentiContext } from './plugin'\n\n/** Injection key for the Fluenti i18n context. @internal */\nexport const FLUENTI_KEY: InjectionKey<FluentiContext> = Symbol('fluenti')\n","import { inject } from 'vue'\nimport { FLUENTI_KEY } from './injection-key'\nimport type { FluentiContext } from './plugin'\n\n/**\n * Composable that returns the Fluenti i18n context.\n *\n * Must be called inside a component whose ancestor app has installed the\n * `createFluenti()` plugin.\n *\n * @throws If the plugin has not been installed\n *\n * @example\n * ```vue\n * <template>\n * <!-- Preferred: v-t directive (compile-time, zero runtime cost) -->\n * <h1 v-t>Welcome to our app</h1>\n * <p v-t>Hello, {name}!</p>\n *\n * <!-- Alternative: tagged template in script -->\n * <p>{{ greeting }}</p>\n * </template>\n *\n * <script setup>\n * import { useI18n } from '@fluenti/vue'\n * const { t, locale, setLocale } = useI18n()\n * const greeting = t`Hello, {name}!`\n * </script>\n * ```\n */\nexport function useI18n(): FluentiContext {\n const ctx = inject(FLUENTI_KEY)\n if (!ctx) {\n throw new Error('[fluenti] useI18n() requires createFluenti plugin')\n }\n return ctx\n}\n\n/** Shorthand composable that returns only the reactive locale ref. */\nexport function useLocale() {\n return useI18n().locale\n}\n"],"mappings":"qBAIA,IAAa,EAA4C,OAAO,UAAU,CC0B1E,SAAgB,GAA0B,CACxC,IAAM,GAAA,EAAA,EAAA,QAAa,EAAY,CAC/B,GAAI,CAAC,EACH,MAAU,MAAM,oDAAoD,CAEtE,OAAO,EAIT,SAAgB,GAAY,CAC1B,OAAO,GAAS,CAAC"}
@@ -8,7 +8,10 @@ function n() {
8
8
  if (!n) throw Error("[fluenti] useI18n() requires createFluenti plugin");
9
9
  return n;
10
10
  }
11
+ function r() {
12
+ return n().locale;
13
+ }
11
14
  //#endregion
12
- export { t as n, n as t };
15
+ export { r as n, t as r, n as t };
13
16
 
14
- //# sourceMappingURL=use-i18n-DrhdlExQ.js.map
17
+ //# sourceMappingURL=use-i18n-DV-MXUZc.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"use-i18n-DrhdlExQ.js","names":[],"sources":["../src/injection-key.ts","../src/use-i18n.ts"],"sourcesContent":["import type { InjectionKey } from 'vue'\nimport type { FluentiContext } from './plugin'\n\n/** Injection key for the Fluenti i18n context. @internal */\nexport const FLUENTI_KEY: InjectionKey<FluentiContext> = Symbol('fluenti')\n","import { inject } from 'vue'\nimport { FLUENTI_KEY } from './injection-key'\nimport type { FluentiContext } from './plugin'\n\n/**\n * Composable that returns the Fluenti i18n context.\n *\n * Must be called inside a component whose ancestor app has installed the\n * `createFluenti()` plugin.\n *\n * @throws If the plugin has not been installed\n *\n * @example\n * ```vue\n * <template>\n * <!-- Preferred: v-t directive (compile-time, zero runtime cost) -->\n * <h1 v-t>Welcome to our app</h1>\n * <p v-t>Hello, {name}!</p>\n *\n * <!-- Alternative: tagged template in script -->\n * <p>{{ greeting }}</p>\n * </template>\n *\n * <script setup>\n * import { useI18n } from '@fluenti/vue'\n * const { t, locale, setLocale } = useI18n()\n * const greeting = t`Hello, {name}!`\n * </script>\n * ```\n */\nexport function useI18n(): FluentiContext {\n const ctx = inject(FLUENTI_KEY)\n if (!ctx) {\n throw new Error('[fluenti] useI18n() requires createFluenti plugin')\n }\n return ctx\n}\n"],"mappings":";;AAIA,IAAa,IAA4C,OAAO,UAAU;;;AC0B1E,SAAgB,IAA0B;CACxC,IAAM,IAAM,EAAO,EAAY;AAC/B,KAAI,CAAC,EACH,OAAU,MAAM,oDAAoD;AAEtE,QAAO"}
1
+ {"version":3,"file":"use-i18n-DV-MXUZc.js","names":[],"sources":["../src/injection-key.ts","../src/use-i18n.ts"],"sourcesContent":["import type { InjectionKey } from 'vue'\nimport type { FluentiContext } from './plugin'\n\n/** Injection key for the Fluenti i18n context. @internal */\nexport const FLUENTI_KEY: InjectionKey<FluentiContext> = Symbol('fluenti')\n","import { inject } from 'vue'\nimport { FLUENTI_KEY } from './injection-key'\nimport type { FluentiContext } from './plugin'\n\n/**\n * Composable that returns the Fluenti i18n context.\n *\n * Must be called inside a component whose ancestor app has installed the\n * `createFluenti()` plugin.\n *\n * @throws If the plugin has not been installed\n *\n * @example\n * ```vue\n * <template>\n * <!-- Preferred: v-t directive (compile-time, zero runtime cost) -->\n * <h1 v-t>Welcome to our app</h1>\n * <p v-t>Hello, {name}!</p>\n *\n * <!-- Alternative: tagged template in script -->\n * <p>{{ greeting }}</p>\n * </template>\n *\n * <script setup>\n * import { useI18n } from '@fluenti/vue'\n * const { t, locale, setLocale } = useI18n()\n * const greeting = t`Hello, {name}!`\n * </script>\n * ```\n */\nexport function useI18n(): FluentiContext {\n const ctx = inject(FLUENTI_KEY)\n if (!ctx) {\n throw new Error('[fluenti] useI18n() requires createFluenti plugin')\n }\n return ctx\n}\n\n/** Shorthand composable that returns only the reactive locale ref. */\nexport function useLocale() {\n return useI18n().locale\n}\n"],"mappings":";;AAIA,IAAa,IAA4C,OAAO,UAAU;;;AC0B1E,SAAgB,IAA0B;CACxC,IAAM,IAAM,EAAO,EAAY;AAC/B,KAAI,CAAC,EACH,OAAU,MAAM,oDAAoD;AAEtE,QAAO;;AAIT,SAAgB,IAAY;AAC1B,QAAO,GAAS,CAAC"}
@@ -26,4 +26,6 @@ import { FluentiContext } from './plugin';
26
26
  * ```
27
27
  */
28
28
  export declare function useI18n(): FluentiContext;
29
+ /** Shorthand composable that returns only the reactive locale ref. */
30
+ export declare function useLocale(): Readonly<import('vue').Ref<string, string>>;
29
31
  //# sourceMappingURL=use-i18n.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"use-i18n.d.ts","sourceRoot":"","sources":["../src/use-i18n.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,UAAU,CAAA;AAE9C;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AACH,wBAAgB,OAAO,IAAI,cAAc,CAMxC"}
1
+ {"version":3,"file":"use-i18n.d.ts","sourceRoot":"","sources":["../src/use-i18n.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,UAAU,CAAA;AAE9C;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AACH,wBAAgB,OAAO,IAAI,cAAc,CAMxC;AAED,sEAAsE;AACtE,wBAAgB,SAAS,gDAExB"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@fluenti/vue",
3
- "version": "0.4.0-rc.2",
3
+ "version": "0.4.0-rc.4",
4
4
  "type": "module",
5
5
  "description": "Vue 3 compile-time i18n — v-t directive, Trans/Plural/Select components, useI18n composable",
6
6
  "homepage": "https://fluenti.dev",
@@ -87,8 +87,8 @@
87
87
  }
88
88
  },
89
89
  "dependencies": {
90
- "@fluenti/core": "0.4.0-rc.2",
91
- "@fluenti/vite-plugin": "0.4.0-rc.2"
90
+ "@fluenti/core": "0.4.0-rc.4",
91
+ "@fluenti/vite-plugin": "0.4.0-rc.4"
92
92
  },
93
93
  "devDependencies": {
94
94
  "typescript": "^5.9",
@@ -1,2 +0,0 @@
1
- let e=require(`vue`);var t=Symbol(`fluenti`);function n(){let n=(0,e.inject)(t);if(!n)throw Error(`[fluenti] useI18n() requires createFluenti plugin`);return n}Object.defineProperty(exports,`n`,{enumerable:!0,get:function(){return t}}),Object.defineProperty(exports,`t`,{enumerable:!0,get:function(){return n}});
2
- //# sourceMappingURL=use-i18n-CQQp9bxG.cjs.map