Skip to content
Snippets Groups Projects
routine.reducer.ts 2.83 KiB
Newer Older
  • Learn to ignore specific revisions
  • import { PayloadAction, createSlice } from '@reduxjs/toolkit'
    
    import { CategoryType } from '@shared/types/category.type'
    
    import { ThunkDTO, ThunkPersist } from '@shared/types/thunk.type'
    
    import { RoutineManager } from '@utils/routine.manager'
    import { RootState } from '../../stores'
    import { startListening } from '../../stores/middleware/listener.middleware'
    import { setToken } from './user.reducer'
    
    export interface ReducerState {
    
        thunks: Record<CategoryType, ThunkPersist | null>
    
    Matthias Feyll's avatar
    Matthias Feyll committed
    const initialState: ReducerState = {
    
        thunks: {
    
            TABLE: null,
    
    Matthias Feyll's avatar
    Matthias Feyll committed
    const RoutineSlice = createSlice({
        name: 'routine',
    
        initialState,
        reducers: {
    
            addRoutine: (state: any, { payload }: PayloadAction<ThunkDTO>) => {
                const thunk: ThunkPersist = {
                    category: payload.category,
                    payload: payload.payload,
    
                    thunkId: payload.thunk.id,
                    lastupdate: Date.now()
    
                }
    
                state.thunks[payload.category] = thunk
    
            refreshUpdateTimer: (state: any, { payload }: PayloadAction<CategoryType>) => {
                state.thunks[payload].lastupdate = Date.now()
            },
    
    
            removeAll: (state) => {
    
                state.thunks = initialState.thunks
    
    export const { addRoutine, refreshUpdateTimer } = RoutineSlice.actions
    
    Matthias Feyll's avatar
    Matthias Feyll committed
    // on logout remove all routine
    
    startListening({
    
        predicate: (action) => setToken.match(action) && action.payload === null,
    
        effect: async (_, listenerApi) => {
    
            RoutineManager.unsubscribeAll()
    
            listenerApi.dispatch(RoutineSlice.actions.removeAll())
    
    /**
     * Add new routine
     * 
     * This listener handles the connection between the RoutingManager that 
     * stores the non persistable thunk object and the peristable thunk information.
     * The persistable information are stored in this reducer
     */
    
    startListening({
    
    Matthias Feyll's avatar
    Matthias Feyll committed
        predicate: (action) => addRoutine.match(action),
    
        effect: async (action, listenerApi) => {
    
            const { thunk } = action.payload as ThunkDTO
    
            const subscription = await listenerApi.dispatch(thunk(action.payload.payload))
    
            if (subscription.error) {
                throw new Error('Error during routine execution: ' + subscription.error.message)
            }
    
    
            RoutineManager.add(subscription.payload, action.payload.category)
    
    // unsubscribe old routine that is in the same category
    
    startListening({
        predicate: (action) => addRoutine.match(action),
        effect: async (action, listenerApi) => {
            const { routine } = listenerApi.getOriginalState() as RootState
    
            const category = action.payload.category;
    
            const lastThunk = routine.thunks[category as CategoryType]
            if (lastThunk) {
                RoutineManager.unsubscribe(category)
    
    Matthias Feyll's avatar
    Matthias Feyll committed
    export default RoutineSlice.reducer