1- import * as types from './types' ;
2- import parseAsFullyQualifiedURI from './utils/parseAsFullyQualifiedURI' ;
3- import defaultIntlAdapter from './defaultIntlAdapter' ;
4- import { isSpecialUrl } from './utils/isSpecialUrl' ;
1+ import { defaultIntlAdapter } from './defaultIntlAdapter' ;
52import { OptionsIntl } from './interfaces/OptionsSdk' ;
3+ import type { IntlAdapter , IntlConfig , IntlUpdateEvent , IntlUpdateEventInternal } from './types' ;
4+ import { TtlCache } from './utils/TtlCache' ;
5+ import { getCanonicalLocale } from './utils/getCanonicalLocale' ;
6+ import { localizeUrl } from './utils/localizeUrl' ;
7+ import { parseUrl } from './utils/parseUrl' ;
8+
9+ export const cache = new TtlCache ( ) ;
610
711/**
812 * **WARNING:** this class shouldn't be imported directly in the apps or adapters. Use `IlcAppSdk` instead.
913 */
1014export class IlcIntl {
11- private adapter : types . IntlAdapter ;
12- private listeners : any [ ] = [ ] ;
15+ private listeners : ( ( event : IntlUpdateEventInternal ) => void ) [ ] = [ ] ;
1316 private static eventName = 'ilc:intl-update' ;
1417
1518 constructor (
16- private appId : string ,
17- adapter ?: types . IntlAdapter ,
18- private options ?: OptionsIntl ,
19- ) {
20- if ( ! adapter ) {
21- adapter = defaultIntlAdapter ;
22- }
23-
24- this . adapter = adapter ;
25- }
19+ private readonly appId : string ,
20+ private readonly adapter : IntlAdapter = defaultIntlAdapter ,
21+ private readonly options ?: OptionsIntl ,
22+ ) { }
2623
2724 /**
2825 * Allows to retrieve current i18n configuration
@@ -50,7 +47,7 @@ export class IlcIntl {
5047 *
5148 * @param config
5249 */
53- public set ( config : types . IntlConfig ) : void {
50+ public set ( config : IntlConfig ) : void {
5451 if ( ! this . adapter . set ) {
5552 throw new Error ( "Looks like you're trying to call CSR only method during SSR." ) ;
5653 }
@@ -93,14 +90,14 @@ export class IlcIntl {
9390 * @returns - callback that can be used to unsubscribe from changes
9491 */
9592 public onChange < T > (
96- prepareForChange : ( event : types . IntlUpdateEvent ) => Promise < T > | T ,
97- performChange : ( event : types . IntlUpdateEvent , preparedData : T ) => Promise < void > | void ,
93+ prepareForChange : ( event : IntlUpdateEvent ) => Promise < T > | T ,
94+ performChange : ( event : IntlUpdateEvent , preparedData : T ) => Promise < void > | void ,
9895 ) {
9996 if ( ! this . adapter . set ) {
10097 return ( ) => { } ; // Looks like you're trying to call CSR only method during SSR. Doing nothing...
10198 }
10299
103- const wrappedCb = ( e : types . IntlUpdateEventInternal ) => {
100+ const wrappedCb = ( e : IntlUpdateEventInternal ) => {
104101 e . detail . addHandler ( {
105102 actorId : this . appId ,
106103 prepare : prepareForChange ,
@@ -114,7 +111,7 @@ export class IlcIntl {
114111 return ( ) => {
115112 for ( const row of this . listeners ) {
116113 if ( row === wrappedCb ) {
117- window . removeEventListener ( IlcIntl . eventName , row ) ;
114+ window . removeEventListener ( IlcIntl . eventName , row as EventListener ) ;
118115 this . listeners . slice ( this . listeners . indexOf ( wrappedCb ) , 1 ) ;
119116 break ;
120117 }
@@ -131,7 +128,7 @@ export class IlcIntl {
131128 }
132129
133130 for ( const callback of this . listeners ) {
134- window . removeEventListener ( IlcIntl . eventName , callback ) ;
131+ window . removeEventListener ( IlcIntl . eventName , callback as EventListener ) ;
135132 }
136133
137134 this . listeners = [ ] ;
@@ -142,38 +139,19 @@ export class IlcIntl {
142139 *
143140 * @param config
144141 * @param url - absolute path or absolute URI. Ex: "/test?a=1" or "http://tst.com/"
145- * @param configOverride - allows to override default locale
142+ * @param configOverride - allows to override default locales
146143 *
147144 * @internal Used internally by ILC
148145 */
149- static localizeUrl ( config : types . IntlAdapterConfig , url : string , configOverride : { locale ?: string } = { } ) : string {
150- if ( isSpecialUrl ( url ) ) {
151- return url ;
152- }
153-
154- const parsedUri = parseAsFullyQualifiedURI ( url ) ;
155- url = parsedUri . uri ;
156-
157- if ( ! url . startsWith ( '/' ) ) {
158- throw new Error ( `Localization of relative URLs is not supported. Received: "${ url } "` ) ;
159- }
160-
161- url = IlcIntl . parseUrl ( config , url ) . cleanUrl ;
162-
163- const receivedLocale = configOverride . locale || config . default . locale ;
164-
165- const loc = IlcIntl . getCanonicalLocale ( receivedLocale , config . supported . locale ) ;
166-
167- if ( loc === null ) {
168- throw new Error ( `Unsupported locale passed. Received: "${ receivedLocale } "` ) ;
169- }
170-
171- if ( config . routingStrategy === types . RoutingStrategy . PrefixExceptDefault && loc === config . default . locale ) {
172- return parsedUri . origin + url ;
173- }
174-
175- return `${ parsedUri . origin } /${ IlcIntl . getShortenedLocale ( loc , config . supported . locale ) } ${ url } ` ;
176- }
146+ static localizeUrl = cache . wrap (
147+ localizeUrl ,
148+ /**
149+ * supported locales and routing strategy are not expected to change during the runtime frequently
150+ * they are not included in the cache key
151+ * values will be cleaned up by TTL
152+ */
153+ ( config , url , override ) => `${ override ?. locale ?? config . default . locale } :${ url } ` ,
154+ ) ;
177155
178156 /**
179157 * Allows to parse URL and receive "unlocalized" URL and information about locale that was encoded in URL.
@@ -183,30 +161,7 @@ export class IlcIntl {
183161 *
184162 * @internal Used internally by ILC
185163 */
186- static parseUrl ( config : types . IntlAdapterConfig , url : string ) : { locale : string ; cleanUrl : string } {
187- if ( isSpecialUrl ( url ) ) {
188- return {
189- cleanUrl : url ,
190- locale : config . default . locale ,
191- } ;
192- }
193-
194- const parsedUri = parseAsFullyQualifiedURI ( url ) ;
195- url = parsedUri . uri ;
196-
197- if ( ! url . startsWith ( '/' ) ) {
198- throw new Error ( `Localization of relative URLs is not supported. Received: "${ url } "` ) ;
199- }
200-
201- const [ , langPart , ...path ] = url . split ( '/' ) ;
202- const lang = IlcIntl . getCanonicalLocale ( langPart , config . supported . locale ) ;
203-
204- if ( lang !== null && config . supported . locale . indexOf ( lang ) !== - 1 ) {
205- return { cleanUrl : `${ parsedUri . origin } /${ path . join ( '/' ) } ` , locale : lang } ;
206- }
207-
208- return { cleanUrl : parsedUri . origin + url , locale : config . default . locale } ;
209- }
164+ static parseUrl = cache . wrap ( parseUrl , ( config , url ) => url ) ;
210165
211166 /**
212167 * Returns properly formatted locale string.
@@ -217,56 +172,5 @@ export class IlcIntl {
217172 *
218173 * @internal Used internally by ILC
219174 */
220- static getCanonicalLocale ( locale = '' , supportedLocales : string [ ] ) {
221- const supportedLangs = supportedLocales . map ( ( v ) => v . split ( '-' ) [ 0 ] ) . filter ( ( v , i , a ) => a . indexOf ( v ) === i ) ;
222-
223- const locData = locale . split ( '-' ) ;
224-
225- if ( locData . length === 2 ) {
226- locale = locData [ 0 ] . toLowerCase ( ) + '-' + locData [ 1 ] . toUpperCase ( ) ;
227- } else if ( locData . length === 1 ) {
228- locale = locData [ 0 ] . toLowerCase ( ) ;
229- } else {
230- return null ;
231- }
232-
233- if ( supportedLangs . indexOf ( locale . toLowerCase ( ) ) !== - 1 ) {
234- for ( const v of supportedLocales ) {
235- if ( v . split ( '-' ) [ 0 ] === locale ) {
236- locale = v ;
237- break ;
238- }
239- }
240- } else if ( supportedLocales . indexOf ( locale ) === - 1 ) {
241- return null ;
242- }
243-
244- return locale ;
245- }
246-
247- /**
248- * Returns properly formatted short form of locale string.
249- * Ex: en-US -> en, but en-GB -> en-GB
250- *
251- * @internal Used internally by ILC
252- */
253- static getShortenedLocale ( canonicalLocale : string , supportedLocales : string [ ] ) : string {
254- if ( supportedLocales . indexOf ( canonicalLocale ) === - 1 ) {
255- throw new Error ( `Unsupported locale passed. Received: ${ canonicalLocale } ` ) ;
256- }
257-
258- for ( const loc of supportedLocales ) {
259- if ( loc . split ( '-' ) [ 0 ] !== canonicalLocale . split ( '-' ) [ 0 ] ) {
260- continue ;
261- }
262-
263- if ( loc === canonicalLocale ) {
264- return loc . split ( '-' ) [ 0 ] ;
265- } else {
266- return canonicalLocale ;
267- }
268- }
269-
270- return canonicalLocale ;
271- }
175+ static getCanonicalLocale = cache . wrap ( getCanonicalLocale , ( locale ) => locale ) ;
272176}
0 commit comments