relay-runtime 10.1.3 → 11.0.2

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 (106) hide show
  1. package/handlers/connection/ConnectionHandler.js.flow +60 -0
  2. package/handlers/connection/MutationHandlers.js.flow +28 -0
  3. package/index.js +1 -1
  4. package/index.js.flow +9 -3
  5. package/lib/handlers/RelayDefaultHandlerProvider.js +1 -1
  6. package/lib/handlers/connection/ConnectionHandler.js +68 -6
  7. package/lib/handlers/connection/MutationHandlers.js +67 -8
  8. package/lib/index.js +3 -0
  9. package/lib/multi-actor-environment/ActorIdentifier.js +23 -0
  10. package/lib/multi-actor-environment/ActorSpecificEnvironment.js +108 -0
  11. package/lib/multi-actor-environment/MultiActorEnvironment.js +156 -0
  12. package/lib/multi-actor-environment/MultiActorEnvironmentTypes.js +11 -0
  13. package/lib/multi-actor-environment/index.js +17 -0
  14. package/lib/mutations/RelayRecordProxy.js +1 -1
  15. package/lib/mutations/RelayRecordSourceMutator.js +1 -1
  16. package/lib/mutations/RelayRecordSourceProxy.js +1 -1
  17. package/lib/mutations/RelayRecordSourceSelectorProxy.js +1 -1
  18. package/lib/mutations/applyOptimisticMutation.js +1 -1
  19. package/lib/mutations/commitMutation.js +1 -1
  20. package/lib/mutations/validateMutation.js +36 -15
  21. package/lib/network/RelayNetwork.js +1 -1
  22. package/lib/network/RelayQueryResponseCache.js +3 -2
  23. package/lib/query/GraphQLTag.js +1 -1
  24. package/lib/query/fetchQuery.js +129 -13
  25. package/lib/query/fetchQueryInternal.js +3 -4
  26. package/lib/query/fetchQuery_DEPRECATED.js +39 -0
  27. package/lib/store/DataChecker.js +26 -14
  28. package/lib/store/{RelayModernQueryExecutor.js → OperationExecutor.js} +117 -47
  29. package/lib/store/RelayConcreteVariables.js +8 -4
  30. package/lib/store/RelayModernEnvironment.js +105 -136
  31. package/lib/store/RelayModernFragmentSpecResolver.js +16 -9
  32. package/lib/store/RelayModernRecord.js +1 -1
  33. package/lib/store/RelayModernSelector.js +1 -1
  34. package/lib/store/RelayModernStore.js +19 -20
  35. package/lib/store/RelayOperationTracker.js +55 -49
  36. package/lib/store/RelayPublishQueue.js +9 -5
  37. package/lib/store/RelayReader.js +68 -14
  38. package/lib/store/RelayReferenceMarker.js +28 -14
  39. package/lib/store/RelayResponseNormalizer.js +109 -15
  40. package/lib/store/RelayStoreReactFlightUtils.js +6 -4
  41. package/lib/store/RelayStoreSubscriptions.js +18 -8
  42. package/lib/store/RelayStoreSubscriptionsUsingMapByID.js +90 -30
  43. package/lib/store/RelayStoreUtils.js +3 -2
  44. package/lib/store/ResolverFragments.js +57 -0
  45. package/lib/store/cloneRelayHandleSourceField.js +1 -1
  46. package/lib/store/cloneRelayScalarHandleSourceField.js +1 -1
  47. package/lib/store/createFragmentSpecResolver.js +2 -2
  48. package/lib/store/createRelayContext.js +1 -1
  49. package/lib/store/defaultGetDataID.js +3 -1
  50. package/lib/store/hasOverlappingIDs.js +11 -3
  51. package/lib/store/readInlineData.js +1 -1
  52. package/lib/subscription/requestSubscription.js +33 -5
  53. package/lib/util/RelayConcreteNode.js +2 -0
  54. package/lib/util/RelayFeatureFlags.js +8 -3
  55. package/lib/util/RelayProfiler.js +17 -187
  56. package/lib/util/RelayReplaySubject.js +1 -1
  57. package/lib/util/deepFreeze.js +1 -0
  58. package/lib/util/getRelayHandleKey.js +1 -1
  59. package/lib/util/getRequestIdentifier.js +1 -1
  60. package/multi-actor-environment/ActorIdentifier.js.flow +27 -0
  61. package/multi-actor-environment/ActorSpecificEnvironment.js.flow +189 -0
  62. package/multi-actor-environment/MultiActorEnvironment.js.flow +233 -0
  63. package/multi-actor-environment/MultiActorEnvironmentTypes.js.flow +196 -0
  64. package/multi-actor-environment/index.js.flow +24 -0
  65. package/mutations/RelayRecordSourceProxy.js.flow +3 -2
  66. package/mutations/commitMutation.js.flow +1 -1
  67. package/mutations/validateMutation.js.flow +40 -15
  68. package/network/RelayNetworkTypes.js.flow +31 -11
  69. package/network/RelayQueryResponseCache.js.flow +2 -1
  70. package/package.json +3 -2
  71. package/query/fetchQuery.js.flow +147 -20
  72. package/query/fetchQueryInternal.js.flow +2 -3
  73. package/query/fetchQuery_DEPRECATED.js.flow +47 -0
  74. package/relay-runtime.js +2 -2
  75. package/relay-runtime.min.js +2 -2
  76. package/store/DataChecker.js.flow +23 -15
  77. package/store/{RelayModernQueryExecutor.js.flow → OperationExecutor.js.flow} +128 -40
  78. package/store/RelayConcreteVariables.js.flow +5 -0
  79. package/store/RelayModernEnvironment.js.flow +100 -130
  80. package/store/RelayModernFragmentSpecResolver.js.flow +30 -8
  81. package/store/RelayModernStore.js.flow +28 -24
  82. package/store/RelayOperationTracker.js.flow +69 -56
  83. package/store/RelayPublishQueue.js.flow +7 -4
  84. package/store/RelayReader.js.flow +63 -11
  85. package/store/RelayRecordSource.js.flow +3 -3
  86. package/store/RelayRecordSourceMapImpl.js.flow +6 -2
  87. package/store/RelayReferenceMarker.js.flow +28 -18
  88. package/store/RelayResponseNormalizer.js.flow +134 -23
  89. package/store/RelayStoreReactFlightUtils.js.flow +9 -4
  90. package/store/RelayStoreSubscriptions.js.flow +22 -7
  91. package/store/RelayStoreSubscriptionsUsingMapByID.js.flow +36 -12
  92. package/store/RelayStoreTypes.js.flow +51 -22
  93. package/store/RelayStoreUtils.js.flow +2 -1
  94. package/store/ResolverFragments.js.flow +125 -0
  95. package/store/createFragmentSpecResolver.js.flow +2 -0
  96. package/store/defaultGetDataID.js.flow +3 -1
  97. package/store/hasOverlappingIDs.js.flow +11 -9
  98. package/subscription/requestSubscription.js.flow +25 -2
  99. package/util/NormalizationNode.js.flow +13 -0
  100. package/util/ReaderNode.js.flow +14 -1
  101. package/util/RelayConcreteNode.js.flow +2 -0
  102. package/util/RelayFeatureFlags.js.flow +12 -2
  103. package/util/RelayProfiler.js.flow +22 -194
  104. package/util/RelayRuntimeTypes.js.flow +4 -5
  105. package/util/deepFreeze.js.flow +2 -1
  106. package/util/isEmptyObject.js.flow +1 -1
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "relay-runtime",
3
3
  "description": "A core runtime for building GraphQL-driven applications.",
4
- "version": "10.1.3",
4
+ "version": "11.0.2",
5
5
  "keywords": [
6
6
  "graphql",
7
7
  "relay"
@@ -12,7 +12,8 @@
12
12
  "repository": "facebook/relay",
13
13
  "dependencies": {
14
14
  "@babel/runtime": "^7.0.0",
15
- "fbjs": "^3.0.0"
15
+ "fbjs": "^3.0.0",
16
+ "invariant": "^2.2.4"
16
17
  },
17
18
  "directories": {
18
19
  "": "./"
@@ -4,6 +4,7 @@
4
4
  * This source code is licensed under the MIT license found in the
5
5
  * LICENSE file in the root directory of this source tree.
6
6
  *
7
+ * @emails oncall+relay
7
8
  * @flow strict-local
8
9
  * @format
9
10
  */
@@ -12,36 +13,162 @@
12
13
 
13
14
  'use strict';
14
15
 
16
+ const RelayObservable = require('../network/RelayObservable');
17
+
18
+ const fetchQueryInternal = require('./fetchQueryInternal');
19
+ const invariant = require('invariant');
20
+ const reportMissingRequiredFields = require('../util/reportMissingRequiredFields');
21
+
15
22
  const {
16
23
  createOperationDescriptor,
17
24
  } = require('../store/RelayModernOperationDescriptor');
18
25
  const {getRequest} = require('./GraphQLTag');
19
26
 
20
- import type {IEnvironment} from '../store/RelayStoreTypes';
21
- import type {CacheConfig, OperationType} from '../util/RelayRuntimeTypes';
22
- import type {GraphQLTaggedNode} from './GraphQLTag';
27
+ import type {
28
+ CacheConfig,
29
+ FetchQueryFetchPolicy,
30
+ GraphQLTaggedNode,
31
+ IEnvironment,
32
+ OperationDescriptor,
33
+ OperationType,
34
+ Snapshot,
35
+ VariablesOf,
36
+ } from 'relay-runtime';
23
37
 
24
38
  /**
25
- * A helper function to fetch the results of a query. Note that results for
26
- * fragment spreads are masked: fields must be explicitly listed in the query in
27
- * order to be accessible in the result object.
39
+ * Fetches the given query and variables on the provided environment,
40
+ * and de-dupes identical in-flight requests.
41
+ *
42
+ * Observing a request:
43
+ * ====================
44
+ * fetchQuery returns an Observable which you can call .subscribe()
45
+ * on. Subscribe optionally takes an Observer, which you can provide to
46
+ * observe network events:
47
+ *
48
+ * ```
49
+ * fetchQuery(environment, query, variables).subscribe({
50
+ * // Called when network requests starts
51
+ * start: (subsctiption) => {},
52
+ *
53
+ * // Called after a payload is received and written to the local store
54
+ * next: (payload) => {},
55
+ *
56
+ * // Called when network requests errors
57
+ * error: (error) => {},
58
+ *
59
+ * // Called when network requests fully completes
60
+ * complete: () => {},
61
+ *
62
+ * // Called when network request is unsubscribed
63
+ * unsubscribe: (subscription) => {},
64
+ * });
65
+ * ```
66
+ *
67
+ * Request Promise:
68
+ * ================
69
+ * The obervable can be converted to a Promise with .toPromise(), which will
70
+ * resolve to a snapshot of the query data when the first response is received
71
+ * from the server.
72
+ *
73
+ * ```
74
+ * fetchQuery(environment, query, variables).toPromise().then((data) => {
75
+ * // ...
76
+ * });
77
+ * ```
78
+ *
79
+ * In-flight request de-duping:
80
+ * ============================
81
+ * By default, calling fetchQuery multiple times with the same
82
+ * environment, query and variables will not initiate a new request if a request
83
+ * for those same parameters is already in flight.
84
+ *
85
+ * A request is marked in-flight from the moment it starts until the moment it
86
+ * fully completes, regardless of error or successful completion.
87
+ *
88
+ * NOTE: If the request completes _synchronously_, calling fetchQuery
89
+ * a second time with the same arguments in the same tick will _NOT_ de-dupe
90
+ * the request given that it will no longer be in-flight.
91
+ *
92
+ *
93
+ * Data Retention:
94
+ * ===============
95
+ * This function will NOT retain query data, meaning that it is not guaranteed
96
+ * that the fetched data will remain in the Relay store after the request has
97
+ * completed.
98
+ * If you need to retain the query data outside of the network request,
99
+ * you need to use `environment.retain()`.
100
+ *
101
+ *
102
+ * Cancelling requests:
103
+ * ====================
104
+ * If the disposable returned by subscribe is called while the
105
+ * request is in-flight, the request will be cancelled.
106
+ *
107
+ * ```
108
+ * const disposable = fetchQuery(...).subscribe(...);
109
+ *
110
+ * // This will cancel the request if it is in-flight.
111
+ * disposable.dispose();
112
+ * ```
113
+ * NOTE: When using .toPromise(), the request cannot be cancelled.
28
114
  */
29
-
30
- function fetchQuery<T: OperationType>(
115
+ function fetchQuery<TQuery: OperationType>(
31
116
  environment: IEnvironment,
32
- taggedNode: GraphQLTaggedNode,
33
- variables: $PropertyType<T, 'variables'>,
34
- cacheConfig?: ?CacheConfig,
35
- ): Promise<$PropertyType<T, 'response'>> {
36
- const query = getRequest(taggedNode);
37
- if (query.params.operationKind !== 'query') {
38
- throw new Error('fetchQuery: Expected query operation');
117
+ query: GraphQLTaggedNode,
118
+ variables: VariablesOf<TQuery>,
119
+ options?: $ReadOnly<{|
120
+ fetchPolicy?: FetchQueryFetchPolicy,
121
+ networkCacheConfig?: CacheConfig,
122
+ |}>,
123
+ ): RelayObservable<$ElementType<TQuery, 'response'>> {
124
+ const queryNode = getRequest(query);
125
+ invariant(
126
+ queryNode.params.operationKind === 'query',
127
+ 'fetchQuery: Expected query operation',
128
+ );
129
+ const networkCacheConfig = {
130
+ force: true,
131
+ ...options?.networkCacheConfig,
132
+ };
133
+ const operation = createOperationDescriptor(
134
+ queryNode,
135
+ variables,
136
+ networkCacheConfig,
137
+ );
138
+ const fetchPolicy = options?.fetchPolicy ?? 'network-only';
139
+
140
+ function readData(snapshot: Snapshot) {
141
+ if (snapshot.missingRequiredFields != null) {
142
+ reportMissingRequiredFields(environment, snapshot.missingRequiredFields);
143
+ }
144
+ return snapshot.data;
145
+ }
146
+
147
+ switch (fetchPolicy) {
148
+ case 'network-only': {
149
+ return getNetworkObservable(environment, operation).map(readData);
150
+ }
151
+ case 'store-or-network': {
152
+ if (environment.check(operation).status === 'available') {
153
+ return RelayObservable.from(environment.lookup(operation.fragment)).map(
154
+ readData,
155
+ );
156
+ }
157
+ return getNetworkObservable(environment, operation).map(readData);
158
+ }
159
+ default:
160
+ (fetchPolicy: empty);
161
+ throw new Error('fetchQuery: Invalid fetchPolicy ' + fetchPolicy);
39
162
  }
40
- const operation = createOperationDescriptor(query, variables, cacheConfig);
41
- return environment
42
- .execute({operation})
43
- .map(() => environment.lookup(operation.fragment).data)
44
- .toPromise();
163
+ }
164
+
165
+ function getNetworkObservable<TQuery: OperationType>(
166
+ environment: IEnvironment,
167
+ operation: OperationDescriptor,
168
+ ): RelayObservable<$ElementType<TQuery, 'response'>> {
169
+ return fetchQueryInternal
170
+ .fetchQuery(environment, operation)
171
+ .map(() => environment.lookup(operation.fragment));
45
172
  }
46
173
 
47
174
  module.exports = fetchQuery;
@@ -92,8 +92,7 @@ const requestCachesByEnvironment = WEAKMAP_SUPPORTED
92
92
  * Cancelling requests:
93
93
  * ====================
94
94
  * If the subscription returned by subscribe is called while the
95
- * request is in-flight, apart from releasing retained data, the request will
96
- * also be cancelled.
95
+ * request is in-flight, the request will be cancelled.
97
96
  *
98
97
  * ```
99
98
  * const subscription = fetchQuery(...).subscribe(...);
@@ -233,7 +232,7 @@ function getActiveStatusObservableForCachedRequest(
233
232
 
234
233
  /**
235
234
  * If a request is active for the given query, variables and environment,
236
- * this function will return a Promise that will resolve when that request has
235
+ * this function will return a Promise that will resolve when that request
237
236
  * stops being active (receives a final payload), and the data has been saved
238
237
  * to the store.
239
238
  * If no request is active, null will be returned
@@ -0,0 +1,47 @@
1
+ /**
2
+ * Copyright (c) Facebook, Inc. and its 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
+ * @flow strict-local
8
+ * @format
9
+ */
10
+
11
+ // flowlint ambiguous-object-type:error
12
+
13
+ 'use strict';
14
+
15
+ const {
16
+ createOperationDescriptor,
17
+ } = require('../store/RelayModernOperationDescriptor');
18
+ const {getRequest} = require('./GraphQLTag');
19
+
20
+ import type {IEnvironment} from '../store/RelayStoreTypes';
21
+ import type {CacheConfig, OperationType} from '../util/RelayRuntimeTypes';
22
+ import type {GraphQLTaggedNode} from './GraphQLTag';
23
+
24
+ /**
25
+ * A helper function to fetch the results of a query. Note that results for
26
+ * fragment spreads are masked: fields must be explicitly listed in the query in
27
+ * order to be accessible in the result object.
28
+ */
29
+
30
+ function fetchQuery_DEPRECATED<T: OperationType>(
31
+ environment: IEnvironment,
32
+ taggedNode: GraphQLTaggedNode,
33
+ variables: $PropertyType<T, 'variables'>,
34
+ cacheConfig?: ?CacheConfig,
35
+ ): Promise<$PropertyType<T, 'response'>> {
36
+ const query = getRequest(taggedNode);
37
+ if (query.params.operationKind !== 'query') {
38
+ throw new Error('fetchQuery: Expected query operation');
39
+ }
40
+ const operation = createOperationDescriptor(query, variables, cacheConfig);
41
+ return environment
42
+ .execute({operation})
43
+ .map(() => environment.lookup(operation.fragment).data)
44
+ .toPromise();
45
+ }
46
+
47
+ module.exports = fetchQuery_DEPRECATED;