relay-runtime 10.0.0 → 10.1.2
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/handlers/RelayDefaultHandlerProvider.js.flow +6 -0
- package/handlers/connection/MutationHandlers.js.flow +121 -3
- package/index.js +1 -1
- package/index.js.flow +16 -1
- package/lib/handlers/RelayDefaultHandlerProvider.js +9 -0
- package/lib/handlers/connection/MutationHandlers.js +147 -14
- package/lib/index.js +7 -0
- package/lib/mutations/RelayDeclarativeMutationConfig.js +5 -7
- package/lib/mutations/commitMutation.js +1 -4
- package/lib/mutations/validateMutation.js +28 -12
- package/lib/network/RelayQueryResponseCache.js +3 -7
- package/lib/query/GraphQLTag.js +2 -1
- package/lib/query/fetchQuery.js +2 -3
- package/lib/query/fetchQueryInternal.js +2 -3
- package/lib/store/DataChecker.js +85 -10
- package/lib/store/RelayConcreteVariables.js +2 -6
- package/lib/store/RelayModernEnvironment.js +81 -72
- package/lib/store/RelayModernFragmentSpecResolver.js +14 -7
- package/lib/store/RelayModernOperationDescriptor.js +6 -5
- package/lib/store/RelayModernQueryExecutor.js +46 -33
- package/lib/store/RelayModernRecord.js +3 -7
- package/lib/store/RelayModernStore.js +45 -143
- package/lib/store/RelayOperationTracker.js +7 -9
- package/lib/store/RelayOptimisticRecordSource.js +2 -6
- package/lib/store/RelayPublishQueue.js +1 -1
- package/lib/store/RelayReader.js +200 -49
- package/lib/store/RelayRecordSourceMapImpl.js +3 -5
- package/lib/store/RelayReferenceMarker.js +87 -5
- package/lib/store/RelayResponseNormalizer.js +123 -54
- package/lib/store/RelayStoreReactFlightUtils.js +47 -0
- package/lib/store/RelayStoreSubscriptions.js +162 -0
- package/lib/store/RelayStoreSubscriptionsUsingMapByID.js +258 -0
- package/lib/store/StoreInspector.js +3 -9
- package/lib/store/createRelayContext.js +5 -0
- package/lib/store/defaultRequiredFieldLogger.js +18 -0
- package/lib/store/normalizeRelayPayload.js +2 -6
- package/lib/subscription/requestSubscription.js +2 -3
- package/lib/util/NormalizationNode.js +1 -5
- package/lib/util/RelayConcreteNode.js +2 -0
- package/lib/util/RelayFeatureFlags.js +6 -2
- package/lib/util/createPayloadFor3DField.js +2 -7
- package/lib/util/getFragmentIdentifier.js +12 -3
- package/lib/util/getOperation.js +33 -0
- package/lib/util/isEmptyObject.js +25 -0
- package/lib/util/recycleNodesInto.js +6 -9
- package/lib/util/reportMissingRequiredFields.js +48 -0
- package/mutations/commitMutation.js.flow +1 -2
- package/mutations/validateMutation.js.flow +34 -5
- package/network/RelayNetworkTypes.js.flow +22 -0
- package/package.json +2 -2
- package/query/GraphQLTag.js.flow +3 -1
- package/query/fetchQuery.js.flow +2 -2
- package/query/fetchQueryInternal.js.flow +0 -5
- package/relay-runtime.js +2 -2
- package/relay-runtime.min.js +2 -2
- package/store/DataChecker.js.flow +68 -2
- package/store/RelayModernEnvironment.js.flow +107 -87
- package/store/RelayModernFragmentSpecResolver.js.flow +13 -1
- package/store/RelayModernOperationDescriptor.js.flow +5 -1
- package/store/RelayModernQueryExecutor.js.flow +47 -23
- package/store/RelayModernStore.js.flow +40 -114
- package/store/RelayPublishQueue.js.flow +1 -1
- package/store/RelayReader.js.flow +184 -27
- package/store/RelayReferenceMarker.js.flow +72 -5
- package/store/RelayResponseNormalizer.js.flow +140 -50
- package/store/RelayStoreReactFlightUtils.js.flow +64 -0
- package/store/RelayStoreSubscriptions.js.flow +168 -0
- package/store/RelayStoreSubscriptionsUsingMapByID.js.flow +259 -0
- package/store/RelayStoreTypes.js.flow +130 -37
- package/store/StoreInspector.js.flow +1 -3
- package/store/createRelayContext.js.flow +3 -0
- package/store/defaultRequiredFieldLogger.js.flow +23 -0
- package/subscription/requestSubscription.js.flow +5 -2
- package/util/NormalizationNode.js.flow +17 -2
- package/util/ReaderNode.js.flow +20 -1
- package/util/RelayConcreteNode.js.flow +6 -0
- package/util/RelayFeatureFlags.js.flow +10 -1
- package/util/getFragmentIdentifier.js.flow +33 -9
- package/util/getOperation.js.flow +40 -0
- package/util/isEmptyObject.js.flow +25 -0
- package/util/recycleNodesInto.js.flow +13 -8
- package/util/reportMissingRequiredFields.js.flow +51 -0
|
@@ -12,6 +12,8 @@
|
|
|
12
12
|
|
|
13
13
|
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
|
|
14
14
|
|
|
15
|
+
var _createForOfIteratorHelper2 = _interopRequireDefault(require("@babel/runtime/helpers/createForOfIteratorHelper"));
|
|
16
|
+
|
|
15
17
|
var _toConsumableArray2 = _interopRequireDefault(require("@babel/runtime/helpers/toConsumableArray"));
|
|
16
18
|
|
|
17
19
|
var RelayFeatureFlags = require('../util/RelayFeatureFlags');
|
|
@@ -20,6 +22,8 @@ var RelayModernRecord = require('./RelayModernRecord');
|
|
|
20
22
|
|
|
21
23
|
var RelayProfiler = require('../util/RelayProfiler');
|
|
22
24
|
|
|
25
|
+
var areEqual = require("fbjs/lib/areEqual");
|
|
26
|
+
|
|
23
27
|
var invariant = require("fbjs/lib/invariant");
|
|
24
28
|
|
|
25
29
|
var warning = require("fbjs/lib/warning");
|
|
@@ -28,6 +32,7 @@ var _require = require('../util/RelayConcreteNode'),
|
|
|
28
32
|
CONDITION = _require.CONDITION,
|
|
29
33
|
CLIENT_EXTENSION = _require.CLIENT_EXTENSION,
|
|
30
34
|
DEFER = _require.DEFER,
|
|
35
|
+
FLIGHT_FIELD = _require.FLIGHT_FIELD,
|
|
31
36
|
INLINE_FRAGMENT = _require.INLINE_FRAGMENT,
|
|
32
37
|
LINKED_FIELD = _require.LINKED_FIELD,
|
|
33
38
|
LINKED_HANDLE = _require.LINKED_HANDLE,
|
|
@@ -44,18 +49,25 @@ var _require2 = require('./ClientID'),
|
|
|
44
49
|
var _require3 = require('./RelayModernSelector'),
|
|
45
50
|
createNormalizationSelector = _require3.createNormalizationSelector;
|
|
46
51
|
|
|
47
|
-
var _require4 = require('./
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
52
|
+
var _require4 = require('./RelayStoreReactFlightUtils'),
|
|
53
|
+
refineToReactFlightPayloadData = _require4.refineToReactFlightPayloadData,
|
|
54
|
+
REACT_FLIGHT_QUERIES_STORAGE_KEY = _require4.REACT_FLIGHT_QUERIES_STORAGE_KEY,
|
|
55
|
+
REACT_FLIGHT_TREE_STORAGE_KEY = _require4.REACT_FLIGHT_TREE_STORAGE_KEY,
|
|
56
|
+
REACT_FLIGHT_TYPE_NAME = _require4.REACT_FLIGHT_TYPE_NAME;
|
|
57
|
+
|
|
58
|
+
var _require5 = require('./RelayStoreUtils'),
|
|
59
|
+
getArgumentValues = _require5.getArgumentValues,
|
|
60
|
+
getHandleStorageKey = _require5.getHandleStorageKey,
|
|
61
|
+
getModuleComponentKey = _require5.getModuleComponentKey,
|
|
62
|
+
getModuleOperationKey = _require5.getModuleOperationKey,
|
|
63
|
+
getStorageKey = _require5.getStorageKey,
|
|
64
|
+
TYPENAME_KEY = _require5.TYPENAME_KEY,
|
|
65
|
+
ROOT_ID = _require5.ROOT_ID,
|
|
66
|
+
ROOT_TYPE = _require5.ROOT_TYPE;
|
|
67
|
+
|
|
68
|
+
var _require6 = require('./TypeID'),
|
|
69
|
+
generateTypeID = _require6.generateTypeID,
|
|
70
|
+
TYPE_SCHEMA_TYPE = _require6.TYPE_SCHEMA_TYPE;
|
|
59
71
|
|
|
60
72
|
/**
|
|
61
73
|
* Normalizes the results of a query and standard GraphQL response, writing the
|
|
@@ -87,6 +99,7 @@ var RelayResponseNormalizer = /*#__PURE__*/function () {
|
|
|
87
99
|
this._path = options.path ? (0, _toConsumableArray2["default"])(options.path) : [];
|
|
88
100
|
this._recordSource = recordSource;
|
|
89
101
|
this._variables = variables;
|
|
102
|
+
this._reactFlightPayloadDeserializer = options.reactFlightPayloadDeserializer;
|
|
90
103
|
}
|
|
91
104
|
|
|
92
105
|
var _proto = RelayResponseNormalizer.prototype;
|
|
@@ -252,6 +265,15 @@ var RelayResponseNormalizer = /*#__PURE__*/function () {
|
|
|
252
265
|
this._isClientExtension = isClientExtension;
|
|
253
266
|
break;
|
|
254
267
|
|
|
268
|
+
case FLIGHT_FIELD:
|
|
269
|
+
if (RelayFeatureFlags.ENABLE_REACT_FLIGHT_COMPONENT_FIELD) {
|
|
270
|
+
this._normalizeFlightField(node, selection, record, data);
|
|
271
|
+
} else {
|
|
272
|
+
throw new Error('Flight fields are not yet supported.');
|
|
273
|
+
}
|
|
274
|
+
|
|
275
|
+
break;
|
|
276
|
+
|
|
255
277
|
default:
|
|
256
278
|
selection;
|
|
257
279
|
!false ? process.env.NODE_ENV !== "production" ? invariant(false, 'RelayResponseNormalizer(): Unexpected ast kind `%s`.', selection.kind) : invariant(false) : void 0;
|
|
@@ -366,8 +388,10 @@ var RelayResponseNormalizer = /*#__PURE__*/function () {
|
|
|
366
388
|
}
|
|
367
389
|
}
|
|
368
390
|
|
|
369
|
-
if (
|
|
370
|
-
|
|
391
|
+
if (process.env.NODE_ENV !== "production") {
|
|
392
|
+
if (selection.kind === SCALAR_FIELD) {
|
|
393
|
+
this._validateConflictingFieldsWithIdenticalId(record, storageKey, fieldValue);
|
|
394
|
+
}
|
|
371
395
|
}
|
|
372
396
|
|
|
373
397
|
RelayModernRecord.setValue(record, storageKey, null);
|
|
@@ -375,7 +399,9 @@ var RelayResponseNormalizer = /*#__PURE__*/function () {
|
|
|
375
399
|
}
|
|
376
400
|
|
|
377
401
|
if (selection.kind === SCALAR_FIELD) {
|
|
378
|
-
|
|
402
|
+
if (process.env.NODE_ENV !== "production") {
|
|
403
|
+
this._validateConflictingFieldsWithIdenticalId(record, storageKey, fieldValue);
|
|
404
|
+
}
|
|
379
405
|
|
|
380
406
|
RelayModernRecord.setValue(record, storageKey, fieldValue);
|
|
381
407
|
} else if (selection.kind === LINKED_FIELD) {
|
|
@@ -394,20 +420,76 @@ var RelayResponseNormalizer = /*#__PURE__*/function () {
|
|
|
394
420
|
}
|
|
395
421
|
};
|
|
396
422
|
|
|
423
|
+
_proto._normalizeFlightField = function _normalizeFlightField(parent, selection, record, data) {
|
|
424
|
+
var responseKey = selection.alias || selection.name;
|
|
425
|
+
var storageKey = getStorageKey(selection, this._variables);
|
|
426
|
+
var fieldValue = data[responseKey];
|
|
427
|
+
|
|
428
|
+
if (fieldValue == null) {
|
|
429
|
+
RelayModernRecord.setValue(record, storageKey, null);
|
|
430
|
+
return;
|
|
431
|
+
}
|
|
432
|
+
|
|
433
|
+
var reactFlightPayload = refineToReactFlightPayloadData(fieldValue);
|
|
434
|
+
!(reactFlightPayload != null) ? process.env.NODE_ENV !== "production" ? invariant(false, 'RelayResponseNormalizer(): Expected React Flight payload data ' + 'to be an object with `tree` and `queries` properties, got `%s`.', fieldValue) : invariant(false) : void 0;
|
|
435
|
+
!(typeof this._reactFlightPayloadDeserializer === 'function') ? process.env.NODE_ENV !== "production" ? invariant(false, 'RelayResponseNormalizer: Expected reactFlightPayloadDeserializer to ' + 'be a function, got `%s`.', this._reactFlightPayloadDeserializer) : invariant(false) : void 0; // We store the deserialized reactFlightClientResponse in a separate
|
|
436
|
+
// record and link it to the parent record. This is so we can GC the Flight
|
|
437
|
+
// tree later even if the parent record is still reachable.
|
|
438
|
+
|
|
439
|
+
var reactFlightClientResponse = this._reactFlightPayloadDeserializer(reactFlightPayload.tree);
|
|
440
|
+
|
|
441
|
+
var reactFlightID = generateClientID(RelayModernRecord.getDataID(record), getStorageKey(selection, this._variables));
|
|
442
|
+
|
|
443
|
+
var reactFlightClientResponseRecord = this._recordSource.get(reactFlightID);
|
|
444
|
+
|
|
445
|
+
if (reactFlightClientResponseRecord == null) {
|
|
446
|
+
reactFlightClientResponseRecord = RelayModernRecord.create(reactFlightID, REACT_FLIGHT_TYPE_NAME);
|
|
447
|
+
|
|
448
|
+
this._recordSource.set(reactFlightID, reactFlightClientResponseRecord);
|
|
449
|
+
}
|
|
450
|
+
|
|
451
|
+
RelayModernRecord.setValue(reactFlightClientResponseRecord, REACT_FLIGHT_TREE_STORAGE_KEY, reactFlightClientResponse);
|
|
452
|
+
var reachableQueries = [];
|
|
453
|
+
|
|
454
|
+
var _iterator = (0, _createForOfIteratorHelper2["default"])(reactFlightPayload.queries),
|
|
455
|
+
_step;
|
|
456
|
+
|
|
457
|
+
try {
|
|
458
|
+
for (_iterator.s(); !(_step = _iterator.n()).done;) {
|
|
459
|
+
var query = _step.value;
|
|
460
|
+
|
|
461
|
+
if (query.response.data != null) {
|
|
462
|
+
this._moduleImportPayloads.push({
|
|
463
|
+
data: query.response.data,
|
|
464
|
+
dataID: ROOT_ID,
|
|
465
|
+
operationReference: query.module,
|
|
466
|
+
path: [],
|
|
467
|
+
typeName: ROOT_TYPE,
|
|
468
|
+
variables: query.variables
|
|
469
|
+
});
|
|
470
|
+
}
|
|
471
|
+
|
|
472
|
+
reachableQueries.push({
|
|
473
|
+
module: query.module,
|
|
474
|
+
variables: query.variables
|
|
475
|
+
});
|
|
476
|
+
}
|
|
477
|
+
} catch (err) {
|
|
478
|
+
_iterator.e(err);
|
|
479
|
+
} finally {
|
|
480
|
+
_iterator.f();
|
|
481
|
+
}
|
|
482
|
+
|
|
483
|
+
RelayModernRecord.setValue(reactFlightClientResponseRecord, REACT_FLIGHT_QUERIES_STORAGE_KEY, reachableQueries);
|
|
484
|
+
RelayModernRecord.setLinkedRecordID(record, storageKey, reactFlightID);
|
|
485
|
+
};
|
|
486
|
+
|
|
397
487
|
_proto._normalizeLink = function _normalizeLink(field, record, storageKey, fieldValue) {
|
|
398
488
|
var _field$concreteType;
|
|
399
489
|
|
|
400
490
|
!(typeof fieldValue === 'object' && fieldValue) ? process.env.NODE_ENV !== "production" ? invariant(false, 'RelayResponseNormalizer: Expected data for field `%s` to be an object.', storageKey) : invariant(false) : void 0;
|
|
401
|
-
var nextID = this._getDataId(
|
|
402
|
-
|
|
403
|
-
* native_fb,oss) This comment suppresses an error found when Flow
|
|
404
|
-
* v0.98 was deployed. To see the error delete this comment and run
|
|
405
|
-
* Flow. */
|
|
406
|
-
fieldValue,
|
|
407
|
-
/* $FlowFixMe[incompatible-variance] (>=0.98.0 site=www,mobile,react_
|
|
408
|
-
* native_fb,oss) This comment suppresses an error found when Flow
|
|
409
|
-
* v0.98 was deployed. To see the error delete this comment and run
|
|
410
|
-
* Flow. */
|
|
491
|
+
var nextID = this._getDataId( // $FlowFixMe[incompatible-variance]
|
|
492
|
+
fieldValue, // $FlowFixMe[incompatible-variance]
|
|
411
493
|
(_field$concreteType = field.concreteType) !== null && _field$concreteType !== void 0 ? _field$concreteType : this._getRecordType(fieldValue)) || // Reuse previously generated client IDs
|
|
412
494
|
RelayModernRecord.getLinkedRecordID(record, storageKey) || generateClientID(RelayModernRecord.getDataID(record), storageKey);
|
|
413
495
|
!(typeof nextID === 'string') ? process.env.NODE_ENV !== "production" ? invariant(false, 'RelayResponseNormalizer: Expected id on field `%s` to be a string.', storageKey) : invariant(false) : void 0;
|
|
@@ -421,9 +503,7 @@ var RelayResponseNormalizer = /*#__PURE__*/function () {
|
|
|
421
503
|
var nextRecord = this._recordSource.get(nextID);
|
|
422
504
|
|
|
423
505
|
if (!nextRecord) {
|
|
424
|
-
|
|
425
|
-
* native_fb,oss) This comment suppresses an error found when Flow v0.98
|
|
426
|
-
* was deployed. To see the error delete this comment and run Flow. */
|
|
506
|
+
// $FlowFixMe[incompatible-variance]
|
|
427
507
|
var _typeName4 = field.concreteType || this._getRecordType(fieldValue);
|
|
428
508
|
|
|
429
509
|
nextRecord = RelayModernRecord.create(nextID, _typeName4);
|
|
@@ -431,10 +511,7 @@ var RelayResponseNormalizer = /*#__PURE__*/function () {
|
|
|
431
511
|
this._recordSource.set(nextID, nextRecord);
|
|
432
512
|
} else if (process.env.NODE_ENV !== "production") {
|
|
433
513
|
this._validateRecordType(nextRecord, field, fieldValue);
|
|
434
|
-
}
|
|
435
|
-
/* $FlowFixMe[incompatible-variance] (>=0.98.0 site=www,mobile,react_native_
|
|
436
|
-
* fb,oss) This comment suppresses an error found when Flow v0.98 was
|
|
437
|
-
* deployed. To see the error delete this comment and run Flow. */
|
|
514
|
+
} // $FlowFixMe[incompatible-variance]
|
|
438
515
|
|
|
439
516
|
|
|
440
517
|
this._traverseSelections(field, nextRecord, fieldValue);
|
|
@@ -458,16 +535,8 @@ var RelayResponseNormalizer = /*#__PURE__*/function () {
|
|
|
458
535
|
_this._path.push(String(nextIndex));
|
|
459
536
|
|
|
460
537
|
!(typeof item === 'object') ? process.env.NODE_ENV !== "production" ? invariant(false, 'RelayResponseNormalizer: Expected elements for field `%s` to be ' + 'objects.', storageKey) : invariant(false) : void 0;
|
|
461
|
-
var nextID = _this._getDataId(
|
|
462
|
-
|
|
463
|
-
* native_fb,oss) This comment suppresses an error found when Flow
|
|
464
|
-
* v0.98 was deployed. To see the error delete this comment and run
|
|
465
|
-
* Flow. */
|
|
466
|
-
item,
|
|
467
|
-
/* $FlowFixMe[incompatible-variance] (>=0.98.0 site=www,mobile,react_
|
|
468
|
-
* native_fb,oss) This comment suppresses an error found when Flow
|
|
469
|
-
* v0.98 was deployed. To see the error delete this comment and run
|
|
470
|
-
* Flow. */
|
|
538
|
+
var nextID = _this._getDataId( // $FlowFixMe[incompatible-variance]
|
|
539
|
+
item, // $FlowFixMe[incompatible-variance]
|
|
471
540
|
(_field$concreteType2 = field.concreteType) !== null && _field$concreteType2 !== void 0 ? _field$concreteType2 : _this._getRecordType(item)) || prevIDs && prevIDs[nextIndex] || // Reuse previously generated client IDs:
|
|
472
541
|
generateClientID(RelayModernRecord.getDataID(record), storageKey, nextIndex);
|
|
473
542
|
!(typeof nextID === 'string') ? process.env.NODE_ENV !== "production" ? invariant(false, 'RelayResponseNormalizer: Expected id of elements of field `%s` to ' + 'be strings.', storageKey) : invariant(false) : void 0;
|
|
@@ -476,10 +545,7 @@ var RelayResponseNormalizer = /*#__PURE__*/function () {
|
|
|
476
545
|
var nextRecord = _this._recordSource.get(nextID);
|
|
477
546
|
|
|
478
547
|
if (!nextRecord) {
|
|
479
|
-
|
|
480
|
-
* native_fb,oss) This comment suppresses an error found when Flow
|
|
481
|
-
* v0.98 was deployed. To see the error delete this comment and run
|
|
482
|
-
* Flow. */
|
|
548
|
+
// $FlowFixMe[incompatible-variance]
|
|
483
549
|
var _typeName5 = field.concreteType || _this._getRecordType(item);
|
|
484
550
|
|
|
485
551
|
nextRecord = RelayModernRecord.create(nextID, _typeName5);
|
|
@@ -487,14 +553,15 @@ var RelayResponseNormalizer = /*#__PURE__*/function () {
|
|
|
487
553
|
_this._recordSource.set(nextID, nextRecord);
|
|
488
554
|
} else if (process.env.NODE_ENV !== "production") {
|
|
489
555
|
_this._validateRecordType(nextRecord, field, item);
|
|
490
|
-
}
|
|
556
|
+
} // NOTE: the check to strip __DEV__ code only works for simple
|
|
557
|
+
// `if (__DEV__)`
|
|
491
558
|
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
559
|
+
|
|
560
|
+
if (process.env.NODE_ENV !== "production") {
|
|
561
|
+
if (prevIDs) {
|
|
562
|
+
_this._validateConflictingLinkedFieldsWithIdenticalId(record, prevIDs[nextIndex], nextID, storageKey);
|
|
563
|
+
}
|
|
564
|
+
} // $FlowFixMe[incompatible-variance]
|
|
498
565
|
|
|
499
566
|
|
|
500
567
|
_this._traverseSelections(field, nextRecord, item);
|
|
@@ -521,10 +588,11 @@ var RelayResponseNormalizer = /*#__PURE__*/function () {
|
|
|
521
588
|
;
|
|
522
589
|
|
|
523
590
|
_proto._validateConflictingFieldsWithIdenticalId = function _validateConflictingFieldsWithIdenticalId(record, storageKey, fieldValue) {
|
|
591
|
+
// NOTE: Only call this function in DEV
|
|
524
592
|
if (process.env.NODE_ENV !== "production") {
|
|
525
593
|
var dataID = RelayModernRecord.getDataID(record);
|
|
526
594
|
var previousValue = RelayModernRecord.getValue(record, storageKey);
|
|
527
|
-
process.env.NODE_ENV !== "production" ? warning(storageKey === TYPENAME_KEY || previousValue === undefined || previousValue
|
|
595
|
+
process.env.NODE_ENV !== "production" ? warning(storageKey === TYPENAME_KEY || previousValue === undefined || areEqual(previousValue, fieldValue), 'RelayResponseNormalizer: Invalid record. The record contains two ' + 'instances of the same id: `%s` with conflicting field, %s and its values: %s and %s. ' + 'If two fields are different but share ' + 'the same id, one field will overwrite the other.', dataID, storageKey, previousValue, fieldValue) : void 0;
|
|
528
596
|
}
|
|
529
597
|
}
|
|
530
598
|
/**
|
|
@@ -533,6 +601,7 @@ var RelayResponseNormalizer = /*#__PURE__*/function () {
|
|
|
533
601
|
;
|
|
534
602
|
|
|
535
603
|
_proto._validateConflictingLinkedFieldsWithIdenticalId = function _validateConflictingLinkedFieldsWithIdenticalId(record, prevID, nextID, storageKey) {
|
|
604
|
+
// NOTE: Only call this function in DEV
|
|
536
605
|
if (process.env.NODE_ENV !== "production") {
|
|
537
606
|
process.env.NODE_ENV !== "production" ? warning(prevID === undefined || prevID === nextID, 'RelayResponseNormalizer: Invalid record. The record contains ' + 'references to the conflicting field, %s and its id values: %s and %s. ' + 'We need to make sure that the record the field points ' + 'to remains consistent or one field will overwrite the other.', storageKey, prevID, nextID) : void 0;
|
|
538
607
|
}
|
|
@@ -0,0 +1,47 @@
|
|
|
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
|
+
*
|
|
8
|
+
* @format
|
|
9
|
+
*/
|
|
10
|
+
// flowlint ambiguous-object-type:error
|
|
11
|
+
'use strict';
|
|
12
|
+
|
|
13
|
+
var invariant = require("fbjs/lib/invariant");
|
|
14
|
+
|
|
15
|
+
var _require = require('./RelayModernRecord'),
|
|
16
|
+
getType = _require.getType;
|
|
17
|
+
|
|
18
|
+
var REACT_FLIGHT_QUERIES_STORAGE_KEY = 'queries';
|
|
19
|
+
var REACT_FLIGHT_TREE_STORAGE_KEY = 'tree';
|
|
20
|
+
var REACT_FLIGHT_TYPE_NAME = 'ReactFlightComponent';
|
|
21
|
+
|
|
22
|
+
function refineToReactFlightPayloadData(payload) {
|
|
23
|
+
if (payload == null || typeof payload !== 'object' || !Array.isArray(payload.tree) || !Array.isArray(payload.queries)) {
|
|
24
|
+
return null;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
return payload;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
function getReactFlightClientResponse(record) {
|
|
31
|
+
!(getType(record) === REACT_FLIGHT_TYPE_NAME) ? process.env.NODE_ENV !== "production" ? invariant(false, 'getReactFlightClientResponse(): Expected a ReactFlightComponentRecord, ' + 'got %s.', record) : invariant(false) : void 0;
|
|
32
|
+
var response = record[REACT_FLIGHT_TREE_STORAGE_KEY];
|
|
33
|
+
|
|
34
|
+
if (response != null) {
|
|
35
|
+
return response;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
return null;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
module.exports = {
|
|
42
|
+
REACT_FLIGHT_QUERIES_STORAGE_KEY: REACT_FLIGHT_QUERIES_STORAGE_KEY,
|
|
43
|
+
REACT_FLIGHT_TREE_STORAGE_KEY: REACT_FLIGHT_TREE_STORAGE_KEY,
|
|
44
|
+
REACT_FLIGHT_TYPE_NAME: REACT_FLIGHT_TYPE_NAME,
|
|
45
|
+
getReactFlightClientResponse: getReactFlightClientResponse,
|
|
46
|
+
refineToReactFlightPayloadData: refineToReactFlightPayloadData
|
|
47
|
+
};
|
|
@@ -0,0 +1,162 @@
|
|
|
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
|
+
*
|
|
8
|
+
* @format
|
|
9
|
+
*/
|
|
10
|
+
// flowlint ambiguous-object-type:error
|
|
11
|
+
'use strict';
|
|
12
|
+
|
|
13
|
+
var RelayReader = require('./RelayReader');
|
|
14
|
+
|
|
15
|
+
var deepFreeze = require('../util/deepFreeze');
|
|
16
|
+
|
|
17
|
+
var hasOverlappingIDs = require('./hasOverlappingIDs');
|
|
18
|
+
|
|
19
|
+
var isEmptyObject = require('../util/isEmptyObject');
|
|
20
|
+
|
|
21
|
+
var recycleNodesInto = require('../util/recycleNodesInto');
|
|
22
|
+
|
|
23
|
+
var RelayStoreSubscriptions = /*#__PURE__*/function () {
|
|
24
|
+
function RelayStoreSubscriptions() {
|
|
25
|
+
this._subscriptions = new Set();
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
var _proto = RelayStoreSubscriptions.prototype;
|
|
29
|
+
|
|
30
|
+
_proto.subscribe = function subscribe(snapshot, callback) {
|
|
31
|
+
var _this = this;
|
|
32
|
+
|
|
33
|
+
var subscription = {
|
|
34
|
+
backup: null,
|
|
35
|
+
callback: callback,
|
|
36
|
+
snapshot: snapshot,
|
|
37
|
+
stale: false
|
|
38
|
+
};
|
|
39
|
+
|
|
40
|
+
var dispose = function dispose() {
|
|
41
|
+
_this._subscriptions["delete"](subscription);
|
|
42
|
+
};
|
|
43
|
+
|
|
44
|
+
this._subscriptions.add(subscription);
|
|
45
|
+
|
|
46
|
+
return {
|
|
47
|
+
dispose: dispose
|
|
48
|
+
};
|
|
49
|
+
};
|
|
50
|
+
|
|
51
|
+
_proto.snapshotSubscriptions = function snapshotSubscriptions(source) {
|
|
52
|
+
this._subscriptions.forEach(function (subscription) {
|
|
53
|
+
// Backup occurs after writing a new "final" payload(s) and before (re)applying
|
|
54
|
+
// optimistic changes. Each subscription's `snapshot` represents what was *last
|
|
55
|
+
// published to the subscriber*, which notably may include previous optimistic
|
|
56
|
+
// updates. Therefore a subscription can be in any of the following states:
|
|
57
|
+
// - stale=true: This subscription was restored to a different value than
|
|
58
|
+
// `snapshot`. That means this subscription has changes relative to its base,
|
|
59
|
+
// but its base has changed (we just applied a final payload): recompute
|
|
60
|
+
// a backup so that we can later restore to the state the subscription
|
|
61
|
+
// should be in.
|
|
62
|
+
// - stale=false: This subscription was restored to the same value than
|
|
63
|
+
// `snapshot`. That means this subscription does *not* have changes relative
|
|
64
|
+
// to its base, so the current `snapshot` is valid to use as a backup.
|
|
65
|
+
if (!subscription.stale) {
|
|
66
|
+
subscription.backup = subscription.snapshot;
|
|
67
|
+
return;
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
var snapshot = subscription.snapshot;
|
|
71
|
+
var backup = RelayReader.read(source, snapshot.selector);
|
|
72
|
+
var nextData = recycleNodesInto(snapshot.data, backup.data);
|
|
73
|
+
backup.data = nextData; // backup owns the snapshot and can safely mutate
|
|
74
|
+
|
|
75
|
+
subscription.backup = backup;
|
|
76
|
+
});
|
|
77
|
+
};
|
|
78
|
+
|
|
79
|
+
_proto.restoreSubscriptions = function restoreSubscriptions() {
|
|
80
|
+
this._subscriptions.forEach(function (subscription) {
|
|
81
|
+
var backup = subscription.backup;
|
|
82
|
+
subscription.backup = null;
|
|
83
|
+
|
|
84
|
+
if (backup) {
|
|
85
|
+
if (backup.data !== subscription.snapshot.data) {
|
|
86
|
+
subscription.stale = true;
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
subscription.snapshot = {
|
|
90
|
+
data: subscription.snapshot.data,
|
|
91
|
+
isMissingData: backup.isMissingData,
|
|
92
|
+
seenRecords: backup.seenRecords,
|
|
93
|
+
selector: backup.selector,
|
|
94
|
+
missingRequiredFields: backup.missingRequiredFields
|
|
95
|
+
};
|
|
96
|
+
} else {
|
|
97
|
+
subscription.stale = true;
|
|
98
|
+
}
|
|
99
|
+
});
|
|
100
|
+
};
|
|
101
|
+
|
|
102
|
+
_proto.updateSubscriptions = function updateSubscriptions(source, updatedRecordIDs, updatedOwners) {
|
|
103
|
+
var _this2 = this;
|
|
104
|
+
|
|
105
|
+
var hasUpdatedRecords = !isEmptyObject(updatedRecordIDs);
|
|
106
|
+
|
|
107
|
+
this._subscriptions.forEach(function (subscription) {
|
|
108
|
+
var owner = _this2._updateSubscription(source, subscription, updatedRecordIDs, hasUpdatedRecords);
|
|
109
|
+
|
|
110
|
+
if (owner != null) {
|
|
111
|
+
updatedOwners.push(owner);
|
|
112
|
+
}
|
|
113
|
+
});
|
|
114
|
+
}
|
|
115
|
+
/**
|
|
116
|
+
* Notifies the callback for the subscription if the data for the associated
|
|
117
|
+
* snapshot has changed.
|
|
118
|
+
* Additionally, updates the subscription snapshot with the latest snapshot,
|
|
119
|
+
* and marks it as not stale.
|
|
120
|
+
* Returns the owner (RequestDescriptor) if the subscription was affected by the
|
|
121
|
+
* latest update, or null if it was not affected.
|
|
122
|
+
*/
|
|
123
|
+
;
|
|
124
|
+
|
|
125
|
+
_proto._updateSubscription = function _updateSubscription(source, subscription, updatedRecordIDs, hasUpdatedRecords) {
|
|
126
|
+
var backup = subscription.backup,
|
|
127
|
+
callback = subscription.callback,
|
|
128
|
+
snapshot = subscription.snapshot,
|
|
129
|
+
stale = subscription.stale;
|
|
130
|
+
var hasOverlappingUpdates = hasUpdatedRecords && hasOverlappingIDs(snapshot.seenRecords, updatedRecordIDs);
|
|
131
|
+
|
|
132
|
+
if (!stale && !hasOverlappingUpdates) {
|
|
133
|
+
return;
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
var nextSnapshot = hasOverlappingUpdates || !backup ? RelayReader.read(source, snapshot.selector) : backup;
|
|
137
|
+
var nextData = recycleNodesInto(snapshot.data, nextSnapshot.data);
|
|
138
|
+
nextSnapshot = {
|
|
139
|
+
data: nextData,
|
|
140
|
+
isMissingData: nextSnapshot.isMissingData,
|
|
141
|
+
seenRecords: nextSnapshot.seenRecords,
|
|
142
|
+
selector: nextSnapshot.selector,
|
|
143
|
+
missingRequiredFields: nextSnapshot.missingRequiredFields
|
|
144
|
+
};
|
|
145
|
+
|
|
146
|
+
if (process.env.NODE_ENV !== "production") {
|
|
147
|
+
deepFreeze(nextSnapshot);
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
subscription.snapshot = nextSnapshot;
|
|
151
|
+
subscription.stale = false;
|
|
152
|
+
|
|
153
|
+
if (nextSnapshot.data !== snapshot.data) {
|
|
154
|
+
callback(nextSnapshot);
|
|
155
|
+
return snapshot.selector.owner;
|
|
156
|
+
}
|
|
157
|
+
};
|
|
158
|
+
|
|
159
|
+
return RelayStoreSubscriptions;
|
|
160
|
+
}();
|
|
161
|
+
|
|
162
|
+
module.exports = RelayStoreSubscriptions;
|