Files
marketplaces/src/app/i18n/translate.service.ts

74 lines
2.2 KiB
TypeScript
Raw Normal View History

perf(app): lazy-load i18n translation packs, drop dead items-carousel component RC PERF-01 bundle audit follow-up on 61a5714. - i18n: ru/en/hy translation packs (346 KB raw combined) were all statically imported in TranslateService and shipped in the initial bundle regardless of the visitor's language. Now only 'ru' (platform default) is bundled eagerly; 'en'/'hy' are dynamic import()s. The language route guard (languageGuard) awaits preloadLanguage() before activating the route, so translations are always fully loaded before any component renders - no flash of untranslated/fallback content. - widget-host.service.ts: import UnknownWidgetComponent directly instead of via the widgets/ui barrel (index.ts re-exports 6 widgets). - Deleted src/app/components/items-carousel/* - confirmed dead (zero references anywhere, verified via knip and grep), the only consumer of primeng/primeicons in the app. Removed the now-unused `@import 'primeicons/primeicons.css'` from styles.scss (no primeicons CSS classes used elsewhere). primeng/primeicons remain listed in package.json/package-lock.json - npm CLI in this environment is blocked by an unrelated, pre-existing broken `barry-cache` devDependency (ETARGET on `npm install`/`npm uninstall`), so the lockfile could not be safely regenerated. Flagged, not fixed. Routes audit (app.routes.ts): all storefront/builder/backoffice feature routes already use loadComponent/loadChildren; nothing eagerly imported. No route changes needed. Lucide icons (icon-registry.ts): already named/tree-shakeable imports from @lucide/angular, not a full-library import. No change needed. Before/after (npm run build, production): - Initial bundle raw: 1.47 MB -> 1.12 MB (-350 KB / -24%) - Initial bundle transfer (est.): 263.59 kB -> 221.51 kB (-42 kB / -16%) - Budget overage: 769.22 kB over -> 416.84 kB over (still exceeds the 700 KB budget; project-editor-page-component (320 kB), catalog-container-component (126 kB), product-details-container (88 kB), cart-component (61 kB) lazy chunks unchanged - no safe mechanical split identified within scope, see PERF-01 report for detail). Verified: npx tsc --noEmit clean, npm run build green (warning only, no errors). Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-07-24 08:19:13 +04:00
import { Injectable, computed, inject, signal } from '@angular/core';
2026-02-26 23:09:20 +04:00
import { LanguageService } from '../services/language.service';
import { Translations } from './translations';
import { ru } from './ru';
perf(app): lazy-load i18n translation packs, drop dead items-carousel component RC PERF-01 bundle audit follow-up on 61a5714. - i18n: ru/en/hy translation packs (346 KB raw combined) were all statically imported in TranslateService and shipped in the initial bundle regardless of the visitor's language. Now only 'ru' (platform default) is bundled eagerly; 'en'/'hy' are dynamic import()s. The language route guard (languageGuard) awaits preloadLanguage() before activating the route, so translations are always fully loaded before any component renders - no flash of untranslated/fallback content. - widget-host.service.ts: import UnknownWidgetComponent directly instead of via the widgets/ui barrel (index.ts re-exports 6 widgets). - Deleted src/app/components/items-carousel/* - confirmed dead (zero references anywhere, verified via knip and grep), the only consumer of primeng/primeicons in the app. Removed the now-unused `@import 'primeicons/primeicons.css'` from styles.scss (no primeicons CSS classes used elsewhere). primeng/primeicons remain listed in package.json/package-lock.json - npm CLI in this environment is blocked by an unrelated, pre-existing broken `barry-cache` devDependency (ETARGET on `npm install`/`npm uninstall`), so the lockfile could not be safely regenerated. Flagged, not fixed. Routes audit (app.routes.ts): all storefront/builder/backoffice feature routes already use loadComponent/loadChildren; nothing eagerly imported. No route changes needed. Lucide icons (icon-registry.ts): already named/tree-shakeable imports from @lucide/angular, not a full-library import. No change needed. Before/after (npm run build, production): - Initial bundle raw: 1.47 MB -> 1.12 MB (-350 KB / -24%) - Initial bundle transfer (est.): 263.59 kB -> 221.51 kB (-42 kB / -16%) - Budget overage: 769.22 kB over -> 416.84 kB over (still exceeds the 700 KB budget; project-editor-page-component (320 kB), catalog-container-component (126 kB), product-details-container (88 kB), cart-component (61 kB) lazy chunks unchanged - no safe mechanical split identified within scope, see PERF-01 report for detail). Verified: npx tsc --noEmit clean, npm run build green (warning only, no errors). Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-07-24 08:19:13 +04:00
// 'ru' is the platform default language, so it's the only translation pack
// bundled eagerly. 'en'/'hy' are code-split and fetched on demand via
// preloadLanguage() (invoked from languageGuard, which awaits it before
// route activation - components never observe a partially-loaded pack).
const translationLoaders: Record<string, () => Promise<Translations>> = {
en: () => import('./en').then(m => m.en),
hy: () => import('./hy').then(m => m.hy),
};
2026-02-26 23:09:20 +04:00
@Injectable({
providedIn: 'root',
})
export class TranslateService {
private langService = inject(LanguageService);
perf(app): lazy-load i18n translation packs, drop dead items-carousel component RC PERF-01 bundle audit follow-up on 61a5714. - i18n: ru/en/hy translation packs (346 KB raw combined) were all statically imported in TranslateService and shipped in the initial bundle regardless of the visitor's language. Now only 'ru' (platform default) is bundled eagerly; 'en'/'hy' are dynamic import()s. The language route guard (languageGuard) awaits preloadLanguage() before activating the route, so translations are always fully loaded before any component renders - no flash of untranslated/fallback content. - widget-host.service.ts: import UnknownWidgetComponent directly instead of via the widgets/ui barrel (index.ts re-exports 6 widgets). - Deleted src/app/components/items-carousel/* - confirmed dead (zero references anywhere, verified via knip and grep), the only consumer of primeng/primeicons in the app. Removed the now-unused `@import 'primeicons/primeicons.css'` from styles.scss (no primeicons CSS classes used elsewhere). primeng/primeicons remain listed in package.json/package-lock.json - npm CLI in this environment is blocked by an unrelated, pre-existing broken `barry-cache` devDependency (ETARGET on `npm install`/`npm uninstall`), so the lockfile could not be safely regenerated. Flagged, not fixed. Routes audit (app.routes.ts): all storefront/builder/backoffice feature routes already use loadComponent/loadChildren; nothing eagerly imported. No route changes needed. Lucide icons (icon-registry.ts): already named/tree-shakeable imports from @lucide/angular, not a full-library import. No change needed. Before/after (npm run build, production): - Initial bundle raw: 1.47 MB -> 1.12 MB (-350 KB / -24%) - Initial bundle transfer (est.): 263.59 kB -> 221.51 kB (-42 kB / -16%) - Budget overage: 769.22 kB over -> 416.84 kB over (still exceeds the 700 KB budget; project-editor-page-component (320 kB), catalog-container-component (126 kB), product-details-container (88 kB), cart-component (61 kB) lazy chunks unchanged - no safe mechanical split identified within scope, see PERF-01 report for detail). Verified: npx tsc --noEmit clean, npm run build green (warning only, no errors). Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-07-24 08:19:13 +04:00
private readonly translationCache = signal<Record<string, Translations>>({ ru });
2026-02-26 23:09:20 +04:00
readonly translations = computed<Translations>(
perf(app): lazy-load i18n translation packs, drop dead items-carousel component RC PERF-01 bundle audit follow-up on 61a5714. - i18n: ru/en/hy translation packs (346 KB raw combined) were all statically imported in TranslateService and shipped in the initial bundle regardless of the visitor's language. Now only 'ru' (platform default) is bundled eagerly; 'en'/'hy' are dynamic import()s. The language route guard (languageGuard) awaits preloadLanguage() before activating the route, so translations are always fully loaded before any component renders - no flash of untranslated/fallback content. - widget-host.service.ts: import UnknownWidgetComponent directly instead of via the widgets/ui barrel (index.ts re-exports 6 widgets). - Deleted src/app/components/items-carousel/* - confirmed dead (zero references anywhere, verified via knip and grep), the only consumer of primeng/primeicons in the app. Removed the now-unused `@import 'primeicons/primeicons.css'` from styles.scss (no primeicons CSS classes used elsewhere). primeng/primeicons remain listed in package.json/package-lock.json - npm CLI in this environment is blocked by an unrelated, pre-existing broken `barry-cache` devDependency (ETARGET on `npm install`/`npm uninstall`), so the lockfile could not be safely regenerated. Flagged, not fixed. Routes audit (app.routes.ts): all storefront/builder/backoffice feature routes already use loadComponent/loadChildren; nothing eagerly imported. No route changes needed. Lucide icons (icon-registry.ts): already named/tree-shakeable imports from @lucide/angular, not a full-library import. No change needed. Before/after (npm run build, production): - Initial bundle raw: 1.47 MB -> 1.12 MB (-350 KB / -24%) - Initial bundle transfer (est.): 263.59 kB -> 221.51 kB (-42 kB / -16%) - Budget overage: 769.22 kB over -> 416.84 kB over (still exceeds the 700 KB budget; project-editor-page-component (320 kB), catalog-container-component (126 kB), product-details-container (88 kB), cart-component (61 kB) lazy chunks unchanged - no safe mechanical split identified within scope, see PERF-01 report for detail). Verified: npx tsc --noEmit clean, npm run build green (warning only, no errors). Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-07-24 08:19:13 +04:00
() => this.translationCache()[this.langService.currentLanguage()] ?? ru,
2026-02-26 23:09:20 +04:00
);
perf(app): lazy-load i18n translation packs, drop dead items-carousel component RC PERF-01 bundle audit follow-up on 61a5714. - i18n: ru/en/hy translation packs (346 KB raw combined) were all statically imported in TranslateService and shipped in the initial bundle regardless of the visitor's language. Now only 'ru' (platform default) is bundled eagerly; 'en'/'hy' are dynamic import()s. The language route guard (languageGuard) awaits preloadLanguage() before activating the route, so translations are always fully loaded before any component renders - no flash of untranslated/fallback content. - widget-host.service.ts: import UnknownWidgetComponent directly instead of via the widgets/ui barrel (index.ts re-exports 6 widgets). - Deleted src/app/components/items-carousel/* - confirmed dead (zero references anywhere, verified via knip and grep), the only consumer of primeng/primeicons in the app. Removed the now-unused `@import 'primeicons/primeicons.css'` from styles.scss (no primeicons CSS classes used elsewhere). primeng/primeicons remain listed in package.json/package-lock.json - npm CLI in this environment is blocked by an unrelated, pre-existing broken `barry-cache` devDependency (ETARGET on `npm install`/`npm uninstall`), so the lockfile could not be safely regenerated. Flagged, not fixed. Routes audit (app.routes.ts): all storefront/builder/backoffice feature routes already use loadComponent/loadChildren; nothing eagerly imported. No route changes needed. Lucide icons (icon-registry.ts): already named/tree-shakeable imports from @lucide/angular, not a full-library import. No change needed. Before/after (npm run build, production): - Initial bundle raw: 1.47 MB -> 1.12 MB (-350 KB / -24%) - Initial bundle transfer (est.): 263.59 kB -> 221.51 kB (-42 kB / -16%) - Budget overage: 769.22 kB over -> 416.84 kB over (still exceeds the 700 KB budget; project-editor-page-component (320 kB), catalog-container-component (126 kB), product-details-container (88 kB), cart-component (61 kB) lazy chunks unchanged - no safe mechanical split identified within scope, see PERF-01 report for detail). Verified: npx tsc --noEmit clean, npm run build green (warning only, no errors). Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-07-24 08:19:13 +04:00
/**
* Ensures the given language's translation pack is loaded before it is
* activated. Resolves immediately for already-loaded packs (including
* the eagerly-bundled 'ru'); dynamically imports otherwise.
*/
async preloadLanguage(lang: string): Promise<void> {
if (this.translationCache()[lang]) {
return;
}
const loader = translationLoaders[lang];
if (!loader) {
return;
}
const pack = await loader();
this.translationCache.update(cache => ({ ...cache, [lang]: pack }));
}
2026-02-26 23:09:20 +04:00
/**
* Translate a dot-separated key with optional interpolation params.
* Usage: t('cart.phoneMoreDigits', { count: 3 }) "Введите ещё 3 цифр"
*/
t(key: string, params?: Record<string, string | number>): string {
const parts = key.split('.');
let result: unknown = this.translations();
for (const part of parts) {
if (result && typeof result === 'object') {
result = (result as Record<string, unknown>)[part];
} else {
return key;
}
}
if (typeof result !== 'string') {
return key;
}
if (params) {
return result.replace(/\{\{(\w+)\}\}/g, (_, k) =>
params[k] !== undefined ? String(params[k]) : `{{${k}}}`,
);
}
return result;
}
}