relay-runtime 20.1.0 → 21.0.0

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 (262) hide show
  1. package/experimental.js +1 -1
  2. package/experimental.js.flow +8 -8
  3. package/handlers/connection/ConnectionHandler.js.flow +5 -5
  4. package/handlers/connection/ConnectionInterface.js.flow +1 -1
  5. package/index.js +1 -1
  6. package/index.js.flow +125 -62
  7. package/lib/experimental.js +3 -3
  8. package/lib/index.js +105 -57
  9. package/lib/multi-actor-environment/ActorIdentifier.js +2 -2
  10. package/lib/multi-actor-environment/MultiActorEnvironment.js +3 -1
  11. package/lib/mutations/commitMutation.js +8 -8
  12. package/lib/mutations/validateMutation.js +4 -4
  13. package/lib/query/GraphQLTag.js +3 -3
  14. package/lib/query/fetchQuery.js +15 -3
  15. package/lib/store/DataChecker.js +38 -4
  16. package/lib/store/NormalizationEngine.js +373 -0
  17. package/lib/store/OperationExecutor.js +172 -113
  18. package/lib/store/RelayConcreteVariables.js +1 -1
  19. package/lib/store/RelayErrorTrie.js +2 -2
  20. package/lib/store/RelayExperimentalGraphResponseTransform.js +8 -8
  21. package/lib/store/RelayModernEnvironment.js +26 -19
  22. package/lib/store/RelayModernRecord.js +18 -8
  23. package/lib/store/RelayModernSelector.js +9 -9
  24. package/lib/store/RelayModernStore.js +152 -43
  25. package/lib/store/RelayPublishQueue.js +1 -1
  26. package/lib/store/RelayReader.js +76 -38
  27. package/lib/store/RelayRecordSource.js +6 -0
  28. package/lib/store/RelayReferenceMarker.js +2 -1
  29. package/lib/store/RelayResponseNormalizer.js +88 -55
  30. package/lib/store/RelayStoreSubscriptions.js +34 -10
  31. package/lib/store/RelayStoreUtils.js +8 -1
  32. package/lib/store/ResolverFragments.js +2 -2
  33. package/lib/store/live-resolvers/LiveResolverCache.js +25 -9
  34. package/lib/store/observeFragmentExperimental.js +17 -1
  35. package/lib/store/observeQueryExperimental.js +2 -2
  36. package/lib/subscription/requestSubscription.js +3 -3
  37. package/lib/util/RelayError.js +3 -0
  38. package/lib/util/RelayFeatureFlags.js +6 -2
  39. package/lib/util/RelayReplaySubject.js +4 -4
  40. package/lib/util/handlePotentialSnapshotErrors.js +2 -2
  41. package/lib/util/stableCopy.js +2 -2
  42. package/llm-docs/api-reference/entrypoint-apis/entrypoint-container.mdx +38 -0
  43. package/llm-docs/api-reference/entrypoint-apis/load-entrypoint.mdx +77 -0
  44. package/llm-docs/api-reference/entrypoint-apis/use-entrypoint-loader.mdx +99 -0
  45. package/llm-docs/api-reference/graphql/graphql-directives.mdx +378 -0
  46. package/llm-docs/api-reference/hooks/_use-lazy-load-query-extra.mdx +16 -0
  47. package/llm-docs/api-reference/hooks/load-query.mdx +84 -0
  48. package/llm-docs/api-reference/hooks/relay-environment-provider.mdx +78 -0
  49. package/llm-docs/api-reference/hooks/use-client-query.mdx +65 -0
  50. package/llm-docs/api-reference/hooks/use-fragment.mdx +69 -0
  51. package/llm-docs/api-reference/hooks/use-lazy-load-query.mdx +62 -0
  52. package/llm-docs/api-reference/hooks/use-mutation.mdx +94 -0
  53. package/llm-docs/api-reference/hooks/use-pagination-fragment.mdx +166 -0
  54. package/llm-docs/api-reference/hooks/use-prefetchable-forward-pagination-fragment.mdx +134 -0
  55. package/llm-docs/api-reference/hooks/use-preloaded-query.mdx +84 -0
  56. package/llm-docs/api-reference/hooks/use-query-loader.mdx +95 -0
  57. package/llm-docs/api-reference/hooks/use-refetchable-fragment.mdx +122 -0
  58. package/llm-docs/api-reference/hooks/use-relay-environment.mdx +37 -0
  59. package/llm-docs/api-reference/hooks/use-subscription.mdx +66 -0
  60. package/llm-docs/api-reference/relay-resolvers/docblock-format.mdx +321 -0
  61. package/llm-docs/api-reference/relay-resolvers/runtime-functions.mdx +94 -0
  62. package/llm-docs/api-reference/relay-runtime/commit-mutation.mdx +65 -0
  63. package/llm-docs/api-reference/relay-runtime/fetch-query.mdx +113 -0
  64. package/llm-docs/api-reference/relay-runtime/field-logger.mdx +170 -0
  65. package/llm-docs/api-reference/relay-runtime/observe-fragment.mdx +92 -0
  66. package/llm-docs/api-reference/relay-runtime/relay-environment.mdx +53 -0
  67. package/llm-docs/api-reference/relay-runtime/request-subscription.mdx +54 -0
  68. package/llm-docs/api-reference/relay-runtime/runtime-configuration.mdx +52 -0
  69. package/llm-docs/api-reference/relay-runtime/store.mdx +734 -0
  70. package/llm-docs/api-reference/relay-runtime/wait-for-fragment-data.mdx +89 -0
  71. package/llm-docs/api-reference/types/CacheConfig.mdx +8 -0
  72. package/llm-docs/api-reference/types/Disposable.mdx +4 -0
  73. package/llm-docs/api-reference/types/GraphQLSubscriptionConfig.mdx +17 -0
  74. package/llm-docs/api-reference/types/MutationConfig.mdx +31 -0
  75. package/llm-docs/api-reference/types/SelectorStoreUpdater.mdx +6 -0
  76. package/llm-docs/api-reference/types/UploadableMap.mdx +3 -0
  77. package/llm-docs/community/learning-resources.mdx +64 -0
  78. package/llm-docs/debugging/declarative-mutation-directives.mdx +34 -0
  79. package/llm-docs/debugging/disallowed-id-types-error.mdx +43 -0
  80. package/llm-docs/debugging/inconsistent-typename-error.mdx +47 -0
  81. package/llm-docs/debugging/relay-devtools.mdx +73 -0
  82. package/llm-docs/debugging/why-null.mdx +116 -0
  83. package/llm-docs/editor-support.mdx +55 -0
  84. package/llm-docs/error-reference/unknown-field.mdx +36 -0
  85. package/llm-docs/getting-started/babel-plugin.mdx +31 -0
  86. package/llm-docs/getting-started/compiler-config.mdx +25 -0
  87. package/llm-docs/getting-started/compiler.mdx +82 -0
  88. package/llm-docs/getting-started/lint-rules.mdx +87 -0
  89. package/llm-docs/getting-started/production.mdx +30 -0
  90. package/llm-docs/getting-started/quick-start.mdx +213 -0
  91. package/llm-docs/glossary/glossary.mdx +1040 -0
  92. package/llm-docs/guided-tour/list-data/advanced-pagination.mdx +157 -0
  93. package/llm-docs/guided-tour/list-data/connections.mdx +81 -0
  94. package/llm-docs/guided-tour/list-data/pagination.mdx +193 -0
  95. package/llm-docs/guided-tour/list-data/rendering-connections.mdx +112 -0
  96. package/llm-docs/guided-tour/list-data/streaming-pagination.mdx +87 -0
  97. package/llm-docs/guided-tour/managing-data-outside-react/retaining-queries.mdx +51 -0
  98. package/llm-docs/guided-tour/refetching/refetching-queries-with-different-data.mdx +337 -0
  99. package/llm-docs/guided-tour/refetching/refreshing-queries.mdx +350 -0
  100. package/llm-docs/guided-tour/rendering/environment.mdx +59 -0
  101. package/llm-docs/guided-tour/rendering/error-states.mdx +295 -0
  102. package/llm-docs/guided-tour/rendering/fragments.mdx +354 -0
  103. package/llm-docs/guided-tour/rendering/loading-states.mdx +245 -0
  104. package/llm-docs/guided-tour/rendering/queries.mdx +261 -0
  105. package/llm-docs/guided-tour/rendering/variables.mdx +233 -0
  106. package/llm-docs/guided-tour/reusing-cached-data/fetch-policies.mdx +56 -0
  107. package/llm-docs/guided-tour/reusing-cached-data/filling-in-missing-data.mdx +102 -0
  108. package/llm-docs/guided-tour/reusing-cached-data/introduction.mdx +22 -0
  109. package/llm-docs/guided-tour/reusing-cached-data/presence-of-data.mdx +93 -0
  110. package/llm-docs/guided-tour/reusing-cached-data/rendering-partially-cached-data.mdx +175 -0
  111. package/llm-docs/guided-tour/reusing-cached-data/staleness-of-data.mdx +116 -0
  112. package/llm-docs/guided-tour/updating-data/client-only-data.mdx +115 -0
  113. package/llm-docs/guided-tour/updating-data/graphql-mutations.mdx +334 -0
  114. package/llm-docs/guided-tour/updating-data/graphql-subscriptions.mdx +279 -0
  115. package/llm-docs/guided-tour/updating-data/imperatively-modifying-linked-fields.mdx +511 -0
  116. package/llm-docs/guided-tour/updating-data/imperatively-modifying-store-data-legacy.mdx +142 -0
  117. package/llm-docs/guided-tour/updating-data/imperatively-modifying-store-data.mdx +275 -0
  118. package/llm-docs/guided-tour/updating-data/introduction.mdx +25 -0
  119. package/llm-docs/guided-tour/updating-data/local-data-updates.mdx +71 -0
  120. package/llm-docs/guided-tour/updating-data/typesafe-updaters-faq.mdx +83 -0
  121. package/llm-docs/guided-tour/updating-data/updating-connections.mdx +592 -0
  122. package/llm-docs/guides/alias-directive.mdx +160 -0
  123. package/llm-docs/guides/catch-directive.mdx +167 -0
  124. package/llm-docs/guides/client-schema-extensions.mdx +208 -0
  125. package/llm-docs/guides/codemods.mdx +66 -0
  126. package/llm-docs/guides/data-driven-dependencies/client-3d.mdx +255 -0
  127. package/llm-docs/guides/data-driven-dependencies/configuration.mdx +127 -0
  128. package/llm-docs/guides/data-driven-dependencies/introduction.mdx +39 -0
  129. package/llm-docs/guides/data-driven-dependencies/server-3d.mdx +664 -0
  130. package/llm-docs/guides/document-comparison.mdx +106 -0
  131. package/llm-docs/guides/graphql-server-specification.mdx +453 -0
  132. package/llm-docs/guides/network-layer.mdx +69 -0
  133. package/llm-docs/guides/persisted-queries.mdx +328 -0
  134. package/llm-docs/guides/relay-resolvers/context.mdx +99 -0
  135. package/llm-docs/guides/relay-resolvers/defining-fields.mdx +151 -0
  136. package/llm-docs/guides/relay-resolvers/defining-types.mdx +164 -0
  137. package/llm-docs/guides/relay-resolvers/deprecated.mdx +27 -0
  138. package/llm-docs/guides/relay-resolvers/derived-fields.mdx +127 -0
  139. package/llm-docs/guides/relay-resolvers/descriptions.mdx +44 -0
  140. package/llm-docs/guides/relay-resolvers/enabling.mdx +41 -0
  141. package/llm-docs/guides/relay-resolvers/errors.mdx +64 -0
  142. package/llm-docs/guides/relay-resolvers/field-arguments.mdx +63 -0
  143. package/llm-docs/guides/relay-resolvers/introduction.mdx +62 -0
  144. package/llm-docs/guides/relay-resolvers/limitations.mdx +30 -0
  145. package/llm-docs/guides/relay-resolvers/live-fields.mdx +164 -0
  146. package/llm-docs/guides/relay-resolvers/return-types.mdx +161 -0
  147. package/llm-docs/guides/relay-resolvers/suspense.mdx +41 -0
  148. package/llm-docs/guides/required-directive.mdx +240 -0
  149. package/llm-docs/guides/semantic-nullability.mdx +93 -0
  150. package/llm-docs/guides/testing-relay-components.mdx +642 -0
  151. package/llm-docs/guides/testing-relay-with-preloaded-queries.mdx +160 -0
  152. package/llm-docs/guides/throw-on-field-error-directive.mdx +58 -0
  153. package/llm-docs/guides/type-emission.mdx +414 -0
  154. package/llm-docs/home.mdx +32 -0
  155. package/llm-docs/principles-and-architecture/architecture-overview.mdx +24 -0
  156. package/llm-docs/principles-and-architecture/compiler-architecture.mdx +106 -0
  157. package/llm-docs/principles-and-architecture/runtime-architecture.mdx +249 -0
  158. package/llm-docs/principles-and-architecture/thinking-in-graphql.mdx +309 -0
  159. package/llm-docs/principles-and-architecture/thinking-in-relay.mdx +104 -0
  160. package/llm-docs/principles-and-architecture/videos.mdx +50 -0
  161. package/llm-docs/tutorial/arrays-lists.mdx +126 -0
  162. package/llm-docs/tutorial/fragments-1.mdx +487 -0
  163. package/llm-docs/tutorial/graphql.mdx +172 -0
  164. package/llm-docs/tutorial/interfaces-polymorphism.mdx +161 -0
  165. package/llm-docs/tutorial/intro.mdx +58 -0
  166. package/llm-docs/tutorial/mutations-updates.mdx +624 -0
  167. package/llm-docs/tutorial/organizing-mutations-queries-and-subscriptions.mdx +13 -0
  168. package/llm-docs/tutorial/queries-1.mdx +267 -0
  169. package/llm-docs/tutorial/queries-2.mdx +389 -0
  170. package/llm-docs/tutorial/refetchable-fragments.mdx +352 -0
  171. package/multi-actor-environment/ActorIdentifier.js.flow +2 -2
  172. package/multi-actor-environment/ActorSpecificEnvironment.js.flow +7 -7
  173. package/multi-actor-environment/ActorUtils.js.flow +1 -1
  174. package/multi-actor-environment/MultiActorEnvironment.js.flow +12 -8
  175. package/multi-actor-environment/MultiActorEnvironmentTypes.js.flow +3 -3
  176. package/mutations/RelayDeclarativeMutationConfig.js.flow +9 -9
  177. package/mutations/RelayRecordProxy.js.flow +8 -11
  178. package/mutations/RelayRecordSourceMutator.js.flow +4 -4
  179. package/mutations/RelayRecordSourceProxy.js.flow +4 -4
  180. package/mutations/RelayRecordSourceSelectorProxy.js.flow +6 -6
  181. package/mutations/applyOptimisticMutation.js.flow +2 -2
  182. package/mutations/commitMutation.js.flow +20 -16
  183. package/mutations/createUpdatableProxy.js.flow +19 -19
  184. package/mutations/readUpdatableFragment.js.flow +3 -3
  185. package/mutations/readUpdatableQuery.js.flow +3 -3
  186. package/mutations/validateMutation.js.flow +7 -7
  187. package/network/RelayNetworkTypes.js.flow +4 -4
  188. package/network/RelayObservable.js.flow +16 -14
  189. package/network/RelayQueryResponseCache.js.flow +3 -3
  190. package/network/wrapNetworkWithLogObserver.js.flow +1 -1
  191. package/package.json +2 -1
  192. package/query/GraphQLTag.js.flow +22 -10
  193. package/query/fetchQuery.js.flow +23 -10
  194. package/query/fetchQuery_DEPRECATED.js.flow +1 -1
  195. package/store/DataChecker.js.flow +43 -9
  196. package/store/NormalizationEngine.js.flow +779 -0
  197. package/store/OperationExecutor.js.flow +173 -70
  198. package/store/RelayConcreteVariables.js.flow +5 -5
  199. package/store/RelayErrorTrie.js.flow +12 -12
  200. package/store/RelayExperimentalGraphResponseHandler.js.flow +3 -3
  201. package/store/RelayExperimentalGraphResponseTransform.js.flow +10 -10
  202. package/store/RelayModernEnvironment.js.flow +41 -26
  203. package/store/RelayModernFragmentSpecResolver.js.flow +1 -1
  204. package/store/RelayModernOperationDescriptor.js.flow +1 -1
  205. package/store/RelayModernRecord.js.flow +46 -22
  206. package/store/RelayModernSelector.js.flow +21 -21
  207. package/store/RelayModernStore.js.flow +219 -58
  208. package/store/RelayOperationTracker.js.flow +2 -2
  209. package/store/RelayOptimisticRecordSource.js.flow +2 -2
  210. package/store/RelayPublishQueue.js.flow +21 -12
  211. package/store/RelayReader.js.flow +130 -58
  212. package/store/RelayRecordSource.js.flow +10 -0
  213. package/store/RelayRecordState.js.flow +1 -1
  214. package/store/RelayReferenceMarker.js.flow +5 -4
  215. package/store/RelayResponseNormalizer.js.flow +130 -54
  216. package/store/RelayStoreSubscriptions.js.flow +52 -8
  217. package/store/RelayStoreTypes.js.flow +153 -64
  218. package/store/RelayStoreUtils.js.flow +15 -7
  219. package/store/ResolverCache.js.flow +2 -2
  220. package/store/ResolverFragments.js.flow +12 -12
  221. package/store/StoreInspector.js.flow +6 -7
  222. package/store/cloneRelayHandleSourceField.js.flow +1 -1
  223. package/store/cloneRelayScalarHandleSourceField.js.flow +1 -1
  224. package/store/createRelayContext.js.flow +1 -1
  225. package/store/createRelayLoggingContext.js.flow +4 -4
  226. package/store/defaultGetDataID.js.flow +2 -2
  227. package/store/isRelayModernEnvironment.js.flow +4 -2
  228. package/store/live-resolvers/LiveResolverCache.js.flow +55 -20
  229. package/store/live-resolvers/LiveResolverSuspenseSentinel.js.flow +3 -3
  230. package/store/live-resolvers/getOutputTypeRecordIDs.js.flow +1 -1
  231. package/store/live-resolvers/isLiveStateValue.js.flow +2 -2
  232. package/store/live-resolvers/resolverDataInjector.js.flow +8 -5
  233. package/store/observeFragmentExperimental.js.flow +49 -20
  234. package/store/observeQueryExperimental.js.flow +5 -5
  235. package/store/readInlineData.js.flow +4 -4
  236. package/store/waitForFragmentExperimental.js.flow +3 -3
  237. package/subscription/requestSubscription.js.flow +7 -7
  238. package/util/NormalizationNode.js.flow +34 -32
  239. package/util/ReaderNode.js.flow +32 -30
  240. package/util/RelayConcreteNode.js.flow +5 -5
  241. package/util/RelayError.js.flow +4 -1
  242. package/util/RelayFeatureFlags.js.flow +21 -1
  243. package/util/RelayProfiler.js.flow +1 -1
  244. package/util/RelayReplaySubject.js.flow +3 -3
  245. package/util/RelayRuntimeTypes.js.flow +11 -11
  246. package/util/createPayloadFor3DField.js.flow +9 -5
  247. package/util/deepFreeze.js.flow +2 -2
  248. package/util/getFragmentIdentifier.js.flow +1 -1
  249. package/util/getPaginationMetadata.js.flow +1 -1
  250. package/util/getPaginationVariables.js.flow +1 -1
  251. package/util/getPendingOperationsForFragment.js.flow +2 -2
  252. package/util/getRefetchMetadata.js.flow +6 -5
  253. package/util/getValueAtPath.js.flow +3 -3
  254. package/util/handlePotentialSnapshotErrors.js.flow +5 -5
  255. package/util/isEmptyObject.js.flow +1 -1
  256. package/util/isPromise.js.flow +2 -2
  257. package/util/isScalarAndEqual.js.flow +1 -1
  258. package/util/recycleNodesInto.js.flow +2 -2
  259. package/util/registerEnvironmentWithDevTools.js.flow +1 -1
  260. package/util/shallowFreeze.js.flow +1 -1
  261. package/util/stableCopy.js.flow +5 -5
  262. package/util/withProvidedVariables.js.flow +14 -10
@@ -0,0 +1,31 @@
1
+ ---
2
+ id: babel-plugin
3
+ title: Relay Babel Plugin
4
+ slug: /getting-started/babel-plugin/
5
+ description: Setting up Relay's Babel plugin
6
+ keywords:
7
+ - babel
8
+ ---
9
+ # Babel Plugin
10
+
11
+ Relay requires a [Babel plugin](https://www.npmjs.com/package/babel-plugin-relay) to convert GraphQL to compiler-generated runtime artifacts. Depending upon what framework/bundler you are using, there may be a framework-specific plugin you can use:
12
+
13
+ - Vite: [vite-plugin-relay](https://github.com/oscartbeaumont/vite-plugin-relay)
14
+ - Next.js: [Relay config option](https://nextjs.org/docs/architecture/nextjs-compiler#relay)
15
+ - SWC: [@swc/plugin-relay](https://www.npmjs.com/package/@swc/plugin-relay)
16
+
17
+ If not, you can install the Babel plugin manually:
18
+
19
+ ```sh
20
+ yarn add --dev babel-plugin-relay graphql
21
+ ```
22
+
23
+ Add `"relay"` to the list of plugins in your `.babelrc` file:
24
+
25
+ ```javascript
26
+ {
27
+ "plugins": ["relay"]
28
+ }
29
+ ```
30
+
31
+ Please note that the `"relay"` plugin should run before other plugins or presets to ensure the `graphql` template literals are correctly transformed. See Babel's [documentation on this topic](https://babeljs.io/docs/plugins/#pluginpreset-ordering).
@@ -0,0 +1,25 @@
1
+ ---
2
+ id: compiler-config
3
+ title: Compiler Configuration
4
+ slug: /getting-started/compiler-config/
5
+ description: Schema description of the Relay Compiler configuration
6
+ keywords:
7
+ - compiler
8
+ - configuration
9
+ - config
10
+ hide_table_of_contents: false
11
+ ---
12
+ import CompilerConfig from '@site/src/compiler-config/CompilerConfig';
13
+ import schema from '@compilerConfigJsonSchema';
14
+
15
+ ## Compiler Config Options
16
+
17
+ For information about where the Relay compiler looks for its config file, or a minimal config, see the [Relay Compiler](./compiler.mdx#Configuration) page.
18
+
19
+ If you need more advanced options of the Relay Compiler Config, the exhaustive full schema can be found below. The shape of the Relay Compiler Config is given as `ConfigFile`. Note that while the shapes are documented in pseudo TypeScript, the compiler is parsing them in Rust so some subtle differences may exist.
20
+
21
+ :::tip
22
+ Install the [Relay VSCode extension](../editor-support.mdx) to get autocomplete, hover tips, and type checking for the options in your Relay config.
23
+ :::
24
+
25
+ <CompilerConfig schema={schema} definitions={schema.$defs} />
@@ -0,0 +1,82 @@
1
+ ---
2
+ id: compiler
3
+ title: Relay Compiler
4
+ slug: /guides/compiler/
5
+ description: Relay guide to the compiler
6
+ keywords:
7
+ - compiler
8
+ ---
9
+
10
+ Relay depends upon ahead-of-time compilation of GraphQL queries and fragments to generate artifacts that are used at runtime.
11
+
12
+ The Relay compiler is a command line tool that reads GraphQL fragments, queries, and mutations in your JavaScript code and generates TypeScript/Flow types and additional JavaScript code that gets included in your code via [Relay's Babel Plugin](./babel-plugin.mdx).
13
+
14
+ This guide explains configuring and using the Relay Compiler.
15
+
16
+ ## Configuration
17
+
18
+ The Relay compiler will look for a Relay config in the following locations. It's up to you to decide which location works best for your project.
19
+
20
+ * `relay.config.json` in your project root
21
+ * `relay.config.(js/mjs/ts)` in your project root
22
+ * A `"relay"` key in your `package.json`
23
+
24
+ The Relay compiler config tells Relay things like where it can find your GraphQL schema and what language your code is written in. A minimal Relay compiler config looks like this:
25
+
26
+ ```json title="relay.config.json"
27
+ {
28
+ "src": "./src",
29
+ "schema": "./schema.graphql",
30
+ "language": "typescript"
31
+ }
32
+ ```
33
+
34
+ :::tip
35
+ Install the [Relay VSCode extension](../editor-support.mdx) to get autocomplete, hover tips, and type checking for the options in your relay config.
36
+ :::
37
+
38
+ The compiler config is very powerful, and includes many specialized configuration options. For a full enumeration of the available options see the [Compiler Configuration](./compiler-config.mdx) page.
39
+
40
+
41
+ ## Running the compiler
42
+
43
+ It is generally recommended that you add a `scripts` entry to your `package.json` to make it easy to run the Relay compiler for your project.
44
+
45
+ ```json title="package.json"
46
+ {
47
+ "scripts": {
48
+ // change-line
49
+ "relay": "relay-compiler"
50
+ }
51
+ }
52
+ ```
53
+
54
+ With this added you can run the Relay compiler like so:
55
+
56
+ ```sh
57
+ npm run relay
58
+ ```
59
+
60
+ ### Watch mode
61
+
62
+ If you have [watchman](https://facebook.github.io/watchman) installed you can pass `--watch` to the Relay compiler to have it continue running and automatically update generated files as you edit your product code:
63
+
64
+ ```sh
65
+ npm run relay --watch
66
+ ```
67
+
68
+ ### Codemods
69
+
70
+ The Relay compiler supports some built in codemods. Learn more in the [Codemods Guide](../guides/codemods.mdx).
71
+
72
+ ### Document comparison (Experimental)
73
+
74
+ The Relay compiler can compare two GraphQL documents to determine if one is a subset of another. Learn more in the [Document Comparison Guide](../guides/document-comparison.mdx).
75
+
76
+ ### Help
77
+
78
+ To learn about the other capabilities of the Relay compiler see its extensive `--help` output:
79
+
80
+ ```sh
81
+ npm run relay --help
82
+ ```
@@ -0,0 +1,87 @@
1
+ ---
2
+ id: lint-rules
3
+ title: Relay ESLint Plugin
4
+ slug: /getting-started/lint-rules/
5
+ description: ESLint Plugin Relay
6
+ keywords:
7
+ - eslint
8
+ - lint
9
+ ---
10
+
11
+ One of the unique features enabled by Relay is the ability to statically detect unused GraphQL fields. This can [categorically prevent](https://relay.dev/blog/2023/10/24/how-relay-enables-optimal-data-fetching/) the "append only query" problem that is a common dysfunction in many GraphQL clients.
12
+
13
+ ![Relay ESLint Plugin](../../static/img/docs/no-unused-fields.png)
14
+
15
+ This validation, and other helpful checks, are enabled by Relay's ESLint plugin [`eslint-plugin-relay`](https://www.npmjs.com/package/eslint-plugin-relay). **The Relay ESLint plugin is a key part of the Relay developer experience**.
16
+
17
+ ## Installation
18
+
19
+ Assuming you have [ESLint](https://eslint.org/) already installed, you can add the Relay ESLint plugin to your project by running:
20
+
21
+ ```sh
22
+ npm install --save-dev eslint-plugin-relay
23
+ ```
24
+
25
+ Then update your ESLint configuration to include the plugin:
26
+
27
+ ```js tile="eslint.config.js"
28
+ import relay from 'eslint-plugin-relay';
29
+
30
+ export default [
31
+ // ... other ESlint Config
32
+ {
33
+ plugins: { relay },
34
+ rules: relay.configs['ts-recommended'].rules,
35
+ },
36
+ ];
37
+ ```
38
+
39
+ ## Rule Descriptions
40
+
41
+ The following validation rules are included in the Relay ESLint plugin:
42
+
43
+ ### `relay/unused-fields`
44
+ Ensures that every GraphQL field referenced is used within the module that includes it. This helps enable Relay's [optimal data fetching](https://relay.dev/blog/2023/10/24/how-relay-enables-optimal-data-fetching/).
45
+
46
+ ### `relay/no-future-added-value`
47
+ Ensures code does not try to explicitly handle the `"%future added value"` enum variant which Relay inserts as a placeholder to ensure you handle the possibility that new enum variants may be added by the server after your application has been deployed.
48
+
49
+ ### `relay/graphql-syntax`
50
+ Ensures each `graphql` tagged template literal contains syntactically valid GraphQL. This is also validated by the Relay Compiler, but the ESLint plugin can often provide faster feedback.
51
+
52
+ ### `relay/graphql-naming`
53
+ Ensures GraphQL fragments and queries follow Relay's naming conventions. This is also validated by the Relay Compiler, but the ESLint plugin can often provide faster feedback.
54
+
55
+ ### `relay/function-required-argument`
56
+ Ensures that `readInlineData` is always passed an explicit argument even though that argument is allowed to be `undefined` at runtime.
57
+
58
+ ### `relay/hook-required-argument`
59
+ Ensures that Relay hooks are always passed an explicit argument even though that argument is allowed to be `undefined` at runtime.
60
+
61
+ ### `relay/must-colocate-fragment-spreads`
62
+ Ensures that when a fragment spread is added within a module, that module directly imports the module which defines that fragment. This prevents the anti-pattern when one component fetches a fragment that is not used by a direct child component.
63
+ **Note**: This rule leans heavily on Meta's globally unique module names. It likely won't work well in other environments.
64
+
65
+ ## Suppressing rules within graphql tags
66
+
67
+ The following rules support suppression within graphql tags:
68
+
69
+ - `relay/unused-fields`
70
+ - `relay/must-colocate-fragment-spreads`
71
+
72
+ Supported rules can be suppressed by adding `# eslint-disable-next-line relay/name-of-rule` to the preceding line:
73
+
74
+ ```js
75
+ graphql`
76
+ fragment foo on Page {
77
+ # eslint-disable-next-line relay/must-colocate-fragment-spreads
78
+ ...unused1
79
+ }
80
+ `;
81
+ ```
82
+
83
+ Note that only the `eslint-disable-next-line` form of suppression works. `eslint-disable-line` doesn't currently work until graphql-js provides support for [parsing Comment nodes](https://github.com/graphql/graphql-js/issues/2241) in their AST.
84
+
85
+ ## Contributing
86
+
87
+ If you wish to contribute to the Relay ESLint plugin, you can find the code on GitHub at [relay/eslint-plugin-relay](https://github.com/relayjs/eslint-plugin-relay/).
@@ -0,0 +1,30 @@
1
+ ---
2
+ id: production
3
+ title: Production Setup
4
+ slug: /getting-started/production/
5
+ description: Setting up Relay for production use
6
+ keywords:
7
+ - production
8
+ ---
9
+
10
+ Getting the most out of Relay in production requires a few extra steps. This page covers a list of best practices for taking Relay to production.
11
+
12
+ ## Persisted Queries (Trusted Documents)
13
+
14
+ One of GraphQL's key innovations is that it enables clients to define arbitrary queries. While this unlocks a lot of flexibility, it also opens the doors to abuse. Scrapers can use GraphQL to scrape data from your site, and malicious users can use GraphQL to send large requests to your server that cause a denial of service. To prevent this, we recommend using [Persisted Queries](../guides/persisted-queries.mdx) also know as [Trusted Documents](https://benjie.dev/graphql/trusted-documents).
15
+
16
+ With Persisted Queries, the set of queries that the client can send is locked in at build time. This means that scrapers and malicious attackers are limited to sending only the queries used by the client, just like REST. It also has the added benefit that the client code only needs to include a single id for each query rather than the whole query text.
17
+
18
+ <!-- TODO add Entry Points here once we have better docs -->
19
+
20
+ ## Relay Lint Rules
21
+
22
+ A key principle of Relay is data colocation where each component defines its own data dependencies. It's critical to [How Relay Enables Optimal Data Fetching](https://relay.dev/blog/2023/10/24/how-relay-enables-optimal-data-fetching/). However, this is often unintuitive for developers who are used to fetching data in a single query. Relay's ESLint rules can help enforce this pattern by ensuring no component fetches fields which it does not itself use.
23
+
24
+ We recommend using the [`eslint-plugin-relay`](https://github.com/relayjs/eslint-plugin-relay), especially the `relay/unused-fields` rule.
25
+
26
+ Learn how to install them: [Relay ESLint Plugin](./lint-rules.mdx).
27
+
28
+ ## Running the Relay Compiler in CI
29
+
30
+ We recommend committing Relay's generated artifacts to source control along with your application code. This ensures generated types are present without needing an additional build, and allows for inspection of generated artifacts in code review. To ensure the generated artifacts are always in sync with the source code, we recommend running the Relay compiler in CI and ensuring it does not change any generated files. A example bash script which checks for changes can be found [here](https://github.com/facebook/relay/blob/0414c9ad0744483e349e07defcb6d70a52cf8b3c/scripts/check-git-status.sh).
@@ -0,0 +1,213 @@
1
+ ---
2
+ id: quick-start
3
+ title: Quick Start
4
+ slug: /getting-started/quick-start/
5
+ description: Get up and running with Relay
6
+ keywords:
7
+ - quick
8
+ ---
9
+ This quick start guide will start with a new React app using Vite and show you how to add Relay to it.
10
+
11
+ :::tip
12
+ If you'd prefer an automated approach, [`create-relay-app`](https://github.com/tobias-tengler/create-relay-app) by Tobias Tengler will walk you through adding Relay to an existing React app via a series of prompts: `npm create @tobiastengler/relay-app`
13
+ :::
14
+
15
+ We will be building a simple app which shows Star Wars movies fetched from the [example Star Wars GraphQL API](https://graphql.org/swapi-graphql/) hosted by graphql.org.
16
+
17
+ ## Scaffold a React App
18
+
19
+ We’ll start with a [Vite](https://vite.dev/) React app using TypeScript.
20
+
21
+ ```bash
22
+ npm create vite -- --template react-ts
23
+ ```
24
+
25
+ You’ll be prompted for a project name. Type: `relay-example`
26
+
27
+ ## Install Dependencies
28
+
29
+ ```bash
30
+ cd relay-example
31
+
32
+ # Runtime dependencies
33
+ npm install relay-runtime react-relay
34
+ # Dev dependencies
35
+ npm install --save-dev babel-plugin-relay graphql relay-compiler
36
+ ```
37
+
38
+ :::tip
39
+ If you're using an AI coding assistant, install the Relay best practices skill to make your agent a Relay expert:
40
+
41
+ ```bash
42
+ npx skills install facebook/relay
43
+ ```
44
+ :::
45
+
46
+ ## Configure Vite to use Relay
47
+
48
+ Relay uses a [Babel plugin](./babel-plugin.mdx) to insert code generated by the Relay compiler into your bundle. We can enable the Relay Babel plugin we installed earlier by configuring the React Vite plugin.
49
+
50
+ ```tsx title="vite.config.ts"
51
+ import { defineConfig } from 'vite'
52
+ import react from '@vitejs/plugin-react'
53
+
54
+ // https://vite.dev/config/
55
+ export default defineConfig({
56
+ plugins: [
57
+ // change-line
58
+ react({ babel: { plugins: ["relay"] } })
59
+ ],
60
+ })
61
+ ```
62
+
63
+ See [Babel Plugin](./babel-plugin.mdx) for information about how to configure the Babel plugin for other build systems.
64
+
65
+ ## Configure the Relay Compiler
66
+
67
+ Next we will download the GraphQL schema for the Star Wars GraphQL endpoint.
68
+
69
+ ```bash
70
+ curl -O https://raw.githubusercontent.com/graphql/swapi-graphql/refs/heads/master/schema.graphql
71
+ ```
72
+
73
+ And define our `relay.config.json` config file which tells the [Relay Compiler](./compiler.mdx) which schema file we want it to use and other details about our project.
74
+
75
+ ```json title="relay.config.json"
76
+ {
77
+ "src": "./src",
78
+ "schema": "./schema.graphql",
79
+ "language": "typescript"
80
+ }
81
+ ```
82
+
83
+ See [Relay Compiler](./compiler.mdx) for more information about configuring and running the Relay compiler.
84
+
85
+ ## Configure your Relay Environment
86
+
87
+ To allow components within our application to fetch GraphQL we configure a Relay Environment to fetch from our test endpoint and add it to React context.
88
+
89
+ ```tsx title="src/main.tsx"
90
+ import { StrictMode, Suspense } from "react";
91
+ import { createRoot } from "react-dom/client";
92
+ import "./index.css";
93
+ import App from "./App.tsx";
94
+ import { RelayEnvironmentProvider } from "react-relay";
95
+ import { Environment, Network, FetchFunction } from "relay-runtime";
96
+
97
+ const HTTP_ENDPOINT = "https://graphql.org/graphql/";
98
+
99
+ const fetchGraphQL: FetchFunction = async (request, variables) => {
100
+ const resp = await fetch(HTTP_ENDPOINT, {
101
+ method: "POST",
102
+ headers: { "Content-Type": "application/json" },
103
+ body: JSON.stringify({ query: request.text, variables }),
104
+ });
105
+ if (!resp.ok) {
106
+ throw new Error("Response failed.");
107
+ }
108
+ return await resp.json();
109
+ };
110
+
111
+ const environment = new Environment({
112
+ network: Network.create(fetchGraphQL),
113
+ });
114
+
115
+ createRoot(document.getElementById("root")!).render(
116
+ <StrictMode>
117
+ <RelayEnvironmentProvider environment={environment}>
118
+ <Suspense fallback="Loading...">
119
+ <App />
120
+ </Suspense>
121
+ </RelayEnvironmentProvider>
122
+ </StrictMode>
123
+ );
124
+ ```
125
+
126
+ See [Relay Environment](../api-reference/relay-runtime/relay-environment.mdx) for an overview of the Relay Environment and how to configure it.
127
+
128
+ :::tip
129
+ `<RelayEnvironmentProvider>` exposes your Environment via [React context](https://react.dev/learn/passing-data-deeply-with-context), so it must wrap your entire application.
130
+ :::
131
+
132
+ ## Define your first Relay component
133
+
134
+ Finally we can start defining the data we want to fetch and build our UI. Our app will fetch a list of films and render each one using a `<Film>` component.
135
+
136
+ ```tsx title="src/App.tsx"
137
+ import { AppQuery } from "./__generated__/AppQuery.graphql";
138
+ import { graphql, useLazyLoadQuery } from "react-relay";
139
+ import Film from "./Film";
140
+
141
+ export default function App() {
142
+ const data = useLazyLoadQuery<AppQuery>(
143
+ graphql`
144
+ query AppQuery {
145
+ allFilms {
146
+ films {
147
+ id
148
+ ...Film_item
149
+ }
150
+ }
151
+ }
152
+ `,
153
+ {}
154
+ );
155
+
156
+ const films = data?.allFilms?.films?.filter((film) => film != null);
157
+
158
+ return (
159
+ <div>
160
+ <h1>Star Wars Films</h1>
161
+ {films?.map((film) => (
162
+ <Film key={film.id} film={film} />
163
+ ))}
164
+ </div>
165
+ );
166
+ }
167
+ ```
168
+
169
+ ## Define your first fragment
170
+
171
+ One of Relay's core principles is that each component should define its own data dependencies. So, we define our `<Film>` component using a [GraphQL Fragment](https://graphql.org/learn/queries/#fragments).
172
+
173
+ ```typescript title="src/Film.tsx"
174
+ import { graphql, useFragment } from "react-relay";
175
+ import type { Film_item$key } from "./__generated__/Film_item.graphql";
176
+
177
+ export default function FilmListItem(props: { film: Film_item$key; }) {
178
+ const film = useFragment<Film_item$key>(
179
+ graphql`
180
+ fragment Film_item on Film {
181
+ title
182
+ director
183
+ }
184
+ `,
185
+ props.film
186
+ );
187
+
188
+ return (
189
+ <li>
190
+ <b>{film.title}</b>: directed by <i>{film.director}</i>
191
+ </li>
192
+ );
193
+ }
194
+ ```
195
+
196
+ ## Compile and run your app
197
+
198
+ All that’s left is to run the Relay compiler and start your app!
199
+
200
+ The Relay compiler generates TypeScript types and combines your queries and fragments into optimized representations. You have to run the Relay compiler each time you modify your GraphQL queries or fragments.
201
+
202
+ :::tip
203
+ If you have [Watchman](https://facebook.github.io/watchman/) installed you can run `npx relay-compiler --watch` to have the compiler run in watch mode, but you'll need to run `echo "{}" > .watchmanconfig` to create a Watchman root.
204
+ :::
205
+
206
+ ```bash
207
+ npx relay-compiler
208
+ npm run dev
209
+ ```
210
+
211
+ You should now be able to open your app in a browser: [http://localhost:5173/](http://localhost:5173/)
212
+
213
+ May the force be with you!