relay-runtime 11.0.1 → 13.0.0-rc.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (169) hide show
  1. package/handlers/RelayDefaultHandlerProvider.js.flow +2 -2
  2. package/handlers/connection/ConnectionHandler.js.flow +8 -17
  3. package/handlers/connection/MutationHandlers.js.flow +7 -11
  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 +13 -19
  8. package/lib/handlers/connection/MutationHandlers.js +4 -7
  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 +10 -5
  25. package/lib/network/ConvertToExecuteFunction.js +2 -1
  26. package/lib/network/RelayNetwork.js +3 -2
  27. package/lib/network/RelayQueryResponseCache.js +21 -5
  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 +123 -54
  35. package/lib/store/{RelayModernQueryExecutor.js → OperationExecutor.js} +518 -200
  36. package/lib/store/RelayConcreteVariables.js +26 -8
  37. package/lib/store/RelayExperimentalGraphResponseHandler.js +153 -0
  38. package/lib/store/RelayExperimentalGraphResponseTransform.js +391 -0
  39. package/lib/store/RelayModernEnvironment.js +175 -240
  40. package/lib/store/RelayModernFragmentSpecResolver.js +52 -26
  41. package/lib/store/RelayModernOperationDescriptor.js +2 -1
  42. package/lib/store/RelayModernRecord.js +47 -12
  43. package/lib/store/RelayModernSelector.js +14 -8
  44. package/lib/store/RelayModernStore.js +56 -28
  45. package/lib/store/RelayOperationTracker.js +34 -24
  46. package/lib/store/RelayPublishQueue.js +41 -13
  47. package/lib/store/RelayReader.js +288 -48
  48. package/lib/store/RelayRecordSource.js +87 -3
  49. package/lib/store/RelayReferenceMarker.js +34 -22
  50. package/lib/store/RelayResponseNormalizer.js +211 -110
  51. package/lib/store/RelayStoreReactFlightUtils.js +4 -10
  52. package/lib/store/RelayStoreSubscriptions.js +14 -9
  53. package/lib/store/RelayStoreUtils.js +12 -7
  54. package/lib/store/ResolverCache.js +213 -0
  55. package/lib/store/ResolverFragments.js +61 -0
  56. package/lib/store/cloneRelayHandleSourceField.js +5 -4
  57. package/lib/store/cloneRelayScalarHandleSourceField.js +5 -4
  58. package/lib/store/createRelayContext.js +4 -2
  59. package/lib/store/readInlineData.js +6 -2
  60. package/lib/subscription/requestSubscription.js +34 -25
  61. package/lib/util/RelayConcreteNode.js +3 -0
  62. package/lib/util/RelayFeatureFlags.js +10 -4
  63. package/lib/util/RelayProfiler.js +17 -187
  64. package/lib/util/RelayReplaySubject.js +22 -7
  65. package/lib/util/RelayRuntimeTypes.js +0 -6
  66. package/lib/util/StringInterner.js +71 -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 +26 -16
  95. package/network/ConvertToExecuteFunction.js.flow +2 -2
  96. package/network/RelayNetwork.js.flow +4 -5
  97. package/network/RelayNetworkTypes.js.flow +5 -4
  98. package/network/RelayObservable.js.flow +1 -1
  99. package/network/RelayQueryResponseCache.js.flow +34 -21
  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 +141 -59
  111. package/store/{RelayModernQueryExecutor.js.flow → OperationExecutor.js.flow} +605 -303
  112. package/store/RelayConcreteVariables.js.flow +27 -8
  113. package/store/RelayExperimentalGraphResponseHandler.js.flow +124 -0
  114. package/store/RelayExperimentalGraphResponseTransform.js.flow +475 -0
  115. package/store/RelayModernEnvironment.js.flow +173 -240
  116. package/store/RelayModernFragmentSpecResolver.js.flow +55 -31
  117. package/store/RelayModernOperationDescriptor.js.flow +12 -7
  118. package/store/RelayModernRecord.js.flow +67 -11
  119. package/store/RelayModernSelector.js.flow +24 -14
  120. package/store/RelayModernStore.js.flow +66 -36
  121. package/store/RelayOperationTracker.js.flow +59 -43
  122. package/store/RelayOptimisticRecordSource.js.flow +2 -2
  123. package/store/RelayPublishQueue.js.flow +79 -34
  124. package/store/RelayReader.js.flow +351 -73
  125. package/store/RelayRecordSource.js.flow +72 -6
  126. package/store/RelayReferenceMarker.js.flow +40 -26
  127. package/store/RelayResponseNormalizer.js.flow +258 -99
  128. package/store/RelayStoreReactFlightUtils.js.flow +4 -11
  129. package/store/RelayStoreSubscriptions.js.flow +19 -11
  130. package/store/RelayStoreTypes.js.flow +209 -43
  131. package/store/RelayStoreUtils.js.flow +24 -11
  132. package/store/ResolverCache.js.flow +249 -0
  133. package/store/ResolverFragments.js.flow +121 -0
  134. package/store/StoreInspector.js.flow +2 -2
  135. package/store/TypeID.js.flow +1 -1
  136. package/store/ViewerPattern.js.flow +2 -2
  137. package/store/cloneRelayHandleSourceField.js.flow +5 -6
  138. package/store/cloneRelayScalarHandleSourceField.js.flow +5 -6
  139. package/store/createFragmentSpecResolver.js.flow +3 -4
  140. package/store/createRelayContext.js.flow +3 -3
  141. package/store/normalizeRelayPayload.js.flow +6 -7
  142. package/store/readInlineData.js.flow +7 -8
  143. package/subscription/requestSubscription.js.flow +53 -41
  144. package/util/NormalizationNode.js.flow +10 -3
  145. package/util/ReaderNode.js.flow +38 -2
  146. package/util/RelayConcreteNode.js.flow +5 -0
  147. package/util/RelayFeatureFlags.js.flow +24 -10
  148. package/util/RelayProfiler.js.flow +22 -194
  149. package/util/RelayReplaySubject.js.flow +9 -9
  150. package/util/RelayRuntimeTypes.js.flow +72 -3
  151. package/util/StringInterner.js.flow +69 -0
  152. package/util/createPayloadFor3DField.js.flow +3 -3
  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 +1 -0
  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,23 +12,23 @@
12
12
 
13
13
  'use strict';
14
14
 
15
- const RelayFeatureFlags = require('../util/RelayFeatureFlags');
16
- const RelayReader = require('./RelayReader');
17
-
18
- const deepFreeze = require('../util/deepFreeze');
19
- const hasOverlappingIDs = require('./hasOverlappingIDs');
20
- const recycleNodesInto = require('../util/recycleNodesInto');
21
-
22
15
  import type {Disposable} from '../util/RelayRuntimeTypes';
23
16
  import type {
17
+ DataIDSet,
24
18
  LogFunction,
25
19
  OperationDescriptor,
26
- DataIDSet,
27
20
  RecordSource,
28
21
  RequestDescriptor,
29
22
  Snapshot,
30
23
  StoreSubscriptions,
31
24
  } from './RelayStoreTypes';
25
+ import type {ResolverCache} from './ResolverCache';
26
+
27
+ const deepFreeze = require('../util/deepFreeze');
28
+ const recycleNodesInto = require('../util/recycleNodesInto');
29
+ const RelayFeatureFlags = require('../util/RelayFeatureFlags');
30
+ const hasOverlappingIDs = require('./hasOverlappingIDs');
31
+ const RelayReader = require('./RelayReader');
32
32
 
33
33
  type Subscription = {|
34
34
  callback: (snapshot: Snapshot) => void,
@@ -40,10 +40,12 @@ type Subscription = {|
40
40
  class RelayStoreSubscriptions implements StoreSubscriptions {
41
41
  _subscriptions: Set<Subscription>;
42
42
  __log: ?LogFunction;
43
+ _resolverCache: ResolverCache;
43
44
 
44
- constructor(log?: ?LogFunction) {
45
+ constructor(log?: ?LogFunction, resolverCache: ResolverCache) {
45
46
  this._subscriptions = new Set();
46
47
  this.__log = log;
48
+ this._resolverCache = resolverCache;
47
49
  }
48
50
 
49
51
  subscribe(
@@ -77,7 +79,11 @@ class RelayStoreSubscriptions implements StoreSubscriptions {
77
79
  return;
78
80
  }
79
81
  const snapshot = subscription.snapshot;
80
- const backup = RelayReader.read(source, snapshot.selector);
82
+ const backup = RelayReader.read(
83
+ source,
84
+ snapshot.selector,
85
+ this._resolverCache,
86
+ );
81
87
  const nextData = recycleNodesInto(snapshot.data, backup.data);
82
88
  (backup: $FlowFixMe).data = nextData; // backup owns the snapshot and can safely mutate
83
89
  subscription.backup = backup;
@@ -95,6 +101,7 @@ class RelayStoreSubscriptions implements StoreSubscriptions {
95
101
  subscription.snapshot = {
96
102
  data: subscription.snapshot.data,
97
103
  isMissingData: backup.isMissingData,
104
+ missingClientEdges: backup.missingClientEdges,
98
105
  seenRecords: backup.seenRecords,
99
106
  selector: backup.selector,
100
107
  missingRequiredFields: backup.missingRequiredFields,
@@ -150,12 +157,13 @@ class RelayStoreSubscriptions implements StoreSubscriptions {
150
157
  }
151
158
  let nextSnapshot: Snapshot =
152
159
  hasOverlappingUpdates || !backup
153
- ? RelayReader.read(source, snapshot.selector)
160
+ ? RelayReader.read(source, snapshot.selector, this._resolverCache)
154
161
  : backup;
155
162
  const nextData = recycleNodesInto(snapshot.data, nextSnapshot.data);
156
163
  nextSnapshot = ({
157
164
  data: nextData,
158
165
  isMissingData: nextSnapshot.isMissingData,
166
+ missingClientEdges: nextSnapshot.missingClientEdges,
159
167
  seenRecords: nextSnapshot.seenRecords,
160
168
  selector: nextSnapshot.selector,
161
169
  missingRequiredFields: nextSnapshot.missingRequiredFields,
@@ -12,23 +12,30 @@
12
12
 
13
13
  'use strict';
14
14
 
15
+ import type {
16
+ ActorIdentifier,
17
+ IActorEnvironment,
18
+ } from '../multi-actor-environment';
15
19
  import type {
16
20
  GraphQLResponse,
17
21
  INetwork,
18
22
  PayloadData,
19
23
  PayloadError,
20
- ReactFlightServerTree,
21
24
  ReactFlightServerError,
25
+ ReactFlightServerTree,
22
26
  UploadableMap,
23
27
  } from '../network/RelayNetworkTypes';
24
28
  import type RelayObservable from '../network/RelayObservable';
29
+ import type {GraphQLTaggedNode} from '../query/GraphQLTag';
30
+ import type {RequestIdentifier} from '../util/getRequestIdentifier';
25
31
  import type {
32
+ NormalizationArgument,
26
33
  NormalizationLinkedField,
27
34
  NormalizationRootNode,
28
35
  NormalizationScalarField,
29
36
  NormalizationSelectableNode,
30
37
  } from '../util/NormalizationNode';
31
- import type {ReaderFragment} from '../util/ReaderNode';
38
+ import type {ReaderClientEdge, ReaderFragment} from '../util/ReaderNode';
32
39
  import type {
33
40
  ConcreteRequest,
34
41
  RequestParameters,
@@ -37,17 +44,23 @@ import type {
37
44
  CacheConfig,
38
45
  DataID,
39
46
  Disposable,
47
+ OperationType,
40
48
  RenderPolicy,
41
49
  Variables,
42
50
  } from '../util/RelayRuntimeTypes';
43
- import type {RequestIdentifier} from '../util/getRequestIdentifier';
44
51
  import type {InvalidationState} from './RelayModernStore';
45
52
  import type RelayOperationTracker from './RelayOperationTracker';
46
53
  import type {RecordState} from './RelayRecordState';
47
54
 
48
- export opaque type FragmentReference = empty;
55
+ export opaque type FragmentType = empty;
49
56
  export type OperationTracker = RelayOperationTracker;
50
57
 
58
+ export type MutationParameters = {|
59
+ +response: {...},
60
+ +variables: interface {},
61
+ +rawResponse?: {...},
62
+ |};
63
+
51
64
  /*
52
65
  * An individual cached graph object.
53
66
  */
@@ -69,6 +82,7 @@ export type SingularReaderSelector = {|
69
82
  +kind: 'SingularReaderSelector',
70
83
  +dataID: DataID,
71
84
  +isWithinUnmatchedTypeRefinement: boolean,
85
+ +clientEdgeTraversalPath: ClientEdgeTraversalPath | null,
72
86
  +node: ReaderFragment,
73
87
  +owner: RequestDescriptor,
74
88
  +variables: Variables,
@@ -107,12 +121,26 @@ export type MissingRequiredFields =
107
121
  | {|action: 'THROW', field: MissingRequiredField|}
108
122
  | {|action: 'LOG', fields: Array<MissingRequiredField>|};
109
123
 
124
+ export type ClientEdgeTraversalInfo = {|
125
+ +readerClientEdge: ReaderClientEdge,
126
+ +clientEdgeDestinationID: DataID,
127
+ |};
128
+
129
+ export type ClientEdgeTraversalPath =
130
+ $ReadOnlyArray<ClientEdgeTraversalInfo | null>;
131
+
132
+ export type MissingClientEdgeRequestInfo = {|
133
+ +request: ConcreteRequest,
134
+ +clientEdgeDestinationID: DataID,
135
+ |};
136
+
110
137
  /**
111
138
  * A representation of a selector and its results at a particular point in time.
112
139
  */
113
140
  export type Snapshot = {|
114
141
  +data: ?SelectorData,
115
142
  +isMissingData: boolean,
143
+ +missingClientEdges: null | $ReadOnlyArray<MissingClientEdgeRequestInfo>,
116
144
  +seenRecords: DataIDSet,
117
145
  +selector: SingularReaderSelector,
118
146
  +missingRequiredFields: ?MissingRequiredFields,
@@ -144,6 +172,9 @@ export type Props = {[key: string]: mixed, ...};
144
172
  */
145
173
  export type RelayContext = {|
146
174
  environment: IEnvironment,
175
+ getEnvironmentForActor?: ?(
176
+ actorIdentifier: ActorIdentifier,
177
+ ) => IActorEnvironment,
147
178
  |};
148
179
 
149
180
  /**
@@ -190,7 +221,7 @@ export interface FragmentSpecResolver {
190
221
  * Subscribe to resolver updates.
191
222
  * Overrides existing callback (if one has been specified).
192
223
  */
193
- setCallback(callback: () => void): void;
224
+ setCallback(props: Props, callback: () => void): void;
194
225
  }
195
226
 
196
227
  /**
@@ -216,8 +247,10 @@ export interface MutableRecordSource extends RecordSource {
216
247
  }
217
248
 
218
249
  export type CheckOptions = {|
219
- target: MutableRecordSource,
220
250
  handlers: $ReadOnlyArray<MissingFieldHandler>,
251
+ defaultActorIdentifier: ActorIdentifier,
252
+ getTargetForActor: (actorIdentifier: ActorIdentifier) => MutableRecordSource,
253
+ getSourceForActor: (actorIdentifier: ActorIdentifier) => RecordSource,
221
254
  |};
222
255
 
223
256
  export type OperationAvailability =
@@ -332,6 +365,11 @@ export interface Store {
332
365
  invalidationState: InvalidationState,
333
366
  callback: () => void,
334
367
  ): Disposable;
368
+
369
+ /**
370
+ * Get the current write epoch
371
+ */
372
+ getEpoch(): number;
335
373
  }
336
374
 
337
375
  export interface StoreSubscriptions {
@@ -359,7 +397,7 @@ export interface StoreSubscriptions {
359
397
  /**
360
398
  * Notifies each subscription if the snapshot for the subscription selector has changed.
361
399
  * Mutates the updatedOwners array with any owners (RequestDescriptors) associated
362
- * with the subscriptions that were notifed; i.e. the owners affected by the changes.
400
+ * with the subscriptions that were notified; i.e. the owners affected by the changes.
363
401
  */
364
402
  updateSubscriptions(
365
403
  source: RecordSource,
@@ -427,6 +465,10 @@ export interface RecordSourceProxy {
427
465
  get(dataID: DataID): ?RecordProxy;
428
466
  getRoot(): RecordProxy;
429
467
  invalidateStore(): void;
468
+ readUpdatableQuery_EXPERIMENTAL<TQuery: OperationType>(
469
+ query: GraphQLTaggedNode,
470
+ variables: TQuery['variables'],
471
+ ): TQuery['response'];
430
472
  }
431
473
 
432
474
  export interface ReadOnlyRecordSourceProxy {
@@ -445,6 +487,23 @@ export interface RecordSourceSelectorProxy extends RecordSourceProxy {
445
487
  }
446
488
 
447
489
  export type LogEvent =
490
+ | {|
491
+ +name: 'suspense.fragment',
492
+ +data: mixed,
493
+ +fragment: ReaderFragment,
494
+ +isRelayHooks: boolean,
495
+ +isMissingData: boolean,
496
+ +isPromiseCached: boolean,
497
+ +pendingOperations: $ReadOnlyArray<RequestDescriptor>,
498
+ |}
499
+ | {|
500
+ +name: 'suspense.query',
501
+ +fetchPolicy: string,
502
+ +isPromiseCached: boolean,
503
+ +operation: OperationDescriptor,
504
+ +queryAvailability: ?OperationAvailability,
505
+ +renderPolicy: RenderPolicy,
506
+ |}
448
507
  | {|
449
508
  +name: 'queryresource.fetch',
450
509
  // ID of this query resource request and will be the same
@@ -456,7 +515,7 @@ export type LogEvent =
456
515
  // FetchPolicy from Relay Hooks
457
516
  +fetchPolicy: string,
458
517
  // RenderPolicy from Relay Hooks
459
- +renderPolicy: string,
518
+ +renderPolicy: RenderPolicy,
460
519
  +queryAvailability: OperationAvailability,
461
520
  +shouldFetch: boolean,
462
521
  |}
@@ -468,33 +527,67 @@ export type LogEvent =
468
527
  |}
469
528
  | {|
470
529
  +name: 'network.info',
471
- +transactionID: number,
530
+ +networkRequestId: number,
472
531
  +info: mixed,
473
532
  |}
474
533
  | {|
475
534
  +name: 'network.start',
476
- +transactionID: number,
535
+ +networkRequestId: number,
477
536
  +params: RequestParameters,
478
537
  +variables: Variables,
479
538
  +cacheConfig: CacheConfig,
480
539
  |}
481
540
  | {|
482
541
  +name: 'network.next',
483
- +transactionID: number,
542
+ +networkRequestId: number,
484
543
  +response: GraphQLResponse,
485
544
  |}
486
545
  | {|
487
546
  +name: 'network.error',
488
- +transactionID: number,
547
+ +networkRequestId: number,
489
548
  +error: Error,
490
549
  |}
491
550
  | {|
492
551
  +name: 'network.complete',
493
- +transactionID: number,
552
+ +networkRequestId: number,
494
553
  |}
495
554
  | {|
496
555
  +name: 'network.unsubscribe',
497
- +transactionID: number,
556
+ +networkRequestId: number,
557
+ |}
558
+ | {|
559
+ +name: 'execute.start',
560
+ +executeId: number,
561
+ +params: RequestParameters,
562
+ +variables: Variables,
563
+ +cacheConfig: CacheConfig,
564
+ |}
565
+ | {|
566
+ +name: 'execute.next',
567
+ +executeId: number,
568
+ +response: GraphQLResponse,
569
+ +duration: number,
570
+ |}
571
+ | {|
572
+ +name: 'execute.async.module',
573
+ +executeId: number,
574
+ +operationName: string,
575
+ +duration: number,
576
+ |}
577
+ | {|
578
+ +name: 'execute.flight.payload_deserialize',
579
+ +executeId: number,
580
+ +operationName: string,
581
+ +duration: number,
582
+ |}
583
+ | {|
584
+ +name: 'execute.error',
585
+ +executeId: number,
586
+ +error: Error,
587
+ |}
588
+ | {|
589
+ +name: 'execute.complete',
590
+ +executeId: number,
498
591
  |}
499
592
  | {|
500
593
  +name: 'store.publish',
@@ -584,11 +677,26 @@ export interface IEnvironment {
584
677
  */
585
678
  applyUpdate(optimisticUpdate: OptimisticUpdateFunction): Disposable;
586
679
 
680
+ /**
681
+ * Revert updates for the `update` function.
682
+ */
683
+ revertUpdate(update: OptimisticUpdateFunction): void;
684
+
685
+ /**
686
+ * Revert updates for the `update` function, and apply the `replacement` update.
687
+ */
688
+ replaceUpdate(
689
+ update: OptimisticUpdateFunction,
690
+ replacement: OptimisticUpdateFunction,
691
+ ): void;
692
+
587
693
  /**
588
694
  * Apply an optimistic mutation response and/or updater. The mutation can be
589
695
  * reverted by calling `dispose()` on the returned value.
590
696
  */
591
- applyMutation(optimisticConfig: OptimisticResponseConfig): Disposable;
697
+ applyMutation<TMutation: MutationParameters>(
698
+ optimisticConfig: OptimisticResponseConfig<TMutation>,
699
+ ): Disposable;
592
700
 
593
701
  /**
594
702
  * Commit an updater to the environment. This mutation cannot be reverted and
@@ -637,15 +745,27 @@ export interface IEnvironment {
637
745
  * responses may be returned (via `next`) over time followed by either
638
746
  * the request completing (`completed`) or an error (`error`).
639
747
  *
748
+ * Note: Observables are lazy, so calling this method will do nothing until
749
+ * the result is subscribed to: environment.execute({...}).subscribe({...}).
750
+ */
751
+ execute(config: {|
752
+ operation: OperationDescriptor,
753
+ |}): RelayObservable<GraphQLResponse>;
754
+
755
+ /**
756
+ * Send a subscription to the server with Observer semantics: one or more
757
+ * responses may be returned (via `next`) over time followed by either
758
+ * the request completing (`completed`) or an error (`error`).
759
+ *
640
760
  * Networks/servers that support subscriptions may choose to hold the
641
761
  * subscription open indefinitely such that `complete` is not called.
642
762
  *
643
763
  * Note: Observables are lazy, so calling this method will do nothing until
644
- * the result is subscribed to: environment.execute({...}).subscribe({...}).
764
+ * the result is subscribed to: environment.executeSubscription({...}).subscribe({...}).
645
765
  */
646
- execute(config: {|
766
+ executeSubscription<TMutation: MutationParameters>(config: {|
647
767
  operation: OperationDescriptor,
648
- updater?: ?SelectorStoreUpdater,
768
+ updater?: ?SelectorStoreUpdater<TMutation['response']>,
649
769
  |}): RelayObservable<GraphQLResponse>;
650
770
 
651
771
  /**
@@ -658,18 +778,14 @@ export interface IEnvironment {
658
778
  * the result is subscribed to:
659
779
  * environment.executeMutation({...}).subscribe({...}).
660
780
  */
661
- executeMutation({|
662
- operation: OperationDescriptor,
663
- optimisticUpdater?: ?SelectorStoreUpdater,
664
- optimisticResponse?: ?Object,
665
- updater?: ?SelectorStoreUpdater,
666
- uploadables?: ?UploadableMap,
667
- |}): RelayObservable<GraphQLResponse>;
781
+ executeMutation<TMutation: MutationParameters>(
782
+ config: ExecuteMutationConfig<TMutation>,
783
+ ): RelayObservable<GraphQLResponse>;
668
784
 
669
785
  /**
670
786
  * Returns an Observable of GraphQLResponse resulting from executing the
671
787
  * provided Query or Subscription operation responses, the result of which is
672
- * then normalized and comitted to the publish queue.
788
+ * then normalized and committed to the publish queue.
673
789
  *
674
790
  * Note: Observables are lazy, so calling this method will do nothing until
675
791
  * the result is subscribed to:
@@ -710,7 +826,7 @@ export interface IEnvironment {
710
826
  export type ModuleImportPointer = {
711
827
  +__fragmentPropName: ?string,
712
828
  +__module_component: mixed,
713
- +$fragmentRefs: mixed,
829
+ +$fragmentSpreads: mixed,
714
830
  ...
715
831
  };
716
832
 
@@ -754,6 +870,7 @@ export type HandleFieldPayload = {|
754
870
  * with a `@module` fragment spread, or a Flight field's:
755
871
  *
756
872
  * ## @module Fragment Spread
873
+ * - args: Local arguments from the parent
757
874
  * - data: The GraphQL response value for the @match field.
758
875
  * - dataID: The ID of the store object linked to by the @match field.
759
876
  * - operationReference: A reference to a generated module containing the
@@ -781,14 +898,48 @@ export type HandleFieldPayload = {|
781
898
  * root data.
782
899
  */
783
900
  export type ModuleImportPayload = {|
901
+ +kind: 'ModuleImportPayload',
902
+ +args: ?$ReadOnlyArray<NormalizationArgument>,
784
903
  +data: PayloadData,
785
904
  +dataID: DataID,
786
905
  +operationReference: mixed,
787
906
  +path: $ReadOnlyArray<string>,
788
907
  +typeName: string,
789
908
  +variables: Variables,
909
+ +actorIdentifier: ?ActorIdentifier,
910
+ |};
911
+
912
+ /**
913
+ * A payload that represents data necessary to process the results of an object
914
+ * with experimental actor change directive.
915
+ *
916
+ * - data: The GraphQL response value for the actor change field.
917
+ * - dataID: The ID of the store object linked to by the actor change field.
918
+ * - node: NormalizationLinkedField, where the actor change directive is used
919
+ * - path: to a field in the response
920
+ * - variables: Query variables.
921
+ * - typeName: the type that matched.
922
+ *
923
+ * The dataID, variables, and fragmentName can be used to create a Selector
924
+ * which can in turn be used to normalize and publish the data. The dataID and
925
+ * typeName can also be used to construct a root record for normalization.
926
+ */
927
+ export type ActorPayload = {|
928
+ +kind: 'ActorPayload',
929
+ +data: PayloadData,
930
+ +dataID: DataID,
931
+ +node: NormalizationLinkedField,
932
+ +path: $ReadOnlyArray<string>,
933
+ +typeName: string,
934
+ +variables: Variables,
935
+ +actorIdentifier: ActorIdentifier,
790
936
  |};
791
937
 
938
+ /**
939
+ * Union type of possible payload followups we may handle during normalization.
940
+ */
941
+ export type FollowupPayload = ModuleImportPayload | ActorPayload;
942
+
792
943
  /**
793
944
  * Data emitted after processing a Defer or Stream node during normalization
794
945
  * that describes how to process the corresponding response chunk when it
@@ -801,6 +952,7 @@ export type DeferPlaceholder = {|
801
952
  +path: $ReadOnlyArray<string>,
802
953
  +selector: NormalizationSelector,
803
954
  +typeName: string,
955
+ +actorIdentifier: ?ActorIdentifier,
804
956
  |};
805
957
  export type StreamPlaceholder = {|
806
958
  +kind: 'stream',
@@ -809,6 +961,7 @@ export type StreamPlaceholder = {|
809
961
  +parentID: DataID,
810
962
  +node: NormalizationSelectableNode,
811
963
  +variables: Variables,
964
+ +actorIdentifier: ?ActorIdentifier,
812
965
  |};
813
966
  export type IncrementalDataPlaceholder = DeferPlaceholder | StreamPlaceholder;
814
967
 
@@ -842,35 +995,33 @@ export type StoreUpdater = (store: RecordSourceProxy) => void;
842
995
  * order to easily access the root fields of a query/mutation as well as a
843
996
  * second argument of the response object of the mutation.
844
997
  */
845
- export type SelectorStoreUpdater = (
998
+ export type SelectorStoreUpdater<-TMutationResponse> = (
846
999
  store: RecordSourceSelectorProxy,
847
- // Actually SelectorData, but mixed is inconvenient to access deeply in
848
- // product code.
849
- data: $FlowFixMe,
1000
+ data: ?TMutationResponse,
850
1001
  ) => void;
851
1002
 
852
1003
  /**
853
1004
  * A set of configs that can be used to apply an optimistic update into the
854
1005
  * store.
855
1006
  */
856
- export type OptimisticUpdate =
1007
+ export type OptimisticUpdate<TMutation: MutationParameters> =
857
1008
  | OptimisticUpdateFunction
858
- | OptimisticUpdateRelayPayload;
1009
+ | OptimisticUpdateRelayPayload<TMutation>;
859
1010
 
860
1011
  export type OptimisticUpdateFunction = {|
861
1012
  +storeUpdater: StoreUpdater,
862
1013
  |};
863
1014
 
864
- export type OptimisticUpdateRelayPayload = {|
1015
+ export type OptimisticUpdateRelayPayload<TMutation: MutationParameters> = {|
865
1016
  +operation: OperationDescriptor,
866
1017
  +payload: RelayResponsePayload,
867
- +updater: ?SelectorStoreUpdater,
1018
+ +updater: ?SelectorStoreUpdater<TMutation['response']>,
868
1019
  |};
869
1020
 
870
- export type OptimisticResponseConfig = {|
1021
+ export type OptimisticResponseConfig<TMutation: MutationParameters> = {|
871
1022
  +operation: OperationDescriptor,
872
1023
  +response: ?PayloadData,
873
- +updater: ?SelectorStoreUpdater,
1024
+ +updater: ?SelectorStoreUpdater<TMutation['response']>,
874
1025
  |};
875
1026
 
876
1027
  /**
@@ -930,24 +1081,39 @@ export type RelayResponsePayload = {|
930
1081
  +errors: ?Array<PayloadError>,
931
1082
  +fieldPayloads: ?Array<HandleFieldPayload>,
932
1083
  +incrementalPlaceholders: ?Array<IncrementalDataPlaceholder>,
933
- +moduleImportPayloads: ?Array<ModuleImportPayload>,
1084
+ +followupPayloads: ?Array<FollowupPayload>,
934
1085
  +source: MutableRecordSource,
935
1086
  +isFinal: boolean,
936
1087
  |};
937
1088
 
938
1089
  /**
939
- * Public interface for Publish Queue
1090
+ * Configuration on the executeMutation(...).
1091
+ */
1092
+ export type ExecuteMutationConfig<TMutation: MutationParameters> = {|
1093
+ operation: OperationDescriptor,
1094
+ optimisticUpdater?: ?SelectorStoreUpdater<TMutation['response']>,
1095
+ optimisticResponse?: ?Object,
1096
+ updater?: ?SelectorStoreUpdater<TMutation['response']>,
1097
+ uploadables?: ?UploadableMap,
1098
+ |};
1099
+
1100
+ /**
1101
+ * Public interface for Publish Queue.
940
1102
  */
941
1103
  export interface PublishQueue {
942
1104
  /**
943
1105
  * Schedule applying an optimistic updates on the next `run()`.
944
1106
  */
945
- applyUpdate(updater: OptimisticUpdate): void;
1107
+ applyUpdate<TMutation: MutationParameters>(
1108
+ updater: OptimisticUpdate<TMutation>,
1109
+ ): void;
946
1110
 
947
1111
  /**
948
1112
  * Schedule reverting an optimistic updates on the next `run()`.
949
1113
  */
950
- revertUpdate(updater: OptimisticUpdate): void;
1114
+ revertUpdate<TMutation: MutationParameters>(
1115
+ updater: OptimisticUpdate<TMutation>,
1116
+ ): void;
951
1117
 
952
1118
  /**
953
1119
  * Schedule a revert of all optimistic updates on the next `run()`.
@@ -957,10 +1123,10 @@ export interface PublishQueue {
957
1123
  /**
958
1124
  * Schedule applying a payload to the store on the next `run()`.
959
1125
  */
960
- commitPayload(
1126
+ commitPayload<TMutation: MutationParameters>(
961
1127
  operation: OperationDescriptor,
962
1128
  payload: RelayResponsePayload,
963
- updater?: ?SelectorStoreUpdater,
1129
+ updater?: ?SelectorStoreUpdater<TMutation['response']>,
964
1130
  ): void;
965
1131
 
966
1132
  /**
@@ -12,20 +12,23 @@
12
12
 
13
13
  'use strict';
14
14
 
15
- const RelayConcreteNode = require('../util/RelayConcreteNode');
16
-
17
- const getRelayHandleKey = require('../util/getRelayHandleKey');
18
- const invariant = require('invariant');
19
- const stableCopy = require('../util/stableCopy');
20
-
21
15
  import type {
22
- NormalizationHandle,
23
16
  NormalizationArgument,
24
17
  NormalizationField,
18
+ NormalizationHandle,
25
19
  } from '../util/NormalizationNode';
26
- import type {ReaderArgument, ReaderField} from '../util/ReaderNode';
20
+ import type {
21
+ ReaderActorChange,
22
+ ReaderArgument,
23
+ ReaderField,
24
+ } from '../util/ReaderNode';
27
25
  import type {Variables} from '../util/RelayRuntimeTypes';
28
26
 
27
+ const getRelayHandleKey = require('../util/getRelayHandleKey');
28
+ const RelayConcreteNode = require('../util/RelayConcreteNode');
29
+ const stableCopy = require('../util/stableCopy');
30
+ const invariant = require('invariant');
31
+
29
32
  export type Arguments = interface {+[string]: mixed};
30
33
 
31
34
  const {VARIABLE, LITERAL, OBJECT_VALUE, LIST_VALUE} = RelayConcreteNode;
@@ -121,14 +124,19 @@ function getHandleStorageKey(
121
124
  * used here for consistency.
122
125
  */
123
126
  function getStorageKey(
124
- field: NormalizationField | NormalizationHandle | ReaderField,
127
+ field:
128
+ | NormalizationField
129
+ | NormalizationHandle
130
+ | ReaderField
131
+ | ReaderActorChange,
125
132
  variables: Variables,
126
133
  ): string {
127
134
  if (field.storageKey) {
128
135
  // TODO T23663664: Handle nodes do not yet define a static storageKey.
129
136
  return (field: $FlowFixMe).storageKey;
130
137
  }
131
- const {args, name} = field;
138
+ const args = typeof field.args === 'undefined' ? undefined : field.args;
139
+ const name = field.name;
132
140
  return args && args.length !== 0
133
141
  ? formatStorageKey(name, getArgumentValues(args, variables))
134
142
  : name;
@@ -178,7 +186,6 @@ function getStableVariableValue(name: string, variables: Variables): mixed {
178
186
  'getVariableValue(): Undefined variable `%s`.',
179
187
  name,
180
188
  );
181
- // $FlowFixMe[cannot-write]
182
189
  return stableCopy(variables[name]);
183
190
  }
184
191
 
@@ -194,6 +201,8 @@ function getModuleOperationKey(documentName: string): string {
194
201
  * Constants shared by all implementations of RecordSource/MutableRecordSource/etc.
195
202
  */
196
203
  const RelayStoreUtils = {
204
+ ACTOR_IDENTIFIER_KEY: '__actorIdentifier',
205
+ CLIENT_EDGE_TRAVERSAL_PATH: '__clientEdgeTraversalPath',
197
206
  FRAGMENTS_KEY: '__fragments',
198
207
  FRAGMENT_OWNER_KEY: '__fragmentOwner',
199
208
  FRAGMENT_PROP_NAME_KEY: '__fragmentPropName',
@@ -206,6 +215,10 @@ const RelayStoreUtils = {
206
215
  TYPENAME_KEY: '__typename',
207
216
  INVALIDATED_AT_KEY: '__invalidated_at',
208
217
  IS_WITHIN_UNMATCHED_TYPE_REFINEMENT: '__isWithinUnmatchedTypeRefinement',
218
+ RELAY_RESOLVER_VALUE_KEY: '__resolverValue',
219
+ RELAY_RESOLVER_INVALIDATION_KEY: '__resolverValueMayBeInvalid',
220
+ RELAY_RESOLVER_INPUTS_KEY: '__resolverInputValues',
221
+ RELAY_RESOLVER_READER_SELECTOR_KEY: '__resolverReaderSelector',
209
222
 
210
223
  formatStorageKey,
211
224
  getArgumentValue,