relay-runtime 11.0.2 → 12.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 (100) hide show
  1. package/index.js +1 -1
  2. package/index.js.flow +16 -1
  3. package/lib/index.js +15 -0
  4. package/lib/multi-actor-environment/ActorIdentifier.js +11 -1
  5. package/lib/multi-actor-environment/ActorSpecificEnvironment.js +59 -19
  6. package/lib/multi-actor-environment/ActorUtils.js +27 -0
  7. package/lib/multi-actor-environment/MultiActorEnvironment.js +305 -55
  8. package/lib/multi-actor-environment/index.js +5 -1
  9. package/lib/mutations/RelayRecordSourceSelectorProxy.js +6 -1
  10. package/lib/mutations/commitMutation.js +4 -1
  11. package/lib/mutations/validateMutation.js +6 -1
  12. package/lib/network/RelayObservable.js +3 -1
  13. package/lib/network/RelayQueryResponseCache.js +19 -3
  14. package/lib/network/wrapNetworkWithLogObserver.js +78 -0
  15. package/lib/store/DataChecker.js +110 -40
  16. package/lib/store/OperationExecutor.js +478 -204
  17. package/lib/store/RelayConcreteVariables.js +21 -0
  18. package/lib/store/RelayModernEnvironment.js +41 -85
  19. package/lib/store/RelayModernFragmentSpecResolver.js +48 -22
  20. package/lib/store/RelayModernRecord.js +35 -1
  21. package/lib/store/RelayModernStore.js +48 -14
  22. package/lib/store/RelayOperationTracker.js +33 -23
  23. package/lib/store/RelayPublishQueue.js +23 -5
  24. package/lib/store/RelayReader.js +138 -44
  25. package/lib/store/RelayRecordSource.js +87 -3
  26. package/lib/store/RelayReferenceMarker.js +28 -15
  27. package/lib/store/RelayResponseNormalizer.js +164 -91
  28. package/lib/store/RelayStoreReactFlightUtils.js +1 -7
  29. package/lib/store/RelayStoreSubscriptions.js +8 -5
  30. package/lib/store/RelayStoreUtils.js +7 -2
  31. package/lib/store/ResolverCache.js +213 -0
  32. package/lib/store/ResolverFragments.js +1 -1
  33. package/lib/store/createRelayContext.js +1 -1
  34. package/lib/subscription/requestSubscription.js +27 -29
  35. package/lib/util/RelayConcreteNode.js +1 -0
  36. package/lib/util/RelayFeatureFlags.js +3 -5
  37. package/lib/util/RelayReplaySubject.js +21 -6
  38. package/lib/util/getPaginationMetadata.js +41 -0
  39. package/lib/util/getPaginationVariables.js +67 -0
  40. package/lib/util/getPendingOperationsForFragment.js +55 -0
  41. package/lib/util/getRefetchMetadata.js +36 -0
  42. package/lib/util/getValueAtPath.js +51 -0
  43. package/lib/util/isEmptyObject.js +1 -1
  44. package/lib/util/registerEnvironmentWithDevTools.js +26 -0
  45. package/lib/util/withDuration.js +31 -0
  46. package/multi-actor-environment/ActorIdentifier.js.flow +17 -1
  47. package/multi-actor-environment/ActorSpecificEnvironment.js.flow +72 -44
  48. package/multi-actor-environment/ActorUtils.js.flow +33 -0
  49. package/multi-actor-environment/MultiActorEnvironment.js.flow +332 -80
  50. package/multi-actor-environment/MultiActorEnvironmentTypes.js.flow +61 -12
  51. package/multi-actor-environment/index.js.flow +3 -0
  52. package/mutations/RelayRecordSourceSelectorProxy.js.flow +7 -2
  53. package/mutations/commitMutation.js.flow +2 -0
  54. package/mutations/validateMutation.js.flow +8 -0
  55. package/network/RelayObservable.js.flow +2 -0
  56. package/network/RelayQueryResponseCache.js.flow +31 -18
  57. package/network/wrapNetworkWithLogObserver.js.flow +99 -0
  58. package/package.json +1 -1
  59. package/relay-runtime.js +2 -2
  60. package/relay-runtime.min.js +2 -2
  61. package/store/ClientID.js.flow +5 -1
  62. package/store/DataChecker.js.flow +126 -35
  63. package/store/OperationExecutor.js.flow +528 -265
  64. package/store/RelayConcreteVariables.js.flow +26 -1
  65. package/store/RelayModernEnvironment.js.flow +41 -94
  66. package/store/RelayModernFragmentSpecResolver.js.flow +40 -14
  67. package/store/RelayModernOperationDescriptor.js.flow +9 -3
  68. package/store/RelayModernRecord.js.flow +49 -0
  69. package/store/RelayModernStore.js.flow +50 -12
  70. package/store/RelayOperationTracker.js.flow +56 -34
  71. package/store/RelayPublishQueue.js.flow +31 -8
  72. package/store/RelayReader.js.flow +148 -42
  73. package/store/RelayRecordSource.js.flow +72 -6
  74. package/store/RelayReferenceMarker.js.flow +29 -12
  75. package/store/RelayResponseNormalizer.js.flow +164 -48
  76. package/store/RelayStoreReactFlightUtils.js.flow +1 -7
  77. package/store/RelayStoreSubscriptions.js.flow +10 -3
  78. package/store/RelayStoreTypes.js.flow +128 -12
  79. package/store/RelayStoreUtils.js.flow +17 -3
  80. package/store/ResolverCache.js.flow +247 -0
  81. package/store/ResolverFragments.js.flow +6 -3
  82. package/store/createRelayContext.js.flow +1 -1
  83. package/subscription/requestSubscription.js.flow +41 -29
  84. package/util/NormalizationNode.js.flow +10 -3
  85. package/util/ReaderNode.js.flow +15 -1
  86. package/util/RelayConcreteNode.js.flow +1 -0
  87. package/util/RelayFeatureFlags.js.flow +8 -10
  88. package/util/RelayReplaySubject.js.flow +7 -6
  89. package/util/getPaginationMetadata.js.flow +74 -0
  90. package/util/getPaginationVariables.js.flow +112 -0
  91. package/util/getPendingOperationsForFragment.js.flow +62 -0
  92. package/util/getRefetchMetadata.js.flow +80 -0
  93. package/util/getValueAtPath.js.flow +46 -0
  94. package/util/isEmptyObject.js.flow +1 -0
  95. package/util/registerEnvironmentWithDevTools.js.flow +33 -0
  96. package/util/withDuration.js.flow +32 -0
  97. package/lib/store/RelayRecordSourceMapImpl.js +0 -107
  98. package/lib/store/RelayStoreSubscriptionsUsingMapByID.js +0 -318
  99. package/store/RelayRecordSourceMapImpl.js.flow +0 -91
  100. package/store/RelayStoreSubscriptionsUsingMapByID.js.flow +0 -283
@@ -13,6 +13,7 @@
13
13
 
14
14
  import type {PayloadData, GraphQLResponse} from '../network/RelayNetworkTypes';
15
15
  import type RelayObservable from '../network/RelayObservable';
16
+ import type RelayPublishQueue from '../store/RelayPublishQueue';
16
17
  import type {
17
18
  OperationAvailability,
18
19
  OperationDescriptor,
@@ -24,10 +25,17 @@ import type {
24
25
  StoreUpdater,
25
26
  IEnvironment,
26
27
  ExecuteMutationConfig,
28
+ RecordSourceProxy,
27
29
  } from '../store/RelayStoreTypes';
28
30
  import type {Disposable} from '../util/RelayRuntimeTypes';
29
31
  import type {ActorIdentifier} from './ActorIdentifier';
30
32
 
33
+ export type MultiActorStoreUpdater = (
34
+ actorIdentifier: ActorIdentifier,
35
+ environment: IActorEnvironment,
36
+ store: RecordSourceProxy,
37
+ ) => void;
38
+
31
39
  /**
32
40
  * Interface of actor specific sub-environment
33
41
  */
@@ -42,6 +50,17 @@ export interface IActorEnvironment extends IEnvironment {
42
50
  * Identifier of the actor for the current active environment
43
51
  */
44
52
  +actorIdentifier: ActorIdentifier;
53
+
54
+ /**
55
+ * TODO: this needs to move the the MultiActorEnvironment with different API.
56
+ */
57
+ getPublishQueue(): RelayPublishQueue;
58
+
59
+ /**
60
+ * Optional. A human-readable identifier of the environment.
61
+ * This value should be visible in the dev tools.
62
+ */
63
+ +configName: ?string;
45
64
  }
46
65
 
47
66
  /**
@@ -64,7 +83,7 @@ export interface IMultiActorEnvironment {
64
83
  * selector.
65
84
  */
66
85
  check(
67
- actorIdentifier: ActorIdentifier,
86
+ actorEnvironment: IActorEnvironment,
68
87
  operation: OperationDescriptor,
69
88
  ): OperationAvailability;
70
89
 
@@ -74,7 +93,7 @@ export interface IMultiActorEnvironment {
74
93
  * the snapshot's selector to change.
75
94
  */
76
95
  subscribe(
77
- actorIdentifier: ActorIdentifier,
96
+ actorEnvironment: IActorEnvironment,
78
97
  snapshot: Snapshot,
79
98
  callback: (snapshot: Snapshot) => void,
80
99
  ): Disposable;
@@ -85,7 +104,7 @@ export interface IMultiActorEnvironment {
85
104
  * until the returned reference is disposed.
86
105
  */
87
106
  retain(
88
- actorIdentifier: ActorIdentifier,
107
+ actorEnvironment: IActorEnvironment,
89
108
  operation: OperationDescriptor,
90
109
  ): Disposable;
91
110
 
@@ -94,16 +113,33 @@ export interface IMultiActorEnvironment {
94
113
  * by calling `dispose()` on the returned value.
95
114
  */
96
115
  applyUpdate(
97
- actorIdentifier: ActorIdentifier,
116
+ actorEnvironment: IActorEnvironment,
98
117
  optimisticUpdate: OptimisticUpdateFunction,
99
118
  ): Disposable;
100
119
 
120
+ /**
121
+ * Revert updates for the `update` function.
122
+ */
123
+ revertUpdate(
124
+ actorEnvironment: IActorEnvironment,
125
+ update: OptimisticUpdateFunction,
126
+ ): void;
127
+
128
+ /**
129
+ * Revert updates for the `update` function, and apply the `replacement` update.
130
+ */
131
+ replaceUpdate(
132
+ actorEnvironment: IActorEnvironment,
133
+ update: OptimisticUpdateFunction,
134
+ replacement: OptimisticUpdateFunction,
135
+ ): void;
136
+
101
137
  /**
102
138
  * Apply an optimistic mutation response and/or updater. The mutation can be
103
139
  * reverted by calling `dispose()` on the returned value.
104
140
  */
105
141
  applyMutation(
106
- actorIdentifier: ActorIdentifier,
142
+ actorEnvironment: IActorEnvironment,
107
143
  optimisticConfig: OptimisticResponseConfig,
108
144
  ): Disposable;
109
145
 
@@ -112,13 +148,21 @@ export interface IMultiActorEnvironment {
112
148
  * should therefore not be used for optimistic updates. This is mainly
113
149
  * intended for updating fields from client schema extensions.
114
150
  */
115
- commitUpdate(actorIdentifier: ActorIdentifier, updater: StoreUpdater): void;
151
+ commitUpdate(
152
+ actorEnvironment: IActorEnvironment,
153
+ updater: StoreUpdater,
154
+ ): void;
155
+
156
+ /**
157
+ * Commit store updates for each actor-specific environment known to MultiActorEnvironment
158
+ */
159
+ commitMultiActorUpdate(updater: MultiActorStoreUpdater): void;
116
160
 
117
161
  /**
118
162
  * Commit a payload to the environment using the given operation selector.
119
163
  */
120
164
  commitPayload(
121
- actorIdentifier: ActorIdentifier,
165
+ actorEnvironment: IActorEnvironment,
122
166
  operationDescriptor: OperationDescriptor,
123
167
  payload: PayloadData,
124
168
  ): void;
@@ -127,7 +171,7 @@ export interface IMultiActorEnvironment {
127
171
  * Read the results of a selector from in-memory records in the store.
128
172
  */
129
173
  lookup(
130
- actorIdentifier: ActorIdentifier,
174
+ actorEnvironment: IActorEnvironment,
131
175
  selector: SingularReaderSelector,
132
176
  ): Snapshot;
133
177
 
@@ -143,7 +187,7 @@ export interface IMultiActorEnvironment {
143
187
  * the result is subscribed to: environment.execute({...}).subscribe({...}).
144
188
  */
145
189
  execute(
146
- actorIdentifier: ActorIdentifier,
190
+ actorEnvironment: IActorEnvironment,
147
191
  config: {
148
192
  operation: OperationDescriptor,
149
193
  updater?: ?SelectorStoreUpdater,
@@ -161,7 +205,7 @@ export interface IMultiActorEnvironment {
161
205
  * environment.executeMutation({...}).subscribe({...}).
162
206
  */
163
207
  executeMutation(
164
- actorIdentifier: ActorIdentifier,
208
+ actorEnvironment: IActorEnvironment,
165
209
  config: ExecuteMutationConfig,
166
210
  ): RelayObservable<GraphQLResponse>;
167
211
 
@@ -175,7 +219,7 @@ export interface IMultiActorEnvironment {
175
219
  * environment.executeWithSource({...}).subscribe({...}).
176
220
  */
177
221
  executeWithSource(
178
- actorIdentifier: ActorIdentifier,
222
+ actorEnvironment: IActorEnvironment,
179
223
  {
180
224
  operation: OperationDescriptor,
181
225
  source: RelayObservable<GraphQLResponse>,
@@ -190,7 +234,12 @@ export interface IMultiActorEnvironment {
190
234
  * active GraphQL subscription
191
235
  */
192
236
  isRequestActive(
193
- actorIdentifier: ActorIdentifier,
237
+ actorEnvironment: IActorEnvironment,
194
238
  requestIdentifier: string,
195
239
  ): boolean;
240
+
241
+ /**
242
+ * Returns `true` if execute in the server environment
243
+ */
244
+ isServer(): boolean;
196
245
  }
@@ -13,6 +13,8 @@
13
13
 
14
14
  const MultiActorEnvironment = require('./MultiActorEnvironment');
15
15
 
16
+ const {getActorIdentifier} = require('./ActorIdentifier');
17
+
16
18
  export type {ActorIdentifier} from './ActorIdentifier';
17
19
  export type {
18
20
  IActorEnvironment,
@@ -21,4 +23,5 @@ export type {
21
23
 
22
24
  module.exports = {
23
25
  MultiActorEnvironment,
26
+ getActorIdentifier,
24
27
  };
@@ -78,10 +78,15 @@ class RelayRecordSourceSelectorProxy implements RecordSourceSelectorProxy {
78
78
  fieldName: string,
79
79
  plural: boolean,
80
80
  ): ReaderLinkedField {
81
- const field = selector.node.selections.find(
81
+ let field = selector.node.selections.find(
82
82
  selection =>
83
- selection.kind === 'LinkedField' && selection.name === fieldName,
83
+ (selection.kind === 'LinkedField' && selection.name === fieldName) ||
84
+ (selection.kind === 'RequiredField' &&
85
+ selection.field.name === fieldName),
84
86
  );
87
+ if (field && field.kind === 'RequiredField') {
88
+ field = field.field;
89
+ }
85
90
  invariant(
86
91
  field && field.kind === 'LinkedField',
87
92
  'RelayRecordSourceSelectorProxy#getRootField(): Cannot find root ' +
@@ -113,6 +113,8 @@ function commitMutation<T: MutationParameters>(
113
113
  } = config;
114
114
  const operation = createOperationDescriptor(
115
115
  mutation,
116
+ /* $FlowFixMe[class-object-subtyping] added when improving typing for this
117
+ * parameters */
116
118
  variables,
117
119
  cacheConfig,
118
120
  generateUniqueClientID(),
@@ -30,9 +30,11 @@ type ValidationContext = {|
30
30
 
31
31
  const warning = require('warning');
32
32
 
33
+ // $FlowFixMe[method-unbinding] added when improving typing for this parameters
33
34
  const hasOwnProperty = Object.prototype.hasOwnProperty;
34
35
 
35
36
  const {
37
+ ACTOR_CHANGE,
36
38
  CONDITION,
37
39
  CLIENT_COMPONENT,
38
40
  CLIENT_EXTENSION,
@@ -128,6 +130,12 @@ if (__DEV__) {
128
130
  case LINKED_FIELD:
129
131
  case FLIGHT_FIELD:
130
132
  return validateField(optimisticResponse, selection, context);
133
+ case ACTOR_CHANGE:
134
+ return validateField(
135
+ optimisticResponse,
136
+ selection.linkedField,
137
+ context,
138
+ );
131
139
  case INLINE_FRAGMENT:
132
140
  const type = selection.type;
133
141
  const isConcreteType = selection.abstractKey == null;
@@ -355,11 +355,13 @@ class RelayObservable<+T> implements Subscribable<T> {
355
355
  }
356
356
  }
357
357
 
358
+ // $FlowFixMe[incompatible-call]
358
359
  this.subscribe({
359
360
  start,
360
361
  next(value) {
361
362
  try {
362
363
  if (!sink.closed) {
364
+ // $FlowFixMe[incompatible-call]
363
365
  RelayObservable.from(fn(value)).subscribe({
364
366
  start,
365
367
  next: sink.next,
@@ -16,11 +16,14 @@ const invariant = require('invariant');
16
16
  const stableCopy = require('../util/stableCopy');
17
17
 
18
18
  import type {Variables} from '../util/RelayRuntimeTypes';
19
- import type {GraphQLSingularResponse} from './RelayNetworkTypes';
19
+ import type {
20
+ GraphQLResponse,
21
+ GraphQLSingularResponse,
22
+ } from './RelayNetworkTypes';
20
23
 
21
24
  type Response = {
22
25
  fetchTime: number,
23
- payload: GraphQLSingularResponse,
26
+ payload: GraphQLResponse,
24
27
  ...
25
28
  };
26
29
 
@@ -55,7 +58,7 @@ class RelayQueryResponseCache {
55
58
  this._responses.clear();
56
59
  }
57
60
 
58
- get(queryID: string, variables: Variables): ?GraphQLSingularResponse {
61
+ get(queryID: string, variables: Variables): ?GraphQLResponse {
59
62
  const cacheKey = getCacheKey(queryID, variables);
60
63
  this._responses.forEach((response, key) => {
61
64
  if (!isCurrent(response.fetchTime, this._ttl)) {
@@ -63,23 +66,33 @@ class RelayQueryResponseCache {
63
66
  }
64
67
  });
65
68
  const response = this._responses.get(cacheKey);
66
- return response != null
67
- ? // $FlowFixMe[speculation-ambiguous]
68
- ({
69
- ...response.payload,
70
- extensions: {
71
- ...response.payload.extensions,
72
- cacheTimestamp: response.fetchTime,
73
- },
74
- }: GraphQLSingularResponse)
75
- : null;
69
+ if (response == null) {
70
+ return null;
71
+ }
72
+ if (Array.isArray(response.payload)) {
73
+ return response.payload.map(
74
+ payload =>
75
+ // $FlowFixMe[incompatible-cast]
76
+ ({
77
+ ...payload,
78
+ extensions: {
79
+ ...payload.extensions,
80
+ cacheTimestamp: response.fetchTime,
81
+ },
82
+ }: GraphQLSingularResponse),
83
+ );
84
+ }
85
+ // $FlowFixMe[incompatible-cast]
86
+ return ({
87
+ ...response.payload,
88
+ extensions: {
89
+ ...response.payload.extensions,
90
+ cacheTimestamp: response.fetchTime,
91
+ },
92
+ }: GraphQLSingularResponse);
76
93
  }
77
94
 
78
- set(
79
- queryID: string,
80
- variables: Variables,
81
- payload: GraphQLSingularResponse,
82
- ): void {
95
+ set(queryID: string, variables: Variables, payload: GraphQLResponse): void {
83
96
  const fetchTime = Date.now();
84
97
  const cacheKey = getCacheKey(queryID, variables);
85
98
  this._responses.delete(cacheKey); // deletion resets key ordering
@@ -0,0 +1,99 @@
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
8
+ * @format
9
+ */
10
+
11
+ // flowlint ambiguous-object-type:error
12
+
13
+ 'use strict';
14
+
15
+ const generateID = require('../util/generateID');
16
+
17
+ import type ActorSpecificEnvironment from '../multi-actor-environment/ActorSpecificEnvironment';
18
+ import type RelayModernEnvironment from '../store/RelayModernEnvironment';
19
+ import type {RequestParameters} from '../util/RelayConcreteNode';
20
+ import type {CacheConfig, Variables} from '../util/RelayRuntimeTypes';
21
+ import type {
22
+ INetwork,
23
+ GraphQLResponse,
24
+ UploadableMap,
25
+ } from './RelayNetworkTypes';
26
+ import type RelayObservable from './RelayObservable';
27
+
28
+ /**
29
+ * Wraps the network with logging to ensure that network requests are
30
+ * always logged. Relying on each network callsite to be wrapped is
31
+ * untenable and will eventually lead to holes in the logging.
32
+ * NOTE: This function takes an environment instance, because Relay
33
+ * devtools will mutate the `env.__log` method, and the devtools rely
34
+ * on it to receive network events.
35
+ */
36
+ function wrapNetworkWithLogObserver(
37
+ env: RelayModernEnvironment | ActorSpecificEnvironment,
38
+ network: INetwork,
39
+ ): INetwork {
40
+ return {
41
+ execute(
42
+ params: RequestParameters,
43
+ variables: Variables,
44
+ cacheConfig: CacheConfig,
45
+ uploadables?: ?UploadableMap,
46
+ ): RelayObservable<GraphQLResponse> {
47
+ const networkRequestId = generateID();
48
+ const logObserver = {
49
+ start: subscription => {
50
+ env.__log({
51
+ name: 'network.start',
52
+ networkRequestId,
53
+ params,
54
+ variables,
55
+ cacheConfig,
56
+ });
57
+ },
58
+ next: response => {
59
+ env.__log({
60
+ name: 'network.next',
61
+ networkRequestId,
62
+ response,
63
+ });
64
+ },
65
+ error: error => {
66
+ env.__log({
67
+ name: 'network.error',
68
+ networkRequestId,
69
+ error,
70
+ });
71
+ },
72
+ complete: () => {
73
+ env.__log({
74
+ name: 'network.complete',
75
+ networkRequestId,
76
+ });
77
+ },
78
+ unsubscribe: () => {
79
+ env.__log({
80
+ name: 'network.unsubscribe',
81
+ networkRequestId,
82
+ });
83
+ },
84
+ };
85
+ const logRequestInfo = info => {
86
+ env.__log({
87
+ name: 'network.info',
88
+ networkRequestId,
89
+ info,
90
+ });
91
+ };
92
+ return network
93
+ .execute(params, variables, cacheConfig, uploadables, logRequestInfo)
94
+ .do(logObserver);
95
+ },
96
+ };
97
+ }
98
+
99
+ module.exports = wrapNetworkWithLogObserver;
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": "11.0.2",
4
+ "version": "12.0.0",
5
5
  "keywords": [
6
6
  "graphql",
7
7
  "relay"