Skip to content

Commit

Permalink
feat: initial idea
Browse files Browse the repository at this point in the history
  • Loading branch information
markuczy committed Jul 15, 2024
1 parent cbc274b commit 96578bb
Show file tree
Hide file tree
Showing 4 changed files with 31 additions and 59 deletions.
Original file line number Diff line number Diff line change
@@ -1,69 +1,51 @@
import { Injectable, OnDestroy } from '@angular/core'
import { BehaviorSubject, Observable, filter, first, map, of, race, tap, withLatestFrom } from 'rxjs'
import { Observable, filter, map, of, tap } from 'rxjs'
import { SyncableTopic } from '@onecx/accelerator'

// This topic is defined here and not in integration-interface, because
// it is not used as framework independent integration but for improving
// angular specific things
class TranslationCacheTopic extends SyncableTopic<Record<string, any>> {
class TranslationCacheTopic extends SyncableTopic<string> {
constructor() {
super('translationCache', 1)
super('translationCache', 2)
}
}

declare global {
interface Window {
onecxTranslations: Record<string, any>
}
}

@Injectable({ providedIn: 'root' })
export class TranslationCacheService implements OnDestroy {
private id = ''
private translationTopic$ = new TranslationCacheTopic()
private translations$ = new BehaviorSubject<any>({})
constructor() {
this.translationTopic$
.pipe(
filter((message) => message['id'] === this.id),
withLatestFrom(this.translations$),
map(([topicTranslations, translations]) => {
let foundValueOthersDoNotKnow = false
const newTranslations = { ...translations }
Object.keys(topicTranslations).forEach((k) => {
if (!topicTranslations[k] && translations[k] && k !== this.id) {
foundValueOthersDoNotKnow = true
}
newTranslations[k] ??= topicTranslations[k]
})
return [newTranslations, foundValueOthersDoNotKnow]
}),
tap(([newTranslations, foundValueOthersDoNotKnow]) => {
if (foundValueOthersDoNotKnow) {
this.translationTopic$.publish(newTranslations)
}
}),
map(([newTranslations]) => newTranslations)
)
.subscribe(this.translations$)
window['onecxTranslations'] ??= {}
}
ngOnDestroy(): void {
this.translationTopic$.destroy()
}

setId(id: string) {
this.id = 'translation-'.concat(id)
}

getTranslationFile(url: string, cacheMissFunction: () => Observable<any>): Observable<any> {
if (this.translations$.value[url]) {
return of(this.translations$.value[url])
if (window['onecxTranslations'][url]) {
return of(window['onecxTranslations'][url])
}
this.translationTopic$.publish({ ...this.translations$.value, [url]: null, id: this.id })
return race(
this.translations$.pipe(
filter((t) => t[url]),
map((t) => t[url])
),
cacheMissFunction().pipe(
tap((t) => {
this.translationTopic$.publish({ ...this.translations$.value, [url]: t, id: this.id })
})

if (window['onecxTranslations'][url] === null) {
return this.translationTopic$.pipe(
filter((messageUrl) => messageUrl === url),
map(() => window['onecxTranslations'][url])
)
).pipe(first())
}

window['onecxTranslations'][url] = null
return cacheMissFunction().pipe(
tap((t) => {
this.translationTopic$.publish(url)
window['onecxTranslations'][url] = t
}),
map(() => window['onecxTranslations'][url])
)
}
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { Location } from '@angular/common'
import { HttpClient } from '@angular/common/http'
import { inject, InjectionToken } from '@angular/core'
import { inject } from '@angular/core'
import { TranslateLoader } from '@ngx-translate/core'
import { map, ReplaySubject, tap } from 'rxjs'
import { TranslationCacheService } from '../services/translation-cache.service'
Expand All @@ -10,16 +10,12 @@ import { TranslateCombinedLoader } from './translate.combined.loader'

let lastTranslateLoaderTimerId = 0

export const REMOTE_COMPONENT_ID = new InjectionToken<string>('REMOTE_COMPONENT_ID')

export function createRemoteComponentTranslateLoader(
http: HttpClient,
baseUrlReplaySubject$: ReplaySubject<string>,
remoteComponentId: string,
translationCacheService?: TranslationCacheService
): TranslateLoader {
const ts = translationCacheService ?? inject(TranslationCacheService)
ts.setId(remoteComponentId)
const timerId = lastTranslateLoaderTimerId++

console.time('createRemoteComponentTranslateLoader_' + timerId)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ describe('CreateTranslateLoader', () => {
currentMfe$ = of({ remoteBaseUrl: 'remoteUrl' })
globalLoading$ = of(false)
const translateLoader = environmentInjector.runInContext(() =>
createTranslateLoader(httpClientMock, <AppStateService>(<unknown>appStateServiceMock), 'mfe_id')
createTranslateLoader(httpClientMock, <AppStateService>(<unknown>appStateServiceMock))
)

translateLoader.getTranslation('en').subscribe(() => {
Expand All @@ -70,7 +70,7 @@ describe('CreateTranslateLoader', () => {
currentMfe$ = of({})
globalLoading$ = of(true)
const translateLoader = environmentInjector.runInContext(() =>
createTranslateLoader(httpClientMock, <AppStateService>(<unknown>appStateServiceMock), 'mfe_id')
createTranslateLoader(httpClientMock, <AppStateService>(<unknown>appStateServiceMock))
)

translateLoader.getTranslation('en').subscribe(() => {
Expand All @@ -87,7 +87,6 @@ describe('CreateTranslateLoader', () => {
const translateLoader = createTranslateLoader(
httpClientMock,
<AppStateService>(<unknown>appStateServiceMock),
'mfe_id',
translationCacheService
)

Expand All @@ -103,7 +102,6 @@ describe('CreateTranslateLoader', () => {
const translateLoader = createTranslateLoader(
httpClientMock,
<AppStateService>(<unknown>appStateServiceMock),
'mfe_id',
translationCacheService
)

Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { Location } from '@angular/common'
import { HttpClient } from '@angular/common/http'
import { InjectionToken, inject } from '@angular/core'
import { inject } from '@angular/core'
import { TranslateLoader } from '@ngx-translate/core'
import { AppStateService } from '@onecx/angular-integration-interface'
import { combineLatest, filter, map, tap } from 'rxjs'
Expand All @@ -11,16 +11,12 @@ import { TranslateCombinedLoader } from './translate.combined.loader'

let lastTranslateLoaderTimerId = 0

export const MFE_ID = new InjectionToken<string>('MFE_ID')

export function createTranslateLoader(
http: HttpClient,
appStateService: AppStateService,
mfeId: string,
translationCacheService?: TranslationCacheService
): TranslateLoader {
const ts = translationCacheService ?? inject(TranslationCacheService)
ts.setId(mfeId)
const timerId = lastTranslateLoaderTimerId++

console.time('createTranslateLoader_' + timerId)
Expand Down

0 comments on commit 96578bb

Please sign in to comment.