Skip to content

Commit

Permalink
Expose datachecker to the network layer
Browse files Browse the repository at this point in the history
Reviewed By: lynnshaoyu

Differential Revision: D69814081

fbshipit-source-id: b1203bf2aee0c06f9ecbb69596f12d5c997bceb1
  • Loading branch information
tyao1 authored and facebook-github-bot committed Feb 20, 2025
1 parent 2e41a45 commit 7b68e1f
Show file tree
Hide file tree
Showing 5 changed files with 281 additions and 4 deletions.
3 changes: 3 additions & 0 deletions packages/relay-runtime/network/RelayNetworkTypes.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@

'use strict';

import type {OperationAvailability} from '../store/RelayStoreTypes';
import type {RequestParameters} from '../util/RelayConcreteNode';
import type {CacheConfig, Variables} from '../util/RelayRuntimeTypes';
import type RelayObservable, {ObservableFromValue} from './RelayObservable';
Expand Down Expand Up @@ -104,6 +105,8 @@ export type ExecuteFunction = (
logRequestInfo?: ?LogRequestInfoFunction,
encryptedVariables?: ?string,
preprocessResponse?: ?preprocessResponseFunction,
// Run datachecker on the current operation and returns the OperationAvailability
checkOperation?: () => OperationAvailability,
) => RelayObservable<GraphQLResponse>;

/**
Expand Down
20 changes: 19 additions & 1 deletion packages/relay-runtime/network/wrapNetworkWithLogObserver.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,12 +12,17 @@
'use strict';
import type ActorSpecificEnvironment from '../multi-actor-environment/ActorSpecificEnvironment';
import type RelayModernEnvironment from '../store/RelayModernEnvironment';
import type {
LogRequestInfoFunction,
OperationAvailability,
} from '../store/RelayStoreTypes';
import type {RequestParameters} from '../util/RelayConcreteNode';
import type {CacheConfig, Variables} from '../util/RelayRuntimeTypes';
import type {
GraphQLResponse,
INetwork,
UploadableMap,
preprocessResponseFunction,
} from './RelayNetworkTypes';
import type RelayObservable from './RelayObservable';
import type {Subscription} from './RelayObservable';
Expand All @@ -42,6 +47,10 @@ function wrapNetworkWithLogObserver(
variables: Variables,
cacheConfig: CacheConfig,
uploadables?: ?UploadableMap,
_?: ?LogRequestInfoFunction,
encryptedVariables?: ?string,
preprocessResponse?: ?preprocessResponseFunction,
checkOperation?: () => OperationAvailability,
): RelayObservable<GraphQLResponse> {
const networkRequestId = generateID();
const logObserver = {
Expand Down Expand Up @@ -89,7 +98,16 @@ function wrapNetworkWithLogObserver(
});
};
return network
.execute(params, variables, cacheConfig, uploadables, logRequestInfo)
.execute(
params,
variables,
cacheConfig,
uploadables,
logRequestInfo,
encryptedVariables,
preprocessResponse,
checkOperation,
)
.do(logObserver);
},
};
Expand Down
11 changes: 8 additions & 3 deletions packages/relay-runtime/store/RelayModernEnvironment.js
Original file line number Diff line number Diff line change
Expand Up @@ -327,13 +327,18 @@ class RelayModernEnvironment implements IEnvironment {
operation: OperationDescriptor,
}): RelayObservable<GraphQLResponse> {
return this._execute({
createSource: () =>
this.getNetwork().execute(
createSource: () => {
return this.getNetwork().execute(
operation.request.node.params,
operation.request.variables,
operation.request.cacheConfig || {},
null,
),
undefined,
undefined,
undefined,
() => this.check(operation),
);
},
isClientPayload: false,
operation,
optimisticConfig: null,
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
/**
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
* @flow strict-local
* @format
* @oncall relay
*/

'use strict';
import type {GraphQLResponse} from '../../network/RelayNetworkTypes';

const RelayObservable = require('../../network/RelayObservable');
const {graphql} = require('../../query/GraphQLTag');
const RelayModernEnvironment = require('../RelayModernEnvironment');
const {
createOperationDescriptor,
} = require('../RelayModernOperationDescriptor');
const RelayModernStore = require('../RelayModernStore');
const RelayRecordSource = require('../RelayRecordSource');
const {disallowWarnings} = require('relay-test-utils-internal');

disallowWarnings();

describe('execute() provides a `check` function for the network layer to determine availability of data in store', () => {
let callbacks;
let complete;
let environment;
let error;
let next;
let operation;
let query;
let source;
let store;
let subject;
let variables;
let network;
let check;
beforeEach(() => {
query = graphql`
query RelayModernEnvironmentExecuteWithCheckTestQuery(
$fetchSize: Boolean!
) {
me {
name
profilePicture(size: 42) @include(if: $fetchSize) {
uri
}
}
}
`;
variables = {fetchSize: false};
operation = createOperationDescriptor(query, variables);

complete = jest.fn<[], mixed>();
error = jest.fn<[Error], mixed>();
next = jest.fn<[GraphQLResponse], mixed>();
callbacks = {complete, error, next};

network = {
execute: jest.fn(
(_query, _variables, _cacheConfig, _1, _2, _3, _4, _check) => {
check = _check;
return RelayObservable.create(sink => {
subject = sink;
});
},
),
};
source = RelayRecordSource.create();
store = new RelayModernStore(source);
environment = new RelayModernEnvironment({
network,
store,
});
});

it('returns the correct availability in the check function', () => {
environment.execute({operation}).subscribe(callbacks);
expect(check().status).toBe('missing');
subject.next({
data: {
me: {
id: '842472',
__typename: 'User',
name: 'Joe',
},
},
});
jest.runAllTimers();

environment.execute({operation}).subscribe(callbacks);
expect(check().status).toBe('available');
});
});

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

0 comments on commit 7b68e1f

Please sign in to comment.