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 Helmet from 'react-helmet'
import React from 'react'
import { renderToString } from 'react-dom/server'
// import { ServerStyleSheet } from 'view-container/styles/styled-components'
import { ServerStyleSheet } from '@skava/modules/___dist/view-container/styles/styled-components'
// import { ServerStyleSheet } from 'view-container'
import { StaticRouter } from 'react-router-dom'
import { getDataFromTree, ApolloProvider } from 'react-apollo'
import { Provider } from 'xmobx/mobx-react'
import { cacheIfNeeded } from '../../../middleware/cacheMiddleware'
import {
  respondRedirect,
  respondHyperText,
  respondError,
} from '../../responders'
import { ServerHTML } from '../../HTML'
import { renderFinalString } from './renderFinalString'
import { ServerSideRenderContext } from './ServerSideRenderContext'

export class ServerSideRenderMaster {
  private context: ServerSideRenderContext
  constructor(context: ServerSideRenderContext) {
    this.context = context
  }

  public onSuccess = () => {
    const { req, res, reactRouterContext, htmlView } = this.context

    cacheIfNeeded(req, res, htmlView)

    /**
     * Check if the router context contains a redirect, if so we need to set
     * the specific status and redirect header and end the res.
     */
    const { url, status } = reactRouterContext
    if (url) {
      respondRedirect(res, url)
    } else {
      respondHyperText(res, status, htmlView)
    }
  }

  public onError = (apolloRenderingError: Error) => {
    console.error('[EXCEPTION_ALERT] [ssr] APOLLO ERROR', apolloRenderingError)
    respondError(this.context.res, apolloRenderingError)
  }

  public walk() {
    return getDataFromTree(this.context.appView)
  }

  public setup() {
    /**
     * Create the job context for our provider,
     * this grants us the ability to track the resolved jobs
     * so we can send it back to the client.
     */
    this.context.store = this.context.OmniStore.create()
  }

  public renderApp() {
    const { req, reactRouterContext, store, client, App } = this.context

    /**
     * @description Declare our React application.
     * @see https://www.apollographql.com/docs/react/recipes/server-side-rendering.html
     */
    this.context.appView = (
      <StaticRouter location={req.url} context={reactRouterContext}>
        <ApolloProvider client={client}>
          <Provider store={store}>
            <App />
          </Provider>
        </ApolloProvider>
      </StaticRouter>
    )
  }

  /**
   * @see https://github.com/styled-components/styled-components/issues/378
   * @todo https://github.com/nfl/react-helmet/issues/216
   * @see https://www.apollographql.com/docs/react/features/server-side-rendering.html#server-initialization
   */
  public renderToString() {
    const {
      req,
      appView,
      nonce,
      store,
      reactRouterContext,
      client,
    } = this.context

    const serializableExtractedApolloState = client.extract()
    const sheet = new ServerStyleSheet()
    const styledView = sheet.collectStyles(appView)
    const appString = renderToString(styledView)
    const styledTags = sheet.getStyleElement()

    const htmlView = (
      <ServerHTML
        isCached={req.SHOULD_CACHE_SSR}
        reactAppString={appString}
        nonce={nonce}
        helmet={Helmet.rewind()}
        styledTags={styledTags}
        apolloState={serializableExtractedApolloState}
        storeState={store}
        routerState={reactRouterContext}
      />
    )

    return renderFinalString(htmlView)
  }
}