Repository: apollographql/apollo-client

Problem statement:
Fix circular dependency with `DocumentTransform` import in `InMemoryCache`
### Issue Description

When testing out the first beta release, I tried to run `@apollo/client` in a CLI environment and it blows up trying to instantiate `InMemoryCache`. When logging the import, it appears everything from the `cache` module is set as `undefined`. Through trial and error, I have narrowed it down to #10509 which introduced the new custom document transform feature.

Re-reviewing that PR, I noted that `InMemoryCache` [imports](https://github.com/apollographql/apollo-client/pull/10509/files#diff-b62f0293ff7b2f7bd5c12e8641f0eab4b630696d6eba70f6d55f2ec444bdccafR32) the `DocumentTransform` from `core`, yet core exports modules from [`cache`](https://github.com/apollographql/apollo-client/blob/f796ce1ac72f31a951a1d0f0b78d19dd039a6398/src/core/index.ts#L41-L61) resulting in a circular dependency. While some bundlers seem to be able to resolve circular dependencies, running this in the CLI environment fails entirely.

Since `DocumentTransform` is used both by [core](https://github.com/apollographql/apollo-client/pull/10509/files#diff-5fb8ad16cfbcb51bc035d32b5963734561c440b48417a1c2dbf80a16098be67bR145-R149) and by the [cache](https://github.com/apollographql/apollo-client/pull/10509/files#diff-b62f0293ff7b2f7bd5c12e8641f0eab4b630696d6eba70f6d55f2ec444bdccafR51), we should move that module to a neutral location to avoid the circular dependency.

### Link to Reproduction

https://github.com/apollographql/apollo-utils/pull/287

### Reproduction Steps

Use the new [`generate-persisted-query-manifest`](https://github.com/apollographql/apollo-utils/pull/287/files#diff-2e820a95431b3426c91e69100ea3eaac46e88669f0a0fa3aa53d8e0c78fbd229) tool and notice that it blows up with the error:

```
TypeError: core_1.InMemoryCache is not a constructor
    at generatePersistedQueryManifest (/node_modules/@apollo/generate-persisted-query-manifest/dist/index.js:66:16)
```


Hints:

Patch:
diff --git a/src/cache/inmemory/inMemoryCache.ts b/src/cache/inmemory/inMemoryCache.ts
--- a/src/cache/inmemory/inMemoryCache.ts
+++ b/src/cache/inmemory/inMemoryCache.ts
@@ -17,6 +17,7 @@ import type {
 import {
   addTypenameToDocument,
   isReference,
+  DocumentTransform,
 } from '../../utilities';
 import type {
   InMemoryCacheConfig,
@@ -29,7 +30,6 @@ import { makeVar, forgetCache, recallCache } from './reactiveVars';
 import { Policies } from './policies';
 import { hasOwn, normalizeConfig, shouldCanonizeResults } from './helpers';
 import { canonicalStringify } from './object-canon';
-import { DocumentTransform } from '../../core';
 import type { OperationVariables } from '../../core';
 
 type BroadcastOptions = Pick<
diff --git a/src/core/ApolloClient.ts b/src/core/ApolloClient.ts
--- a/src/core/ApolloClient.ts
+++ b/src/core/ApolloClient.ts
@@ -5,12 +5,11 @@ import type { ExecutionResult, DocumentNode } from 'graphql';
 import type { FetchResult, GraphQLRequest} from '../link/core';
 import { ApolloLink, execute } from '../link/core';
 import type { ApolloCache, DataProxy, Reference } from '../cache';
-import type { Observable } from '../utilities';
+import type { DocumentTransform, Observable } from '../utilities';
 import { version } from '../version';
 import type { UriFunction } from '../link/http';
 import { HttpLink } from '../link/http';
 
-import type { DocumentTransform } from './DocumentTransform';
 import { QueryManager } from './QueryManager';
 import type { ObservableQuery } from './ObservableQuery';
 
diff --git a/src/core/QueryManager.ts b/src/core/QueryManager.ts
--- a/src/core/QueryManager.ts
+++ b/src/core/QueryManager.ts
@@ -34,6 +34,7 @@ import {
   makeUniqueId,
   isDocumentNode,
   isNonNullObject,
+  DocumentTransform,
 } from '../utilities';
 import { mergeIncrementalData } from '../utilities/common/incrementalResult';
 import { ApolloError, isApolloError, graphQLResultHasProtocolErrors } from '../errors';
@@ -57,7 +58,6 @@ import type {
   InternalRefetchQueriesResult,
   InternalRefetchQueriesMap,
 } from './types';
-import { DocumentTransform } from './DocumentTransform';
 import { LocalState } from './LocalState';
 
 import type {
diff --git a/src/core/index.ts b/src/core/index.ts
--- a/src/core/index.ts
+++ b/src/core/index.ts
@@ -31,11 +31,6 @@ export {
   FragmentMatcher,
 } from './LocalState';
 export { isApolloError, ApolloError } from '../errors';
-export { 
-  DocumentTransform,
-  DocumentTransformCacheKey
-} from './DocumentTransform';
-
 /* Cache */
 
 export {
@@ -77,6 +72,8 @@ export {
 /* Utilities */
 
 export {
+  DocumentTransform,
+  DocumentTransformCacheKey,
   Observable,
   Observer,
   ObservableSubscription,
diff --git a/src/core/DocumentTransform.ts b/src/utilities/graphql/DocumentTransform.ts
similarity index 96%
rename from src/core/DocumentTransform.ts
rename to src/utilities/graphql/DocumentTransform.ts
--- a/src/core/DocumentTransform.ts
+++ b/src/utilities/graphql/DocumentTransform.ts
@@ -1,6 +1,7 @@
 import { Trie } from '@wry/trie';
-import { canUseWeakMap, canUseWeakSet, checkDocument } from '../utilities';
-import { invariant } from '../utilities/globals';
+import { canUseWeakMap, canUseWeakSet } from '../common/canUse';
+import { checkDocument } from './getFromAST';
+import { invariant } from '../globals';
 import type { DocumentNode } from 'graphql';
 
 export type DocumentTransformCacheKey = ReadonlyArray<unknown>;
diff --git a/src/utilities/index.ts b/src/utilities/index.ts
--- a/src/utilities/index.ts
+++ b/src/utilities/index.ts
@@ -12,6 +12,11 @@ export {
   getInclusionDirectives,
 } from './graphql/directives';
 
+export { 
+  DocumentTransform,
+  DocumentTransformCacheKey
+} from './graphql/DocumentTransform';
+
 export {
   FragmentMap,
   FragmentMapFunction,


Test patch:
diff --git a/src/__tests__/__snapshots__/exports.ts.snap b/src/__tests__/__snapshots__/exports.ts.snap
--- a/src/__tests__/__snapshots__/exports.ts.snap
+++ b/src/__tests__/__snapshots__/exports.ts.snap
@@ -383,6 +383,7 @@ Array [
   "Concast",
   "DEV",
   "DeepMerger",
+  "DocumentTransform",
   "Observable",
   "addTypenameToDocument",
   "argumentsObjectFromField",
diff --git a/src/__tests__/client.ts b/src/__tests__/client.ts
--- a/src/__tests__/client.ts
+++ b/src/__tests__/client.ts
@@ -4,7 +4,6 @@ import gql from 'graphql-tag';
 
 import {
   ApolloClient,
-  DocumentTransform,
   FetchPolicy,
   WatchQueryFetchPolicy,
   QueryOptions,
@@ -14,7 +13,7 @@ import {
   NetworkStatus,
 } from '../core';
 
-import { Observable, ObservableSubscription, offsetLimitPagination, removeDirectivesFromDocument } from '../utilities';
+import { DocumentTransform, Observable, ObservableSubscription, offsetLimitPagination, removeDirectivesFromDocument } from '../utilities';
 import { ApolloLink } from '../link/core';
 import { createFragmentRegistry, InMemoryCache, makeVar, PossibleTypesMap } from '../cache';
 import { ApolloError } from '../errors';
diff --git a/src/core/__tests__/ObservableQuery.ts b/src/core/__tests__/ObservableQuery.ts
--- a/src/core/__tests__/ObservableQuery.ts
+++ b/src/core/__tests__/ObservableQuery.ts
@@ -4,14 +4,13 @@ import { TypedDocumentNode } from "@graphql-typed-document-node/core";
 
 import { 
   ApolloClient,
-  DocumentTransform,
   NetworkStatus,
   WatchQueryFetchPolicy
 } from "../../core";
 import { ObservableQuery } from "../ObservableQuery";
 import { QueryManager } from "../QueryManager";
 
-import { Observable, removeDirectivesFromDocument } from "../../utilities";
+import { DocumentTransform, Observable, removeDirectivesFromDocument } from "../../utilities";
 import { ApolloLink, FetchResult } from "../../link/core";
 import { InMemoryCache, NormalizedCacheObject } from "../../cache";
 import { ApolloError } from "../../errors";
diff --git a/src/core/__tests__/DocumentTransform.ts b/src/utilities/graphql/__tests__/DocumentTransform.ts
similarity index 99%
rename from src/core/__tests__/DocumentTransform.ts
rename to src/utilities/graphql/__tests__/DocumentTransform.ts
--- a/src/core/__tests__/DocumentTransform.ts
+++ b/src/utilities/graphql/__tests__/DocumentTransform.ts
@@ -1,9 +1,6 @@
 import { DocumentTransform } from '../DocumentTransform';
-import {
-  isMutationOperation,
-  isQueryOperation,
-  removeDirectivesFromDocument,
-} from '../../utilities';
+import { isMutationOperation, isQueryOperation } from '../operations';
+import { removeDirectivesFromDocument } from '../transform';
 import { gql } from 'graphql-tag';
 import { DocumentNode, visit, Kind } from 'graphql';