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
@@ -16,88 +16,131 @@ const OperationExecutor = require('../store/OperationExecutor');
16
16
  const RelayDefaultHandlerProvider = require('../handlers/RelayDefaultHandlerProvider');
17
17
  const RelayModernStore = require('../store/RelayModernStore');
18
18
  const RelayObservable = require('../network/RelayObservable');
19
- const RelayPublishQueue = require('../store/RelayPublishQueue');
20
19
  const RelayRecordSource = require('../store/RelayRecordSource');
21
20
 
22
21
  const defaultGetDataID = require('../store/defaultGetDataID');
22
+ const defaultRequiredFieldLogger = require('../store/defaultRequiredFieldLogger');
23
23
 
24
24
  import type {HandlerProvider} from '../handlers/RelayDefaultHandlerProvider';
25
25
  import type {GraphQLResponse, PayloadData} from '../network/RelayNetworkTypes';
26
26
  import type {INetwork} from '../network/RelayNetworkTypes';
27
- import type {ActiveState} from '../store/OperationExecutor';
27
+ import type {ActiveState, TaskScheduler} from '../store/OperationExecutor';
28
28
  import type {GetDataID} from '../store/RelayResponseNormalizer';
29
29
  import type {
30
- IEnvironment,
30
+ ExecuteMutationConfig,
31
+ LogFunction,
32
+ MissingFieldHandler,
33
+ MutableRecordSource,
34
+ OperationAvailability,
35
+ OperationDescriptor,
36
+ OperationLoader,
31
37
  OptimisticResponseConfig,
32
38
  OptimisticUpdateFunction,
33
- OperationDescriptor,
34
- OperationAvailability,
35
- Snapshot,
39
+ ReactFlightPayloadDeserializer,
40
+ ReactFlightServerErrorHandler,
41
+ RequiredFieldLogger,
36
42
  SelectorStoreUpdater,
37
43
  SingularReaderSelector,
44
+ Snapshot,
45
+ Store,
38
46
  StoreUpdater,
39
- RequiredFieldLogger,
40
- ExecuteMutationConfig,
41
- LogFunction,
42
47
  } from '../store/RelayStoreTypes';
43
48
  import type {Disposable} from '../util/RelayRuntimeTypes';
49
+ import type {RenderPolicy} from '../util/RelayRuntimeTypes';
44
50
  import type {ActorIdentifier} from './ActorIdentifier';
45
51
  import type {
46
52
  IActorEnvironment,
47
53
  IMultiActorEnvironment,
54
+ MultiActorStoreUpdater,
48
55
  } from './MultiActorEnvironmentTypes';
49
56
 
50
- function todo(what: string) {
51
- throw new Error(`Not implementd: ${what}`);
52
- }
53
-
54
57
  export type MultiActorEnvironmentConfig = $ReadOnly<{
58
+ createConfigNameForActor?: ?(actorIdentifier: ActorIdentifier) => string,
55
59
  createNetworkForActor: (actorIdentifier: ActorIdentifier) => INetwork,
60
+ createStoreForActor?: ?(actorIdentifier: ActorIdentifier) => Store,
61
+ defaultRenderPolicy?: ?RenderPolicy,
56
62
  getDataID?: GetDataID,
57
63
  handlerProvider?: HandlerProvider,
58
- logFn: LogFunction,
59
- requiredFieldLogger: RequiredFieldLogger,
64
+ isServer?: ?boolean,
65
+ logFn?: ?LogFunction,
66
+ missingFieldHandlers?: ?$ReadOnlyArray<MissingFieldHandler>,
67
+ operationLoader?: ?OperationLoader,
68
+ reactFlightPayloadDeserializer?: ?ReactFlightPayloadDeserializer,
69
+ reactFlightServerErrorHandler?: ?ReactFlightServerErrorHandler,
70
+ requiredFieldLogger?: ?RequiredFieldLogger,
71
+ scheduler?: ?TaskScheduler,
72
+ shouldProcessClientComponents?: ?boolean,
60
73
  treatMissingFieldsAsNull?: boolean,
61
74
  }>;
62
75
 
63
76
  class MultiActorEnvironment implements IMultiActorEnvironment {
64
77
  +_actorEnvironments: Map<ActorIdentifier, IActorEnvironment>;
78
+ +_createConfigNameForActor: ?(actorIdentifier: ActorIdentifier) => string;
65
79
  +_createNetworkForActor: (actorIdentifier: ActorIdentifier) => INetwork;
80
+ +_createStoreForActor: ?(actorIdentifier: ActorIdentifier) => Store;
81
+ +_defaultRenderPolicy: RenderPolicy;
66
82
  +_getDataID: GetDataID;
67
83
  +_handlerProvider: HandlerProvider;
84
+ +_isServer: boolean;
68
85
  +_logFn: LogFunction;
86
+ +_missingFieldHandlers: ?$ReadOnlyArray<MissingFieldHandler>;
69
87
  +_operationExecutions: Map<string, ActiveState>;
88
+ +_operationLoader: ?OperationLoader;
89
+ +_reactFlightPayloadDeserializer: ?ReactFlightPayloadDeserializer;
90
+ +_reactFlightServerErrorHandler: ?ReactFlightServerErrorHandler;
70
91
  +_requiredFieldLogger: RequiredFieldLogger;
92
+ +_scheduler: ?TaskScheduler;
93
+ +_shouldProcessClientComponents: ?boolean;
71
94
  +_treatMissingFieldsAsNull: boolean;
72
95
 
73
96
  constructor(config: MultiActorEnvironmentConfig) {
74
97
  this._actorEnvironments = new Map();
98
+ this._operationLoader = config.operationLoader;
75
99
  this._createNetworkForActor = config.createNetworkForActor;
100
+ this._scheduler = config.scheduler;
76
101
  this._getDataID = config.getDataID ?? defaultGetDataID;
77
102
  this._handlerProvider = config.handlerProvider
78
103
  ? config.handlerProvider
79
104
  : RelayDefaultHandlerProvider;
80
- this._logFn = config.logFn;
105
+ this._logFn = config.logFn ?? emptyFunction;
81
106
  this._operationExecutions = new Map();
82
- this._requiredFieldLogger = config.requiredFieldLogger;
107
+ this._requiredFieldLogger =
108
+ config.requiredFieldLogger ?? defaultRequiredFieldLogger;
109
+ this._shouldProcessClientComponents = config.shouldProcessClientComponents;
83
110
  this._treatMissingFieldsAsNull = config.treatMissingFieldsAsNull ?? false;
111
+ this._isServer = config.isServer ?? false;
112
+ this._missingFieldHandlers = config.missingFieldHandlers;
113
+ this._createStoreForActor = config.createStoreForActor;
114
+ this._reactFlightPayloadDeserializer =
115
+ config.reactFlightPayloadDeserializer;
116
+ this._reactFlightServerErrorHandler = config.reactFlightServerErrorHandler;
117
+ this._createConfigNameForActor = config.createConfigNameForActor;
118
+ this._defaultRenderPolicy = config.defaultRenderPolicy ?? 'partial';
84
119
  }
85
120
 
86
121
  /**
87
- * This method will create an actor specfic environment. It will create a new instance
88
- * and store it in the internal maps. If will return a memozied version
122
+ * This method will create an actor specific environment. It will create a new instance
123
+ * and store it in the internal maps. If will return a memoized version
89
124
  * of the environment if we already created one for actor.
90
125
  */
91
- forActor(actorIdentifier: ActorIdentifier): IEnvironment & IActorEnvironment {
126
+ forActor(actorIdentifier: ActorIdentifier): IActorEnvironment {
92
127
  const environment = this._actorEnvironments.get(actorIdentifier);
93
128
  if (environment == null) {
94
129
  const newEnvironment = new ActorSpecificEnvironment({
130
+ configName: this._createConfigNameForActor
131
+ ? this._createConfigNameForActor(actorIdentifier)
132
+ : null,
95
133
  actorIdentifier,
96
134
  multiActorEnvironment: this,
97
135
  logFn: this._logFn,
98
136
  requiredFieldLogger: this._requiredFieldLogger,
99
- store: new RelayModernStore(RelayRecordSource.create()),
137
+ store:
138
+ this._createStoreForActor != null
139
+ ? this._createStoreForActor(actorIdentifier)
140
+ : new RelayModernStore(RelayRecordSource.create()),
100
141
  network: this._createNetworkForActor(actorIdentifier),
142
+ handlerProvider: this._handlerProvider,
143
+ defaultRenderPolicy: this._defaultRenderPolicy,
101
144
  });
102
145
  this._actorEnvironments.set(actorIdentifier, newEnvironment);
103
146
  return newEnvironment;
@@ -107,127 +150,336 @@ class MultiActorEnvironment implements IMultiActorEnvironment {
107
150
  }
108
151
 
109
152
  check(
110
- actorIdentifier: ActorIdentifier,
153
+ actorEnvironment: IActorEnvironment,
111
154
  operation: OperationDescriptor,
112
155
  ): OperationAvailability {
113
- return todo('check');
156
+ if (
157
+ this._missingFieldHandlers == null ||
158
+ this._missingFieldHandlers.length === 0
159
+ ) {
160
+ return actorEnvironment.getStore().check(operation, {
161
+ handlers: [],
162
+ defaultActorIdentifier: actorEnvironment.actorIdentifier,
163
+ getSourceForActor: actorIdentifier => {
164
+ return this.forActor(actorIdentifier)
165
+ .getStore()
166
+ .getSource();
167
+ },
168
+ getTargetForActor: () => {
169
+ return RelayRecordSource.create();
170
+ },
171
+ });
172
+ }
173
+ return this._checkSelectorAndHandleMissingFields(
174
+ actorEnvironment,
175
+ operation,
176
+ this._missingFieldHandlers,
177
+ );
178
+ }
179
+
180
+ _checkSelectorAndHandleMissingFields(
181
+ actorEnvironment: IActorEnvironment,
182
+ operation: OperationDescriptor,
183
+ handlers: $ReadOnlyArray<MissingFieldHandler>,
184
+ ): OperationAvailability {
185
+ const targets: Map<ActorIdentifier, MutableRecordSource> = new Map([
186
+ [actorEnvironment.actorIdentifier, RelayRecordSource.create()],
187
+ ]);
188
+ const result = actorEnvironment.getStore().check(operation, {
189
+ handlers,
190
+ defaultActorIdentifier: actorEnvironment.actorIdentifier,
191
+ getSourceForActor: actorIdentifier => {
192
+ return this.forActor(actorIdentifier)
193
+ .getStore()
194
+ .getSource();
195
+ },
196
+ getTargetForActor: actorIdentifier => {
197
+ let target = targets.get(actorIdentifier);
198
+ if (target == null) {
199
+ target = RelayRecordSource.create();
200
+ targets.set(actorIdentifier, target);
201
+ }
202
+ return target;
203
+ },
204
+ });
205
+ for (const [actorIdentifier, target] of targets) {
206
+ if (target.size() > 0) {
207
+ this._scheduleUpdates(() => {
208
+ const publishQueue = this.forActor(actorIdentifier).getPublishQueue();
209
+ publishQueue.commitSource(target);
210
+ publishQueue.run();
211
+ });
212
+ }
213
+ }
214
+
215
+ return result;
114
216
  }
115
217
 
116
218
  subscribe(
117
- actorIdentifier: ActorIdentifier,
219
+ actorEnvironment: IActorEnvironment,
118
220
  snapshot: Snapshot,
119
221
  callback: (snapshot: Snapshot) => void,
120
222
  ): Disposable {
121
- return todo('subscribe');
223
+ // TODO: make actor aware
224
+ return actorEnvironment.getStore().subscribe(snapshot, callback);
122
225
  }
123
226
 
124
227
  retain(
125
- actorIdentifier: ActorIdentifier,
228
+ actorEnvironment: IActorEnvironment,
126
229
  operation: OperationDescriptor,
127
230
  ): Disposable {
128
- return todo('retain');
231
+ // TODO: make actor aware
232
+ return actorEnvironment.getStore().retain(operation);
129
233
  }
130
234
 
131
235
  applyUpdate(
132
- actorIdentifier: ActorIdentifier,
236
+ actorEnvironment: IActorEnvironment,
133
237
  optimisticUpdate: OptimisticUpdateFunction,
134
238
  ): Disposable {
135
- return todo('applyUpdate');
239
+ const publishQueue = actorEnvironment.getPublishQueue();
240
+ const dispose = () => {
241
+ this._scheduleUpdates(() => {
242
+ publishQueue.revertUpdate(optimisticUpdate);
243
+ publishQueue.run();
244
+ });
245
+ };
246
+ this._scheduleUpdates(() => {
247
+ publishQueue.applyUpdate(optimisticUpdate);
248
+ publishQueue.run();
249
+ });
250
+ return {dispose};
251
+ }
252
+
253
+ revertUpdate(
254
+ actorEnvironment: IActorEnvironment,
255
+ update: OptimisticUpdateFunction,
256
+ ): void {
257
+ const publishQueue = actorEnvironment.getPublishQueue();
258
+ this._scheduleUpdates(() => {
259
+ publishQueue.revertUpdate(update);
260
+ publishQueue.run();
261
+ });
262
+ }
263
+
264
+ replaceUpdate(
265
+ actorEnvironment: IActorEnvironment,
266
+ update: OptimisticUpdateFunction,
267
+ replacement: OptimisticUpdateFunction,
268
+ ): void {
269
+ const publishQueue = actorEnvironment.getPublishQueue();
270
+ this._scheduleUpdates(() => {
271
+ publishQueue.revertUpdate(update);
272
+ publishQueue.applyUpdate(replacement);
273
+ publishQueue.run();
274
+ });
136
275
  }
137
276
 
138
277
  applyMutation(
139
- actorIdentifier: ActorIdentifier,
278
+ actorEnvironment: IActorEnvironment,
140
279
  optimisticConfig: OptimisticResponseConfig,
141
280
  ): Disposable {
142
- return todo('applyMutation');
281
+ const subscription = this._execute(actorEnvironment, {
282
+ createSource: () => RelayObservable.create(_sink => {}),
283
+ isClientPayload: false,
284
+ operation: optimisticConfig.operation,
285
+ optimisticConfig,
286
+ updater: null,
287
+ }).subscribe({});
288
+ return {
289
+ dispose: () => subscription.unsubscribe(),
290
+ };
143
291
  }
144
292
 
145
- commitUpdate(actorIdentifier: ActorIdentifier, updater: StoreUpdater): void {
146
- return todo('commitUpdate');
293
+ commitUpdate(
294
+ actorEnvironment: IActorEnvironment,
295
+ updater: StoreUpdater,
296
+ ): void {
297
+ const publishQueue = actorEnvironment.getPublishQueue();
298
+ this._scheduleUpdates(() => {
299
+ publishQueue.commitUpdate(updater);
300
+ publishQueue.run();
301
+ });
147
302
  }
148
303
 
149
304
  commitPayload(
150
- actorIdentifier: ActorIdentifier,
305
+ actorEnvironment: IActorEnvironment,
151
306
  operationDescriptor: OperationDescriptor,
152
307
  payload: PayloadData,
153
308
  ): void {
154
- return todo('commitPayload');
309
+ this._execute(actorEnvironment, {
310
+ createSource: () => RelayObservable.from({data: payload}),
311
+ isClientPayload: true,
312
+ operation: operationDescriptor,
313
+ optimisticConfig: null,
314
+ updater: null,
315
+ }).subscribe({});
155
316
  }
156
317
 
157
318
  lookup(
158
- actorIdentifier: ActorIdentifier,
319
+ actorEnvironment: IActorEnvironment,
159
320
  selector: SingularReaderSelector,
160
321
  ): Snapshot {
161
- return todo('lookup');
322
+ // TODO: make actor aware
323
+ return actorEnvironment.getStore().lookup(selector);
162
324
  }
163
325
 
164
326
  execute(
165
- actorIdentifier: ActorIdentifier,
166
- config: {
327
+ actorEnvironment: IActorEnvironment,
328
+ {
329
+ operation,
330
+ updater,
331
+ }: {
167
332
  operation: OperationDescriptor,
168
333
  updater?: ?SelectorStoreUpdater,
169
334
  },
170
335
  ): RelayObservable<GraphQLResponse> {
171
- const {operation, updater} = config;
172
- return RelayObservable.create(sink => {
173
- const actorEnvironemnt = this.forActor(actorIdentifier);
174
- const source = actorEnvironemnt
175
- .getNetwork()
176
- .execute(
177
- operation.request.node.params,
178
- operation.request.variables,
179
- operation.request.cacheConfig || {},
180
- null,
181
- );
182
- const executor = OperationExecutor.execute({
183
- operation,
184
- operationExecutions: this._operationExecutions,
185
- operationLoader: null,
186
- optimisticConfig: null,
187
- publishQueue: new RelayPublishQueue(
188
- actorEnvironemnt.getStore(),
189
- this._handlerProvider,
190
- this._getDataID,
191
- ),
192
- reactFlightPayloadDeserializer: null,
193
- reactFlightServerErrorHandler: null,
194
- scheduler: null,
195
- sink,
196
- source,
197
- store: actorEnvironemnt.getStore(),
198
- updater,
199
- operationTracker: actorEnvironemnt.getOperationTracker(),
200
- getDataID: this._getDataID,
201
- treatMissingFieldsAsNull: this._treatMissingFieldsAsNull,
202
- shouldProcessClientComponents: false,
203
- });
204
- return () => executor.cancel();
336
+ return this._execute(actorEnvironment, {
337
+ createSource: () =>
338
+ actorEnvironment
339
+ .getNetwork()
340
+ .execute(
341
+ operation.request.node.params,
342
+ operation.request.variables,
343
+ operation.request.cacheConfig || {},
344
+ null,
345
+ ),
346
+ isClientPayload: false,
347
+ operation,
348
+ optimisticConfig: null,
349
+ updater,
205
350
  });
206
351
  }
207
352
 
208
353
  executeMutation(
209
- actorIdentifier: ActorIdentifier,
210
- config: ExecuteMutationConfig,
354
+ actorEnvironment: IActorEnvironment,
355
+ {
356
+ operation,
357
+ optimisticResponse,
358
+ optimisticUpdater,
359
+ updater,
360
+ uploadables,
361
+ }: ExecuteMutationConfig,
211
362
  ): RelayObservable<GraphQLResponse> {
212
- return todo('executeMutation');
363
+ let optimisticConfig;
364
+ if (optimisticResponse || optimisticUpdater) {
365
+ optimisticConfig = {
366
+ operation: operation,
367
+ response: optimisticResponse,
368
+ updater: optimisticUpdater,
369
+ };
370
+ }
371
+ return this._execute(actorEnvironment, {
372
+ createSource: () =>
373
+ actorEnvironment.getNetwork().execute(
374
+ operation.request.node.params,
375
+ operation.request.variables,
376
+ {
377
+ ...operation.request.cacheConfig,
378
+ force: true,
379
+ },
380
+ uploadables,
381
+ ),
382
+ isClientPayload: false,
383
+ operation,
384
+ optimisticConfig,
385
+ updater,
386
+ });
213
387
  }
214
388
 
215
389
  executeWithSource(
216
- actorIdentifier: ActorIdentifier,
390
+ actorEnvironment: IActorEnvironment,
217
391
  config: {
218
392
  operation: OperationDescriptor,
219
393
  source: RelayObservable<GraphQLResponse>,
220
394
  },
221
395
  ): RelayObservable<GraphQLResponse> {
222
- return todo('executeWithSource');
396
+ return this._execute(actorEnvironment, {
397
+ createSource: () => config.source,
398
+ isClientPayload: false,
399
+ operation: config.operation,
400
+ optimisticConfig: null,
401
+ updater: null,
402
+ });
223
403
  }
224
404
 
225
405
  isRequestActive(
226
- actorIdentifier: ActorIdentifier,
406
+ _actorEnvironment: IActorEnvironment,
227
407
  requestIdentifier: string,
228
408
  ): boolean {
229
- return todo('isRequestActive');
409
+ const activeState = this._operationExecutions.get(requestIdentifier);
410
+ return activeState === 'active';
411
+ }
412
+
413
+ isServer(): boolean {
414
+ return this._isServer;
415
+ }
416
+
417
+ _execute(
418
+ actorEnvironment: IActorEnvironment,
419
+ {
420
+ createSource,
421
+ isClientPayload,
422
+ operation,
423
+ optimisticConfig,
424
+ updater,
425
+ }: {|
426
+ createSource: () => RelayObservable<GraphQLResponse>,
427
+ isClientPayload: boolean,
428
+ operation: OperationDescriptor,
429
+ optimisticConfig: ?OptimisticResponseConfig,
430
+ updater: ?SelectorStoreUpdater,
431
+ |},
432
+ ): RelayObservable<GraphQLResponse> {
433
+ return RelayObservable.create(sink => {
434
+ const executor = OperationExecutor.execute({
435
+ actorIdentifier: actorEnvironment.actorIdentifier,
436
+ getDataID: this._getDataID,
437
+ isClientPayload,
438
+ operation,
439
+ operationExecutions: this._operationExecutions,
440
+ operationLoader: this._operationLoader,
441
+ operationTracker: actorEnvironment.getOperationTracker(),
442
+ optimisticConfig,
443
+ getPublishQueue: (actorIdentifier: ActorIdentifier) => {
444
+ return this.forActor(actorIdentifier).getPublishQueue();
445
+ },
446
+ reactFlightPayloadDeserializer: this._reactFlightPayloadDeserializer,
447
+ reactFlightServerErrorHandler: this._reactFlightServerErrorHandler,
448
+ scheduler: this._scheduler,
449
+ shouldProcessClientComponents: this._shouldProcessClientComponents,
450
+ sink,
451
+ // NOTE: Some product tests expect `Network.execute` to be called only
452
+ // when the Observable is executed.
453
+ source: createSource(),
454
+ getStore: (actorIdentifier: ActorIdentifier) => {
455
+ return this.forActor(actorIdentifier).getStore();
456
+ },
457
+ treatMissingFieldsAsNull: this._treatMissingFieldsAsNull,
458
+ updater,
459
+ log: this._logFn,
460
+ });
461
+ return () => executor.cancel();
462
+ });
463
+ }
464
+
465
+ _scheduleUpdates(task: () => void) {
466
+ const scheduler = this._scheduler;
467
+ if (scheduler != null) {
468
+ scheduler.schedule(task);
469
+ } else {
470
+ task();
471
+ }
472
+ }
473
+
474
+ commitMultiActorUpdate(updater: MultiActorStoreUpdater): void {
475
+ for (const [actorIdentifier, environment] of this._actorEnvironments) {
476
+ environment.commitUpdate(storeProxy => {
477
+ updater(actorIdentifier, environment, storeProxy);
478
+ });
479
+ }
230
480
  }
231
481
  }
232
482
 
483
+ function emptyFunction() {}
484
+
233
485
  module.exports = MultiActorEnvironment;