relay-runtime 18.2.0 → 19.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/experimental.js +1 -1
- package/experimental.js.flow +8 -6
- package/index.js +1 -1
- package/index.js.flow +3 -0
- package/lib/experimental.js +5 -2
- package/lib/index.js +3 -0
- package/lib/multi-actor-environment/ActorSpecificEnvironment.js +1 -1
- package/lib/mutations/RelayRecordSourceProxy.js +2 -1
- package/lib/mutations/createUpdatableProxy.js +1 -1
- package/lib/mutations/validateMutation.js +2 -2
- package/lib/network/RelayObservable.js +1 -3
- package/lib/network/wrapNetworkWithLogObserver.js +2 -2
- package/lib/query/fetchQuery.js +1 -1
- package/lib/store/DataChecker.js +4 -5
- package/lib/store/OperationExecutor.js +11 -0
- package/lib/store/RelayModernEnvironment.js +13 -4
- package/lib/store/RelayModernFragmentSpecResolver.js +4 -4
- package/lib/store/RelayModernStore.js +43 -21
- package/lib/store/RelayPublishQueue.js +11 -15
- package/lib/store/RelayReader.js +131 -151
- package/lib/store/RelayReferenceMarker.js +3 -4
- package/lib/store/RelayResponseNormalizer.js +47 -26
- package/lib/store/RelayStoreSubscriptions.js +2 -2
- package/lib/store/RelayStoreUtils.js +8 -0
- package/lib/store/ResolverFragments.js +2 -2
- package/lib/store/createRelayLoggingContext.js +17 -0
- package/lib/store/generateTypenamePrefixedDataID.js +9 -0
- package/lib/store/live-resolvers/LiveResolverCache.js +2 -1
- package/lib/store/live-resolvers/resolverDataInjector.js +4 -4
- package/lib/store/observeFragmentExperimental.js +60 -13
- package/lib/store/observeQueryExperimental.js +21 -0
- package/lib/util/RelayFeatureFlags.js +6 -1
- package/lib/util/handlePotentialSnapshotErrors.js +11 -8
- package/multi-actor-environment/ActorSpecificEnvironment.js.flow +1 -0
- package/mutations/RelayRecordSourceProxy.js.flow +4 -0
- package/mutations/createUpdatableProxy.js.flow +1 -1
- package/mutations/validateMutation.js.flow +3 -3
- package/network/RelayNetworkTypes.js.flow +3 -0
- package/network/RelayObservable.js.flow +1 -5
- package/network/wrapNetworkWithLogObserver.js.flow +19 -1
- package/package.json +1 -1
- package/query/fetchQuery.js.flow +1 -1
- package/store/DataChecker.js.flow +5 -2
- package/store/OperationExecutor.js.flow +12 -1
- package/store/RelayExperimentalGraphResponseTransform.js.flow +4 -4
- package/store/RelayModernEnvironment.js.flow +22 -6
- package/store/RelayModernFragmentSpecResolver.js.flow +6 -6
- package/store/RelayModernSelector.js.flow +2 -0
- package/store/RelayModernStore.js.flow +74 -27
- package/store/RelayPublishQueue.js.flow +32 -21
- package/store/RelayReader.js.flow +159 -96
- package/store/RelayReferenceMarker.js.flow +3 -4
- package/store/RelayResponseNormalizer.js.flow +93 -67
- package/store/RelayStoreSubscriptions.js.flow +2 -2
- package/store/RelayStoreTypes.js.flow +33 -4
- package/store/RelayStoreUtils.js.flow +29 -0
- package/store/ResolverCache.js.flow +2 -2
- package/store/ResolverFragments.js.flow +5 -3
- package/store/StoreInspector.js.flow +5 -0
- package/store/createRelayContext.js.flow +3 -2
- package/store/createRelayLoggingContext.js.flow +46 -0
- package/store/generateTypenamePrefixedDataID.js.flow +25 -0
- package/store/live-resolvers/LiveResolverCache.js.flow +2 -1
- package/store/live-resolvers/resolverDataInjector.js.flow +10 -6
- package/store/observeFragmentExperimental.js.flow +82 -28
- package/store/observeQueryExperimental.js.flow +61 -0
- package/store/waitForFragmentExperimental.js.flow +4 -3
- package/util/NormalizationNode.js.flow +2 -1
- package/util/RelayConcreteNode.js.flow +2 -0
- package/util/RelayError.js.flow +1 -0
- package/util/RelayFeatureFlags.js.flow +18 -0
- package/util/RelayRuntimeTypes.js.flow +6 -3
- package/util/getPaginationVariables.js.flow +2 -0
- package/util/handlePotentialSnapshotErrors.js.flow +23 -11
- package/util/registerEnvironmentWithDevTools.js.flow +4 -2
- package/util/withProvidedVariables.js.flow +1 -0
- package/util/withStartAndDuration.js.flow +3 -0
- package/relay-runtime-experimental.js +0 -4
- package/relay-runtime-experimental.min.js +0 -9
- package/relay-runtime.js +0 -4
- package/relay-runtime.min.js +0 -9
|
@@ -54,6 +54,7 @@ var RelayResponseNormalizer = /*#__PURE__*/function () {
|
|
|
54
54
|
this._recordSource = recordSource;
|
|
55
55
|
this._variables = variables;
|
|
56
56
|
this._shouldProcessClientComponents = options.shouldProcessClientComponents;
|
|
57
|
+
this._log = options.log;
|
|
57
58
|
}
|
|
58
59
|
var _proto = RelayResponseNormalizer.prototype;
|
|
59
60
|
_proto.normalizeResponse = function normalizeResponse(node, dataID, data, errors) {
|
|
@@ -205,8 +206,6 @@ var RelayResponseNormalizer = /*#__PURE__*/function () {
|
|
|
205
206
|
this._normalizeActorChange(selection, record, data);
|
|
206
207
|
break;
|
|
207
208
|
case 'RelayResolver':
|
|
208
|
-
this._normalizeResolver(selection, record, data);
|
|
209
|
-
break;
|
|
210
209
|
case 'RelayLiveResolver':
|
|
211
210
|
this._normalizeResolver(selection, record, data);
|
|
212
211
|
break;
|
|
@@ -289,7 +288,8 @@ var RelayResponseNormalizer = /*#__PURE__*/function () {
|
|
|
289
288
|
var responseKey = selection.alias || selection.name;
|
|
290
289
|
var storageKey = getStorageKey(selection, this._variables);
|
|
291
290
|
var fieldValue = data[responseKey];
|
|
292
|
-
|
|
291
|
+
var isNoncompliantlyNullish = RelayFeatureFlags.ENABLE_NONCOMPLIANT_ERROR_HANDLING_ON_LISTS && Array.isArray(fieldValue) && fieldValue.length === 0;
|
|
292
|
+
if (fieldValue == null || isNoncompliantlyNullish) {
|
|
293
293
|
if (fieldValue === undefined) {
|
|
294
294
|
var isOptionalField = this._isClientExtension || this._isUnmatchedAbstractType;
|
|
295
295
|
if (isOptionalField) {
|
|
@@ -301,12 +301,18 @@ var RelayResponseNormalizer = /*#__PURE__*/function () {
|
|
|
301
301
|
return;
|
|
302
302
|
}
|
|
303
303
|
}
|
|
304
|
-
if (
|
|
305
|
-
|
|
306
|
-
|
|
304
|
+
if (selection.kind === 'ScalarField') {
|
|
305
|
+
this._validateConflictingFieldsWithIdenticalId(record, storageKey, null);
|
|
306
|
+
}
|
|
307
|
+
if (isNoncompliantlyNullish) {
|
|
308
|
+
if (selection.kind === 'LinkedField') {
|
|
309
|
+
RelayModernRecord.setLinkedRecordIDs(record, storageKey, []);
|
|
310
|
+
} else {
|
|
311
|
+
RelayModernRecord.setValue(record, storageKey, []);
|
|
307
312
|
}
|
|
313
|
+
} else {
|
|
314
|
+
RelayModernRecord.setValue(record, storageKey, null);
|
|
308
315
|
}
|
|
309
|
-
RelayModernRecord.setValue(record, storageKey, null);
|
|
310
316
|
var errorTrie = this._errorTrie;
|
|
311
317
|
if (errorTrie != null) {
|
|
312
318
|
var errors = getErrorsByKey(errorTrie, responseKey);
|
|
@@ -317,9 +323,7 @@ var RelayResponseNormalizer = /*#__PURE__*/function () {
|
|
|
317
323
|
return;
|
|
318
324
|
}
|
|
319
325
|
if (selection.kind === 'ScalarField') {
|
|
320
|
-
|
|
321
|
-
this._validateConflictingFieldsWithIdenticalId(record, storageKey, fieldValue);
|
|
322
|
-
}
|
|
326
|
+
this._validateConflictingFieldsWithIdenticalId(record, storageKey, fieldValue);
|
|
323
327
|
RelayModernRecord.setValue(record, storageKey, fieldValue);
|
|
324
328
|
} else if (selection.kind === 'LinkedField') {
|
|
325
329
|
this._path.push(responseKey);
|
|
@@ -387,16 +391,14 @@ var RelayResponseNormalizer = /*#__PURE__*/function () {
|
|
|
387
391
|
!(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;
|
|
388
392
|
var nextID = this._getDataId(fieldValue, (_field$concreteType2 = field.concreteType) !== null && _field$concreteType2 !== void 0 ? _field$concreteType2 : this._getRecordType(fieldValue)) || RelayModernRecord.getLinkedRecordID(record, storageKey) || generateClientID(RelayModernRecord.getDataID(record), storageKey);
|
|
389
393
|
!(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;
|
|
390
|
-
|
|
391
|
-
this._validateConflictingLinkedFieldsWithIdenticalId(RelayModernRecord.getLinkedRecordID(record, storageKey), nextID, storageKey);
|
|
392
|
-
}
|
|
394
|
+
this._validateConflictingLinkedFieldsWithIdenticalId(RelayModernRecord.getLinkedRecordID(record, storageKey), nextID, storageKey);
|
|
393
395
|
RelayModernRecord.setLinkedRecordID(record, storageKey, nextID);
|
|
394
396
|
var nextRecord = this._recordSource.get(nextID);
|
|
395
397
|
if (!nextRecord) {
|
|
396
398
|
var typeName = field.concreteType || this._getRecordType(fieldValue);
|
|
397
399
|
nextRecord = RelayModernRecord.create(nextID, typeName);
|
|
398
400
|
this._recordSource.set(nextID, nextRecord);
|
|
399
|
-
} else
|
|
401
|
+
} else {
|
|
400
402
|
this._validateRecordType(nextRecord, field, fieldValue);
|
|
401
403
|
}
|
|
402
404
|
this._traverseSelections(field, nextRecord, fieldValue);
|
|
@@ -424,13 +426,11 @@ var RelayResponseNormalizer = /*#__PURE__*/function () {
|
|
|
424
426
|
var typeName = field.concreteType || _this._getRecordType(item);
|
|
425
427
|
nextRecord = RelayModernRecord.create(nextID, typeName);
|
|
426
428
|
_this._recordSource.set(nextID, nextRecord);
|
|
427
|
-
} else
|
|
429
|
+
} else {
|
|
428
430
|
_this._validateRecordType(nextRecord, field, item);
|
|
429
431
|
}
|
|
430
|
-
if (
|
|
431
|
-
|
|
432
|
-
_this._validateConflictingLinkedFieldsWithIdenticalId(prevIDs[nextIndex], nextID, storageKey);
|
|
433
|
-
}
|
|
432
|
+
if (prevIDs) {
|
|
433
|
+
_this._validateConflictingLinkedFieldsWithIdenticalId(prevIDs[nextIndex], nextID, storageKey);
|
|
434
434
|
}
|
|
435
435
|
_this._traverseSelections(field, nextRecord, item);
|
|
436
436
|
_this._errorTrie = oldErrorTrie;
|
|
@@ -439,21 +439,42 @@ var RelayResponseNormalizer = /*#__PURE__*/function () {
|
|
|
439
439
|
RelayModernRecord.setLinkedRecordIDs(record, storageKey, nextIDs);
|
|
440
440
|
};
|
|
441
441
|
_proto._validateRecordType = function _validateRecordType(record, field, payload) {
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
442
|
+
if (RelayFeatureFlags.ENABLE_STORE_ID_COLLISION_LOGGING) {
|
|
443
|
+
var _field$concreteType4;
|
|
444
|
+
var typeName = (_field$concreteType4 = field.concreteType) !== null && _field$concreteType4 !== void 0 ? _field$concreteType4 : this._getRecordType(payload);
|
|
445
|
+
var dataID = RelayModernRecord.getDataID(record);
|
|
446
|
+
var expected = isClientID(dataID) && dataID !== ROOT_ID || RelayModernRecord.getType(record) === typeName;
|
|
447
|
+
if (!expected) {
|
|
448
|
+
var logEvent = {
|
|
449
|
+
name: 'idCollision.typename',
|
|
450
|
+
previous_typename: RelayModernRecord.getType(record),
|
|
451
|
+
new_typename: typeName
|
|
452
|
+
};
|
|
453
|
+
if (this._log != null) {
|
|
454
|
+
this._log(logEvent);
|
|
455
|
+
}
|
|
456
|
+
}
|
|
457
|
+
}
|
|
458
|
+
if (process.env.NODE_ENV !== "production") {
|
|
459
|
+
var _field$concreteType5;
|
|
460
|
+
var _typeName3 = (_field$concreteType5 = field.concreteType) !== null && _field$concreteType5 !== void 0 ? _field$concreteType5 : this._getRecordType(payload);
|
|
461
|
+
var _dataID = RelayModernRecord.getDataID(record);
|
|
462
|
+
var _expected = isClientID(_dataID) && _dataID !== ROOT_ID || RelayModernRecord.getType(record) === _typeName3;
|
|
463
|
+
process.env.NODE_ENV !== "production" ? warning(_expected, 'RelayResponseNormalizer: Invalid record `%s`. Expected %s to be ' + 'consistent, but the record was assigned conflicting types `%s` ' + 'and `%s`. The GraphQL server likely violated the globally unique ' + 'id requirement by returning the same id for different objects.', _dataID, TYPENAME_KEY, RelayModernRecord.getType(record), _typeName3) : void 0;
|
|
464
|
+
}
|
|
446
465
|
};
|
|
447
466
|
_proto._validateConflictingFieldsWithIdenticalId = function _validateConflictingFieldsWithIdenticalId(record, storageKey, fieldValue) {
|
|
448
467
|
if (process.env.NODE_ENV !== "production") {
|
|
449
|
-
var dataID = RelayModernRecord.getDataID(record);
|
|
450
468
|
var previousValue = RelayModernRecord.getValue(record, storageKey);
|
|
451
|
-
|
|
469
|
+
var dataID = RelayModernRecord.getDataID(record);
|
|
470
|
+
var expected = storageKey === TYPENAME_KEY || previousValue === undefined || areEqual(previousValue, fieldValue);
|
|
471
|
+
process.env.NODE_ENV !== "production" ? warning(expected, '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;
|
|
452
472
|
}
|
|
453
473
|
};
|
|
454
474
|
_proto._validateConflictingLinkedFieldsWithIdenticalId = function _validateConflictingLinkedFieldsWithIdenticalId(prevID, nextID, storageKey) {
|
|
455
475
|
if (process.env.NODE_ENV !== "production") {
|
|
456
|
-
|
|
476
|
+
var expected = prevID === undefined || prevID === nextID;
|
|
477
|
+
process.env.NODE_ENV !== "production" ? warning(expected, '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;
|
|
457
478
|
}
|
|
458
479
|
};
|
|
459
480
|
return RelayResponseNormalizer;
|
|
@@ -59,7 +59,7 @@ var RelayStoreSubscriptions = /*#__PURE__*/function () {
|
|
|
59
59
|
missingLiveResolverFields: backup.missingLiveResolverFields,
|
|
60
60
|
seenRecords: backup.seenRecords,
|
|
61
61
|
selector: backup.selector,
|
|
62
|
-
|
|
62
|
+
fieldErrors: backup.fieldErrors
|
|
63
63
|
};
|
|
64
64
|
} else {
|
|
65
65
|
subscription.stale = true;
|
|
@@ -94,7 +94,7 @@ var RelayStoreSubscriptions = /*#__PURE__*/function () {
|
|
|
94
94
|
missingLiveResolverFields: nextSnapshot.missingLiveResolverFields,
|
|
95
95
|
seenRecords: nextSnapshot.seenRecords,
|
|
96
96
|
selector: nextSnapshot.selector,
|
|
97
|
-
|
|
97
|
+
fieldErrors: nextSnapshot.fieldErrors
|
|
98
98
|
};
|
|
99
99
|
if (process.env.NODE_ENV !== "production") {
|
|
100
100
|
deepFreeze(nextSnapshot);
|
|
@@ -4,6 +4,7 @@ var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefau
|
|
|
4
4
|
var _toConsumableArray2 = _interopRequireDefault(require("@babel/runtime/helpers/toConsumableArray"));
|
|
5
5
|
var getRelayHandleKey = require('../util/getRelayHandleKey');
|
|
6
6
|
var RelayConcreteNode = require('../util/RelayConcreteNode');
|
|
7
|
+
var RelayFeatureFlags = require('../util/RelayFeatureFlags');
|
|
7
8
|
var _require = require('../util/stableCopy'),
|
|
8
9
|
stableCopy = _require.stableCopy;
|
|
9
10
|
var invariant = require('invariant');
|
|
@@ -14,6 +15,7 @@ var VARIABLE = RelayConcreteNode.VARIABLE,
|
|
|
14
15
|
var ERRORS_KEY = '__errors';
|
|
15
16
|
var MODULE_COMPONENT_KEY_PREFIX = '__module_component_';
|
|
16
17
|
var MODULE_OPERATION_KEY_PREFIX = '__module_operation_';
|
|
18
|
+
var RELAY_READ_TIME_RESOLVER_KEY_PREFIX = '$r:';
|
|
17
19
|
function getArgumentValue(arg, variables) {
|
|
18
20
|
if (arg.kind === VARIABLE) {
|
|
19
21
|
return getStableVariableValue(arg.variableName, variables);
|
|
@@ -76,6 +78,10 @@ function getStorageKey(field, variables) {
|
|
|
76
78
|
var name = field.name;
|
|
77
79
|
return args && args.length !== 0 ? formatStorageKey(name, getArgumentValues(args, variables)) : name;
|
|
78
80
|
}
|
|
81
|
+
function getReadTimeResolverStorageKey(field, variables) {
|
|
82
|
+
var storageKey = getStorageKey(field, variables);
|
|
83
|
+
return RelayFeatureFlags.ENABLE_READ_TIME_RESOLVER_STORAGE_KEY_PREFIX ? '$r:' + storageKey : storageKey;
|
|
84
|
+
}
|
|
79
85
|
function getArguments(field) {
|
|
80
86
|
if (field.kind === 'RelayResolver' || field.kind === 'RelayLiveResolver') {
|
|
81
87
|
var _field$fragment2;
|
|
@@ -141,11 +147,13 @@ var RelayStoreUtils = {
|
|
|
141
147
|
RELAY_RESOLVER_SNAPSHOT_KEY: '__resolverSnapshot',
|
|
142
148
|
RELAY_RESOLVER_ERROR_KEY: '__resolverError',
|
|
143
149
|
RELAY_RESOLVER_OUTPUT_TYPE_RECORD_IDS: '__resolverOutputTypeRecordIDs',
|
|
150
|
+
RELAY_READ_TIME_RESOLVER_KEY_PREFIX: RELAY_READ_TIME_RESOLVER_KEY_PREFIX,
|
|
144
151
|
formatStorageKey: formatStorageKey,
|
|
145
152
|
getArgumentValue: getArgumentValue,
|
|
146
153
|
getArgumentValues: getArgumentValues,
|
|
147
154
|
getHandleStorageKey: getHandleStorageKey,
|
|
148
155
|
getStorageKey: getStorageKey,
|
|
156
|
+
getReadTimeResolverStorageKey: getReadTimeResolverStorageKey,
|
|
149
157
|
getStableStorageKey: getStableStorageKey,
|
|
150
158
|
getModuleComponentKey: getModuleComponentKey,
|
|
151
159
|
getModuleOperationKey: getModuleOperationKey
|
|
@@ -28,8 +28,8 @@ function readFragment(fragmentInput, fragmentKey) {
|
|
|
28
28
|
var _context$getDataForRe = context.getDataForResolverFragment(fragmentSelector, fragmentKey),
|
|
29
29
|
data = _context$getDataForRe.data,
|
|
30
30
|
isMissingData = _context$getDataForRe.isMissingData,
|
|
31
|
-
|
|
32
|
-
if (isMissingData ||
|
|
31
|
+
fieldErrors = _context$getDataForRe.fieldErrors;
|
|
32
|
+
if (isMissingData || fieldErrors != null && fieldErrors.some(eventShouldThrow)) {
|
|
33
33
|
throw RESOLVER_FRAGMENT_ERRORED_SENTINEL;
|
|
34
34
|
}
|
|
35
35
|
return data;
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var invariant = require('invariant');
|
|
4
|
+
var relayLoggingContext;
|
|
5
|
+
var firstReact;
|
|
6
|
+
function createRelayLoggingContext(react) {
|
|
7
|
+
if (!relayLoggingContext) {
|
|
8
|
+
relayLoggingContext = react.createContext(null);
|
|
9
|
+
if (process.env.NODE_ENV !== "production") {
|
|
10
|
+
relayLoggingContext.displayName = 'RelayLoggingContext';
|
|
11
|
+
}
|
|
12
|
+
firstReact = react;
|
|
13
|
+
}
|
|
14
|
+
!(react === firstReact) ? process.env.NODE_ENV !== "production" ? invariant(false, '[createRelayLoggingContext]: You are passing a different instance of React', react.version) : invariant(false) : void 0;
|
|
15
|
+
return relayLoggingContext;
|
|
16
|
+
}
|
|
17
|
+
module.exports = createRelayLoggingContext;
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var TYPENAME_PREFIX = '__type:';
|
|
4
|
+
function generateTypenamePrefixedDataID(typeName, dataID) {
|
|
5
|
+
return "".concat(TYPENAME_PREFIX).concat(typeName, ":").concat(dataID);
|
|
6
|
+
}
|
|
7
|
+
module.exports = {
|
|
8
|
+
generateTypenamePrefixedDataID: generateTypenamePrefixedDataID
|
|
9
|
+
};
|
|
@@ -22,6 +22,7 @@ var _require5 = require('../RelayStoreUtils'),
|
|
|
22
22
|
RELAY_RESOLVER_OUTPUT_TYPE_RECORD_IDS = _require5.RELAY_RESOLVER_OUTPUT_TYPE_RECORD_IDS,
|
|
23
23
|
RELAY_RESOLVER_SNAPSHOT_KEY = _require5.RELAY_RESOLVER_SNAPSHOT_KEY,
|
|
24
24
|
RELAY_RESOLVER_VALUE_KEY = _require5.RELAY_RESOLVER_VALUE_KEY,
|
|
25
|
+
getReadTimeResolverStorageKey = _require5.getReadTimeResolverStorageKey,
|
|
25
26
|
getStorageKey = _require5.getStorageKey;
|
|
26
27
|
var getOutputTypeRecordIDs = require('./getOutputTypeRecordIDs');
|
|
27
28
|
var isLiveStateValue = require('./isLiveStateValue');
|
|
@@ -55,7 +56,7 @@ var LiveResolverCache = /*#__PURE__*/function () {
|
|
|
55
56
|
_proto.readFromCacheOrEvaluate = function readFromCacheOrEvaluate(recordID, field, variables, evaluate, getDataForResolverFragment) {
|
|
56
57
|
var recordSource = this._getRecordSource();
|
|
57
58
|
var record = expectRecord(recordSource, recordID);
|
|
58
|
-
var storageKey =
|
|
59
|
+
var storageKey = getReadTimeResolverStorageKey(field, variables);
|
|
59
60
|
var linkedID = RelayModernRecord.getLinkedRecordID(record, storageKey);
|
|
60
61
|
var linkedRecord = linkedID == null ? null : recordSource.get(linkedID);
|
|
61
62
|
var updatedDataIDs;
|
|
@@ -5,26 +5,26 @@ var _require = require('../ResolverFragments'),
|
|
|
5
5
|
var invariant = require('invariant');
|
|
6
6
|
function resolverDataInjector(fragment, _resolverFn, fieldName, isRequiredField) {
|
|
7
7
|
var resolverFn = _resolverFn;
|
|
8
|
-
return function (fragmentKey, args) {
|
|
8
|
+
return function (fragmentKey, args, resolverContext) {
|
|
9
9
|
var data = readFragment(fragment, fragmentKey);
|
|
10
10
|
if (fieldName != null) {
|
|
11
11
|
if (data == null) {
|
|
12
12
|
if (isRequiredField === true) {
|
|
13
13
|
!false ? process.env.NODE_ENV !== "production" ? invariant(false, 'Expected required resolver field `%s` in fragment `%s` to be present. But resolvers fragment data is null/undefined.', fieldName, fragment.name) : invariant(false) : void 0;
|
|
14
14
|
} else {
|
|
15
|
-
return resolverFn(null, args);
|
|
15
|
+
return resolverFn(null, args, resolverContext);
|
|
16
16
|
}
|
|
17
17
|
}
|
|
18
18
|
if (fieldName in data) {
|
|
19
19
|
if (isRequiredField === true) {
|
|
20
20
|
!(data[fieldName] != null) ? process.env.NODE_ENV !== "production" ? invariant(false, 'Expected required resolver field `%s` in fragment `%s` to be non-null.', fieldName, fragment.name) : invariant(false) : void 0;
|
|
21
21
|
}
|
|
22
|
-
return resolverFn(data[fieldName], args);
|
|
22
|
+
return resolverFn(data[fieldName], args, resolverContext);
|
|
23
23
|
} else {
|
|
24
24
|
!false ? process.env.NODE_ENV !== "production" ? invariant(false, 'Missing field `%s` in fragment `%s` in resolver response.', fieldName, fragment.name) : invariant(false) : void 0;
|
|
25
25
|
}
|
|
26
26
|
} else {
|
|
27
|
-
return resolverFn(
|
|
27
|
+
return resolverFn(null, args, resolverContext);
|
|
28
28
|
}
|
|
29
29
|
};
|
|
30
30
|
}
|
|
@@ -1,14 +1,17 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
|
|
3
|
+
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault")["default"];
|
|
3
4
|
var _asyncToGenerator = require("@babel/runtime/helpers/asyncToGenerator").default;
|
|
5
|
+
var _createForOfIteratorHelper2 = _interopRequireDefault(require("@babel/runtime/helpers/createForOfIteratorHelper"));
|
|
4
6
|
var Observable = require('../network/RelayObservable');
|
|
5
|
-
var _require = require('../query/
|
|
6
|
-
|
|
7
|
-
var
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
7
|
+
var _require = require('../query/fetchQueryInternal'),
|
|
8
|
+
getObservableForActiveRequest = _require.getObservableForActiveRequest;
|
|
9
|
+
var _require2 = require('../query/GraphQLTag'),
|
|
10
|
+
getFragment = _require2.getFragment;
|
|
11
|
+
var _require3 = require('../util/handlePotentialSnapshotErrors'),
|
|
12
|
+
handlePotentialSnapshotErrors = _require3.handlePotentialSnapshotErrors;
|
|
13
|
+
var _require4 = require('./RelayModernSelector'),
|
|
14
|
+
getSelector = _require4.getSelector;
|
|
12
15
|
var invariant = require('invariant');
|
|
13
16
|
function waitForFragmentData(_x, _x2, _x3) {
|
|
14
17
|
return _waitForFragmentData.apply(this, arguments);
|
|
@@ -47,15 +50,15 @@ function observeFragment(environment, fragment, fragmentRef) {
|
|
|
47
50
|
!(fragmentSelector != null) ? process.env.NODE_ENV !== "production" ? invariant(false, 'Expected a selector, got null.') : invariant(false) : void 0;
|
|
48
51
|
switch (fragmentSelector.kind) {
|
|
49
52
|
case 'SingularReaderSelector':
|
|
50
|
-
return
|
|
53
|
+
return observeSingularSelector(environment, fragment, fragmentSelector);
|
|
51
54
|
case 'PluralReaderSelector':
|
|
52
55
|
{
|
|
53
|
-
|
|
56
|
+
return observePluralSelector(environment, fragment, fragmentSelector);
|
|
54
57
|
}
|
|
55
58
|
}
|
|
56
59
|
!false ? process.env.NODE_ENV !== "production" ? invariant(false, 'Unsupported fragment selector kind') : invariant(false) : void 0;
|
|
57
60
|
}
|
|
58
|
-
function
|
|
61
|
+
function observeSingularSelector(environment, fragmentNode, fragmentSelector) {
|
|
59
62
|
var snapshot = environment.lookup(fragmentSelector);
|
|
60
63
|
return Observable.create(function (sink) {
|
|
61
64
|
sink.next(snapshotToFragmentState(environment, fragmentNode, fragmentSelector.owner, snapshot));
|
|
@@ -67,6 +70,28 @@ function observeSelector(environment, fragmentNode, fragmentSelector) {
|
|
|
67
70
|
};
|
|
68
71
|
});
|
|
69
72
|
}
|
|
73
|
+
function observePluralSelector(environment, fragmentNode, fragmentSelector) {
|
|
74
|
+
var snapshots = fragmentSelector.selectors.map(function (selector) {
|
|
75
|
+
return environment.lookup(selector);
|
|
76
|
+
});
|
|
77
|
+
return Observable.create(function (sink) {
|
|
78
|
+
var states = snapshots.map(function (snapshot, index) {
|
|
79
|
+
return snapshotToFragmentState(environment, fragmentNode, fragmentSelector.selectors[index].owner, snapshot);
|
|
80
|
+
});
|
|
81
|
+
sink.next(mergeFragmentStates(states));
|
|
82
|
+
var subscriptions = snapshots.map(function (snapshot, index) {
|
|
83
|
+
return environment.subscribe(snapshot, function (latestSnapshot) {
|
|
84
|
+
states[index] = snapshotToFragmentState(environment, fragmentNode, fragmentSelector.selectors[index].owner, latestSnapshot);
|
|
85
|
+
sink.next(mergeFragmentStates(states));
|
|
86
|
+
});
|
|
87
|
+
});
|
|
88
|
+
return function () {
|
|
89
|
+
return subscriptions.forEach(function (subscription) {
|
|
90
|
+
return subscription.dispose();
|
|
91
|
+
});
|
|
92
|
+
};
|
|
93
|
+
});
|
|
94
|
+
}
|
|
70
95
|
function snapshotToFragmentState(environment, fragmentNode, owner, snapshot) {
|
|
71
96
|
var missingLiveResolverFields = snapshot.missingLiveResolverFields != null && snapshot.missingLiveResolverFields.length > 0;
|
|
72
97
|
var missingClientEdges = snapshot.missingClientEdges != null && snapshot.missingClientEdges.length > 0;
|
|
@@ -76,15 +101,14 @@ function snapshotToFragmentState(environment, fragmentNode, owner, snapshot) {
|
|
|
76
101
|
};
|
|
77
102
|
}
|
|
78
103
|
if (snapshot.isMissingData) {
|
|
79
|
-
|
|
80
|
-
if (pendingOperations != null) {
|
|
104
|
+
if (getObservableForActiveRequest(environment, owner) != null || environment.getOperationTracker().getPendingOperationsAffectingOwner(owner) != null) {
|
|
81
105
|
return {
|
|
82
106
|
state: 'loading'
|
|
83
107
|
};
|
|
84
108
|
}
|
|
85
109
|
}
|
|
86
110
|
try {
|
|
87
|
-
handlePotentialSnapshotErrors(environment, snapshot.
|
|
111
|
+
handlePotentialSnapshotErrors(environment, snapshot.fieldErrors);
|
|
88
112
|
} catch (error) {
|
|
89
113
|
return {
|
|
90
114
|
error: error,
|
|
@@ -97,6 +121,29 @@ function snapshotToFragmentState(environment, fragmentNode, owner, snapshot) {
|
|
|
97
121
|
value: snapshot.data
|
|
98
122
|
};
|
|
99
123
|
}
|
|
124
|
+
function mergeFragmentStates(states) {
|
|
125
|
+
var value = [];
|
|
126
|
+
var _iterator = (0, _createForOfIteratorHelper2["default"])(states),
|
|
127
|
+
_step;
|
|
128
|
+
try {
|
|
129
|
+
for (_iterator.s(); !(_step = _iterator.n()).done;) {
|
|
130
|
+
var state = _step.value;
|
|
131
|
+
if (state.state === 'ok') {
|
|
132
|
+
value.push(state.value);
|
|
133
|
+
} else {
|
|
134
|
+
return state;
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
} catch (err) {
|
|
138
|
+
_iterator.e(err);
|
|
139
|
+
} finally {
|
|
140
|
+
_iterator.f();
|
|
141
|
+
}
|
|
142
|
+
return {
|
|
143
|
+
state: 'ok',
|
|
144
|
+
value: value
|
|
145
|
+
};
|
|
146
|
+
}
|
|
100
147
|
module.exports = {
|
|
101
148
|
observeFragment: observeFragment,
|
|
102
149
|
waitForFragmentData: waitForFragmentData
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault")["default"];
|
|
4
|
+
var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty"));
|
|
5
|
+
var _require = require('./observeFragmentExperimental'),
|
|
6
|
+
observeFragment = _require.observeFragment;
|
|
7
|
+
var _require2 = require('./RelayModernOperationDescriptor'),
|
|
8
|
+
createOperationDescriptor = _require2.createOperationDescriptor;
|
|
9
|
+
function observeQuery(environment, gqlQuery, variables) {
|
|
10
|
+
var operation = createOperationDescriptor(gqlQuery, variables);
|
|
11
|
+
var rootFragmentRef = {
|
|
12
|
+
__id: operation.fragment.dataID,
|
|
13
|
+
__fragments: (0, _defineProperty2["default"])({}, operation.fragment.node.name, operation.request.variables),
|
|
14
|
+
__fragmentOwner: operation.request
|
|
15
|
+
};
|
|
16
|
+
var fragmentNode = operation.request.node.fragment;
|
|
17
|
+
return observeFragment(environment, fragmentNode, rootFragmentRef);
|
|
18
|
+
}
|
|
19
|
+
module.exports = {
|
|
20
|
+
observeQuery: observeQuery
|
|
21
|
+
};
|
|
@@ -12,6 +12,7 @@ var RelayFeatureFlags = {
|
|
|
12
12
|
MAX_DATA_ID_LENGTH: null,
|
|
13
13
|
STRING_INTERN_LEVEL: 0,
|
|
14
14
|
LOG_MISSING_RECORDS_IN_PROD: false,
|
|
15
|
+
ENABLE_STORE_ID_COLLISION_LOGGING: false,
|
|
15
16
|
ENABLE_NONCOMPLIANT_ERROR_HANDLING_ON_LISTS: false,
|
|
16
17
|
ENABLE_LOOSE_SUBSCRIPTION_ATTRIBUTION: false,
|
|
17
18
|
ENABLE_OPERATION_TRACKER_OPTIMISTIC_UPDATES: false,
|
|
@@ -20,6 +21,10 @@ var RelayFeatureFlags = {
|
|
|
20
21
|
MARK_RESOLVER_VALUES_AS_CLEAN_AFTER_FRAGMENT_REREAD: false,
|
|
21
22
|
ENABLE_CYLE_DETECTION_IN_VARIABLES: false,
|
|
22
23
|
ENABLE_ACTIVITY_COMPATIBILITY: false,
|
|
23
|
-
ENABLE_READ_TIME_RESOLVER_STORAGE_KEY_PREFIX: true
|
|
24
|
+
ENABLE_READ_TIME_RESOLVER_STORAGE_KEY_PREFIX: true,
|
|
25
|
+
ENABLE_USE_PAGINATION_IS_LOADING_FIX: false,
|
|
26
|
+
DISALLOW_NESTED_UPDATES: false,
|
|
27
|
+
ENABLE_TYPENAME_PREFIXED_DATA_ID: false,
|
|
28
|
+
ENABLE_UI_CONTEXT_ON_RELAY_LOGGER: false
|
|
24
29
|
};
|
|
25
30
|
module.exports = RelayFeatureFlags;
|
|
@@ -1,22 +1,25 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
3
|
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault")["default"];
|
|
4
|
+
var _objectSpread2 = _interopRequireDefault(require("@babel/runtime/helpers/objectSpread2"));
|
|
4
5
|
var _createForOfIteratorHelper2 = _interopRequireDefault(require("@babel/runtime/helpers/createForOfIteratorHelper"));
|
|
5
6
|
var invariant = require('invariant');
|
|
6
|
-
function handleFieldErrors(environment,
|
|
7
|
-
var _iterator = (0, _createForOfIteratorHelper2["default"])(
|
|
7
|
+
function handleFieldErrors(environment, fieldErrors, loggingContext) {
|
|
8
|
+
var _iterator = (0, _createForOfIteratorHelper2["default"])(fieldErrors),
|
|
8
9
|
_step;
|
|
9
10
|
try {
|
|
10
11
|
for (_iterator.s(); !(_step = _iterator.n()).done;) {
|
|
11
12
|
var fieldError = _step.value;
|
|
12
|
-
environment.relayFieldLogger(fieldError)
|
|
13
|
+
environment.relayFieldLogger((0, _objectSpread2["default"])((0, _objectSpread2["default"])({}, fieldError), {}, {
|
|
14
|
+
uiContext: loggingContext
|
|
15
|
+
}));
|
|
13
16
|
}
|
|
14
17
|
} catch (err) {
|
|
15
18
|
_iterator.e(err);
|
|
16
19
|
} finally {
|
|
17
20
|
_iterator.f();
|
|
18
21
|
}
|
|
19
|
-
var _iterator2 = (0, _createForOfIteratorHelper2["default"])(
|
|
22
|
+
var _iterator2 = (0, _createForOfIteratorHelper2["default"])(fieldErrors),
|
|
20
23
|
_step2;
|
|
21
24
|
try {
|
|
22
25
|
for (_iterator2.s(); !(_step2 = _iterator2.n()).done;) {
|
|
@@ -24,7 +27,7 @@ function handleFieldErrors(environment, errorResponseFields) {
|
|
|
24
27
|
if (eventShouldThrow(_fieldError)) {
|
|
25
28
|
switch (_fieldError.kind) {
|
|
26
29
|
case 'relay_resolver.error':
|
|
27
|
-
throw new Error("Relay: Resolver error at path '".concat(_fieldError.fieldPath, "' in '").concat(_fieldError.owner, "'."));
|
|
30
|
+
throw new Error("Relay: Resolver error at path '".concat(_fieldError.fieldPath, "' in '").concat(_fieldError.owner, "'. Message: ").concat(_fieldError.error.message));
|
|
28
31
|
case 'relay_field_payload.error':
|
|
29
32
|
throw new Error("Relay: Unexpected response payload - check server logs for details.");
|
|
30
33
|
case 'missing_expected_data.throw':
|
|
@@ -62,9 +65,9 @@ function eventShouldThrow(event) {
|
|
|
62
65
|
throw new Error('Relay: Unexpected event kind');
|
|
63
66
|
}
|
|
64
67
|
}
|
|
65
|
-
function handlePotentialSnapshotErrors(environment,
|
|
66
|
-
if (
|
|
67
|
-
handleFieldErrors(environment,
|
|
68
|
+
function handlePotentialSnapshotErrors(environment, fieldErrors, loggingContext) {
|
|
69
|
+
if (fieldErrors != null) {
|
|
70
|
+
handleFieldErrors(environment, fieldErrors, loggingContext);
|
|
68
71
|
}
|
|
69
72
|
}
|
|
70
73
|
module.exports = {
|
|
@@ -87,6 +87,7 @@ class ActorSpecificEnvironment implements IActorEnvironment {
|
|
|
87
87
|
config.handlerProvider,
|
|
88
88
|
defaultGetDataID,
|
|
89
89
|
config.missingFieldHandlers,
|
|
90
|
+
this.__log,
|
|
90
91
|
);
|
|
91
92
|
this._defaultRenderPolicy = config.defaultRenderPolicy;
|
|
92
93
|
// TODO:T92305692 Remove `options` in favor of directly using `actorIdentifier` on the environment
|
|
@@ -18,6 +18,7 @@ import type {
|
|
|
18
18
|
FragmentType,
|
|
19
19
|
HandleFieldPayload,
|
|
20
20
|
HasUpdatableSpread,
|
|
21
|
+
LogFunction,
|
|
21
22
|
MissingFieldHandler,
|
|
22
23
|
RecordProxy,
|
|
23
24
|
RecordSource,
|
|
@@ -53,12 +54,14 @@ class RelayRecordSourceProxy implements RecordSourceProxy {
|
|
|
53
54
|
_invalidatedStore: boolean;
|
|
54
55
|
_idsMarkedForInvalidation: DataIDSet;
|
|
55
56
|
_missingFieldHandlers: $ReadOnlyArray<MissingFieldHandler>;
|
|
57
|
+
_log: LogFunction;
|
|
56
58
|
|
|
57
59
|
constructor(
|
|
58
60
|
mutator: RelayRecordSourceMutator,
|
|
59
61
|
getDataID: GetDataID,
|
|
60
62
|
handlerProvider?: ?HandlerProvider,
|
|
61
63
|
missingFieldHandlers: $ReadOnlyArray<MissingFieldHandler>,
|
|
64
|
+
log: ?LogFunction,
|
|
62
65
|
) {
|
|
63
66
|
this.__mutator = mutator;
|
|
64
67
|
this._handlerProvider = handlerProvider || null;
|
|
@@ -67,6 +70,7 @@ class RelayRecordSourceProxy implements RecordSourceProxy {
|
|
|
67
70
|
this._invalidatedStore = false;
|
|
68
71
|
this._idsMarkedForInvalidation = new Set();
|
|
69
72
|
this._missingFieldHandlers = missingFieldHandlers;
|
|
73
|
+
this._log = log ?? (LogEvent => {});
|
|
70
74
|
}
|
|
71
75
|
|
|
72
76
|
publishSource(
|
|
@@ -181,11 +181,11 @@ function updateProxyFromSelections<TData>(
|
|
|
181
181
|
case 'ClientEdgeToServerObject':
|
|
182
182
|
case 'Defer':
|
|
183
183
|
case 'ModuleImport':
|
|
184
|
-
case 'RelayLiveResolver':
|
|
185
184
|
case 'RequiredField':
|
|
186
185
|
case 'CatchField':
|
|
187
186
|
case 'Stream':
|
|
188
187
|
case 'RelayResolver':
|
|
188
|
+
case 'RelayLiveResolver':
|
|
189
189
|
// These types of reader nodes are not currently handled.
|
|
190
190
|
throw new Error(
|
|
191
191
|
'Encountered an unexpected ReaderSelection variant in RelayRecordSourceProxy. This indicates a bug in Relay.',
|
|
@@ -145,13 +145,13 @@ if (__DEV__) {
|
|
|
145
145
|
return validateModuleImport(context);
|
|
146
146
|
case 'TypeDiscriminator':
|
|
147
147
|
return validateAbstractKey(context, selection.abstractKey);
|
|
148
|
-
case 'RelayResolver':
|
|
149
|
-
case 'RelayLiveResolver':
|
|
150
148
|
case 'ClientEdgeToClientObject':
|
|
151
149
|
case 'LinkedHandle':
|
|
152
150
|
case 'ScalarHandle':
|
|
153
151
|
case 'Defer':
|
|
154
|
-
case 'Stream':
|
|
152
|
+
case 'Stream':
|
|
153
|
+
case 'RelayResolver':
|
|
154
|
+
case 'RelayLiveResolver': {
|
|
155
155
|
// TODO(T35864292) - Add missing validations for these types
|
|
156
156
|
return;
|
|
157
157
|
}
|
|
@@ -11,6 +11,7 @@
|
|
|
11
11
|
|
|
12
12
|
'use strict';
|
|
13
13
|
|
|
14
|
+
import type {OperationAvailability} from '../store/RelayStoreTypes';
|
|
14
15
|
import type {RequestParameters} from '../util/RelayConcreteNode';
|
|
15
16
|
import type {CacheConfig, Variables} from '../util/RelayRuntimeTypes';
|
|
16
17
|
import type RelayObservable, {ObservableFromValue} from './RelayObservable';
|
|
@@ -104,6 +105,8 @@ export type ExecuteFunction = (
|
|
|
104
105
|
logRequestInfo?: ?LogRequestInfoFunction,
|
|
105
106
|
encryptedVariables?: ?string,
|
|
106
107
|
preprocessResponse?: ?preprocessResponseFunction,
|
|
108
|
+
// Run datachecker on the current operation and returns the OperationAvailability
|
|
109
|
+
checkOperation?: () => OperationAvailability,
|
|
107
110
|
) => RelayObservable<GraphQLResponse>;
|
|
108
111
|
|
|
109
112
|
/**
|
|
@@ -614,11 +614,7 @@ if (__DEV__) {
|
|
|
614
614
|
// Default implementation of HostReportErrors() in development builds.
|
|
615
615
|
// Can be replaced by the host application environment.
|
|
616
616
|
RelayObservable.onUnhandledError((error, isUncaughtThrownError) => {
|
|
617
|
-
|
|
618
|
-
if (typeof fail === 'function') {
|
|
619
|
-
// In test environments (Jest), fail() immediately fails the current test.
|
|
620
|
-
fail(String(error));
|
|
621
|
-
} else if (isUncaughtThrownError) {
|
|
617
|
+
if (isUncaughtThrownError) {
|
|
622
618
|
// Rethrow uncaught thrown errors on the next frame to avoid breaking
|
|
623
619
|
// current logic.
|
|
624
620
|
setTimeout(() => {
|