diff --git a/CHANGELOG.md b/CHANGELOG.md
index 30d9faf85d8..0869745be6d 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -31,6 +31,9 @@
- The `gql` template tag should now be imported from the `@apollo/client` package, rather than the `graphql-tag` package. Although the `graphql-tag` package still works for now, future versions of `@apollo/client` may change the implementation details of `gql` without a major version bump.
[@hwillson](https://github.com/hwillson) in [#5451](https://github.com/apollographql/apollo-client/pull/5451)
+- `@apollo/client/core` can be used to import the Apollo Client core, which includes everything the main `@apollo/client` package does, except for all React related functionality.
+ [@kamilkisiela](https://github.com/kamilkisiela) in [#5541](https://github.com/apollographql/apollo-client/pull/5541)
+
### Breaking Changes
- Removed `graphql-anywhere` since it's no longer used by Apollo Client.
@@ -65,6 +68,8 @@
- The `ObservableQuery#getCurrentResult` method no longer falls back to reading from the cache, so calling it immediately after `client.watchQuery` will consistently return a `loading: true` result. When the `fetchPolicy` permits cached results, those results will be delivered via the `next` method of the `ObservableQuery`, and can be obtained by `getCurrentResult` after they have been delivered. This change prevents race conditions where the initial behavior of one query could depend on the timing of cache writes associated with other queries.
[@benjamn](https://github.com/benjamn) in [#5565](https://github.com/apollographql/apollo-client/pull/5565)
+- The `QueryOptions`, `MutationOptions`, and `SubscriptionOptions` React Apollo interfaces have been renamed to `QueryDataOptions`, `MutationDataOptions`, and `SubscriptionDataOptions` (to avoid conflicting with similarly named and exported Apollo Client interfaces).
+
## Apollo Client (2.6.4)
### Apollo Client (2.6.4)
diff --git a/config/prepareDist.js b/config/prepareDist.js
index 880b870e722..86e5f8a9c07 100644
--- a/config/prepareDist.js
+++ b/config/prepareDist.js
@@ -1,16 +1,23 @@
// The Apollo Client source that is published to npm is located in the
-// "dist" directory. This utility script is called just before deploying
-// Apollo Client, to make sure the "dist" directory is prepared for publishing.
+// "dist" directory. This utility script is called when building Apollo Client,
+// to make sure the "dist" directory is prepared for publishing.
//
// This script will:
//
// - Copy the current root package.json into "dist" after adjusting it for
// publishing.
// - Copy the supporting files from the root into "dist" (e.g. `README.MD`,
-// `LICENSE`, etc.)
+// `LICENSE`, etc.).
+// - Create a new `package.json` for each sub-set bundle we support, and
+// store it in the appropriate dist sub-directory.
-const packageJson = require('../package.json');
const fs = require('fs');
+const recast = require('recast');
+
+
+/* @apollo/client */
+
+const packageJson = require('../package.json');
// The root package.json is marked as private to prevent publishing
// from happening in the root of the project. This sets the package back to
@@ -25,13 +32,14 @@ delete packageJson.bundlesize;
// on-going package development (e.g. running tests, supporting npm link, etc.).
// When publishing from "dist" however, we need to update the package.json
// to point to the files within the same directory.
-const distPackageJson = JSON.stringify(
- packageJson,
- (_key, value) => (
- typeof value === 'string' ? value.replace(/\.\/dist\//, '') : value
- ),
- 2
-);
+const distPackageJson = JSON.stringify(packageJson, (_key, value) => {
+ if (typeof value === 'string' && value.startsWith('./dist/')) {
+ const parts = value.split('/');
+ parts.splice(1, 1); // remove dist
+ return parts.join('/');
+ }
+ return value;
+}, 2) + "\n";
// Save the modified package.json to "dist"
fs.writeFileSync(`${__dirname}/../dist/package.json`, distPackageJson);
@@ -41,3 +49,46 @@ const srcDir = `${__dirname}/..`;
const destDir = `${srcDir}/dist`;
fs.copyFileSync(`${srcDir}/README.md`, `${destDir}/README.md`);
fs.copyFileSync(`${srcDir}/LICENSE`, `${destDir}/LICENSE`);
+
+
+/* @apollo/client/core */
+
+function buildPackageJson(bundleName) {
+ return JSON.stringify({
+ name: `@apollo/client/${bundleName}`,
+ main: `${bundleName}.cjs.js`,
+ module: 'index.js',
+ types: 'index.d.ts',
+ }, null, 2) + "\n";
+}
+
+// Create a `core` bundle package.json, storing it in the dist core
+// directory. This helps provide a way for Apollo Client to be used without
+// React, via `@apollo/client/core`.
+fs.writeFileSync(
+ `${__dirname}/../dist/core/package.json`,
+ buildPackageJson('core')
+);
+
+// Build a new `core.cjs.js` entry point file, that includes everything
+// except the exports listed in `src/react/index.ts`. Copy this file into
+// the `dist/core` directory, to allow Apollo Client core only imports
+// using `@apollo/client/core`.
+
+const reactIndexSrc = fs.readFileSync(`${__dirname}/../dist/react/index.js`);
+const reactExports = [];
+recast.visit(recast.parse(reactIndexSrc), {
+ visitExportSpecifier(path) {
+ reactExports.push(path.value.exported.name);
+ return false;
+ },
+});
+
+fs.writeFileSync(`${__dirname}/../dist/core/core.cjs.js`, [
+ "const allExports = require('../apollo-client.cjs');",
+ `const reactExportNames = new Set(${JSON.stringify(reactExports)});`,
+ "Object.keys(allExports).forEach(name => {",
+ " if (!reactExportNames.has(name)) exports[name] = allExports[name];",
+ "});",
+ "",
+].join('\n'));
diff --git a/config/rollup.config.js b/config/rollup.config.js
index b1275cdf73f..db4419dc9b7 100644
--- a/config/rollup.config.js
+++ b/config/rollup.config.js
@@ -9,7 +9,7 @@ import packageJson from '../package.json';
const distDir = './dist';
const globals = {
- 'tslib': 'tslib',
+ tslib: 'tslib',
'ts-invariant': 'invariant',
'symbol-observable': '$$observable',
'graphql/language/printer': 'print',
@@ -21,7 +21,7 @@ const globals = {
'@wry/equality': 'wryEquality',
graphql: 'graphql',
react: 'React',
- 'zen-observable': 'Observable'
+ 'zen-observable': 'Observable',
};
const hasOwn = Object.prototype.hasOwnProperty;
@@ -30,12 +30,12 @@ function external(id) {
return hasOwn.call(globals, id);
}
-function prepareESM() {
+function prepareESM(input, outputDir) {
return {
- input: packageJson.module,
+ input,
external,
output: {
- dir: distDir,
+ dir: outputDir,
format: 'esm',
sourcemap: true,
},
@@ -58,39 +58,39 @@ function prepareESM() {
}),
cjs({
namedExports: {
- 'graphql-tag': ['gql']
- }
+ 'graphql-tag': ['gql'],
+ },
}),
- ]
+ ],
};
}
-function prepareCJS() {
+function prepareCJS(input, output) {
return {
- input: packageJson.module,
+ input,
external,
output: {
- file: packageJson.main,
+ file: output,
format: 'cjs',
sourcemap: true,
- exports: 'named'
+ exports: 'named',
},
plugins: [
nodeResolve(),
cjs({
namedExports: {
- 'graphql-tag': ['gql']
- }
+ 'graphql-tag': ['gql'],
+ },
}),
- ]
- }
+ ],
+ };
}
-function prepareCJSMinified() {
+function prepareCJSMinified(input) {
return {
- input: packageJson.main,
+ input,
output: {
- file: packageJson.main.replace('.js', '.min.js'),
+ file: input.replace('.js', '.min.js'),
format: 'cjs',
},
plugins: [
@@ -141,10 +141,10 @@ function prepareTesting() {
function rollup() {
return [
- prepareESM(),
- prepareCJS(),
- prepareCJSMinified(),
- prepareTesting()
+ prepareESM(packageJson.module, distDir),
+ prepareCJS(packageJson.module, packageJson.main),
+ prepareCJSMinified(packageJson.main),
+ prepareTesting(),
];
}
diff --git a/package-lock.json b/package-lock.json
index a37ae957609..5476c365130 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -6992,9 +6992,9 @@
}
},
"recast": {
- "version": "0.18.2",
- "resolved": "https://registry.npmjs.org/recast/-/recast-0.18.2.tgz",
- "integrity": "sha512-MbuHc1lzIDIn7bpxaqIAGwwtyaokkzPqINf1Vm/LA0BSyVrTgXNVTTT7RzWC9kP+vqrUoYVpd6wHhI8x75ej8w==",
+ "version": "0.18.5",
+ "resolved": "https://registry.npmjs.org/recast/-/recast-0.18.5.tgz",
+ "integrity": "sha512-sD1WJrpLQAkXGyQZyGzTM75WJvyAd98II5CHdK3IYbt/cZlU0UzCRVU11nUFNXX9fBVEt4E9ajkMjBlUlG+Oog==",
"dev": true,
"requires": {
"ast-types": "0.13.2",
diff --git a/package.json b/package.json
index 50e3ebb6b19..b4f238d46c6 100644
--- a/package.json
+++ b/package.json
@@ -30,7 +30,7 @@
"scripts": {
"prebuild": "npm run clean",
"build": "npx tsc",
- "postbuild": "npm run bundle",
+ "postbuild": "npm run bundle && npm run prepdist",
"watch": "npx tsc-watch --onSuccess \"npm run postbuild\"",
"clean": "npx rimraf -r dist coverage lib",
"test": "jest --config ./config/jest.config.js",
@@ -41,7 +41,7 @@
"coverage:upload": "npx codecov",
"bundlesize": "npm run build && bundlesize",
"prepdist": "node ./config/prepareDist.js",
- "predeploy": "npm run build && npm run prepdist",
+ "predeploy": "npm run build",
"deploy": "cd dist && npm publish --tag beta"
},
"bundlesize": [
@@ -89,6 +89,7 @@
"prop-types": "15.7.2",
"react": "^16.11.0",
"react-dom": "^16.11.0",
+ "recast": "^0.18.5",
"rimraf": "^3.0.0",
"rollup": "1.21.2",
"rollup-plugin-commonjs": "^10.1.0",
diff --git a/src/core/index.ts b/src/core/index.ts
new file mode 100644
index 00000000000..c84426336e2
--- /dev/null
+++ b/src/core/index.ts
@@ -0,0 +1,85 @@
+/* Core */
+
+export {
+ ApolloClient,
+ ApolloClientOptions,
+ DefaultOptions
+} from '../ApolloClient';
+export {
+ ObservableQuery,
+ FetchMoreOptions,
+ UpdateQueryOptions,
+ ApolloCurrentQueryResult,
+} from '../core/ObservableQuery';
+export {
+ QueryBaseOptions,
+ QueryOptions,
+ WatchQueryOptions,
+ MutationOptions,
+ SubscriptionOptions,
+ FetchPolicy,
+ WatchQueryFetchPolicy,
+ ErrorPolicy,
+ FetchMoreQueryOptions,
+ SubscribeToMoreOptions,
+ MutationUpdaterFn,
+} from '../core/watchQueryOptions';
+export { NetworkStatus } from '../core/networkStatus';
+export * from '../core/types';
+export {
+ Resolver,
+ FragmentMatcher as LocalStateFragmentMatcher,
+} from '../core/LocalState';
+export { isApolloError, ApolloError } from '../errors/ApolloError';
+
+/* Cache */
+
+export { Transaction, ApolloCache } from '../cache/core/cache';
+export { Cache } from '../cache/core/types/Cache';
+export { DataProxy } from '../cache/core/types/DataProxy';
+export {
+ InMemoryCache,
+ InMemoryCacheConfig,
+} from '../cache/inmemory/inMemoryCache';
+export { defaultDataIdFromObject } from '../cache/inmemory/policies';
+export * from '../cache/inmemory/types';
+
+/* Link */
+
+export { empty } from '../link/core/empty';
+export { from } from '../link/core/from';
+export { split } from '../link/core/split';
+export { concat } from '../link/core/concat';
+export { execute } from '../link/core/execute';
+export { ApolloLink } from '../link/core/ApolloLink';
+export * from '../link/core/types';
+export {
+ parseAndCheckHttpResponse,
+ ServerParseError
+} from '../link/http/parseAndCheckHttpResponse';
+export {
+ serializeFetchParameter,
+ ClientParseError
+} from '../link/http/serializeFetchParameter';
+export {
+ HttpOptions,
+ fallbackHttpConfig,
+ selectHttpOptionsAndBody,
+ UriFunction
+} from '../link/http/selectHttpOptionsAndBody';
+export { checkFetcher } from '../link/http/checkFetcher';
+export { createSignalIfSupported } from '../link/http/createSignalIfSupported';
+export { selectURI } from '../link/http/selectURI';
+export { createHttpLink } from '../link/http/createHttpLink';
+export { HttpLink } from '../link/http/HttpLink';
+export { fromError } from '../link/utils/fromError';
+export { ServerError, throwServerError } from '../link/utils/throwServerError';
+
+/* Utilities */
+
+export { Observable } from '../utilities/observables/Observable';
+export { getMainDefinition } from '../utilities/graphql/getFromAST';
+
+/* Supporting */
+
+export { default as gql } from 'graphql-tag';
diff --git a/src/index.ts b/src/index.ts
index 4834c678247..78a29b8b5a3 100644
--- a/src/index.ts
+++ b/src/index.ts
@@ -1,102 +1,2 @@
-/* Core */
-
-export {
- ApolloClient,
- ApolloClientOptions,
- DefaultOptions
-} from './ApolloClient';
-export {
- ObservableQuery,
- FetchMoreOptions,
- UpdateQueryOptions,
- ApolloCurrentQueryResult,
-} from './core/ObservableQuery';
-export {
- QueryBaseOptions,
- QueryOptions,
- WatchQueryOptions,
- MutationOptions,
- SubscriptionOptions,
- FetchPolicy,
- WatchQueryFetchPolicy,
- ErrorPolicy,
- FetchMoreQueryOptions,
- SubscribeToMoreOptions,
- MutationUpdaterFn,
-} from './core/watchQueryOptions';
-export { NetworkStatus } from './core/networkStatus';
-export * from './core/types';
-export {
- Resolver,
- FragmentMatcher as LocalStateFragmentMatcher,
-} from './core/LocalState';
-export { isApolloError, ApolloError } from './errors/ApolloError';
-
-/* Cache */
-
-export { Transaction, ApolloCache } from './cache/core/cache';
-export { Cache } from './cache/core/types/Cache';
-export { DataProxy } from './cache/core/types/DataProxy';
-export {
- InMemoryCache,
- InMemoryCacheConfig,
-} from './cache/inmemory/inMemoryCache';
-export { defaultDataIdFromObject } from './cache/inmemory/policies';
-export * from './cache/inmemory/types';
-
-/* React */
-
-export { ApolloProvider } from './react/context/ApolloProvider';
-export { ApolloConsumer } from './react/context/ApolloConsumer';
-export {
- getApolloContext,
- resetApolloContext,
- ApolloContextValue
-} from './react/context/ApolloContext';
-export { useQuery } from './react/hooks/useQuery';
-export { useLazyQuery } from './react/hooks/useLazyQuery';
-export { useMutation } from './react/hooks/useMutation';
-export { useSubscription } from './react/hooks/useSubscription';
-export { useApolloClient } from './react/hooks/useApolloClient';
-export { RenderPromises } from './react/ssr/RenderPromises';
-export * from './react/types/types';
-export * from './react/parser/parser';
-
-/* Link */
-
-export { empty } from './link/core/empty';
-export { from } from './link/core/from';
-export { split } from './link/core/split';
-export { concat } from './link/core/concat';
-export { execute } from './link/core/execute';
-export { ApolloLink } from './link/core/ApolloLink';
-export * from './link/core/types';
-export {
- parseAndCheckHttpResponse,
- ServerParseError
-} from './link/http/parseAndCheckHttpResponse';
-export {
- serializeFetchParameter,
- ClientParseError
-} from './link/http/serializeFetchParameter';
-export {
- HttpOptions,
- fallbackHttpConfig,
- selectHttpOptionsAndBody,
- UriFunction
-} from './link/http/selectHttpOptionsAndBody';
-export { checkFetcher } from './link/http/checkFetcher';
-export { createSignalIfSupported } from './link/http/createSignalIfSupported';
-export { selectURI } from './link/http/selectURI';
-export { createHttpLink } from './link/http/createHttpLink';
-export { HttpLink } from './link/http/HttpLink';
-export { fromError } from './link/utils/fromError';
-export { ServerError, throwServerError } from './link/utils/throwServerError';
-
-/* Utilities */
-
-export { Observable } from './utilities/observables/Observable';
-
-/* Supporting */
-
-export { default as gql } from 'graphql-tag';
+export * from './core';
+export * from './react';
diff --git a/src/react/data/MutationData.ts b/src/react/data/MutationData.ts
index 316ef21c13b..78d20e568a7 100644
--- a/src/react/data/MutationData.ts
+++ b/src/react/data/MutationData.ts
@@ -3,7 +3,7 @@ import { equal as isEqual } from '@wry/equality';
import { DocumentType } from '../parser/parser';
import { ApolloError } from '../../errors/ApolloError';
import {
- MutationOptions,
+ MutationDataOptions,
MutationTuple,
MutationFunctionOptions,
MutationResult
@@ -27,7 +27,7 @@ export class MutationData<
result,
setResult
}: {
- options: MutationOptions;
+ options: MutationDataOptions;
context: any;
result: MutationResult;
setResult: (result: MutationResult) => any;
diff --git a/src/react/data/QueryData.ts b/src/react/data/QueryData.ts
index c7f7b771191..853a9934ce4 100644
--- a/src/react/data/QueryData.ts
+++ b/src/react/data/QueryData.ts
@@ -15,7 +15,7 @@ import { DocumentType } from '../parser/parser';
import {
QueryResult,
QueryPreviousData,
- QueryOptions,
+ QueryDataOptions,
QueryCurrentObservable,
QueryTuple,
QueryLazyOptions,
@@ -36,7 +36,7 @@ export class QueryData extends OperationData {
context,
forceUpdate
}: {
- options: QueryOptions;
+ options: QueryDataOptions;
context: any;
forceUpdate: any;
}) {
diff --git a/src/react/data/SubscriptionData.ts b/src/react/data/SubscriptionData.ts
index 4ce09eebda4..9128899de3c 100644
--- a/src/react/data/SubscriptionData.ts
+++ b/src/react/data/SubscriptionData.ts
@@ -3,14 +3,14 @@ import { equal as isEqual } from '@wry/equality';
import { OperationData } from './OperationData';
import {
SubscriptionCurrentObservable,
- SubscriptionOptions,
+ SubscriptionDataOptions,
SubscriptionResult
} from '../types/types';
export class SubscriptionData<
TData = any,
TVariables = any
-> extends OperationData> {
+> extends OperationData> {
private setResult: any;
private currentObservable: SubscriptionCurrentObservable = {};
@@ -19,7 +19,7 @@ export class SubscriptionData<
context,
setResult
}: {
- options: SubscriptionOptions;
+ options: SubscriptionDataOptions;
context: any;
setResult: any;
}) {
@@ -77,7 +77,7 @@ export class SubscriptionData<
delete this.currentObservable.query;
}
- private initialize(options: SubscriptionOptions) {
+ private initialize(options: SubscriptionDataOptions) {
if (this.currentObservable.query || this.getOptions().skip === true) return;
this.currentObservable.query = this.refreshClient().client.subscribe({
query: options.subscription,
diff --git a/src/react/hooks/utils/useBaseQuery.ts b/src/react/hooks/utils/useBaseQuery.ts
index 4e09bde168d..5810e55f2d5 100644
--- a/src/react/hooks/utils/useBaseQuery.ts
+++ b/src/react/hooks/utils/useBaseQuery.ts
@@ -3,7 +3,7 @@ import { DocumentNode } from 'graphql';
import {
QueryHookOptions,
- QueryOptions,
+ QueryDataOptions,
QueryTuple,
QueryResult,
} from '../../types/types';
@@ -25,7 +25,7 @@ export function useBaseQuery(
if (!queryDataRef.current) {
queryDataRef.current = new QueryData({
- options: updatedOptions as QueryOptions,
+ options: updatedOptions as QueryDataOptions,
context,
forceUpdate
});
diff --git a/src/react/index.ts b/src/react/index.ts
new file mode 100644
index 00000000000..0cf189fadde
--- /dev/null
+++ b/src/react/index.ts
@@ -0,0 +1,21 @@
+export { ApolloProvider } from './context/ApolloProvider';
+export { ApolloConsumer } from './context/ApolloConsumer';
+export {
+ getApolloContext,
+ resetApolloContext,
+ ApolloContextValue
+} from './context/ApolloContext';
+export { useQuery } from './hooks/useQuery';
+export { useLazyQuery } from './hooks/useLazyQuery';
+export { useMutation } from './hooks/useMutation';
+export { useSubscription } from './hooks/useSubscription';
+export { useApolloClient } from './hooks/useApolloClient';
+export { RenderPromises } from './ssr/RenderPromises';
+export {
+ DocumentType,
+ IDocumentDefinition,
+ operationName,
+ parser
+} from './parser/parser';
+
+export * from './types/types';
diff --git a/src/react/ssr/RenderPromises.ts b/src/react/ssr/RenderPromises.ts
index ae2849e6a69..734c7ef395c 100644
--- a/src/react/ssr/RenderPromises.ts
+++ b/src/react/ssr/RenderPromises.ts
@@ -1,7 +1,7 @@
import { DocumentNode } from 'graphql';
import { ObservableQuery } from '../../core/ObservableQuery';
-import { QueryOptions } from '../types/types';
+import { QueryDataOptions } from '../types/types';
import { QueryData } from '../data/QueryData';
type QueryInfo = {
@@ -18,7 +18,7 @@ function makeDefaultQueryInfo(): QueryInfo {
export class RenderPromises {
// Map from Query component instances to pending fetchData promises.
- private queryPromises = new Map, Promise>();
+ private queryPromises = new Map, Promise>();
// Two-layered map from (query document, stringified variables) to QueryInfo
// objects. These QueryInfo objects are intended to survive through the whole
@@ -29,14 +29,14 @@ export class RenderPromises {
// Registers the server side rendered observable.
public registerSSRObservable(
observable: ObservableQuery,
- props: QueryOptions
+ props: QueryDataOptions
) {
this.lookupQueryInfo(props).observable = observable;
}
// Get's the cached observable that matches the SSR Query instances query and variables.
public getSSRObservable(
- props: QueryOptions
+ props: QueryDataOptions
) {
return this.lookupQueryInfo(props).observable;
}
@@ -84,7 +84,7 @@ export class RenderPromises {
}
private lookupQueryInfo(
- props: QueryOptions
+ props: QueryDataOptions
): QueryInfo {
const { queryInfoTrie } = this;
const { query, variables } = props;
diff --git a/src/react/types/types.ts b/src/react/types/types.ts
index 3e082c5ed37..415efe694d8 100644
--- a/src/react/types/types.ts
+++ b/src/react/types/types.ts
@@ -85,7 +85,7 @@ export interface QueryResult
called: boolean;
}
-export interface QueryOptions
+export interface QueryDataOptions
extends QueryFunctionOptions {
children?: (result: QueryResult) => ReactNode;
query: DocumentNode;
@@ -109,7 +109,7 @@ export interface QueryPreviousData {
observableQueryOptions?: {};
result?: ApolloQueryResult | null;
loading?: boolean;
- options?: QueryOptions;
+ options?: QueryDataOptions;
error?: ApolloError;
}
@@ -188,7 +188,7 @@ export interface MutationHookOptions<
mutation?: DocumentNode;
}
-export interface MutationOptions
+export interface MutationDataOptions
extends BaseMutationOptions {
mutation: DocumentNode;
}
@@ -235,7 +235,7 @@ export interface SubscriptionHookOptions<
subscription?: DocumentNode;
}
-export interface SubscriptionOptions<
+export interface SubscriptionDataOptions<
TData = any,
TVariables = OperationVariables
> extends BaseSubscriptionOptions {