relay-runtime 9.0.0 → 10.1.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 (142) hide show
  1. package/handlers/RelayDefaultHandlerProvider.js.flow +47 -0
  2. package/handlers/connection/ConnectionHandler.js.flow +549 -0
  3. package/handlers/connection/ConnectionInterface.js.flow +92 -0
  4. package/handlers/connection/MutationHandlers.js.flow +199 -0
  5. package/index.js +1 -1
  6. package/index.js.flow +335 -0
  7. package/lib/handlers/RelayDefaultHandlerProvider.js +20 -0
  8. package/lib/handlers/connection/ConnectionHandler.js +1 -3
  9. package/lib/handlers/connection/MutationHandlers.js +212 -0
  10. package/lib/index.js +14 -2
  11. package/lib/mutations/RelayDeclarativeMutationConfig.js +22 -45
  12. package/lib/mutations/RelayRecordProxy.js +1 -3
  13. package/lib/mutations/RelayRecordSourceMutator.js +1 -3
  14. package/lib/mutations/RelayRecordSourceProxy.js +1 -3
  15. package/lib/mutations/RelayRecordSourceSelectorProxy.js +1 -3
  16. package/lib/mutations/commitMutation.js +2 -3
  17. package/lib/mutations/validateMutation.js +40 -9
  18. package/lib/network/RelayObservable.js +9 -9
  19. package/lib/network/RelayQueryResponseCache.js +8 -6
  20. package/lib/query/GraphQLTag.js +2 -1
  21. package/lib/query/PreloadableQueryRegistry.js +70 -0
  22. package/lib/query/fetchQuery.js +2 -3
  23. package/lib/query/fetchQueryInternal.js +5 -14
  24. package/lib/store/DataChecker.js +200 -71
  25. package/lib/store/RelayConcreteVariables.js +6 -2
  26. package/lib/store/RelayModernEnvironment.js +124 -65
  27. package/lib/store/RelayModernFragmentSpecResolver.js +19 -14
  28. package/lib/store/RelayModernOperationDescriptor.js +6 -5
  29. package/lib/store/RelayModernQueryExecutor.js +122 -73
  30. package/lib/store/RelayModernRecord.js +14 -9
  31. package/lib/store/RelayModernSelector.js +6 -2
  32. package/lib/store/RelayModernStore.js +281 -131
  33. package/lib/store/RelayOperationTracker.js +35 -78
  34. package/lib/store/RelayOptimisticRecordSource.js +7 -5
  35. package/lib/store/RelayPublishQueue.js +2 -4
  36. package/lib/store/RelayReader.js +304 -52
  37. package/lib/store/RelayRecordSource.js +1 -3
  38. package/lib/store/RelayRecordSourceMapImpl.js +13 -18
  39. package/lib/store/RelayReferenceMarker.js +125 -14
  40. package/lib/store/RelayResponseNormalizer.js +261 -66
  41. package/lib/store/RelayStoreReactFlightUtils.js +47 -0
  42. package/lib/store/RelayStoreUtils.js +1 -0
  43. package/lib/store/StoreInspector.js +8 -8
  44. package/lib/store/TypeID.js +28 -0
  45. package/lib/store/cloneRelayScalarHandleSourceField.js +44 -0
  46. package/lib/store/defaultRequiredFieldLogger.js +18 -0
  47. package/lib/store/normalizeRelayPayload.js +6 -2
  48. package/lib/store/readInlineData.js +1 -1
  49. package/lib/subscription/requestSubscription.js +4 -3
  50. package/lib/util/NormalizationNode.js +1 -5
  51. package/lib/util/RelayConcreteNode.js +11 -6
  52. package/lib/util/RelayError.js +39 -9
  53. package/lib/util/RelayFeatureFlags.js +6 -3
  54. package/lib/util/RelayReplaySubject.js +3 -3
  55. package/lib/util/createPayloadFor3DField.js +7 -2
  56. package/lib/util/getFragmentIdentifier.js +12 -3
  57. package/lib/util/getOperation.js +33 -0
  58. package/lib/util/getRequestIdentifier.js +2 -2
  59. package/lib/util/isEmptyObject.js +25 -0
  60. package/lib/util/recycleNodesInto.js +6 -7
  61. package/lib/util/reportMissingRequiredFields.js +48 -0
  62. package/mutations/RelayDeclarativeMutationConfig.js.flow +380 -0
  63. package/mutations/RelayRecordProxy.js.flow +165 -0
  64. package/mutations/RelayRecordSourceMutator.js.flow +238 -0
  65. package/mutations/RelayRecordSourceProxy.js.flow +164 -0
  66. package/mutations/RelayRecordSourceSelectorProxy.js.flow +119 -0
  67. package/mutations/applyOptimisticMutation.js.flow +76 -0
  68. package/mutations/commitLocalUpdate.js.flow +24 -0
  69. package/mutations/commitMutation.js.flow +181 -0
  70. package/mutations/validateMutation.js.flow +242 -0
  71. package/network/ConvertToExecuteFunction.js.flow +49 -0
  72. package/network/RelayNetwork.js.flow +84 -0
  73. package/network/RelayNetworkTypes.js.flow +145 -0
  74. package/network/RelayObservable.js.flow +634 -0
  75. package/network/RelayQueryResponseCache.js.flow +111 -0
  76. package/package.json +2 -2
  77. package/query/GraphQLTag.js.flow +168 -0
  78. package/query/PreloadableQueryRegistry.js.flow +65 -0
  79. package/query/fetchQuery.js.flow +47 -0
  80. package/query/fetchQueryInternal.js.flow +343 -0
  81. package/relay-runtime.js +2 -2
  82. package/relay-runtime.min.js +2 -2
  83. package/store/ClientID.js.flow +43 -0
  84. package/store/DataChecker.js.flow +568 -0
  85. package/store/RelayConcreteVariables.js.flow +96 -0
  86. package/store/RelayModernEnvironment.js.flow +571 -0
  87. package/store/RelayModernFragmentSpecResolver.js.flow +438 -0
  88. package/store/RelayModernOperationDescriptor.js.flow +92 -0
  89. package/store/RelayModernQueryExecutor.js.flow +1345 -0
  90. package/store/RelayModernRecord.js.flow +403 -0
  91. package/store/RelayModernSelector.js.flow +455 -0
  92. package/store/RelayModernStore.js.flow +858 -0
  93. package/store/RelayOperationTracker.js.flow +164 -0
  94. package/store/RelayOptimisticRecordSource.js.flow +119 -0
  95. package/store/RelayPublishQueue.js.flow +401 -0
  96. package/store/RelayReader.js.flow +638 -0
  97. package/store/RelayRecordSource.js.flow +29 -0
  98. package/store/RelayRecordSourceMapImpl.js.flow +87 -0
  99. package/store/RelayRecordState.js.flow +37 -0
  100. package/store/RelayReferenceMarker.js.flow +324 -0
  101. package/store/RelayResponseNormalizer.js.flow +791 -0
  102. package/store/RelayStoreReactFlightUtils.js.flow +64 -0
  103. package/store/RelayStoreTypes.js.flow +958 -0
  104. package/store/RelayStoreUtils.js.flow +219 -0
  105. package/store/StoreInspector.js.flow +171 -0
  106. package/store/TypeID.js.flow +28 -0
  107. package/store/ViewerPattern.js.flow +26 -0
  108. package/store/cloneRelayHandleSourceField.js.flow +66 -0
  109. package/store/cloneRelayScalarHandleSourceField.js.flow +62 -0
  110. package/store/createFragmentSpecResolver.js.flow +55 -0
  111. package/store/createRelayContext.js.flow +44 -0
  112. package/store/defaultGetDataID.js.flow +27 -0
  113. package/store/defaultRequiredFieldLogger.js.flow +23 -0
  114. package/store/hasOverlappingIDs.js.flow +34 -0
  115. package/store/isRelayModernEnvironment.js.flow +27 -0
  116. package/store/normalizeRelayPayload.js.flow +51 -0
  117. package/store/readInlineData.js.flow +75 -0
  118. package/subscription/requestSubscription.js.flow +103 -0
  119. package/util/JSResourceTypes.flow.js.flow +20 -0
  120. package/util/NormalizationNode.js.flow +213 -0
  121. package/util/ReaderNode.js.flow +227 -0
  122. package/util/RelayConcreteNode.js.flow +99 -0
  123. package/util/RelayDefaultHandleKey.js.flow +17 -0
  124. package/util/RelayError.js.flow +62 -0
  125. package/util/RelayFeatureFlags.js.flow +37 -0
  126. package/util/RelayProfiler.js.flow +284 -0
  127. package/util/RelayReplaySubject.js.flow +135 -0
  128. package/util/RelayRuntimeTypes.js.flow +72 -0
  129. package/util/createPayloadFor3DField.js.flow +43 -0
  130. package/util/deepFreeze.js.flow +36 -0
  131. package/util/generateID.js.flow +21 -0
  132. package/util/getFragmentIdentifier.js.flow +76 -0
  133. package/util/getOperation.js.flow +40 -0
  134. package/util/getRelayHandleKey.js.flow +41 -0
  135. package/util/getRequestIdentifier.js.flow +42 -0
  136. package/util/isEmptyObject.js.flow +25 -0
  137. package/util/isPromise.js.flow +21 -0
  138. package/util/isScalarAndEqual.js.flow +26 -0
  139. package/util/recycleNodesInto.js.flow +87 -0
  140. package/util/reportMissingRequiredFields.js.flow +51 -0
  141. package/util/resolveImmediate.js.flow +30 -0
  142. package/util/stableCopy.js.flow +35 -0
@@ -0,0 +1,571 @@
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
+ * @emails oncall+relay
9
+ * @format
10
+ */
11
+
12
+ // flowlint ambiguous-object-type:error
13
+
14
+ 'use strict';
15
+
16
+ const RelayDefaultHandlerProvider = require('../handlers/RelayDefaultHandlerProvider');
17
+ const RelayFeatureFlags = require('../util/RelayFeatureFlags');
18
+ const RelayModernQueryExecutor = require('./RelayModernQueryExecutor');
19
+ const RelayObservable = require('../network/RelayObservable');
20
+ const RelayOperationTracker = require('../store/RelayOperationTracker');
21
+ const RelayPublishQueue = require('./RelayPublishQueue');
22
+ const RelayRecordSource = require('./RelayRecordSource');
23
+
24
+ const defaultGetDataID = require('./defaultGetDataID');
25
+ const defaultRequiredFieldLogger = require('./defaultRequiredFieldLogger');
26
+ const generateID = require('../util/generateID');
27
+ const invariant = require('invariant');
28
+
29
+ import type {HandlerProvider} from '../handlers/RelayDefaultHandlerProvider';
30
+ import type {
31
+ GraphQLResponse,
32
+ INetwork,
33
+ LogRequestInfoFunction,
34
+ PayloadData,
35
+ UploadableMap,
36
+ } from '../network/RelayNetworkTypes';
37
+ import type {Observer} from '../network/RelayObservable';
38
+ import type {RequestParameters} from '../util/RelayConcreteNode';
39
+ import type {
40
+ CacheConfig,
41
+ Disposable,
42
+ RenderPolicy,
43
+ Variables,
44
+ } from '../util/RelayRuntimeTypes';
45
+ import type {ActiveState} from './RelayModernQueryExecutor';
46
+ import type {TaskScheduler} from './RelayModernQueryExecutor';
47
+ import type {GetDataID} from './RelayResponseNormalizer';
48
+ import type {
49
+ IEnvironment,
50
+ LogFunction,
51
+ MissingFieldHandler,
52
+ RequiredFieldLogger,
53
+ OperationAvailability,
54
+ OperationDescriptor,
55
+ OperationLoader,
56
+ OperationTracker,
57
+ OptimisticResponseConfig,
58
+ OptimisticUpdateFunction,
59
+ PublishQueue,
60
+ ReactFlightPayloadDeserializer,
61
+ SelectorStoreUpdater,
62
+ SingularReaderSelector,
63
+ Snapshot,
64
+ Store,
65
+ StoreUpdater,
66
+ } from './RelayStoreTypes';
67
+
68
+ export type EnvironmentConfig = {|
69
+ +configName?: string,
70
+ +handlerProvider?: ?HandlerProvider,
71
+ +treatMissingFieldsAsNull?: boolean,
72
+ +log?: ?LogFunction,
73
+ +operationLoader?: ?OperationLoader,
74
+ +reactFlightPayloadDeserializer?: ?ReactFlightPayloadDeserializer,
75
+ +network: INetwork,
76
+ +scheduler?: ?TaskScheduler,
77
+ +store: Store,
78
+ +missingFieldHandlers?: ?$ReadOnlyArray<MissingFieldHandler>,
79
+ +operationTracker?: ?OperationTracker,
80
+ /**
81
+ * This method is likely to change in future versions, use at your own risk.
82
+ * It can potentially break existing calls like store.get(<id>),
83
+ * because the internal ID might not be the `id` field on the node anymore
84
+ */
85
+ +UNSTABLE_DO_NOT_USE_getDataID?: ?GetDataID,
86
+ +UNSTABLE_defaultRenderPolicy?: ?RenderPolicy,
87
+ +options?: mixed,
88
+ +isServer?: boolean,
89
+ +requiredFieldLogger?: ?RequiredFieldLogger,
90
+ |};
91
+
92
+ class RelayModernEnvironment implements IEnvironment {
93
+ __log: LogFunction;
94
+ +_defaultRenderPolicy: RenderPolicy;
95
+ _operationLoader: ?OperationLoader;
96
+ _reactFlightPayloadDeserializer: ?ReactFlightPayloadDeserializer;
97
+ _network: INetwork;
98
+ _publishQueue: PublishQueue;
99
+ _scheduler: ?TaskScheduler;
100
+ _store: Store;
101
+ configName: ?string;
102
+ _missingFieldHandlers: ?$ReadOnlyArray<MissingFieldHandler>;
103
+ _operationTracker: OperationTracker;
104
+ _getDataID: GetDataID;
105
+ _treatMissingFieldsAsNull: boolean;
106
+ _operationExecutions: Map<string, ActiveState>;
107
+ +options: mixed;
108
+ +_isServer: boolean;
109
+ requiredFieldLogger: RequiredFieldLogger;
110
+
111
+ constructor(config: EnvironmentConfig) {
112
+ this.configName = config.configName;
113
+ const handlerProvider = config.handlerProvider
114
+ ? config.handlerProvider
115
+ : RelayDefaultHandlerProvider;
116
+ this._treatMissingFieldsAsNull = config.treatMissingFieldsAsNull === true;
117
+ const operationLoader = config.operationLoader;
118
+ const reactFlightPayloadDeserializer =
119
+ config.reactFlightPayloadDeserializer;
120
+ if (__DEV__) {
121
+ if (operationLoader != null) {
122
+ invariant(
123
+ typeof operationLoader === 'object' &&
124
+ typeof operationLoader.get === 'function' &&
125
+ typeof operationLoader.load === 'function',
126
+ 'RelayModernEnvironment: Expected `operationLoader` to be an object ' +
127
+ 'with get() and load() functions, got `%s`.',
128
+ operationLoader,
129
+ );
130
+ }
131
+ if (reactFlightPayloadDeserializer != null) {
132
+ invariant(
133
+ typeof reactFlightPayloadDeserializer === 'function',
134
+ 'RelayModernEnvironment: Expected `reactFlightPayloadDeserializer` ' +
135
+ ' to be a function, got `%s`.',
136
+ reactFlightPayloadDeserializer,
137
+ );
138
+ }
139
+ }
140
+ this.__log = config.log ?? emptyFunction;
141
+ this.requiredFieldLogger =
142
+ config.requiredFieldLogger ?? defaultRequiredFieldLogger;
143
+ this._defaultRenderPolicy =
144
+ config.UNSTABLE_defaultRenderPolicy ??
145
+ RelayFeatureFlags.ENABLE_PARTIAL_RENDERING_DEFAULT === true
146
+ ? 'partial'
147
+ : 'full';
148
+ this._operationLoader = operationLoader;
149
+ this._operationExecutions = new Map();
150
+ this._network = config.network;
151
+ this._getDataID = config.UNSTABLE_DO_NOT_USE_getDataID ?? defaultGetDataID;
152
+ this._publishQueue = new RelayPublishQueue(
153
+ config.store,
154
+ handlerProvider,
155
+ this._getDataID,
156
+ );
157
+ this._scheduler = config.scheduler ?? null;
158
+ this._store = config.store;
159
+ this.options = config.options;
160
+ this._isServer = config.isServer ?? false;
161
+
162
+ (this: any).__setNet = newNet => (this._network = newNet);
163
+
164
+ if (__DEV__) {
165
+ const {inspect} = require('./StoreInspector');
166
+ (this: any).DEBUG_inspect = (dataID: ?string) => inspect(this, dataID);
167
+ }
168
+
169
+ // Register this Relay Environment with Relay DevTools if it exists.
170
+ // Note: this must always be the last step in the constructor.
171
+ const _global =
172
+ typeof global !== 'undefined'
173
+ ? global
174
+ : typeof window !== 'undefined'
175
+ ? window
176
+ : undefined;
177
+ const devToolsHook = _global && _global.__RELAY_DEVTOOLS_HOOK__;
178
+ if (devToolsHook) {
179
+ devToolsHook.registerEnvironment(this);
180
+ }
181
+ this._missingFieldHandlers = config.missingFieldHandlers;
182
+ this._operationTracker =
183
+ config.operationTracker ?? new RelayOperationTracker();
184
+ this._reactFlightPayloadDeserializer = reactFlightPayloadDeserializer;
185
+ }
186
+
187
+ getStore(): Store {
188
+ return this._store;
189
+ }
190
+
191
+ getNetwork(): INetwork {
192
+ return this._network;
193
+ }
194
+
195
+ getOperationTracker(): RelayOperationTracker {
196
+ return this._operationTracker;
197
+ }
198
+
199
+ isRequestActive(requestIdentifier: string): boolean {
200
+ const activeState = this._operationExecutions.get(requestIdentifier);
201
+ return activeState === 'active';
202
+ }
203
+
204
+ UNSTABLE_getDefaultRenderPolicy(): RenderPolicy {
205
+ return this._defaultRenderPolicy;
206
+ }
207
+
208
+ applyUpdate(optimisticUpdate: OptimisticUpdateFunction): Disposable {
209
+ const dispose = () => {
210
+ this._scheduleUpdates(() => {
211
+ this._publishQueue.revertUpdate(optimisticUpdate);
212
+ this._publishQueue.run();
213
+ });
214
+ };
215
+ this._scheduleUpdates(() => {
216
+ this._publishQueue.applyUpdate(optimisticUpdate);
217
+ this._publishQueue.run();
218
+ });
219
+ return {dispose};
220
+ }
221
+
222
+ revertUpdate(update: OptimisticUpdateFunction): void {
223
+ this._scheduleUpdates(() => {
224
+ this._publishQueue.revertUpdate(update);
225
+ this._publishQueue.run();
226
+ });
227
+ }
228
+
229
+ replaceUpdate(
230
+ update: OptimisticUpdateFunction,
231
+ newUpdate: OptimisticUpdateFunction,
232
+ ): void {
233
+ this._scheduleUpdates(() => {
234
+ this._publishQueue.revertUpdate(update);
235
+ this._publishQueue.applyUpdate(newUpdate);
236
+ this._publishQueue.run();
237
+ });
238
+ }
239
+
240
+ applyMutation(optimisticConfig: OptimisticResponseConfig): Disposable {
241
+ const subscription = RelayObservable.create(sink => {
242
+ const source = RelayObservable.create(_sink => {});
243
+ const executor = RelayModernQueryExecutor.execute({
244
+ operation: optimisticConfig.operation,
245
+ operationExecutions: this._operationExecutions,
246
+ operationLoader: this._operationLoader,
247
+ optimisticConfig,
248
+ publishQueue: this._publishQueue,
249
+ reactFlightPayloadDeserializer: this._reactFlightPayloadDeserializer,
250
+ scheduler: this._scheduler,
251
+ sink,
252
+ source,
253
+ store: this._store,
254
+ updater: null,
255
+ operationTracker: this._operationTracker,
256
+ getDataID: this._getDataID,
257
+ treatMissingFieldsAsNull: this._treatMissingFieldsAsNull,
258
+ });
259
+ return () => executor.cancel();
260
+ }).subscribe({});
261
+ return {
262
+ dispose: () => subscription.unsubscribe(),
263
+ };
264
+ }
265
+
266
+ check(operation: OperationDescriptor): OperationAvailability {
267
+ if (
268
+ this._missingFieldHandlers == null ||
269
+ this._missingFieldHandlers.length === 0
270
+ ) {
271
+ return this._store.check(operation);
272
+ }
273
+ return this._checkSelectorAndHandleMissingFields(
274
+ operation,
275
+ this._missingFieldHandlers,
276
+ );
277
+ }
278
+
279
+ commitPayload(operation: OperationDescriptor, payload: PayloadData): void {
280
+ RelayObservable.create(sink => {
281
+ const executor = RelayModernQueryExecutor.execute({
282
+ operation: operation,
283
+ operationExecutions: this._operationExecutions,
284
+ operationLoader: this._operationLoader,
285
+ optimisticConfig: null,
286
+ publishQueue: this._publishQueue,
287
+ reactFlightPayloadDeserializer: this._reactFlightPayloadDeserializer,
288
+ scheduler: this._scheduler,
289
+ sink,
290
+ source: RelayObservable.from({
291
+ data: payload,
292
+ }),
293
+ store: this._store,
294
+ updater: null,
295
+ operationTracker: this._operationTracker,
296
+ getDataID: this._getDataID,
297
+ isClientPayload: true,
298
+ treatMissingFieldsAsNull: this._treatMissingFieldsAsNull,
299
+ });
300
+ return () => executor.cancel();
301
+ }).subscribe({});
302
+ }
303
+
304
+ commitUpdate(updater: StoreUpdater): void {
305
+ this._scheduleUpdates(() => {
306
+ this._publishQueue.commitUpdate(updater);
307
+ this._publishQueue.run();
308
+ });
309
+ }
310
+
311
+ lookup(readSelector: SingularReaderSelector): Snapshot {
312
+ return this._store.lookup(readSelector);
313
+ }
314
+
315
+ subscribe(
316
+ snapshot: Snapshot,
317
+ callback: (snapshot: Snapshot) => void,
318
+ ): Disposable {
319
+ return this._store.subscribe(snapshot, callback);
320
+ }
321
+
322
+ retain(operation: OperationDescriptor): Disposable {
323
+ return this._store.retain(operation);
324
+ }
325
+
326
+ isServer(): boolean {
327
+ return this._isServer;
328
+ }
329
+
330
+ _checkSelectorAndHandleMissingFields(
331
+ operation: OperationDescriptor,
332
+ handlers: $ReadOnlyArray<MissingFieldHandler>,
333
+ ): OperationAvailability {
334
+ const target = RelayRecordSource.create();
335
+ const result = this._store.check(operation, {target, handlers});
336
+ if (target.size() > 0) {
337
+ this._scheduleUpdates(() => {
338
+ this._publishQueue.commitSource(target);
339
+ this._publishQueue.run();
340
+ });
341
+ }
342
+ return result;
343
+ }
344
+
345
+ _scheduleUpdates(task: () => void) {
346
+ const scheduler = this._scheduler;
347
+ if (scheduler != null) {
348
+ scheduler.schedule(task);
349
+ } else {
350
+ task();
351
+ }
352
+ }
353
+
354
+ /**
355
+ * Returns an Observable of GraphQLResponse resulting from executing the
356
+ * provided Query or Subscription operation, each result of which is then
357
+ * normalized and committed to the publish queue.
358
+ *
359
+ * Note: Observables are lazy, so calling this method will do nothing until
360
+ * the result is subscribed to: environment.execute({...}).subscribe({...}).
361
+ */
362
+ execute({
363
+ operation,
364
+ updater,
365
+ }: {|
366
+ operation: OperationDescriptor,
367
+ updater?: ?SelectorStoreUpdater,
368
+ |}): RelayObservable<GraphQLResponse> {
369
+ const [logObserver, logRequestInfo] = this.__createLogObserver(
370
+ operation.request.node.params,
371
+ operation.request.variables,
372
+ );
373
+ return RelayObservable.create(sink => {
374
+ const source = this._network
375
+ .execute(
376
+ operation.request.node.params,
377
+ operation.request.variables,
378
+ operation.request.cacheConfig || {},
379
+ null,
380
+ logRequestInfo,
381
+ )
382
+ .do(logObserver);
383
+ const executor = RelayModernQueryExecutor.execute({
384
+ operation,
385
+ operationExecutions: this._operationExecutions,
386
+ operationLoader: this._operationLoader,
387
+ optimisticConfig: null,
388
+ publishQueue: this._publishQueue,
389
+ reactFlightPayloadDeserializer: this._reactFlightPayloadDeserializer,
390
+ scheduler: this._scheduler,
391
+ sink,
392
+ source,
393
+ store: this._store,
394
+ updater,
395
+ operationTracker: this._operationTracker,
396
+ getDataID: this._getDataID,
397
+ treatMissingFieldsAsNull: this._treatMissingFieldsAsNull,
398
+ });
399
+ return () => executor.cancel();
400
+ });
401
+ }
402
+
403
+ /**
404
+ * Returns an Observable of GraphQLResponse resulting from executing the
405
+ * provided Mutation operation, the result of which is then normalized and
406
+ * committed to the publish queue along with an optional optimistic response
407
+ * or updater.
408
+ *
409
+ * Note: Observables are lazy, so calling this method will do nothing until
410
+ * the result is subscribed to:
411
+ * environment.executeMutation({...}).subscribe({...}).
412
+ */
413
+ executeMutation({
414
+ operation,
415
+ optimisticResponse,
416
+ optimisticUpdater,
417
+ updater,
418
+ uploadables,
419
+ }: {|
420
+ operation: OperationDescriptor,
421
+ optimisticUpdater?: ?SelectorStoreUpdater,
422
+ optimisticResponse?: ?Object,
423
+ updater?: ?SelectorStoreUpdater,
424
+ uploadables?: ?UploadableMap,
425
+ |}): RelayObservable<GraphQLResponse> {
426
+ const [logObserver, logRequestInfo] = this.__createLogObserver(
427
+ operation.request.node.params,
428
+ operation.request.variables,
429
+ );
430
+ return RelayObservable.create(sink => {
431
+ let optimisticConfig;
432
+ if (optimisticResponse || optimisticUpdater) {
433
+ optimisticConfig = {
434
+ operation: operation,
435
+ response: optimisticResponse,
436
+ updater: optimisticUpdater,
437
+ };
438
+ }
439
+ const source = this._network
440
+ .execute(
441
+ operation.request.node.params,
442
+ operation.request.variables,
443
+ {
444
+ ...operation.request.cacheConfig,
445
+ force: true,
446
+ },
447
+ uploadables,
448
+ logRequestInfo,
449
+ )
450
+ .do(logObserver);
451
+ const executor = RelayModernQueryExecutor.execute({
452
+ operation,
453
+ operationExecutions: this._operationExecutions,
454
+ operationLoader: this._operationLoader,
455
+ optimisticConfig,
456
+ publishQueue: this._publishQueue,
457
+ reactFlightPayloadDeserializer: this._reactFlightPayloadDeserializer,
458
+ scheduler: this._scheduler,
459
+ sink,
460
+ source,
461
+ store: this._store,
462
+ updater,
463
+ operationTracker: this._operationTracker,
464
+ getDataID: this._getDataID,
465
+ treatMissingFieldsAsNull: this._treatMissingFieldsAsNull,
466
+ });
467
+ return () => executor.cancel();
468
+ });
469
+ }
470
+
471
+ /**
472
+ * Returns an Observable of GraphQLResponse resulting from executing the
473
+ * provided Query or Subscription operation responses, the result of which is
474
+ * then normalized and comitted to the publish queue.
475
+ *
476
+ * Note: Observables are lazy, so calling this method will do nothing until
477
+ * the result is subscribed to:
478
+ * environment.executeWithSource({...}).subscribe({...}).
479
+ */
480
+ executeWithSource({
481
+ operation,
482
+ source,
483
+ }: {|
484
+ operation: OperationDescriptor,
485
+ source: RelayObservable<GraphQLResponse>,
486
+ |}): RelayObservable<GraphQLResponse> {
487
+ return RelayObservable.create(sink => {
488
+ const executor = RelayModernQueryExecutor.execute({
489
+ operation,
490
+ operationExecutions: this._operationExecutions,
491
+ operationLoader: this._operationLoader,
492
+ operationTracker: this._operationTracker,
493
+ optimisticConfig: null,
494
+ publishQueue: this._publishQueue,
495
+ reactFlightPayloadDeserializer: this._reactFlightPayloadDeserializer,
496
+ scheduler: this._scheduler,
497
+ sink,
498
+ source,
499
+ store: this._store,
500
+ getDataID: this._getDataID,
501
+ treatMissingFieldsAsNull: this._treatMissingFieldsAsNull,
502
+ });
503
+ return () => executor.cancel();
504
+ });
505
+ }
506
+
507
+ toJSON(): mixed {
508
+ return `RelayModernEnvironment(${this.configName ?? ''})`;
509
+ }
510
+
511
+ __createLogObserver(
512
+ params: RequestParameters,
513
+ variables: Variables,
514
+ ): [Observer<GraphQLResponse>, LogRequestInfoFunction] {
515
+ const transactionID = generateID();
516
+ const log = this.__log;
517
+ const logObserver = {
518
+ start: subscription => {
519
+ log({
520
+ name: 'execute.start',
521
+ transactionID,
522
+ params,
523
+ variables,
524
+ });
525
+ },
526
+ next: response => {
527
+ log({
528
+ name: 'execute.next',
529
+ transactionID,
530
+ response,
531
+ });
532
+ },
533
+ error: error => {
534
+ log({
535
+ name: 'execute.error',
536
+ transactionID,
537
+ error,
538
+ });
539
+ },
540
+ complete: () => {
541
+ log({
542
+ name: 'execute.complete',
543
+ transactionID,
544
+ });
545
+ },
546
+ unsubscribe: () => {
547
+ log({
548
+ name: 'execute.unsubscribe',
549
+ transactionID,
550
+ });
551
+ },
552
+ };
553
+ const logRequestInfo = info => {
554
+ log({
555
+ name: 'execute.info',
556
+ transactionID,
557
+ info,
558
+ });
559
+ };
560
+ return [logObserver, logRequestInfo];
561
+ }
562
+ }
563
+
564
+ // Add a sigil for detection by `isRelayModernEnvironment()` to avoid a
565
+ // realm-specific instanceof check, and to aid in module tree-shaking to
566
+ // avoid requiring all of RelayRuntime just to detect its environment.
567
+ (RelayModernEnvironment: any).prototype['@@RelayModernEnvironment'] = true;
568
+
569
+ function emptyFunction() {}
570
+
571
+ module.exports = RelayModernEnvironment;