@i18n-micro/core 1.1.2 → 1.1.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.
package/dist/base.d.ts CHANGED
@@ -6,12 +6,7 @@ export interface BaseI18nOptions {
6
6
  plural?: PluralFunc;
7
7
  missingWarn?: boolean;
8
8
  missingHandler?: (locale: string, key: string, routeName: string) => void;
9
- getPreviousPageInfo?: () => {
10
- locale: string;
11
- routeName: string;
12
- } | null;
13
9
  getCustomMissingHandler?: () => MissingHandler | null;
14
- enablePreviousPageFallback?: boolean;
15
10
  }
16
11
  /**
17
12
  * Abstract base class for i18n adapters
@@ -25,12 +20,7 @@ export declare abstract class BaseI18n {
25
20
  pluralFunc: PluralFunc;
26
21
  missingWarn: boolean;
27
22
  missingHandler?: (locale: string, key: string, routeName: string) => void;
28
- getPreviousPageInfo?: () => {
29
- locale: string;
30
- routeName: string;
31
- } | null;
32
23
  getCustomMissingHandler?: () => MissingHandler | null;
33
- enablePreviousPageFallback: boolean;
34
24
  constructor(options?: BaseI18nOptions);
35
25
  /**
36
26
  * Get current locale
package/dist/index.cjs CHANGED
@@ -1 +1 @@
1
- "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});class g{formatNumber(e,t,r){return new Intl.NumberFormat(t,r).format(e)}formatDate(e,t,r){const n=new Date(e);return Number.isNaN(n.getTime())?"Invalid Date":new Intl.DateTimeFormat(t,r).format(n)}formatRelativeTime(e,t,r){const n=new Date(e);if(Number.isNaN(n.getTime()))return new Intl.RelativeTimeFormat(t,r).format(0,"second");const i=Math.floor((new Date().getTime()-n.getTime())/1e3),o=[{unit:"year",seconds:31536e3},{unit:"month",seconds:2592e3},{unit:"day",seconds:86400},{unit:"hour",seconds:3600},{unit:"minute",seconds:60},{unit:"second",seconds:1}];for(const{unit:l,seconds:u}of o){const c=Math.floor(i/u);if(c>=1)return new Intl.RelativeTimeFormat(t,r).format(-c,l)}return new Intl.RelativeTimeFormat(t,r).format(0,"second")}}const p=/\{(\w+)\}/g;function h(s,e){return e?s.replace(p,(t,r)=>{const n=e[r];return n!==void 0?String(n):`{${r}}`}):s}function v(s){return s==="prefix"||s==="prefix_and_default"}function T(s){return s==="no_prefix"}function P(s){return s==="prefix"}function b(s){return s==="prefix_except_default"}function x(s){return s==="prefix_and_default"}const m=(s,e,t,r,n)=>{const a=n(s,t);if(!a)return null;const i=a.toString().split("|");if(i.length===0)return null;const o=e<i.length?i[e]:i[i.length-1];return o?o.trim().replace("{count}",e.toString()):null};function f(s,e){if(!s||typeof e!="string")return null;if(e in s){const n=s[e];return n}const t=e.split(".");let r=s;for(const n of t)if(r&&typeof r=="object"&&n in r)r=r[n];else return null;return r??null}function d(s){const e=s?.translations??new Map;return{hasCache(t,r){const n=`${t}:${r}`;return e.has(n)||e.has(t)},getCache(t,r){const n=`${t}:${r}`;return e.get(n)},setCache(t,r,n){},hasTranslation(t,r){for(const[n,a]of e)if((n===t||n.startsWith(`${t}:`))&&f(a,r)!==null)return!0;return!1},hasGeneralTranslation(t){return e.has(t)},hasPageTranslation(t,r){return e.has(`${t}:${r}`)},getTranslation(t,r,n){const a=`${t}:${r}`,i=e.get(a),o=f(i,n);if(o!==null)return o;const l=e.get(t);return f(l,n)},loadTranslations(t,r){const n=e.get(t)??{};e.set(t,{...n,...r})},setTranslations(t,r){e.set(t,r)},loadPageTranslations(t,r,n){const a=`${t}:${r}`,i=e.get(a);!i||Object.keys(i).length===0?e.set(a,n):e.set(a,{...i,...n})},mergeTranslation(t,r,n,a=!1){const i=`${t}:${r}`,o=e.get(i)??{};e.set(i,{...o,...n})},mergeGlobalTranslation(t,r,n=!1){const a=e.get(t)??{};e.set(t,{...a,...r})},clearCache(){e.clear()}}}class N{constructor(e={}){this.formatter=new g,this.helper=d(e.storage),this.formatter=new g,this.pluralFunc=e.plural||m,this.missingWarn=e.missingWarn??!0,this.missingHandler=e.missingHandler,this.getPreviousPageInfo=e.getPreviousPageInfo,this.getCustomMissingHandler=e.getCustomMissingHandler,this.enablePreviousPageFallback=e.enablePreviousPageFallback??!1}t(e,t,r,n){if(!e)return"";const a=this.getLocale(),i=n||this.getRoute();let o=this.helper.getTranslation(a,i,e);if(!o&&this.enablePreviousPageFallback&&this.getPreviousPageInfo){const l=this.getPreviousPageInfo();if(l){const u=this.helper.getTranslation(l.locale,l.routeName,e);u&&(o=u,process.env.NODE_ENV!=="production"&&console.log(`Using fallback translation from previous route: ${l.routeName} -> ${e}`))}}if(!o){const l=this.getFallbackLocale();a!==l&&(o=this.helper.getTranslation(l,i,e))}if(!o){const l=this.getCustomMissingHandler?.();l?l(a,e,i):this.missingHandler?this.missingHandler(a,e,i):this.missingWarn&&process.env.NODE_ENV!=="production"&&typeof window<"u"&&console.warn(`Not found '${e}' key in '${a}' locale messages for route '${i}'.`),o=r===void 0?e:r||e}return typeof o=="string"&&t?h(o,t):o}ts(e,t,r,n){return this.t(e,t,r,n)?.toString()??r??e}tc(e,t,r){const{count:n,...a}=typeof t=="number"?{count:t}:t;if(n===void 0)return r??e;const i=(l,u,c)=>this.t(l,u,c);return this.pluralFunc(e,Number.parseInt(n.toString(),10),a,this.getLocale(),i)??r??e}tn(e,t){return this.formatter.formatNumber(e,this.getLocale(),t)}td(e,t){return this.formatter.formatDate(e,this.getLocale(),t)}tdr(e,t){return this.formatter.formatRelativeTime(e,this.getLocale(),t)}has(e,t){const r=t||this.getRoute(),n=this.getLocale();return!!this.helper.getTranslation(n,r,e)}clearCache(){this.helper.clearCache()}loadTranslationsCore(e,t,r){r?this.helper.mergeGlobalTranslation(e,t,!0):this.helper.setTranslations(e,t)}loadRouteTranslationsCore(e,t,r,n){n?this.helper.mergeTranslation(e,t,r,!0):this.helper.loadPageTranslations(e,t,r)}}exports.BaseI18n=N;exports.FormatService=g;exports.defaultPlural=m;exports.interpolate=h;exports.isNoPrefixStrategy=T;exports.isPrefixAndDefaultStrategy=x;exports.isPrefixExceptDefaultStrategy=b;exports.isPrefixStrategy=P;exports.useTranslationHelper=d;exports.withPrefixStrategy=v;
1
+ "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});class g{formatNumber(t,e,r){return new Intl.NumberFormat(e,r).format(t)}formatDate(t,e,r){const n=new Date(t);return Number.isNaN(n.getTime())?"Invalid Date":new Intl.DateTimeFormat(e,r).format(n)}formatRelativeTime(t,e,r){const n=new Date(t);if(Number.isNaN(n.getTime()))return new Intl.RelativeTimeFormat(e,r).format(0,"second");const i=Math.floor((new Date().getTime()-n.getTime())/1e3),o=[{unit:"year",seconds:31536e3},{unit:"month",seconds:2592e3},{unit:"day",seconds:86400},{unit:"hour",seconds:3600},{unit:"minute",seconds:60},{unit:"second",seconds:1}];for(const{unit:l,seconds:c}of o){const u=Math.floor(i/c);if(u>=1)return new Intl.RelativeTimeFormat(e,r).format(-u,l)}return new Intl.RelativeTimeFormat(e,r).format(0,"second")}}const p=/\{(\w+)\}/g;function h(s,t){return t?s.replace(p,(e,r)=>{const n=t[r];return n!==void 0?String(n):`{${r}}`}):s}function T(s){return s==="prefix"||s==="prefix_and_default"}function v(s){return s==="no_prefix"}function x(s){return s==="prefix"}function S(s){return s==="prefix_except_default"}function w(s){return s==="prefix_and_default"}const m=(s,t,e,r,n)=>{const a=n(s,e);if(!a)return null;const i=a.toString().split("|");if(i.length===0)return null;const o=t<i.length?i[t]:i[i.length-1];return o?o.trim().replace("{count}",t.toString()):null};function f(s,t){if(!s||typeof t!="string")return null;if(t in s){const n=s[t];return n}const e=t.split(".");let r=s;for(const n of e)if(r&&typeof r=="object"&&n in r)r=r[n];else return null;return r??null}function d(s){const t=s?.translations??new Map;return{hasCache(e,r){const n=`${e}:${r}`;return t.has(n)||t.has(e)},getCache(e,r){const n=`${e}:${r}`;return t.get(n)},setCache(e,r,n){},hasTranslation(e,r){for(const[n,a]of t)if((n===e||n.startsWith(`${e}:`))&&f(a,r)!==null)return!0;return!1},hasGeneralTranslation(e){return t.has(e)},hasPageTranslation(e,r){return t.has(`${e}:${r}`)},getTranslation(e,r,n){const a=`${e}:${r}`,i=t.get(a),o=f(i,n);if(o!==null)return o;const l=t.get(e);return f(l,n)},loadTranslations(e,r){const n=t.get(e)??{};t.set(e,{...n,...r})},setTranslations(e,r){t.set(e,r)},loadPageTranslations(e,r,n){const a=`${e}:${r}`,i=t.get(a);!i||Object.keys(i).length===0?t.set(a,n):t.set(a,{...i,...n})},mergeTranslation(e,r,n,a=!1){const i=`${e}:${r}`,o=t.get(i)??{};t.set(i,{...o,...n})},mergeGlobalTranslation(e,r,n=!1){const a=t.get(e)??{};t.set(e,{...a,...r})},clearCache(){t.clear()}}}class ${constructor(t={}){this.formatter=new g,this.helper=d(t.storage),this.formatter=new g,this.pluralFunc=t.plural||m,this.missingWarn=t.missingWarn??!0,this.missingHandler=t.missingHandler,this.getCustomMissingHandler=t.getCustomMissingHandler}t(t,e,r,n){if(!t)return"";const a=this.getLocale(),i=n||this.getRoute();let o=this.helper.getTranslation(a,i,t);if(!o){const l=this.getFallbackLocale();a!==l&&(o=this.helper.getTranslation(l,i,t))}if(!o){const l=this.getCustomMissingHandler?.();l?l(a,t,i):this.missingHandler?this.missingHandler(a,t,i):this.missingWarn&&process.env.NODE_ENV!=="production"&&typeof window<"u"&&console.warn(`Not found '${t}' key in '${a}' locale messages for route '${i}'.`),o=r===void 0?t:r||t}return typeof o=="string"&&e?h(o,e):o}ts(t,e,r,n){return this.t(t,e,r,n)?.toString()??r??t}tc(t,e,r){const{count:n,...a}=typeof e=="number"?{count:e}:e;if(n===void 0)return r??t;const i=(l,c,u)=>this.t(l,c,u);return this.pluralFunc(t,Number.parseInt(n.toString(),10),a,this.getLocale(),i)??r??t}tn(t,e){return this.formatter.formatNumber(t,this.getLocale(),e)}td(t,e){return this.formatter.formatDate(t,this.getLocale(),e)}tdr(t,e){return this.formatter.formatRelativeTime(t,this.getLocale(),e)}has(t,e){const r=e||this.getRoute(),n=this.getLocale();return!!this.helper.getTranslation(n,r,t)}clearCache(){this.helper.clearCache()}loadTranslationsCore(t,e,r){r?this.helper.mergeGlobalTranslation(t,e,!0):this.helper.setTranslations(t,e)}loadRouteTranslationsCore(t,e,r,n){n?this.helper.mergeTranslation(t,e,r,!0):this.helper.loadPageTranslations(t,e,r)}}exports.BaseI18n=$;exports.FormatService=g;exports.defaultPlural=m;exports.interpolate=h;exports.isNoPrefixStrategy=v;exports.isPrefixAndDefaultStrategy=w;exports.isPrefixExceptDefaultStrategy=S;exports.isPrefixStrategy=x;exports.useTranslationHelper=d;exports.withPrefixStrategy=T;
package/dist/index.mjs CHANGED
@@ -1,15 +1,15 @@
1
- class g {
2
- formatNumber(e, t, n) {
3
- return new Intl.NumberFormat(t, n).format(e);
1
+ class h {
2
+ formatNumber(t, e, n) {
3
+ return new Intl.NumberFormat(e, n).format(t);
4
4
  }
5
- formatDate(e, t, n) {
6
- const r = new Date(e);
7
- return Number.isNaN(r.getTime()) ? "Invalid Date" : new Intl.DateTimeFormat(t, n).format(r);
5
+ formatDate(t, e, n) {
6
+ const r = new Date(t);
7
+ return Number.isNaN(r.getTime()) ? "Invalid Date" : new Intl.DateTimeFormat(e, n).format(r);
8
8
  }
9
- formatRelativeTime(e, t, n) {
10
- const r = new Date(e);
9
+ formatRelativeTime(t, e, n) {
10
+ const r = new Date(t);
11
11
  if (Number.isNaN(r.getTime()))
12
- return new Intl.RelativeTimeFormat(t, n).format(0, "second");
12
+ return new Intl.RelativeTimeFormat(e, n).format(0, "second");
13
13
  const i = Math.floor(((/* @__PURE__ */ new Date()).getTime() - r.getTime()) / 1e3), o = [
14
14
  { unit: "year", seconds: 31536e3 },
15
15
  { unit: "month", seconds: 2592e3 },
@@ -18,54 +18,54 @@ class g {
18
18
  { unit: "minute", seconds: 60 },
19
19
  { unit: "second", seconds: 1 }
20
20
  ];
21
- for (const { unit: l, seconds: u } of o) {
22
- const c = Math.floor(i / u);
23
- if (c >= 1)
24
- return new Intl.RelativeTimeFormat(t, n).format(-c, l);
21
+ for (const { unit: l, seconds: c } of o) {
22
+ const u = Math.floor(i / c);
23
+ if (u >= 1)
24
+ return new Intl.RelativeTimeFormat(e, n).format(-u, l);
25
25
  }
26
- return new Intl.RelativeTimeFormat(t, n).format(0, "second");
26
+ return new Intl.RelativeTimeFormat(e, n).format(0, "second");
27
27
  }
28
28
  }
29
- const h = /\{(\w+)\}/g;
30
- function m(s, e) {
31
- return e ? s.replace(h, (t, n) => {
32
- const r = e[n];
29
+ const g = /\{(\w+)\}/g;
30
+ function m(s, t) {
31
+ return t ? s.replace(g, (e, n) => {
32
+ const r = t[n];
33
33
  return r !== void 0 ? String(r) : `{${n}}`;
34
34
  }) : s;
35
35
  }
36
- function v(s) {
36
+ function T(s) {
37
37
  return s === "prefix" || s === "prefix_and_default";
38
38
  }
39
- function T(s) {
39
+ function v(s) {
40
40
  return s === "no_prefix";
41
41
  }
42
- function P(s) {
42
+ function w(s) {
43
43
  return s === "prefix";
44
44
  }
45
- function b(s) {
45
+ function x(s) {
46
46
  return s === "prefix_except_default";
47
47
  }
48
- function N(s) {
48
+ function $(s) {
49
49
  return s === "prefix_and_default";
50
50
  }
51
- const d = (s, e, t, n, r) => {
52
- const a = r(s, t);
51
+ const d = (s, t, e, n, r) => {
52
+ const a = r(s, e);
53
53
  if (!a)
54
54
  return null;
55
55
  const i = a.toString().split("|");
56
56
  if (i.length === 0) return null;
57
- const o = e < i.length ? i[e] : i[i.length - 1];
58
- return o ? o.trim().replace("{count}", e.toString()) : null;
57
+ const o = t < i.length ? i[t] : i[i.length - 1];
58
+ return o ? o.trim().replace("{count}", t.toString()) : null;
59
59
  };
60
- function f(s, e) {
61
- if (!s || typeof e != "string") return null;
62
- if (e in s) {
63
- const r = s[e];
60
+ function f(s, t) {
61
+ if (!s || typeof t != "string") return null;
62
+ if (t in s) {
63
+ const r = s[t];
64
64
  return r;
65
65
  }
66
- const t = e.split(".");
66
+ const e = t.split(".");
67
67
  let n = s;
68
- for (const r of t)
68
+ for (const r of e)
69
69
  if (n && typeof n == "object" && r in n)
70
70
  n = n[r];
71
71
  else
@@ -73,131 +73,124 @@ function f(s, e) {
73
73
  return n ?? null;
74
74
  }
75
75
  function p(s) {
76
- const e = s?.translations ?? /* @__PURE__ */ new Map();
76
+ const t = s?.translations ?? /* @__PURE__ */ new Map();
77
77
  return {
78
- hasCache(t, n) {
79
- const r = `${t}:${n}`;
80
- return e.has(r) || e.has(t);
78
+ hasCache(e, n) {
79
+ const r = `${e}:${n}`;
80
+ return t.has(r) || t.has(e);
81
81
  },
82
- getCache(t, n) {
83
- const r = `${t}:${n}`;
84
- return e.get(r);
82
+ getCache(e, n) {
83
+ const r = `${e}:${n}`;
84
+ return t.get(r);
85
85
  },
86
- setCache(t, n, r) {
86
+ setCache(e, n, r) {
87
87
  },
88
- hasTranslation(t, n) {
89
- for (const [r, a] of e)
90
- if ((r === t || r.startsWith(`${t}:`)) && f(a, n) !== null)
88
+ hasTranslation(e, n) {
89
+ for (const [r, a] of t)
90
+ if ((r === e || r.startsWith(`${e}:`)) && f(a, n) !== null)
91
91
  return !0;
92
92
  return !1;
93
93
  },
94
- hasGeneralTranslation(t) {
95
- return e.has(t);
94
+ hasGeneralTranslation(e) {
95
+ return t.has(e);
96
96
  },
97
- hasPageTranslation(t, n) {
98
- return e.has(`${t}:${n}`);
97
+ hasPageTranslation(e, n) {
98
+ return t.has(`${e}:${n}`);
99
99
  },
100
- getTranslation(t, n, r) {
101
- const a = `${t}:${n}`, i = e.get(a), o = f(i, r);
100
+ getTranslation(e, n, r) {
101
+ const a = `${e}:${n}`, i = t.get(a), o = f(i, r);
102
102
  if (o !== null) return o;
103
- const l = e.get(t);
103
+ const l = t.get(e);
104
104
  return f(l, r);
105
105
  },
106
- loadTranslations(t, n) {
107
- const r = e.get(t) ?? {};
108
- e.set(t, { ...r, ...n });
106
+ loadTranslations(e, n) {
107
+ const r = t.get(e) ?? {};
108
+ t.set(e, { ...r, ...n });
109
109
  },
110
- setTranslations(t, n) {
111
- e.set(t, n);
110
+ setTranslations(e, n) {
111
+ t.set(e, n);
112
112
  },
113
- loadPageTranslations(t, n, r) {
114
- const a = `${t}:${n}`, i = e.get(a);
115
- !i || Object.keys(i).length === 0 ? e.set(a, r) : e.set(a, { ...i, ...r });
113
+ loadPageTranslations(e, n, r) {
114
+ const a = `${e}:${n}`, i = t.get(a);
115
+ !i || Object.keys(i).length === 0 ? t.set(a, r) : t.set(a, { ...i, ...r });
116
116
  },
117
- mergeTranslation(t, n, r, a = !1) {
118
- const i = `${t}:${n}`, o = e.get(i) ?? {};
119
- e.set(i, { ...o, ...r });
117
+ mergeTranslation(e, n, r, a = !1) {
118
+ const i = `${e}:${n}`, o = t.get(i) ?? {};
119
+ t.set(i, { ...o, ...r });
120
120
  },
121
- mergeGlobalTranslation(t, n, r = !1) {
122
- const a = e.get(t) ?? {};
123
- e.set(t, { ...a, ...n });
121
+ mergeGlobalTranslation(e, n, r = !1) {
122
+ const a = t.get(e) ?? {};
123
+ t.set(e, { ...a, ...n });
124
124
  },
125
125
  clearCache() {
126
- e.clear();
126
+ t.clear();
127
127
  }
128
128
  };
129
129
  }
130
- class $ {
131
- constructor(e = {}) {
132
- this.formatter = new g(), this.helper = p(e.storage), this.formatter = new g(), this.pluralFunc = e.plural || d, this.missingWarn = e.missingWarn ?? !0, this.missingHandler = e.missingHandler, this.getPreviousPageInfo = e.getPreviousPageInfo, this.getCustomMissingHandler = e.getCustomMissingHandler, this.enablePreviousPageFallback = e.enablePreviousPageFallback ?? !1;
130
+ class _ {
131
+ constructor(t = {}) {
132
+ this.formatter = new h(), this.helper = p(t.storage), this.formatter = new h(), this.pluralFunc = t.plural || d, this.missingWarn = t.missingWarn ?? !0, this.missingHandler = t.missingHandler, this.getCustomMissingHandler = t.getCustomMissingHandler;
133
133
  }
134
134
  // --- Public methods (implemented in base class) ---
135
135
  /**
136
136
  * Get translation for a key
137
137
  * Based on logic from src/runtime/plugins/01.plugin.ts
138
138
  */
139
- t(e, t, n, r) {
140
- if (!e) return "";
139
+ t(t, e, n, r) {
140
+ if (!t) return "";
141
141
  const a = this.getLocale(), i = r || this.getRoute();
142
- let o = this.helper.getTranslation(a, i, e);
143
- if (!o && this.enablePreviousPageFallback && this.getPreviousPageInfo) {
144
- const l = this.getPreviousPageInfo();
145
- if (l) {
146
- const u = this.helper.getTranslation(l.locale, l.routeName, e);
147
- u && (o = u, process.env.NODE_ENV !== "production" && console.log(`Using fallback translation from previous route: ${l.routeName} -> ${e}`));
148
- }
149
- }
142
+ let o = this.helper.getTranslation(a, i, t);
150
143
  if (!o) {
151
144
  const l = this.getFallbackLocale();
152
- a !== l && (o = this.helper.getTranslation(l, i, e));
145
+ a !== l && (o = this.helper.getTranslation(l, i, t));
153
146
  }
154
147
  if (!o) {
155
148
  const l = this.getCustomMissingHandler?.();
156
- l ? l(a, e, i) : this.missingHandler ? this.missingHandler(a, e, i) : this.missingWarn && process.env.NODE_ENV !== "production" && typeof window < "u" && console.warn(`Not found '${e}' key in '${a}' locale messages for route '${i}'.`), o = n === void 0 ? e : n || e;
149
+ l ? l(a, t, i) : this.missingHandler ? this.missingHandler(a, t, i) : this.missingWarn && process.env.NODE_ENV !== "production" && typeof window < "u" && console.warn(`Not found '${t}' key in '${a}' locale messages for route '${i}'.`), o = n === void 0 ? t : n || t;
157
150
  }
158
- return typeof o == "string" && t ? m(o, t) : o;
151
+ return typeof o == "string" && e ? m(o, e) : o;
159
152
  }
160
153
  /**
161
154
  * Get translation as string
162
155
  */
163
- ts(e, t, n, r) {
164
- return this.t(e, t, n, r)?.toString() ?? n ?? e;
156
+ ts(t, e, n, r) {
157
+ return this.t(t, e, n, r)?.toString() ?? n ?? t;
165
158
  }
166
159
  /**
167
160
  * Plural translation
168
161
  */
169
- tc(e, t, n) {
170
- const { count: r, ...a } = typeof t == "number" ? { count: t } : t;
162
+ tc(t, e, n) {
163
+ const { count: r, ...a } = typeof e == "number" ? { count: e } : e;
171
164
  if (r === void 0)
172
- return n ?? e;
173
- const i = (l, u, c) => this.t(l, u, c);
174
- return this.pluralFunc(e, Number.parseInt(r.toString(), 10), a, this.getLocale(), i) ?? n ?? e;
165
+ return n ?? t;
166
+ const i = (l, c, u) => this.t(l, c, u);
167
+ return this.pluralFunc(t, Number.parseInt(r.toString(), 10), a, this.getLocale(), i) ?? n ?? t;
175
168
  }
176
169
  /**
177
170
  * Format number
178
171
  */
179
- tn(e, t) {
180
- return this.formatter.formatNumber(e, this.getLocale(), t);
172
+ tn(t, e) {
173
+ return this.formatter.formatNumber(t, this.getLocale(), e);
181
174
  }
182
175
  /**
183
176
  * Format date
184
177
  */
185
- td(e, t) {
186
- return this.formatter.formatDate(e, this.getLocale(), t);
178
+ td(t, e) {
179
+ return this.formatter.formatDate(t, this.getLocale(), e);
187
180
  }
188
181
  /**
189
182
  * Format relative time
190
183
  */
191
- tdr(e, t) {
192
- return this.formatter.formatRelativeTime(e, this.getLocale(), t);
184
+ tdr(t, e) {
185
+ return this.formatter.formatRelativeTime(t, this.getLocale(), e);
193
186
  }
194
187
  /**
195
188
  * Check if translation exists
196
189
  * Based on logic from src/runtime/plugins/01.plugin.ts
197
190
  */
198
- has(e, t) {
199
- const n = t || this.getRoute(), r = this.getLocale();
200
- return !!this.helper.getTranslation(r, n, e);
191
+ has(t, e) {
192
+ const n = e || this.getRoute(), r = this.getLocale();
193
+ return !!this.helper.getTranslation(r, n, t);
201
194
  }
202
195
  /**
203
196
  * Clear cache
@@ -210,26 +203,26 @@ class $ {
210
203
  * Core translation loading logic (without reactivity)
211
204
  * Subclasses can override addTranslations/addRouteTranslations to add reactivity
212
205
  */
213
- loadTranslationsCore(e, t, n) {
214
- n ? this.helper.mergeGlobalTranslation(e, t, !0) : this.helper.setTranslations(e, t);
206
+ loadTranslationsCore(t, e, n) {
207
+ n ? this.helper.mergeGlobalTranslation(t, e, !0) : this.helper.setTranslations(t, e);
215
208
  }
216
209
  /**
217
210
  * Core route translation loading logic (without reactivity)
218
211
  * Subclasses can override addRouteTranslations to add reactivity
219
212
  */
220
- loadRouteTranslationsCore(e, t, n, r) {
221
- r ? this.helper.mergeTranslation(e, t, n, !0) : this.helper.loadPageTranslations(e, t, n);
213
+ loadRouteTranslationsCore(t, e, n, r) {
214
+ r ? this.helper.mergeTranslation(t, e, n, !0) : this.helper.loadPageTranslations(t, e, n);
222
215
  }
223
216
  }
224
217
  export {
225
- $ as BaseI18n,
226
- g as FormatService,
218
+ _ as BaseI18n,
219
+ h as FormatService,
227
220
  d as defaultPlural,
228
221
  m as interpolate,
229
- T as isNoPrefixStrategy,
230
- N as isPrefixAndDefaultStrategy,
231
- b as isPrefixExceptDefaultStrategy,
232
- P as isPrefixStrategy,
222
+ v as isNoPrefixStrategy,
223
+ $ as isPrefixAndDefaultStrategy,
224
+ x as isPrefixExceptDefaultStrategy,
225
+ w as isPrefixStrategy,
233
226
  p as useTranslationHelper,
234
- v as withPrefixStrategy
227
+ T as withPrefixStrategy
235
228
  };
@@ -1,7 +1,7 @@
1
1
  import { Translations } from '@i18n-micro/types';
2
2
  /**
3
- * Bare Metal: Простое хранилище переводов без Ref, useState, devalue.
4
- * Ключ Map: locale (general) или locale:routeName (page-specific).
3
+ * Bare Metal: Simple translation storage without Ref, useState, devalue.
4
+ * Map key: locale (general) or locale:routeName (page-specific).
5
5
  */
6
6
  export interface TranslationStorage {
7
7
  translations: Map<string, Translations>;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@i18n-micro/core",
3
- "version": "1.1.2",
3
+ "version": "1.1.4",
4
4
  "description": "",
5
5
  "repository": "s00d/nuxt-i18n-micro",
6
6
  "license": "MIT",
@@ -22,7 +22,7 @@
22
22
  },
23
23
  "keywords": [],
24
24
  "dependencies": {
25
- "@i18n-micro/types": "1.1.1"
25
+ "@i18n-micro/types": "1.1.4"
26
26
  },
27
27
  "devDependencies": {
28
28
  "vite": "^7.3.1",
package/src/base.ts CHANGED
@@ -8,10 +8,7 @@ export interface BaseI18nOptions {
8
8
  plural?: PluralFunc
9
9
  missingWarn?: boolean
10
10
  missingHandler?: (locale: string, key: string, routeName: string) => void
11
- // Optional hooks for Nuxt runtime specific features
12
- getPreviousPageInfo?: () => { locale: string; routeName: string } | null
13
11
  getCustomMissingHandler?: () => MissingHandler | null
14
- enablePreviousPageFallback?: boolean
15
12
  }
16
13
 
17
14
  /**
@@ -27,10 +24,7 @@ export abstract class BaseI18n {
27
24
  public pluralFunc: PluralFunc
28
25
  public missingWarn: boolean
29
26
  public missingHandler?: (locale: string, key: string, routeName: string) => void
30
- // Optional hooks for Nuxt runtime specific features
31
- public getPreviousPageInfo?: () => { locale: string; routeName: string } | null
32
27
  public getCustomMissingHandler?: () => MissingHandler | null
33
- public enablePreviousPageFallback: boolean
34
28
 
35
29
  constructor(options: BaseI18nOptions = {}) {
36
30
  this.helper = useTranslationHelper(options.storage)
@@ -38,9 +32,7 @@ export abstract class BaseI18n {
38
32
  this.pluralFunc = options.plural || defaultPlural
39
33
  this.missingWarn = options.missingWarn ?? true
40
34
  this.missingHandler = options.missingHandler
41
- this.getPreviousPageInfo = options.getPreviousPageInfo
42
35
  this.getCustomMissingHandler = options.getCustomMissingHandler
43
- this.enablePreviousPageFallback = options.enablePreviousPageFallback ?? false
44
36
  }
45
37
 
46
38
  // --- Abstract methods (must be implemented by subclasses) ---
@@ -77,21 +69,7 @@ export abstract class BaseI18n {
77
69
  // Note: In Nuxt runtime, server already merges global translations, so we don't need explicit fallback
78
70
  let value = this.helper.getTranslation<string>(locale, route, key)
79
71
 
80
- // 2. If translation not found and there are saved previous translations, use them (only if enabled)
81
- if (!value && this.enablePreviousPageFallback && this.getPreviousPageInfo) {
82
- const prev = this.getPreviousPageInfo()
83
- if (prev) {
84
- const prevValue = this.helper.getTranslation<string>(prev.locale, prev.routeName, key)
85
- if (prevValue) {
86
- value = prevValue
87
- if (process.env.NODE_ENV !== 'production') {
88
- console.log(`Using fallback translation from previous route: ${prev.routeName} -> ${key}`)
89
- }
90
- }
91
- }
92
- }
93
-
94
- // 3. Fallback to fallbackLocale if not found and different (for non-Nuxt adapters)
72
+ // 2. Fallback to fallbackLocale if not found and different (for non-Nuxt adapters)
95
73
  if (!value) {
96
74
  const fallbackLocale = this.getFallbackLocale()
97
75
  if (locale !== fallbackLocale) {
@@ -99,7 +77,7 @@ export abstract class BaseI18n {
99
77
  }
100
78
  }
101
79
 
102
- // 4. Handle missing
80
+ // 3. Handle missing
103
81
  if (!value) {
104
82
  // Call custom handler if set (Nuxt runtime), otherwise use instance handler
105
83
  const customHandler = this.getCustomMissingHandler?.()
@@ -117,7 +95,7 @@ export abstract class BaseI18n {
117
95
  value = defaultValue === undefined ? key : defaultValue || key
118
96
  }
119
97
 
120
- // 5. Interpolate
98
+ // 4. Interpolate
121
99
  return typeof value === 'string' && params ? interpolate(value, params) : (value as CleanTranslation)
122
100
  }
123
101
 
@@ -1,8 +1,8 @@
1
1
  import type { Translations } from '@i18n-micro/types'
2
2
 
3
3
  /**
4
- * Bare Metal: Простое хранилище переводов без Ref, useState, devalue.
5
- * Ключ Map: locale (general) или locale:routeName (page-specific).
4
+ * Bare Metal: Simple translation storage without Ref, useState, devalue.
5
+ * Map key: locale (general) or locale:routeName (page-specific).
6
6
  */
7
7
  export interface TranslationStorage {
8
8
  translations: Map<string, Translations>
@@ -81,7 +81,7 @@ export function useTranslationHelper(storage?: TranslationStorage) {
81
81
  loadPageTranslations(locale: string, routeName: string, data: Translations): void {
82
82
  const key = `${locale}:${routeName}`
83
83
  const existing = translations.get(key)
84
- // Perf: при пустом existing — сохраняем ссылку, избегаем O(n) копирования больших объектов
84
+ // Perf: when existing is empty keep reference, avoid O(n) copying of large objects
85
85
  if (!existing || Object.keys(existing).length === 0) {
86
86
  translations.set(key, data)
87
87
  } else {
@@ -118,23 +118,6 @@ describe('BaseI18n', () => {
118
118
  expect(i18n.t('title', undefined, undefined, 'about')).toBe('Route Title')
119
119
  })
120
120
 
121
- test('should use previousPageInfo fallback when enabled', async () => {
122
- const storage = { translations: new Map<string, Translations>() }
123
- const prevInfo = { locale: 'fr', routeName: 'previous' }
124
- const i18n = new TestI18n('en', 'en', 'general', {
125
- storage,
126
- getPreviousPageInfo: () => prevInfo,
127
- enablePreviousPageFallback: true,
128
- })
129
-
130
- const translations: Translations = { greeting: 'Bonjour' }
131
- await i18n['helper'].loadPageTranslations('fr', 'previous', translations)
132
-
133
- // Current locale is 'en', route is 'general', translation not found
134
- // Should fallback to previous page info: locale 'fr', route 'previous'
135
- expect(i18n.t('greeting')).toBe('Bonjour')
136
- })
137
-
138
121
  test('should call missingHandler when translation is missing', () => {
139
122
  const handler = jest.fn()
140
123
  const i18n = new TestI18n('en', 'en', 'general', { missingHandler: handler })