Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Export utilities via @apollo/client/utilities #5683

Merged
merged 4 commits into from
Dec 14, 2019
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 3 additions & 6 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -48,9 +48,6 @@
- Removed `apollo-boost` since Apollo Client 3.0 provides a boost like getting started experience out of the box. <br/>
[@hwillson](https://github.com/hwillson) in [#5217](https://github.com/apollographql/apollo-client/pull/5217)

- The `@apollo/client` package is now published without a nested `@apollo/client/lib` directory. <br/>
[@hwillson](https://github.com/hwillson) in [#5357](https://github.com/apollographql/apollo-client/pull/5357)

- The `queryManager` property of `ApolloClient` instances is now marked as
`private`, paving the way for a more aggressive redesign of its API.

@@ -68,9 +65,6 @@
- `ApolloClient` is now only available as a named export. The default `ApolloClient` export has been removed. <br/>
[@hwillson](https://github.com/hwillson) in [#5425](https://github.com/apollographql/apollo-client/pull/5425)

- Utilities that were previously externally available through the `apollo-utilities` package, are now internal only. <br/>
[@hwillson](https://github.com/hwillson) in [#TODO](https://github.com/apollographql/apollo-client/pull/TODO)

- 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. </br>
[@benjamn](https://github.com/benjamn) in [#5565](https://github.com/apollographql/apollo-client/pull/5565)

@@ -94,6 +88,9 @@
- Custom field `read` functions can read from neighboring fields using the `getFieldValue(fieldName)` helper, and may also read fields from other entities by calling `getFieldValue(fieldName, foreignReference)`. <br/>
[@benjamn](https://github.com/benjamn) in [#5651](https://github.com/apollographql/apollo-client/pull/5651)

- Utilities that were previously externally available through the `apollo-utilities` package are now only available by importing from `@apollo/client/utilities`. <br/>
[@hwillson](https://github.com/hwillson) in [#5683](https://github.com/apollographql/apollo-client/pull/5683)

## Apollo Client (2.6.4)

### Apollo Client (2.6.4)
20 changes: 13 additions & 7 deletions config/prepareDist.js
Original file line number Diff line number Diff line change
@@ -53,7 +53,7 @@ fs.copyFileSync(`${srcDir}/README.md`, `${destDir}/README.md`);
fs.copyFileSync(`${srcDir}/LICENSE`, `${destDir}/LICENSE`);


/* @apollo/client/core, @apollo/client/cache */
/* @apollo/client/core, @apollo/client/cache, @apollo/client/utilities */

function buildPackageJson(bundleName) {
return JSON.stringify({
@@ -91,15 +91,21 @@ function writeCjsIndex(bundleName, exportNames, includeNames = true) {
].join('\n'));
}

// Create `core` and `cache` bundle package.json files, storing them in their
// associated dist directory. This helps provide a way for the Apollo Client
// core to be used without React (via `@apollo/client/core`), and the cache
// to be used by itself (via `@apollo/client/cache`). Also create
// `core.cjs.js` and `cache.cjs.js` CommonJS entry point files that only
// include the exports needed for each bundle.
// Create `core`, `cache` and `utilities` bundle package.json files, storing
// them in their associated dist directory. This helps provide a way for the
// Apollo Client core to be used without React (via `@apollo/client/core`),
// and AC's cache and utilities to be used by themselves
// (`@apollo/client/cache` and `@apollo/client/utilities`), via the
// `core.cjs.js`, `cache.cjs.js` and `utilities.cjs.js` CommonJS entry point
// files that only include the exports needed for each bundle.

fs.writeFileSync(`${distRoot}/core/package.json`, buildPackageJson('core'));
writeCjsIndex('core', loadExportNames('react'), false);

fs.writeFileSync(`${distRoot}/cache/package.json`, buildPackageJson('cache'));
writeCjsIndex('cache', loadExportNames('cache'));

fs.writeFileSync(
`${distRoot}/utilities/package.json`,
buildPackageJson('utilities')
);
18 changes: 18 additions & 0 deletions config/rollup.config.js
Original file line number Diff line number Diff line change
@@ -108,6 +108,23 @@ function prepareCJSMinified(input) {
};
}

function prepareUtilities() {
const utilsDistDir = `${distDir}/utilities`;
return {
input: `${utilsDistDir}/index.js`,
external,
output: {
file: `${utilsDistDir}/utilities.cjs.js`,
format: 'cjs',
sourcemap: true,
exports: 'named',
},
plugins: [
nodeResolve(),
],
};
}

Comment on lines +111 to +127
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We can't follow our usual approach of creating a file that just re-exports only the items it needs from the main apollo-client.cjs.js bundle, as we aren't exporting utilities in apollo-client.cjs.js. Here we're building a separate utilities.cjs.js bundle instead.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yep, makes sense. Even easier this way.

// Build a separate CJS only `testing.js` bundle, that includes React
// testing utilities like `MockedProvider` (testing utilities are kept out of
// the main `apollo-client` bundle). This bundle can be accessed directly
@@ -144,6 +161,7 @@ function rollup() {
prepareESM(packageJson.module, distDir),
prepareCJS(packageJson.module, packageJson.main),
prepareCJSMinified(packageJson.main),
prepareUtilities(),
prepareTesting(),
];
}
5 changes: 3 additions & 2 deletions src/cache/inmemory/entityStore.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
import { dep, OptimisticDependencyFunction, KeyTrie } from 'optimism';
import { invariant } from 'ts-invariant';
import { equal } from '@wry/equality';

import { isReference, StoreValue } from '../../utilities/graphql/storeUtils';
import {
DeepMerger,
ReconcilerFunction,
} from '../../utilities/common/mergeDeep';
import { isEqual } from '../../utilities/common/isEqual';
import { canUseWeakMap } from '../../utilities/common/canUse';
import { NormalizedCache, NormalizedCacheObject, StoreObject } from './types';
import {
@@ -482,7 +483,7 @@ const storeObjectReconciler: ReconcilerFunction<[EntityStore]> = function (
// returning incoming would be logically correct) because preserving
// the referential identity of existing data can prevent needless
// rereading and rerendering.
if (isEqual(existing, incoming)) {
if (equal(existing, incoming)) {
return existing;
}
}
4 changes: 2 additions & 2 deletions src/core/LocalState.ts
Original file line number Diff line number Diff line change
@@ -32,7 +32,6 @@ import {
} from '../utilities/graphql/storeUtils';
import { ApolloClient } from '../ApolloClient';
import { Resolvers, OperationVariables } from './types';
import { capitalizeFirstLetter } from '../utilities/common/capitalizeFirstLetter';

export type Resolver = (
rootValue?: any,
@@ -278,7 +277,8 @@ export class LocalState<TCacheShape> {
.operation;

const defaultOperationType = definitionOperation
? capitalizeFirstLetter(definitionOperation)
? definitionOperation.charAt(0).toUpperCase() +
definitionOperation.slice(1)
: 'Query';

const { cache, client } = this;
12 changes: 6 additions & 6 deletions src/core/ObservableQuery.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { invariant, InvariantError } from 'ts-invariant';
import { equal } from '@wry/equality';

import { isEqual } from '../utilities/common/isEqual';
import { tryFunctionOrLogError } from '../utilities/common/errorHandling';
import { cloneDeep } from '../utilities/common/cloneDeep';
import { getOperationDefinition } from '../utilities/graphql/getFromAST';
@@ -207,7 +207,7 @@ export class ObservableQuery<
newResult &&
snapshot.networkStatus === newResult.networkStatus &&
snapshot.stale === newResult.stale &&
isEqual(snapshot.data, newResult.data)
equal(snapshot.data, newResult.data)
);
}

@@ -260,15 +260,15 @@ export class ObservableQuery<
fetchPolicy = 'network-only';
}

if (!isEqual(this.variables, variables)) {
if (!equal(this.variables, variables)) {
// update observable variables
this.variables = {
...this.variables,
...variables,
};
}

if (!isEqual(this.options.variables, this.variables)) {
if (!equal(this.options.variables, this.variables)) {
// Update the existing options with new variables
this.options.variables = {
...this.options.variables,
@@ -446,7 +446,7 @@ export class ObservableQuery<

variables = variables || this.variables;

if (!tryFetch && isEqual(variables, this.variables)) {
if (!tryFetch && equal(variables, this.variables)) {
// If we have no observers, then we don't actually want to make a network
// request. As soon as someone observes the query, the request will kick
// off. For now, we just store any changes. (See #1077)
@@ -600,7 +600,7 @@ export class ObservableQuery<
previousResult &&
fetchPolicy !== 'cache-only' &&
queryManager.transform(query).serverQuery &&
!isEqual(previousVariables, variables)
!equal(previousVariables, variables)
) {
this.refetch();
} else {
6 changes: 3 additions & 3 deletions src/data/queries.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { DocumentNode, GraphQLError, ExecutionResult } from 'graphql';
import { invariant } from 'ts-invariant';

import { isEqual } from '../utilities/common/isEqual';
import { equal } from '@wry/equality';
import { NetworkStatus } from '../core/networkStatus';
import { isNonEmptyArray } from '../utilities/common/arrays';

@@ -44,7 +44,7 @@ export class QueryStore {
invariant(
!previousQuery ||
previousQuery.document === query.document ||
isEqual(previousQuery.document, query.document),
equal(previousQuery.document, query.document),
'Internal Error: may not update existing query string in store',
);

@@ -57,7 +57,7 @@ export class QueryStore {
previousQuery.networkStatus !== NetworkStatus.loading
// if the previous query was still loading, we don't want to remember it at all.
) {
if (!isEqual(previousQuery.variables, query.variables)) {
if (!equal(previousQuery.variables, query.variables)) {
isSetVariables = true;
previousVariables = previousQuery.variables;
}
4 changes: 2 additions & 2 deletions src/react/data/MutationData.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { equal as isEqual } from '@wry/equality';
import { equal } from '@wry/equality';

import { DocumentType } from '../parser/parser';
import { ApolloError } from '../../errors/ApolloError';
@@ -175,7 +175,7 @@ export class MutationData<
private updateResult(result: MutationResult<TData>) {
if (
this.isMounted &&
(!this.previousResult || !isEqual(this.previousResult, result))
(!this.previousResult || !equal(this.previousResult, result))
) {
this.setResult(result);
this.previousResult = result;
4 changes: 2 additions & 2 deletions src/react/data/OperationData.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { DocumentNode } from 'graphql';
import { equal as isEqual } from '@wry/equality';
import { equal } from '@wry/equality';
import { invariant } from 'ts-invariant';

import { ApolloClient } from '../../ApolloClient';
@@ -29,7 +29,7 @@ export abstract class OperationData<TOptions = any> {
newOptions: CommonOptions<TOptions>,
storePrevious: boolean = false
) {
if (storePrevious && !isEqual(this.options, newOptions)) {
if (storePrevious && !equal(this.options, newOptions)) {
this.previousOptions = this.options;
}
this.options = newOptions;
12 changes: 6 additions & 6 deletions src/react/data/QueryData.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { equal as isEqual } from '@wry/equality';
import { equal } from '@wry/equality';

import { ApolloError } from '../../errors/ApolloError';
import { NetworkStatus } from '../../core/networkStatus';
@@ -245,7 +245,7 @@ export class QueryData<TData, TVariables> extends OperationData {
};

if (
!isEqual(
!equal(
newObservableQueryOptions,
this.previousData.observableQueryOptions
)
@@ -280,7 +280,7 @@ export class QueryData<TData, TVariables> extends OperationData {
previousResult &&
previousResult.loading === loading &&
previousResult.networkStatus === networkStatus &&
isEqual(previousResult.data, data)
equal(previousResult.data, data)
) {
return;
}
@@ -306,7 +306,7 @@ export class QueryData<TData, TVariables> extends OperationData {
const previousResult = this.previousData.result;
if (
(previousResult && previousResult.loading) ||
!isEqual(error, this.previousData.error)
!equal(error, this.previousData.error)
) {
this.previousData.error = error;
onNewData();
@@ -433,8 +433,8 @@ export class QueryData<TData, TVariables> extends OperationData {
if (
this.previousOptions &&
!this.previousData.loading &&
isEqual(this.previousOptions.query, query) &&
isEqual(this.previousOptions.variables, variables)
equal(this.previousOptions.query, query) &&
equal(this.previousOptions.variables, variables)
) {
return;
}
4 changes: 2 additions & 2 deletions src/react/data/SubscriptionData.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { equal as isEqual } from '@wry/equality';
import { equal } from '@wry/equality';

import { OperationData } from './OperationData';
import {
@@ -54,7 +54,7 @@ export class SubscriptionData<
this.previousOptions &&
Object.keys(this.previousOptions).length > 0 &&
(this.previousOptions.subscription !== this.getOptions().subscription ||
!isEqual(this.previousOptions.variables, this.getOptions().variables) ||
!equal(this.previousOptions.variables, this.getOptions().variables) ||
this.previousOptions.skip !== this.getOptions().skip)
) {
this.cleanup();
4 changes: 2 additions & 2 deletions src/react/hooks/utils/useDeepMemo.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { equal as isEqual } from '@wry/equality';
import { equal } from '@wry/equality';

import { requireReactLazily } from '../../react';

@@ -17,7 +17,7 @@ export function useDeepMemo<TKey, TValue>(
const { useRef } = React;
const ref = useRef<{ key: TKey; value: TValue }>();

if (!ref.current || !isEqual(key, ref.current.key)) {
if (!ref.current || !equal(key, ref.current.key)) {
ref.current = { key, value: memoFn() };
}

Loading