All Downloads are FREE. Search and download functionalities are using the official Maven repository.

ducks.datasource.Providers.service.cachedRequest.ts Maven / Gradle / Ivy

The newest version!
import get from 'lodash/get'
import { select } from 'redux-saga/effects'
import dayjs from 'dayjs'

import type { State as GlobalState } from '../../../State'
import { dataProviderResolver } from '../../../../core/dataProviderResolver'
import { CachedProvider, QueryResult } from '../../Provider'
import { getFullKey } from '../Storage'

import { checkExpiration } from './checkExpiration'
import { fetch } from './fetch'
import { createCachedMappings, checkInvalidateParams, Key, Mapping } from './cachedMappings'

interface Params {
    provider: CachedProvider
    page: number
    sorting: string
    id: string
    apiProvider: unknown
    storage: Storage
    key: string
}

export function* cachedRequest(params: Params) {
    const { provider, page, sorting, id, apiProvider, storage, key } = params

    const { size, invalidateParams } = provider
    const query = { page: get(params, 'page', page), size, sorting }
    const state: GlobalState = yield select()

    let resolvedProvider = null

    try {
        resolvedProvider = dataProviderResolver(state, provider, query, params)
    } catch (error) {
        // TODO обработка error?

        // eslint-disable-next-line no-console
        console.error(error)

        return { list: [], paging: { count: 0, page: 1 } }
    }

    const { baseQuery, pathParams }: { baseQuery: Mapping, pathParams: Mapping } = resolvedProvider
    const mappings = { [Key.QUERY]: { ...baseQuery }, [Key.PATH]: { ...pathParams } }

    const storageData = storage.getItem(getFullKey(key))

    if (storageData) {
        const { cacheExpires } = provider

        const json = JSON.parse(storageData)
        const { timestamp } = json
        const isExpired = checkExpiration(timestamp, cacheExpires)

        if (!isExpired) {
            const { cachedMappings } = json

            const isValid = checkInvalidateParams(
                invalidateParams,
                cachedMappings,
                mappings,
            )

            if (isValid) { return json }
        }
    }

    const data: QueryResult = yield fetch(id, resolvedProvider, apiProvider)
    const cachedData = { ...data }

    cachedData.timestamp = dayjs().format()
    cachedData.cachedMappings = createCachedMappings(invalidateParams, mappings)

    storage.setItem(getFullKey(key), JSON.stringify(cachedData))

    return data
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy