relay-runtime 20.1.1 → 21.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (334) hide show
  1. package/experimental.d.ts +34 -0
  2. package/experimental.js +1 -1
  3. package/experimental.js.flow +11 -11
  4. package/handlers/RelayDefaultHandlerProvider.d.ts +12 -0
  5. package/handlers/connection/ConnectionHandler.d.ts +51 -0
  6. package/handlers/connection/ConnectionHandler.js.flow +5 -5
  7. package/handlers/connection/ConnectionInterface.d.ts +40 -0
  8. package/handlers/connection/ConnectionInterface.js.flow +1 -1
  9. package/handlers/connection/MutationHandlers.d.ts +17 -0
  10. package/index.d.ts +274 -0
  11. package/index.js +1 -1
  12. package/index.js.flow +125 -62
  13. package/lib/experimental.js +3 -3
  14. package/lib/index.js +105 -57
  15. package/lib/multi-actor-environment/ActorIdentifier.js +2 -2
  16. package/lib/multi-actor-environment/MultiActorEnvironment.js +3 -1
  17. package/lib/mutations/commitMutation.js +8 -8
  18. package/lib/mutations/validateMutation.js +4 -4
  19. package/lib/query/GraphQLTag.js +3 -3
  20. package/lib/query/fetchQuery.js +15 -3
  21. package/lib/store/DataChecker.js +38 -4
  22. package/lib/store/NormalizationEngine.js +373 -0
  23. package/lib/store/OperationExecutor.js +172 -113
  24. package/lib/store/RelayConcreteVariables.js +1 -1
  25. package/lib/store/RelayErrorTrie.js +2 -2
  26. package/lib/store/RelayExperimentalGraphResponseTransform.js +8 -8
  27. package/lib/store/RelayModernEnvironment.js +26 -19
  28. package/lib/store/RelayModernRecord.js +18 -8
  29. package/lib/store/RelayModernSelector.js +9 -9
  30. package/lib/store/RelayModernStore.js +152 -43
  31. package/lib/store/RelayPublishQueue.js +1 -1
  32. package/lib/store/RelayReader.js +76 -38
  33. package/lib/store/RelayRecordSource.js +6 -0
  34. package/lib/store/RelayReferenceMarker.js +2 -1
  35. package/lib/store/RelayResponseNormalizer.js +88 -55
  36. package/lib/store/RelayStoreSubscriptions.js +34 -10
  37. package/lib/store/RelayStoreUtils.js +8 -1
  38. package/lib/store/ResolverFragments.js +2 -2
  39. package/lib/store/live-resolvers/LiveResolverCache.js +25 -9
  40. package/lib/store/observeFragmentExperimental.js +17 -1
  41. package/lib/store/observeQueryExperimental.js +2 -2
  42. package/lib/subscription/requestSubscription.js +3 -3
  43. package/lib/util/RelayError.js +3 -0
  44. package/lib/util/RelayFeatureFlags.js +6 -2
  45. package/lib/util/RelayReplaySubject.js +4 -4
  46. package/lib/util/handlePotentialSnapshotErrors.js +2 -2
  47. package/lib/util/stableCopy.js +2 -2
  48. package/llm-docs/api-reference/entrypoint-apis/entrypoint-container.mdx +38 -0
  49. package/llm-docs/api-reference/entrypoint-apis/load-entrypoint.mdx +77 -0
  50. package/llm-docs/api-reference/entrypoint-apis/use-entrypoint-loader.mdx +99 -0
  51. package/llm-docs/api-reference/graphql/graphql-directives.mdx +378 -0
  52. package/llm-docs/api-reference/hooks/_use-lazy-load-query-extra.mdx +16 -0
  53. package/llm-docs/api-reference/hooks/load-query.mdx +84 -0
  54. package/llm-docs/api-reference/hooks/relay-environment-provider.mdx +78 -0
  55. package/llm-docs/api-reference/hooks/use-client-query.mdx +65 -0
  56. package/llm-docs/api-reference/hooks/use-fragment.mdx +69 -0
  57. package/llm-docs/api-reference/hooks/use-lazy-load-query.mdx +62 -0
  58. package/llm-docs/api-reference/hooks/use-mutation.mdx +94 -0
  59. package/llm-docs/api-reference/hooks/use-pagination-fragment.mdx +166 -0
  60. package/llm-docs/api-reference/hooks/use-prefetchable-forward-pagination-fragment.mdx +134 -0
  61. package/llm-docs/api-reference/hooks/use-preloaded-query.mdx +84 -0
  62. package/llm-docs/api-reference/hooks/use-query-loader.mdx +95 -0
  63. package/llm-docs/api-reference/hooks/use-refetchable-fragment.mdx +122 -0
  64. package/llm-docs/api-reference/hooks/use-relay-environment.mdx +37 -0
  65. package/llm-docs/api-reference/hooks/use-subscription.mdx +66 -0
  66. package/llm-docs/api-reference/relay-resolvers/docblock-format.mdx +321 -0
  67. package/llm-docs/api-reference/relay-resolvers/runtime-functions.mdx +94 -0
  68. package/llm-docs/api-reference/relay-runtime/commit-mutation.mdx +65 -0
  69. package/llm-docs/api-reference/relay-runtime/fetch-query.mdx +118 -0
  70. package/llm-docs/api-reference/relay-runtime/field-logger.mdx +170 -0
  71. package/llm-docs/api-reference/relay-runtime/observe-fragment.mdx +92 -0
  72. package/llm-docs/api-reference/relay-runtime/relay-environment.mdx +53 -0
  73. package/llm-docs/api-reference/relay-runtime/request-subscription.mdx +54 -0
  74. package/llm-docs/api-reference/relay-runtime/runtime-configuration.mdx +52 -0
  75. package/llm-docs/api-reference/relay-runtime/store.mdx +734 -0
  76. package/llm-docs/api-reference/relay-runtime/wait-for-fragment-data.mdx +89 -0
  77. package/llm-docs/api-reference/types/CacheConfig.mdx +8 -0
  78. package/llm-docs/api-reference/types/Disposable.mdx +4 -0
  79. package/llm-docs/api-reference/types/GraphQLSubscriptionConfig.mdx +17 -0
  80. package/llm-docs/api-reference/types/MutationConfig.mdx +31 -0
  81. package/llm-docs/api-reference/types/SelectorStoreUpdater.mdx +6 -0
  82. package/llm-docs/api-reference/types/UploadableMap.mdx +3 -0
  83. package/llm-docs/community/learning-resources.mdx +64 -0
  84. package/llm-docs/debugging/declarative-mutation-directives.mdx +34 -0
  85. package/llm-docs/debugging/disallowed-id-types-error.mdx +43 -0
  86. package/llm-docs/debugging/inconsistent-typename-error.mdx +47 -0
  87. package/llm-docs/debugging/relay-devtools.mdx +73 -0
  88. package/llm-docs/debugging/why-null.mdx +116 -0
  89. package/llm-docs/editor-support.mdx +55 -0
  90. package/llm-docs/error-reference/unknown-field.mdx +36 -0
  91. package/llm-docs/getting-started/babel-plugin.mdx +31 -0
  92. package/llm-docs/getting-started/compiler-config.mdx +25 -0
  93. package/llm-docs/getting-started/compiler.mdx +98 -0
  94. package/llm-docs/getting-started/lint-rules.mdx +87 -0
  95. package/llm-docs/getting-started/production.mdx +30 -0
  96. package/llm-docs/getting-started/quick-start.mdx +216 -0
  97. package/llm-docs/glossary/glossary.mdx +1040 -0
  98. package/llm-docs/guided-tour/list-data/advanced-pagination.mdx +157 -0
  99. package/llm-docs/guided-tour/list-data/connections.mdx +81 -0
  100. package/llm-docs/guided-tour/list-data/pagination.mdx +193 -0
  101. package/llm-docs/guided-tour/list-data/rendering-connections.mdx +112 -0
  102. package/llm-docs/guided-tour/list-data/streaming-pagination.mdx +87 -0
  103. package/llm-docs/guided-tour/managing-data-outside-react/retaining-queries.mdx +51 -0
  104. package/llm-docs/guided-tour/refetching/refetching-queries-with-different-data.mdx +337 -0
  105. package/llm-docs/guided-tour/refetching/refreshing-queries.mdx +350 -0
  106. package/llm-docs/guided-tour/rendering/environment.mdx +59 -0
  107. package/llm-docs/guided-tour/rendering/error-states.mdx +295 -0
  108. package/llm-docs/guided-tour/rendering/fragments.mdx +354 -0
  109. package/llm-docs/guided-tour/rendering/loading-states.mdx +245 -0
  110. package/llm-docs/guided-tour/rendering/queries.mdx +261 -0
  111. package/llm-docs/guided-tour/rendering/variables.mdx +233 -0
  112. package/llm-docs/guided-tour/reusing-cached-data/fetch-policies.mdx +56 -0
  113. package/llm-docs/guided-tour/reusing-cached-data/filling-in-missing-data.mdx +102 -0
  114. package/llm-docs/guided-tour/reusing-cached-data/introduction.mdx +22 -0
  115. package/llm-docs/guided-tour/reusing-cached-data/presence-of-data.mdx +93 -0
  116. package/llm-docs/guided-tour/reusing-cached-data/rendering-partially-cached-data.mdx +175 -0
  117. package/llm-docs/guided-tour/reusing-cached-data/staleness-of-data.mdx +116 -0
  118. package/llm-docs/guided-tour/updating-data/client-only-data.mdx +115 -0
  119. package/llm-docs/guided-tour/updating-data/graphql-mutations.mdx +334 -0
  120. package/llm-docs/guided-tour/updating-data/graphql-subscriptions.mdx +279 -0
  121. package/llm-docs/guided-tour/updating-data/imperatively-modifying-linked-fields.mdx +511 -0
  122. package/llm-docs/guided-tour/updating-data/imperatively-modifying-store-data-legacy.mdx +142 -0
  123. package/llm-docs/guided-tour/updating-data/imperatively-modifying-store-data.mdx +275 -0
  124. package/llm-docs/guided-tour/updating-data/introduction.mdx +25 -0
  125. package/llm-docs/guided-tour/updating-data/local-data-updates.mdx +71 -0
  126. package/llm-docs/guided-tour/updating-data/typesafe-updaters-faq.mdx +83 -0
  127. package/llm-docs/guided-tour/updating-data/updating-connections.mdx +592 -0
  128. package/llm-docs/guides/alias-directive.mdx +160 -0
  129. package/llm-docs/guides/catch-directive.mdx +167 -0
  130. package/llm-docs/guides/client-schema-extensions.mdx +208 -0
  131. package/llm-docs/guides/codemods.mdx +79 -0
  132. package/llm-docs/guides/data-driven-dependencies/client-3d.mdx +255 -0
  133. package/llm-docs/guides/data-driven-dependencies/configuration.mdx +127 -0
  134. package/llm-docs/guides/data-driven-dependencies/introduction.mdx +39 -0
  135. package/llm-docs/guides/data-driven-dependencies/server-3d.mdx +664 -0
  136. package/llm-docs/guides/document-comparison.mdx +106 -0
  137. package/llm-docs/guides/graphql-server-specification.mdx +453 -0
  138. package/llm-docs/guides/network-layer.mdx +69 -0
  139. package/llm-docs/guides/persisted-queries.mdx +328 -0
  140. package/llm-docs/guides/relay-resolvers/context.mdx +99 -0
  141. package/llm-docs/guides/relay-resolvers/defining-fields.mdx +151 -0
  142. package/llm-docs/guides/relay-resolvers/defining-types.mdx +164 -0
  143. package/llm-docs/guides/relay-resolvers/deprecated.mdx +27 -0
  144. package/llm-docs/guides/relay-resolvers/derived-fields.mdx +127 -0
  145. package/llm-docs/guides/relay-resolvers/descriptions.mdx +44 -0
  146. package/llm-docs/guides/relay-resolvers/enabling.mdx +41 -0
  147. package/llm-docs/guides/relay-resolvers/errors.mdx +64 -0
  148. package/llm-docs/guides/relay-resolvers/field-arguments.mdx +63 -0
  149. package/llm-docs/guides/relay-resolvers/introduction.mdx +62 -0
  150. package/llm-docs/guides/relay-resolvers/limitations.mdx +30 -0
  151. package/llm-docs/guides/relay-resolvers/live-fields.mdx +164 -0
  152. package/llm-docs/guides/relay-resolvers/return-types.mdx +161 -0
  153. package/llm-docs/guides/relay-resolvers/suspense.mdx +41 -0
  154. package/llm-docs/guides/required-directive.mdx +240 -0
  155. package/llm-docs/guides/semantic-nullability.mdx +93 -0
  156. package/llm-docs/guides/testing-relay-components.mdx +642 -0
  157. package/llm-docs/guides/testing-relay-with-preloaded-queries.mdx +160 -0
  158. package/llm-docs/guides/throw-on-field-error-directive.mdx +58 -0
  159. package/llm-docs/guides/type-emission.mdx +414 -0
  160. package/llm-docs/home.mdx +32 -0
  161. package/llm-docs/principles-and-architecture/architecture-overview.mdx +24 -0
  162. package/llm-docs/principles-and-architecture/compiler-architecture.mdx +106 -0
  163. package/llm-docs/principles-and-architecture/runtime-architecture.mdx +249 -0
  164. package/llm-docs/principles-and-architecture/thinking-in-graphql.mdx +309 -0
  165. package/llm-docs/principles-and-architecture/thinking-in-relay.mdx +104 -0
  166. package/llm-docs/principles-and-architecture/videos.mdx +50 -0
  167. package/llm-docs/tutorial/arrays-lists.mdx +126 -0
  168. package/llm-docs/tutorial/fragments-1.mdx +487 -0
  169. package/llm-docs/tutorial/graphql.mdx +172 -0
  170. package/llm-docs/tutorial/interfaces-polymorphism.mdx +161 -0
  171. package/llm-docs/tutorial/intro.mdx +58 -0
  172. package/llm-docs/tutorial/mutations-updates.mdx +624 -0
  173. package/llm-docs/tutorial/organizing-mutations-queries-and-subscriptions.mdx +13 -0
  174. package/llm-docs/tutorial/queries-1.mdx +267 -0
  175. package/llm-docs/tutorial/queries-2.mdx +389 -0
  176. package/llm-docs/tutorial/refetchable-fragments.mdx +352 -0
  177. package/multi-actor-environment/ActorIdentifier.d.ts +17 -0
  178. package/multi-actor-environment/ActorIdentifier.js.flow +2 -2
  179. package/multi-actor-environment/ActorSpecificEnvironment.js.flow +15 -15
  180. package/multi-actor-environment/ActorUtils.js.flow +1 -1
  181. package/multi-actor-environment/MultiActorEnvironment.d.ts +123 -0
  182. package/multi-actor-environment/MultiActorEnvironment.js.flow +32 -24
  183. package/multi-actor-environment/MultiActorEnvironmentTypes.d.ts +225 -0
  184. package/multi-actor-environment/MultiActorEnvironmentTypes.js.flow +6 -6
  185. package/multi-actor-environment/index.d.ts +14 -0
  186. package/multi-actor-environment.d.ts +8 -0
  187. package/mutations/RelayDeclarativeMutationConfig.d.ts +70 -0
  188. package/mutations/RelayDeclarativeMutationConfig.js.flow +9 -9
  189. package/mutations/RelayRecordProxy.js.flow +8 -11
  190. package/mutations/RelayRecordSourceMutator.js.flow +4 -4
  191. package/mutations/RelayRecordSourceProxy.js.flow +4 -4
  192. package/mutations/RelayRecordSourceSelectorProxy.js.flow +6 -6
  193. package/mutations/applyOptimisticMutation.d.ts +25 -0
  194. package/mutations/applyOptimisticMutation.js.flow +2 -2
  195. package/mutations/commitLocalUpdate.d.ts +10 -0
  196. package/mutations/commitMutation.d.ts +48 -0
  197. package/mutations/commitMutation.js.flow +21 -17
  198. package/mutations/createUpdatableProxy.js.flow +19 -19
  199. package/mutations/readUpdatableFragment.js.flow +3 -3
  200. package/mutations/readUpdatableQuery.js.flow +3 -3
  201. package/mutations/validateMutation.js.flow +7 -7
  202. package/network/RelayNetwork.d.ts +12 -0
  203. package/network/RelayNetworkTypes.d.ts +145 -0
  204. package/network/RelayNetworkTypes.js.flow +18 -18
  205. package/network/RelayObservable.d.ts +197 -0
  206. package/network/RelayObservable.js.flow +32 -30
  207. package/network/RelayQueryResponseCache.d.ts +16 -0
  208. package/network/RelayQueryResponseCache.js.flow +3 -3
  209. package/network/wrapNetworkWithLogObserver.js.flow +1 -1
  210. package/package.json +2 -1
  211. package/query/GraphQLTag.d.ts +45 -0
  212. package/query/GraphQLTag.js.flow +22 -10
  213. package/query/fetchQuery.d.ts +21 -0
  214. package/query/fetchQuery.js.flow +23 -10
  215. package/query/fetchQueryInternal.d.ts +26 -0
  216. package/query/fetchQueryInternal.js.flow +4 -4
  217. package/query/fetchQuery_DEPRECATED.d.ts +17 -0
  218. package/query/fetchQuery_DEPRECATED.js.flow +1 -1
  219. package/store/ClientID.d.ts +14 -0
  220. package/store/DataChecker.js.flow +51 -15
  221. package/store/NormalizationEngine.js.flow +782 -0
  222. package/store/OperationExecutor.d.ts +51 -0
  223. package/store/OperationExecutor.js.flow +204 -98
  224. package/store/RelayConcreteVariables.js.flow +5 -5
  225. package/store/RelayErrorTrie.js.flow +12 -12
  226. package/store/RelayExperimentalGraphResponseHandler.js.flow +3 -3
  227. package/store/RelayExperimentalGraphResponseTransform.js.flow +10 -10
  228. package/store/RelayModernEnvironment.d.ts +97 -0
  229. package/store/RelayModernEnvironment.js.flow +58 -43
  230. package/store/RelayModernFragmentSpecResolver.js.flow +1 -1
  231. package/store/RelayModernOperationDescriptor.d.ts +28 -0
  232. package/store/RelayModernOperationDescriptor.js.flow +1 -1
  233. package/store/RelayModernRecord.d.ts +92 -0
  234. package/store/RelayModernRecord.js.flow +44 -20
  235. package/store/RelayModernSelector.d.ts +123 -0
  236. package/store/RelayModernSelector.js.flow +21 -21
  237. package/store/RelayModernStore.d.ts +57 -0
  238. package/store/RelayModernStore.js.flow +219 -58
  239. package/store/RelayOperationTracker.d.ts +29 -0
  240. package/store/RelayOperationTracker.js.flow +2 -2
  241. package/store/RelayOptimisticRecordSource.js.flow +2 -2
  242. package/store/RelayPublishQueue.js.flow +29 -20
  243. package/store/RelayReader.js.flow +129 -57
  244. package/store/RelayRecordSource.d.ts +26 -0
  245. package/store/RelayRecordSource.js.flow +10 -0
  246. package/store/RelayRecordState.d.ts +28 -0
  247. package/store/RelayRecordState.js.flow +1 -1
  248. package/store/RelayReferenceMarker.js.flow +5 -4
  249. package/store/RelayResponseNormalizer.d.ts +28 -0
  250. package/store/RelayResponseNormalizer.js.flow +130 -62
  251. package/store/RelayStoreSubscriptions.js.flow +52 -8
  252. package/store/RelayStoreTypes.d.ts +1327 -0
  253. package/store/RelayStoreTypes.js.flow +371 -278
  254. package/store/RelayStoreUtils.d.ts +86 -0
  255. package/store/RelayStoreUtils.js.flow +16 -8
  256. package/store/ResolverCache.js.flow +2 -2
  257. package/store/ResolverFragments.d.ts +43 -0
  258. package/store/ResolverFragments.js.flow +22 -14
  259. package/store/StoreInspector.js.flow +7 -8
  260. package/store/ViewerPattern.d.ts +11 -0
  261. package/store/cloneRelayHandleSourceField.js.flow +1 -1
  262. package/store/cloneRelayScalarHandleSourceField.js.flow +1 -1
  263. package/store/createFragmentSpecResolver.d.ts +16 -0
  264. package/store/createRelayContext.js.flow +1 -1
  265. package/store/createRelayLoggingContext.js.flow +4 -4
  266. package/store/defaultGetDataID.js.flow +2 -2
  267. package/store/isRelayModernEnvironment.d.ts +8 -0
  268. package/store/isRelayModernEnvironment.js.flow +4 -2
  269. package/store/live-resolvers/LiveResolverCache.js.flow +55 -20
  270. package/store/live-resolvers/LiveResolverSuspenseSentinel.js.flow +3 -3
  271. package/store/live-resolvers/getOutputTypeRecordIDs.js.flow +1 -1
  272. package/store/live-resolvers/isLiveStateValue.js.flow +2 -2
  273. package/store/live-resolvers/resolverDataInjector.d.ts +27 -0
  274. package/store/live-resolvers/resolverDataInjector.js.flow +8 -5
  275. package/store/observeFragmentExperimental.d.ts +46 -0
  276. package/store/observeFragmentExperimental.js.flow +50 -21
  277. package/store/observeQueryExperimental.d.ts +30 -0
  278. package/store/observeQueryExperimental.js.flow +5 -5
  279. package/store/readInlineData.d.ts +19 -0
  280. package/store/readInlineData.js.flow +5 -5
  281. package/store/waitForFragmentExperimental.d.ts +49 -0
  282. package/store/waitForFragmentExperimental.js.flow +3 -3
  283. package/subscription/requestSubscription.d.ts +27 -0
  284. package/subscription/requestSubscription.js.flow +10 -10
  285. package/util/JSResourceTypes.flow.js.flow +4 -4
  286. package/util/NormalizationNode.d.ts +235 -0
  287. package/util/NormalizationNode.js.flow +127 -123
  288. package/util/ReaderNode.d.ts +264 -0
  289. package/util/ReaderNode.js.flow +156 -151
  290. package/util/RelayConcreteNode.d.ts +120 -0
  291. package/util/RelayConcreteNode.js.flow +32 -32
  292. package/util/RelayError.d.ts +13 -0
  293. package/util/RelayError.js.flow +4 -1
  294. package/util/RelayFeatureFlags.d.ts +40 -0
  295. package/util/RelayFeatureFlags.js.flow +21 -1
  296. package/util/RelayProfiler.d.ts +121 -0
  297. package/util/RelayProfiler.js.flow +1 -1
  298. package/util/RelayReplaySubject.d.ts +25 -0
  299. package/util/RelayReplaySubject.js.flow +3 -3
  300. package/util/RelayRuntimeTypes.d.ts +59 -0
  301. package/util/RelayRuntimeTypes.js.flow +36 -33
  302. package/util/createPayloadFor3DField.d.ts +17 -0
  303. package/util/createPayloadFor3DField.js.flow +9 -5
  304. package/util/deepFreeze.d.ts +8 -0
  305. package/util/deepFreeze.js.flow +2 -2
  306. package/util/getFragmentIdentifier.d.ts +10 -0
  307. package/util/getFragmentIdentifier.js.flow +1 -1
  308. package/util/getPaginationMetadata.d.ts +20 -0
  309. package/util/getPaginationMetadata.js.flow +1 -1
  310. package/util/getPaginationVariables.d.ts +20 -0
  311. package/util/getPaginationVariables.js.flow +1 -1
  312. package/util/getPendingOperationsForFragment.d.ts +18 -0
  313. package/util/getPendingOperationsForFragment.js.flow +2 -2
  314. package/util/getRefetchMetadata.d.ts +19 -0
  315. package/util/getRefetchMetadata.js.flow +6 -5
  316. package/util/getRelayHandleKey.d.ts +8 -0
  317. package/util/getRequestIdentifier.d.ts +17 -0
  318. package/util/getValueAtPath.d.ts +8 -0
  319. package/util/getValueAtPath.js.flow +3 -3
  320. package/util/handlePotentialSnapshotErrors.d.ts +14 -0
  321. package/util/handlePotentialSnapshotErrors.js.flow +5 -5
  322. package/util/isEmptyObject.js.flow +1 -1
  323. package/util/isPromise.d.ts +8 -0
  324. package/util/isPromise.js.flow +2 -2
  325. package/util/isScalarAndEqual.d.ts +8 -0
  326. package/util/isScalarAndEqual.js.flow +1 -1
  327. package/util/recycleNodesInto.d.ts +8 -0
  328. package/util/recycleNodesInto.js.flow +2 -2
  329. package/util/registerEnvironmentWithDevTools.js.flow +1 -1
  330. package/util/shallowFreeze.js.flow +1 -1
  331. package/util/stableCopy.d.ts +8 -0
  332. package/util/stableCopy.js.flow +5 -5
  333. package/util/withProvidedVariables.d.ts +19 -0
  334. package/util/withProvidedVariables.js.flow +14 -10
@@ -40,6 +40,7 @@ const {
40
40
  assertInternalActorIdentifier,
41
41
  } = require('../multi-actor-environment/ActorIdentifier');
42
42
  const deepFreeze = require('../util/deepFreeze');
43
+ const RelayFeatureFlags = require('../util/RelayFeatureFlags');
43
44
  const resolveImmediate = require('../util/resolveImmediate');
44
45
  const DataChecker = require('./DataChecker');
45
46
  const defaultGetDataID = require('./defaultGetDataID');
@@ -54,11 +55,16 @@ const RelayReader = require('./RelayReader');
54
55
  const RelayReferenceMarker = require('./RelayReferenceMarker');
55
56
  const RelayStoreSubscriptions = require('./RelayStoreSubscriptions');
56
57
  const RelayStoreUtils = require('./RelayStoreUtils');
57
- const {ROOT_ID, ROOT_TYPE} = require('./RelayStoreUtils');
58
+ const {
59
+ FIELD_GRANULAR_NOTIFICATIONS_KEY,
60
+ ROOT_ID,
61
+ ROOT_TYPE,
62
+ getFieldNotificationKey,
63
+ } = require('./RelayStoreUtils');
58
64
  const invariant = require('invariant');
59
65
 
60
66
  export opaque type InvalidationState = {
61
- dataIDs: $ReadOnlyArray<DataID>,
67
+ dataIDs: ReadonlyArray<DataID>,
62
68
  invalidations: Map<DataID, ?number>,
63
69
  };
64
70
 
@@ -67,6 +73,11 @@ type InvalidationSubscription = {
67
73
  invalidationState: InvalidationState,
68
74
  };
69
75
 
76
+ type Batch = {
77
+ sourceOperations: Array<OperationDescriptor>,
78
+ invalidateStore: boolean,
79
+ };
80
+
70
81
  const DEFAULT_RELEASE_BUFFER_SIZE = 10;
71
82
 
72
83
  /**
@@ -115,6 +126,8 @@ class RelayModernStore implements Store {
115
126
  _resolverContext: ?ResolverContext;
116
127
  _actorIdentifier: ?ActorIdentifier;
117
128
  _treatMissingFieldsAsNull: boolean;
129
+ _deferDeduplicatedFields: boolean;
130
+ _batch: Batch | null;
118
131
 
119
132
  constructor(
120
133
  source: MutableRecordSource,
@@ -134,6 +147,7 @@ class RelayModernStore implements Store {
134
147
  // These additional config options are only used if the experimental
135
148
  // @outputType resolver feature is used
136
149
  treatMissingFieldsAsNull?: ?boolean,
150
+ deferDeduplicatedFields?: ?boolean,
137
151
  actorIdentifier?: ?ActorIdentifier,
138
152
  },
139
153
  ) {
@@ -182,7 +196,9 @@ class RelayModernStore implements Store {
182
196
  options?.shouldProcessClientComponents ?? false;
183
197
 
184
198
  this._treatMissingFieldsAsNull = options?.treatMissingFieldsAsNull ?? false;
199
+ this._deferDeduplicatedFields = options?.deferDeduplicatedFields ?? false;
185
200
  this._actorIdentifier = options?.actorIdentifier;
201
+ this._batch = null;
186
202
 
187
203
  initializeRecordSource(this._recordSource);
188
204
  }
@@ -235,6 +251,60 @@ class RelayModernStore implements Store {
235
251
  }
236
252
  }
237
253
 
254
+ /**
255
+ * Batch multiple store updates into a single notification pass.
256
+ *
257
+ * Fragments will still correctly Suspend on their own parent query during
258
+ * a batch. However, cross-operation Suspense (a fragment suspending on a
259
+ * *different* in-flight operation) may not work correctly for operations
260
+ * that complete during the batch.
261
+ */
262
+ experimental_batchUpdates(callback: () => void): void {
263
+ if (this._batch != null) {
264
+ throw new Error(
265
+ 'RelayModernStore: Cannot batch updates while already batching updates.',
266
+ );
267
+ }
268
+ const log = this.__log;
269
+ if (log != null) {
270
+ log({name: 'store.batch.start'});
271
+ }
272
+ const batch: Batch = {sourceOperations: [], invalidateStore: false};
273
+ this._batch = batch;
274
+ try {
275
+ callback();
276
+ } finally {
277
+ this._batch = null;
278
+ this.notify(undefined, batch.invalidateStore);
279
+ for (const sourceOperation of batch.sourceOperations) {
280
+ this._recordSourceOperation(sourceOperation);
281
+ }
282
+ if (log != null) {
283
+ log({
284
+ name: 'store.batch.complete',
285
+ sourceOperations: batch.sourceOperations,
286
+ invalidateStore: batch.invalidateStore,
287
+ });
288
+ }
289
+ }
290
+ }
291
+
292
+ batchLiveStateUpdatesWithoutNotify(callback: () => void): boolean {
293
+ if (this.__log != null) {
294
+ this.__log({name: 'liveresolver.batch.start'});
295
+ }
296
+ let hasPublished = false;
297
+ try {
298
+ hasPublished =
299
+ this._resolverCache.batchLiveStateUpdatesWithoutNotify(callback);
300
+ } finally {
301
+ if (this.__log != null) {
302
+ this.__log({name: 'liveresolver.batch.end'});
303
+ }
304
+ }
305
+ return hasPublished;
306
+ }
307
+
238
308
  check(
239
309
  operation: OperationDescriptor,
240
310
  options?: CheckOptions,
@@ -341,7 +411,7 @@ class RelayModernStore implements Store {
341
411
  if (this._releaseBuffer.length > this._gcReleaseBufferSize) {
342
412
  const _id = this._releaseBuffer.shift();
343
413
  if (!this._shouldRetainWithinTTL_EXPERIMENTAL) {
344
- // $FlowFixMe[incompatible-call]
414
+ // $FlowFixMe[incompatible-type]
345
415
  this._roots.delete(_id);
346
416
  }
347
417
  this.scheduleGC();
@@ -385,6 +455,7 @@ class RelayModernStore implements Store {
385
455
  const snapshot = RelayReader.read(
386
456
  source,
387
457
  selector,
458
+ log,
388
459
  this._resolverCache,
389
460
  this._resolverContext,
390
461
  );
@@ -404,7 +475,22 @@ class RelayModernStore implements Store {
404
475
  notify(
405
476
  sourceOperation?: OperationDescriptor,
406
477
  invalidateStore?: boolean,
407
- ): $ReadOnlyArray<RequestDescriptor> {
478
+ ): ReadonlyArray<RequestDescriptor> {
479
+ // If we're inside a batchUpdates() call, defer notification.
480
+ const batch = this._batch;
481
+ if (batch != null) {
482
+ if (sourceOperation != null) {
483
+ batch.sourceOperations.push(sourceOperation);
484
+ }
485
+ if (invalidateStore === true) {
486
+ batch.invalidateStore = true;
487
+ }
488
+ // Returning [] here means the OperationExecutor's _updateOperationTracker
489
+ // will be a no-op for this call, since it relies on notify() returning
490
+ // the list of affected owners. See the experimental_batchUpdates JSDoc.
491
+ return [];
492
+ }
493
+
408
494
  const log = this.__log;
409
495
  if (log != null) {
410
496
  log({
@@ -413,69 +499,78 @@ class RelayModernStore implements Store {
413
499
  });
414
500
  }
415
501
 
416
- // Increment the current write when notifying after executing
417
- // a set of changes to the store.
418
- this._currentWriteEpoch++;
502
+ if (!RelayFeatureFlags.OPTIMIZE_NOTIFY) {
503
+ // Increment the current write when notifying after executing
504
+ // a set of changes to the store.
505
+ this._currentWriteEpoch++;
419
506
 
420
- if (invalidateStore === true) {
421
- this._globalInvalidationEpoch = this._currentWriteEpoch;
507
+ if (invalidateStore === true) {
508
+ this._globalInvalidationEpoch = this._currentWriteEpoch;
509
+ }
422
510
  }
423
511
 
424
512
  // When a record is updated, we need to also handle records that depend on it,
425
513
  // specifically Relay Resolver result records containing results based on the
426
514
  // updated records. This both adds to updatedRecordIDs and invalidates any
427
515
  // cached data as needed.
428
- this._resolverCache.invalidateDataIDs(this._updatedRecordIDs);
516
+ if (!RelayFeatureFlags.OPTIMIZE_NOTIFY || this._updatedRecordIDs.size > 0) {
517
+ this._resolverCache.invalidateDataIDs(this._updatedRecordIDs);
518
+ }
429
519
 
430
520
  const source = this.getSource();
431
521
  const updatedOwners: Array<RequestDescriptor> = [];
432
- this._storeSubscriptions.updateSubscriptions(
433
- source,
434
- this._updatedRecordIDs,
435
- updatedOwners,
436
- sourceOperation,
437
- );
438
- this._invalidationSubscriptions.forEach(subscription => {
439
- this._updateInvalidationSubscription(
440
- subscription,
441
- invalidateStore === true,
522
+ if (!RelayFeatureFlags.OPTIMIZE_NOTIFY || this._updatedRecordIDs.size > 0) {
523
+ this._storeSubscriptions.updateSubscriptions(
524
+ source,
525
+ this._updatedRecordIDs,
526
+ updatedOwners,
527
+ sourceOperation,
442
528
  );
443
- });
529
+ } else {
530
+ // If no record is updated, we still need to traverse stale subscriptions for
531
+ // subscriptions that were using values from optimistic updates
532
+ this._storeSubscriptions.updateStaleSubscriptions(
533
+ source,
534
+ this._updatedRecordIDs,
535
+ updatedOwners,
536
+ sourceOperation,
537
+ );
538
+ }
444
539
 
445
- // If a source operation was provided (indicating the operation
446
- // that produced this update to the store), record the current epoch
447
- // at which this operation was written.
448
- if (sourceOperation != null) {
449
- // We only track the epoch at which the operation was written if
450
- // it was previously retained, to keep the size of our operation
451
- // epoch map bounded. If a query wasn't retained, we assume it can
452
- // may be deleted at any moment and thus is not relevant for us to track
453
- // for the purposes of invalidation.
454
- const id = sourceOperation.request.identifier;
455
- const rootEntry = this._roots.get(id);
456
- if (rootEntry != null) {
457
- rootEntry.epoch = this._currentWriteEpoch;
458
- rootEntry.fetchTime = Date.now();
459
- } else if (
460
- sourceOperation.request.node.params.operationKind === 'query' &&
461
- this._gcReleaseBufferSize > 0 &&
462
- this._releaseBuffer.length < this._gcReleaseBufferSize
463
- ) {
464
- // The operation isn't retained but there is space in the release buffer:
465
- // temporarily track this operation in case the data can be reused soon.
466
- const temporaryRootEntry = {
467
- operation: sourceOperation,
468
- refCount: 0,
469
- epoch: this._currentWriteEpoch,
470
- fetchTime: Date.now(),
471
- };
472
- this._releaseBuffer.push(id);
473
- /* $FlowFixMe[incompatible-call] Natural Inference rollout. See
474
- * https://fburl.com/gdoc/y8dn025u */
475
- this._roots.set(id, temporaryRootEntry);
540
+ if (
541
+ RelayFeatureFlags.OPTIMIZE_NOTIFY &&
542
+ (this._updatedRecordIDs.size > 0 ||
543
+ updatedOwners.length > 0 ||
544
+ this._invalidatedRecordIDs.size > 0 ||
545
+ invalidateStore === true ||
546
+ this._globalInvalidationEpoch === this._currentWriteEpoch)
547
+ ) {
548
+ // Increment the current write when notifying after executing
549
+ // a set of changes to the store.
550
+ this._currentWriteEpoch++;
551
+
552
+ if (invalidateStore === true) {
553
+ this._globalInvalidationEpoch = this._currentWriteEpoch;
476
554
  }
477
555
  }
478
556
 
557
+ if (
558
+ !RelayFeatureFlags.OPTIMIZE_NOTIFY ||
559
+ this._invalidatedRecordIDs.size > 0 ||
560
+ invalidateStore === true
561
+ ) {
562
+ this._invalidationSubscriptions.forEach(subscription => {
563
+ this._updateInvalidationSubscription(
564
+ subscription,
565
+ invalidateStore === true,
566
+ );
567
+ });
568
+ }
569
+
570
+ if (sourceOperation != null) {
571
+ this._recordSourceOperation(sourceOperation);
572
+ }
573
+
479
574
  if (log != null) {
480
575
  log({
481
576
  name: 'store.notify.complete',
@@ -493,6 +588,40 @@ class RelayModernStore implements Store {
493
588
  return updatedOwners;
494
589
  }
495
590
 
591
+ /**
592
+ * Record that a source operation was written at the current epoch.
593
+ * We only track the epoch at which the operation was written if
594
+ * it was previously retained, to keep the size of our operation
595
+ * epoch map bounded. If a query wasn't retained, we assume it can
596
+ * be deleted at any moment and thus is not relevant for us to track
597
+ * for the purposes of invalidation.
598
+ */
599
+ _recordSourceOperation(sourceOperation: OperationDescriptor): void {
600
+ const id = sourceOperation.request.identifier;
601
+ const rootEntry = this._roots.get(id);
602
+ if (rootEntry != null) {
603
+ rootEntry.epoch = this._currentWriteEpoch;
604
+ rootEntry.fetchTime = Date.now();
605
+ } else if (
606
+ sourceOperation.request.node.params.operationKind === 'query' &&
607
+ this._gcReleaseBufferSize > 0 &&
608
+ this._releaseBuffer.length < this._gcReleaseBufferSize
609
+ ) {
610
+ // The operation isn't retained but there is space in the release buffer:
611
+ // temporarily track this operation in case the data can be reused soon.
612
+ const temporaryRootEntry = {
613
+ operation: sourceOperation,
614
+ refCount: 0,
615
+ epoch: this._currentWriteEpoch,
616
+ fetchTime: Date.now(),
617
+ };
618
+ this._releaseBuffer.push(id);
619
+ /* $FlowFixMe[incompatible-type] Natural Inference rollout. See
620
+ * https://fburl.com/gdoc/y8dn025u */
621
+ this._roots.set(id, temporaryRootEntry);
622
+ }
623
+ }
624
+
496
625
  publish(source: RecordSource, idsMarkedForInvalidation?: DataIDSet): void {
497
626
  const target = this._getMutableRecordSource();
498
627
  updateTargetFromSource(
@@ -543,7 +672,7 @@ class RelayModernStore implements Store {
543
672
  return {dispose};
544
673
  }
545
674
 
546
- toJSON(): mixed {
675
+ toJSON(): unknown {
547
676
  return 'RelayModernStore()';
548
677
  }
549
678
 
@@ -556,7 +685,7 @@ class RelayModernStore implements Store {
556
685
  return this._updatedRecordIDs;
557
686
  }
558
687
 
559
- lookupInvalidationState(dataIDs: $ReadOnlyArray<DataID>): InvalidationState {
688
+ lookupInvalidationState(dataIDs: ReadonlyArray<DataID>): InvalidationState {
560
689
  const invalidations = new Map<DataID, ?number>();
561
690
  dataIDs.forEach(dataID => {
562
691
  const record = this.getSource().get(dataID);
@@ -795,7 +924,7 @@ class RelayModernStore implements Store {
795
924
  RELAY_RESOLVER_LIVE_STATE_SUBSCRIPTION_KEY,
796
925
  );
797
926
  if (maybeResolverSubscription != null) {
798
- // $FlowFixMe - this value if it is not null, it is a function
927
+ // $FlowFixMe[not-a-function] - this value if it is not null, it is a function
799
928
  maybeResolverSubscription();
800
929
  }
801
930
  }
@@ -819,14 +948,13 @@ class RelayModernStore implements Store {
819
948
  }
820
949
 
821
950
  // Internal API for normalizing @outputType payloads in LiveResolverCache.
822
- __getNormalizationOptions(
823
- path: $ReadOnlyArray<string>,
824
- ): NormalizationOptions {
951
+ __getNormalizationOptions(path: ReadonlyArray<string>): NormalizationOptions {
825
952
  return {
826
953
  path,
827
954
  getDataID: this._getDataID,
828
955
  log: this.__log,
829
956
  treatMissingFieldsAsNull: this._treatMissingFieldsAsNull,
957
+ deferDeduplicatedFields: this._deferDeduplicatedFields,
830
958
  shouldProcessClientComponents: this._shouldProcessClientComponents,
831
959
  actorIdentifier: this._actorIdentifier,
832
960
  };
@@ -846,6 +974,13 @@ class RelayModernStore implements Store {
846
974
  function initializeRecordSource(target: MutableRecordSource) {
847
975
  if (!target.has(ROOT_ID)) {
848
976
  const rootRecord = RelayModernRecord.create(ROOT_ID, ROOT_TYPE);
977
+ if (RelayFeatureFlags.ENABLE_FIELD_GRANULAR_NOTIFICATIONS) {
978
+ RelayModernRecord.setValue(
979
+ rootRecord,
980
+ FIELD_GRANULAR_NOTIFICATIONS_KEY,
981
+ true,
982
+ );
983
+ }
849
984
  target.set(ROOT_ID, rootRecord);
850
985
  }
851
986
  }
@@ -930,6 +1065,32 @@ function updateTargetFromSource(
930
1065
  }
931
1066
  updatedRecordIDs.add(dataID);
932
1067
  target.set(dataID, nextRecord);
1068
+
1069
+ // Add per-field notification keys for field-granular records
1070
+ if (
1071
+ RelayModernRecord.getValue(
1072
+ nextRecord,
1073
+ FIELD_GRANULAR_NOTIFICATIONS_KEY,
1074
+ )
1075
+ ) {
1076
+ const fields = RelayModernRecord.getFields(nextRecord);
1077
+ for (let jj = 0; jj < fields.length; jj++) {
1078
+ const storageKey = fields[jj];
1079
+ // Skip internal metadata keys (all start with '__')
1080
+ if (storageKey.startsWith('__')) {
1081
+ continue;
1082
+ }
1083
+ if (
1084
+ RelayModernRecord.hasFieldChanged(
1085
+ targetRecord,
1086
+ nextRecord,
1087
+ storageKey,
1088
+ )
1089
+ ) {
1090
+ updatedRecordIDs.add(getFieldNotificationKey(dataID, storageKey));
1091
+ }
1092
+ }
1093
+ }
933
1094
  }
934
1095
  } else if (sourceRecord === null) {
935
1096
  target.delete(dataID);
@@ -0,0 +1,29 @@
1
+ /**
2
+ * Copyright (c) Meta Platforms, Inc. and affiliates.
3
+ *
4
+ * This source code is licensed under the MIT license found in the
5
+ * LICENSE file in the root directory of this source tree.
6
+ */
7
+
8
+ import { RequestDescriptor } from './RelayStoreTypes';
9
+
10
+ export class RelayOperationTracker {
11
+ /**
12
+ * Update the map of current processing operations with the set of
13
+ * affected owners and notify subscribers
14
+ */
15
+ update(pendingOperation: RequestDescriptor, affectedOwners: Set<RequestDescriptor>): void;
16
+
17
+ /**
18
+ * Once pending operation is completed we need to remove it
19
+ * from all tracking maps
20
+ */
21
+ complete(pendingOperation: RequestDescriptor): void;
22
+
23
+ _resolveOwnerResolvers(owner: RequestDescriptor): void;
24
+
25
+ getPendingOperationsAffectingOwner(owner: RequestDescriptor): {
26
+ promise: Promise<void>;
27
+ pendingOperations: readonly RequestDescriptor[];
28
+ } | null;
29
+ }
@@ -23,7 +23,7 @@ class RelayOperationTracker {
23
23
  {
24
24
  promise: Promise<void>,
25
25
  resolve: () => void,
26
- pendingOperations: $ReadOnlyArray<RequestDescriptor>,
26
+ pendingOperations: ReadonlyArray<RequestDescriptor>,
27
27
  },
28
28
  >;
29
29
 
@@ -150,7 +150,7 @@ class RelayOperationTracker {
150
150
 
151
151
  getPendingOperationsAffectingOwner(owner: RequestDescriptor): {
152
152
  promise: Promise<void>,
153
- pendingOperations: $ReadOnlyArray<RequestDescriptor>,
153
+ pendingOperations: ReadonlyArray<RequestDescriptor>,
154
154
  } | null {
155
155
  const ownerIdentifier = owner.identifier;
156
156
  const pendingOperationsForOwner =
@@ -25,7 +25,7 @@ const RelayRecordSource = require('./RelayRecordSource');
25
25
  const invariant = require('invariant');
26
26
 
27
27
  const UNPUBLISH_RECORD_SENTINEL = RelayModernRecord.fromObject(
28
- // $FlowFixMe[incompatible-call] frozen objects are readonly
28
+ // $FlowFixMe[incompatible-type] frozen objects are readonly
29
29
  Object.freeze({
30
30
  __UNPUBLISH_RECORD_SENTINEL: true,
31
31
  }),
@@ -88,7 +88,7 @@ class RelayOptimisticRecordSource implements MutableRecordSource {
88
88
  }
89
89
 
90
90
  remove(dataID: DataID): void {
91
- // $FlowFixMe[incompatible-call] frozen objects are readonly
91
+ // $FlowFixMe[incompatible-type] frozen objects are readonly
92
92
  this._sink.set(dataID, UNPUBLISH_RECORD_SENTINEL);
93
93
  }
94
94
 
@@ -40,23 +40,23 @@ const RelayRecordSource = require('./RelayRecordSource');
40
40
  const invariant = require('invariant');
41
41
  const warning = require('warning');
42
42
 
43
- type PendingCommit<TMutation: MutationParameters> =
43
+ type PendingCommit<TMutation extends MutationParameters> =
44
44
  | PendingRelayPayload<TMutation>
45
45
  | PendingRecordSource
46
46
  | PendingUpdater;
47
- type PendingRelayPayload<TMutation: MutationParameters> = {
48
- +kind: 'payload',
49
- +operation: OperationDescriptor,
50
- +payload: RelayResponsePayload,
51
- +updater: ?SelectorStoreUpdater<TMutation['response']>,
47
+ type PendingRelayPayload<TMutation extends MutationParameters> = {
48
+ readonly kind: 'payload',
49
+ readonly operation: OperationDescriptor,
50
+ readonly payload: RelayResponsePayload,
51
+ readonly updater: ?SelectorStoreUpdater<TMutation['response']>,
52
52
  };
53
53
  type PendingRecordSource = {
54
- +kind: 'source',
55
- +source: RecordSource,
54
+ readonly kind: 'source',
55
+ readonly source: RecordSource,
56
56
  };
57
57
  type PendingUpdater = {
58
- +kind: 'updater',
59
- +updater: StoreUpdater,
58
+ readonly kind: 'updater',
59
+ readonly updater: StoreUpdater,
60
60
  };
61
61
 
62
62
  const _global: typeof global | $FlowFixMe =
@@ -86,7 +86,7 @@ const applyWithGuard =
86
86
  class RelayPublishQueue implements PublishQueue {
87
87
  _store: Store;
88
88
  _handlerProvider: ?HandlerProvider;
89
- _missingFieldHandlers: $ReadOnlyArray<MissingFieldHandler>;
89
+ _missingFieldHandlers: ReadonlyArray<MissingFieldHandler>;
90
90
  _getDataID: GetDataID;
91
91
  _log: ?LogFunction;
92
92
 
@@ -116,7 +116,7 @@ class RelayPublishQueue implements PublishQueue {
116
116
  store: Store,
117
117
  handlerProvider?: ?HandlerProvider,
118
118
  getDataID: GetDataID,
119
- missingFieldHandlers: $ReadOnlyArray<MissingFieldHandler>,
119
+ missingFieldHandlers: ReadonlyArray<MissingFieldHandler>,
120
120
  log: LogFunction,
121
121
  ) {
122
122
  this._hasStoreSnapshot = false;
@@ -135,7 +135,7 @@ class RelayPublishQueue implements PublishQueue {
135
135
  /**
136
136
  * Schedule applying an optimistic updates on the next `run()`.
137
137
  */
138
- applyUpdate<TMutation: MutationParameters>(
138
+ applyUpdate<TMutation extends MutationParameters>(
139
139
  updater: OptimisticUpdate<TMutation>,
140
140
  ): void {
141
141
  invariant(
@@ -150,7 +150,7 @@ class RelayPublishQueue implements PublishQueue {
150
150
  /**
151
151
  * Schedule reverting an optimistic updates on the next `run()`.
152
152
  */
153
- revertUpdate<TMutation: MutationParameters>(
153
+ revertUpdate<TMutation extends MutationParameters>(
154
154
  updater: OptimisticUpdate<TMutation>,
155
155
  ): void {
156
156
  if (this._pendingOptimisticUpdates.has(updater)) {
@@ -174,7 +174,7 @@ class RelayPublishQueue implements PublishQueue {
174
174
  /**
175
175
  * Schedule applying a payload to the store on the next `run()`.
176
176
  */
177
- commitPayload<TMutation: MutationParameters>(
177
+ commitPayload<TMutation extends MutationParameters>(
178
178
  operation: OperationDescriptor,
179
179
  payload: RelayResponsePayload,
180
180
  updater?: ?SelectorStoreUpdater<TMutation['response']>,
@@ -213,11 +213,11 @@ class RelayPublishQueue implements PublishQueue {
213
213
  /**
214
214
  * Execute all queued up operations from the other public methods.
215
215
  */
216
- run(
217
- sourceOperation?: OperationDescriptor,
218
- ): $ReadOnlyArray<RequestDescriptor> {
216
+ run(sourceOperation?: OperationDescriptor): ReadonlyArray<RequestDescriptor> {
219
217
  const runWillClearGcHold =
220
218
  // $FlowFixMe[incompatible-type]
219
+ /* $FlowFixMe[invalid-compare] Error discovered during Constant Condition
220
+ * roll out. See https://fburl.com/workplace/4oq3zi07. */
221
221
  this._appliedOptimisticUpdates === 0 && !!this._gcHold;
222
222
  const runIsANoop =
223
223
  // this._pendingBackupRebase is true if an applied optimistic
@@ -286,7 +286,7 @@ class RelayPublishQueue implements PublishQueue {
286
286
  * _publishSourceFromPayload will return a boolean indicating if the
287
287
  * publish caused the store to be globally invalidated.
288
288
  */
289
- _publishSourceFromPayload<TMutation: MutationParameters>(
289
+ _publishSourceFromPayload<TMutation extends MutationParameters>(
290
290
  pendingPayload: PendingRelayPayload<TMutation>,
291
291
  ): boolean {
292
292
  const {payload, operation, updater} = pendingPayload;
@@ -462,7 +462,16 @@ function lookupSelector(
462
462
  source: RecordSource,
463
463
  selector: SingularReaderSelector,
464
464
  ): ?SelectorData {
465
- const selectorData = RelayReader.read(source, selector).data;
465
+ const selectorData = RelayReader.read(
466
+ source,
467
+ selector,
468
+ // The reader here is used to read the selector data for the updater.
469
+ // It is normal to not use all data in the update, so we don't pass
470
+ // the logger to skip tracking usages.
471
+ null,
472
+ undefined,
473
+ undefined,
474
+ ).data;
466
475
  if (__DEV__) {
467
476
  const deepFreeze = require('../util/deepFreeze');
468
477
  if (selectorData) {