github.com/pyroscope-io/pyroscope@v0.37.3-0.20230725203016-5f6947968bd0/webapp/javascript/redux/reducers/continuous/comparisonView.thunks.ts (about) 1 import { renderSingle, RenderOutput } from '@webapp/services/render'; 2 import { RequestAbortedError } from '@webapp/services/base'; 3 import { addNotification } from '../notifications'; 4 import { createAsyncThunk } from '../../async-thunk'; 5 import { ContinuousState } from './state'; 6 7 let comparisonSideAbortControllerLeft: AbortController | undefined; 8 let comparisonSideAbortControllerRight: AbortController | undefined; 9 10 export const fetchComparisonSide = createAsyncThunk< 11 { side: 'left' | 'right'; data: Pick<RenderOutput, 'profile'> }, 12 { side: 'left' | 'right'; query: string }, 13 { state: { continuous: ContinuousState } } 14 >('continuous/fetchComparisonSide', async ({ side, query }, thunkAPI) => { 15 const state = thunkAPI.getState(); 16 17 const res = await (() => { 18 switch (side) { 19 case 'left': { 20 if (comparisonSideAbortControllerLeft) { 21 comparisonSideAbortControllerLeft.abort(); 22 } 23 24 comparisonSideAbortControllerLeft = new AbortController(); 25 thunkAPI.signal = comparisonSideAbortControllerLeft.signal; 26 27 return renderSingle( 28 { 29 ...state.continuous, 30 query, 31 32 from: state.continuous.leftFrom, 33 until: state.continuous.leftUntil, 34 }, 35 comparisonSideAbortControllerLeft 36 ); 37 } 38 case 'right': { 39 if (comparisonSideAbortControllerRight) { 40 comparisonSideAbortControllerRight.abort(); 41 } 42 43 comparisonSideAbortControllerRight = new AbortController(); 44 thunkAPI.signal = comparisonSideAbortControllerRight.signal; 45 46 return renderSingle( 47 { 48 ...state.continuous, 49 query, 50 51 from: state.continuous.rightFrom, 52 until: state.continuous.rightUntil, 53 }, 54 comparisonSideAbortControllerRight 55 ); 56 } 57 default: { 58 throw new Error('invalid side'); 59 } 60 } 61 })(); 62 63 if (res?.isErr && res?.error instanceof RequestAbortedError) { 64 return thunkAPI.rejectWithValue({ rejectedWithValue: 'reloading' }); 65 } 66 67 if (res.isOk) { 68 return Promise.resolve({ 69 side, 70 data: { 71 profile: res.value.profile, 72 }, 73 }); 74 } 75 76 thunkAPI.dispatch( 77 addNotification({ 78 type: 'danger', 79 title: `Failed to load the ${side} side comparison`, 80 message: res.error.message, 81 }) 82 ); 83 84 return Promise.reject(res.error); 85 });