From 6c29db3098557f59607eadc56d93398a700946d3 Mon Sep 17 00:00:00 2001 From: ahmetkuslular Date: Mon, 13 Jun 2022 15:19:37 +0300 Subject: [PATCH] ADD request dispatcher client --- src/index.js | 4 +- src/renderMultiple.js | 1 + .../RequestDispatcher/RequestDispatcher.js | 4 +- .../RequestDispatcher.utils.js | 5 +- src/universal/hooks/useRequestDispatcher.js | 82 +++++++++++++++++++ src/universal/utils/requestDispatcher.js | 19 +++++ 6 files changed, 111 insertions(+), 4 deletions(-) create mode 100644 src/universal/hooks/useRequestDispatcher.js create mode 100644 src/universal/utils/requestDispatcher.js diff --git a/src/index.js b/src/index.js index a17b25e..734b89d 100644 --- a/src/index.js +++ b/src/index.js @@ -1,5 +1,7 @@ import voltran from './universal/partials/withBaseComponent'; import apiService, { ClientApiManager, ServerApiManager } from './universal/core/apiService'; +import requestDispatcher from './universal/utils/requestDispatcher'; +import useRequestDispatcher from './universal/hooks/useRequestDispatcher'; export default voltran; -export { ClientApiManager, ServerApiManager, apiService }; +export { ClientApiManager, ServerApiManager, apiService, requestDispatcher, useRequestDispatcher }; diff --git a/src/renderMultiple.js b/src/renderMultiple.js index 4db40e4..315b517 100644 --- a/src/renderMultiple.js +++ b/src/renderMultiple.js @@ -45,6 +45,7 @@ function getRenderer(name, req) { cookies, url: urlWithPath, userAgent, + headers, componentPath: fullComponentPath, ...renderOptions }; diff --git a/src/universal/components/RequestDispatcher/RequestDispatcher.js b/src/universal/components/RequestDispatcher/RequestDispatcher.js index 42a87dd..99010af 100644 --- a/src/universal/components/RequestDispatcher/RequestDispatcher.js +++ b/src/universal/components/RequestDispatcher/RequestDispatcher.js @@ -23,14 +23,14 @@ const RequestDispatcher = () => { const eventBus = getEventBus(); const broadcast = (effect, error, body) => { - effect.Subscribers.forEach(responseName => { + effect.subscribers.forEach(responseName => { eventBus.emit(`${responsePrefix}${responseName}`, { error, body }); }); }; const runEffect = (effect, params) => { effect - .Request({ params }) + .request({ params }) .then(response => broadcast(effect, null, response)) .catch(error => broadcast(effect, error, null)); }; diff --git a/src/universal/components/RequestDispatcher/RequestDispatcher.utils.js b/src/universal/components/RequestDispatcher/RequestDispatcher.utils.js index 7541882..0cd2d38 100644 --- a/src/universal/components/RequestDispatcher/RequestDispatcher.utils.js +++ b/src/universal/components/RequestDispatcher/RequestDispatcher.utils.js @@ -6,7 +6,10 @@ const isEventExist = eventName => { }; const isExitCondition = condition => { - return Object.keys(getProjectWindowData()).indexOf(condition) > -1 || condition === 'default'; + return ( + Object.keys(getProjectWindowData()).indexOf(condition?.toUpperCase()) > -1 || + condition === 'default' + ); }; export { isExitCondition, isEventExist }; diff --git a/src/universal/hooks/useRequestDispatcher.js b/src/universal/hooks/useRequestDispatcher.js new file mode 100644 index 0000000..a5bee3f --- /dev/null +++ b/src/universal/hooks/useRequestDispatcher.js @@ -0,0 +1,82 @@ +import { useEffect, useReducer } from 'react'; +import requestDispatcher from '../utils/requestDispatcher'; + +function createAction(type, payload) { + return { + type, + payload + }; +} + +function reducer(state, action) { + switch (action.type) { + case 'UPDATE_DATA': + return { ...state, ...action.payload }; + default: + return state; + } +} + +const initialState = { + isLoading: false, + data: null, + err: null +}; + +function init(defaultData) { + return { ...initialState, data: { ...initialState.data, ...defaultData } }; +} + +const useRequestDispatcher = ({ effect, subscribe = '', defaultData }) => { + const [store, dispatch] = useReducer(reducer, defaultData, init); + const { isLoading, data, error } = store; + + const fetchData = params => { + if (effect) { + dispatch( + createAction('SET_LOADING', { + isLoading: true + }) + ); + if (Array.isArray(effect)) { + effect?.forEach(request => { + requestDispatcher.request(request, params); + }); + } else { + requestDispatcher.request(effect, params); + } + } + }; + + useEffect(() => { + if (process.env.BROWSER && subscribe) { + requestDispatcher.subscribe(subscribe, (error, data) => { + if (error) { + dispatch( + createAction('UPDATE_DATA', { + isLoading: false, + error + }) + ); + } else { + dispatch( + createAction('UPDATE_DATA', { + isLoading: false, + error: null, + data + }) + ); + } + }); + } + }, []); + + return { + isLoading, + data, + error, + fetchData + }; +}; + +export default useRequestDispatcher; diff --git a/src/universal/utils/requestDispatcher.js b/src/universal/utils/requestDispatcher.js new file mode 100644 index 0000000..fba05d7 --- /dev/null +++ b/src/universal/utils/requestDispatcher.js @@ -0,0 +1,19 @@ +import { getEventBus } from './helper'; + +const responsePrefix = 'RequestDispatcher.Response.'; +const requestPrefix = 'RequestDispatcher.'; + +export default { + subscribe(requestName, callback) { + getEventBus().on(`${responsePrefix}${requestName}`, ({ error, body }) => { + if (error) { + callback(error, null); + } else { + callback(null, body); + } + }); + }, + request(requestName, params, options) { + getEventBus().emit(`${requestPrefix}${requestName}`, params, options); + } +};