@sveltekit-i18n/base 1.0.0-beta.5 → 1.0.0-rc.2

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/README.md CHANGED
@@ -3,16 +3,18 @@
3
3
  [![npm version](https://badge.fury.io/js/@sveltekit-i18n%2Fbase.svg)](https://badge.fury.io/js/@sveltekit-i18n%2Fbase) ![](https://github.com/sveltekit-i18n/base/workflows/Tests/badge.svg)
4
4
 
5
5
  # @sveltekit-i18n/base
6
- This repository contains the base functionality of [sveltekit-i18n](https://github.com/sveltekit-i18n/lib) and provides support for external message parsers.
6
+ This repository contains a base functionality of [sveltekit-i18n](https://github.com/sveltekit-i18n/lib) and provides support for external message parsers.
7
+
8
+ __IMPORTANT: THIS PACKAGE IS STILL IN DEVELOPMENT - API MAY VARY UNTIL 1.0.0__
7
9
 
8
10
  ## Key features
9
11
 
10
12
  ✅ SvelteKit ready\
11
13
  ✅ SSR support\
14
+ ✅ Custom parsers – you can use any message syntax you need\
12
15
  ✅ Custom data sources – no matter if you are using local files or remote API to get your translations\
13
16
  ✅ Module-based – your translations are loaded for visited pages only (and only once!)\
14
17
  ✅ Component-scoped translations – you can create multiple instances with custom definitions\
15
- ✅ Custom parsers – you can use any message syntax you need\
16
18
  ✅ TS support\
17
19
  ✅ No external dependencies
18
20
 
@@ -23,8 +25,8 @@ Setup `translations.js` in your lib folder...
23
25
  import i18n from '@sveltekit-i18n/base';
24
26
  import parser from '@sveltekit-i18n/parser-default'; // use your preferred parser (or create your own)
25
27
 
26
- /** @type {import('@sveltekit-i18n/base').Config} */
27
- export const config = ({
28
+ /** @namespace {import('@sveltekit-i18n/parser-default').Config} */
29
+ const config = ({
28
30
  parser: parser({}),
29
31
  loaders: [
30
32
  {
@@ -115,7 +117,12 @@ export const { t, locale, locales, loading, loadTranslations } = new i18n(config
115
117
  </div>
116
118
  ```
117
119
 
120
+
118
121
  ## More info
119
- [Docs](https://github.com/sveltekit-i18n/lib/tree/master/docs/README.md)\
120
- [Examples](https://github.com/sveltekit-i18n/lib/tree/master/examples)\
121
- [Changelog](https://github.com/sveltekit-i18n/lib/releases)
122
+ [Docs](https://github.com/sveltekit-i18n/base/tree/master/docs/README.md)\
123
+ [Examples](https://github.com/sveltekit-i18n/lib/tree/master/examples#parsers)\
124
+ [Changelog](https://github.com/sveltekit-i18n/base/releases)
125
+
126
+
127
+ ## Issues
128
+ If you are facing some issues related to the base functionality, create a ticket [here](https://github.com/sveltekit-i18n/lib/issues).
package/dist/index.cjs CHANGED
@@ -1 +1 @@
1
- var b=Object.defineProperty,E=Object.defineProperties,O=Object.getOwnPropertyDescriptor,W=Object.getOwnPropertyDescriptors,K=Object.getOwnPropertyNames,T=Object.getOwnPropertySymbols;var v=Object.prototype.hasOwnProperty,F=Object.prototype.propertyIsEnumerable;var P=(s,t,e)=>t in s?b(s,t,{enumerable:!0,configurable:!0,writable:!0,value:e}):s[t]=e,r=(s,t)=>{for(var e in t||(t={}))v.call(t,e)&&P(s,e,t[e]);if(T)for(var e of T(t))F.call(t,e)&&P(s,e,t[e]);return s},c=(s,t)=>E(s,W(t)),D=s=>b(s,"__esModule",{value:!0});var m=(s,t)=>{var e={};for(var o in s)v.call(s,o)&&t.indexOf(o)<0&&(e[o]=s[o]);if(s!=null&&T)for(var o of T(s))t.indexOf(o)<0&&F.call(s,o)&&(e[o]=s[o]);return e};var N=(s,t)=>{for(var e in t)b(s,e,{get:t[e],enumerable:!0})},M=(s,t,e,o)=>{if(t&&typeof t=="object"||typeof t=="function")for(let i of K(t))!v.call(s,i)&&(e||i!=="default")&&b(s,i,{get:()=>t[i],enumerable:!(o=O(t,i))||o.enumerable});return s};var z=(s=>(t,e)=>s&&s.get(t)||(e=M(D({}),t,1),s&&s.set(t,e),e))(typeof WeakMap!="undefined"?new WeakMap:0);var V={};N(V,{default:()=>I});var a=require("svelte/store");var d=(s,t={})=>s||t,w=(s,t)=>Object.keys(d(s)).reduce((e,o)=>{let i=s[o],n=t?`${t}.${o}`:`${o}`;return i&&typeof i=="object"?r(r({},e),w(i,n)):c(r({},e),{[n]:i})},{}),x=async s=>{try{return(await Promise.all(s.map(i=>{var n=i,{loader:e}=n,o=m(n,["loader"]);return new Promise(async l=>{let h;try{h=await e()}catch(p){console.error(`Failed to load translation. Verify your '${o.locale}' > '${o.key}' loader.`),console.error(p)}l(c(r({loader:e},o),{data:h}))})}))).reduce((e,{key:o,data:i,locale:n})=>i?c(r({},e),{[n]:w(c(r({},d(e[n])),{[o]:i}))}):e,{})}catch(t){console.error(t)}return{}},$=s=>t=>{try{if(typeof t=="string")return t===s;if(typeof t=="object")return t.test(s)}catch{throw new Error("Invalid route config!")}return!1};var j=class{constructor(t){this.loadedKeys={};this.currentRoute=(0,a.writable)();this.config=(0,a.writable)();this.isLoading=(0,a.writable)(!1);this.promises=[];this.loading={subscribe:this.isLoading.subscribe,toPromise:()=>Promise.all(this.promises),get:()=>(0,a.get)(this.isLoading)};this.privateTranslations=(0,a.writable)({});this.translations={subscribe:this.privateTranslations.subscribe,get:()=>(0,a.get)(this.translations)};this.locales=c(r({},(0,a.derived)([this.config,this.privateTranslations],([t,e])=>{if(!t)return[];let{loaders:o=[]}=t,i=o.map(({locale:l})=>`${l}`.toLowerCase()),n=Object.keys(e).map(l=>`${l}`.toLowerCase());return[...new Set([...i,...n])]},[])),{get:()=>(0,a.get)(this.locales)});this.internalLocale=(0,a.writable)();this.locale=c(r({set:this.internalLocale.set,update:this.internalLocale.update},(0,a.derived)(this.internalLocale,(t,e)=>{let o=t&&`${t}`.toLowerCase(),i=this.getLocale(o);i&&i!==this.locale.get()&&e(i)})),{get:()=>(0,a.get)(this.locale)});this.loaderTrigger=(0,a.derived)([this.internalLocale,this.currentRoute],([t,e],o)=>{t!==void 0&&e!==void 0&&o([t,e])},[]);this.initialized=(0,a.derived)([this.locale,this.currentRoute,this.privateTranslations],([t,e,o],i)=>{(0,a.get)(this.initialized)||i(t!==void 0&&e!==void 0&&!!Object.keys(o).length)});this.translation=(0,a.derived)([this.privateTranslations,this.locale,this.isLoading],([t,e,o],i)=>{let n=t[e];n&&Object.keys(n).length&&!o&&i(n)},{});this.t=c(r({},(0,a.derived)([this.config,this.translation],([{parser:t,fallbackLocale:e}])=>(o,i)=>t==null?void 0:t.parse({key:o,payload:i,translations:this.translations.get(),locale:this.locale.get(),fallbackLocale:e}))),{get:(...t)=>(0,a.get)(this.t)(...t)});this.l=c(r({},(0,a.derived)([this.config,this.translations],([{parser:t,fallbackLocale:e},o])=>(i,n,l)=>t.parse({key:n,payload:l,translations:o,locale:i,fallbackLocale:e}))),{get:(...t)=>(0,a.get)(this.l)(...t)});this.getLocale=t=>t?`${this.locales.get().find(i=>`${i}`.toLowerCase()===`${t}`.toLowerCase())||""}`.toLowerCase():"";this.setLocale=async t=>{!t||(this.internalLocale.set(t),await this.loading.toPromise())};this.setRoute=async t=>{t!==(0,a.get)(this.currentRoute)&&this.currentRoute.set(t),await this.loading.toPromise()};this.loadConfig=async t=>{await this.configLoader(t)};this.addTranslations=(t,e)=>{if(!t)return;let o=Object.keys(d(t));this.privateTranslations.update(i=>o.reduce((n,l)=>c(r({},n),{[l]:r(r({},d(n[l])),w(t[l]))}),i)),o.forEach(i=>{let n=Object.keys(t[i]).map(l=>`${l}`.split(".")[0]);e&&(n=e[i]),this.loadedKeys[i]=Array.from(new Set([...d(this.loadedKeys[i],[]),...d(n,[])]))})};this.getTranslationProps=async(t=this.locale.get(),e=(0,a.get)(this.currentRoute))=>{let o=(0,a.get)(this.config);if(!o||!t)return[];let i=this.translations.get(),{loaders:n,fallbackLocale:l=""}=d(o),h=`${t}`.toLowerCase(),p=l&&`${l}`.toLowerCase(),S=i[h],k=i[p],R=d(n,[]).map(C=>{var u=C,{locale:g}=u,f=m(u,["locale"]);return c(r({},f),{locale:`${g}`.toLowerCase()})}).filter(({routes:g})=>!g||d(g,[]).some($(e))).filter(({key:g,locale:f})=>f===h&&(!S||!d(this.loadedKeys[h],[]).includes(g))||l&&f===p&&(!k||!d(this.loadedKeys[p],[]).includes(g)));if(R.length){this.isLoading.set(!0);let g=await x(R);this.isLoading.set(!1);let f=Object.keys(g).reduce((u,L)=>c(r({},u),{[L]:Object.keys(g[L])}),{}),C=R.filter(({key:u,locale:L})=>d(f[L],[]).some(y=>`${y}`.startsWith(u))).reduce((u,{key:L,locale:y})=>c(r({},u),{[y]:[...u[y]||[],L]}),{});return[g,C]}return[]};this.translationLoader=async t=>{this.promises.push(new Promise(async e=>{let o=await this.getTranslationProps(t);o.length&&this.addTranslations(...o),e()})),await this.loading.toPromise()};this.loadTranslations=async(t,e=(0,a.get)(this.currentRoute)||"")=>{!t||(this.setRoute(e),this.setLocale(t),await this.loading.toPromise())};t&&this.loadConfig(t),this.loaderTrigger.subscribe(()=>this.translationLoader())}async configLoader(t){if(!t)throw new Error("No config!");this.config.set(t);let{initLocale:e="",translations:o}=t;o&&this.addTranslations(o),await this.loadTranslations(e)}};var I=j;module.exports=z(V);0&&(module.exports={});
1
+ var m=Object.defineProperty,j=Object.defineProperties,K=Object.getOwnPropertyDescriptor,N=Object.getOwnPropertyDescriptors,O=Object.getOwnPropertyNames,T=Object.getOwnPropertySymbols;var w=Object.prototype.hasOwnProperty,C=Object.prototype.propertyIsEnumerable;var R=(r,t,s)=>t in r?m(r,t,{enumerable:!0,configurable:!0,writable:!0,value:s}):r[t]=s,l=(r,t)=>{for(var s in t||(t={}))w.call(t,s)&&R(r,s,t[s]);if(T)for(var s of T(t))C.call(t,s)&&R(r,s,t[s]);return r},c=(r,t)=>j(r,N(t)),W=r=>m(r,"__esModule",{value:!0});var y=(r,t)=>{var s={};for(var e in r)w.call(r,e)&&t.indexOf(e)<0&&(s[e]=r[e]);if(r!=null&&T)for(var e of T(r))t.indexOf(e)<0&&C.call(r,e)&&(s[e]=r[e]);return s};var k=(r,t)=>{for(var s in t)m(r,s,{get:t[s],enumerable:!0})},D=(r,t,s,e)=>{if(t&&typeof t=="object"||typeof t=="function")for(let a of O(t))!w.call(r,a)&&(s||a!=="default")&&m(r,a,{get:()=>t[a],enumerable:!(e=K(t,a))||e.enumerable});return r};var z=(r=>(t,s)=>r&&r.get(t)||(s=D(W({}),t,1),r&&r.set(t,s),s))(typeof WeakMap!="undefined"?new WeakMap:0);var A={};k(A,{default:()=>F});var i=require("svelte/store");var P=(r,t)=>Object.keys(r||{}).reduce((s,e)=>{let a=r[e],o=t?`${t}.${e}`:`${e}`;return a&&typeof a=="object"?l(l({},s),P(a,o)):c(l({},s),{[o]:a})},{}),$=async r=>{try{return(await Promise.all(r.map(a=>{var o=a,{loader:s}=o,e=y(o,["loader"]);return new Promise(async n=>{let h;try{h=await s()}catch(p){console.error(`Failed to load translation. Verify your '${e.locale}' > '${e.key}' Loader.`),console.error(p)}n(c(l({loader:s},e),{data:h}))})}))).reduce((s,{key:e,data:a,locale:o})=>a?c(l({},s),{[o]:P(c(l({},s[o]||{}),{[e]:a}))}):s,{})}catch(t){console.error(t)}return{}},x=r=>t=>{try{if(typeof t=="string")return t===r;if(typeof t=="object")return t.test(r)}catch{throw new Error("Invalid route config!")}return!1};var F=class{constructor(t){this.loadedKeys={};this.currentRoute=(0,i.writable)();this.config=(0,i.writable)();this.isLoading=(0,i.writable)(!1);this.promises=[];this.loading={subscribe:this.isLoading.subscribe,toPromise:()=>Promise.all(this.promises),get:()=>(0,i.get)(this.isLoading)};this.privateTranslations=(0,i.writable)({});this.translations={subscribe:this.privateTranslations.subscribe,get:()=>(0,i.get)(this.translations)};this.locales=c(l({},(0,i.derived)([this.config,this.privateTranslations],([t,s])=>{if(!t)return[];let{loaders:e=[]}=t,a=e.map(({locale:n})=>`${n}`.toLowerCase()),o=Object.keys(s).map(n=>`${n}`.toLowerCase());return[...new Set([...a,...o])]},[])),{get:()=>(0,i.get)(this.locales)});this.internalLocale=(0,i.writable)();this.locale=c(l({set:this.internalLocale.set,update:this.internalLocale.update},(0,i.derived)(this.internalLocale,(t,s)=>{let e=t&&`${t}`.toLowerCase(),a=this.getLocale(e);a&&a!==this.locale.get()&&s(a)})),{get:()=>(0,i.get)(this.locale)});this.loaderTrigger=(0,i.derived)([this.internalLocale,this.currentRoute],([t,s],e)=>{t!==void 0&&s!==void 0&&e([t,s])},[]);this.initialized=(0,i.derived)([this.locale,this.currentRoute,this.privateTranslations],([t,s,e],a)=>{(0,i.get)(this.initialized)||a(t!==void 0&&s!==void 0&&!!Object.keys(e).length)});this.translation=(0,i.derived)([this.privateTranslations,this.locale,this.isLoading],([t,s,e],a)=>{let o=t[s];o&&Object.keys(o).length&&!e&&a(o)},{});this.translate=({parser:t,key:s,params:e,translations:a,locale:o,fallbackLocale:n})=>{if(!s)throw new Error("No key provided to $t()");if(!o)throw new Error("No locale set!");let h=(a[o]||{})[s];return n&&h===void 0&&(h=(a[n]||{})[s]),t.parse(h,e,o,s)};this.t=c(l({},(0,i.derived)([this.config,this.translation],([{parser:t,fallbackLocale:s}])=>(e,...a)=>this.translate({parser:t,key:e,params:a,translations:this.translations.get(),locale:this.locale.get(),fallbackLocale:s}))),{get:(t,...s)=>(0,i.get)(this.t)(t,...s)});this.l=c(l({},(0,i.derived)([this.config,this.translations],([{parser:t,fallbackLocale:s},e])=>(a,o,...n)=>this.translate({parser:t,key:o,params:n,translations:e,locale:a,fallbackLocale:s}))),{get:(t,s,...e)=>(0,i.get)(this.l)(t,s,...e)});this.getLocale=t=>t?`${this.locales.get().find(a=>`${a}`.toLowerCase()===`${t}`.toLowerCase())||""}`.toLowerCase():"";this.setLocale=async t=>{!t||(this.internalLocale.set(t),await this.loading.toPromise())};this.setRoute=async t=>{t!==(0,i.get)(this.currentRoute)&&this.currentRoute.set(t),await this.loading.toPromise()};this.loadConfig=async t=>{await this.configLoader(t)};this.addTranslations=(t,s)=>{if(!t)return;let e=Object.keys(t||{});this.privateTranslations.update(a=>e.reduce((o,n)=>c(l({},o),{[n]:l(l({},o[n]||{}),P(t[n]))}),a)),e.forEach(a=>{let o=Object.keys(t[a]).map(n=>`${n}`.split(".")[0]);s&&(o=s[a]),this.loadedKeys[a]=Array.from(new Set([...this.loadedKeys[a]||[],...o||[]]))})};this.getTranslationProps=async(t=this.locale.get(),s=(0,i.get)(this.currentRoute))=>{let e=(0,i.get)(this.config);if(!e||!t)return[];let a=this.translations.get(),{loaders:o,fallbackLocale:n=""}=e||{},h=`${t}`.toLowerCase(),p=n&&`${n}`.toLowerCase(),S=a[h],E=a[p],b=(o||[]).map(v=>{var g=v,{locale:d}=g,u=y(g,["locale"]);return c(l({},u),{locale:`${d}`.toLowerCase()})}).filter(({routes:d})=>!d||(d||[]).some(x(s))).filter(({key:d,locale:u})=>u===h&&(!S||!(this.loadedKeys[h]||[]).includes(d))||n&&u===p&&(!E||!(this.loadedKeys[p]||[]).includes(d)));if(b.length){this.isLoading.set(!0);let d=await $(b);this.isLoading.set(!1);let u=Object.keys(d).reduce((g,f)=>c(l({},g),{[f]:Object.keys(d[f])}),{}),v=b.filter(({key:g,locale:f})=>(u[f]||[]).some(L=>`${L}`.startsWith(g))).reduce((g,{key:f,locale:L})=>c(l({},g),{[L]:[...g[L]||[],f]}),{});return[d,v]}return[]};this.translationLoader=async t=>{this.promises.push(new Promise(async s=>{let e=await this.getTranslationProps(t);e.length&&this.addTranslations(...e),s()})),await this.loading.toPromise()};this.loadTranslations=async(t,s=(0,i.get)(this.currentRoute)||"")=>{!t||(this.setRoute(s),this.setLocale(t),await this.loading.toPromise())};t&&this.loadConfig(t),this.loaderTrigger.subscribe(()=>this.translationLoader())}async configLoader(t){if(!t)throw new Error("No config!");this.config.set(t);let{initLocale:s="",translations:e}=t;e&&this.addTranslations(e),await this.loadTranslations(s)}};module.exports=z(A);0&&(module.exports={});
package/dist/index.d.ts CHANGED
@@ -1,50 +1,77 @@
1
1
  import { Readable, Writable } from 'svelte/store';
2
2
 
3
- type LoadingStore = Readable<boolean> & { toPromise: () => Promise<void[]>, get: () => boolean };
4
-
5
- type Loader = () => Promise<Record<any, any>>;
6
-
7
- type Route = string | RegExp;
8
-
9
- type LoaderModule = {
10
- key: string;
11
- locale: string;
12
- routes?: Route[];
13
- loader: Loader;
3
+ declare type ExtendedStore<T, Get = () => T, Store = Readable<T>> = Store & {
4
+ get: Get;
14
5
  };
15
-
16
- type TranslationFunction = (key: string, vars?: Record<any, any>) => string;
17
-
18
- type LocalTranslationFunction = (locale: string, key: string, vars?: Record<any, any>) => string;
19
-
20
- type ExtendedStore<T, Get = () => T, Store = Readable<T>> = Store & { get: Get };
21
-
22
- type ConfigTranslations = { [locale: string]: Record<string, any> };
23
-
24
- type Translations = { [locale: string]: Record<string, string> };
25
-
26
- type Parse<Payload = Record<any, any>> = (props: {
27
- key: string;
28
- payload?: Payload;
29
- translations: Translations;
30
- locale: string;
31
- fallbackLocale?: string;
32
- }) => string;
33
-
34
- type Parser = {
35
- parse: Parse;
36
- };
37
-
38
- type Config = {
39
- parser: Parser;
40
- loaders?: LoaderModule[];
41
- translations?: ConfigTranslations;
42
- initLocale?: string;
43
- fallbackLocale?: string;
6
+ declare type LoadingStore = Readable<boolean> & {
7
+ toPromise: () => Promise<void[]>;
8
+ get: () => boolean;
44
9
  };
10
+ declare module DotNotation {
11
+ type Input = any;
12
+ type Output<V = any, K extends keyof V = keyof V> = {
13
+ [P in K]?: V[K];
14
+ } | null;
15
+ type T = <I = Input>(input: I, parentKey?: string) => Output<I>;
16
+ }
17
+ declare module Config {
18
+ type Loaders = Loader.LoaderModule[] | undefined;
19
+ type Translations = Translations.T | undefined;
20
+ type Locale = string;
21
+ type InitLocale = Locale | undefined;
22
+ type FallbackLocale = Locale | undefined;
23
+ type T<P extends Parser.Params = any> = {
24
+ loaders?: Loaders;
25
+ translations?: Translations;
26
+ initLocale?: InitLocale;
27
+ fallbackLocale?: FallbackLocale;
28
+ parser: Parser.T<P>;
29
+ };
30
+ }
31
+ declare module Loader {
32
+ type Key = string;
33
+ type Locale = Config.Locale;
34
+ type Route = string | RegExp;
35
+ type LoaderModule = {
36
+ key: Key;
37
+ locale: Locale;
38
+ routes?: Route[];
39
+ loader: T;
40
+ };
41
+ type T = () => Promise<Record<any, any>>;
42
+ }
43
+ declare module Parser {
44
+ type Value = any;
45
+ type Params = Array<unknown>;
46
+ type Locale = Config.Locale;
47
+ type Key = Loader.Key;
48
+ type Output = any;
49
+ type Parse<P extends Parser.Params = any> = (value: Value, params: P, locale: Locale, key: Key) => Output;
50
+ type ParserFactory<ParserConfig = any, P extends Parser.Params = any> = (config?: ParserConfig) => Parser.T<P>;
51
+ type T<P extends Parser.Params = any> = {
52
+ parse: Parse<P>;
53
+ };
54
+ }
55
+ declare module Translations {
56
+ type SerializedTranslations = T<DotNotation.Output>;
57
+ type FetchTranslations = (loaders: Loader.LoaderModule[]) => Promise<SerializedTranslations>;
58
+ type TranslationFunction<P extends Parser.Params = any> = (key: string, ...restParams: P) => string;
59
+ type LocalTranslationFunction<P extends Parser.Params = any> = (locale: string, key: string, ...restParams: P) => string;
60
+ type Translate<P extends Parser.Params = any> = (props: {
61
+ parser: Parser.T<P>;
62
+ key: string;
63
+ params: P;
64
+ translations: SerializedTranslations;
65
+ locale: string;
66
+ fallbackLocale?: string;
67
+ }) => string;
68
+ type T<T = any> = {
69
+ [locale: string]: Record<string, T>;
70
+ };
71
+ }
45
72
 
46
- declare class I18n {
47
- constructor(config?: Config);
73
+ declare class I18n<ParserParams extends Parser.Params = any> {
74
+ constructor(config?: Config.T<ParserParams>);
48
75
  private loadedKeys;
49
76
  private currentRoute;
50
77
  private config;
@@ -52,25 +79,26 @@ declare class I18n {
52
79
  private promises;
53
80
  loading: LoadingStore;
54
81
  private privateTranslations;
55
- translations: ExtendedStore<Translations>;
82
+ translations: ExtendedStore<Translations.SerializedTranslations>;
56
83
  locales: ExtendedStore<string[]>;
57
84
  private internalLocale;
58
85
  locale: ExtendedStore<string, () => string, Writable<string>>;
59
86
  private loaderTrigger;
60
87
  initialized: Readable<boolean>;
61
88
  private translation;
62
- t: ExtendedStore<TranslationFunction, TranslationFunction>;
63
- l: ExtendedStore<LocalTranslationFunction, LocalTranslationFunction>;
89
+ private translate;
90
+ t: ExtendedStore<Translations.TranslationFunction<ParserParams>, Translations.TranslationFunction<ParserParams>>;
91
+ l: ExtendedStore<Translations.LocalTranslationFunction<ParserParams>, Translations.LocalTranslationFunction<ParserParams>>;
64
92
  private getLocale;
65
93
  setLocale: (locale?: string | undefined) => Promise<void>;
66
94
  setRoute: (route: string) => Promise<void>;
67
- configLoader(config: Config): Promise<void>;
68
- loadConfig: (config: Config) => Promise<void>;
69
- addTranslations: (translations?: ConfigTranslations | undefined, keys?: Record<string, string[]> | undefined) => void;
70
- getTranslationProps: ($locale?: string, $route?: string) => Promise<[ConfigTranslations, Record<string, string[]>] | [
95
+ configLoader(config: Config.T<ParserParams>): Promise<void>;
96
+ loadConfig: (config: Config.T<ParserParams>) => Promise<void>;
97
+ addTranslations: (translations?: Config.Translations, keys?: Record<string, string[]> | undefined) => void;
98
+ getTranslationProps: ($locale?: string, $route?: string) => Promise<[Config.Translations, Record<string, string[]>] | [
71
99
  ]>;
72
100
  private translationLoader;
73
101
  loadTranslations: (locale: string, route?: string) => Promise<void>;
74
102
  }
75
103
 
76
- export { Config, Parse, Parser, I18n as default };
104
+ export { Config, Loader, Parser, Translations, I18n as default };
package/dist/index.js CHANGED
@@ -1 +1 @@
1
- var O=Object.defineProperty,W=Object.defineProperties;var K=Object.getOwnPropertyDescriptors;var m=Object.getOwnPropertySymbols;var F=Object.prototype.hasOwnProperty,x=Object.prototype.propertyIsEnumerable;var P=(i,t,e)=>t in i?O(i,t,{enumerable:!0,configurable:!0,writable:!0,value:e}):i[t]=e,n=(i,t)=>{for(var e in t||(t={}))F.call(t,e)&&P(i,e,t[e]);if(m)for(var e of m(t))x.call(t,e)&&P(i,e,t[e]);return i},l=(i,t)=>W(i,K(t));var w=(i,t)=>{var e={};for(var o in i)F.call(i,o)&&t.indexOf(o)<0&&(e[o]=i[o]);if(i!=null&&m)for(var o of m(i))t.indexOf(o)<0&&x.call(i,o)&&(e[o]=i[o]);return e};import{derived as h,get as g,writable as T}from"svelte/store";var c=(i,t={})=>i||t,R=(i,t)=>Object.keys(c(i)).reduce((e,o)=>{let s=i[o],a=t?`${t}.${o}`:`${o}`;return s&&typeof s=="object"?n(n({},e),R(s,a)):l(n({},e),{[a]:s})},{}),$=async i=>{try{return(await Promise.all(i.map(s=>{var a=s,{loader:e}=a,o=w(a,["loader"]);return new Promise(async r=>{let f;try{f=await e()}catch(y){console.error(`Failed to load translation. Verify your '${o.locale}' > '${o.key}' loader.`),console.error(y)}r(l(n({loader:e},o),{data:f}))})}))).reduce((e,{key:o,data:s,locale:a})=>s?l(n({},e),{[a]:R(l(n({},c(e[a])),{[o]:s}))}):e,{})}catch(t){console.error(t)}return{}},j=i=>t=>{try{if(typeof t=="string")return t===i;if(typeof t=="object")return t.test(i)}catch{throw new Error("Invalid route config!")}return!1};var S=class{constructor(t){this.loadedKeys={};this.currentRoute=T();this.config=T();this.isLoading=T(!1);this.promises=[];this.loading={subscribe:this.isLoading.subscribe,toPromise:()=>Promise.all(this.promises),get:()=>g(this.isLoading)};this.privateTranslations=T({});this.translations={subscribe:this.privateTranslations.subscribe,get:()=>g(this.translations)};this.locales=l(n({},h([this.config,this.privateTranslations],([t,e])=>{if(!t)return[];let{loaders:o=[]}=t,s=o.map(({locale:r})=>`${r}`.toLowerCase()),a=Object.keys(e).map(r=>`${r}`.toLowerCase());return[...new Set([...s,...a])]},[])),{get:()=>g(this.locales)});this.internalLocale=T();this.locale=l(n({set:this.internalLocale.set,update:this.internalLocale.update},h(this.internalLocale,(t,e)=>{let o=t&&`${t}`.toLowerCase(),s=this.getLocale(o);s&&s!==this.locale.get()&&e(s)})),{get:()=>g(this.locale)});this.loaderTrigger=h([this.internalLocale,this.currentRoute],([t,e],o)=>{t!==void 0&&e!==void 0&&o([t,e])},[]);this.initialized=h([this.locale,this.currentRoute,this.privateTranslations],([t,e,o],s)=>{g(this.initialized)||s(t!==void 0&&e!==void 0&&!!Object.keys(o).length)});this.translation=h([this.privateTranslations,this.locale,this.isLoading],([t,e,o],s)=>{let a=t[e];a&&Object.keys(a).length&&!o&&s(a)},{});this.t=l(n({},h([this.config,this.translation],([{parser:t,fallbackLocale:e}])=>(o,s)=>t==null?void 0:t.parse({key:o,payload:s,translations:this.translations.get(),locale:this.locale.get(),fallbackLocale:e}))),{get:(...t)=>g(this.t)(...t)});this.l=l(n({},h([this.config,this.translations],([{parser:t,fallbackLocale:e},o])=>(s,a,r)=>t.parse({key:a,payload:r,translations:o,locale:s,fallbackLocale:e}))),{get:(...t)=>g(this.l)(...t)});this.getLocale=t=>t?`${this.locales.get().find(s=>`${s}`.toLowerCase()===`${t}`.toLowerCase())||""}`.toLowerCase():"";this.setLocale=async t=>{!t||(this.internalLocale.set(t),await this.loading.toPromise())};this.setRoute=async t=>{t!==g(this.currentRoute)&&this.currentRoute.set(t),await this.loading.toPromise()};this.loadConfig=async t=>{await this.configLoader(t)};this.addTranslations=(t,e)=>{if(!t)return;let o=Object.keys(c(t));this.privateTranslations.update(s=>o.reduce((a,r)=>l(n({},a),{[r]:n(n({},c(a[r])),R(t[r]))}),s)),o.forEach(s=>{let a=Object.keys(t[s]).map(r=>`${r}`.split(".")[0]);e&&(a=e[s]),this.loadedKeys[s]=Array.from(new Set([...c(this.loadedKeys[s],[]),...c(a,[])]))})};this.getTranslationProps=async(t=this.locale.get(),e=g(this.currentRoute))=>{let o=g(this.config);if(!o||!t)return[];let s=this.translations.get(),{loaders:a,fallbackLocale:r=""}=c(o),f=`${t}`.toLowerCase(),y=r&&`${r}`.toLowerCase(),k=s[f],E=s[y],v=c(a,[]).map(C=>{var u=C,{locale:d}=u,L=w(u,["locale"]);return l(n({},L),{locale:`${d}`.toLowerCase()})}).filter(({routes:d})=>!d||c(d,[]).some(j(e))).filter(({key:d,locale:L})=>L===f&&(!k||!c(this.loadedKeys[f],[]).includes(d))||r&&L===y&&(!E||!c(this.loadedKeys[y],[]).includes(d)));if(v.length){this.isLoading.set(!0);let d=await $(v);this.isLoading.set(!1);let L=Object.keys(d).reduce((u,p)=>l(n({},u),{[p]:Object.keys(d[p])}),{}),C=v.filter(({key:u,locale:p})=>c(L[p],[]).some(b=>`${b}`.startsWith(u))).reduce((u,{key:p,locale:b})=>l(n({},u),{[b]:[...u[b]||[],p]}),{});return[d,C]}return[]};this.translationLoader=async t=>{this.promises.push(new Promise(async e=>{let o=await this.getTranslationProps(t);o.length&&this.addTranslations(...o),e()})),await this.loading.toPromise()};this.loadTranslations=async(t,e=g(this.currentRoute)||"")=>{!t||(this.setRoute(e),this.setLocale(t),await this.loading.toPromise())};t&&this.loadConfig(t),this.loaderTrigger.subscribe(()=>this.translationLoader())}async configLoader(t){if(!t)throw new Error("No config!");this.config.set(t);let{initLocale:e="",translations:o}=t;o&&this.addTranslations(o),await this.loadTranslations(e)}};var V=S;export{V as default};
1
+ var j=Object.defineProperty,K=Object.defineProperties;var N=Object.getOwnPropertyDescriptors;var y=Object.getOwnPropertySymbols;var C=Object.prototype.hasOwnProperty,$=Object.prototype.propertyIsEnumerable;var R=(o,t,s)=>t in o?j(o,t,{enumerable:!0,configurable:!0,writable:!0,value:s}):o[t]=s,n=(o,t)=>{for(var s in t||(t={}))C.call(t,s)&&R(o,s,t[s]);if(y)for(var s of y(t))$.call(t,s)&&R(o,s,t[s]);return o},l=(o,t)=>K(o,N(t));var P=(o,t)=>{var s={};for(var e in o)C.call(o,e)&&t.indexOf(e)<0&&(s[e]=o[e]);if(o!=null&&y)for(var e of y(o))t.indexOf(e)<0&&$.call(o,e)&&(s[e]=o[e]);return s};import{derived as u,get as d,writable as T}from"svelte/store";var b=(o,t)=>Object.keys(o||{}).reduce((s,e)=>{let a=o[e],r=t?`${t}.${e}`:`${e}`;return a&&typeof a=="object"?n(n({},s),b(a,r)):l(n({},s),{[r]:a})},{}),x=async o=>{try{return(await Promise.all(o.map(a=>{var r=a,{loader:s}=r,e=P(r,["loader"]);return new Promise(async i=>{let h;try{h=await s()}catch(L){console.error(`Failed to load translation. Verify your '${e.locale}' > '${e.key}' Loader.`),console.error(L)}i(l(n({loader:s},e),{data:h}))})}))).reduce((s,{key:e,data:a,locale:r})=>a?l(n({},s),{[r]:b(l(n({},s[r]||{}),{[e]:a}))}):s,{})}catch(t){console.error(t)}return{}},F=o=>t=>{try{if(typeof t=="string")return t===o;if(typeof t=="object")return t.test(o)}catch{throw new Error("Invalid route config!")}return!1};var k=class{constructor(t){this.loadedKeys={};this.currentRoute=T();this.config=T();this.isLoading=T(!1);this.promises=[];this.loading={subscribe:this.isLoading.subscribe,toPromise:()=>Promise.all(this.promises),get:()=>d(this.isLoading)};this.privateTranslations=T({});this.translations={subscribe:this.privateTranslations.subscribe,get:()=>d(this.translations)};this.locales=l(n({},u([this.config,this.privateTranslations],([t,s])=>{if(!t)return[];let{loaders:e=[]}=t,a=e.map(({locale:i})=>`${i}`.toLowerCase()),r=Object.keys(s).map(i=>`${i}`.toLowerCase());return[...new Set([...a,...r])]},[])),{get:()=>d(this.locales)});this.internalLocale=T();this.locale=l(n({set:this.internalLocale.set,update:this.internalLocale.update},u(this.internalLocale,(t,s)=>{let e=t&&`${t}`.toLowerCase(),a=this.getLocale(e);a&&a!==this.locale.get()&&s(a)})),{get:()=>d(this.locale)});this.loaderTrigger=u([this.internalLocale,this.currentRoute],([t,s],e)=>{t!==void 0&&s!==void 0&&e([t,s])},[]);this.initialized=u([this.locale,this.currentRoute,this.privateTranslations],([t,s,e],a)=>{d(this.initialized)||a(t!==void 0&&s!==void 0&&!!Object.keys(e).length)});this.translation=u([this.privateTranslations,this.locale,this.isLoading],([t,s,e],a)=>{let r=t[s];r&&Object.keys(r).length&&!e&&a(r)},{});this.translate=({parser:t,key:s,params:e,translations:a,locale:r,fallbackLocale:i})=>{if(!s)throw new Error("No key provided to $t()");if(!r)throw new Error("No locale set!");let h=(a[r]||{})[s];return i&&h===void 0&&(h=(a[i]||{})[s]),t.parse(h,e,r,s)};this.t=l(n({},u([this.config,this.translation],([{parser:t,fallbackLocale:s}])=>(e,...a)=>this.translate({parser:t,key:e,params:a,translations:this.translations.get(),locale:this.locale.get(),fallbackLocale:s}))),{get:(t,...s)=>d(this.t)(t,...s)});this.l=l(n({},u([this.config,this.translations],([{parser:t,fallbackLocale:s},e])=>(a,r,...i)=>this.translate({parser:t,key:r,params:i,translations:e,locale:a,fallbackLocale:s}))),{get:(t,s,...e)=>d(this.l)(t,s,...e)});this.getLocale=t=>t?`${this.locales.get().find(a=>`${a}`.toLowerCase()===`${t}`.toLowerCase())||""}`.toLowerCase():"";this.setLocale=async t=>{!t||(this.internalLocale.set(t),await this.loading.toPromise())};this.setRoute=async t=>{t!==d(this.currentRoute)&&this.currentRoute.set(t),await this.loading.toPromise()};this.loadConfig=async t=>{await this.configLoader(t)};this.addTranslations=(t,s)=>{if(!t)return;let e=Object.keys(t||{});this.privateTranslations.update(a=>e.reduce((r,i)=>l(n({},r),{[i]:n(n({},r[i]||{}),b(t[i]))}),a)),e.forEach(a=>{let r=Object.keys(t[a]).map(i=>`${i}`.split(".")[0]);s&&(r=s[a]),this.loadedKeys[a]=Array.from(new Set([...this.loadedKeys[a]||[],...r||[]]))})};this.getTranslationProps=async(t=this.locale.get(),s=d(this.currentRoute))=>{let e=d(this.config);if(!e||!t)return[];let a=this.translations.get(),{loaders:r,fallbackLocale:i=""}=e||{},h=`${t}`.toLowerCase(),L=i&&`${i}`.toLowerCase(),S=a[h],E=a[L],w=(r||[]).map(v=>{var g=v,{locale:c}=g,f=P(g,["locale"]);return l(n({},f),{locale:`${c}`.toLowerCase()})}).filter(({routes:c})=>!c||(c||[]).some(F(s))).filter(({key:c,locale:f})=>f===h&&(!S||!(this.loadedKeys[h]||[]).includes(c))||i&&f===L&&(!E||!(this.loadedKeys[L]||[]).includes(c)));if(w.length){this.isLoading.set(!0);let c=await x(w);this.isLoading.set(!1);let f=Object.keys(c).reduce((g,p)=>l(n({},g),{[p]:Object.keys(c[p])}),{}),v=w.filter(({key:g,locale:p})=>(f[p]||[]).some(m=>`${m}`.startsWith(g))).reduce((g,{key:p,locale:m})=>l(n({},g),{[m]:[...g[m]||[],p]}),{});return[c,v]}return[]};this.translationLoader=async t=>{this.promises.push(new Promise(async s=>{let e=await this.getTranslationProps(t);e.length&&this.addTranslations(...e),s()})),await this.loading.toPromise()};this.loadTranslations=async(t,s=d(this.currentRoute)||"")=>{!t||(this.setRoute(s),this.setLocale(t),await this.loading.toPromise())};t&&this.loadConfig(t),this.loaderTrigger.subscribe(()=>this.translationLoader())}async configLoader(t){if(!t)throw new Error("No config!");this.config.set(t);let{initLocale:s="",translations:e}=t;e&&this.addTranslations(e),await this.loadTranslations(s)}};export{k as default};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sveltekit-i18n/base",
3
- "version": "1.0.0-beta.5",
3
+ "version": "1.0.0-rc.2",
4
4
  "description": "Base functionality of sveltekit-i18n library with a support for external message parsers.",
5
5
  "type": "module",
6
6
  "main": "./dist/index.cjs",
@@ -15,10 +15,10 @@
15
15
  "./package.json": "./package.json"
16
16
  },
17
17
  "scripts": {
18
- "dev": "tsup src/index.ts --watch",
18
+ "dev": "tsup --watch",
19
19
  "test": "jest",
20
- "build": "tsup src/index.ts --dts --format cjs,esm --minify",
21
- "prepublishOnly": "rm -rf dist && npm run build",
20
+ "build": "tsup",
21
+ "prepublishOnly": "npm run build",
22
22
  "lint": "eslint --fix --ext .ts,.js --ignore-path .gitignore ."
23
23
  },
24
24
  "files": [
@@ -47,7 +47,10 @@
47
47
  },
48
48
  "homepage": "https://github.com/sveltekit-i18n/base#readme",
49
49
  "peerDependencies": {
50
- "svelte": "^3.44.3"
50
+ "svelte": "^3.x"
51
+ },
52
+ "optionalDependencies": {
53
+ "@sveltekit-i18n/parser-default": "^1.x"
51
54
  },
52
55
  "devDependencies": {
53
56
  "@types/jest": "^27.0.3",
@@ -56,10 +59,8 @@
56
59
  "eslint": "^8.4.1",
57
60
  "eslint-config-airbnb-typescript": "^16.1.0",
58
61
  "eslint-plugin-import": "^2.25.3",
59
- "eslint-plugin-svelte3": "^3.2.1",
60
62
  "jest": "^27.4.5",
61
63
  "pre-commit": "^1.2.2",
62
- "svelte": "^3.44.3",
63
64
  "ts-jest": "^27.1.2",
64
65
  "tsup": "^5.11.13",
65
66
  "typescript": "^4.5.4"