diff --git a/projects/ngx-hal/src/lib/classes/hal-storage/cache-first-fetch-later.storage.ts b/projects/ngx-hal/src/lib/classes/hal-storage/cache-first-fetch-later.storage.ts new file mode 100644 index 0000000..1977ad3 --- /dev/null +++ b/projects/ngx-hal/src/lib/classes/hal-storage/cache-first-fetch-later.storage.ts @@ -0,0 +1,28 @@ +import { from, Observable, of } from 'rxjs'; +import { distinctUntilChanged, mergeMap } from 'rxjs/operators'; +import { HalModel } from '../../models/hal.model'; +import { HalDocument } from '../hal-document'; +import { EtagHalStorage } from './etag-hal-storage'; + +export class CacheFirstFetchLaterStorage extends EtagHalStorage { + public makeGetRequestWrapper( + urls: { originalUrl: string; cleanUrl: string; urlWithParams: string }, + cachedResource: T | HalDocument, + originalGetRequest$: Observable> + ): Observable> { + if (cachedResource) { + return from([of(cachedResource), originalGetRequest$]).pipe( + mergeMap((request) => request), + distinctUntilChanged(this.areModelsEqual.bind(this)) + ); + } + + return originalGetRequest$; + } + + private areModelsEqual(model1: T | HalDocument, model2: T | HalDocument): boolean { + const localModel1 = this.getRawStorageModel(model1.uniqueModelIdentificator); + const localModel2 = this.getRawStorageModel(model2.uniqueModelIdentificator); + return localModel1.etag === localModel2.etag; + } +} diff --git a/projects/ngx-hal/src/lib/classes/hal-storage/hal-storage-factory.ts b/projects/ngx-hal/src/lib/classes/hal-storage/hal-storage-factory.ts index 1edd952..42d7163 100644 --- a/projects/ngx-hal/src/lib/classes/hal-storage/hal-storage-factory.ts +++ b/projects/ngx-hal/src/lib/classes/hal-storage/hal-storage-factory.ts @@ -2,6 +2,7 @@ import { CacheStrategy } from '../../enums/cache-strategy.enum'; import { SimpleHalStorage } from '../../classes/hal-storage/simple-hal-storage'; import { EtagHalStorage } from '../../classes/hal-storage/etag-hal-storage'; import { HalStorage } from './hal-storage'; +import { CacheFirstFetchLaterStorage } from './cache-first-fetch-later.storage'; export type HalStorageType = SimpleHalStorage | EtagHalStorage; @@ -15,6 +16,9 @@ export function createHalStorage(cacheStrategy: CacheStrategy = CacheStrategy.NO case CacheStrategy.ETAG: storage = new EtagHalStorage(); break; + case CacheStrategy.CACHE_FIRST_FETCH_LATER: + storage = new CacheFirstFetchLaterStorage(); + break; case CacheStrategy.CUSTOM: if (!storageInstance) { throw new Error('When CacheStrategy.CUSTOM is specified, config.storage is required.'); diff --git a/projects/ngx-hal/src/lib/enums/cache-strategy.enum.ts b/projects/ngx-hal/src/lib/enums/cache-strategy.enum.ts index 05a20bb..0161a08 100644 --- a/projects/ngx-hal/src/lib/enums/cache-strategy.enum.ts +++ b/projects/ngx-hal/src/lib/enums/cache-strategy.enum.ts @@ -1,4 +1,5 @@ export enum CacheStrategy { + CACHE_FIRST_FETCH_LATER = 'CACHE_FIRST_FETCH_LATER', CUSTOM = 'CUSTOM', ETAG = 'ETAG', NONE = 'NONE' diff --git a/projects/ngx-hal/src/public_api.ts b/projects/ngx-hal/src/public_api.ts index 3647f98..51a300a 100644 --- a/projects/ngx-hal/src/public_api.ts +++ b/projects/ngx-hal/src/public_api.ts @@ -17,6 +17,7 @@ export * from './lib/classes/pagination'; export * from './lib/classes/hal-storage/hal-storage'; export * from './lib/classes/hal-storage/etag-hal-storage'; export * from './lib/classes/hal-storage/simple-hal-storage'; +export * from './lib/classes/hal-storage/cache-first-fetch-later.storage'; export * from './lib/enums/cache-strategy.enum';