relay-runtime 10.0.1 → 10.1.3
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 +152 -20
- package/index.js +1 -1
- package/index.js.flow +17 -1
- package/lib/handlers/RelayDefaultHandlerProvider.js +9 -0
- package/lib/handlers/connection/MutationHandlers.js +185 -21
- 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 +39 -137
- 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 +196 -33
- package/lib/store/RelayRecordSourceMapImpl.js +3 -5
- package/lib/store/RelayReferenceMarker.js +87 -5
- package/lib/store/RelayResponseNormalizer.js +115 -19
- 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 +2 -6
- 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 +7 -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 +4 -1
- 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 +33 -107
- package/store/RelayPublishQueue.js.flow +1 -1
- package/store/RelayReader.js.flow +180 -15
- package/store/RelayReferenceMarker.js.flow +72 -5
- package/store/RelayResponseNormalizer.js.flow +130 -19
- 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/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 +12 -1
- package/util/getFragmentIdentifier.js.flow +33 -9
- package/util/getOperation.js.flow +40 -0
- package/util/getRequestIdentifier.js.flow +1 -1
- package/util/isEmptyObject.js.flow +25 -0
- package/util/recycleNodesInto.js.flow +11 -0
- package/util/reportMissingRequiredFields.js.flow +51 -0
|
@@ -13,14 +13,10 @@
|
|
|
13
13
|
|
|
14
14
|
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
|
|
15
15
|
|
|
16
|
-
var
|
|
16
|
+
var _objectSpread2 = _interopRequireDefault(require("@babel/runtime/helpers/objectSpread2"));
|
|
17
17
|
|
|
18
18
|
var _toConsumableArray2 = _interopRequireDefault(require("@babel/runtime/helpers/toConsumableArray"));
|
|
19
19
|
|
|
20
|
-
function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); if (enumerableOnly) symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; }); keys.push.apply(keys, symbols); } return keys; }
|
|
21
|
-
|
|
22
|
-
function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; if (i % 2) { ownKeys(Object(source), true).forEach(function (key) { (0, _defineProperty2["default"])(target, key, source[key]); }); } else if (Object.getOwnPropertyDescriptors) { Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); } else { ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } } return target; }
|
|
23
|
-
|
|
24
20
|
var inspect = function inspect() {};
|
|
25
21
|
|
|
26
22
|
if (process.env.NODE_ENV !== "production") {
|
|
@@ -138,7 +134,7 @@ if (process.env.NODE_ENV !== "production") {
|
|
|
138
134
|
return record;
|
|
139
135
|
}
|
|
140
136
|
|
|
141
|
-
return new Proxy(
|
|
137
|
+
return new Proxy((0, _objectSpread2["default"])({}, record), {
|
|
142
138
|
get: function get(target, prop) {
|
|
143
139
|
var value = target[prop];
|
|
144
140
|
|
|
@@ -18,6 +18,11 @@ var firstReact;
|
|
|
18
18
|
function createRelayContext(react) {
|
|
19
19
|
if (!relayContext) {
|
|
20
20
|
relayContext = react.createContext(null);
|
|
21
|
+
|
|
22
|
+
if (process.env.NODE_ENV !== "production") {
|
|
23
|
+
relayContext.displayName = 'RelayContext';
|
|
24
|
+
}
|
|
25
|
+
|
|
21
26
|
firstReact = react;
|
|
22
27
|
}
|
|
23
28
|
|
|
@@ -0,0 +1,18 @@
|
|
|
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
|
+
'use strict';
|
|
11
|
+
|
|
12
|
+
var defaultRequiredFieldLogger = function defaultRequiredFieldLogger(event) {
|
|
13
|
+
if (process.env.NODE_ENV !== "production" && event.kind === 'missing_field.log') {
|
|
14
|
+
throw new Error('Relay Environment Configuration Error (dev only): `@required(action: LOG)` requires that the Relay Environment be configured with a `requiredFieldLogger`.');
|
|
15
|
+
}
|
|
16
|
+
};
|
|
17
|
+
|
|
18
|
+
module.exports = defaultRequiredFieldLogger;
|
|
@@ -12,11 +12,7 @@
|
|
|
12
12
|
|
|
13
13
|
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
|
|
14
14
|
|
|
15
|
-
var
|
|
16
|
-
|
|
17
|
-
function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); if (enumerableOnly) symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; }); keys.push.apply(keys, symbols); } return keys; }
|
|
18
|
-
|
|
19
|
-
function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; if (i % 2) { ownKeys(Object(source), true).forEach(function (key) { (0, _defineProperty2["default"])(target, key, source[key]); }); } else if (Object.getOwnPropertyDescriptors) { Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); } else { ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } } return target; }
|
|
15
|
+
var _objectSpread2 = _interopRequireDefault(require("@babel/runtime/helpers/objectSpread2"));
|
|
20
16
|
|
|
21
17
|
var RelayModernRecord = require('./RelayModernRecord');
|
|
22
18
|
|
|
@@ -31,7 +27,7 @@ function normalizeRelayPayload(selector, payload, errors, options) {
|
|
|
31
27
|
var source = RelayRecordSource.create();
|
|
32
28
|
source.set(selector.dataID, RelayModernRecord.create(selector.dataID, ROOT_TYPE));
|
|
33
29
|
var relayPayload = RelayResponseNormalizer.normalize(source, selector, payload, options);
|
|
34
|
-
return
|
|
30
|
+
return (0, _objectSpread2["default"])((0, _objectSpread2["default"])({}, relayPayload), {}, {
|
|
35
31
|
errors: errors
|
|
36
32
|
});
|
|
37
33
|
}
|
|
@@ -33,7 +33,7 @@ function requestSubscription(environment, config) {
|
|
|
33
33
|
onNext = config.onNext,
|
|
34
34
|
variables = config.variables,
|
|
35
35
|
cacheConfig = config.cacheConfig;
|
|
36
|
-
var operation = createOperationDescriptor(subscription, variables);
|
|
36
|
+
var operation = createOperationDescriptor(subscription, variables, cacheConfig);
|
|
37
37
|
process.env.NODE_ENV !== "production" ? warning(!(config.updater && configs), 'requestSubscription: Expected only one of `updater` and `configs` to be provided') : void 0;
|
|
38
38
|
|
|
39
39
|
var _ref = configs ? RelayDeclarativeMutationConfig.convert(configs, subscription, null
|
|
@@ -43,8 +43,7 @@ function requestSubscription(environment, config) {
|
|
|
43
43
|
|
|
44
44
|
var sub = environment.execute({
|
|
45
45
|
operation: operation,
|
|
46
|
-
updater: updater
|
|
47
|
-
cacheConfig: cacheConfig
|
|
46
|
+
updater: updater
|
|
48
47
|
}).map(function () {
|
|
49
48
|
var data = environment.lookup(operation.fragment).data; // $FlowFixMe[incompatible-cast]
|
|
50
49
|
|
|
@@ -28,6 +28,7 @@ var RelayConcreteNode = {
|
|
|
28
28
|
CLIENT_EXTENSION: 'ClientExtension',
|
|
29
29
|
DEFER: 'Defer',
|
|
30
30
|
CONNECTION: 'Connection',
|
|
31
|
+
FLIGHT_FIELD: 'FlightField',
|
|
31
32
|
FRAGMENT: 'Fragment',
|
|
32
33
|
FRAGMENT_SPREAD: 'FragmentSpread',
|
|
33
34
|
INLINE_DATA_FRAGMENT_SPREAD: 'InlineDataFragmentSpread',
|
|
@@ -39,6 +40,7 @@ var RelayConcreteNode = {
|
|
|
39
40
|
LIST_VALUE: 'ListValue',
|
|
40
41
|
LOCAL_ARGUMENT: 'LocalArgument',
|
|
41
42
|
MODULE_IMPORT: 'ModuleImport',
|
|
43
|
+
REQUIRED_FIELD: 'RequiredField',
|
|
42
44
|
OBJECT_VALUE: 'ObjectValue',
|
|
43
45
|
OPERATION: 'Operation',
|
|
44
46
|
REQUEST: 'Request',
|
|
@@ -11,10 +11,15 @@
|
|
|
11
11
|
'use strict';
|
|
12
12
|
|
|
13
13
|
var RelayFeatureFlags = {
|
|
14
|
-
// T45504512: new connection model
|
|
15
14
|
ENABLE_VARIABLE_CONNECTION_KEY: false,
|
|
16
15
|
ENABLE_PARTIAL_RENDERING_DEFAULT: false,
|
|
17
16
|
ENABLE_RELAY_CONTAINERS_SUSPENSE: false,
|
|
18
|
-
ENABLE_PRECISE_TYPE_REFINEMENT: false
|
|
17
|
+
ENABLE_PRECISE_TYPE_REFINEMENT: false,
|
|
18
|
+
ENABLE_REACT_FLIGHT_COMPONENT_FIELD: false,
|
|
19
|
+
ENABLE_REQUIRED_DIRECTIVES: false,
|
|
20
|
+
ENABLE_GETFRAGMENTIDENTIFIER_OPTIMIZATION: false,
|
|
21
|
+
ENABLE_FRIENDLY_QUERY_NAME_GQL_URL: false,
|
|
22
|
+
ENABLE_STORE_SUBSCRIPTIONS_REFACTOR: false,
|
|
23
|
+
ENABLE_LOAD_QUERY_REQUEST_DEDUPING: true
|
|
19
24
|
};
|
|
20
25
|
module.exports = RelayFeatureFlags;
|
|
@@ -13,19 +13,14 @@
|
|
|
13
13
|
|
|
14
14
|
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
|
|
15
15
|
|
|
16
|
-
var
|
|
17
|
-
|
|
18
|
-
function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); if (enumerableOnly) symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; }); keys.push.apply(keys, symbols); } return keys; }
|
|
19
|
-
|
|
20
|
-
function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; if (i % 2) { ownKeys(Object(source), true).forEach(function (key) { (0, _defineProperty2["default"])(target, key, source[key]); }); } else if (Object.getOwnPropertyDescriptors) { Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); } else { ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } } return target; }
|
|
16
|
+
var _objectSpread2 = _interopRequireDefault(require("@babel/runtime/helpers/objectSpread2"));
|
|
21
17
|
|
|
22
18
|
var _require = require('../store/RelayStoreUtils'),
|
|
23
19
|
getModuleComponentKey = _require.getModuleComponentKey,
|
|
24
20
|
getModuleOperationKey = _require.getModuleOperationKey;
|
|
25
21
|
|
|
26
22
|
function createPayloadFor3DField(name, operation, component, response) {
|
|
27
|
-
var data =
|
|
28
|
-
|
|
23
|
+
var data = (0, _objectSpread2["default"])({}, response);
|
|
29
24
|
data[getModuleComponentKey(name)] = component;
|
|
30
25
|
data[getModuleOperationKey(name)] = operation;
|
|
31
26
|
return data;
|
|
@@ -11,6 +11,10 @@
|
|
|
11
11
|
// flowlint ambiguous-object-type:error
|
|
12
12
|
'use strict';
|
|
13
13
|
|
|
14
|
+
var RelayFeatureFlags = require('./RelayFeatureFlags');
|
|
15
|
+
|
|
16
|
+
var isEmptyObject = require('./isEmptyObject');
|
|
17
|
+
|
|
14
18
|
var stableCopy = require('./stableCopy');
|
|
15
19
|
|
|
16
20
|
var _require = require('../store/RelayModernSelector'),
|
|
@@ -19,15 +23,20 @@ var _require = require('../store/RelayModernSelector'),
|
|
|
19
23
|
getSelector = _require.getSelector;
|
|
20
24
|
|
|
21
25
|
function getFragmentIdentifier(fragmentNode, fragmentRef) {
|
|
22
|
-
var _JSON$stringify;
|
|
23
|
-
|
|
24
26
|
var selector = getSelector(fragmentNode, fragmentRef);
|
|
25
27
|
var fragmentOwnerIdentifier = selector == null ? 'null' : selector.kind === 'SingularReaderSelector' ? selector.owner.identifier : '[' + selector.selectors.map(function (sel) {
|
|
26
28
|
return sel.owner.identifier;
|
|
27
29
|
}).join(',') + ']';
|
|
28
30
|
var fragmentVariables = getVariablesFromFragment(fragmentNode, fragmentRef);
|
|
29
31
|
var dataIDs = getDataIDsFromFragment(fragmentNode, fragmentRef);
|
|
30
|
-
|
|
32
|
+
|
|
33
|
+
if (RelayFeatureFlags.ENABLE_GETFRAGMENTIDENTIFIER_OPTIMIZATION) {
|
|
34
|
+
return fragmentOwnerIdentifier + '/' + fragmentNode.name + '/' + (fragmentVariables == null || isEmptyObject(fragmentVariables) ? '{}' : JSON.stringify(stableCopy(fragmentVariables))) + '/' + (typeof dataIDs === 'undefined' ? 'missing' : dataIDs == null ? 'null' : Array.isArray(dataIDs) ? '[' + dataIDs.join(',') + ']' : dataIDs);
|
|
35
|
+
} else {
|
|
36
|
+
var _JSON$stringify;
|
|
37
|
+
|
|
38
|
+
return fragmentOwnerIdentifier + '/' + fragmentNode.name + '/' + JSON.stringify(stableCopy(fragmentVariables)) + '/' + ((_JSON$stringify = JSON.stringify(dataIDs)) !== null && _JSON$stringify !== void 0 ? _JSON$stringify : 'missing');
|
|
39
|
+
}
|
|
31
40
|
}
|
|
32
41
|
|
|
33
42
|
module.exports = getFragmentIdentifier;
|
|
@@ -0,0 +1,33 @@
|
|
|
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
|
+
* @emails oncall+relay
|
|
10
|
+
*/
|
|
11
|
+
// flowlint ambiguous-object-type:error
|
|
12
|
+
'use strict';
|
|
13
|
+
|
|
14
|
+
var _require = require('./RelayConcreteNode'),
|
|
15
|
+
REQUEST = _require.REQUEST,
|
|
16
|
+
SPLIT_OPERATION = _require.SPLIT_OPERATION;
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* OperationLoaders can return either a NormalizationSplitOperation or
|
|
20
|
+
* ConcreteRequest.
|
|
21
|
+
*/
|
|
22
|
+
function getOperation(node) {
|
|
23
|
+
switch (node.kind) {
|
|
24
|
+
case REQUEST:
|
|
25
|
+
return node.operation;
|
|
26
|
+
|
|
27
|
+
case SPLIT_OPERATION:
|
|
28
|
+
default:
|
|
29
|
+
return node;
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
module.exports = getOperation;
|
|
@@ -0,0 +1,25 @@
|
|
|
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
|
+
* @emails oncall+relay
|
|
10
|
+
*/
|
|
11
|
+
'use strict';
|
|
12
|
+
|
|
13
|
+
var hasOwnProperty = Object.prototype.hasOwnProperty;
|
|
14
|
+
|
|
15
|
+
function isEmptyObject(obj) {
|
|
16
|
+
for (var _key in obj) {
|
|
17
|
+
if (hasOwnProperty.call(obj, _key)) {
|
|
18
|
+
return false;
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
return true;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
module.exports = isEmptyObject;
|
|
@@ -9,12 +9,15 @@
|
|
|
9
9
|
*/
|
|
10
10
|
// flowlint ambiguous-object-type:error
|
|
11
11
|
'use strict';
|
|
12
|
+
|
|
13
|
+
var hasWeakSetDefined = typeof WeakSet !== 'undefined';
|
|
14
|
+
var hasWeakMapDefined = typeof WeakMap !== 'undefined';
|
|
12
15
|
/**
|
|
13
16
|
* Recycles subtrees from `prevData` by replacing equal subtrees in `nextData`.
|
|
14
17
|
*/
|
|
15
18
|
|
|
16
19
|
function recycleNodesInto(prevData, nextData) {
|
|
17
|
-
if (prevData === nextData || typeof prevData !== 'object' || !prevData || typeof nextData !== 'object' || !nextData) {
|
|
20
|
+
if (prevData === nextData || typeof prevData !== 'object' || prevData instanceof Set || prevData instanceof Map || hasWeakSetDefined && prevData instanceof WeakSet || hasWeakMapDefined && prevData instanceof WeakMap || !prevData || typeof nextData !== 'object' || nextData instanceof Set || nextData instanceof Map || hasWeakSetDefined && nextData instanceof WeakSet || hasWeakMapDefined && nextData instanceof WeakMap || !nextData) {
|
|
18
21
|
return nextData;
|
|
19
22
|
}
|
|
20
23
|
|
|
@@ -0,0 +1,48 @@
|
|
|
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
|
+
* @emails oncall+relay
|
|
9
|
+
* @format
|
|
10
|
+
*/
|
|
11
|
+
'use strict';
|
|
12
|
+
|
|
13
|
+
function reportMissingRequiredFields(environment, missingRequiredFields) {
|
|
14
|
+
switch (missingRequiredFields.action) {
|
|
15
|
+
case 'THROW':
|
|
16
|
+
{
|
|
17
|
+
var _missingRequiredField = missingRequiredFields.field,
|
|
18
|
+
path = _missingRequiredField.path,
|
|
19
|
+
owner = _missingRequiredField.owner; // This gives the consumer the chance to throw their own error if they so wish.
|
|
20
|
+
|
|
21
|
+
environment.requiredFieldLogger({
|
|
22
|
+
kind: 'missing_field.throw',
|
|
23
|
+
owner: owner,
|
|
24
|
+
fieldPath: path
|
|
25
|
+
});
|
|
26
|
+
throw new Error("Relay: Missing @required value at path '".concat(path, "' in '").concat(owner, "'."));
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
case 'LOG':
|
|
30
|
+
missingRequiredFields.fields.forEach(function (_ref) {
|
|
31
|
+
var path = _ref.path,
|
|
32
|
+
owner = _ref.owner;
|
|
33
|
+
environment.requiredFieldLogger({
|
|
34
|
+
kind: 'missing_field.log',
|
|
35
|
+
owner: owner,
|
|
36
|
+
fieldPath: path
|
|
37
|
+
});
|
|
38
|
+
});
|
|
39
|
+
break;
|
|
40
|
+
|
|
41
|
+
default:
|
|
42
|
+
{
|
|
43
|
+
missingRequiredFields.action;
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
module.exports = reportMissingRequiredFields;
|
|
@@ -13,7 +13,6 @@
|
|
|
13
13
|
'use strict';
|
|
14
14
|
|
|
15
15
|
const RelayDeclarativeMutationConfig = require('./RelayDeclarativeMutationConfig');
|
|
16
|
-
const RelayFeatureFlags = require('../util/RelayFeatureFlags');
|
|
17
16
|
|
|
18
17
|
const invariant = require('invariant');
|
|
19
18
|
const isRelayModernEnvironment = require('../store/isRelayModernEnvironment');
|
|
@@ -115,6 +114,7 @@ function commitMutation<T: MutationParameters>(
|
|
|
115
114
|
const operation = createOperationDescriptor(
|
|
116
115
|
mutation,
|
|
117
116
|
variables,
|
|
117
|
+
cacheConfig,
|
|
118
118
|
generateUniqueClientID(),
|
|
119
119
|
);
|
|
120
120
|
// TODO: remove this check after we fix flow.
|
|
@@ -142,7 +142,6 @@ function commitMutation<T: MutationParameters>(
|
|
|
142
142
|
const errors = [];
|
|
143
143
|
const subscription = environment
|
|
144
144
|
.executeMutation({
|
|
145
|
-
cacheConfig,
|
|
146
145
|
operation,
|
|
147
146
|
optimisticResponse,
|
|
148
147
|
optimisticUpdater,
|
|
@@ -19,16 +19,19 @@ import type {
|
|
|
19
19
|
import type {ConcreteRequest} from '../util/RelayConcreteNode';
|
|
20
20
|
import type {Variables} from '../util/RelayRuntimeTypes';
|
|
21
21
|
|
|
22
|
-
type ValidationContext = {
|
|
22
|
+
type ValidationContext = {|
|
|
23
23
|
visitedPaths: Set<string>,
|
|
24
24
|
path: string,
|
|
25
25
|
variables: Variables,
|
|
26
26
|
missingDiff: Object,
|
|
27
27
|
extraDiff: Object,
|
|
28
|
-
|
|
29
|
-
};
|
|
28
|
+
moduleImportPaths: Set<string>,
|
|
29
|
+
|};
|
|
30
|
+
|
|
30
31
|
const warning = require('warning');
|
|
31
32
|
|
|
33
|
+
const hasOwnProperty = Object.prototype.hasOwnProperty;
|
|
34
|
+
|
|
32
35
|
let validateMutation = () => {};
|
|
33
36
|
if (__DEV__) {
|
|
34
37
|
const addFieldToDiff = (path: string, diff: Object, isScalar) => {
|
|
@@ -55,6 +58,7 @@ if (__DEV__) {
|
|
|
55
58
|
variables: variables || {},
|
|
56
59
|
missingDiff: {},
|
|
57
60
|
extraDiff: {},
|
|
61
|
+
moduleImportPaths: new Set(),
|
|
58
62
|
};
|
|
59
63
|
validateSelections(
|
|
60
64
|
optimisticResponse,
|
|
@@ -97,6 +101,7 @@ if (__DEV__) {
|
|
|
97
101
|
return;
|
|
98
102
|
case 'ScalarField':
|
|
99
103
|
case 'LinkedField':
|
|
104
|
+
case 'FlightField':
|
|
100
105
|
return validateField(optimisticResponse, selection, context);
|
|
101
106
|
case 'InlineFragment':
|
|
102
107
|
const type = selection.type;
|
|
@@ -114,6 +119,7 @@ if (__DEV__) {
|
|
|
114
119
|
});
|
|
115
120
|
return;
|
|
116
121
|
case 'ModuleImport':
|
|
122
|
+
return validateModuleImport(context);
|
|
117
123
|
case 'LinkedHandle':
|
|
118
124
|
case 'ScalarHandle':
|
|
119
125
|
case 'Defer':
|
|
@@ -128,6 +134,10 @@ if (__DEV__) {
|
|
|
128
134
|
}
|
|
129
135
|
};
|
|
130
136
|
|
|
137
|
+
const validateModuleImport = (context: ValidationContext) => {
|
|
138
|
+
context.moduleImportPaths.add(context.path);
|
|
139
|
+
};
|
|
140
|
+
|
|
131
141
|
const validateField = (
|
|
132
142
|
optimisticResponse: Object,
|
|
133
143
|
field: NormalizationField,
|
|
@@ -138,7 +148,7 @@ if (__DEV__) {
|
|
|
138
148
|
context.visitedPaths.add(path);
|
|
139
149
|
switch (field.kind) {
|
|
140
150
|
case 'ScalarField':
|
|
141
|
-
if (
|
|
151
|
+
if (hasOwnProperty.call(optimisticResponse, fieldName) === false) {
|
|
142
152
|
addFieldToDiff(path, context.missingDiff, true);
|
|
143
153
|
}
|
|
144
154
|
return;
|
|
@@ -146,7 +156,7 @@ if (__DEV__) {
|
|
|
146
156
|
const selections = field.selections;
|
|
147
157
|
if (
|
|
148
158
|
optimisticResponse[fieldName] === null ||
|
|
149
|
-
(
|
|
159
|
+
(hasOwnProperty.call(optimisticResponse, fieldName) &&
|
|
150
160
|
optimisticResponse[fieldName] === undefined)
|
|
151
161
|
) {
|
|
152
162
|
return;
|
|
@@ -178,6 +188,21 @@ if (__DEV__) {
|
|
|
178
188
|
return;
|
|
179
189
|
}
|
|
180
190
|
}
|
|
191
|
+
case 'FlightField':
|
|
192
|
+
if (
|
|
193
|
+
optimisticResponse[fieldName] === null ||
|
|
194
|
+
(hasOwnProperty.call(optimisticResponse, fieldName) &&
|
|
195
|
+
optimisticResponse[fieldName] === undefined)
|
|
196
|
+
) {
|
|
197
|
+
return;
|
|
198
|
+
}
|
|
199
|
+
throw new Error(
|
|
200
|
+
'validateMutation: Flight fields are not compatible with ' +
|
|
201
|
+
'optimistic updates, as React does not have the component code ' +
|
|
202
|
+
'necessary to process new data on the client. Instead, you ' +
|
|
203
|
+
'should update your code to require a full refetch of the Flight ' +
|
|
204
|
+
'field so your UI can be updated.',
|
|
205
|
+
);
|
|
181
206
|
}
|
|
182
207
|
};
|
|
183
208
|
|
|
@@ -196,6 +221,10 @@ if (__DEV__) {
|
|
|
196
221
|
Object.keys(optimisticResponse).forEach((key: string) => {
|
|
197
222
|
const value = optimisticResponse[key];
|
|
198
223
|
const path = `${context.path}.${key}`;
|
|
224
|
+
// if it's a module import path we don't have an ast so we cannot validate it
|
|
225
|
+
if (context.moduleImportPaths.has(path)) {
|
|
226
|
+
return;
|
|
227
|
+
}
|
|
199
228
|
if (!context.visitedPaths.has(path)) {
|
|
200
229
|
addFieldToDiff(path, context.extraDiff);
|
|
201
230
|
return;
|
|
@@ -121,3 +121,25 @@ export type SubscribeFunction = (
|
|
|
121
121
|
|
|
122
122
|
export type Uploadable = File | Blob;
|
|
123
123
|
export type UploadableMap = {[key: string]: Uploadable, ...};
|
|
124
|
+
|
|
125
|
+
/**
|
|
126
|
+
* React Flight tree created on the server.
|
|
127
|
+
*/
|
|
128
|
+
export type ReactFlightServerTree = mixed;
|
|
129
|
+
export type ReactFlightPayloadQuery = {|
|
|
130
|
+
+id: mixed,
|
|
131
|
+
+module: mixed,
|
|
132
|
+
+response: GraphQLSingularResponse,
|
|
133
|
+
+variables: Variables,
|
|
134
|
+
|};
|
|
135
|
+
/**
|
|
136
|
+
* Data that is returned by a Flight compliant GraphQL server.
|
|
137
|
+
*
|
|
138
|
+
* - tree: an array of values that will be iterated and fed into
|
|
139
|
+
* ReactFlightDOMRelayClient.
|
|
140
|
+
* - queries: an array of queries that the server preloaded for the client.
|
|
141
|
+
*/
|
|
142
|
+
export type ReactFlightPayloadData = {|
|
|
143
|
+
+tree: Array<ReactFlightServerTree>,
|
|
144
|
+
+queries: Array<ReactFlightPayloadQuery>,
|
|
145
|
+
|};
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "relay-runtime",
|
|
3
3
|
"description": "A core runtime for building GraphQL-driven applications.",
|
|
4
|
-
"version": "10.
|
|
4
|
+
"version": "10.1.3",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"graphql",
|
|
7
7
|
"relay"
|
|
@@ -12,7 +12,7 @@
|
|
|
12
12
|
"repository": "facebook/relay",
|
|
13
13
|
"dependencies": {
|
|
14
14
|
"@babel/runtime": "^7.0.0",
|
|
15
|
-
"fbjs": "^
|
|
15
|
+
"fbjs": "^3.0.0"
|
|
16
16
|
},
|
|
17
17
|
"directories": {
|
|
18
18
|
"": "./"
|
package/query/GraphQLTag.js.flow
CHANGED
|
@@ -44,7 +44,8 @@ function graphql(strings: Array<string>): GraphQLTaggedNode {
|
|
|
44
44
|
false,
|
|
45
45
|
'graphql: Unexpected invocation at runtime. Either the Babel transform ' +
|
|
46
46
|
'was not set up, or it failed to identify this call site. Make sure it ' +
|
|
47
|
-
'is being used verbatim as `graphql`.'
|
|
47
|
+
'is being used verbatim as `graphql`. Note also that there cannot be ' +
|
|
48
|
+
'a space between graphql and the backtick that follows.',
|
|
48
49
|
);
|
|
49
50
|
}
|
|
50
51
|
|
|
@@ -155,6 +156,7 @@ function getInlineDataFragment(
|
|
|
155
156
|
|
|
156
157
|
module.exports = {
|
|
157
158
|
getFragment,
|
|
159
|
+
getNode,
|
|
158
160
|
getPaginationFragment,
|
|
159
161
|
getRefetchableFragment,
|
|
160
162
|
getRequest,
|
package/query/fetchQuery.js.flow
CHANGED
|
@@ -37,9 +37,9 @@ function fetchQuery<T: OperationType>(
|
|
|
37
37
|
if (query.params.operationKind !== 'query') {
|
|
38
38
|
throw new Error('fetchQuery: Expected query operation');
|
|
39
39
|
}
|
|
40
|
-
const operation = createOperationDescriptor(query, variables);
|
|
40
|
+
const operation = createOperationDescriptor(query, variables, cacheConfig);
|
|
41
41
|
return environment
|
|
42
|
-
.execute({operation
|
|
42
|
+
.execute({operation})
|
|
43
43
|
.map(() => environment.lookup(operation.fragment).data)
|
|
44
44
|
.toPromise();
|
|
45
45
|
}
|
|
@@ -24,7 +24,6 @@ import type {
|
|
|
24
24
|
OperationDescriptor,
|
|
25
25
|
RequestDescriptor,
|
|
26
26
|
} from '../store/RelayStoreTypes';
|
|
27
|
-
import type {CacheConfig} from '../util/RelayRuntimeTypes';
|
|
28
27
|
import type {RequestIdentifier} from '../util/getRequestIdentifier';
|
|
29
28
|
|
|
30
29
|
type RequestCacheEntry = {|
|
|
@@ -106,14 +105,10 @@ const requestCachesByEnvironment = WEAKMAP_SUPPORTED
|
|
|
106
105
|
function fetchQuery(
|
|
107
106
|
environment: IEnvironment,
|
|
108
107
|
operation: OperationDescriptor,
|
|
109
|
-
options?: {|
|
|
110
|
-
networkCacheConfig?: CacheConfig,
|
|
111
|
-
|},
|
|
112
108
|
): Observable<GraphQLResponse> {
|
|
113
109
|
return fetchQueryDeduped(environment, operation.request.identifier, () =>
|
|
114
110
|
environment.execute({
|
|
115
111
|
operation,
|
|
116
|
-
cacheConfig: options?.networkCacheConfig,
|
|
117
112
|
}),
|
|
118
113
|
);
|
|
119
114
|
}
|