Skip to content

Commit 5df7dda

Browse files
committed
feat(store): clean implementation
1 parent 941c610 commit 5df7dda

File tree

2 files changed

+49
-45
lines changed

2 files changed

+49
-45
lines changed

projects/ngx-translate/src/lib/translate.service.ts

Lines changed: 22 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -185,8 +185,6 @@ export class TranslateService implements ITranslateService, OnDestroy {
185185
private missingTranslationHandler = inject(MissingTranslationHandler);
186186
private store: TranslateStore = inject(TranslateStore);
187187

188-
private _loaderIndex!: number;
189-
190188
private readonly extend: boolean = false;
191189

192190
/**
@@ -227,8 +225,6 @@ export class TranslateService implements ITranslateService, OnDestroy {
227225
}
228226

229227
constructor() {
230-
this._loaderIndex = this.store.addLoader(inject(TranslateLoader));
231-
232228
const config: TranslateServiceConfig = {
233229
extend: false,
234230
fallbackLang: null,
@@ -249,10 +245,12 @@ export class TranslateService implements ITranslateService, OnDestroy {
249245
if (config.extend) {
250246
this.extend = true;
251247
}
248+
249+
this.store.addLoader(this.currentLoader);
252250
}
253251

254-
ngOnDestroy() {
255-
this.store.removeLoader(this._loaderIndex);
252+
ngOnDestroy(): void {
253+
this.store.removeLoader(this.currentLoader);
256254
}
257255

258256
/**
@@ -350,28 +348,24 @@ export class TranslateService implements ITranslateService, OnDestroy {
350348
this.pending = true;
351349

352350
const loaders = this.store.getLoaders();
353-
if (loaders.size === 0) return of({} as InterpolatableTranslationObject);
354-
355-
const requests: Observable<TranslationObject>[] = [];
356-
loaders.forEach((loader) => {
357-
requests.push(loader.getTranslation(lang).pipe(take(1)));
358-
});
351+
let loadAndMerge: Observable<TranslationObject>;
352+
353+
if (loaders.length === 0) {
354+
return of({} as InterpolatableTranslationObject);
355+
} else if (loaders.length === 1) {
356+
loadAndMerge = loaders[0].getTranslation(lang);
357+
} else {
358+
const requests: Observable<TranslationObject>[] = loaders.map((loader) =>
359+
loader.getTranslation(lang).pipe(take(1)),
360+
);
361+
loadAndMerge = forkJoin(requests).pipe(
362+
map((results: TranslationObject[]) =>
363+
results.reduce((acc, curr) => mergeDeep(acc, curr), {} as TranslationObject),
364+
),
365+
);
366+
}
359367

360-
// Merge all translation objects
361-
const loadingTranslations = (
362-
requests.length > 1
363-
? forkJoin(requests).pipe(
364-
map((results: TranslationObject[]) =>
365-
results.reduce(
366-
(acc, curr) => mergeDeep(acc, curr),
367-
{} as TranslationObject,
368-
),
369-
),
370-
)
371-
: requests[0]
372-
).pipe(shareReplay(1), take(1));
373-
374-
this.loadingTranslations = loadingTranslations.pipe(
368+
this.loadingTranslations = loadAndMerge.pipe(shareReplay(1), take(1)).pipe(
375369
map((res: TranslationObject) => this.compiler.compileTranslations(res, lang)),
376370
shareReplay(1),
377371
take(1),
@@ -388,7 +382,7 @@ export class TranslateService implements ITranslateService, OnDestroy {
388382
},
389383
});
390384

391-
return loadingTranslations;
385+
return this.loadingTranslations;
392386
}
393387

394388
/**

projects/ngx-translate/src/lib/translate.store.ts

Lines changed: 27 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
import { Injectable } from "@angular/core";
22
import { Observable, Subject } from "rxjs";
3-
import { TranslateLoader } from "./translate.loader";
43
import {
54
FallbackLangChangeEvent,
65
InterpolatableTranslation,
@@ -10,11 +9,17 @@ import {
109
TranslationChangeEvent,
1110
} from "./translate.service";
1211
import { getValue, mergeDeep } from "./util";
12+
import { TranslateLoader } from "./translate.loader";
1313

1414
export type DeepReadonly<T> = {
1515
readonly [K in keyof T]: T[K] extends object ? DeepReadonly<T[K]> : T[K];
1616
};
1717

18+
interface LoaderReference {
19+
loader: TranslateLoader;
20+
count: number;
21+
}
22+
1823
@Injectable()
1924
export class TranslateStore {
2025
private _onTranslationChange: Subject<TranslationChangeEvent> =
@@ -29,27 +34,33 @@ export class TranslateStore {
2934
private translations: Record<Language, InterpolatableTranslationObject> = {};
3035
private languages: Language[] = [];
3136

32-
private loaders = new Map<number, TranslateLoader>();
37+
private loaders: LoaderReference[] = [];
3338

34-
/**
35-
* Adds a new loader to the store
36-
* @returns the index of the newly added loader
37-
*/
38-
addLoader(loader: TranslateLoader) {
39-
let loaderIndex = 0;
40-
while (this.loaders.has(loaderIndex)) {
41-
loaderIndex++;
39+
public addLoader(loader: TranslateLoader): void {
40+
const existingLoader = this.getLoaderRef(loader);
41+
if (existingLoader) {
42+
existingLoader.count++;
43+
} else {
44+
this.loaders.push({ loader, count: 1 });
4245
}
43-
this.loaders.set(loaderIndex, loader);
44-
return loaderIndex;
4546
}
4647

47-
removeLoader(loaderIndex: number) {
48-
if (this.loaders.has(loaderIndex)) this.loaders.delete(loaderIndex);
48+
public removeLoader(loader: TranslateLoader): void {
49+
const existingLoader = this.getLoaderRef(loader);
50+
if (existingLoader) {
51+
existingLoader.count--;
52+
if (existingLoader.count === 0) {
53+
this.loaders = this.loaders.filter((ref) => ref.loader !== loader);
54+
}
55+
}
4956
}
5057

51-
getLoaders() {
52-
return this.loaders;
58+
private getLoaderRef(loader: TranslateLoader): LoaderReference | undefined {
59+
return this.loaders.find((ref) => ref.loader === loader);
60+
}
61+
62+
public getLoaders(): TranslateLoader[] {
63+
return this.loaders.map((ref) => ref.loader);
5364
}
5465

5566
public getTranslations(language: Language): DeepReadonly<InterpolatableTranslationObject> {
@@ -96,7 +107,6 @@ export class TranslateStore {
96107

97108
public setCurrentLang(lang: string, emitChange = true): void {
98109
this.currentLang = lang;
99-
100110
if (emitChange) {
101111
this._onLangChange.next({ lang: lang, translations: this.translations[lang] });
102112
}

0 commit comments

Comments
 (0)