1- import { isNil } from 'lodash' ;
2-
31import type {
42 GetSettingsParams ,
53 GetSingleSettingParams ,
64 SetSingleSettingParams ,
7- Setting ,
85} from '../../../types/api/settings' ;
6+ import { serializeReduxError } from '../../../utils/errors/serializeReduxError' ;
97import type { AppDispatch } from '../../defaultStore' ;
108import { api } from '../api' ;
119
1210import { SETTINGS_OPTIONS } from './constants' ;
11+ import { parseSettingValue , stringifySettingValue } from './utils' ;
1312
1413export const settingsApi = api . injectEndpoints ( {
1514 endpoints : ( builder ) => ( {
16- getSingleSetting : builder . query ( {
17- queryFn : async ( { name, user} : GetSingleSettingParams , baseApi ) => {
15+ getSingleSetting : builder . query < unknown , GetSingleSettingParams > ( {
16+ queryFn : async ( { name, user} ) => {
1817 try {
19- if ( ! window . api . metaSettings ) {
18+ if ( ! window . api ? .metaSettings ) {
2019 throw new Error ( 'MetaSettings API is not available' ) ;
2120 }
21+
2222 const data = await window . api . metaSettings . getSingleSetting ( {
2323 name,
2424 user,
2525 // Directly access options here to avoid them in cache key
2626 preventBatching : SETTINGS_OPTIONS [ name ] ?. preventBatching ,
2727 } ) ;
2828
29- const dispatch = baseApi . dispatch as AppDispatch ;
30-
31- // Try to sync local value if there is no backend value
32- syncLocalValueToMetaIfNoData ( data , dispatch ) ;
33-
34- return { data} ;
29+ return { data : parseSettingValue ( data ?. value ) } ;
3530 } catch ( error ) {
36- return { error} ;
31+ return { error : serializeReduxError ( error ) } ;
3732 }
3833 } ,
3934 } ) ,
4035 setSingleSetting : builder . mutation ( {
41- queryFn : async ( params : SetSingleSettingParams ) => {
36+ queryFn : async ( {
37+ name,
38+ user,
39+ value,
40+ } : Omit < SetSingleSettingParams , 'value' > & { value : unknown } ) => {
4241 try {
43- if ( ! window . api . metaSettings ) {
42+ if ( ! window . api ? .metaSettings ) {
4443 throw new Error ( 'MetaSettings API is not available' ) ;
4544 }
4645
47- const data = await window . api . metaSettings . setSingleSetting ( params ) ;
46+ const data = await window . api . metaSettings . setSingleSetting ( {
47+ name,
48+ user,
49+ value : stringifySettingValue ( value ) ,
50+ } ) ;
4851
4952 if ( data . status !== 'SUCCESS' ) {
50- throw new Error ( 'Setting status is not SUCCESS' ) ;
53+ throw new Error ( 'Cannot set setting - status is not SUCCESS' ) ;
5154 }
5255
5356 return { data} ;
5457 } catch ( error ) {
55- return { error} ;
58+ return { error : serializeReduxError ( error ) } ;
5659 }
5760 } ,
5861 async onQueryStarted ( args , { dispatch, queryFulfilled} ) {
5962 const { name, user, value} = args ;
6063
6164 // Optimistically update existing cache entry
6265 const patchResult = dispatch (
63- settingsApi . util . updateQueryData ( 'getSingleSetting' , { name, user} , ( draft ) => {
64- return { ...draft , name, user, value} ;
65- } ) ,
66+ settingsApi . util . updateQueryData ( 'getSingleSetting' , { name, user} , ( ) => value ) ,
6667 ) ;
6768 try {
6869 await queryFulfilled ;
@@ -74,39 +75,31 @@ export const settingsApi = api.injectEndpoints({
7475 getSettings : builder . query ( {
7576 queryFn : async ( { name, user} : GetSettingsParams , baseApi ) => {
7677 try {
77- if ( ! window . api . metaSettings ) {
78+ if ( ! window . api ? .metaSettings ) {
7879 throw new Error ( 'MetaSettings API is not available' ) ;
7980 }
8081 const data = await window . api . metaSettings . getSettings ( { name, user} ) ;
8182
82- const patches : Promise < void > [ ] = [ ] ;
83+ const patches : Promise < unknown > [ ] = [ ] ;
8384 const dispatch = baseApi . dispatch as AppDispatch ;
8485
85- // Upsert received data in getSingleSetting cache
86+ // Upsert received data in getSingleSetting cache to prevent further redundant requests
8687 name . forEach ( ( settingName ) => {
87- const settingData = data [ settingName ] ?? { } ;
88+ const settingData = data [ settingName ] ;
8889
8990 const cacheEntryParams : GetSingleSettingParams = {
9091 name : settingName ,
9192 user,
9293 } ;
93- const newValue = { name : settingName , user , value : settingData ?. value } ;
94+ const newSettingValue = parseSettingValue ( settingData ?. value ) ;
9495
9596 const patch = dispatch (
9697 settingsApi . util . upsertQueryData (
9798 'getSingleSetting' ,
9899 cacheEntryParams ,
99- newValue ,
100+ newSettingValue ,
100101 ) ,
101- ) . then ( ( ) => {
102- // Try to sync local value if there is no backend value
103- // Do it after upsert if finished to ensure proper values update order
104- // 1. New entry added to cache with nil value
105- // 2. Positive entry update - local storage value replace nil in cache
106- // 3.1. Set is successful, local value in cache
107- // 3.2. Set is not successful, cache value reverted to previous nil
108- syncLocalValueToMetaIfNoData ( settingData , dispatch ) ;
109- } ) ;
102+ ) ;
110103
111104 patches . push ( patch ) ;
112105 } ) ;
@@ -116,24 +109,10 @@ export const settingsApi = api.injectEndpoints({
116109
117110 return { data} ;
118111 } catch ( error ) {
119- return { error} ;
112+ return { error : serializeReduxError ( error ) } ;
120113 }
121114 } ,
122115 } ) ,
123116 } ) ,
124117 overrideExisting : 'throw' ,
125118} ) ;
126-
127- function syncLocalValueToMetaIfNoData ( params : Setting , dispatch : AppDispatch ) {
128- const localValue = localStorage . getItem ( params . name ) ;
129-
130- if ( isNil ( params . value ) && ! isNil ( localValue ) ) {
131- dispatch (
132- settingsApi . endpoints . setSingleSetting . initiate ( {
133- name : params . name ,
134- user : params . user ,
135- value : localValue ,
136- } ) ,
137- ) ;
138- }
139- }
0 commit comments