add cache for maps details

This commit is contained in:
MathieuG-P
2022-11-30 00:48:55 +01:00
parent 57ab0b9ff2
commit b7db145517
3 changed files with 51 additions and 4 deletions
@@ -19,7 +19,6 @@ export class BeatSaverApiService {
if(hashs.length > 50){ throw "too musch map hashs"; }
const paramsHashs = hashs.join(",");
const resp = await fetch(`${this.bsaverApiUrl}/maps/hash/${paramsHashs}`);
const data = await resp.json() as Record<Lowercase<T>, BsvMapDetail> | BsvMapDetail;
@@ -1,6 +1,8 @@
import { splitIntoChunk } from "renderer/helpers/array-tools";
import { of } from "rxjs";
import { Observable } from "rxjs";
import { BsvMapDetail } from "shared/models/maps";
import { OsDiagnosticService } from "../os-diagnostic.service";
import { BeatSaverApiService } from "./beat-saver-api.service";
export class BeatSaverService {
@@ -13,24 +15,45 @@ export class BeatSaverService {
}
private readonly bsaverApi: BeatSaverApiService;
private readonly os: OsDiagnosticService;
private readonly cachedMapsDetails = new Map<string, BsvMapDetail>()
private constructor(){
this.bsaverApi = BeatSaverApiService.getInstance();
this.os = OsDiagnosticService.getInstance();
}
public getMapDetailsFromHashs(hashs: string[]): Observable<BsvMapDetail[]>{
const chunkHash = splitIntoChunk(hashs, 50);
const filtredHashs = hashs.map(h => h.toLowerCase()).filter(hash => !Array.from(this.cachedMapsDetails.keys()).includes(hash));
const chunkHash = splitIntoChunk(filtredHashs, 50);
const mapDetails = Array.from(this.cachedMapsDetails.entries()).reduce((res , [hash, details]) => {
if(hashs.includes(hash)){
res.push(details);
}
return res;
}, [] as BsvMapDetail[]);
if(this.os.isOffline){
return of(mapDetails);
}
return new Observable(observer => {
(async () => {
const mapDetails: BsvMapDetail[] = [];
for(const hashs of chunkHash){
const res = await this.bsaverApi.getMapsDetailsByHashs(hashs);
if(res.status === 200){
mapDetails.push(...Object.values<BsvMapDetail>(res.data));
mapDetails.forEach(detail => this.cachedMapsDetails.set(detail.versions.at(0).hash.toLowerCase(), detail));
}
if(mapDetails.length > 0){
observer.next(mapDetails);
}
@@ -0,0 +1,25 @@
import { BehaviorSubject } from "rxjs";
export class OsDiagnosticService {
private static instance: OsDiagnosticService;
public static getInstance(): OsDiagnosticService{
if(!OsDiagnosticService.instance){ OsDiagnosticService.instance = new OsDiagnosticService(); }
return OsDiagnosticService.instance;
}
private _isOnline$ = new BehaviorSubject(true);
private constructor(){
window.addEventListener("online", () => this._isOnline$.next(true));
window.addEventListener("offline", () => this._isOnline$.next(false));
}
public get isOnline(){ return this._isOnline$.value; }
public get isOffline(){ return !this._isOnline$.value; }
public get isOnline$(){ return this._isOnline$.asObservable(); }
}