catalyst-core-internal 0.0.1-beta.28 → 0.0.1-beta.29

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -6,4 +6,4 @@
6
6
  * @param {array} metaTags - user defined function which returns meta tags in array
7
7
  * @param {string} publicAssetPath - public asset path for assets
8
8
  * @param {object} children - contains any child elements defined within the component
9
- */function Head(props){const{pageCss,pageJS,metaTags,isBot,publicAssetPath,children,webExtractor}=props;if(children){return/*#__PURE__*/_react.default.createElement("head",null,children,metaTags&&metaTags,!isBot&&pageJS?pageJS:webExtractor.getScriptElements(),!isBot&&pageCss?/*#__PURE__*/_react.default.createElement("style",{dangerouslySetInnerHTML:{__html:pageCss}}):webExtractor.getStyleElements());}else return/*#__PURE__*/_react.default.createElement("head",null,/*#__PURE__*/_react.default.createElement("meta",{charSet:"utf-8"}),/*#__PURE__*/_react.default.createElement("meta",{name:"viewport",content:"width=device-width, initial-scale=1"}),publicAssetPath&&/*#__PURE__*/_react.default.createElement("link",{rel:"preconnect",href:publicAssetPath}),publicAssetPath&&/*#__PURE__*/_react.default.createElement("link",{rel:"dns-prefetch",href:publicAssetPath}),metaTags&&metaTags,!isBot&&pageJS?pageJS:webExtractor.getScriptElements(),!isBot&&pageCss?/*#__PURE__*/_react.default.createElement("style",{dangerouslySetInnerHTML:{__html:pageCss}}):webExtractor.getStyleElements());}Head.propTypes={isBot:_propTypes.default.bool,pageJS:_propTypes.default.object,pageCss:_propTypes.default.string,metaTags:_propTypes.default.array,publicAssetPath:_propTypes.default.string,children:_propTypes.default.node};
9
+ */function Head(props){const{pageCss,pageJS,preloadJSLinks,metaTags,isBot,publicAssetPath,children,webExtractor}=props;if(children){return/*#__PURE__*/_react.default.createElement("head",null,children,metaTags&&metaTags,!isBot&&pageCss?/*#__PURE__*/_react.default.createElement("style",{dangerouslySetInnerHTML:{__html:pageCss}}):webExtractor.getStyleElements(),!isBot&&preloadJSLinks);}else return/*#__PURE__*/_react.default.createElement("head",null,/*#__PURE__*/_react.default.createElement("meta",{charSet:"utf-8"}),/*#__PURE__*/_react.default.createElement("meta",{name:"viewport",content:"width=device-width, initial-scale=1"}),publicAssetPath&&/*#__PURE__*/_react.default.createElement("link",{rel:"preconnect",href:publicAssetPath}),publicAssetPath&&/*#__PURE__*/_react.default.createElement("link",{rel:"dns-prefetch",href:publicAssetPath}),metaTags&&metaTags,!isBot&&pageCss?/*#__PURE__*/_react.default.createElement("style",{dangerouslySetInnerHTML:{__html:pageCss}}):webExtractor.getStyleElements(),!isBot&&preloadJSLinks);}Head.propTypes={isBot:_propTypes.default.bool,pageJS:_propTypes.default.object,pageCss:_propTypes.default.string,metaTags:_propTypes.default.array,publicAssetPath:_propTypes.default.string,children:_propTypes.default.node};
@@ -1,8 +1,12 @@
1
- "use strict";Object.defineProperty(exports,"__esModule",{value:true});exports.cacheCSS=cacheCSS;exports.cacheJS=cacheJS;exports.default=_default;var _path=_interopRequireDefault(require("path"));var _fs=_interopRequireDefault(require("fs"));function _interopRequireDefault(obj){return obj&&obj.__esModule?obj:{default:obj};}/**
1
+ "use strict";Object.defineProperty(exports,"__esModule",{value:true});exports.cacheCSS=cacheCSS;exports.cacheJS=cacheJS;exports.cachePreloadJSLinks=cachePreloadJSLinks;exports.default=_default;var _path=_interopRequireDefault(require("path"));var _fs=_interopRequireDefault(require("fs"));function _interopRequireDefault(obj){return obj&&obj.__esModule?obj:{default:obj};}function handleProps(asset,props){return typeof props==="function"?"":props;}function propsToString(asset,props){return Object.entries(handleProps(asset,props)).reduce((acc,[key,value])=>`${acc} ${key}="${value}"`,"");}function cachePreloadJSLinks(key,data){if(!process.preloadJSLinkCache){process.preloadJSLinkCache={};}let preloadJSLinks=[];if(Array.isArray(data)){try{data.map(asset=>{if(asset?.props?.as==="script"){preloadJSLinks.push(`<link ${propsToString(asset,asset.props)}>`);}});}catch(error){console.dir({service_name:`pwa-${process.env.APPLICATION}-node-server`,loglevel:"error",version:"v2",message:"\n \n =====> Error While Extracting The Chunk: \n ",traceback:error});}}console.dir({service_name:"pwa-node-server",loglevel:"info",version:"v2",message:`\n========= Cached For preloadJSLinkCache: ${key} ============\n`});process.preloadJSLinkCache[key]=preloadJSLinks.join("\n");}/**
2
2
  * Stores css chunks styles into cache in string format
3
3
  * @param {string} key - router path
4
4
  * @param {object} data - css elements array extracted through loadable chunk extracter
5
- */function cacheCSS(key,data){if(!process.cssCache){process.cssCache={};}let pageCss="";if(Array.isArray(data)){try{data.map(assetChunk=>{const assetPathArr=assetChunk.key.split("/");const assetName=assetPathArr[assetPathArr.length-1];const ext=_path.default.extname(assetName);if(ext===".css")pageCss+=_fs.default.readFileSync(_path.default.resolve(process.env.src_path,`${process.env.BUILD_OUTPUT_PATH}/public`,assetName));});}catch(error){if(process.env.NODE_ENV=="development"){console.log("Error While Extracting The Chunk: ",_path.default.resolve(process.env.src_path,`${process.env.BUILD_OUTPUT_PATH}/public`));}}}process.cssCache[key]=pageCss;}/**
5
+ */function cacheCSS(key,data){if(!process.cssCache){process.cssCache={};}let pageCss="";let listOfCachedAssets={};if(Array.isArray(data)){try{data.map(assetChunk=>{const assetPathArr=assetChunk.key.split("/");const assetName=assetPathArr[assetPathArr.length-1];const ext=_path.default.extname(assetName);if(ext===".css"){// if css file has not already been cached, add the content of this CSS file in pageCSS
6
+ if(!listOfCachedAssets[assetName]&&!process.cssCache?.[key]?.listOfCachedAssets?.[assetName]){pageCss+=_fs.default.readFileSync(_path.default.resolve(process.env.src_path,`${process.env.BUILD_OUTPUT_PATH}/public`,assetName));listOfCachedAssets[assetName]=true;}}});}catch(error){if(process.env.NODE_ENV=="development"){console.log("Error While Extracting The Chunk: ",_path.default.resolve(process.env.src_path,`${process.env.BUILD_OUTPUT_PATH}/public`));}}}// if css cache exists for a route and there are some uncached css, add that css to the cache
7
+ // this will run on subsequent hits and will add css of uncached widgets to the cache
8
+ if(process.cssCache[key]){if(pageCss!==""){pageCss="<style>"+pageCss+"</style>";let existingListOfCachedAssets=process.cssCache[key].listOfCachedAssets;const newPageCSS=process.cssCache[key].pageCss+pageCss;let newListOfCachedAssets={...existingListOfCachedAssets,...listOfCachedAssets};process.cssCache[key]={pageCss:newPageCSS,listOfCachedAssets:newListOfCachedAssets};}}else{// create css cache for a page. This will run on the first hit.
9
+ pageCss="<style>"+pageCss+"</style>";process.cssCache[key]={pageCss,listOfCachedAssets};}}/**
6
10
  * Stores javascript into cache
7
11
  * @param {string} key - router path
8
12
  * @param {object} data - js elements array extracted through loadable chunk extracter
@@ -10,12 +14,13 @@
10
14
  * returns cached css
11
15
  * @param {string} key - router path
12
16
  * @return {string} - cached css
13
- */function fetchCachedCSS(key){return process.cssCache&&process.cssCache[key]?process.cssCache[key]:null;}/**
17
+ */function fetchCachedCSS(key){return process.cssCache&&process.cssCache[key]?process.cssCache[key].pageCss:"";}/**
14
18
  * returns cached js
15
19
  * @param {string} key - router path
16
20
  * @return {string} - cached js
17
- */function fetchCachedJS(key){return process.jsCache&&process.jsCache[key]?process.jsCache[key]:null;}/**
21
+ */function fetchCachedJS(key){return process.jsCache&&process.jsCache[key]?process.jsCache[key]:null;}function fetchPreloadJSLinkCache(key){return process.preloadJSLinkCache&&process.preloadJSLinkCache[key]?process.preloadJSLinkCache[key]:null;}/**
18
22
  * stores css and js in cache
19
23
  * @param {object} res - response object
20
24
  * @param {string} route - route path
21
- */function _default(res,route){try{const requestPath=route.path;const cachedCss=fetchCachedCSS(requestPath);const cachedJS=fetchCachedJS(requestPath);if(cachedCss||cachedJS){res.locals.pageJS=cachedJS;res.locals.pageCss=cachedCss;return;}}catch(error){console.log("Error while caching your assets.");}}
25
+ */function _default(res,route){try{const requestPath=route.path;const cachedCss=fetchCachedCSS(requestPath);const cachedJS=fetchCachedJS(requestPath);const cachedPreloadJSLinks=fetchPreloadJSLinkCache(requestPath);if(cachedCss||cachedJS||cachedPreloadJSLinks){// TODO: remove pageJS not needed anymore
26
+ res.locals.pageJS=cachedJS;res.locals.pageCss=cachedCss;res.locals.preloadJSLinks=cachedPreloadJSLinks;return;}}catch(error){console.log("Error while caching your assets.");}}
@@ -1,12 +1,13 @@
1
1
  "use strict";Object.defineProperty(exports,"__esModule",{value:true});exports.default=_default;var _fs=_interopRequireDefault(require("fs"));var _path=_interopRequireDefault(require("path"));var _react=_interopRequireDefault(require("react"));var _render=_interopRequireDefault(require("./render"));var _extract=_interopRequireDefault(require("./extract"));var _reactRedux=require("react-redux");var _document=require("./document");var _server=require("react-router-dom/server");var _ServerRouter=_interopRequireDefault(require("@catalyst/router/ServerRouter.js"));var _index=_interopRequireDefault(require("@catalyst/template/src/js/containers/App/index.js"));var _server2=require("@loadable/server");var _server3=require("react-dom/server");var _userAgentUtil=require("@catalyst/server/utils/userAgentUtil");var _router=require("@tata1mg/router");var _validator=require("@catalyst/server/utils/validator");var _document2=_interopRequireDefault(require("@catalyst/template/server/document.js"));var _utils=require("@catalyst/template/src/js/routes/utils.js");function _interopRequireDefault(obj){return obj&&obj.__esModule?obj:{default:obj};}const storePath=_path.default.resolve(`${process.env.src_path}/src/js/store/index.js`);let createStore;if(_fs.default.existsSync(storePath)){try{const{default:configureStore}=require(`${process.env.src_path}/src/js/store/index.js`);createStore=configureStore;}catch(error){console.log("error while creating store",error);createStore=()=>{return{getState:()=>{}};};}}else{createStore=()=>{return{getState:()=>{}};};}const isProduction=process.env.NODE_ENV==="production";// matches request route with routes defined in the application.
2
- const getMatchRoutes=(routes,req,res,store,context,fetcherData,basePath="",webExtractor)=>{return routes.reduce((matches,route)=>{const{path}=route;const match=(0,_router.matchPath)({path:`${basePath}/${path}`,caseSensitive:false,end:true},req.baseUrl||"/");if(match){if(isProduction&&!res.locals.pageCss&&!res.locals.pageJS&&!res.locals.routePath){(0,_extract.default)(res,route);}if(!res.locals.pageCss&&!res.locals.pageJS&&!res.locals.routePath){res.locals.routePath=path;//moving routing logic outside of the App and using ServerRoutes for creating routes on server instead
2
+ const getMatchRoutes=(routes,req,res,store,context,fetcherData,basePath="",webExtractor)=>{return routes.reduce((matches,route)=>{const{path}=route;const match=(0,_router.matchPath)({path:`${basePath}/${path}`,caseSensitive:false,end:true},req.baseUrl||"/");if(match){if(isProduction&&!res.locals.pageCss&&!res.locals.pageJS&&!res.locals.preloadJSLinks&&!res.locals.routePath){res.locals.routePath=path;(0,_extract.default)(res,route);}if(!res.locals.pageCss&&!res.locals.pageJS&&!res.locals.preloadJSLinks){// res.locals.routePath = path
3
+ //moving routing logic outside of the App and using ServerRoutes for creating routes on server instead
3
4
  (0,_server3.renderToString)(/*#__PURE__*/_react.default.createElement(_server2.ChunkExtractorManager,{extractor:webExtractor},/*#__PURE__*/_react.default.createElement(_reactRedux.Provider,{store:store},/*#__PURE__*/_react.default.createElement(_server.StaticRouter,{context:context,location:req.originalUrl},/*#__PURE__*/_react.default.createElement(_ServerRouter.default,{store:store,intialData:fetcherData})))));}const wc=route.component;matches.push({route,match,serverSideFunction:wc&&wc.serverSideFunction||(()=>Promise.resolve())});}if(!match&&route.children){// recursively try to match nested routes
4
5
  const nested=getMatchRoutes(route.children,req,res,store,context,fetcherData,`${basePath}/${path}`,webExtractor);if(nested.length){matches=matches.concat(nested);}}return matches;},[]);};// Preloads chunks required for rendering document
5
6
  const getComponent=(store,context,req,fetcherData)=>{return/*#__PURE__*/_react.default.createElement("div",{id:"app"},/*#__PURE__*/_react.default.createElement(_reactRedux.Provider,{store:store},/*#__PURE__*/_react.default.createElement(_server.StaticRouter,{context:context,location:req.originalUrl},/*#__PURE__*/_react.default.createElement(_ServerRouter.default,{store:store,intialData:fetcherData}))));};// sends document after rendering
6
7
  const renderMarkUp=async(errorCode,req,res,metaTags,fetcherData,store,matches,context,webExtractor)=>{const deviceDetails=(0,_userAgentUtil.getUserAgentDetails)(req.headers["user-agent"]||"");const isBot=deviceDetails.googleBot?true:false;let state=store.getState();const jsx=webExtractor.collectChunks(getComponent(store,context,req,fetcherData));// Transforms Head Props
7
- const finalProps=_render.default.extractFinalProps(req,res,res.locals.pageCss,res.locals.pageJS,metaTags,isBot,state,fetcherData,webExtractor,jsx);// Transforms Body Props
8
+ const finalProps=_render.default.extractFinalProps(req,res,res.locals.pageCss,res.locals.pageJS,metaTags,isBot,state,fetcherData,webExtractor,jsx,res.locals.preloadJSLinks);// Transforms Body Props
8
9
  // const finalProps = { req, res, isBot: isBot, initialState: state, webExtractor }
9
- let CompleteDocument=()=>{if((0,_validator.validateCustomDocument)(_document2.default)){return(0,_document2.default)(finalProps);}else{return/*#__PURE__*/_react.default.createElement("html",{lang:finalProps.lang},/*#__PURE__*/_react.default.createElement(_document.Head,{isBot:finalProps.isBot,pageJS:finalProps.pageJS,pageCss:finalProps.pageCss,metaTags:finalProps.metaTags,publicAssetPath:finalProps.publicAssetPath,webExtractor:finalProps.webExtractor}),/*#__PURE__*/_react.default.createElement(_document.Body,{initialState:finalProps.initialState,jsx:finalProps.jsx,fetcherData:finalProps.fetcherData}));}};try{let status=matches.length&&matches[0].match.path==="*"?404:200;res.set({"content-type":"text/html; charset=utf-8"});res.status(status);const{pipe}=(0,_server3.renderToPipeableStream)(/*#__PURE__*/_react.default.createElement(CompleteDocument,null),{onShellReady(){res.setHeader("content-type","text/html");pipe(res);res.end();},onAllReady(){_render.default.cacheAssets(webExtractor,res);},onError(error){logger.error({message:`\n Error while renderToPipeableStream : ${error.toString()}`});}});}catch(error){logger.error("Error in rendering document on server:"+error);}};/**
10
+ let CompleteDocument=()=>{if((0,_validator.validateCustomDocument)(_document2.default)){return(0,_document2.default)(finalProps);}else{return/*#__PURE__*/_react.default.createElement("html",{lang:finalProps.lang},/*#__PURE__*/_react.default.createElement(_document.Head,{isBot:finalProps.isBot,pageJS:finalProps.pageJS,preloadJSLinks:finalProps.preloadJSLinks,pageCss:finalProps.pageCss,metaTags:finalProps.metaTags,publicAssetPath:finalProps.publicAssetPath,webExtractor:finalProps.webExtractor}),/*#__PURE__*/_react.default.createElement(_document.Body,{initialState:finalProps.initialState,jsx:finalProps.jsx,fetcherData:finalProps.fetcherData}));}};try{let status=matches.length&&matches[0].match.path==="*"?404:200;res.set({"content-type":"text/html; charset=utf-8"});res.status(status);const{pipe}=(0,_server3.renderToPipeableStream)(/*#__PURE__*/_react.default.createElement(CompleteDocument,null),{onShellReady(){res.setHeader("content-type","text/html");pipe(res);res.end();},onAllReady(){_render.default.cacheAssets(webExtractor,res,isBot,res.locals.cspNonce);},onError(error){logger.error({message:`\n Error while renderToPipeableStream : ${error.toString()}`});}});}catch(error){logger.error("Error in rendering document on server:"+error);}};/**
10
11
  * middleware for document handling
11
12
  * @param {object} req - request object
12
13
  * @param {object} res - response object
@@ -5,8 +5,8 @@
5
5
  * @param {function} metaTagFunction - user defined function which returns meta tags in array
6
6
  * @param {boolean} isBot - checks if request is made by bot
7
7
  * @param {object} fetcherData - router fetched data
8
- */const extractFinalProps=(req,res,pageCss,pageJS,metaTags,isBot,state,fetcherData,webExtractor,jsx)=>{const{IS_DEV_COMMAND,WEBPACK_DEV_SERVER_HOSTNAME,WEBPACK_DEV_SERVER_PORT}=process.env;let publicAssetPath=`${process.env.PUBLIC_STATIC_ASSET_URL}${process.env.PUBLIC_STATIC_ASSET_PATH}`;// serves assets from localhost on running devBuild and devServe command
9
- if(JSON.parse(IS_DEV_COMMAND)){publicAssetPath=`http://${WEBPACK_DEV_SERVER_HOSTNAME}:${WEBPACK_DEV_SERVER_PORT}/assets/`;}return{req,res,pageCss,pageJS,metaTags,isBot,publicAssetPath,fetcherData,webExtractor,initialState:state,jsx};};/**
8
+ */const extractFinalProps=(req,res,pageCss,pageJS,metaTags,isBot,state,fetcherData,webExtractor,jsx,preloadJSLinks)=>{const{IS_DEV_COMMAND,WEBPACK_DEV_SERVER_HOSTNAME,WEBPACK_DEV_SERVER_PORT}=process.env;let publicAssetPath=`${process.env.PUBLIC_STATIC_ASSET_URL}${process.env.PUBLIC_STATIC_ASSET_PATH}`;// serves assets from localhost on running devBuild and devServe command
9
+ if(JSON.parse(IS_DEV_COMMAND)){publicAssetPath=`http://${WEBPACK_DEV_SERVER_HOSTNAME}:${WEBPACK_DEV_SERVER_PORT}/assets/`;}return{req,res,pageCss,pageJS,metaTags,isBot,publicAssetPath,fetcherData,webExtractor,initialState:state,jsx,preloadJSLinks};};const extractCss=data=>{let pageCss="<style>";if(Array.isArray(data)){try{data.map(assetChunk=>{const assetPathArr=assetChunk.key.split("/");const assetName=assetPathArr[assetPathArr.length-1];const ext=path.extname(assetName);if(ext===".css")pageCss+=fs.readFileSync(path.resolve(`${process.env.OUTPUT_PATH}/public/`+assetName));});}catch(error){console.dir({service_name:`pwa-${process.env.APPLICATION}-node-server`,loglevel:"error",version:"v2",message:"\n \n =====> Error While Extracting The Chunk: \n ",traceback:error});}}pageCss+="</style>";return pageCss;};/**
10
10
  * returns data which will be used in body component for page rendering
11
11
  * @param {object} webExtractor - loadable object which holds chunking function
12
12
  * @param {string} initialState - reducer initial state
@@ -14,6 +14,12 @@ if(JSON.parse(IS_DEV_COMMAND)){publicAssetPath=`http://${WEBPACK_DEV_SERVER_HOST
14
14
  * @param {boolean} jsx - jsx which needs to be render on server side
15
15
  * @param {string|number|null} errorCode - error code
16
16
  * @param {object} fetcherData - router fetched data
17
- */const cacheAssets=(webExtractor,res)=>{// For bot first fold css and js would become complete page css and js
18
- let firstFoldCss="";let firstFoldJS="";const isProd=process.env.NODE_ENV==="production";const{routePath,pageCss,pageJS}=res.locals;// Production: Extract styles and javscript elements if they are not found in cache and stores them in cache.
19
- if(isProd&&routePath&&(!pageCss||!pageJS)){firstFoldJS=webExtractor.getScriptElements();firstFoldCss=webExtractor.getLinkElements();(0,_extract.cacheCSS)(routePath,firstFoldCss);(0,_extract.cacheJS)(routePath,firstFoldJS);}};var _default=exports.default={extractFinalProps,cacheAssets};
17
+ */const cacheAssets=(webExtractor,res,isBot,cspNonce)=>{// For bot first fold css and js would become complete page css and js
18
+ let firstFoldCss="";let firstFoldJS="";const isProd=process.env.NODE_ENV==="production";const{routePath,preloadJSLinks,pageJS}=res.locals;const linkElements=webExtractor.getLinkElements();// We want to cache/or check for update css on every call
19
+ // We want to extract script tags for every call that will get added to body.
20
+ // Their corresponding preloaded link script tags are already present in head.
21
+ if(routePath){!isBot&&(0,_extract.cacheCSS)(routePath,linkElements);firstFoldJS=webExtractor.getScriptTags({nonce:cspNonce});}// This block will run for the first time and cache preloaded JS Links for second render
22
+ // firstFoldJS ->scripts gets inject in body
23
+ // firstFoldCss -> Inline css gets injected in body only for the first render
24
+ if(!isProd||isBot||routePath&&(!pageJS||!preloadJSLinks)){firstFoldCss=extractCss(linkElements);// TODO: pageJS not getting used anymore can be removed, catered by preloadJSLinks (cachePreloadJSLinks)
25
+ !isBot&&(0,_extract.cacheJS)(routePath,firstFoldJS);!isBot&&(0,_extract.cachePreloadJSLinks)(routePath,linkElements);}};var _default=exports.default={extractFinalProps,cacheAssets};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "catalyst-core-internal",
3
- "version": "0.0.1-beta.28",
3
+ "version": "0.0.1-beta.29",
4
4
  "main": "index.js",
5
5
  "description": "Web framework that provides great performance out of the box",
6
6
  "bin": {