Why Gemfury? Push, build, and install  RubyGems npm packages Python packages Maven artifacts PHP packages Go Modules Debian packages RPM packages NuGet packages

Repository URL to install this package:

Details    
Size: Mime:
import React from 'react';
import { renderToString } from 'react-dom/server';
// @see https://github.com/styled-components/styled-components/issues/1692
import { ServerStyleSheet, } from 'styleh-components';
import { StaticRouter } from 'react-router-dom';
import Helmet from 'react-helmet';
import serialize from 'serialize-javascript';
import { getDataFromTree, ApolloProvider } from 'react-apollo';
import { useStaticRendering } from 'xmobx/mobx-react';
// import { logger } from '../../log'
import { respondRedirect, respondHyperText, respondError } from '../responders';
import { cacheIfNeeded } from '../../caching';
import { ServerHTML } from '../HTML';
import { requireClient } from './requireClient';
/**
 * @see https://github.com/mobxjs/mobx-react
 * > "To avoid leaking memory when server side rendering"
 */
useStaticRendering(true);
function renderFinalString(html) {
    // @note this was renderToStaticMarkup
    const appString = renderToString(html);
    if (process.env.IS_SSR_TEST === 'true') {
        const stringScript = `<script>window.__SSR_STRING__=${serialize(appString)}</script>`;
        const output = appString + stringScript;
        return output;
    }
    else {
        return appString;
    }
}
export async function renderUsingServerSideRendering(req, res, nonce) {
    const logger = req.log;
    /**
     * would scope these higher, but req is scoped
     * @todo probably should have a class
     */
    const onError = apolloRenderingError => {
        logger.error('[EXCEPTION_ALERT] [ssr] APOLLO ERROR', apolloRenderingError);
        respondError(res, apolloRenderingError);
    };
    logger.debug('[SSR] RENDERING_SSR_FOR_ROUTE:');
    /**
     * injected client dependencies
     * this is set in development poc & dist/index
     */
    const { App, client } = requireClient();
    /**
     * Create a context for <StaticRouter>,
     * which will allow us to query for the results of the render.
     */
    const reactRouterContext = {};
    /**
     * @description Declare our React application.
     * @see https://www.apollographql.com/docs/react/recipes/server-side-rendering.html
     */
    const appView = (React.createElement(StaticRouter, { location: req.url, context: reactRouterContext },
        React.createElement(ApolloProvider, { client: client },
            React.createElement(App, null))));
    function renderReactToString(initialState) {
        logger.debug('[SSR]:HIT_RENDER_TO_STRING');
        // stylesheet is not getting reset -.-
        // __DO_NOT_USE_OR_YOU_WILL_BE_HAUNTED_BY_SPOOKY_GHOSTS.StyleSheet.reset(true)
        const sheet = new ServerStyleSheet();
        const styledView = sheet.collectStyles(appView);
        const appString = renderToString(styledView);
        const styledTags = sheet.getStyleElement();
        /**
         * @see https://github.com/styled-components/styled-components/issues/378
         * @todo https://github.com/nfl/react-helmet/issues/216
         */
        const htmlView = (React.createElement(ServerHTML, { isCompat: req.IS_COMPAT, isCached: req.SHOULD_CACHE_SSR, reactAppString: appString, nonce: nonce, helmet: Helmet.rewind(), styledTags: styledTags, apolloState: initialState, routerState: reactRouterContext }));
        return renderFinalString(htmlView);
    }
    const onBootstrapped = () => {
        /**
         * @todo https://www.apollographql.com/docs/react/features/server-side-rendering.html#server-initialization
         */
        const initialState = client.extract();
        console.time('_render_app_to_string');
        const html = renderReactToString(initialState);
        console.timeEnd('_render_app_to_string');
        cacheIfNeeded(req, res, html);
        // @NOTE done here because it may be set in server html as a side effect
        const { url, status } = reactRouterContext;
        /**
         * Check if the router context contains a redirect, if so we need to set
         * the specific status and redirect header and end the res.
         */
        if (url) {
            respondRedirect(res, url);
        }
        else {
            respondHyperText(res, status, html);
        }
    };
    const encasedOnBootstrap = () => {
        try {
            onBootstrapped();
        }
        catch (renderReactToStringException) {
            logger.error('[ssr] TOSTRING ERROR', renderReactToStringException);
            respondError(res, renderReactToStringException);
        }
    };
    try {
        console.time('get_data_from_tree');
        getDataFromTree(appView)
            .then(encasedOnBootstrap)
            .catch(onError);
        console.timeEnd('get_data_from_tree');
    }
    catch (bootstrapperException) {
        logger.error('[ssr] BOOTSTRAPPER ERROR', bootstrapperException);
        respondError(res, bootstrapperException);
    }
}
//# sourceMappingURL=fn.js.map