UNPKG

relay-runtime

Version:

A core runtime for building GraphQL-driven applications.

111 lines (103 loc) 3.21 kB
/** * 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 {ConcreteRequest} from '../util/RelayConcreteNode'; import type { CacheConfig, DataID, OperationType, Variables, VariablesOf, } from '../util/RelayRuntimeTypes'; import type {OperationDescriptor, RequestDescriptor} from './RelayStoreTypes'; const deepFreeze = require('../util/deepFreeze'); const getRequestIdentifier = require('../util/getRequestIdentifier'); const RelayFeatureFlags = require('../util/RelayFeatureFlags'); const {hasCycle} = require('../util/stableCopy'); const {getOperationVariables} = require('./RelayConcreteVariables'); const { createNormalizationSelector, createReaderSelector, } = require('./RelayModernSelector'); const {ROOT_ID} = require('./RelayStoreUtils'); const invariant = require('invariant'); /** * Creates an instance of the `OperationDescriptor` type defined in * `RelayStoreTypes` given an operation and some variables. The input variables * are filtered to exclude variables that do not match defined arguments on the * operation, and default values are populated for null values. */ function createOperationDescriptor<TQuery: OperationType>( request: ConcreteRequest, variables: VariablesOf<TQuery>, cacheConfig?: ?CacheConfig, dataID?: DataID = ROOT_ID, ): OperationDescriptor { const operation = request.operation; const operationVariables = getOperationVariables( operation, request.params.providedVariables, variables, ); if (RelayFeatureFlags.ENABLE_CYLE_DETECTION_IN_VARIABLES) { invariant( !hasCycle(operationVariables), 'Cycle detected in variables passed to operation `%s`.', request.operation.name, ); } const requestDescriptor = createRequestDescriptor( request, operationVariables, cacheConfig, ); const operationDescriptor = { fragment: createReaderSelector( request.fragment, dataID, operationVariables, requestDescriptor, ), request: requestDescriptor, root: createNormalizationSelector(operation, dataID, operationVariables), }; if (__DEV__) { // Freezing properties short-circuits a deepFreeze of snapshots that contain // an OperationDescriptor via their selector's owner, avoiding stack // overflow on larger queries. Object.freeze(operationDescriptor.fragment); Object.freeze(operationDescriptor.root); Object.freeze(operationDescriptor); } return operationDescriptor; } function createRequestDescriptor( request: ConcreteRequest, variables: Variables, cacheConfig?: ?CacheConfig, ): RequestDescriptor { const requestDescriptor = { identifier: getRequestIdentifier(request.params, variables), node: request, variables: variables, cacheConfig: cacheConfig, }; if (__DEV__) { deepFreeze(variables); Object.freeze(request); Object.freeze(requestDescriptor); } return requestDescriptor; } module.exports = { createOperationDescriptor, createRequestDescriptor, };