relay-runtime 20.1.1 → 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 +44 -20
  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 +129 -57
  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 +125 -57
  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,734 @@
1
+ ---
2
+ id: store
3
+ title: Store
4
+ slug: /api-reference/store/
5
+ description: API reference for the Relay store
6
+ keywords:
7
+ - store
8
+ ---
9
+
10
+ import DocsRating from '@site/src/core/DocsRating';
11
+ import {OssOnly, FbInternalOnly} from 'docusaurus-plugin-internaldocs-fb/internal';
12
+
13
+ The Relay Store can be used to programmatically update client-side data inside [`updater` functions](../../guided-tour/updating-data/graphql-mutations/). The following is a reference of the Relay Store interface.
14
+
15
+ Table of Contents:
16
+
17
+ - [RecordSourceSelectorProxy](#recordsourceselectorproxy)
18
+ - [RecordProxy](#recordproxy)
19
+ - [RecordSourceProxy](#recordsourceproxy)
20
+ - [ConnectionHandler](#connectionhandler)
21
+
22
+ ## RecordSourceSelectorProxy
23
+
24
+ The `RecordSourceSelectorProxy` is the type of the `store` that [`updater` functions](../../guided-tour/updating-data/graphql-mutations/) receive as an argument. The following is the `RecordSourceSelectorProxy` interface:
25
+
26
+ ```javascript
27
+ interface RecordSourceSelectorProxy {
28
+ create(dataID: string, typeName: string): RecordProxy;
29
+ delete(dataID: string): void;
30
+ get(dataID: string): ?RecordProxy;
31
+ getRoot(): RecordProxy;
32
+ getRootField(fieldName: string): ?RecordProxy;
33
+ getPluralRootField(fieldName: string): ?Array<?RecordProxy>;
34
+ invalidateStore(): void;
35
+ }
36
+ ```
37
+
38
+ ### `create(dataID: string, typeName: string): RecordProxy`
39
+
40
+ Creates a new record in the store given a `dataID` and the `typeName` as defined by the GraphQL schema. Returns a [`RecordProxy`](#recordproxy) which serves as an interface to mutate the newly created record.
41
+
42
+ #### Example
43
+
44
+ ```javascript
45
+ const record = store.create(dataID, 'Todo');
46
+ ```
47
+
48
+ ### `delete(dataID: string): void`
49
+
50
+ Deletes a record from the store given its `dataID`. For existing edges to the deleted record, `undefined` will be returned in the default case even when the value is typed as non-nullable. When [`@throwOnFieldError`](../../guides/throw-on-field-error-directive/) is present, the missing data will throw an error.
51
+
52
+ #### Example
53
+
54
+ ```javascript
55
+ store.delete(dataID);
56
+ ```
57
+
58
+ ### `get(dataID: string): ?RecordProxy`
59
+
60
+ Retrieves a record from the store given its `dataID`. Returns a [`RecordProxy`](#recordproxy) which serves as an interface to mutate the record.
61
+
62
+ #### Example
63
+
64
+ ```javascript
65
+ const record = store.get(dataID);
66
+ ```
67
+
68
+ ### `getRoot(): RecordProxy`
69
+
70
+ Returns the [`RecordProxy`](#recordproxy) representing the root of the GraphQL document.
71
+
72
+ #### Example
73
+
74
+ Given the GraphQL document:
75
+
76
+ ```graphql
77
+ viewer {
78
+ id
79
+ }
80
+ ```
81
+
82
+ Usage:
83
+
84
+ ```javascript
85
+ // Represents root query
86
+ const root = store.getRoot();
87
+ // Get the viewer linked record
88
+ const viewer = root.getLinkedRecord('viewer');
89
+ ```
90
+
91
+ ### `getRootField(fieldName: string): ?RecordProxy`
92
+
93
+ Retrieves a root field from the store given the `fieldName`, as defined by the GraphQL document. Returns a [`RecordProxy`](#recordproxy) which serves as an interface to mutate the record.
94
+
95
+ #### Example
96
+
97
+ Given the GraphQL document:
98
+
99
+ ```graphql
100
+ viewer {
101
+ id
102
+ }
103
+ ```
104
+
105
+ Usage:
106
+
107
+ ```javascript
108
+ const viewer = store.getRootField('viewer');
109
+ ```
110
+
111
+ ### `getPluralRootField(fieldName: string): ?Array<?RecordProxy>`
112
+
113
+ Retrieves a root field that represents a collection from the store given the `fieldName`, as defined by the GraphQL document. Returns an array of [`RecordProxies`](#recordproxy).
114
+
115
+ #### Example
116
+
117
+ Given the GraphQL document:
118
+
119
+ ```graphql
120
+ nodes(first: 10) {
121
+ # ...
122
+ }
123
+ ```
124
+
125
+ Usage:
126
+
127
+ ```javascript
128
+ const nodes = store.getPluralRootField('nodes');
129
+ ```
130
+
131
+ ### `invalidateStore(): void`
132
+
133
+ Globally invalidates the Relay store. This will cause any data that was written to the store before invalidation occurred to be considered stale, and will be considered to require refetch the next time a query is checked with `environment.check()`.
134
+
135
+ #### Example
136
+
137
+ ```javascript
138
+ store.invalidateStore();
139
+ ```
140
+
141
+ After global invalidation, any query that is checked before refetching it will be considered stale:
142
+
143
+ ```javascript
144
+ environment.check(query) === 'stale'
145
+ ```
146
+
147
+ ## RecordProxy
148
+
149
+ The `RecordProxy` serves as an interface to mutate records:
150
+
151
+ ```javascript
152
+ interface RecordProxy {
153
+ copyFieldsFrom(sourceRecord: RecordProxy): void;
154
+ getDataID(): string;
155
+ getLinkedRecord(name: string, arguments?: ?Object): ?RecordProxy;
156
+ getLinkedRecords(name: string, arguments?: ?Object): ?Array<?RecordProxy>;
157
+ getOrCreateLinkedRecord(
158
+ name: string,
159
+ typeName: string,
160
+ arguments?: ?Object,
161
+ ): RecordProxy;
162
+ getType(): string;
163
+ getValue(name: string, arguments?: ?Object): mixed;
164
+ setLinkedRecord(
165
+ record: RecordProxy,
166
+ name: string,
167
+ arguments?: ?Object,
168
+ ): RecordProxy;
169
+ setLinkedRecords(
170
+ records: Array<?RecordProxy>,
171
+ name: string,
172
+ arguments?: ?Object,
173
+ ): RecordProxy;
174
+ setValue(value: mixed, name: string, arguments?: ?Object): RecordProxy;
175
+ invalidateRecord(): void;
176
+ }
177
+ ```
178
+
179
+ ### `getDataID(): string`
180
+
181
+ Returns the `dataID` of the current record.
182
+
183
+ #### Example
184
+
185
+ ```javascript
186
+ const id = record.getDataID();
187
+ ```
188
+
189
+ ### `getType(): string`
190
+
191
+ Gets the type of the current record, as defined by the GraphQL schema.
192
+
193
+ #### Example
194
+
195
+ ```javascript
196
+ const type = user.getType(); // User
197
+ ```
198
+
199
+ ### `getValue(name: string, arguments?: ?Object): mixed`
200
+
201
+ Gets the value of a field in the current record given the field name.
202
+
203
+ #### Example
204
+
205
+ Given the GraphQL document:
206
+
207
+ ```graphql
208
+ viewer {
209
+ id
210
+ name
211
+ }
212
+ ```
213
+
214
+ Usage:
215
+
216
+ ```javascript
217
+ const name = viewer.getValue('name');
218
+ ```
219
+
220
+ Optionally, if the field takes arguments, you can pass a bag of `variables`.
221
+
222
+ #### Example
223
+
224
+ Given the GraphQL document:
225
+
226
+ ```graphql
227
+ viewer {
228
+ id
229
+ name(arg: $arg)
230
+ }
231
+ ```
232
+
233
+ Usage:
234
+
235
+ ```javascript
236
+ const name = viewer.getValue('name', {arg: 'value'});
237
+ ```
238
+
239
+ ### `getLinkedRecord(name: string, arguments?: ?Object): ?RecordProxy`
240
+
241
+ Retrieves a record associated with the current record given the field name, as defined by the GraphQL document. Returns a `RecordProxy`.
242
+
243
+ #### Example
244
+
245
+ Given the GraphQL document:
246
+
247
+ ```graphql
248
+ rootField {
249
+ viewer {
250
+ id
251
+ name
252
+ }
253
+ }
254
+ ```
255
+
256
+ Usage:
257
+
258
+ ```javascript
259
+ const rootField = store.getRootField('rootField');
260
+ const viewer = rootField.getLinkedRecord('viewer');
261
+ ```
262
+
263
+ Optionally, if the linked record takes arguments, you can pass a bag of `variables` as well.
264
+
265
+ #### Example
266
+
267
+ Given the GraphQL document:
268
+
269
+ ```graphql
270
+ rootField {
271
+ viewer(arg: $arg) {
272
+ id
273
+ }
274
+ }
275
+ ```
276
+
277
+ Usage:
278
+
279
+ ```javascript
280
+ const rootField = store.getRootField('rootField');
281
+ const viewer = rootField.getLinkedRecord('viewer', {arg: 'value'});
282
+ ```
283
+
284
+ ### `getLinkedRecords(name: string, arguments?: ?Object): ?Array<?RecordProxy>`
285
+
286
+ Retrieves the set of records associated with the current record given the field name, as defined by the GraphQL document. Returns an array of `RecordProxies`.
287
+
288
+ #### Example
289
+
290
+ Given the GraphQL document:
291
+
292
+ ```graphql
293
+ rootField {
294
+ nodes {
295
+ # ...
296
+ }
297
+ }
298
+ ```
299
+
300
+ Usage:
301
+
302
+ ```javascript
303
+ const rootField = store.getRootField('rootField');
304
+ const nodes = rootField.getLinkedRecords('nodes');
305
+ ```
306
+
307
+ Optionally, if the linked record takes arguments, you can pass a bag of `variables` as well.
308
+
309
+ #### Example
310
+
311
+ Given the GraphQL document:
312
+
313
+ ```graphql
314
+ rootField {
315
+ nodes(first: $count) {
316
+ # ...
317
+ }
318
+ }
319
+ ```
320
+
321
+ Usage:
322
+
323
+ ```javascript
324
+ const rootField = store.getRootField('rootField');
325
+ const nodes = rootField.getLinkedRecords('nodes', {count: 10});
326
+ ```
327
+
328
+ ### `getOrCreateLinkedRecord(name: string, typeName: string, arguments?: ?Object)`
329
+
330
+ Retrieves a record associated with the current record given the field name, as defined by the GraphQL document. If the linked record does not exist, it will be created given the type name. Returns a `RecordProxy`.
331
+
332
+ #### Example
333
+
334
+ Given the GraphQL document:
335
+
336
+ ```graphql
337
+ rootField {
338
+ viewer {
339
+ id
340
+ }
341
+ }
342
+ ```
343
+
344
+ Usage:
345
+
346
+ ```javascript
347
+ const rootField = store.getRootField('rootField');
348
+ const newViewer = rootField.getOrCreateLinkedRecord('viewer', 'User'); // Will create if it doesn't exist
349
+ ```
350
+
351
+ Optionally, if the linked record takes arguments, you can pass a bag of `variables` as well.
352
+
353
+ ### `setValue(value: mixed, name: string, arguments?: ?Object): RecordProxy`
354
+
355
+ Mutates the current record by setting a new value on the specified field. Returns the mutated record.
356
+
357
+ Given the GraphQL document:
358
+
359
+ ```graphql
360
+ viewer {
361
+ id
362
+ name
363
+ }
364
+ ```
365
+
366
+ Usage:
367
+
368
+ ```javascript
369
+ viewer.setValue('New Name', 'name');
370
+ ```
371
+
372
+ Optionally, if the field takes arguments, you can pass a bag of `variables`.
373
+
374
+ ```javascript
375
+ viewer.setValue('New Name', 'name', {arg: 'value'});
376
+ ```
377
+
378
+ ### `copyFieldsFrom(sourceRecord: RecordProxy): void`
379
+
380
+ Mutates the current record by copying the fields over from the passed in record `sourceRecord`.
381
+
382
+ #### Example
383
+
384
+ ```javascript
385
+ const record = store.get(id1);
386
+ const otherRecord = store.get(id2);
387
+ record.copyFieldsFrom(otherRecord); // Mutates `record`
388
+ ```
389
+
390
+ ### `setLinkedRecord(record: RecordProxy, name: string, arguments?: ?Object)`
391
+
392
+ Mutates the current record by setting a new linked record on the given field name.
393
+
394
+ #### Example
395
+
396
+ Given the GraphQL document:
397
+
398
+ ```graphql
399
+ rootField {
400
+ viewer {
401
+ id
402
+ }
403
+ }
404
+ ```
405
+
406
+ Usage:
407
+
408
+ ```javascript
409
+ const rootField = store.getRootField('rootField');
410
+ const newViewer = store.create(/* ... */);
411
+ rootField.setLinkedRecord(newViewer, 'viewer');
412
+ ```
413
+
414
+ Optionally, if the linked record takes arguments, you can pass a bag of `variables` as well.
415
+
416
+ ### `setLinkedRecords(records: Array<RecordProxy>, name: string, variables?: ?Object)`
417
+
418
+ Mutates the current record by setting a new set of linked records on the given field name.
419
+
420
+ #### Example
421
+
422
+ Given the GraphQL document:
423
+
424
+ ```graphql
425
+ rootField {
426
+ nodes {
427
+ # ...
428
+ }
429
+ }
430
+ ```
431
+
432
+ Usage:
433
+
434
+ ```javascript
435
+ const rootField = store.getRootField('rootField');
436
+ const newNode = store.create(/* ... */);
437
+ const newNodes = [...rootField.getLinkedRecords('nodes'), newNode];
438
+ rootField.setLinkedRecords(newNodes, 'nodes');
439
+ ```
440
+
441
+ Optionally, if the linked record takes arguments, you can pass a bag of `variables` as well.
442
+
443
+ ### `invalidateRecord(): void`
444
+
445
+ Invalidates the record. This will cause any query that references this record to be considered stale until the next time it is refetched, and will be considered to require a refetch the next time such a query is checked with `environment.check()`.
446
+
447
+ #### Example
448
+
449
+ ```javascript
450
+ const record = store.get('4');
451
+ record.invalidateRecord();
452
+ ```
453
+
454
+ After invalidating a record, any query that references the invalidated record and that is checked before refetching it will be considered stale:
455
+
456
+ ```javascript
457
+ environment.check(query) === 'stale'
458
+ ```
459
+
460
+ ## RecordSourceProxy
461
+
462
+ The `RecordSourceProxy` serves as an interface to mutate records.
463
+
464
+ :::danger
465
+ `RecordSourceProxy` exposes many low level APIs that are not typesafe. Users should consider using [typesafe updaters](../../guided-tour/updating-data/typesafe-updaters-faq/), [optimistic updates](../../guided-tour/updating-data/graphql-mutations/#optimistic-updates), and [relay resolvers](../../guides/relay-resolvers/introduction/) instead if their use case can be covered by these alternatives.
466
+ :::
467
+
468
+ ```javascript
469
+ interface RecordSourceProxy {
470
+ create(dataID: DataID, typeName: string): RecordProxy;
471
+ delete(dataID: DataID): void;
472
+ get(dataID: DataID): ?RecordProxy;
473
+ getRoot(): RecordProxy;
474
+ invalidateStore(): void;
475
+ readUpdatableFragment<TFragmentType: FragmentType, TData>(
476
+ fragment: UpdatableFragment<TFragmentType, TData>,
477
+ fragmentReference: HasUpdatableSpread<TFragmentType>,
478
+ ): UpdatableData<TData>;
479
+ readUpdatableQuery<TVariables: Variables, TData>(
480
+ query: UpdatableQuery<TVariables, TData>,
481
+ variables: TVariables,
482
+ ): UpdatableData<TData>;
483
+ }
484
+ ```
485
+
486
+ ### `create(dataID: DataID, typeName: string): RecordProxy`
487
+
488
+ Creates a new record in the store given a `dataID` and the `typeName` as defined by the GraphQL schema. Returns a [`RecordProxy`](#recordproxy) which serves as an interface to mutate the newly created record.
489
+
490
+ #### Example
491
+
492
+ ```javascript
493
+ const record = store.create(dataID, 'Todo');
494
+ ```
495
+
496
+ ### `delete(dataID: DataID): void`
497
+
498
+ Deletes a record from the store given its `dataID`. For existing edges to the deleted record, `undefined` will be returned in the default case even when the value is typed as non-nullable. When [`@throwOnFieldError`](../../guides/throw-on-field-error-directive/) is present, the missing data will throw an error.
499
+
500
+ #### Example
501
+
502
+ ```javascript
503
+ store.delete(dataID);
504
+ ```
505
+
506
+ ### `get(dataID: DataID): ?RecordProxy`
507
+
508
+ Retrieves a record from the store given its `dataID`. Returns a [`RecordProxy`](#recordproxy) which serves as an interface to read/mutate the record.
509
+
510
+ #### Example
511
+
512
+ ```javascript
513
+ const record = store.get(dataID);
514
+ ```
515
+
516
+ ### `getRoot(): RecordProxy`
517
+
518
+ Returns the [`RecordProxy`](#recordproxy) representing the root of the GraphQL document.
519
+
520
+ #### Example
521
+
522
+ Given the GraphQL document:
523
+
524
+ ```graphql
525
+ viewer {
526
+ id
527
+ }
528
+ ```
529
+
530
+ Usage:
531
+
532
+ ```javascript
533
+ // Represents root query
534
+ const root = store.getRoot();
535
+ // Get the viewer linked record
536
+ const viewer = root.getLinkedRecord('viewer');
537
+ ```
538
+
539
+ ### `invalidateStore(): void;`
540
+
541
+ Globally invalidates the Relay store. This will cause any data that was written to the store before invalidation occurred to be considered stale, and will be considered to require refetch the next time a query is checked with `environment.check()` or is fetched with a `store-or-network` [fetch policy](../../guided-tour/reusing-cached-data/fetch-policies/).
542
+
543
+ #### Example
544
+
545
+ ```javascript
546
+ store.invalidateStore();
547
+ ```
548
+
549
+ After global invalidation, any query that is checked before refetching it will be considered stale:
550
+
551
+ ```javascript
552
+ environment.check(query) === 'stale'
553
+ ```
554
+
555
+ ### `readUpdatableFragment(fragment: UpdatableFragment<TFragmentType, TData>,fragmentReference: HasUpdatableSpread<TFragmentType>): UpdatableData<TData>;`
556
+
557
+ Fetches an updatable fragment from the store. This updatable fragment's fields can then be imperatively modified to update data in the store.
558
+
559
+ For more information on updating the store imperatively, see this [section](../../guided-tour/updating-data/imperatively-modifying-store-data/) of the guided tour.
560
+
561
+ #### Example
562
+ ```javascript
563
+ const fragment = graphql`
564
+ fragment StoryLikeButton_updatable on Story @updatable {
565
+ likeCount
566
+ doesViewerLike
567
+ }
568
+ `;
569
+ const {
570
+ updatableData
571
+ } = store.readUpdatableFragment(
572
+ fragment,
573
+ story
574
+ );
575
+ updatableData.likeCount = updatableData.likeCount + 1
576
+ ```
577
+
578
+ ### `readUpdatableQuery(query: UpdatableQuery<TVariables, TData>,variables: TVariables): UpdatableData<TData>`
579
+
580
+ Reads an updatable query from the store. This updatable query's fields can be imperatively modified to update data in the store. Unlike `readUpdatableFragment`, you do not need to pass in a `fragmentReference` as an input argument.
581
+
582
+ For more information on updating the store imperatively, see this [section](../../guided-tour/updating-data/imperatively-modifying-store-data/) of the guided tour.
583
+
584
+ #### Example
585
+
586
+ ```javascript
587
+ const {updatableData} = store.readUpdatableQuery(
588
+ graphql`
589
+ query NameUpdaterUpdateQuery @updatable {
590
+ viewer {
591
+ name
592
+ }
593
+ }
594
+ `,
595
+ {}
596
+ );
597
+ const viewer = updatableData.viewer;
598
+ viewer.name = newName;
599
+ ```
600
+
601
+ ## ConnectionHandler
602
+
603
+ `ConnectionHandler` is a utility module exposed by `relay-runtime` that aids in the manipulation of connections. `ConnectionHandler` exposes the following interface:
604
+
605
+ ```javascript
606
+ interface ConnectionHandler {
607
+ getConnection(
608
+ record: RecordProxy,
609
+ key: string,
610
+ filters?: ?Object,
611
+ ): ?RecordProxy,
612
+ createEdge(
613
+ store: RecordSourceProxy,
614
+ connection: RecordProxy,
615
+ node: RecordProxy,
616
+ edgeType: string,
617
+ ): RecordProxy,
618
+ insertEdgeBefore(
619
+ connection: RecordProxy,
620
+ newEdge: RecordProxy,
621
+ cursor?: ?string,
622
+ ): void,
623
+ insertEdgeAfter(
624
+ connection: RecordProxy,
625
+ newEdge: RecordProxy,
626
+ cursor?: ?string,
627
+ ): void,
628
+ deleteNode(connection: RecordProxy, nodeID: string): void
629
+ }
630
+ ```
631
+
632
+ ### `getConnection(record: RecordProxy, key: string, filters?: ?Object)`
633
+
634
+ Given a record and a connection key, and optionally a set of filters, `getConnection` retrieves a [`RecordProxy`](#recordproxy) that represents a connection that was annotated with a `@connection` directive.
635
+
636
+ First, let's take a look at a plain connection:
637
+
638
+ ```graphql
639
+ fragment FriendsFragment on User {
640
+ friends(first: 10) {
641
+ edges {
642
+ node {
643
+ id
644
+ }
645
+ }
646
+ }
647
+ }
648
+ ```
649
+
650
+ Accessing a plain connection field like this is the same as other regular fields:
651
+
652
+ ```javascript
653
+ // The `friends` connection record can be accessed with:
654
+ const user = store.get(userID);
655
+ const friends = user && user.getLinkedRecord('friends');
656
+
657
+ // Access fields on the connection:
658
+ const edges = friends && friends.getLinkedRecords('edges');
659
+ ```
660
+
661
+ When using [usePaginationFragment](../use-pagination-fragment/), we usually annotate the actual connection field with `@connection` to tell Relay which part needs to be paginated:
662
+
663
+ ```graphql
664
+ fragment FriendsFragment on User {
665
+ friends(first: 10, orderby: "firstname") @connection(
666
+ key: "FriendsFragment_friends",
667
+ ) {
668
+ edges {
669
+ node {
670
+ id
671
+ }
672
+ }
673
+ }
674
+ }
675
+ ```
676
+
677
+ For connections like the above, `ConnectionHandler` helps us find the record:
678
+
679
+ ```javascript
680
+ import {ConnectionHandler} from 'relay-runtime';
681
+
682
+ // The `friends` connection record can be accessed with:
683
+ const user = store.get(userID);
684
+ const friends = ConnectionHandler.getConnection(
685
+ user, // parent record
686
+ 'FriendsFragment_friends', // connection key
687
+ {orderby: 'firstname'} // 'filters' that is used to identify the connection
688
+ );
689
+ // Access fields on the connection:
690
+ const edges = friends.getLinkedRecords('edges');
691
+ ```
692
+
693
+ ### Edge creation and insertion
694
+
695
+ #### `createEdge(store: RecordSourceProxy, connection: RecordProxy, node: RecordProxy, edgeType: string)`
696
+
697
+ Creates an edge given a [`store`](#recordsourceselectorproxy), a connection, the edge node, and the edge type.
698
+
699
+ #### `insertEdgeBefore(connection: RecordProxy, newEdge: RecordProxy, cursor?: ?string)`
700
+
701
+ Given a connection, inserts the edge at the beginning of the connection, or before the specified `cursor`.
702
+
703
+ #### `insertEdgeAfter(connection: RecordProxy, newEdge: RecordProxy, cursor?: ?string)`
704
+
705
+ Given a connection, inserts the edge at the end of the connection, or after the specified `cursor`.
706
+
707
+ #### Example
708
+
709
+ ```javascript
710
+ const user = store.get(userID);
711
+ const friends = ConnectionHandler.getConnection(user, 'FriendsFragment_friends');
712
+ const newFriend = store.get(newFriendId);
713
+ const edge = ConnectionHandler.createEdge(store, friends, newFriend, 'UserEdge');
714
+
715
+ // No cursor provided, append the edge at the end.
716
+ ConnectionHandler.insertEdgeAfter(friends, edge);
717
+
718
+ // No cursor provided, insert the edge at the front:
719
+ ConnectionHandler.insertEdgeBefore(friends, edge);
720
+ ```
721
+
722
+ ### `deleteNode(connection: RecordProxy, nodeID: string): void`
723
+
724
+ Given a connection, deletes any edges whose node id matches the given id.
725
+
726
+ #### Example
727
+
728
+ ```javascript
729
+ const user = store.get(userID);
730
+ const friends = ConnectionHandler.getConnection(user, 'FriendsFragment_friends');
731
+ ConnectionHandler.deleteNode(friends, idToDelete);
732
+ ```
733
+
734
+ <DocsRating />