Skip to content
This repository has been archived by the owner on Sep 24, 2024. It is now read-only.

Commit

Permalink
Merge pull request #29 from commercelayer/feat/remove-polling
Browse files Browse the repository at this point in the history
Remove polling and cleanup reducers and providers
  • Loading branch information
pfferrari authored Mar 21, 2023
2 parents 61d10a0 + ca5b897 commit 87dd7c7
Show file tree
Hide file tree
Showing 24 changed files with 146 additions and 415 deletions.
23 changes: 7 additions & 16 deletions packages/app-webhooks/@typing/App.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,39 +4,30 @@ declare module 'App' {
export interface WebhookDetailsContextValue {
state: WebhookDetailsContextState
refetch: () => Promise<void>
deleteWebhook: () => Promise<boolean>
resetWebhookCircuit: () => Promise<void>
}

export interface WebhookDetailsContextState {
data?: Webhook
isLoading: boolean
isDeleting: boolean
isCircuitResetting: boolean
isPolling: boolean
isNotFound: boolean
}

export interface WebhookDeleteContextValue
extends Omit<WebhookDetailsContextValue, 'resetWebhookCircuit' | 'state'> {
state: WebhookFormContextState
deleteWebhook: () => Promise<boolean>
}

export type WebhookDeleteContextState = Omit<
WebhookDetailsContextState,
'isCircuitResetting'
>
export interface WebhookDeleteContextState
extends WebhookDetailsContextState {
isDeleting: boolean
}

export interface WebhookFormContextValue
extends Omit<
WebhookDetailsContextValue,
'deleteWebhook' | 'resetWebhookCircuit' | 'state'
> {
extends Omit<WebhookDetailsContextValue, 'resetWebhookCircuit' | 'state'> {
state: WebhookFormContextState
}

export type WebhookFormContextState = Omit<
WebhookDetailsContextState,
'isCircuitResetting'
>
export interface WebhookFormContextState extends WebhookDetailsContextState {}
}
53 changes: 13 additions & 40 deletions packages/app-webhooks/src/components/Delete/Provider.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,7 @@ import {
useCallback,
useContext,
useEffect,
useReducer,
useRef
useReducer
} from 'react'
import { initialState, initialValues } from './data'
import { reducer } from './reducer'
Expand All @@ -18,8 +17,6 @@ interface WebhookDeleteProviderProps {
children: ((props: WebhookDeleteContextValue) => ReactNode) | ReactNode
}

const POLLING_INTERVAL = 4000

const Context = createContext<WebhookDeleteContextValue>(initialValues)
export const useWebhookDeleteContext = (): WebhookDeleteContextValue =>
useContext(Context)
Expand All @@ -30,56 +27,32 @@ export function WebhookDeleteProvider({
children
}: WebhookDeleteProviderProps): JSX.Element {
const [state, dispatch] = useReducer(reducer, initialState)
const intervalId = useRef<NodeJS.Timer | null>(null)

const fetchWebhook = useCallback(
async ({ handleLoadingState }: { handleLoadingState: boolean }) => {
handleLoadingState && dispatch({ type: 'setLoading', payload: true })
try {
const webhookDelete = await sdkClient.webhooks.retrieve(webhookId)
dispatch({ type: 'setData', payload: webhookDelete })
} catch {
dispatch({ type: 'setNotFound', payload: true })
dispatch({ type: 'togglePolling', payload: false })
}
handleLoadingState && dispatch({ type: 'setLoading', payload: false })
},
[webhookId]
)
const fetchWebhook = useCallback(async () => {
try {
const webhook = await sdkClient.webhooks.retrieve(webhookId)
dispatch({ type: 'webhook/loaded', payload: webhook })
} catch {
dispatch({ type: 'webhook/onError' })
}
}, [webhookId])

const deleteWebhook = useCallback(async (): Promise<boolean> => {
dispatch({ type: 'setDeleting', payload: true })
return await sdkClient.webhooks
.delete(webhookId)
.then(() => true)
.catch(() => {
dispatch({ type: 'setDeleting', payload: false })
return false
})
}, [webhookId])

useEffect(
function startPolling() {
void fetchWebhook({ handleLoadingState: true })
if (!state.isPolling) {
return
}
intervalId.current = setInterval(() => {
void fetchWebhook({ handleLoadingState: false })
}, POLLING_INTERVAL)

return () => {
if (intervalId.current != null) {
clearInterval(intervalId.current)
}
}
},
[state.isPolling]
)
useEffect(function init() {
void fetchWebhook()
}, [])

const value: WebhookDeleteContextValue = {
state,
refetch: async () => await fetchWebhook({ handleLoadingState: false }),
refetch: async () => await fetchWebhook(),
deleteWebhook
}

Expand Down
11 changes: 4 additions & 7 deletions packages/app-webhooks/src/components/Delete/data.ts
Original file line number Diff line number Diff line change
@@ -1,16 +1,13 @@
import { WebhookDetailsContextState, WebhookDetailsContextValue } from 'App'
import { WebhookDeleteContextState, WebhookDeleteContextValue } from 'App'

export const initialState: WebhookDetailsContextState = {
export const initialState: WebhookDeleteContextState = {
isLoading: true,
isPolling: false,
isDeleting: false,
isCircuitResetting: false,
isNotFound: false
}

export const initialValues: WebhookDetailsContextValue = {
export const initialValues: WebhookDeleteContextValue = {
state: initialState,
refetch: async () => undefined,
deleteWebhook: async () => false,
resetWebhookCircuit: async () => {}
deleteWebhook: async () => false
}
32 changes: 8 additions & 24 deletions packages/app-webhooks/src/components/Delete/reducer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,41 +2,25 @@ import { Webhook } from '@commercelayer/sdk'
import { WebhookDeleteContextState } from 'App'

type Action =
| { type: 'setLoading'; payload: boolean }
| { type: 'setDeleting'; payload: boolean }
| { type: 'setNotFound'; payload: boolean }
| { type: 'setData'; payload: Webhook }
| { type: 'togglePolling'; payload: boolean }
| { type: 'webhook/loaded'; payload: Webhook }
| { type: 'webhook/onError' }

export const reducer = (
state: WebhookDeleteContextState,
action: Action
): WebhookDeleteContextState | never => {
switch (action.type) {
case 'setLoading':
case 'webhook/loaded':
return {
...state,
isLoading: action.payload
data: action.payload,
isLoading: false
}
case 'setDeleting':
case 'webhook/onError':
return {
...state,
isDeleting: action.payload
}
case 'setNotFound':
return {
...state,
isNotFound: action.payload
}
case 'setData':
return {
...state,
data: action.payload
}
case 'togglePolling':
return {
...state,
isPolling: action.payload
isNotFound: true,
isLoading: false
}
default:
return state
Expand Down
79 changes: 22 additions & 57 deletions packages/app-webhooks/src/components/Details/Provider.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,7 @@ import {
useCallback,
useContext,
useEffect,
useReducer,
useRef
useReducer
} from 'react'
import { initialState, initialValues } from './data'
import { reducer } from './reducer'
Expand All @@ -18,8 +17,6 @@ interface WebhookDetailsProviderProps {
children: ((props: WebhookDetailsContextValue) => ReactNode) | ReactNode
}

const POLLING_INTERVAL = 4000

const Context = createContext<WebhookDetailsContextValue>(initialValues)
export const useWebhookDetailsContext = (): WebhookDetailsContextValue =>
useContext(Context)
Expand All @@ -30,71 +27,39 @@ export function WebhookDetailsProvider({
children
}: WebhookDetailsProviderProps): JSX.Element {
const [state, dispatch] = useReducer(reducer, initialState)
const intervalId = useRef<NodeJS.Timer | null>(null)

const fetchWebhook = useCallback(
async ({ handleLoadingState }: { handleLoadingState: boolean }) => {
handleLoadingState && dispatch({ type: 'setLoading', payload: true })
try {
const webhookDetails = await sdkClient.webhooks.retrieve(webhookId, {
include: ['last_event_callbacks']
})
dispatch({ type: 'setData', payload: webhookDetails })
} catch {
dispatch({ type: 'setNotFound', payload: true })
dispatch({ type: 'togglePolling', payload: false })
dispatch({ type: 'setLoading', payload: false })
}
handleLoadingState && dispatch({ type: 'setLoading', payload: false })
},
[webhookId]
)

const deleteWebhook = useCallback(async (): Promise<boolean> => {
dispatch({ type: 'setDeleting', payload: true })
return await sdkClient.webhooks
.delete(webhookId)
.then(() => true)
.catch(() => {
dispatch({ type: 'setDeleting', payload: false })
return false
const fetchWebhook = useCallback(async () => {
try {
const webhook = await sdkClient.webhooks.retrieve(webhookId, {
include: ['last_event_callbacks']
})
dispatch({ type: 'webhook/loaded', payload: webhook })
} catch {
dispatch({ type: 'webhook/onError' })
}
}, [webhookId])

const resetWebhookCircuit = useCallback(async (): Promise<void> => {
dispatch({ type: 'setCircuitResetting', payload: true })
await sdkClient.webhooks
.update({ id: webhookId, _reset_circuit: true })
.then(() => true)
.catch(() => {
dispatch({ type: 'setCircuitResetting', payload: false })
void fetchWebhook({ handleLoadingState: true })
.update(
{ id: webhookId, _reset_circuit: true },
{
include: ['last_event_callbacks']
}
)
.then((webhook) => {
dispatch({ type: 'webhook/loaded', payload: webhook })
})
.catch(() => {})
}, [webhookId])

useEffect(
function startPolling() {
void fetchWebhook({ handleLoadingState: true })
if (!state.isPolling) {
return
}
intervalId.current = setInterval(() => {
void fetchWebhook({ handleLoadingState: false })
}, POLLING_INTERVAL)

return () => {
if (intervalId.current != null) {
clearInterval(intervalId.current)
}
}
},
[state.isPolling]
)
useEffect(function init() {
void fetchWebhook()
}, [])

const value: WebhookDetailsContextValue = {
state,
refetch: async () => await fetchWebhook({ handleLoadingState: false }),
deleteWebhook,
refetch: async () => await fetchWebhook(),
resetWebhookCircuit
}

Expand Down
4 changes: 0 additions & 4 deletions packages/app-webhooks/src/components/Details/data.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,11 @@ import { WebhookDetailsContextState, WebhookDetailsContextValue } from 'App'

export const initialState: WebhookDetailsContextState = {
isLoading: true,
isPolling: false,
isDeleting: false,
isCircuitResetting: false,
isNotFound: false
}

export const initialValues: WebhookDetailsContextValue = {
state: initialState,
refetch: async () => undefined,
deleteWebhook: async () => false,
resetWebhookCircuit: async () => {}
}
38 changes: 8 additions & 30 deletions packages/app-webhooks/src/components/Details/reducer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,47 +2,25 @@ import { Webhook } from '@commercelayer/sdk'
import { WebhookDetailsContextState } from 'App'

type Action =
| { type: 'setLoading'; payload: boolean }
| { type: 'setDeleting'; payload: boolean }
| { type: 'setCircuitResetting'; payload: boolean }
| { type: 'setNotFound'; payload: boolean }
| { type: 'setData'; payload: Webhook }
| { type: 'togglePolling'; payload: boolean }
| { type: 'webhook/loaded'; payload: Webhook }
| { type: 'webhook/onError' }

export const reducer = (
state: WebhookDetailsContextState,
action: Action
): WebhookDetailsContextState | never => {
switch (action.type) {
case 'setLoading':
case 'webhook/loaded':
return {
...state,
isLoading: action.payload
data: action.payload,
isLoading: false
}
case 'setDeleting':
case 'webhook/onError':
return {
...state,
isDeleting: action.payload
}
case 'setCircuitResetting':
return {
...state,
isCircuitResetting: action.payload
}
case 'setNotFound':
return {
...state,
isNotFound: action.payload
}
case 'setData':
return {
...state,
data: action.payload
}
case 'togglePolling':
return {
...state,
isPolling: action.payload
isNotFound: true,
isLoading: false
}
default:
return state
Expand Down
Loading

0 comments on commit 87dd7c7

Please sign in to comment.