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    
@skava/framework / src / client / apolloClient.tsx
Size: Mime:
/**
 * @file @todo https://www.apollographql.com/docs/react/features/performance.html#cache-redirects
 * @todo @see https://www.apollographql.com/docs/react/advanced/boost-migration
 */
import {
  ApolloReducerConfig,
  ApolloClient,
  HttpLink,
  InMemoryCache,
  ApolloLink,
} from 'apollo-boost'
import { persistCache } from 'apollo-cache-persist'
import { onError } from 'apollo-link-error'
import { GraphQLError } from 'graphql'
import { oneStorage } from '@skava/modules/___dist/persistance'
import { isObj, isEmpty } from 'exotic'

const IS_BROWSER = typeof window === 'object'
const proxyUrl = process.env.API_URL === '"' ? '' : process.env.API_URL || ''
const apiBaseUrl = proxyUrl
  ? proxyUrl
  : IS_BROWSER
    ? ''
    : process.env.SERVER_URL

/**
 * @note we add `credentials` to send cookies via fetch
 * @todo @see https://github.com/bitinn/node-fetch/issues/49
 * @see https://github.com/apollographql/apollo-link/issues/83
 * @see https://github.com/github/fetch#sending-cookies
 */
const cookieFetch = (url: string, options: RequestInit) => {
  const credentials: RequestCredentials = process.env.SUBAPP_GRAPHQL
    ? 'same-origin'
    : 'include'

  const fetchOptions = {
    ...options,
    credentials,
  }

  return fetch(url, fetchOptions)
}

const uri = `${apiBaseUrl}/graphql`
const httpLink = new HttpLink({ uri, fetch: cookieFetch })

/**
 * @api https://www.apollographql.com/docs/react/features/cache-updates.html#normalization
 * @todo freeze @@perf
 */
const inMemoryCacheConfig: ApolloReducerConfig = {}
const cache = new InMemoryCache(inMemoryCacheConfig).restore(
  IS_BROWSER && window.__APOLLO_STATE__
)

/**
 * Apollo Middlewares
 */
const logError = (error: GraphQLError): void => {
  const { message, locations, path } = error
  console.error(
    `[GraphQL error]: Message: ${message}, Location: ${locations}, Path: ${path}`
  )
}

const errorLink = onError(namedErrorResponseParams => {
  const {
    graphQLErrors,
    networkError,
    response,
    operation,
  } = namedErrorResponseParams

  if (isObj(graphQLErrors)) {
    const list = graphQLErrors as GraphQLError[]
    list.forEach(logError)
  }
  if (!isEmpty(networkError)) {
    console.error(`[Network error]: ${networkError}`)
  }

  const hasError = isObj(graphQLErrors) || !isEmpty(networkError)
  const isValidResponse = isObj(response)
  if (hasError && isValidResponse) {
    // ignore... for now
    response.errors = null
  }
})

/**
 * @see https://github.com/apollographql/apollo-link/tree/master/packages/apollo-link-error
 * @todo https://www.apollographql.com/docs/link/index.html#graphql-tools custom fetcher?
 */
const consoleLink = new ApolloLink((operation, forward) => {
  console.info(`starting request for ${operation.operationName}`)
  return forward(operation).map(data => {
    console.info(`ending request for ${operation.operationName}`)
    return data
  })
})

const link = ApolloLink.from([errorLink, consoleLink, httpLink])

/**
 * @see https://github.com/apollographql/apollo-cache-persist/blob/0bc569308379b4cc59b2c7f5f4823428b208ada0/src/types/index.ts
 */
if (process.env.USE_APOLLO_CACHE) {
  const cacheConfig = {
    cache,
    // @todo this isn't working for types
    storage: oneStorage as any,
    key: 'graphql-client-cache',
  }

  persistCache(cacheConfig)
}

/**
 * @todo
 * @requires https://github.com/apollographql/apollo-client/blob/master/docs/source/recipes/server-side-rendering.md#store-rehydration
 *
 * @see https://github.com/apollographql/apollo-client/blob/82a846c9591bcff975cc28d3786105b80a49b4ba/src/queries/queryTransform.ts#L30
 * @see https://github.com/apollographql/apollo-client/issues/1913#issuecomment-348359030
 */
const clientConfig = {
  link,
  cache,
  ssrMode: true,
  // addTypename: false,
}
if (process.env.DISABLE_SSR && IS_BROWSER === true) {
  clientConfig.ssrMode = false
}
if (!process.env.DISABLE_CACHE) {
  clientConfig.cache = cache
}
if (IS_BROWSER === false) {
  // @see https://github.com/apollographql/apollo-client/issues/1419
  // clientConfig.cache = undefined
}

const client = new ApolloClient(clientConfig)

// important
export default client
export { cache }
export { client }
// less important
export { uri }
export { httpLink }
export { clientConfig }