Skip to content

Commit

Permalink
Restore Apollo Client 3.7 getApolloContext behaviour (#11082)
Browse files Browse the repository at this point in the history
* Restore Apollo Client 3.7 `getApolloContext` behaviour

* update size-limits

---------

Co-authored-by: Jerel Miller <jerelmiller@gmail.com>
  • Loading branch information
phryneas and jerelmiller committed Jul 24, 2023
1 parent 0264fee commit 0f1cde3
Show file tree
Hide file tree
Showing 3 changed files with 24 additions and 33 deletions.
5 changes: 5 additions & 0 deletions .changeset/tame-owls-lick.md
@@ -0,0 +1,5 @@
---
'@apollo/client': patch
---

Restore Apollo Client 3.7 `getApolloContext` behaviour
4 changes: 2 additions & 2 deletions .size-limit.cjs
@@ -1,7 +1,7 @@
const checks = [
{
path: "dist/apollo-client.min.cjs",
limit: "37990"
limit: "38000"
},
{
path: "dist/main.cjs",
Expand All @@ -10,7 +10,7 @@ const checks = [
{
path: "dist/index.js",
import: "{ ApolloClient, InMemoryCache, HttpLink }",
limit: "31980"
limit: "31971"
},
...[
"ApolloProvider",
Expand Down
48 changes: 17 additions & 31 deletions src/react/context/ApolloContext.ts
Expand Up @@ -2,33 +2,20 @@ import * as React from 'react';
import type { ApolloClient } from '../../core/index.js';
import { canUseSymbol } from '../../utilities/index.js';
import type { RenderPromises } from '../ssr/index.js';
import { global, invariant } from '../../utilities/globals/index.js';
import { invariant } from '../../utilities/globals/index.js';

export interface ApolloContextValue {
client?: ApolloClient<object>;
renderPromises?: RenderPromises;
}

declare global {
interface Window {
[contextKey]: Map<
typeof React.createContext,
React.Context<ApolloContextValue>
>;
}
}

// To make sure that Apollo Client does not create more than one React context
// per React version, we store that Context in a global Map, keyed by the
// React version. This way, if there are multiple versions of React loaded,
// (e.g. in a Microfrontend environment), each React version will get its own
// Apollo context.
// If there are multiple versions of Apollo Client though, which can happen by
// accident, this can avoid bugs where those multiple Apollo Client versions
// would be unable to "see each other", even if an ApolloProvider was present.
const contextKey: unique symbol = canUseSymbol
// To make sure Apollo Client doesn't create more than one React context
// (which can lead to problems like having an Apollo Client instance added
// in one context, then attempting to retrieve it from another different
// context), a single Apollo context is created and tracked in global state.
const contextKey = canUseSymbol
? Symbol.for('__APOLLO_CONTEXT__')
: ('__APOLLO_CONTEXT__' as any);
: '__APOLLO_CONTEXT__';

export function getApolloContext(): React.Context<ApolloContextValue> {
invariant(
Expand All @@ -39,19 +26,18 @@ export function getApolloContext(): React.Context<ApolloContextValue> {
// TODO: change to React documentation once React documentation contains information about Client Components
'For more information, see https://nextjs.org/docs/getting-started/react-essentials#client-components'
);

let contextStorage =
global[contextKey] || (global[contextKey] = new Map());

let value = contextStorage.get(React.createContext);
if (!value) {
value = Object.assign(React.createContext<ApolloContextValue>({}), {
displayName: 'ApolloContext',
let context = (React.createContext as any)[contextKey] as React.Context<ApolloContextValue>;
if (!context) {
Object.defineProperty(React.createContext, contextKey, {
value: context = React.createContext<ApolloContextValue>({}),
enumerable: false,
writable: false,
configurable: true,
});
contextStorage.set(React.createContext, value);
context.displayName = 'ApolloContext';
}

return value;
return context;
}

/**
Expand Down

0 comments on commit 0f1cde3

Please sign in to comment.