2026-07-05 02:08:15 +04:00
|
|
|
import { Injectable } from '@angular/core';
|
|
|
|
|
import { HttpClient } from '@angular/common/http';
|
2026-07-05 04:17:31 +04:00
|
|
|
import { Observable, catchError, map, of, shareReplay, switchMap, take } from 'rxjs';
|
2026-07-05 02:08:15 +04:00
|
|
|
import { WidgetManifestEntry, WidgetManifestFile } from '../contracts/widget-manifest.contract';
|
2026-07-05 04:17:31 +04:00
|
|
|
import { ConfigService } from '../../core/config/config.service';
|
2026-07-05 02:08:15 +04:00
|
|
|
|
|
|
|
|
@Injectable({ providedIn: 'root' })
|
|
|
|
|
export class WidgetManifestService {
|
2026-07-05 04:17:31 +04:00
|
|
|
private readonly fallbackManifestUrl = '/assets/mock/bootstrap/widget-manifest.json';
|
|
|
|
|
private readonly manifestByUrl = new Map<string, Observable<WidgetManifestFile>>();
|
2026-07-05 02:08:15 +04:00
|
|
|
|
2026-07-05 04:17:31 +04:00
|
|
|
constructor(
|
|
|
|
|
private readonly http: HttpClient,
|
|
|
|
|
private readonly configService: ConfigService
|
|
|
|
|
) {}
|
2026-07-05 02:08:15 +04:00
|
|
|
|
|
|
|
|
getManifest(): Observable<WidgetManifestFile> {
|
2026-07-05 04:17:31 +04:00
|
|
|
return this.resolveManifestUrl().pipe(
|
|
|
|
|
switchMap((manifestUrl) => {
|
|
|
|
|
const cached = this.manifestByUrl.get(manifestUrl);
|
|
|
|
|
if (cached) {
|
|
|
|
|
return cached;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const manifest$ = this.http.get<WidgetManifestFile>(manifestUrl).pipe(
|
|
|
|
|
shareReplay({ bufferSize: 1, refCount: true }),
|
|
|
|
|
catchError(() => of({ widgets: [] }))
|
|
|
|
|
);
|
2026-07-05 02:08:15 +04:00
|
|
|
|
2026-07-05 04:17:31 +04:00
|
|
|
this.manifestByUrl.set(manifestUrl, manifest$);
|
|
|
|
|
return manifest$;
|
|
|
|
|
})
|
|
|
|
|
);
|
2026-07-05 02:08:15 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
getWidgets(): Observable<WidgetManifestEntry[]> {
|
|
|
|
|
return this.getManifest().pipe(map((manifest) => manifest.widgets ?? []));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
getWidget(type: string): Observable<WidgetManifestEntry | undefined> {
|
|
|
|
|
return this.getWidgets().pipe(map((widgets) => widgets.find((widget) => widget.type === type)));
|
|
|
|
|
}
|
2026-07-05 04:17:31 +04:00
|
|
|
|
|
|
|
|
private resolveManifestUrl(): Observable<string> {
|
|
|
|
|
const snapshotUrl = this.configService.getBootstrapSnapshot()?.widgetRegistry?.manifestUrl;
|
|
|
|
|
if (snapshotUrl) {
|
|
|
|
|
return of(snapshotUrl);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return this.configService.loadBootstrap().pipe(
|
|
|
|
|
take(1),
|
|
|
|
|
map((bootstrap) => bootstrap.widgetRegistry?.manifestUrl || this.fallbackManifestUrl),
|
|
|
|
|
catchError(() => of(this.fallbackManifestUrl))
|
|
|
|
|
);
|
|
|
|
|
}
|
2026-07-05 02:08:15 +04:00
|
|
|
}
|