From e33858da03436f02125db8e668ba10522888f656 Mon Sep 17 00:00:00 2001 From: ahmetkuslular Date: Wed, 2 Mar 2022 02:02:57 +0300 Subject: [PATCH] ADD History service --- package.json | 1 + src/render.js | 20 ++++++- src/renderMultiple.js | 10 ++-- src/universal/partials/Welcome/partials.js | 2 +- src/universal/partials/withBaseComponent.js | 14 ++++- src/universal/service/HistoryService.js | 60 +++++++++++++++++++++ src/universal/utils/constants.js | 4 +- 7 files changed, 102 insertions(+), 9 deletions(-) create mode 100644 src/universal/service/HistoryService.js diff --git a/package.json b/package.json index 671af7e..3fb19b1 100644 --- a/package.json +++ b/package.json @@ -60,6 +60,7 @@ "file-loader": "1.1.11", "helmet": "3.21.3", "hiddie": "^1.0.0", + "history": "^5.3.0", "husky": "^3.1.0", "identity-obj-proxy": "3.0.0", "intersection-observer": "0.7.0", diff --git a/src/render.js b/src/render.js index 4b75aef..f7e6cc6 100644 --- a/src/render.js +++ b/src/render.js @@ -16,6 +16,19 @@ import logger from './universal/utils/logger'; import omit from 'lodash/omit'; const appConfig = require('__APP_CONFIG__'); +const previewPages = require('__V_PREVIEW_PAGES__'); + +function getPreview(output) { + const { layouts = {} } = previewPages?.default || {}; + let PreviewFile = Preview; + + console.log('layouts:', layouts); + if (layouts.default) { + PreviewFile = layouts.default; + } + + return PreviewFile(output); +} const render = async (req, res) => { const isWithoutStateValue = isWithoutState(req.query); @@ -23,6 +36,7 @@ const render = async (req, res) => { .split('/') .filter(part => part); const componentPath = `/${pathParts.join('/')}`; + const isPreviewValue = isPreview(req.query); const routeInfo = matchUrlInRouteConfigs(componentPath); @@ -38,7 +52,8 @@ const render = async (req, res) => { .replace('//', '/'), userAgent: Buffer.from(req.headers['user-agent'] || [], 'utf-8').toString('base64'), headers: JSON.parse(xss(JSON.stringify(req.headers))), - isWithoutState: isWithoutStateValue + isWithoutState: isWithoutStateValue, + isPreview: isPreviewValue }; const component = new Component(routeInfo.path); @@ -82,7 +97,8 @@ const render = async (req, res) => { const voltranEnv = appConfig.voltranEnv || 'local'; if (voltranEnv !== 'prod' && isPreviewQuery) { - res.status(statusCode).html(Preview([fullHtml].join('\n'))); + const response = getPreview([fullHtml].join('\n')); + res.status(statusCode).html(response); } else { res .status(HTTP_STATUS_CODES.INTERNAL_SERVER_ERROR) diff --git a/src/renderMultiple.js b/src/renderMultiple.js index 9e4f758..9ab45a6 100644 --- a/src/renderMultiple.js +++ b/src/renderMultiple.js @@ -145,9 +145,13 @@ async function setInitialStates(renderers) { winner .execute() .then(response => callback(null, response)) - .catch(exception => - callback(new Error(`${winner.uri} : ${exception.message}`), null) - ); + .catch(exception => { + if (renderer.component.object.byPassWhenFailed) { + callback(null, { data: { isFailed: true } }); + } else { + callback(new Error(`${winner.uri} : ${exception.message}`), null); + } + }); }; } }); diff --git a/src/universal/partials/Welcome/partials.js b/src/universal/partials/Welcome/partials.js index 5bb1499..c734fec 100644 --- a/src/universal/partials/Welcome/partials.js +++ b/src/universal/partials/Welcome/partials.js @@ -10,7 +10,7 @@ Object.keys(components).forEach(path => { partials.push({ name: info.fragmentName, url: path, - status: info.status + status: info?.fragment?.previewStatus || info.status }); } }); diff --git a/src/universal/partials/withBaseComponent.js b/src/universal/partials/withBaseComponent.js index 0f78d45..9eb10e3 100644 --- a/src/universal/partials/withBaseComponent.js +++ b/src/universal/partials/withBaseComponent.js @@ -5,6 +5,7 @@ import ClientApp from '../components/ClientApp'; import { WINDOW_GLOBAL_PARAMS } from '../utils/constants'; import { createComponentName } from '../utils/helper'; import voltranConfig from '../../../voltran.config'; +import HistoryService from '../service/HistoryService'; const getStaticProps = () => { const staticProps = {}; @@ -24,7 +25,12 @@ const withBaseComponent = (PageComponent, pathName) => { if (process.env.BROWSER && window[prefix] && window[prefix][componentName.toUpperCase()]) { const fragments = window[prefix][componentName.toUpperCase()]; - const history = window[WINDOW_GLOBAL_PARAMS.HISTORY]; + + window[WINDOW_GLOBAL_PARAMS.VOLTRAN_HISTORY] = + window[WINDOW_GLOBAL_PARAMS.VOLTRAN_HISTORY] || + new HistoryService(WINDOW_GLOBAL_PARAMS.VOLTRAN_HISTORY); + const history = window[WINDOW_GLOBAL_PARAMS.VOLTRAN_HISTORY].getHistory(); + const staticProps = getStaticProps(); Object.keys(fragments).forEach(id => { @@ -37,7 +43,11 @@ const withBaseComponent = (PageComponent, pathName) => { ReactDOM.hydrate( - + , componentEl, () => { diff --git a/src/universal/service/HistoryService.js b/src/universal/service/HistoryService.js new file mode 100644 index 0000000..0797cac --- /dev/null +++ b/src/universal/service/HistoryService.js @@ -0,0 +1,60 @@ +import { createBrowserHistory } from 'history'; +import { WINDOW_GLOBAL_PARAMS } from '../utils/constants'; + +let instance; + +const setReferrer = referrer => { + if (process.env.BROWSER) { + window.ref = referrer; + } +}; + +export default class HistoryService { + constructor(historyKey) { + if (instance) { + return instance; + } + + this.current = ''; + this.previous = ''; + this.history = null; + this.historyKey = historyKey; + this._listenCallback = this._listenCallback.bind(this); + + this._selectHistoryKey(); + + if (process.env.BROWSER) { + this.current = window.location.href; + this.history = window[this.historyKey]; + + if (this.historyKey === historyKey) { + this.history.listen(this._listenCallback); + } + } + + instance = this; + } + + _listenCallback(location) { + if (!process.env.BROWSER) return; + + this.previous = this.current; + this.current = `${window.location.origin}${location.pathname}${location.search}${location.hash}`; + setReferrer(this.previous); + } + + _selectHistoryKey() { + if (!process.env.BROWSER) return; + + // eslint-disable-next-line no-prototype-builtins + if (!window.hasOwnProperty(WINDOW_GLOBAL_PARAMS.HISTORY)) { + window[this.historyKey] = createBrowserHistory(); + } else { + this.historyKey = WINDOW_GLOBAL_PARAMS.HISTORY; + } + } + + getHistory() { + return this.history; + } +} diff --git a/src/universal/utils/constants.js b/src/universal/utils/constants.js index a119311..684b0f9 100644 --- a/src/universal/utils/constants.js +++ b/src/universal/utils/constants.js @@ -1,7 +1,9 @@ const appConfig = require('__APP_CONFIG__'); +const voltranConfig = require('../../../voltran.config'); const WINDOW_GLOBAL_PARAMS = { - HISTORY: 'storefront.pwa.mobile.global.history' + HISTORY: 'storefront.pwa.mobile.global.history', + VOLTRAN_HISTORY: voltranConfig.historyKey || 'voltran.global.history' }; const HTTP_STATUS_CODES = {