import { Transaction } from '@ulangi/sqlite-adapter' ; import { ActionType , createAction } from '@ulangi/ulangi-action' ; import { GetRemoteConfigRequest , RemoteConfig , } from '@ulangi/ulangi-common/interfaces' ; import { GetRemoteConfigResponseResolver } from '@ulangi/ulangi-common/resolvers' ; import { DatabaseFacade , RemoteConfigModel , } from '@ulangi/ulangi-local-database' ; import axios , { AxiosResponse } from 'axios' ; import * as moment from 'moment' ; import { call , fork , put , take } from 'redux-saga/effects' ; import { PromiseType } from 'utility-types' ; import { errorConverter } from '../converters/ErrorConverter' ; import { SagaEnv } from '../interfaces/SagaEnv' ; import { PublicSaga } from '../sagas/PublicSaga' ; import { createRequest } from '../utils/createRequest' ; export class RemoteConfigSaga extends PublicSaga { private getRemoteConfigResponseResolver = new GetRemoteConfigResponseResolver ( ) ; private database : DatabaseFacade ; private remoteConfigModel : RemoteConfigModel ; public constructor ( database , remoteConfigModel ) { super ( ) ; this . database = database ; this . remoteConfigModel = remoteConfigModel ; } public * run ( env ) { yield fork ( [ this , this . allowFetch ] ) ; yield fork ( [ this , this . allowUpdate ] , env . API_URL ) ; } public * allowFetch ( ) { while ( true ) { yield take ( ActionType . REMOTE_CONFIG__FETCH ) ; try { yield put ( createAction ( ActionType . REMOTE_CONFIG__FETCHING , null ) ) ; const sharedDb = this . database . getDb ( 'shared' ) ; const remoteConfig = yield call ( [ this . remoteConfigModel , 'getRemoteConfig' ] , sharedDb , true ) ; yield put ( createAction ( ActionType . REMOTE_CONFIG__FETCH_SUCCEEDED , { remoteConfig , } ) ) ; } catch ( error ) { yield put ( createAction ( ActionType . REMOTE_CONFIG__FETCH_FAILED , { errorCode : errorConverter . getErrorCode ( error ) , error , } ) ) ; } } } public * allowUpdate ( apiUrl ) { while ( true ) { yield take ( ActionType . REMOTE_CONFIG__UPDATE ) ; try { yield put ( createAction ( ActionType . REMOTE_CONFIG__UPDATING , null ) ) ; const remoteConfig = yield call ( [ this , this . fetchFromServer ] , apiUrl ) ; yield call ( [ this , this . insertCacheIntoDb ] , remoteConfig ) ; yield put ( createAction ( ActionType . REMOTE_CONFIG__UPDATE_SUCCEEDED , null ) ) ; } catch ( error ) { yield put ( createAction ( ActionType . REMOTE_CONFIG__UPDATE_FAILED , { errorCode : errorConverter . getErrorCode ( error ) , error , } ) ) ; } } } private * fetchFromServer ( apiUrl ) { const response = yield call ( [ axios , 'request' ] , createRequest < GetRemoteConfigRequest > ( 'get' , apiUrl , '/get-remote-config' , null , null , null ) ) ; return this . getRemoteConfigResponseResolver . resolve ( response . data , true ) . remoteConfig ; } private * insertCacheIntoDb ( remoteConfig ) { const sharedDb = this . database . getDb ( 'shared' ) ; yield call ( [ sharedDb , 'transaction' ] , ( tx ) : void => { this . remoteConfigModel . insertRemoteConfig ( tx , remoteConfig ) ; this . remoteConfigModel . insertLastFetchTime ( tx , moment ( ) . unix ( ) ) ; } ) ; } }