@yaagoub/federation-tools 1.1.2 → 1.1.3

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.
@@ -28,6 +28,8 @@ class EnvService {
28
28
  http = inject(HttpClient);
29
29
  federation = inject(Federation);
30
30
  envMap = inject(APP_CONFIG_ENV);
31
+ loading;
32
+ loaded = false;
31
33
  getManifestUrl() {
32
34
  return this.federation.getShellOrigin() + '/env.manifest.json';
33
35
  }
@@ -35,19 +37,31 @@ class EnvService {
35
37
  return origin.replace(/\/+$/, '') + '/env.json';
36
38
  }
37
39
  async load() {
38
- try {
40
+ if (this.loaded)
41
+ return;
42
+ if (this.loading)
43
+ return this.loading;
44
+ this.loading = (async () => {
39
45
  const envManifest = await firstValueFrom(this.http.get(this.getManifestUrl()));
40
- const remoteNames = Object.keys(envManifest);
41
- const remoteLoads = remoteNames.map(async (remoteName) => {
42
- const remoteOrigin = envManifest[remoteName];
43
- const env = await firstValueFrom(this.http.get(this.getRemoteEnvUrl(remoteOrigin)));
44
- this.envMap.set(remoteName, env);
45
- });
46
- await Promise.all(remoteLoads);
46
+ await Promise.all(Object.entries(envManifest).map(async ([name, origin]) => {
47
+ if (this.envMap.has(name))
48
+ return;
49
+ const env = await firstValueFrom(this.http.get(this.getRemoteEnvUrl(origin)));
50
+ this.envMap.set(name, env);
51
+ }));
52
+ this.loaded = true;
53
+ })();
54
+ return this.loading;
55
+ }
56
+ async ensure(remoteName) {
57
+ if (!this.envMap.has(remoteName)) {
58
+ await this.load();
47
59
  }
48
- catch (e) {
49
- throw new Error(`Failed to load environment configuration; cannot continue. ${e?.message ?? e}`);
60
+ const env = this.envMap.get(remoteName);
61
+ if (!env) {
62
+ throw new Error(`Env "${remoteName}" not found after retry`);
50
63
  }
64
+ return env;
51
65
  }
52
66
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: EnvService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
53
67
  static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: EnvService, providedIn: 'root' });
@@ -59,27 +73,41 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.15", ngImpo
59
73
 
60
74
  class Env {
61
75
  envMap = inject(APP_CONFIG_ENV);
62
- get(remoteName) {
63
- const v = this.envMap.get(remoteName);
64
- if (!v) {
65
- throw new Error(`Env for "${remoteName}" not loaded. Did you register provideAppInitializer(() => env.load()) ?`);
76
+ envService = inject(EnvService);
77
+ /**
78
+ * Safe async access (recommended)
79
+ */
80
+ async get(remoteName) {
81
+ if (this.envMap.has(remoteName)) {
82
+ return this.envMap.get(remoteName);
66
83
  }
67
- return v;
84
+ return this.envService.ensure(remoteName);
85
+ }
86
+ /**
87
+ * Sync access (only after bootstrap)
88
+ */
89
+ getSync(remoteName) {
90
+ const env = this.envMap.get(remoteName);
91
+ if (!env) {
92
+ throw new Error(`Env "${remoteName}" not ready. Use get() instead.`);
93
+ }
94
+ return env;
95
+ }
96
+ has(remoteName) {
97
+ return this.envMap.has(remoteName);
68
98
  }
69
99
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: Env, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
70
100
  static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: Env, providedIn: 'root' });
71
101
  }
72
102
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: Env, decorators: [{
73
103
  type: Injectable,
74
- args: [{
75
- providedIn: 'root'
76
- }]
104
+ args: [{ providedIn: 'root' }]
77
105
  }] });
78
106
 
79
107
  function provideFederationEnv() {
80
108
  return makeEnvironmentProviders([
81
109
  EnvService, Federation, Env,
82
- { provide: APP_CONFIG_ENV, useValue: new Map() },
110
+ { provide: APP_CONFIG_ENV, useFactory: () => new Map() },
83
111
  provideAppInitializer(() => inject(EnvService).load()),
84
112
  ]);
85
113
  }
@@ -198,12 +226,27 @@ class TranslationRegistry {
198
226
  http = inject(HttpClient);
199
227
  federation = inject(Federation);
200
228
  store = inject(APP_TRANSLATIONS_STORE);
229
+ loading = new Map();
230
+ loaded = new Set();
201
231
  async load(lang) {
202
- const manifest = await firstValueFrom(this.http.get(this.federation.getShellOrigin() + '/i18n.manifest.json'));
203
- await Promise.all(Object.entries(manifest).map(async ([name, origin]) => {
204
- const translations = await firstValueFrom(this.http.get(`${origin}/i18n/${lang}.json`));
205
- this.store.set(name, translations);
206
- }));
232
+ if (this.loaded.has(lang))
233
+ return;
234
+ if (this.loading.has(lang)) {
235
+ return this.loading.get(lang);
236
+ }
237
+ const promise = (async () => {
238
+ const manifest = await firstValueFrom(this.http.get(this.federation.getShellOrigin() + '/i18n.manifest.json'));
239
+ const entries = await Promise.all(Object.entries(manifest).map(async ([name, origin]) => {
240
+ const translations = await firstValueFrom(this.http.get(`${origin}/i18n/${lang}.json`));
241
+ return [name, translations];
242
+ }));
243
+ // ⚠ atomic commit (important)
244
+ entries.forEach(([name, translations]) => this.store.set(name, translations));
245
+ this.loaded.add(lang);
246
+ })();
247
+ this.loading.set(lang, promise);
248
+ await promise;
249
+ this.loading.delete(lang);
207
250
  }
208
251
  getMergedTranslations() {
209
252
  const result = {};
@@ -220,11 +263,11 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.15", ngImpo
220
263
 
221
264
  function provideFederationTranslation() {
222
265
  return makeEnvironmentProviders([
266
+ TranslationRegistry,
223
267
  {
224
268
  provide: APP_TRANSLATIONS_STORE,
225
269
  useFactory: () => new Map(),
226
- },
227
- TranslationRegistry,
270
+ }
228
271
  ]);
229
272
  }
230
273
 
@@ -1 +1 @@
1
- {"version":3,"file":"yaagoub-federation-tools.mjs","sources":["../../../projects/federation-tools/src/federation/federation.service.ts","../../../projects/federation-tools/src/env/env.service.ts","../../../projects/federation-tools/src/env/env.ts","../../../projects/federation-tools/src/providers/provide-env.ts","../../../projects/federation-tools/src/asset/asset.service.ts","../../../projects/federation-tools/src/asset/asset.ts","../../../projects/federation-tools/src/asset/asset.directive.ts","../../../projects/federation-tools/src/providers/provide-assets.ts","../../../projects/federation-tools/src/i18n/translation-registry.service.ts","../../../projects/federation-tools/src/providers/provide-trans.ts","../../../projects/federation-tools/src/i18n/federated-translate.loader.ts","../../../projects/federation-tools/src/yaagoub-federation-tools.ts"],"sourcesContent":["import { Injectable } from \"@angular/core\";\r\n\r\n@Injectable({\r\n providedIn: 'root'\r\n})\r\nexport class Federation {\r\n getShellOrigin(): string {\r\n return window.location.origin;\r\n }\r\n}\r\n","import { inject, Injectable } from '@angular/core';\r\nimport { HttpClient } from '@angular/common/http';\r\nimport { firstValueFrom } from 'rxjs';\r\nimport { InjectionToken } from '@angular/core';\r\nimport { Federation } from '../federation/federation.service';\r\n\r\nexport type EnvMap = Map<string, Record<string, any>>;\r\n\r\n/**\r\n * Holds all loaded env objects:\r\n * - key: remoteName (from env-manifest.json) + 'shell'\r\n * - value: parsed env.json for that remote\r\n */\r\nexport const APP_CONFIG_ENV = new InjectionToken<EnvMap>('env-settings');\r\n\r\n@Injectable({ providedIn: 'root' })\r\nexport class EnvService {\r\n private readonly http = inject(HttpClient);\r\n private readonly federation = inject(Federation);\r\n private readonly envMap: EnvMap = inject(APP_CONFIG_ENV);\r\n\r\n private getManifestUrl(): string {\r\n return this.federation.getShellOrigin() + '/env.manifest.json';\r\n }\r\n\r\n private getRemoteEnvUrl(origin: string): string {\r\n return origin.replace(/\\/+$/, '') + '/env.json';\r\n }\r\n\r\n async load(): Promise<void> {\r\n try {\r\n const envManifest = await firstValueFrom(\r\n this.http.get<Record<string, string>>(this.getManifestUrl())\r\n );\r\n\r\n const remoteNames = Object.keys(envManifest);\r\n\r\n const remoteLoads = remoteNames.map(async (remoteName) => {\r\n const remoteOrigin = envManifest[remoteName];\r\n const env = await firstValueFrom(\r\n this.http.get<Record<string, any>>(this.getRemoteEnvUrl(remoteOrigin))\r\n );\r\n this.envMap.set(remoteName, env);\r\n });\r\n\r\n await Promise.all(remoteLoads);\r\n\r\n } catch (e: any) {\r\n throw new Error(\r\n `Failed to load environment configuration; cannot continue. ${e?.message ?? e}`\r\n );\r\n }\r\n }\r\n}\r\n","import { inject, Injectable } from \"@angular/core\";\r\nimport { APP_CONFIG_ENV, EnvMap } from \"./env.service\";\r\n\r\n@Injectable({\r\n providedIn: 'root'\r\n})\r\nexport class Env {\r\n private readonly envMap: EnvMap = inject(APP_CONFIG_ENV);\r\n\r\n get(remoteName: string): Record<string, any> {\r\n const v = this.envMap.get(remoteName);\r\n if (!v) {\r\n throw new Error(\r\n `Env for \"${remoteName}\" not loaded. Did you register provideAppInitializer(() => env.load()) ?`\r\n );\r\n }\r\n return v;\r\n }\r\n}","import { EnvironmentProviders, inject, makeEnvironmentProviders, provideAppInitializer } from '@angular/core';\nimport { APP_CONFIG_ENV, EnvService, EnvMap } from '../env/env.service';\nimport { Federation } from '../federation/federation.service';\nimport { Env } from '../env/env';\n\nexport function provideFederationEnv(): EnvironmentProviders {\n return makeEnvironmentProviders([\n EnvService, Federation, Env,\n { provide: APP_CONFIG_ENV, useValue: new Map() as EnvMap },\n provideAppInitializer(() => inject(EnvService).load()),\n ]);\n}","import { InjectionToken } from \"@angular/core\";\r\nimport { inject, Injectable } from '@angular/core';\r\nimport { HttpClient } from '@angular/common/http';\r\nimport { firstValueFrom } from 'rxjs';\r\n\r\nimport { Federation } from '../federation/federation.service';\r\n\r\nexport type AssetRegistry = Map<string, string>;\r\n\r\nexport const APP_CONFIG_ASSETS = new InjectionToken<AssetRegistry>('asset-registry');\r\n\r\n\r\n@Injectable({ providedIn: 'root' })\r\nexport class AssetService {\r\n\r\n private readonly http = inject(HttpClient);\r\n private readonly federation = inject(Federation);\r\n private readonly assets = inject(APP_CONFIG_ASSETS);\r\n\r\n private getAssetManifest() {\r\n return this.http.get<Record<string, string>>(\r\n this.federation.getShellOrigin() + '/assets.manifest.json'\r\n );\r\n }\r\n\r\n async load(): Promise<void> {\r\n try {\r\n const manifest = await firstValueFrom(this.getAssetManifest());\r\n\r\n // Remotes\r\n Object.entries(manifest).forEach(([remote, origin]) => {\r\n this.assets.set(remote, origin);\r\n });\r\n\r\n } catch (error) {\r\n throw new Error(\r\n 'Failed to load asset configuration, cannot continue. ' + error\r\n );\r\n }\r\n }\r\n\r\n resolve(assetRef: string): string {\r\n /**\r\n * assetRef format:\r\n * shell:logo.svg\r\n * user:img/avatar.png\r\n * doc:video/intro.mp4\r\n */\r\n\r\n if (!assetRef.includes(':')) {\r\n throw new Error(`Invalid asset reference: ${assetRef}`);\r\n }\r\n\r\n const [scope, path] = assetRef.split(':');\r\n const origin = this.assets.get(scope);\r\n\r\n if (!origin) {\r\n throw new Error(`Unknown asset scope: ${scope}`);\r\n }\r\n\r\n return `${origin}/${path}`;\r\n }\r\n\r\n}\r\n","import { inject, Injectable } from '@angular/core';\r\nimport { AssetService } from \"./asset.service\";\r\n\r\n\r\n@Injectable({ providedIn: 'root' })\r\nexport class Assets {\r\n private readonly assetService = inject(AssetService);\r\n\r\n get(assetRef: string): string {\r\n return this.assetService.resolve(assetRef);\r\n }\r\n}\r\n","import {\r\n Directive,\r\n ElementRef,\r\n OnChanges,\r\n inject,\r\n SimpleChanges,\r\n input,\r\n} from '@angular/core';\r\nimport { AssetService } from './asset.service';\r\n\r\n@Directive({\r\n selector: '[asset]',\r\n standalone: true,\r\n})\r\nexport class AssetDirective implements OnChanges {\r\n private readonly el = inject(ElementRef<HTMLElement>);\r\n private readonly assetService = inject(AssetService);\r\n\r\n asset = input<string>('');\r\n\r\n ngOnChanges(changes: SimpleChanges): void {\r\n if (!this.asset()) return;\r\n\r\n const url = this.assetService.resolve(this.asset());\r\n const nativeEl = this.el.nativeElement;\r\n\r\n const attr = this.detectAttribute(nativeEl);\r\n\r\n nativeEl.setAttribute(attr, url);\r\n }\r\n\r\n private detectAttribute(el: HTMLElement): string {\r\n const tag = el.tagName.toLowerCase();\r\n\r\n switch (tag) {\r\n case 'img':\r\n case 'video':\r\n case 'audio':\r\n case 'iframe':\r\n case 'source':\r\n return 'src';\r\n\r\n case 'a':\r\n return 'href';\r\n\r\n case 'object':\r\n return 'data';\r\n\r\n default:\r\n return 'src';\r\n }\r\n }\r\n}\r\n","import { inject, makeEnvironmentProviders, provideAppInitializer } from '@angular/core';\r\nimport { APP_CONFIG_ASSETS, AssetService } from '../asset/asset.service';\r\nimport { Assets } from '../asset/asset';\r\n\r\nexport function provideFederationAsset() {\r\n return makeEnvironmentProviders([\r\n AssetService, Assets,\r\n {\r\n provide: APP_CONFIG_ASSETS,\r\n useValue: new Map<string, string>(),\r\n },\r\n provideAppInitializer(() => inject(AssetService).load()),\r\n ]);\r\n}\r\n","import { Injectable, InjectionToken, inject } from '@angular/core';\r\nimport { HttpClient } from '@angular/common/http';\r\nimport { firstValueFrom } from 'rxjs';\r\n\r\nimport { Federation } from '../federation/federation.service';\r\n\r\nexport const APP_TRANSLATIONS_STORE =\r\n new InjectionToken<Map<string, any>>('APP_TRANSLATIONS_STORE');\r\n\r\n@Injectable({ providedIn: 'root' })\r\nexport class TranslationRegistry {\r\n private readonly http = inject(HttpClient);\r\n private readonly federation = inject(Federation);\r\n private readonly store = inject(APP_TRANSLATIONS_STORE);\r\n\r\n async load(lang: string): Promise<void> {\r\n\r\n const manifest = await firstValueFrom(\r\n this.http.get<Record<string, string>>(\r\n this.federation.getShellOrigin() + '/i18n.manifest.json'\r\n )\r\n );\r\n\r\n await Promise.all(\r\n Object.entries(manifest).map(async ([name, origin]) => {\r\n const translations = await firstValueFrom(\r\n this.http.get(`${origin}/i18n/${lang}.json`)\r\n );\r\n this.store.set(name, translations);\r\n }),\r\n );\r\n }\r\n\r\n getMergedTranslations(): any {\r\n const result: any = {};\r\n this.store.forEach(value => Object.assign(result, value));\r\n return result;\r\n }\r\n}\r\n","import { makeEnvironmentProviders } from '@angular/core';\r\nimport { APP_TRANSLATIONS_STORE, TranslationRegistry } from '../i18n/translation-registry.service';\r\n\r\n\r\nexport function provideFederationTranslation() {\r\n return makeEnvironmentProviders([\r\n {\r\n provide: APP_TRANSLATIONS_STORE,\r\n useFactory: () => new Map<string, any>(),\r\n },\r\n TranslationRegistry,\r\n ]);\r\n}\r\n","import { Injectable, inject } from '@angular/core';\r\nimport { TranslateLoader } from '@ngx-translate/core';\r\nimport { Observable, from } from 'rxjs';\r\nimport { map } from 'rxjs/operators';\r\nimport { TranslationRegistry } from './translation-registry.service';\r\n\r\n@Injectable({ providedIn: 'root' })\r\nexport class FederatedTranslateLoader implements TranslateLoader {\r\n private readonly registry = inject(TranslationRegistry);\r\n\r\n getTranslation(lang: string): Observable<any> {\r\n return from(this.registry.load(lang)).pipe(\r\n map(() => this.registry.getMergedTranslations())\r\n );\r\n }\r\n}\r\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"yaagoub-federation-tools.mjs","sources":["../../../projects/federation-tools/src/federation/federation.service.ts","../../../projects/federation-tools/src/env/env.service.ts","../../../projects/federation-tools/src/env/env.ts","../../../projects/federation-tools/src/providers/provide-env.ts","../../../projects/federation-tools/src/asset/asset.service.ts","../../../projects/federation-tools/src/asset/asset.ts","../../../projects/federation-tools/src/asset/asset.directive.ts","../../../projects/federation-tools/src/providers/provide-assets.ts","../../../projects/federation-tools/src/i18n/translation-registry.service.ts","../../../projects/federation-tools/src/providers/provide-trans.ts","../../../projects/federation-tools/src/i18n/federated-translate.loader.ts","../../../projects/federation-tools/src/yaagoub-federation-tools.ts"],"sourcesContent":["import { Injectable } from \"@angular/core\";\r\n\r\n@Injectable({\r\n providedIn: 'root'\r\n})\r\nexport class Federation {\r\n getShellOrigin(): string {\r\n return window.location.origin;\r\n }\r\n}\r\n","import { inject, Injectable } from '@angular/core';\r\nimport { HttpClient } from '@angular/common/http';\r\nimport { firstValueFrom } from 'rxjs';\r\nimport { InjectionToken } from '@angular/core';\r\nimport { Federation } from '../federation/federation.service';\r\n\r\nexport type EnvMap = Map<string, Record<string, any>>;\r\n\r\n/**\r\n * Holds all loaded env objects:\r\n * - key: remoteName (from env-manifest.json) + 'shell'\r\n * - value: parsed env.json for that remote\r\n */\r\nexport const APP_CONFIG_ENV = new InjectionToken<EnvMap>('env-settings');\r\n\r\n@Injectable({ providedIn: 'root' })\r\nexport class EnvService {\r\n private readonly http = inject(HttpClient);\r\n private readonly federation = inject(Federation);\r\n private readonly envMap: EnvMap = inject(APP_CONFIG_ENV);\r\n\r\n private loading?: Promise<void>;\r\n private loaded = false;\r\n\r\n private getManifestUrl(): string {\r\n return this.federation.getShellOrigin() + '/env.manifest.json';\r\n }\r\n\r\n private getRemoteEnvUrl(origin: string): string {\r\n return origin.replace(/\\/+$/, '') + '/env.json';\r\n }\r\n\r\n async load(): Promise<void> {\r\n if (this.loaded) return;\r\n if (this.loading) return this.loading;\r\n\r\n this.loading = (async () => {\r\n const envManifest = await firstValueFrom(\r\n this.http.get<Record<string, string>>(this.getManifestUrl())\r\n );\r\n\r\n await Promise.all(\r\n Object.entries(envManifest).map(async ([name, origin]) => {\r\n if (this.envMap.has(name)) return;\r\n\r\n const env = await firstValueFrom(\r\n this.http.get<Record<string, any>>(this.getRemoteEnvUrl(origin))\r\n );\r\n this.envMap.set(name, env);\r\n })\r\n );\r\n\r\n this.loaded = true;\r\n })();\r\n\r\n return this.loading;\r\n }\r\n\r\n async ensure(remoteName: string): Promise<Record<string, any>> {\r\n if (!this.envMap.has(remoteName)) {\r\n await this.load();\r\n }\r\n\r\n const env = this.envMap.get(remoteName);\r\n if (!env) {\r\n throw new Error(`Env \"${remoteName}\" not found after retry`);\r\n }\r\n\r\n return env;\r\n }\r\n}\r\n","import { inject, Injectable } from \"@angular/core\";\r\nimport { APP_CONFIG_ENV, EnvMap, EnvService } from \"./env.service\";\r\n\r\n\r\n@Injectable({ providedIn: 'root' })\r\nexport class Env {\r\n private readonly envMap = inject(APP_CONFIG_ENV);\r\n private readonly envService = inject(EnvService);\r\n\r\n /**\r\n * Safe async access (recommended)\r\n */\r\n async get(remoteName: string): Promise<Record<string, any>> {\r\n if (this.envMap.has(remoteName)) {\r\n return this.envMap.get(remoteName)!;\r\n }\r\n\r\n return this.envService.ensure(remoteName);\r\n }\r\n\r\n /**\r\n * Sync access (only after bootstrap)\r\n */\r\n getSync(remoteName: string): Record<string, any> {\r\n const env = this.envMap.get(remoteName);\r\n if (!env) {\r\n throw new Error(\r\n `Env \"${remoteName}\" not ready. Use get() instead.`\r\n );\r\n }\r\n return env;\r\n }\r\n\r\n has(remoteName: string): boolean {\r\n return this.envMap.has(remoteName);\r\n }\r\n}\r\n","import { EnvironmentProviders, inject, makeEnvironmentProviders, provideAppInitializer } from '@angular/core';\nimport { APP_CONFIG_ENV, EnvService, EnvMap } from '../env/env.service';\nimport { Federation } from '../federation/federation.service';\nimport { Env } from '../env/env';\n\nexport function provideFederationEnv(): EnvironmentProviders {\n return makeEnvironmentProviders([\n EnvService, Federation, Env,\n { provide: APP_CONFIG_ENV, useFactory: () => new Map() as EnvMap },\n provideAppInitializer(() => inject(EnvService).load()),\n ]);\n}","import { InjectionToken } from \"@angular/core\";\r\nimport { inject, Injectable } from '@angular/core';\r\nimport { HttpClient } from '@angular/common/http';\r\nimport { firstValueFrom } from 'rxjs';\r\n\r\nimport { Federation } from '../federation/federation.service';\r\n\r\nexport type AssetRegistry = Map<string, string>;\r\n\r\nexport const APP_CONFIG_ASSETS = new InjectionToken<AssetRegistry>('asset-registry');\r\n\r\n\r\n@Injectable({ providedIn: 'root' })\r\nexport class AssetService {\r\n\r\n private readonly http = inject(HttpClient);\r\n private readonly federation = inject(Federation);\r\n private readonly assets = inject(APP_CONFIG_ASSETS);\r\n\r\n private getAssetManifest() {\r\n return this.http.get<Record<string, string>>(\r\n this.federation.getShellOrigin() + '/assets.manifest.json'\r\n );\r\n }\r\n\r\n async load(): Promise<void> {\r\n try {\r\n const manifest = await firstValueFrom(this.getAssetManifest());\r\n\r\n // Remotes\r\n Object.entries(manifest).forEach(([remote, origin]) => {\r\n this.assets.set(remote, origin);\r\n });\r\n\r\n } catch (error) {\r\n throw new Error(\r\n 'Failed to load asset configuration, cannot continue. ' + error\r\n );\r\n }\r\n }\r\n\r\n resolve(assetRef: string): string {\r\n /**\r\n * assetRef format:\r\n * shell:logo.svg\r\n * user:img/avatar.png\r\n * doc:video/intro.mp4\r\n */\r\n\r\n if (!assetRef.includes(':')) {\r\n throw new Error(`Invalid asset reference: ${assetRef}`);\r\n }\r\n\r\n const [scope, path] = assetRef.split(':');\r\n const origin = this.assets.get(scope);\r\n\r\n if (!origin) {\r\n throw new Error(`Unknown asset scope: ${scope}`);\r\n }\r\n\r\n return `${origin}/${path}`;\r\n }\r\n\r\n}\r\n","import { inject, Injectable } from '@angular/core';\r\nimport { AssetService } from \"./asset.service\";\r\n\r\n\r\n@Injectable({ providedIn: 'root' })\r\nexport class Assets {\r\n private readonly assetService = inject(AssetService);\r\n\r\n get(assetRef: string): string {\r\n return this.assetService.resolve(assetRef);\r\n }\r\n}\r\n","import {\r\n Directive,\r\n ElementRef,\r\n OnChanges,\r\n inject,\r\n SimpleChanges,\r\n input,\r\n} from '@angular/core';\r\nimport { AssetService } from './asset.service';\r\n\r\n@Directive({\r\n selector: '[asset]',\r\n standalone: true,\r\n})\r\nexport class AssetDirective implements OnChanges {\r\n private readonly el = inject(ElementRef<HTMLElement>);\r\n private readonly assetService = inject(AssetService);\r\n\r\n asset = input<string>('');\r\n\r\n ngOnChanges(changes: SimpleChanges): void {\r\n if (!this.asset()) return;\r\n\r\n const url = this.assetService.resolve(this.asset());\r\n const nativeEl = this.el.nativeElement;\r\n\r\n const attr = this.detectAttribute(nativeEl);\r\n\r\n nativeEl.setAttribute(attr, url);\r\n }\r\n\r\n private detectAttribute(el: HTMLElement): string {\r\n const tag = el.tagName.toLowerCase();\r\n\r\n switch (tag) {\r\n case 'img':\r\n case 'video':\r\n case 'audio':\r\n case 'iframe':\r\n case 'source':\r\n return 'src';\r\n\r\n case 'a':\r\n return 'href';\r\n\r\n case 'object':\r\n return 'data';\r\n\r\n default:\r\n return 'src';\r\n }\r\n }\r\n}\r\n","import { inject, makeEnvironmentProviders, provideAppInitializer } from '@angular/core';\r\nimport { APP_CONFIG_ASSETS, AssetService } from '../asset/asset.service';\r\nimport { Assets } from '../asset/asset';\r\n\r\nexport function provideFederationAsset() {\r\n return makeEnvironmentProviders([\r\n AssetService, Assets,\r\n {\r\n provide: APP_CONFIG_ASSETS,\r\n useValue: new Map<string, string>(),\r\n },\r\n provideAppInitializer(() => inject(AssetService).load()),\r\n ]);\r\n}\r\n","import { Injectable, InjectionToken, inject } from '@angular/core';\r\nimport { HttpClient } from '@angular/common/http';\r\nimport { firstValueFrom } from 'rxjs';\r\n\r\nimport { Federation } from '../federation/federation.service';\r\n\r\nexport const APP_TRANSLATIONS_STORE =\r\n new InjectionToken<Map<string, any>>('APP_TRANSLATIONS_STORE');\r\n\r\n@Injectable({ providedIn: 'root' })\r\nexport class TranslationRegistry {\r\n private readonly http = inject(HttpClient);\r\n private readonly federation = inject(Federation);\r\n private readonly store = inject(APP_TRANSLATIONS_STORE);\r\n\r\n private loading = new Map<string, Promise<void>>();\r\n private loaded = new Set<string>();\r\n\r\n async load(lang: string): Promise<void> {\r\n if (this.loaded.has(lang)) return;\r\n\r\n if (this.loading.has(lang)) {\r\n return this.loading.get(lang)!;\r\n }\r\n\r\n const promise = (async () => {\r\n const manifest = await firstValueFrom(\r\n this.http.get<Record<string, string>>(\r\n this.federation.getShellOrigin() + '/i18n.manifest.json'\r\n )\r\n );\r\n\r\n const entries = await Promise.all(\r\n Object.entries(manifest).map(async ([name, origin]) => {\r\n const translations = await firstValueFrom(\r\n this.http.get(`${origin}/i18n/${lang}.json`)\r\n );\r\n return [name, translations] as const;\r\n })\r\n );\r\n\r\n // ⚠ atomic commit (important)\r\n entries.forEach(([name, translations]) =>\r\n this.store.set(name, translations)\r\n );\r\n\r\n this.loaded.add(lang);\r\n })();\r\n\r\n this.loading.set(lang, promise);\r\n await promise;\r\n this.loading.delete(lang);\r\n }\r\n\r\n getMergedTranslations(): any {\r\n const result: any = {};\r\n this.store.forEach(value => Object.assign(result, value));\r\n return result;\r\n }\r\n}\r\n","import { makeEnvironmentProviders } from '@angular/core';\r\nimport { APP_TRANSLATIONS_STORE, TranslationRegistry } from '../i18n/translation-registry.service';\r\n\r\n\r\nexport function provideFederationTranslation() {\r\n return makeEnvironmentProviders([\r\n TranslationRegistry,\r\n {\r\n provide: APP_TRANSLATIONS_STORE,\r\n useFactory: () => new Map<string, any>(),\r\n }\r\n ]);\r\n}\r\n","import { Injectable, inject } from '@angular/core';\r\nimport { TranslateLoader } from '@ngx-translate/core';\r\nimport { Observable, from } from 'rxjs';\r\nimport { map } from 'rxjs/operators';\r\nimport { TranslationRegistry } from './translation-registry.service';\r\n\r\n@Injectable({ providedIn: 'root' })\r\nexport class FederatedTranslateLoader implements TranslateLoader {\r\n private readonly registry = inject(TranslationRegistry);\r\n\r\n getTranslation(lang: string): Observable<any> {\r\n return from(this.registry.load(lang)).pipe(\r\n map(() => this.registry.getMergedTranslations())\r\n );\r\n }\r\n}\r\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":[],"mappings":"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"}
package/index.d.ts CHANGED
@@ -5,7 +5,16 @@ import { Observable } from 'rxjs';
5
5
 
6
6
  declare class Env {
7
7
  private readonly envMap;
8
- get(remoteName: string): Record<string, any>;
8
+ private readonly envService;
9
+ /**
10
+ * Safe async access (recommended)
11
+ */
12
+ get(remoteName: string): Promise<Record<string, any>>;
13
+ /**
14
+ * Sync access (only after bootstrap)
15
+ */
16
+ getSync(remoteName: string): Record<string, any>;
17
+ has(remoteName: string): boolean;
9
18
  static ɵfac: i0.ɵɵFactoryDeclaration<Env, never>;
10
19
  static ɵprov: i0.ɵɵInjectableDeclaration<Env>;
11
20
  }
@@ -45,6 +54,8 @@ declare class TranslationRegistry {
45
54
  private readonly http;
46
55
  private readonly federation;
47
56
  private readonly store;
57
+ private loading;
58
+ private loaded;
48
59
  load(lang: string): Promise<void>;
49
60
  getMergedTranslations(): any;
50
61
  static ɵfac: i0.ɵɵFactoryDeclaration<TranslationRegistry, never>;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@yaagoub/federation-tools",
3
- "version": "1.1.2",
3
+ "version": "1.1.3",
4
4
  "peerDependencies": {
5
5
  "@angular/common": ">=15.0.0",
6
6
  "@angular/core": ">=15.0.0"