relay-runtime 4.0.0 → 5.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.
- package/index.js +1 -1
- package/lib/ClientID.js +1 -1
- package/lib/ConvertToExecuteFunction.js +1 -1
- package/lib/DataChecker.js +10 -9
- package/lib/NormalizationNode.js +1 -1
- package/lib/ReaderNode.js +1 -1
- package/lib/RelayCombinedEnvironmentTypes.js +1 -1
- package/lib/RelayConcreteNode.js +1 -1
- package/lib/RelayConnectionHandler.js +1 -1
- package/lib/RelayConnectionInterface.js +1 -1
- package/lib/RelayDefaultHandleKey.js +1 -1
- package/lib/RelayDefaultHandlerProvider.js +1 -6
- package/lib/RelayDefaultMissingFieldHandlers.js +26 -0
- package/lib/RelayFeatureFlags.js +3 -5
- package/lib/RelayModernEnvironment.js +30 -20
- package/lib/RelayModernFragmentOwner.js +1 -1
- package/lib/RelayModernFragmentSpecResolver.js +36 -49
- package/lib/RelayModernOperationDescriptor.js +1 -1
- package/lib/RelayModernQueryExecutor.js +200 -92
- package/lib/RelayModernSelector.js +36 -16
- package/lib/RelayModernStore.js +14 -8
- package/lib/RelayNetwork.js +1 -1
- package/lib/RelayNetworkLogger.js +1 -1
- package/lib/RelayNetworkTypes.js +1 -1
- package/lib/RelayObservable.js +69 -40
- package/lib/RelayOperationTracker.js +26 -39
- package/lib/RelayPublishQueue.js +24 -19
- package/lib/RelayQueryResponseCache.js +1 -1
- package/lib/RelayReader.js +23 -5
- package/lib/RelayRecordProxy.js +7 -3
- package/lib/RelayRecordSourceMutator.js +1 -1
- package/lib/RelayRecordSourceProxy.js +5 -2
- package/lib/RelayRecordSourceSelectorProxy.js +1 -1
- package/lib/RelayRecordState.js +1 -1
- package/lib/RelayReferenceMarker.js +4 -3
- package/lib/RelayReplaySubject.js +1 -1
- package/lib/RelayResponseNormalizer.js +57 -19
- package/lib/RelayRuntimeTypes.js +1 -1
- package/lib/RelayStoreUtils.js +39 -9
- package/lib/RelayViewerHandler.js +2 -49
- package/lib/StoreInspector.js +1 -1
- package/lib/cloneRelayHandleSourceField.js +1 -1
- package/lib/commitLocalUpdate.js +1 -1
- package/lib/createRelayContext.js +1 -1
- package/lib/deepFreeze.js +1 -1
- package/lib/defaultGetDataID.js +24 -0
- package/lib/fetchQueryInternal.js +1 -1
- package/lib/fetchRelayModernQuery.js +1 -1
- package/lib/getFragmentIdentifier.js +1 -1
- package/lib/getFragmentSpecIdentifier.js +1 -1
- package/lib/getRequestParametersIdentifier.js +1 -1
- package/lib/hasOverlappingIDs.js +1 -1
- package/lib/index.js +5 -0
- package/lib/isPromise.js +1 -1
- package/lib/isScalarAndEqual.js +1 -1
- package/lib/normalizeRelayPayload.js +2 -5
- package/lib/recycleNodesInto.js +7 -1
- package/package.json +2 -2
- package/relay-runtime.js +2 -2
- package/relay-runtime.min.js +2 -2
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
* This source code is licensed under the MIT license found in the
|
|
5
5
|
* LICENSE file in the root directory of this source tree.
|
|
6
6
|
*
|
|
7
|
-
*
|
|
7
|
+
*
|
|
8
8
|
* @format
|
|
9
9
|
* @emails oncall+relay
|
|
10
10
|
*/
|
|
@@ -16,8 +16,6 @@ var _toConsumableArray2 = _interopRequireDefault(require("@babel/runtime/helpers
|
|
|
16
16
|
|
|
17
17
|
var RelayError = require("./RelayError");
|
|
18
18
|
|
|
19
|
-
var RelayFeatureFlags = require("./RelayFeatureFlags");
|
|
20
|
-
|
|
21
19
|
var RelayInMemoryRecordSource = require("./RelayInMemoryRecordSource");
|
|
22
20
|
|
|
23
21
|
var RelayModernRecord = require("./RelayModernRecord");
|
|
@@ -28,6 +26,11 @@ var RelayResponseNormalizer = require("./RelayResponseNormalizer");
|
|
|
28
26
|
|
|
29
27
|
var invariant = require("fbjs/lib/invariant");
|
|
30
28
|
|
|
29
|
+
var stableCopy = require("./stableCopy"); // flowlint-next-line untyped-import:off
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
var warning = require("fbjs/lib/warning");
|
|
33
|
+
|
|
31
34
|
var _require = require("./ClientID"),
|
|
32
35
|
generateClientID = _require.generateClientID;
|
|
33
36
|
|
|
@@ -62,8 +65,9 @@ function () {
|
|
|
62
65
|
sink = _ref.sink,
|
|
63
66
|
source = _ref.source,
|
|
64
67
|
updater = _ref.updater,
|
|
65
|
-
operationTracker = _ref.operationTracker
|
|
66
|
-
|
|
68
|
+
operationTracker = _ref.operationTracker,
|
|
69
|
+
getDataID = _ref.getDataID;
|
|
70
|
+
this._incrementalResults = new Map();
|
|
67
71
|
this._nextSubscriptionId = 0;
|
|
68
72
|
this._operation = operation;
|
|
69
73
|
this._operationLoader = operationLoader;
|
|
@@ -76,13 +80,14 @@ function () {
|
|
|
76
80
|
this._updater = updater;
|
|
77
81
|
this._subscriptions = new Map();
|
|
78
82
|
this._operationTracker = operationTracker;
|
|
83
|
+
this._getDataID = getDataID;
|
|
79
84
|
var id = this._nextSubscriptionId++;
|
|
80
85
|
source.subscribe({
|
|
81
86
|
complete: function complete() {
|
|
82
87
|
return _this._complete(id);
|
|
83
88
|
},
|
|
84
89
|
error: function error(_error2) {
|
|
85
|
-
return _this._error(
|
|
90
|
+
return _this._error(_error2);
|
|
86
91
|
},
|
|
87
92
|
next: function next(response) {
|
|
88
93
|
try {
|
|
@@ -133,7 +138,7 @@ function () {
|
|
|
133
138
|
this._publishQueue.run();
|
|
134
139
|
}
|
|
135
140
|
|
|
136
|
-
this.
|
|
141
|
+
this._incrementalResults.clear();
|
|
137
142
|
|
|
138
143
|
this._completeOperationTracker();
|
|
139
144
|
};
|
|
@@ -163,7 +168,7 @@ function () {
|
|
|
163
168
|
return _this2._complete(_id2);
|
|
164
169
|
},
|
|
165
170
|
error: function error(_error3) {
|
|
166
|
-
return _this2._error(
|
|
171
|
+
return _this2._error(_error3);
|
|
167
172
|
},
|
|
168
173
|
start: function start(subscription) {
|
|
169
174
|
return _this2._start(_id2, subscription);
|
|
@@ -184,7 +189,7 @@ function () {
|
|
|
184
189
|
}
|
|
185
190
|
};
|
|
186
191
|
|
|
187
|
-
_proto._error = function _error(
|
|
192
|
+
_proto._error = function _error(error) {
|
|
188
193
|
this.cancel();
|
|
189
194
|
|
|
190
195
|
this._sink.error(error);
|
|
@@ -192,8 +197,8 @@ function () {
|
|
|
192
197
|
|
|
193
198
|
_proto._start = function _start(id, subscription) {
|
|
194
199
|
this._subscriptions.set(id, subscription);
|
|
195
|
-
}
|
|
196
|
-
|
|
200
|
+
} // Handle a raw GraphQL response.
|
|
201
|
+
;
|
|
197
202
|
|
|
198
203
|
_proto._next = function _next(_id, response) {
|
|
199
204
|
var _this3 = this;
|
|
@@ -245,10 +250,14 @@ function () {
|
|
|
245
250
|
label = response.label;
|
|
246
251
|
|
|
247
252
|
if (path != null || label != null) {
|
|
248
|
-
if (typeof label
|
|
249
|
-
|
|
253
|
+
if (typeof label === 'string' && Array.isArray(path)) {
|
|
254
|
+
this._processIncrementalResponse({
|
|
255
|
+
path: path,
|
|
256
|
+
label: label,
|
|
257
|
+
response: responseWithData
|
|
258
|
+
});
|
|
250
259
|
} else {
|
|
251
|
-
|
|
260
|
+
!false ? process.env.NODE_ENV !== "production" ? invariant(false, 'RelayModernQueryExecutor: invalid incremental payload, expected ' + '`path` and `label` to either both be null/undefined, or ' + '`path` to be an `Array<string | number>` and `label` to be a ' + '`string`.') : invariant(false) : void 0;
|
|
252
261
|
}
|
|
253
262
|
} else {
|
|
254
263
|
this._processResponse(responseWithData);
|
|
@@ -262,7 +271,7 @@ function () {
|
|
|
262
271
|
!(this._optimisticUpdate === null) ? process.env.NODE_ENV !== "production" ? invariant(false, 'environment.execute: only support one optimistic response per ' + 'execute.') : invariant(false) : void 0;
|
|
263
272
|
var payload = normalizeResponse(response, this._operation.root, ROOT_TYPE, []
|
|
264
273
|
/* path */
|
|
265
|
-
);
|
|
274
|
+
, this._getDataID);
|
|
266
275
|
var incrementalPlaceholders = payload.incrementalPlaceholders,
|
|
267
276
|
moduleImportPayloads = payload.moduleImportPayloads;
|
|
268
277
|
|
|
@@ -283,6 +292,8 @@ function () {
|
|
|
283
292
|
};
|
|
284
293
|
|
|
285
294
|
_proto._processResponse = function _processResponse(response) {
|
|
295
|
+
var _response$extensions2;
|
|
296
|
+
|
|
286
297
|
if (this._optimisticUpdate !== null) {
|
|
287
298
|
this._publishQueue.revertUpdate(this._optimisticUpdate);
|
|
288
299
|
|
|
@@ -291,9 +302,9 @@ function () {
|
|
|
291
302
|
|
|
292
303
|
var payload = normalizeResponse(response, this._operation.root, ROOT_TYPE, []
|
|
293
304
|
/* path */
|
|
294
|
-
);
|
|
305
|
+
, this._getDataID);
|
|
295
306
|
|
|
296
|
-
this.
|
|
307
|
+
this._incrementalResults.clear();
|
|
297
308
|
|
|
298
309
|
this._source.clear();
|
|
299
310
|
|
|
@@ -304,12 +315,20 @@ function () {
|
|
|
304
315
|
var updatedOwners = this._publishQueue.run();
|
|
305
316
|
|
|
306
317
|
this._updateOperationTracker(updatedOwners);
|
|
307
|
-
|
|
318
|
+
|
|
319
|
+
if (payload.incrementalPlaceholders && payload.incrementalPlaceholders.length !== 0 && ((_response$extensions2 = response.extensions) === null || _response$extensions2 === void 0 ? void 0 : _response$extensions2.is_final) === true) {
|
|
320
|
+
// The query has defer/stream selections that are enabled, but the server
|
|
321
|
+
// indicated that this is a "final" payload: no incremental payloads will
|
|
322
|
+
// be delivered. Warn that the query was (likely) executed on the server
|
|
323
|
+
// in non-streaming mode, with incremental delivery disabled.
|
|
324
|
+
process.env.NODE_ENV !== "production" ? warning(false, 'RelayModernEnvironment: Operation `%s` contains @defer/@stream ' + 'directives but was executed in non-streaming mode. See ' + 'https://fburl.com/relay-incremental-delivery-non-streaming-warning.', this._operation.node.params.name) : void 0;
|
|
325
|
+
}
|
|
326
|
+
}
|
|
308
327
|
/**
|
|
309
328
|
* Handles any follow-up actions for a Relay payload for @match, @defer,
|
|
310
329
|
* and (in the future) @stream directives.
|
|
311
330
|
*/
|
|
312
|
-
|
|
331
|
+
;
|
|
313
332
|
|
|
314
333
|
_proto._processPayloadFollowups = function _processPayloadFollowups(payload) {
|
|
315
334
|
var _this4 = this;
|
|
@@ -326,12 +345,11 @@ function () {
|
|
|
326
345
|
}
|
|
327
346
|
|
|
328
347
|
if (incrementalPlaceholders && incrementalPlaceholders.length !== 0) {
|
|
329
|
-
!RelayFeatureFlags.ENABLE_INCREMENTAL_DELIVERY ? process.env.NODE_ENV !== "production" ? invariant(false, 'RelayModernEnvironment: Unexpected use of @defer/@stream in ' + 'operation `%s`.', this._operation.node.params.name) : invariant(false) : void 0;
|
|
330
348
|
incrementalPlaceholders.forEach(function (incrementalPlaceholder) {
|
|
331
349
|
_this4._processIncrementalPlaceholder(payload, incrementalPlaceholder);
|
|
332
350
|
});
|
|
333
351
|
}
|
|
334
|
-
}
|
|
352
|
+
}
|
|
335
353
|
/**
|
|
336
354
|
* Processes a ModuleImportPayload, asynchronously resolving the normalization
|
|
337
355
|
* AST and using it to normalize the field data into a RelayResponsePayload.
|
|
@@ -339,34 +357,47 @@ function () {
|
|
|
339
357
|
* defer, stream, etc); these are handled by calling
|
|
340
358
|
* `_processPayloadFollowups()`.
|
|
341
359
|
*/
|
|
342
|
-
|
|
360
|
+
;
|
|
343
361
|
|
|
344
362
|
_proto._processModuleImportPayload = function _processModuleImportPayload(moduleImportPayload, operationLoader) {
|
|
345
363
|
var _this5 = this;
|
|
346
364
|
|
|
347
|
-
var
|
|
348
|
-
// thrown by the load function, which is user-defined. Guard against that
|
|
349
|
-
// with Observable.from(new Promise(<work>)).
|
|
365
|
+
var syncOperation = operationLoader.get(moduleImportPayload.operationReference);
|
|
350
366
|
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
_this5.
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
367
|
+
if (syncOperation != null) {
|
|
368
|
+
// If the operation module is available synchronously, normalize the
|
|
369
|
+
// data synchronously.
|
|
370
|
+
this._schedule(function () {
|
|
371
|
+
_this5._handleModuleImportPayload(moduleImportPayload, syncOperation);
|
|
372
|
+
});
|
|
373
|
+
} else {
|
|
374
|
+
// Otherwise load the operation module and schedule a task to normalize
|
|
375
|
+
// the data when the module is available.
|
|
376
|
+
var _id3 = this._nextSubscriptionId++; // Observable.from(operationLoader.load()) wouldn't catch synchronous
|
|
377
|
+
// errors thrown by the load function, which is user-defined. Guard
|
|
378
|
+
// against that with Observable.from(new Promise(<work>)).
|
|
379
|
+
|
|
380
|
+
|
|
381
|
+
RelayObservable.from(new Promise(function (resolve, reject) {
|
|
382
|
+
operationLoader.load(moduleImportPayload.operationReference).then(resolve, reject);
|
|
383
|
+
})).map(function (operation) {
|
|
384
|
+
if (operation != null) {
|
|
385
|
+
_this5._schedule(function () {
|
|
386
|
+
_this5._handleModuleImportPayload(moduleImportPayload, operation);
|
|
387
|
+
});
|
|
388
|
+
}
|
|
389
|
+
}).subscribe({
|
|
390
|
+
complete: function complete() {
|
|
391
|
+
return _this5._complete(_id3);
|
|
392
|
+
},
|
|
393
|
+
error: function error(_error4) {
|
|
394
|
+
return _this5._error(_error4);
|
|
395
|
+
},
|
|
396
|
+
start: function start(subscription) {
|
|
397
|
+
return _this5._start(_id3, subscription);
|
|
398
|
+
}
|
|
399
|
+
});
|
|
400
|
+
}
|
|
370
401
|
};
|
|
371
402
|
|
|
372
403
|
_proto._handleModuleImportPayload = function _handleModuleImportPayload(moduleImportPayload, operation) {
|
|
@@ -377,7 +408,7 @@ function () {
|
|
|
377
408
|
};
|
|
378
409
|
var relayPayload = normalizeResponse({
|
|
379
410
|
data: moduleImportPayload.data
|
|
380
|
-
}, selector, moduleImportPayload.typeName, moduleImportPayload.path);
|
|
411
|
+
}, selector, moduleImportPayload.typeName, moduleImportPayload.path, this._getDataID);
|
|
381
412
|
|
|
382
413
|
this._processPayloadFollowups(relayPayload);
|
|
383
414
|
|
|
@@ -386,39 +417,44 @@ function () {
|
|
|
386
417
|
var updatedOwners = this._publishQueue.run();
|
|
387
418
|
|
|
388
419
|
this._updateOperationTracker(updatedOwners);
|
|
389
|
-
}
|
|
420
|
+
}
|
|
390
421
|
/**
|
|
391
|
-
*
|
|
392
|
-
*
|
|
393
|
-
*
|
|
394
|
-
*
|
|
395
|
-
*
|
|
422
|
+
* The executor now knows that GraphQL responses are expected for a given
|
|
423
|
+
* label/path:
|
|
424
|
+
* - Store the placeholder in order to process any future responses that may
|
|
425
|
+
* arrive.
|
|
426
|
+
* - Then process any responses that had already arrived.
|
|
427
|
+
*
|
|
428
|
+
* The placeholder contains the normalization selector, path (for nested
|
|
429
|
+
* defer/stream), and other metadata used to normalize the incremental
|
|
430
|
+
* response(s).
|
|
396
431
|
*/
|
|
397
|
-
|
|
432
|
+
;
|
|
398
433
|
|
|
399
434
|
_proto._processIncrementalPlaceholder = function _processIncrementalPlaceholder(relayPayload, placeholder) {
|
|
435
|
+
var _this6 = this;
|
|
436
|
+
|
|
400
437
|
var _relayPayload$fieldPa;
|
|
401
438
|
|
|
402
439
|
// Update the label => path => placeholder map
|
|
403
|
-
var
|
|
404
|
-
label = placeholder.label,
|
|
440
|
+
var label = placeholder.label,
|
|
405
441
|
path = placeholder.path;
|
|
406
442
|
var pathKey = path.map(String).join('.');
|
|
407
443
|
|
|
408
|
-
var
|
|
444
|
+
var resultForLabel = this._incrementalResults.get(label);
|
|
409
445
|
|
|
410
|
-
if (
|
|
411
|
-
|
|
412
|
-
kind: kind,
|
|
413
|
-
placeholdersByPath: new Map()
|
|
414
|
-
};
|
|
446
|
+
if (resultForLabel == null) {
|
|
447
|
+
resultForLabel = new Map();
|
|
415
448
|
|
|
416
|
-
this.
|
|
417
|
-
} else if (dataForLabel.kind !== kind) {
|
|
418
|
-
!false ? process.env.NODE_ENV !== "production" ? invariant(false, 'RelayModernEnvironment: Received inconsistent data for label `%s`, ' + 'expected `@%s` data but got `@%s` data.', label, dataForLabel.kind, kind) : invariant(false) : void 0;
|
|
449
|
+
this._incrementalResults.set(label, resultForLabel);
|
|
419
450
|
}
|
|
420
451
|
|
|
421
|
-
|
|
452
|
+
var resultForPath = resultForLabel.get(pathKey);
|
|
453
|
+
var pendingResponses = resultForPath != null && resultForPath.kind === 'response' ? resultForPath.responses : null;
|
|
454
|
+
resultForLabel.set(pathKey, {
|
|
455
|
+
kind: 'placeholder',
|
|
456
|
+
placeholder: placeholder
|
|
457
|
+
}); // Store references to the parent node to allow detecting concurrent
|
|
422
458
|
// modifications to the parent before items arrive and to replay
|
|
423
459
|
// handle field payloads to account for new information on source records.
|
|
424
460
|
|
|
@@ -438,34 +474,86 @@ function () {
|
|
|
438
474
|
// ancestor.field links to the parent record (example: connections)
|
|
439
475
|
fieldID === parentID
|
|
440
476
|
);
|
|
441
|
-
}); //
|
|
442
|
-
//
|
|
477
|
+
}); // If an incremental payload exists for some id that record should also
|
|
478
|
+
// exist.
|
|
479
|
+
|
|
480
|
+
!(parentRecord != null) ? process.env.NODE_ENV !== "production" ? invariant(false, 'RelayModernEnvironment: Expected record `%s` to exist.', parentID) : invariant(false) : void 0;
|
|
481
|
+
var nextParentRecord;
|
|
482
|
+
var nextParentPayloads;
|
|
483
|
+
|
|
484
|
+
var previousParentEntry = this._source.get(parentID);
|
|
485
|
+
|
|
486
|
+
if (previousParentEntry != null) {
|
|
487
|
+
// If a previous entry exists, merge the previous/next records and
|
|
488
|
+
// payloads together.
|
|
489
|
+
nextParentRecord = RelayModernRecord.update(previousParentEntry.record, parentRecord);
|
|
490
|
+
var handlePayloads = new Map();
|
|
491
|
+
|
|
492
|
+
var dedupePayload = function dedupePayload(payload) {
|
|
493
|
+
var key = stableStringify(payload);
|
|
494
|
+
handlePayloads.set(key, payload);
|
|
495
|
+
};
|
|
496
|
+
|
|
497
|
+
previousParentEntry.fieldPayloads.forEach(dedupePayload);
|
|
498
|
+
parentPayloads.forEach(dedupePayload);
|
|
499
|
+
nextParentPayloads = Array.from(handlePayloads.values());
|
|
500
|
+
} else {
|
|
501
|
+
nextParentRecord = parentRecord;
|
|
502
|
+
nextParentPayloads = parentPayloads;
|
|
503
|
+
}
|
|
443
504
|
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
505
|
+
this._source.set(parentID, {
|
|
506
|
+
record: nextParentRecord,
|
|
507
|
+
fieldPayloads: nextParentPayloads
|
|
508
|
+
}); // If there were any queued responses, process them now that placeholders
|
|
509
|
+
// are in place
|
|
510
|
+
|
|
511
|
+
|
|
512
|
+
if (pendingResponses != null) {
|
|
513
|
+
pendingResponses.forEach(function (incrementalResponse) {
|
|
514
|
+
_this6._schedule(function () {
|
|
515
|
+
_this6._processIncrementalResponse(incrementalResponse);
|
|
516
|
+
});
|
|
448
517
|
});
|
|
449
518
|
}
|
|
450
|
-
}
|
|
519
|
+
}
|
|
451
520
|
/**
|
|
452
521
|
* Lookup the placeholder the describes how to process an incremental
|
|
453
522
|
* response, normalize/publish it, and process any nested defer/match/stream
|
|
454
523
|
* metadata.
|
|
455
524
|
*/
|
|
525
|
+
;
|
|
456
526
|
|
|
527
|
+
_proto._processIncrementalResponse = function _processIncrementalResponse(incrementalResponse) {
|
|
528
|
+
var label = incrementalResponse.label,
|
|
529
|
+
path = incrementalResponse.path,
|
|
530
|
+
response = incrementalResponse.response;
|
|
457
531
|
|
|
458
|
-
|
|
459
|
-
!RelayFeatureFlags.ENABLE_INCREMENTAL_DELIVERY ? process.env.NODE_ENV !== "production" ? invariant(false, 'RelayModernEnvironment: Unexpected use of @defer/@stream in ' + 'operation `%s`.', this._operation.node.params.name) : invariant(false) : void 0;
|
|
532
|
+
var resultForLabel = this._incrementalResults.get(label);
|
|
460
533
|
|
|
461
|
-
|
|
534
|
+
if (resultForLabel == null) {
|
|
535
|
+
resultForLabel = new Map();
|
|
462
536
|
|
|
463
|
-
|
|
537
|
+
this._incrementalResults.set(label, resultForLabel);
|
|
538
|
+
}
|
|
464
539
|
|
|
465
|
-
if (
|
|
540
|
+
if (label.indexOf('$defer$') !== -1) {
|
|
466
541
|
var pathKey = path.map(String).join('.');
|
|
467
|
-
var
|
|
468
|
-
|
|
542
|
+
var resultForPath = resultForLabel.get(pathKey);
|
|
543
|
+
|
|
544
|
+
if (resultForPath == null) {
|
|
545
|
+
resultForPath = {
|
|
546
|
+
kind: 'response',
|
|
547
|
+
responses: [incrementalResponse]
|
|
548
|
+
};
|
|
549
|
+
resultForLabel.set(pathKey, resultForPath);
|
|
550
|
+
return;
|
|
551
|
+
} else if (resultForPath.kind === 'response') {
|
|
552
|
+
resultForPath.responses.push(incrementalResponse);
|
|
553
|
+
return;
|
|
554
|
+
}
|
|
555
|
+
|
|
556
|
+
var placeholder = resultForPath.placeholder;
|
|
469
557
|
!(placeholder.kind === 'defer') ? process.env.NODE_ENV !== "production" ? invariant(false, 'RelayModernEnvironment: Expected data for path `%s` for label `%s` ' + 'to be data for @defer, was `@%s`.', pathKey, label, placeholder.kind) : invariant(false) : void 0;
|
|
470
558
|
|
|
471
559
|
this._processDeferResponse(label, path, placeholder, response);
|
|
@@ -476,9 +564,22 @@ function () {
|
|
|
476
564
|
// (the item index is used later to insert the element in the list)
|
|
477
565
|
var _pathKey = path.slice(0, -2).map(String).join('.');
|
|
478
566
|
|
|
479
|
-
var
|
|
567
|
+
var _resultForPath = resultForLabel.get(_pathKey);
|
|
568
|
+
|
|
569
|
+
if (_resultForPath == null) {
|
|
570
|
+
_resultForPath = {
|
|
571
|
+
kind: 'response',
|
|
572
|
+
responses: [incrementalResponse]
|
|
573
|
+
};
|
|
574
|
+
resultForLabel.set(_pathKey, _resultForPath);
|
|
575
|
+
return;
|
|
576
|
+
} else if (_resultForPath.kind === 'response') {
|
|
577
|
+
_resultForPath.responses.push(incrementalResponse);
|
|
578
|
+
|
|
579
|
+
return;
|
|
580
|
+
}
|
|
480
581
|
|
|
481
|
-
|
|
582
|
+
var _placeholder = _resultForPath.placeholder;
|
|
482
583
|
!(_placeholder.kind === 'stream') ? process.env.NODE_ENV !== "production" ? invariant(false, 'RelayModernEnvironment: Expected data for path `%s` for label `%s` ' + 'to be data for @stream, was `@%s`.', _pathKey, label, _placeholder.kind) : invariant(false) : void 0;
|
|
483
584
|
|
|
484
585
|
this._processStreamResponse(label, path, _placeholder, response);
|
|
@@ -487,7 +588,7 @@ function () {
|
|
|
487
588
|
|
|
488
589
|
_proto._processDeferResponse = function _processDeferResponse(label, path, placeholder, response) {
|
|
489
590
|
var parentID = placeholder.selector.dataID;
|
|
490
|
-
var relayPayload = normalizeResponse(response, placeholder.selector, placeholder.typeName, placeholder.path);
|
|
591
|
+
var relayPayload = normalizeResponse(response, placeholder.selector, placeholder.typeName, placeholder.path, this._getDataID);
|
|
491
592
|
|
|
492
593
|
this._processPayloadFollowups(relayPayload);
|
|
493
594
|
|
|
@@ -515,14 +616,14 @@ function () {
|
|
|
515
616
|
var updatedOwners = this._publishQueue.run();
|
|
516
617
|
|
|
517
618
|
this._updateOperationTracker(updatedOwners);
|
|
518
|
-
}
|
|
619
|
+
}
|
|
519
620
|
/**
|
|
520
621
|
* Process the data for one item in a @stream field.
|
|
521
622
|
*/
|
|
522
|
-
|
|
623
|
+
;
|
|
523
624
|
|
|
524
625
|
_proto._processStreamResponse = function _processStreamResponse(label, path, placeholder, response) {
|
|
525
|
-
var _field$alias,
|
|
626
|
+
var _field$alias, _field$concreteType, _this$_getDataID;
|
|
526
627
|
|
|
527
628
|
var parentID = placeholder.parentID,
|
|
528
629
|
node = placeholder.node,
|
|
@@ -549,10 +650,12 @@ function () {
|
|
|
549
650
|
|
|
550
651
|
var finalPathEntry = path[path.length - 1];
|
|
551
652
|
var itemIndex = parseInt(finalPathEntry, 10);
|
|
552
|
-
!(itemIndex === finalPathEntry && itemIndex >= 0) ? process.env.NODE_ENV !== "production" ? invariant(false, 'RelayModernEnvironment: Expected path for @stream to end in a ' + 'positive integer index, got `%s`', finalPathEntry) : invariant(false) : void 0;
|
|
653
|
+
!(itemIndex === finalPathEntry && itemIndex >= 0) ? process.env.NODE_ENV !== "production" ? invariant(false, 'RelayModernEnvironment: Expected path for @stream to end in a ' + 'positive integer index, got `%s`', finalPathEntry) : invariant(false) : void 0;
|
|
654
|
+
var typeName = (_field$concreteType = field.concreteType) !== null && _field$concreteType !== void 0 ? _field$concreteType : data[TYPENAME_KEY];
|
|
655
|
+
!(typeof typeName === 'string') ? process.env.NODE_ENV !== "production" ? invariant(false, 'RelayModernEnvironment: Expected @stream field `%s` to have a ' + '__typename.', field.name) : invariant(false) : void 0; // Determine the __id of the new item: this must equal the value that would
|
|
553
656
|
// be assigned had the item not been streamed
|
|
554
657
|
|
|
555
|
-
var itemID = ((
|
|
658
|
+
var itemID = ((_this$_getDataID = this._getDataID(data, typeName)) !== null && _this$_getDataID !== void 0 ? _this$_getDataID : prevIDs && prevIDs[itemIndex]) || // Reuse previously generated client IDs
|
|
556
659
|
generateClientID(parentID, storageKey, itemIndex);
|
|
557
660
|
!(typeof itemID === 'string') ? process.env.NODE_ENV !== "production" ? invariant(false, 'RelayModernEnvironment: Expected id of elements of field `%s` to ' + 'be strings.', storageKey) : invariant(false) : void 0; // Build a selector to normalize the item data with
|
|
558
661
|
|
|
@@ -560,9 +663,7 @@ function () {
|
|
|
560
663
|
dataID: itemID,
|
|
561
664
|
node: field,
|
|
562
665
|
variables: variables
|
|
563
|
-
};
|
|
564
|
-
var typeName = (_field$concreteType = field.concreteType) !== null && _field$concreteType !== void 0 ? _field$concreteType : data[TYPENAME_KEY];
|
|
565
|
-
!(typeof typeName === 'string') ? process.env.NODE_ENV !== "production" ? invariant(false, 'RelayModernEnvironment: Expected @stream field `%s` to have a ' + '__typename.', field.name) : invariant(false) : void 0; // Update the cached version of the parent record to reflect the new item:
|
|
666
|
+
}; // Update the cached version of the parent record to reflect the new item:
|
|
566
667
|
// this is used when subsequent stream payloads arrive to see if there
|
|
567
668
|
// have been concurrent modifications to the list
|
|
568
669
|
|
|
@@ -579,7 +680,7 @@ function () {
|
|
|
579
680
|
// modified.
|
|
580
681
|
|
|
581
682
|
|
|
582
|
-
var relayPayload = normalizeResponse(response, selector, typeName, (0, _toConsumableArray2["default"])(placeholder.path)
|
|
683
|
+
var relayPayload = normalizeResponse(response, selector, typeName, [].concat((0, _toConsumableArray2["default"])(placeholder.path), [responseKey, String(itemIndex)]), this._getDataID);
|
|
583
684
|
|
|
584
685
|
this._processPayloadFollowups(relayPayload);
|
|
585
686
|
|
|
@@ -659,7 +760,7 @@ function () {
|
|
|
659
760
|
return Executor;
|
|
660
761
|
}();
|
|
661
762
|
|
|
662
|
-
function normalizeResponse(response, selector, typeName, path) {
|
|
763
|
+
function normalizeResponse(response, selector, typeName, path, getDataID) {
|
|
663
764
|
var data = response.data,
|
|
664
765
|
errors = response.errors;
|
|
665
766
|
var source = new RelayInMemoryRecordSource();
|
|
@@ -667,7 +768,8 @@ function normalizeResponse(response, selector, typeName, path) {
|
|
|
667
768
|
source.set(selector.dataID, record);
|
|
668
769
|
var normalizeResult = RelayResponseNormalizer.normalize(source, selector, data, {
|
|
669
770
|
handleStrippedNulls: true,
|
|
670
|
-
path: path
|
|
771
|
+
path: path,
|
|
772
|
+
getDataID: getDataID
|
|
671
773
|
});
|
|
672
774
|
return {
|
|
673
775
|
errors: errors,
|
|
@@ -678,6 +780,12 @@ function normalizeResponse(response, selector, typeName, path) {
|
|
|
678
780
|
};
|
|
679
781
|
}
|
|
680
782
|
|
|
783
|
+
function stableStringify(value) {
|
|
784
|
+
var _JSON$stringify;
|
|
785
|
+
|
|
786
|
+
return (_JSON$stringify = JSON.stringify(stableCopy(value))) !== null && _JSON$stringify !== void 0 ? _JSON$stringify : ''; // null-check for flow
|
|
787
|
+
}
|
|
788
|
+
|
|
681
789
|
module.exports = {
|
|
682
790
|
execute: execute
|
|
683
791
|
};
|
|
@@ -9,8 +9,6 @@
|
|
|
9
9
|
*/
|
|
10
10
|
'use strict';
|
|
11
11
|
|
|
12
|
-
var RelayFeatureFlags = require("./RelayFeatureFlags");
|
|
13
|
-
|
|
14
12
|
var areEqual = require("fbjs/lib/areEqual");
|
|
15
13
|
|
|
16
14
|
var invariant = require("fbjs/lib/invariant");
|
|
@@ -69,7 +67,11 @@ function getSingularSelector(operationVariables, fragment, item, explicitOwner)
|
|
|
69
67
|
if (explicitOwner != null && typeof explicitOwner === 'object') {
|
|
70
68
|
var ownerOperationVariables = explicitOwner.variables;
|
|
71
69
|
|
|
72
|
-
var _fragmentVariables = getFragmentVariables(fragment, ownerOperationVariables,
|
|
70
|
+
var _fragmentVariables = getFragmentVariables(fragment, ownerOperationVariables,
|
|
71
|
+
/* $FlowFixMe(>=0.98.0 site=www,mobile,react_native_fb,oss) This comment
|
|
72
|
+
* suppresses an error found when Flow v0.98 was deployed. To see the
|
|
73
|
+
* error delete this comment and run Flow. */
|
|
74
|
+
argumentVariables);
|
|
73
75
|
|
|
74
76
|
return {
|
|
75
77
|
owner: explicitOwner,
|
|
@@ -87,7 +89,11 @@ function getSingularSelector(operationVariables, fragment, item, explicitOwner)
|
|
|
87
89
|
|
|
88
90
|
|
|
89
91
|
var owner = (_ref = (_explicitOwner = explicitOwner) !== null && _explicitOwner !== void 0 ? _explicitOwner : item[FRAGMENT_OWNER_KEY]) !== null && _ref !== void 0 ? _ref : null;
|
|
90
|
-
var fragmentVariables = getFragmentVariables(fragment, operationVariables,
|
|
92
|
+
var fragmentVariables = getFragmentVariables(fragment, operationVariables,
|
|
93
|
+
/* $FlowFixMe(>=0.98.0 site=www,mobile,react_native_fb,oss) This comment
|
|
94
|
+
* suppresses an error found when Flow v0.98 was deployed. To see the
|
|
95
|
+
* error delete this comment and run Flow. */
|
|
96
|
+
argumentVariables);
|
|
91
97
|
return {
|
|
92
98
|
// $FlowFixMe - TODO T39154660
|
|
93
99
|
owner: owner,
|
|
@@ -152,9 +158,17 @@ function getSelector(operationVariables, fragment, item, explicitOwner) {
|
|
|
152
158
|
|
|
153
159
|
if (explicitOwner !== undefined) {
|
|
154
160
|
!Array.isArray(explicitOwner) ? process.env.NODE_ENV !== "production" ? invariant(false, 'RelayModernSelector: Expected explcitly provided owner for ' + 'fragment `%s` to be an array, got `%s`.', fragment.name, JSON.stringify(explicitOwner)) : invariant(false) : void 0;
|
|
155
|
-
selectorOrSelectors = getPluralSelector(operationVariables, fragment,
|
|
161
|
+
selectorOrSelectors = getPluralSelector(operationVariables, fragment,
|
|
162
|
+
/* $FlowFixMe(>=0.98.0 site=www,mobile,react_native_fb,oss) This comment
|
|
163
|
+
* suppresses an error found when Flow v0.98 was deployed. To see the
|
|
164
|
+
* error delete this comment and run Flow. */
|
|
165
|
+
item, explicitOwner);
|
|
156
166
|
} else {
|
|
157
|
-
selectorOrSelectors = getPluralSelector(operationVariables, fragment,
|
|
167
|
+
selectorOrSelectors = getPluralSelector(operationVariables, fragment,
|
|
168
|
+
/* $FlowFixMe(>=0.98.0 site=www,mobile,react_native_fb,oss) This comment
|
|
169
|
+
* suppresses an error found when Flow v0.98 was deployed. To see the
|
|
170
|
+
* error delete this comment and run Flow. */
|
|
171
|
+
item);
|
|
158
172
|
}
|
|
159
173
|
} else {
|
|
160
174
|
!!Array.isArray(item) ? process.env.NODE_ENV !== "production" ? invariant(false, 'RelayModernSelector: Expected value for fragment `%s` to be an object, got `%s`. ' + 'Add `@relay(plural: true)` to fragment `%s` to allow the prop to be an array of items.', fragment.name, JSON.stringify(item), fragment.name) : invariant(false) : void 0;
|
|
@@ -233,6 +247,10 @@ function getDataIDsFromFragment(fragment, item) {
|
|
|
233
247
|
idOrIDs = item;
|
|
234
248
|
} else if (fragment.metadata && fragment.metadata.plural === true) {
|
|
235
249
|
!Array.isArray(item) ? process.env.NODE_ENV !== "production" ? invariant(false, 'RelayModernSelector: Expected value for fragment `%s` to be an array, got `%s`. ' + 'Remove `@relay(plural: true)` from fragment `%s` to allow the prop to be an object.', fragment.name, JSON.stringify(item), fragment.name) : invariant(false) : void 0;
|
|
250
|
+
/* $FlowFixMe(>=0.98.0 site=www,mobile,react_native_fb,oss) This comment
|
|
251
|
+
* suppresses an error found when Flow v0.98 was deployed. To see the error
|
|
252
|
+
* delete this comment and run Flow. */
|
|
253
|
+
|
|
236
254
|
idOrIDs = getDataIDs(fragment, item);
|
|
237
255
|
} else {
|
|
238
256
|
!!Array.isArray(item) ? process.env.NODE_ENV !== "production" ? invariant(false, 'RelayModernFragmentSpecResolver: Expected value for fragment `%s` to be an object, got `%s`. ' + 'Add `@relay(plural: true)` to fragment `%s` to allow the prop to be an array of items.', fragment.name, JSON.stringify(item), fragment.name) : invariant(false) : void 0;
|
|
@@ -320,8 +338,15 @@ function getVariablesFromFragment(operationVariables, fragment, item, explicitOw
|
|
|
320
338
|
|
|
321
339
|
if (explicitOwner !== undefined) {
|
|
322
340
|
!Array.isArray(explicitOwner) ? process.env.NODE_ENV !== "production" ? invariant(false, 'RelayModernSelector: Expected explcitly provided owner for ' + 'fragment `%s` to be an array, got `%s`.', fragment.name, JSON.stringify(explicitOwner)) : invariant(false) : void 0;
|
|
323
|
-
return getVariablesFromPluralFragment(operationVariables, fragment,
|
|
341
|
+
return getVariablesFromPluralFragment(operationVariables, fragment,
|
|
342
|
+
/* $FlowFixMe(>=0.98.0 site=www,mobile,react_native_fb,oss) This comment
|
|
343
|
+
* suppresses an error found when Flow v0.98 was deployed. To see the
|
|
344
|
+
* error delete this comment and run Flow. */
|
|
345
|
+
item, explicitOwner);
|
|
324
346
|
} else {
|
|
347
|
+
/* $FlowFixMe(>=0.98.0 site=www,mobile,react_native_fb,oss) This comment
|
|
348
|
+
* suppresses an error found when Flow v0.98 was deployed. To see the
|
|
349
|
+
* error delete this comment and run Flow. */
|
|
325
350
|
return getVariablesFromPluralFragment(operationVariables, fragment, item);
|
|
326
351
|
}
|
|
327
352
|
} else {
|
|
@@ -371,16 +396,11 @@ function getVariablesFromPluralFragment(operationVariables, fragment, items, own
|
|
|
371
396
|
|
|
372
397
|
function areEqualSelectors(thisSelector, thatSelector) {
|
|
373
398
|
var areVariablesEqual = areEqual(thisSelector.selector.variables, thatSelector.selector.variables);
|
|
374
|
-
var areReaderSelectorsEqual = thisSelector.selector.dataID === thatSelector.selector.dataID && thisSelector.selector.node === thatSelector.selector.node && areVariablesEqual;
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
// NOTE: If fragment ownership is enabled, we should also compare if
|
|
378
|
-
// the owners attached to the selectors are the same, otherwise we might
|
|
379
|
-
// skip setting a new selector that has a new owner.
|
|
380
|
-
return areReaderSelectorsEqual && thisSelector.owner === thatSelector.owner;
|
|
381
|
-
}
|
|
399
|
+
var areReaderSelectorsEqual = thisSelector.selector.dataID === thatSelector.selector.dataID && thisSelector.selector.node === thatSelector.selector.node && areVariablesEqual; // NOTE: With fragment ownership we need to also compare if
|
|
400
|
+
// the owners attached to the selectors are the same, otherwise we might
|
|
401
|
+
// skip setting a new selector that has a new owner.
|
|
382
402
|
|
|
383
|
-
return areReaderSelectorsEqual;
|
|
403
|
+
return areReaderSelectorsEqual && thisSelector.owner === thatSelector.owner;
|
|
384
404
|
}
|
|
385
405
|
|
|
386
406
|
module.exports = {
|