relay-runtime 11.0.0 → 13.0.0-rc.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 (169) hide show
  1. package/handlers/RelayDefaultHandlerProvider.js.flow +2 -2
  2. package/handlers/connection/ConnectionHandler.js.flow +8 -10
  3. package/handlers/connection/MutationHandlers.js.flow +31 -7
  4. package/index.js +1 -1
  5. package/index.js.flow +60 -36
  6. package/lib/handlers/RelayDefaultHandlerProvider.js +1 -1
  7. package/lib/handlers/connection/ConnectionHandler.js +8 -8
  8. package/lib/handlers/connection/MutationHandlers.js +61 -5
  9. package/lib/index.js +58 -43
  10. package/lib/multi-actor-environment/ActorIdentifier.js +33 -0
  11. package/lib/multi-actor-environment/ActorSpecificEnvironment.js +152 -0
  12. package/lib/multi-actor-environment/ActorUtils.js +27 -0
  13. package/lib/multi-actor-environment/MultiActorEnvironment.js +419 -0
  14. package/lib/multi-actor-environment/MultiActorEnvironmentTypes.js +11 -0
  15. package/lib/multi-actor-environment/index.js +21 -0
  16. package/lib/mutations/RelayDeclarativeMutationConfig.js +4 -1
  17. package/lib/mutations/RelayRecordProxy.js +3 -2
  18. package/lib/mutations/RelayRecordSourceMutator.js +3 -2
  19. package/lib/mutations/RelayRecordSourceProxy.js +12 -4
  20. package/lib/mutations/RelayRecordSourceSelectorProxy.js +18 -5
  21. package/lib/mutations/applyOptimisticMutation.js +6 -6
  22. package/lib/mutations/commitMutation.js +14 -10
  23. package/lib/mutations/readUpdatableQuery_EXPERIMENTAL.js +238 -0
  24. package/lib/mutations/validateMutation.js +12 -5
  25. package/lib/network/ConvertToExecuteFunction.js +2 -1
  26. package/lib/network/RelayNetwork.js +3 -2
  27. package/lib/network/RelayQueryResponseCache.js +21 -4
  28. package/lib/network/wrapNetworkWithLogObserver.js +79 -0
  29. package/lib/query/GraphQLTag.js +3 -2
  30. package/lib/query/fetchQuery.js +6 -5
  31. package/lib/query/fetchQueryInternal.js +1 -1
  32. package/lib/query/fetchQuery_DEPRECATED.js +2 -1
  33. package/lib/store/ClientID.js +7 -1
  34. package/lib/store/DataChecker.js +141 -60
  35. package/lib/store/{RelayModernQueryExecutor.js → OperationExecutor.js} +532 -195
  36. package/lib/store/RelayConcreteVariables.js +24 -4
  37. package/lib/store/RelayModernEnvironment.js +175 -234
  38. package/lib/store/RelayModernFragmentSpecResolver.js +52 -26
  39. package/lib/store/RelayModernOperationDescriptor.js +2 -1
  40. package/lib/store/RelayModernRecord.js +47 -12
  41. package/lib/store/RelayModernSelector.js +14 -8
  42. package/lib/store/RelayModernStore.js +58 -29
  43. package/lib/store/RelayOperationTracker.js +34 -24
  44. package/lib/store/RelayPublishQueue.js +41 -13
  45. package/lib/store/RelayReader.js +287 -46
  46. package/lib/store/RelayRecordSource.js +87 -3
  47. package/lib/store/RelayReferenceMarker.js +55 -31
  48. package/lib/store/RelayResponseNormalizer.js +250 -108
  49. package/lib/store/RelayStoreReactFlightUtils.js +8 -12
  50. package/lib/store/RelayStoreSubscriptions.js +14 -9
  51. package/lib/store/RelayStoreUtils.js +11 -5
  52. package/lib/store/ResolverCache.js +213 -0
  53. package/lib/store/ResolverFragments.js +61 -0
  54. package/lib/store/cloneRelayHandleSourceField.js +5 -4
  55. package/lib/store/cloneRelayScalarHandleSourceField.js +5 -4
  56. package/lib/store/createRelayContext.js +4 -2
  57. package/lib/store/defaultGetDataID.js +3 -1
  58. package/lib/store/readInlineData.js +6 -2
  59. package/lib/subscription/requestSubscription.js +35 -9
  60. package/lib/util/RelayConcreteNode.js +4 -0
  61. package/lib/util/RelayFeatureFlags.js +11 -4
  62. package/lib/util/RelayProfiler.js +17 -187
  63. package/lib/util/RelayReplaySubject.js +22 -7
  64. package/lib/util/RelayRuntimeTypes.js +0 -6
  65. package/lib/util/StringInterner.js +71 -0
  66. package/lib/util/deepFreeze.js +1 -0
  67. package/lib/util/getFragmentIdentifier.js +15 -7
  68. package/lib/util/getOperation.js +2 -1
  69. package/lib/util/getPaginationMetadata.js +41 -0
  70. package/lib/util/getPaginationVariables.js +66 -0
  71. package/lib/util/getPendingOperationsForFragment.js +55 -0
  72. package/lib/util/getRefetchMetadata.js +36 -0
  73. package/lib/util/getRelayHandleKey.js +2 -2
  74. package/lib/util/getRequestIdentifier.js +2 -2
  75. package/lib/util/getValueAtPath.js +51 -0
  76. package/lib/util/isEmptyObject.js +1 -1
  77. package/lib/util/registerEnvironmentWithDevTools.js +26 -0
  78. package/lib/util/withDuration.js +31 -0
  79. package/multi-actor-environment/ActorIdentifier.js.flow +43 -0
  80. package/multi-actor-environment/ActorSpecificEnvironment.js.flow +225 -0
  81. package/multi-actor-environment/ActorUtils.js.flow +33 -0
  82. package/multi-actor-environment/MultiActorEnvironment.js.flow +506 -0
  83. package/multi-actor-environment/MultiActorEnvironmentTypes.js.flow +261 -0
  84. package/multi-actor-environment/index.js.flow +26 -0
  85. package/mutations/RelayDeclarativeMutationConfig.js.flow +32 -26
  86. package/mutations/RelayRecordProxy.js.flow +4 -5
  87. package/mutations/RelayRecordSourceMutator.js.flow +4 -6
  88. package/mutations/RelayRecordSourceProxy.js.flow +19 -10
  89. package/mutations/RelayRecordSourceSelectorProxy.js.flow +22 -7
  90. package/mutations/applyOptimisticMutation.js.flow +13 -14
  91. package/mutations/commitLocalUpdate.js.flow +1 -1
  92. package/mutations/commitMutation.js.flow +35 -46
  93. package/mutations/readUpdatableQuery_EXPERIMENTAL.js.flow +309 -0
  94. package/mutations/validateMutation.js.flow +28 -16
  95. package/network/ConvertToExecuteFunction.js.flow +2 -2
  96. package/network/RelayNetwork.js.flow +4 -5
  97. package/network/RelayNetworkTypes.js.flow +17 -8
  98. package/network/RelayObservable.js.flow +1 -1
  99. package/network/RelayQueryResponseCache.js.flow +34 -20
  100. package/network/wrapNetworkWithLogObserver.js.flow +100 -0
  101. package/package.json +3 -2
  102. package/query/GraphQLTag.js.flow +9 -9
  103. package/query/PreloadableQueryRegistry.js.flow +2 -1
  104. package/query/fetchQuery.js.flow +11 -13
  105. package/query/fetchQueryInternal.js.flow +6 -9
  106. package/query/fetchQuery_DEPRECATED.js.flow +6 -6
  107. package/relay-runtime.js +2 -2
  108. package/relay-runtime.min.js +2 -2
  109. package/store/ClientID.js.flow +14 -3
  110. package/store/DataChecker.js.flow +162 -67
  111. package/store/{RelayModernQueryExecutor.js.flow → OperationExecutor.js.flow} +616 -283
  112. package/store/RelayConcreteVariables.js.flow +27 -5
  113. package/store/RelayModernEnvironment.js.flow +176 -235
  114. package/store/RelayModernFragmentSpecResolver.js.flow +55 -31
  115. package/store/RelayModernOperationDescriptor.js.flow +12 -7
  116. package/store/RelayModernRecord.js.flow +67 -11
  117. package/store/RelayModernSelector.js.flow +24 -14
  118. package/store/RelayModernStore.js.flow +72 -36
  119. package/store/RelayOperationTracker.js.flow +59 -43
  120. package/store/RelayOptimisticRecordSource.js.flow +2 -2
  121. package/store/RelayPublishQueue.js.flow +79 -34
  122. package/store/RelayReader.js.flow +351 -72
  123. package/store/RelayRecordSource.js.flow +72 -6
  124. package/store/RelayReferenceMarker.js.flow +60 -33
  125. package/store/RelayResponseNormalizer.js.flow +288 -102
  126. package/store/RelayStoreReactFlightUtils.js.flow +9 -13
  127. package/store/RelayStoreSubscriptions.js.flow +19 -11
  128. package/store/RelayStoreTypes.js.flow +210 -44
  129. package/store/RelayStoreUtils.js.flow +25 -11
  130. package/store/ResolverCache.js.flow +249 -0
  131. package/store/ResolverFragments.js.flow +121 -0
  132. package/store/StoreInspector.js.flow +2 -2
  133. package/store/TypeID.js.flow +1 -1
  134. package/store/ViewerPattern.js.flow +2 -2
  135. package/store/cloneRelayHandleSourceField.js.flow +5 -6
  136. package/store/cloneRelayScalarHandleSourceField.js.flow +5 -6
  137. package/store/createFragmentSpecResolver.js.flow +3 -4
  138. package/store/createRelayContext.js.flow +3 -3
  139. package/store/defaultGetDataID.js.flow +3 -1
  140. package/store/normalizeRelayPayload.js.flow +6 -7
  141. package/store/readInlineData.js.flow +7 -8
  142. package/subscription/requestSubscription.js.flow +54 -27
  143. package/util/NormalizationNode.js.flow +16 -3
  144. package/util/ReaderNode.js.flow +38 -2
  145. package/util/RelayConcreteNode.js.flow +4 -0
  146. package/util/RelayFeatureFlags.js.flow +24 -8
  147. package/util/RelayProfiler.js.flow +22 -194
  148. package/util/RelayReplaySubject.js.flow +9 -9
  149. package/util/RelayRuntimeTypes.js.flow +73 -4
  150. package/util/StringInterner.js.flow +69 -0
  151. package/util/createPayloadFor3DField.js.flow +3 -3
  152. package/util/deepFreeze.js.flow +2 -1
  153. package/util/getFragmentIdentifier.js.flow +27 -15
  154. package/util/getOperation.js.flow +2 -2
  155. package/util/getPaginationMetadata.js.flow +72 -0
  156. package/util/getPaginationVariables.js.flow +108 -0
  157. package/util/getPendingOperationsForFragment.js.flow +62 -0
  158. package/util/getRefetchMetadata.js.flow +79 -0
  159. package/util/getRelayHandleKey.js.flow +1 -2
  160. package/util/getRequestIdentifier.js.flow +3 -3
  161. package/util/getValueAtPath.js.flow +46 -0
  162. package/util/isEmptyObject.js.flow +2 -1
  163. package/util/registerEnvironmentWithDevTools.js.flow +33 -0
  164. package/util/resolveImmediate.js.flow +1 -1
  165. package/util/withDuration.js.flow +32 -0
  166. package/lib/store/RelayRecordSourceMapImpl.js +0 -107
  167. package/lib/store/RelayStoreSubscriptionsUsingMapByID.js +0 -318
  168. package/store/RelayRecordSourceMapImpl.js.flow +0 -91
  169. package/store/RelayStoreSubscriptionsUsingMapByID.js.flow +0 -283
@@ -12,15 +12,6 @@
12
12
 
13
13
  'use strict';
14
14
 
15
- const RelayDeclarativeMutationConfig = require('../mutations/RelayDeclarativeMutationConfig');
16
-
17
- const warning = require('warning');
18
-
19
- const {getRequest} = require('../query/GraphQLTag');
20
- const {
21
- createOperationDescriptor,
22
- } = require('../store/RelayModernOperationDescriptor');
23
-
24
15
  import type {DeclarativeMutationConfig} from '../mutations/RelayDeclarativeMutationConfig';
25
16
  import type {GraphQLTaggedNode} from '../query/GraphQLTag';
26
17
  import type {
@@ -33,7 +24,33 @@ import type {
33
24
  Variables,
34
25
  } from '../util/RelayRuntimeTypes';
35
26
 
36
- export type GraphQLSubscriptionConfig<TSubscriptionPayload> = {|
27
+ const RelayDeclarativeMutationConfig = require('../mutations/RelayDeclarativeMutationConfig');
28
+ const {getRequest} = require('../query/GraphQLTag');
29
+ const {
30
+ createOperationDescriptor,
31
+ } = require('../store/RelayModernOperationDescriptor');
32
+ const {createReaderSelector} = require('../store/RelayModernSelector');
33
+ const RelayFeatureFlags = require('../util/RelayFeatureFlags');
34
+ const warning = require('warning');
35
+
36
+ export type SubscriptionParameters = {|
37
+ +response: {...},
38
+ +variables: interface {},
39
+ +rawResponse?: {...},
40
+ |};
41
+
42
+ export type GraphQLSubscriptionConfig<T: SubscriptionParameters> = {|
43
+ configs?: Array<DeclarativeMutationConfig>,
44
+ cacheConfig?: CacheConfig,
45
+ subscription: GraphQLTaggedNode,
46
+ variables: T['variables'],
47
+ onCompleted?: ?() => void,
48
+ onError?: ?(error: Error) => void,
49
+ onNext?: ?(response: ?T['response']) => void,
50
+ updater?: ?SelectorStoreUpdater<T['response']>,
51
+ |};
52
+
53
+ export type DEPRECATED_GraphQLSubscriptionConfig<TSubscriptionPayload> = {|
37
54
  configs?: Array<DeclarativeMutationConfig>,
38
55
  cacheConfig?: CacheConfig,
39
56
  subscription: GraphQLTaggedNode,
@@ -41,25 +58,19 @@ export type GraphQLSubscriptionConfig<TSubscriptionPayload> = {|
41
58
  onCompleted?: ?() => void,
42
59
  onError?: ?(error: Error) => void,
43
60
  onNext?: ?(response: ?TSubscriptionPayload) => void,
44
- updater?: ?SelectorStoreUpdater,
61
+ updater?: ?SelectorStoreUpdater<TSubscriptionPayload>,
45
62
  |};
46
63
 
47
64
  function requestSubscription<TSubscriptionPayload>(
48
65
  environment: IEnvironment,
49
- config: GraphQLSubscriptionConfig<TSubscriptionPayload>,
66
+ config: DEPRECATED_GraphQLSubscriptionConfig<TSubscriptionPayload>,
50
67
  ): Disposable {
51
68
  const subscription = getRequest(config.subscription);
52
69
  if (subscription.params.operationKind !== 'subscription') {
53
70
  throw new Error('requestSubscription: Must use Subscription operation');
54
71
  }
55
- const {
56
- configs,
57
- onCompleted,
58
- onError,
59
- onNext,
60
- variables,
61
- cacheConfig,
62
- } = config;
72
+ const {configs, onCompleted, onError, onNext, variables, cacheConfig} =
73
+ config;
63
74
  const operation = createOperationDescriptor(
64
75
  subscription,
65
76
  variables,
@@ -81,17 +92,33 @@ function requestSubscription<TSubscriptionPayload>(
81
92
  : config;
82
93
 
83
94
  const sub = environment
84
- .execute({
95
+ .executeSubscription({
85
96
  operation,
86
97
  updater,
87
98
  })
88
- .map(() => {
89
- const data = environment.lookup(operation.fragment).data;
90
- // $FlowFixMe[incompatible-cast]
91
- return (data: TSubscriptionPayload);
92
- })
93
99
  .subscribe({
94
- next: onNext,
100
+ next: responses => {
101
+ if (onNext != null) {
102
+ let selector = operation.fragment;
103
+ let nextID;
104
+ if (Array.isArray(responses)) {
105
+ nextID = responses[0]?.extensions?.__relay_subscription_root_id;
106
+ } else {
107
+ nextID = responses.extensions?.__relay_subscription_root_id;
108
+ }
109
+ if (typeof nextID === 'string') {
110
+ selector = createReaderSelector(
111
+ selector.node,
112
+ nextID,
113
+ selector.variables,
114
+ selector.owner,
115
+ );
116
+ }
117
+ const data = environment.lookup(selector).data;
118
+ // $FlowFixMe[incompatible-cast]
119
+ onNext((data: TSubscriptionPayload));
120
+ }
121
+ },
95
122
  error: onError,
96
123
  complete: onCompleted,
97
124
  });
@@ -87,7 +87,7 @@ export type NormalizationInlineFragment = {|
87
87
 
88
88
  export type NormalizationFragmentSpread = {|
89
89
  +kind: 'FragmentSpread',
90
- +fragment: NormalizationNode,
90
+ +fragment: NormalizationSplitOperation,
91
91
  +args: ?$ReadOnlyArray<NormalizationArgument>,
92
92
  |};
93
93
 
@@ -102,7 +102,13 @@ export type NormalizationLinkedField = {|
102
102
  +selections: $ReadOnlyArray<NormalizationSelection>,
103
103
  |};
104
104
 
105
+ export type NormalizationActorChange = {|
106
+ +kind: 'ActorChange',
107
+ +linkedField: NormalizationLinkedField,
108
+ |};
109
+
105
110
  export type NormalizationModuleImport = {|
111
+ +args: ?$ReadOnlyArray<NormalizationArgument>,
106
112
  +kind: 'ModuleImport',
107
113
  +documentName: string,
108
114
  +fragmentPropName: string,
@@ -154,6 +160,12 @@ export type NormalizationFlightField = {|
154
160
  +storageKey: ?string,
155
161
  |};
156
162
 
163
+ export type NormalizationClientComponent = {|
164
+ +args?: ?$ReadOnlyArray<NormalizationArgument>,
165
+ +kind: 'ClientComponent',
166
+ +fragment: NormalizationNode,
167
+ |};
168
+
157
169
  export type NormalizationTypeDiscriminator = {|
158
170
  +kind: 'TypeDiscriminator',
159
171
  +abstractKey: string,
@@ -161,6 +173,7 @@ export type NormalizationTypeDiscriminator = {|
161
173
 
162
174
  export type NormalizationSelection =
163
175
  | NormalizationCondition
176
+ | NormalizationClientComponent
164
177
  | NormalizationClientExtension
165
178
  | NormalizationDefer
166
179
  | NormalizationField
@@ -170,9 +183,11 @@ export type NormalizationSelection =
170
183
  | NormalizationInlineFragment
171
184
  | NormalizationModuleImport
172
185
  | NormalizationStream
186
+ | NormalizationActorChange
173
187
  | NormalizationTypeDiscriminator;
174
188
 
175
189
  export type NormalizationSplitOperation = {|
190
+ +argumentDefinitions?: $ReadOnlyArray<NormalizationLocalArgumentDefinition>,
176
191
  +kind: 'SplitOperation',
177
192
  +name: string,
178
193
  +metadata: ?{+[key: string]: mixed, ...},
@@ -183,8 +198,6 @@ export type NormalizationStream = {|
183
198
  +if: string | null,
184
199
  +kind: 'Stream',
185
200
  +label: string,
186
- +useCustomizedBatch: string | null,
187
- +metadata: ?{+[key: string]: mixed, ...},
188
201
  +selections: $ReadOnlyArray<NormalizationSelection>,
189
202
  |};
190
203
 
@@ -108,7 +108,10 @@ export type ReaderClientExtension = {|
108
108
  +selections: $ReadOnlyArray<ReaderSelection>,
109
109
  |};
110
110
 
111
- export type ReaderField = ReaderScalarField | ReaderLinkedField;
111
+ export type ReaderField =
112
+ | ReaderScalarField
113
+ | ReaderLinkedField
114
+ | ReaderRelayResolver;
112
115
 
113
116
  export type ReaderRootArgument = {|
114
117
  +kind: 'RootArgument',
@@ -133,7 +136,17 @@ export type ReaderLinkedField = {|
133
136
  +selections: $ReadOnlyArray<ReaderSelection>,
134
137
  |};
135
138
 
139
+ export type ReaderActorChange = {|
140
+ +kind: 'ActorChange',
141
+ +alias: ?string,
142
+ +name: string,
143
+ +storageKey: ?string,
144
+ +args: ?$ReadOnlyArray<ReaderArgument>,
145
+ +fragmentSpread: ReaderFragmentSpread,
146
+ |};
147
+
136
148
  export type ReaderModuleImport = {|
149
+ +args?: ?$ReadOnlyArray<ReaderArgument>,
137
150
  +kind: 'ModuleImport',
138
151
  +documentName: string,
139
152
  +fragmentPropName: string,
@@ -206,18 +219,41 @@ export type ReaderRequiredField = {|
206
219
  +path: string,
207
220
  |};
208
221
 
222
+ export type ReaderRelayResolver = {|
223
+ +kind: 'RelayResolver',
224
+ +alias: ?string,
225
+ +name: string,
226
+ +fragment: ReaderFragmentSpread,
227
+ +resolverModule: (rootKey: {
228
+ +$data?: any, // flowlint-line unclear-type:off
229
+ +$fragmentSpreads: any, // flowlint-line unclear-type:off
230
+ +$fragmentRefs: any, // flowlint-line unclear-type:off
231
+ ...
232
+ }) => mixed,
233
+ |};
234
+
235
+ export type ReaderClientEdge = {|
236
+ +kind: 'ClientEdge',
237
+ +linkedField: ReaderLinkedField,
238
+ +operation: ConcreteRequest,
239
+ +backingField: ReaderRelayResolver | ReaderClientExtension,
240
+ |};
241
+
209
242
  export type ReaderSelection =
210
243
  | ReaderCondition
244
+ | ReaderClientEdge
211
245
  | ReaderClientExtension
212
246
  | ReaderDefer
213
247
  | ReaderField
248
+ | ReaderActorChange
214
249
  | ReaderFlightField
215
250
  | ReaderFragmentSpread
216
251
  | ReaderInlineDataFragmentSpread
217
252
  | ReaderInlineFragment
218
253
  | ReaderModuleImport
219
254
  | ReaderStream
220
- | ReaderRequiredField;
255
+ | ReaderRequiredField
256
+ | ReaderRelayResolver;
221
257
 
222
258
  export type ReaderVariableArgument = {|
223
259
  +kind: 'Variable',
@@ -67,7 +67,10 @@ export type GeneratedNode =
67
67
  | NormalizationSplitOperation;
68
68
 
69
69
  const RelayConcreteNode = {
70
+ ACTOR_CHANGE: 'ActorChange',
70
71
  CONDITION: 'Condition',
72
+ CLIENT_COMPONENT: 'ClientComponent',
73
+ CLIENT_EDGE: 'ClientEdge',
71
74
  CLIENT_EXTENSION: 'ClientExtension',
72
75
  DEFER: 'Defer',
73
76
  CONNECTION: 'Connection',
@@ -83,6 +86,7 @@ const RelayConcreteNode = {
83
86
  LIST_VALUE: 'ListValue',
84
87
  LOCAL_ARGUMENT: 'LocalArgument',
85
88
  MODULE_IMPORT: 'ModuleImport',
89
+ RELAY_RESOLVER: 'RelayResolver',
86
90
  REQUIRED_FIELD: 'RequiredField',
87
91
  OBJECT_VALUE: 'ObjectValue',
88
92
  OPERATION: 'Operation',
@@ -4,7 +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
- * @flow strict
7
+ * @flow strict-local
8
8
  * @format
9
9
  */
10
10
 
@@ -12,34 +12,50 @@
12
12
 
13
13
  'use strict';
14
14
 
15
- type FeatureFlags = {|
15
+ import type {Disposable} from '../util/RelayRuntimeTypes';
16
+
17
+ export type FeatureFlags = {|
18
+ DELAY_CLEANUP_OF_PENDING_PRELOAD_QUERIES: boolean,
19
+ ENABLE_CLIENT_EDGES: boolean,
16
20
  ENABLE_VARIABLE_CONNECTION_KEY: boolean,
17
21
  ENABLE_PARTIAL_RENDERING_DEFAULT: boolean,
18
- ENABLE_RELAY_CONTAINERS_SUSPENSE: boolean,
19
- ENABLE_PRECISE_TYPE_REFINEMENT: boolean,
20
22
  ENABLE_REACT_FLIGHT_COMPONENT_FIELD: boolean,
21
23
  ENABLE_REQUIRED_DIRECTIVES: boolean | string,
24
+ ENABLE_RELAY_RESOLVERS: boolean,
22
25
  ENABLE_GETFRAGMENTIDENTIFIER_OPTIMIZATION: boolean,
23
26
  ENABLE_FRIENDLY_QUERY_NAME_GQL_URL: boolean,
24
- ENABLE_STORE_SUBSCRIPTIONS_REFACTOR: boolean,
25
27
  ENABLE_LOAD_QUERY_REQUEST_DEDUPING: boolean,
26
28
  ENABLE_DO_NOT_WRAP_LIVE_QUERY: boolean,
27
29
  ENABLE_NOTIFY_SUBSCRIPTION: boolean,
30
+ BATCH_ASYNC_MODULE_UPDATES_FN: ?(() => void) => Disposable,
31
+ ENABLE_CONTAINERS_SUBSCRIBE_ON_COMMIT: boolean,
32
+ ENABLE_QUERY_RENDERER_OFFSCREEN_SUPPORT: boolean,
33
+ MAX_DATA_ID_LENGTH: ?number,
34
+ REFACTOR_SUSPENSE_RESOURCE: boolean,
35
+ STRING_INTERN_LEVEL: number,
36
+ USE_REACT_CACHE: boolean,
28
37
  |};
29
38
 
30
39
  const RelayFeatureFlags: FeatureFlags = {
40
+ DELAY_CLEANUP_OF_PENDING_PRELOAD_QUERIES: false,
41
+ ENABLE_CLIENT_EDGES: false,
31
42
  ENABLE_VARIABLE_CONNECTION_KEY: false,
32
43
  ENABLE_PARTIAL_RENDERING_DEFAULT: true,
33
- ENABLE_RELAY_CONTAINERS_SUSPENSE: true,
34
- ENABLE_PRECISE_TYPE_REFINEMENT: false,
35
44
  ENABLE_REACT_FLIGHT_COMPONENT_FIELD: false,
36
45
  ENABLE_REQUIRED_DIRECTIVES: false,
46
+ ENABLE_RELAY_RESOLVERS: false,
37
47
  ENABLE_GETFRAGMENTIDENTIFIER_OPTIMIZATION: false,
38
48
  ENABLE_FRIENDLY_QUERY_NAME_GQL_URL: false,
39
- ENABLE_STORE_SUBSCRIPTIONS_REFACTOR: false,
40
49
  ENABLE_LOAD_QUERY_REQUEST_DEDUPING: true,
41
50
  ENABLE_DO_NOT_WRAP_LIVE_QUERY: false,
42
51
  ENABLE_NOTIFY_SUBSCRIPTION: false,
52
+ BATCH_ASYNC_MODULE_UPDATES_FN: null,
53
+ ENABLE_CONTAINERS_SUBSCRIBE_ON_COMMIT: false,
54
+ ENABLE_QUERY_RENDERER_OFFSCREEN_SUPPORT: false,
55
+ MAX_DATA_ID_LENGTH: null,
56
+ REFACTOR_SUSPENSE_RESOURCE: true,
57
+ STRING_INTERN_LEVEL: 0,
58
+ USE_REACT_CACHE: false,
43
59
  };
44
60
 
45
61
  module.exports = RelayFeatureFlags;
@@ -12,25 +12,15 @@
12
12
 
13
13
  'use strict';
14
14
 
15
- type Handler = (name: string, callback: () => void) => void;
16
- type ProfileHandler = (name: string, state?: any) => (error?: Error) => void;
15
+ type EventName = 'fetchRelayQuery';
16
+ type ProfileHandler = (name: EventName, state?: any) => (error?: Error) => void;
17
17
 
18
- function emptyFunction() {}
18
+ const profileHandlersByName: {|
19
+ [name: EventName]: Array<ProfileHandler>,
20
+ |} = {};
19
21
 
20
- const aggregateHandlersByName: {[name: string]: Array<Handler>, ...} = {
21
- '*': [],
22
- };
23
- const profileHandlersByName: {[name: string]: Array<ProfileHandler>, ...} = {
24
- '*': [],
25
- };
26
-
27
- const NOT_INVOKED = {};
28
- const defaultProfiler = {stop: emptyFunction};
29
- const shouldInstrument = name => {
30
- if (__DEV__) {
31
- return true;
32
- }
33
- return name.charAt(0) !== '@';
22
+ const defaultProfiler = {
23
+ stop() {},
34
24
  };
35
25
 
36
26
  /**
@@ -60,154 +50,8 @@ const shouldInstrument = name => {
60
50
  * console.log(`Duration (${name})`, performance.now() - start);
61
51
  * }
62
52
  * });
63
- *
64
- * In order to reduce the impact on performance in production, instrumented
65
- * methods and profilers with names that begin with `@` will only be measured
66
- * if `__DEV__` is true. This should be used for very hot functions.
67
53
  */
68
54
  const RelayProfiler = {
69
- /**
70
- * Instruments methods on a class or object. This re-assigns the method in
71
- * order to preserve function names in stack traces (which are detected by
72
- * modern debuggers via heuristics). Example usage:
73
- *
74
- * const RelayStore = { primeCache: function() {...} };
75
- * RelayProfiler.instrumentMethods(RelayStore, {
76
- * primeCache: 'RelayStore.primeCache'
77
- * });
78
- *
79
- * RelayStore.primeCache.attachHandler(...);
80
- *
81
- * As a result, the methods will be replaced by wrappers that provide the
82
- * `attachHandler` and `detachHandler` methods.
83
- */
84
- instrumentMethods(
85
- object: Function | Object,
86
- names: {[key: string]: string, ...},
87
- ): void {
88
- for (const key in names) {
89
- if (names.hasOwnProperty(key)) {
90
- if (typeof object[key] === 'function') {
91
- object[key] = RelayProfiler.instrument(names[key], object[key]);
92
- }
93
- }
94
- }
95
- },
96
-
97
- /**
98
- * Wraps the supplied function with one that provides the `attachHandler` and
99
- * `detachHandler` methods. Example usage:
100
- *
101
- * const printRelayQuery =
102
- * RelayProfiler.instrument('printRelayQuery', printRelayQuery);
103
- *
104
- * printRelayQuery.attachHandler(...);
105
- *
106
- * NOTE: The instrumentation assumes that no handlers are attached or detached
107
- * in the course of executing another handler.
108
- */
109
- instrument<T: Function>(name: string, originalFunction: T): T {
110
- if (!shouldInstrument(name)) {
111
- originalFunction.attachHandler = emptyFunction;
112
- originalFunction.detachHandler = emptyFunction;
113
- return originalFunction;
114
- }
115
- if (!aggregateHandlersByName.hasOwnProperty(name)) {
116
- aggregateHandlersByName[name] = [];
117
- }
118
- const catchallHandlers = aggregateHandlersByName['*'];
119
- const aggregateHandlers = aggregateHandlersByName[name];
120
- const handlers: Array<Handler> = [];
121
- const contexts: Array<[number, number, number, any, any, any]> = [];
122
- const invokeHandlers = function() {
123
- const context = contexts[contexts.length - 1];
124
- if (context[0]) {
125
- context[0]--;
126
- catchallHandlers[context[0]](name, invokeHandlers);
127
- } else if (context[1]) {
128
- context[1]--;
129
- aggregateHandlers[context[1]](name, invokeHandlers);
130
- } else if (context[2]) {
131
- context[2]--;
132
- handlers[context[2]](name, invokeHandlers);
133
- } else {
134
- context[5] = originalFunction.apply(context[3], context[4]);
135
- }
136
- };
137
- const instrumentedCallback = function() {
138
- let returnValue;
139
- if (
140
- aggregateHandlers.length === 0 &&
141
- handlers.length === 0 &&
142
- catchallHandlers.length === 0
143
- ) {
144
- returnValue = originalFunction.apply(this, arguments);
145
- } else {
146
- contexts.push([
147
- catchallHandlers.length,
148
- aggregateHandlers.length,
149
- handlers.length,
150
- this,
151
- arguments,
152
- NOT_INVOKED,
153
- ]);
154
- invokeHandlers();
155
- const context = contexts.pop();
156
- returnValue = context[5];
157
- if (returnValue === NOT_INVOKED) {
158
- throw new Error(
159
- 'RelayProfiler: Handler did not invoke original function.',
160
- );
161
- }
162
- }
163
- return returnValue;
164
- };
165
- instrumentedCallback.attachHandler = function(handler: Handler): void {
166
- handlers.push(handler);
167
- };
168
- instrumentedCallback.detachHandler = function(handler: Handler): void {
169
- removeFromArray(handlers, handler);
170
- };
171
- instrumentedCallback.displayName = '(instrumented ' + name + ')';
172
- return (instrumentedCallback: any);
173
- },
174
-
175
- /**
176
- * Attaches a handler to all methods instrumented with the supplied name.
177
- *
178
- * function createRenderer() {
179
- * return RelayProfiler.instrument('render', function() {...});
180
- * }
181
- * const renderA = createRenderer();
182
- * const renderB = createRenderer();
183
- *
184
- * // Only profiles `renderA`.
185
- * renderA.attachHandler(...);
186
- *
187
- * // Profiles both `renderA` and `renderB`.
188
- * RelayProfiler.attachAggregateHandler('render', ...);
189
- *
190
- */
191
- attachAggregateHandler(name: string, handler: Handler): void {
192
- if (shouldInstrument(name)) {
193
- if (!aggregateHandlersByName.hasOwnProperty(name)) {
194
- aggregateHandlersByName[name] = [];
195
- }
196
- aggregateHandlersByName[name].push(handler);
197
- }
198
- },
199
-
200
- /**
201
- * Detaches a handler attached via `attachAggregateHandler`.
202
- */
203
- detachAggregateHandler(name: string, handler: Handler): void {
204
- if (shouldInstrument(name)) {
205
- if (aggregateHandlersByName.hasOwnProperty(name)) {
206
- removeFromArray(aggregateHandlersByName[name], handler);
207
- }
208
- }
209
- },
210
-
211
55
  /**
212
56
  * Instruments profiling for arbitrarily asynchronous code by a name.
213
57
  *
@@ -221,28 +65,17 @@ const RelayProfiler = {
221
65
  * Arbitrary state can also be passed into `profile` as a second argument. The
222
66
  * attached profile handlers will receive this as the second argument.
223
67
  */
224
- profile(name: string, state?: any): {stop: (error?: Error) => void, ...} {
225
- const hasCatchAllHandlers = profileHandlersByName['*'].length > 0;
226
- const hasNamedHandlers = profileHandlersByName.hasOwnProperty(name);
227
- if (hasNamedHandlers || hasCatchAllHandlers) {
228
- const profileHandlers =
229
- hasNamedHandlers && hasCatchAllHandlers
230
- ? profileHandlersByName[name].concat(profileHandlersByName['*'])
231
- : hasNamedHandlers
232
- ? profileHandlersByName[name]
233
- : profileHandlersByName['*'];
234
- let stopHandlers;
235
- for (let ii = profileHandlers.length - 1; ii >= 0; ii--) {
236
- const profileHandler = profileHandlers[ii];
237
- const stopHandler = profileHandler(name, state);
238
- stopHandlers = stopHandlers || [];
68
+ profile(name: EventName, state?: any): {stop: (error?: Error) => void, ...} {
69
+ const handlers = profileHandlersByName[name];
70
+ if (handlers && handlers.length > 0) {
71
+ const stopHandlers = [];
72
+ for (let ii = handlers.length - 1; ii >= 0; ii--) {
73
+ const stopHandler = handlers[ii](name, state);
239
74
  stopHandlers.unshift(stopHandler);
240
75
  }
241
76
  return {
242
77
  stop(error?: Error): void {
243
- if (stopHandlers) {
244
- stopHandlers.forEach(stopHandler => stopHandler(error));
245
- }
78
+ stopHandlers.forEach(stopHandler => stopHandler(error));
246
79
  },
247
80
  };
248
81
  }
@@ -250,26 +83,21 @@ const RelayProfiler = {
250
83
  },
251
84
 
252
85
  /**
253
- * Attaches a handler to profiles with the supplied name. You can also
254
- * attach to the special name '*' which is a catch all.
86
+ * Attaches a handler to profiles with the supplied name.
255
87
  */
256
- attachProfileHandler(name: string, handler: ProfileHandler): void {
257
- if (shouldInstrument(name)) {
258
- if (!profileHandlersByName.hasOwnProperty(name)) {
259
- profileHandlersByName[name] = [];
260
- }
261
- profileHandlersByName[name].push(handler);
88
+ attachProfileHandler(name: EventName, handler: ProfileHandler): void {
89
+ if (!profileHandlersByName.hasOwnProperty(name)) {
90
+ profileHandlersByName[name] = [];
262
91
  }
92
+ profileHandlersByName[name].push(handler);
263
93
  },
264
94
 
265
95
  /**
266
96
  * Detaches a handler attached via `attachProfileHandler`.
267
97
  */
268
- detachProfileHandler(name: string, handler: ProfileHandler): void {
269
- if (shouldInstrument(name)) {
270
- if (profileHandlersByName.hasOwnProperty(name)) {
271
- removeFromArray(profileHandlersByName[name], handler);
272
- }
98
+ detachProfileHandler(name: EventName, handler: ProfileHandler): void {
99
+ if (profileHandlersByName.hasOwnProperty(name)) {
100
+ removeFromArray(profileHandlersByName[name], handler);
273
101
  }
274
102
  },
275
103
  };
@@ -12,12 +12,11 @@
12
12
 
13
13
  'use strict';
14
14
 
15
- const RelayObservable = require('../network/RelayObservable');
15
+ import type {Observer, Sink, Subscription} from '../network/RelayObservable';
16
16
 
17
+ const RelayObservable = require('../network/RelayObservable');
17
18
  const invariant = require('invariant');
18
19
 
19
- import type {Observer, Sink, Subscription} from '../network/RelayObservable';
20
-
21
20
  type Event<T> =
22
21
  | {
23
22
  kind: 'next',
@@ -42,7 +41,7 @@ class RelayReplaySubject<T> {
42
41
  _events: Array<Event<T>> = [];
43
42
  _sinks: Set<Sink<T>> = new Set();
44
43
  _observable: RelayObservable<T>;
45
- _subscription: ?Subscription = null;
44
+ _subscription: Array<Subscription> = [];
46
45
 
47
46
  constructor() {
48
47
  this._observable = RelayObservable.create(sink => {
@@ -116,15 +115,16 @@ class RelayReplaySubject<T> {
116
115
  }
117
116
 
118
117
  subscribe(observer: Observer<T> | Sink<T>): Subscription {
119
- this._subscription = this._observable.subscribe(observer);
120
- return this._subscription;
118
+ const subscription = this._observable.subscribe(observer);
119
+ this._subscription.push(subscription);
120
+ return subscription;
121
121
  }
122
122
 
123
123
  unsubscribe() {
124
- if (this._subscription) {
125
- this._subscription.unsubscribe();
126
- this._subscription = null;
124
+ for (const subscription of this._subscription) {
125
+ subscription.unsubscribe();
127
126
  }
127
+ this._subscription = [];
128
128
  }
129
129
 
130
130
  getObserverCount(): number {