import React from 'react' ; import { NextPage , NextPageContext } from 'next' ; import NextApp , { AppContext } from 'next/app' ; import ssrPrepass from 'react-ssr-prepass' ; import { Provider , dedupExchange , cacheExchange , fetchExchange } from 'urql' ; import { initUrqlClient } from './init-urql-client' ; import { NextUrqlClientConfig , MergeExchanges , NextUrqlContext , WithUrqlProps , } from './types' ; function getDisplayName ( Component ) { return Component . displayName || Component . name || 'Component' ; } export function withUrqlClient ( clientConfig , mergeExchanges = ssrExchange => [ dedupExchange , cacheExchange , ssrExchange , fetchExchange , ] ) { return ( AppOrPage ) => { const withUrql = ( { urqlClient , urqlState , ... rest } ) => { const client = React . useMemo ( ( ) => { const clientOptions = typeof clientConfig === 'function' ? clientConfig ( ) : clientConfig ; return ( urqlClient || initUrqlClient ( clientOptions , mergeExchanges , urqlState ) [ 0 ] ! ) ; } , [ urqlClient , urqlState ] ) ; return ( < Provider value = { client } > < AppOrPage urqlClient = { client } { ... rest } /> < /Provider>); } ; withUrql . displayName = `withUrqlClient(${ getDisplayName ( AppOrPage ) })` ; withUrql . getInitialProps = async ( appOrPageCtx ) => { const { AppTree } = appOrPageCtx ; const isApp = ! ! ( appOrPageCtx as AppContext ) . Component ; const ctx = isApp ? ( appOrPageCtx as AppContext ) . ctx : ( appOrPageCtx as NextPageContext ) ; const opts = typeof clientConfig === 'function' ? clientConfig ( ctx ) : clientConfig ; const [ urqlClient , ssrCache ] = initUrqlClient ( opts , mergeExchanges ) ; if ( urqlClient ) { ( ctx as NextUrqlContext ) . urqlClient = urqlClient ; } let pageProps ; if ( AppOrPage . getInitialProps ) { pageProps = await AppOrPage . getInitialProps ( appOrPageCtx as any ) ; } if ( typeof window !== 'undefined' ) { return pageProps ; } const props = { ... pageProps , urqlClient } ; const appTreeProps = isApp ? props : { pageProps : props } ; await ssrPrepass ( < AppTree { ... appTreeProps } / > ) ; return { ... pageProps , urqlState : ssrCache ?. extractData ( ) , } ; } ; return withUrql ; } ; }