Skip to content

Commit

Permalink
Update loadQuery types
Browse files Browse the repository at this point in the history
Reviewed By: kassens

Differential Revision: D49202960

fbshipit-source-id: 526ba58006c6342fc413a2e5ec9203987b113bd9
  • Loading branch information
alunyov authored and facebook-github-bot committed Sep 14, 2023
1 parent 1decb24 commit 3353587
Show file tree
Hide file tree
Showing 7 changed files with 179 additions and 260 deletions.
9 changes: 6 additions & 3 deletions packages/react-relay/relay-hooks/EntryPointTypes.flow.js
Original file line number Diff line number Diff line change
Expand Up @@ -45,12 +45,15 @@ export type LoadQueryOptions = {
+__nameForWarning?: ?string,
};

// Note: the phantom type parameter here helps ensures that the
// $Parameters.js value matches the type param provided to preloadQuery.
// eslint-disable-next-line no-unused-vars
export type PreloadableConcreteRequest<TQuery: OperationType> = {
kind: 'PreloadableConcreteRequest',
params: RequestParameters,
// Note: the phantom type parameter here helps ensures that the
// $Parameters.js value matches the type param provided to preloadQuery.
// We also need to add usage of this generic here,
// becuase not using the generic in the definition makes it
// unconstrained in the call to a function that accepts PreloadableConcreteRequest<T>
__phantom__?: ?TQuery,
};

export type EnvironmentProviderOptions = {+[string]: mixed, ...};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,8 @@ import type {
LoadQueryOptions,
PreloadableConcreteRequest,
} from '../EntryPointTypes.flow';
import type {GraphQLTaggedNode, OperationType} from 'relay-runtime';
import type {loadQuerySourceBehaviorTestQuery} from './__generated__/loadQuerySourceBehaviorTestQuery.graphql';
import type {OperationType, Query} from 'relay-runtime';
import type {GraphQLResponse} from 'relay-runtime/network/RelayNetworkTypes';

const {loadQuery} = require('../loadQuery');
Expand Down Expand Up @@ -43,10 +44,11 @@ const query = graphql`
}
`;

const preloadableConcreteRequest = {
kind: 'PreloadableConcreteRequest',
params: query.params,
};
const preloadableConcreteRequest: PreloadableConcreteRequest<loadQuerySourceBehaviorTestQuery> =
{
kind: 'PreloadableConcreteRequest',
params: query.params,
};

const response = {
data: {
Expand Down Expand Up @@ -148,11 +150,7 @@ beforeEach(() => {
});

writeDataToStore = () => {
loadQuery<$FlowFixMe, _>(
environment,
preloadableConcreteRequest,
variables,
);
loadQuery(environment, preloadableConcreteRequest, variables);
sink.next(response);
sink.complete();
PreloadableQueryRegistry.set(ID, query);
Expand All @@ -163,12 +161,14 @@ beforeEach(() => {
PreloadableQueryRegistry.clear();
};

callLoadQuery = <TQuery: OperationType>(
queryAstOrRequest: GraphQLTaggedNode | PreloadableConcreteRequest<TQuery>,
callLoadQuery = <TOperation: OperationType>(
queryAstOrRequest:
| Query<TOperation['variables'], TOperation['response']>
| PreloadableConcreteRequest<TOperation>,
options?: LoadQueryOptions,
// $FlowFixMe[missing-local-annot]
) => {
const loadedQuery = loadQuery<$FlowFixMe, _>(
const loadedQuery = loadQuery(
environment,
queryAstOrRequest,
variables,
Expand Down Expand Up @@ -425,7 +425,7 @@ describe('when passed a PreloadableConcreteRequest', () => {
// calls to load will get disposed

// Start initial load of query
const queryRef1 = loadQuery<$FlowFixMe, _>(
const queryRef1 = loadQuery(
environment,
preloadableConcreteRequest,
variables,
Expand All @@ -446,7 +446,7 @@ describe('when passed a PreloadableConcreteRequest', () => {
expect(environment.executeWithSource).toBeCalledTimes(1);

// Start second load of query
const queryRef2 = loadQuery<$FlowFixMe, _>(
const queryRef2 = loadQuery(
environment,
preloadableConcreteRequest,
variables,
Expand Down Expand Up @@ -487,15 +487,15 @@ describe('when passed a PreloadableConcreteRequest', () => {

describe('when passed a query AST', () => {
it('should pass network responses onto source', () => {
callLoadQuery(query);
callLoadQuery<loadQuerySourceBehaviorTestQuery>(query);

expect(next).not.toHaveBeenCalled();
sink.next(response);
expect(next).toHaveBeenCalledWith(response);
});

it('should pass network errors onto source', () => {
callLoadQuery(query);
callLoadQuery<loadQuerySourceBehaviorTestQuery>(query);

expect(error).not.toHaveBeenCalled();
sink.error(networkError);
Expand All @@ -504,14 +504,14 @@ describe('when passed a query AST', () => {

describe('when dispose is called before the network response is available', () => {
it('should not pass network responses onto source', () => {
const {dispose} = callLoadQuery(query);
const {dispose} = callLoadQuery<loadQuerySourceBehaviorTestQuery>(query);

dispose();
sink.next(response);
expect(next).not.toHaveBeenCalled();
});
it('should not pass network errors onto source', done => {
const {dispose} = callLoadQuery(query);
const {dispose} = callLoadQuery<loadQuerySourceBehaviorTestQuery>(query);

dispose();

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,9 @@ import type {
CacheConfig,
Variables,
} from '../../../relay-runtime/util/RelayRuntimeTypes';
import type {PreloadableConcreteRequest} from '../EntryPointTypes.flow';
import type {
loadQueryStoreBehaviorTestQuery,
loadQueryStoreBehaviorTestQuery$data,
loadQueryStoreBehaviorTestQuery$variables,
} from './__generated__/loadQueryStoreBehaviorTestQuery.graphql';
Expand Down Expand Up @@ -57,10 +59,11 @@ const query = graphql`
const ID = '12345';
(query.params: $FlowFixMe).id = ID;

const preloadableConcreteRequest = {
kind: 'PreloadableConcreteRequest',
params: query.params,
};
const preloadableConcreteRequest: PreloadableConcreteRequest<loadQueryStoreBehaviorTestQuery> =
{
kind: 'PreloadableConcreteRequest',
params: query.params,
};

const response: GraphQLSingularResponse = {
data: {
Expand Down Expand Up @@ -130,11 +133,7 @@ beforeEach(() => {
.mockImplementation(() => resolvedModule);

writeDataToStore = () => {
loadQuery<OperationType>(
environment,
preloadableConcreteRequest,
variables,
);
loadQuery(environment, preloadableConcreteRequest, variables);
sink.next(response);
sink.complete();
PreloadableQueryRegistry.set(ID, query);
Expand All @@ -157,11 +156,7 @@ describe('when passed a PreloadableConcreteRequest', () => {
});
it('should write the data to the store after the query AST and network response are available', () => {
expect(store.check(operation).status).toBe('missing');
loadQuery<OperationType>(
environment,
preloadableConcreteRequest,
variables,
);
loadQuery(environment, preloadableConcreteRequest, variables);
expect(fetch).toHaveBeenCalled();
expect(store.check(operation).status).toBe('missing');
PreloadableQueryRegistry.set(ID, query);
Expand All @@ -172,11 +167,7 @@ describe('when passed a PreloadableConcreteRequest', () => {

it('should write the data to the store after the network response and query AST are available', () => {
expect(store.check(operation).status).toBe('missing');
loadQuery<OperationType>(
environment,
preloadableConcreteRequest,
variables,
);
loadQuery(environment, preloadableConcreteRequest, variables);
expect(store.check(operation).status).toBe('missing');
sink.next(response);
expect(store.check(operation).status).toBe('missing');
Expand All @@ -186,7 +177,7 @@ describe('when passed a PreloadableConcreteRequest', () => {

it('should not write the data to the store if dispose is called before the query AST and network response are available', () => {
expect(store.check(operation).status).toBe('missing');
const {dispose} = loadQuery<OperationType>(
const {dispose} = loadQuery(
environment,
preloadableConcreteRequest,
variables,
Expand All @@ -200,7 +191,7 @@ describe('when passed a PreloadableConcreteRequest', () => {

it('should not write the data to the store if dispose is called before the network response and query AST are available', () => {
expect(store.check(operation).status).toBe('missing');
const {dispose} = loadQuery<OperationType>(
const {dispose} = loadQuery(
environment,
preloadableConcreteRequest,
variables,
Expand All @@ -214,7 +205,7 @@ describe('when passed a PreloadableConcreteRequest', () => {

it('should not write the data to the store if dispose is called after the query AST is available, but before the network response is available', () => {
expect(store.check(operation).status).toBe('missing');
const {dispose} = loadQuery<OperationType>(
const {dispose} = loadQuery(
environment,
preloadableConcreteRequest,
variables,
Expand All @@ -228,7 +219,7 @@ describe('when passed a PreloadableConcreteRequest', () => {

it('should not write the data to the store if dispose is called after the network response is available, but before the query AST is available', () => {
expect(store.check(operation).status).toBe('missing');
const {dispose} = loadQuery<OperationType>(
const {dispose} = loadQuery(
environment,
preloadableConcreteRequest,
variables,
Expand All @@ -244,18 +235,14 @@ describe('when passed a PreloadableConcreteRequest', () => {
describe('when the query AST is available synchronously', () => {
it('should write data to the store when the network response is available', () => {
expect(store.check(operation).status).toBe('missing');
loadQuery<OperationType>(
environment,
preloadableConcreteRequest,
variables,
);
loadQuery(environment, preloadableConcreteRequest, variables);
sink.next(response);
expect(store.check(operation).status).toBe('available');
});

it('should not write data to the store if dispose is called before the network response is available', () => {
expect(store.check(operation).status).toBe('missing');
const {dispose} = loadQuery<OperationType>(
const {dispose} = loadQuery(
environment,
preloadableConcreteRequest,
variables,
Expand All @@ -271,14 +258,9 @@ describe('when passed a PreloadableConcreteRequest', () => {
beforeEach(() => writeDataToStore());
describe('when the query AST is available synchronously', () => {
it('should write updated data to the store when the network response is available', () => {
loadQuery<OperationType>(
environment,
preloadableConcreteRequest,
variables,
{
fetchPolicy: 'network-only',
},
);
loadQuery(environment, preloadableConcreteRequest, variables, {
fetchPolicy: 'network-only',
});

expect(
(store.lookup(operation.fragment): $FlowFixMe)?.data?.node?.name,
Expand All @@ -290,7 +272,7 @@ describe('when passed a PreloadableConcreteRequest', () => {
});

it('should not write updated data to the store if dispose is called before the network response is available', () => {
const {dispose} = loadQuery<OperationType>(
const {dispose} = loadQuery(
environment,
preloadableConcreteRequest,
variables,
Expand All @@ -311,14 +293,9 @@ describe('when passed a PreloadableConcreteRequest', () => {
resolvedModule = undefined;
});
it('should write updated data to the store when the network response and query AST are available', () => {
loadQuery<OperationType>(
environment,
preloadableConcreteRequest,
variables,
{
fetchPolicy: 'network-only',
},
);
loadQuery(environment, preloadableConcreteRequest, variables, {
fetchPolicy: 'network-only',
});

expect(
(store.lookup(operation.fragment): $FlowFixMe)?.data?.node?.name,
Expand All @@ -334,14 +311,9 @@ describe('when passed a PreloadableConcreteRequest', () => {
).toEqual('Mark');
});
it('should write updated data to the store when the query AST and network response are available', () => {
loadQuery<OperationType>(
environment,
preloadableConcreteRequest,
variables,
{
fetchPolicy: 'network-only',
},
);
loadQuery(environment, preloadableConcreteRequest, variables, {
fetchPolicy: 'network-only',
});

expect(
(store.lookup(operation.fragment): $FlowFixMe)?.data?.node?.name,
Expand All @@ -358,7 +330,7 @@ describe('when passed a PreloadableConcreteRequest', () => {
});

it('should not write updated data to the store if dispose is called before the network response and query AST are available', () => {
const {dispose} = loadQuery<OperationType>(
const {dispose} = loadQuery(
environment,
preloadableConcreteRequest,
variables,
Expand All @@ -379,7 +351,7 @@ describe('when passed a PreloadableConcreteRequest', () => {
});

it('should not write updated data to the store if dispose is called before the query AST and network response are available', () => {
const {dispose} = loadQuery<OperationType>(
const {dispose} = loadQuery(
environment,
preloadableConcreteRequest,
variables,
Expand All @@ -400,7 +372,7 @@ describe('when passed a PreloadableConcreteRequest', () => {
});

it('should not write updated data to the store if dispose is called after the query AST is available and before the network response is available', () => {
const {dispose} = loadQuery<OperationType>(
const {dispose} = loadQuery(
environment,
preloadableConcreteRequest,
variables,
Expand All @@ -424,7 +396,7 @@ describe('when passed a PreloadableConcreteRequest', () => {
});

it('should not write updated data to the store if dispose is called after ·the network repsonse is available and before the query AST is available', () => {
const {dispose} = loadQuery<OperationType>(
const {dispose} = loadQuery(
environment,
preloadableConcreteRequest,
variables,
Expand Down Expand Up @@ -454,14 +426,14 @@ describe('when passed a query AST', () => {
describe('when data is unavailable in the store', () => {
it('should write data to the store when the network response is available', () => {
expect(store.check(operation).status).toBe('missing');
loadQuery<OperationType>(environment, query, variables);
loadQuery(environment, query, variables);
sink.next(response);
expect(store.check(operation).status).toBe('available');
});

it('should not write data to the store if dispose is called before the network response is available', () => {
expect(store.check(operation).status).toBe('missing');
const {dispose} = loadQuery<OperationType>(environment, query, variables);
const {dispose} = loadQuery(environment, query, variables);
dispose();
sink.next(response);
expect(store.check(operation).status).toBe('missing');
Expand All @@ -470,7 +442,7 @@ describe('when passed a query AST', () => {
describe("when data is available in the store, but the fetch policy is 'network-only'", () => {
beforeEach(() => writeDataToStore());
it('should write updated data to the store when the network response is available', () => {
loadQuery<OperationType>(environment, query, variables, {
loadQuery(environment, query, variables, {
fetchPolicy: 'network-only',
});

Expand All @@ -484,14 +456,9 @@ describe('when passed a query AST', () => {
});

it('should not write updated data to the store if dispose is called before the network response is available', () => {
const {dispose} = loadQuery<OperationType>(
environment,
query,
variables,
{
fetchPolicy: 'network-only',
},
);
const {dispose} = loadQuery(environment, query, variables, {
fetchPolicy: 'network-only',
});

dispose();
sink.next(updatedResponse);
Expand Down
Loading

0 comments on commit 3353587

Please sign in to comment.