ProjectEvergreen / greenwood

Greenwood is your workbench for the web, embracing web standards from the ground up to empower your stack from front to back.
https://www.greenwoodjs.io
MIT License
96 stars 9 forks source link

data client is not rehydrating from existing WINDOW.APOLLO_STATE on initial load #349

Open thescientist13 opened 4 years ago

thescientist13 commented 4 years ago

Type of Change

Summary

As observed in #345, when first loading a production build, where data is set in WINDOW.APOLLO_STATE there should be no need for cache.json to be requested via fetch, but it is. 😞

Screen Shot 2020-05-06 at 8 38 13 PM

Details

I think the crux of the issue likely due to the fact that although we configure a real ApolloClient in client.js with the initial WINDOW.APOLLO_STATE

return fetch(`/${root}${rootSuffix}cache.json`)
  .then(response => response.json())
  .then((response) => {
    // mock client.query response
    return {
      data: new InMemoryCache().restore(response).readQuery(params)
    };
  });

We don't actually use that client in "SSG" mode so that would make sense why it wouldn't do that. That said, if this can be solved using an in cache memory, then this might also solve #347 .

thescientist13 commented 4 years ago

Could we try this?

import { ApolloClient } from 'apollo-client';
import { InMemoryCache } from 'apollo-cache-inmemory';
import { HttpLink } from 'apollo-link-http';

const APOLLO_STATE = window.__APOLLO_STATE__; // eslint-disable-line no-underscore-dangle
const client = new ApolloClient({
  cache: new InMemoryCache().restore(APOLLO_STATE),
  link: new HttpLink({
    uri: 'http://localhost:4000'
  })
});
const backupQuery = client.query;
window.backupCache = {};

client.query = (params) => {

  if (APOLLO_STATE) {
    // __APOLLO_STATE__ defined, in "SSG" mode...
    const root = window.location.pathname.split('/')[1];
    const rootSuffix = root === ''
      ? ''
      : '/';
   const path = `/${root}${rootSuffix}cache.json`;

   if(!window.backupCache[path])
      return fetch(path)
        .then(response => response.json())
        .then((response) => {
           // mock client.query response
           window.backupCache[path] = response;
           return {
             data: new InMemoryCache().restore(response).readQuery(params)
           };
        });
   } else {
     return {
       data: new InMemoryCache().restore(window.backupCache[path]).readQuery(params)
     };
   }
  } else {
    // __APOLLO_STATE__ NOT defined, in "SPA" mode
    return backupQuery(params);
  }
};

export default client;

I think we might not even need APOLLO_STATE and the writing of the cache to index.html and just leave it as {}?

thescientist13 commented 4 years ago

As part of #371, it looks like this no longer applies?. Not sure if it has any further impact in regards to caching query calls.

thescientist13 commented 3 years ago

Moving to deferred for this project to be added to our next project, but it looks we can take advantage of the work being deon for adding an MPA setting in #477 to implement what we need for this feature.

More info here - https://github.com/ProjectEvergreen/greenwood/pull/487#issuecomment-798941402