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

ducks.datasource.Providers.Storage.ts Maven / Gradle / Ivy

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

import { dataSourceByIdSelector, dataSourceProviderSelector } from '../selectors'
import type { Provider, QueryOptions, StorageProvider, StorageSubmit } from '../Provider'
import { ProviderType, StorageType } from '../Provider'
import type { DataSourceState } from '../DataSource'
import { getModelByPrefixAndNameSelector } from '../../models/selectors'
import { State } from '../../State'

import { applyFilter } from './storage/applyFilter'
import { applySorting } from './storage/applySorting'
import { applyPaging } from './storage/applyPaging'

const KEY_PREFIX = 'n2o/datasource/'

export const getFullKey = (key: string) => `${KEY_PREFIX}${key}`

export function* submit(id: string, { key, model: prefix, storage: storageType }: StorageSubmit) {
    const model: unknown = yield select(getModelByPrefixAndNameSelector(prefix, id))
    const storage = storageType === StorageType.local ? localStorage : sessionStorage

    if (isEmpty(model)) {
        return storage.removeItem(getFullKey(key))
    }

    const data = Array.isArray(model) ? model : [model]
    const stringData = JSON.stringify(data)

    return storage.setItem(getFullKey(key), stringData)
}

export function* query(id: string, { storage: storageType, key }: StorageProvider, options: QueryOptions) {
    const datasource: DataSourceState = yield select(dataSourceByIdSelector(id))
    const { sorting, paging: { page, size } } = datasource

    if (!key) {
        throw new Error('Parameter "key" is required for query data')
    }

    const storage = storageType === StorageType.local ? localStorage : sessionStorage
    const storageData = storage.getItem(getFullKey(key))

    if (!storageData) {
        return {
            list: [],
            paging: {
                page: 1,
                count: 0,
            },
        }
    }

    const json = JSON.parse(storageData)

    if (!Array.isArray(json)) {
        throw new Error('invalid data format')
    }

    const state: State = yield select()
    const filtered: object[] = applyFilter(state, json)
    const sorted = applySorting(filtered, sorting)
    const { list, paging } = applyPaging(
        sorted,
        {
            size,
            page: typeof options.page === 'undefined' ? page : options.page,
        },
    )

    return {
        list,
        paging: {
            page: paging.page,
            count: filtered.length,
        },
    }
}

export function* clear({ meta }: {
    meta: { clear?: string }
}) {
    const { clear: id } = meta

    if (!id) { return }

    const provider: Provider | void = yield select(dataSourceProviderSelector(id))

    if (!provider || provider.type !== ProviderType.storage) { return }

    const { storage: storageType, key } = provider as StorageProvider
    const storage = storageType === StorageType.local ? localStorage : sessionStorage

    storage.removeItem(getFullKey(key))
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy