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.
Files changed (82) hide show
  1. package/handlers/RelayDefaultHandlerProvider.js.flow +6 -0
  2. package/handlers/connection/MutationHandlers.js.flow +152 -20
  3. package/index.js +1 -1
  4. package/index.js.flow +17 -1
  5. package/lib/handlers/RelayDefaultHandlerProvider.js +9 -0
  6. package/lib/handlers/connection/MutationHandlers.js +185 -21
  7. package/lib/index.js +7 -0
  8. package/lib/mutations/RelayDeclarativeMutationConfig.js +5 -7
  9. package/lib/mutations/commitMutation.js +1 -4
  10. package/lib/mutations/validateMutation.js +28 -12
  11. package/lib/network/RelayQueryResponseCache.js +3 -7
  12. package/lib/query/GraphQLTag.js +2 -1
  13. package/lib/query/fetchQuery.js +2 -3
  14. package/lib/query/fetchQueryInternal.js +2 -3
  15. package/lib/store/DataChecker.js +85 -10
  16. package/lib/store/RelayConcreteVariables.js +2 -6
  17. package/lib/store/RelayModernEnvironment.js +81 -72
  18. package/lib/store/RelayModernFragmentSpecResolver.js +14 -7
  19. package/lib/store/RelayModernOperationDescriptor.js +6 -5
  20. package/lib/store/RelayModernQueryExecutor.js +46 -33
  21. package/lib/store/RelayModernRecord.js +3 -7
  22. package/lib/store/RelayModernStore.js +39 -137
  23. package/lib/store/RelayOperationTracker.js +7 -9
  24. package/lib/store/RelayOptimisticRecordSource.js +2 -6
  25. package/lib/store/RelayPublishQueue.js +1 -1
  26. package/lib/store/RelayReader.js +196 -33
  27. package/lib/store/RelayRecordSourceMapImpl.js +3 -5
  28. package/lib/store/RelayReferenceMarker.js +87 -5
  29. package/lib/store/RelayResponseNormalizer.js +115 -19
  30. package/lib/store/RelayStoreReactFlightUtils.js +47 -0
  31. package/lib/store/RelayStoreSubscriptions.js +162 -0
  32. package/lib/store/RelayStoreSubscriptionsUsingMapByID.js +258 -0
  33. package/lib/store/StoreInspector.js +2 -6
  34. package/lib/store/createRelayContext.js +5 -0
  35. package/lib/store/defaultRequiredFieldLogger.js +18 -0
  36. package/lib/store/normalizeRelayPayload.js +2 -6
  37. package/lib/subscription/requestSubscription.js +2 -3
  38. package/lib/util/NormalizationNode.js +1 -5
  39. package/lib/util/RelayConcreteNode.js +2 -0
  40. package/lib/util/RelayFeatureFlags.js +7 -2
  41. package/lib/util/createPayloadFor3DField.js +2 -7
  42. package/lib/util/getFragmentIdentifier.js +12 -3
  43. package/lib/util/getOperation.js +33 -0
  44. package/lib/util/isEmptyObject.js +25 -0
  45. package/lib/util/recycleNodesInto.js +4 -1
  46. package/lib/util/reportMissingRequiredFields.js +48 -0
  47. package/mutations/commitMutation.js.flow +1 -2
  48. package/mutations/validateMutation.js.flow +34 -5
  49. package/network/RelayNetworkTypes.js.flow +22 -0
  50. package/package.json +2 -2
  51. package/query/GraphQLTag.js.flow +3 -1
  52. package/query/fetchQuery.js.flow +2 -2
  53. package/query/fetchQueryInternal.js.flow +0 -5
  54. package/relay-runtime.js +2 -2
  55. package/relay-runtime.min.js +2 -2
  56. package/store/DataChecker.js.flow +68 -2
  57. package/store/RelayModernEnvironment.js.flow +107 -87
  58. package/store/RelayModernFragmentSpecResolver.js.flow +13 -1
  59. package/store/RelayModernOperationDescriptor.js.flow +5 -1
  60. package/store/RelayModernQueryExecutor.js.flow +47 -23
  61. package/store/RelayModernStore.js.flow +33 -107
  62. package/store/RelayPublishQueue.js.flow +1 -1
  63. package/store/RelayReader.js.flow +180 -15
  64. package/store/RelayReferenceMarker.js.flow +72 -5
  65. package/store/RelayResponseNormalizer.js.flow +130 -19
  66. package/store/RelayStoreReactFlightUtils.js.flow +64 -0
  67. package/store/RelayStoreSubscriptions.js.flow +168 -0
  68. package/store/RelayStoreSubscriptionsUsingMapByID.js.flow +259 -0
  69. package/store/RelayStoreTypes.js.flow +130 -37
  70. package/store/createRelayContext.js.flow +3 -0
  71. package/store/defaultRequiredFieldLogger.js.flow +23 -0
  72. package/subscription/requestSubscription.js.flow +5 -2
  73. package/util/NormalizationNode.js.flow +17 -2
  74. package/util/ReaderNode.js.flow +20 -1
  75. package/util/RelayConcreteNode.js.flow +6 -0
  76. package/util/RelayFeatureFlags.js.flow +12 -1
  77. package/util/getFragmentIdentifier.js.flow +33 -9
  78. package/util/getOperation.js.flow +40 -0
  79. package/util/getRequestIdentifier.js.flow +1 -1
  80. package/util/isEmptyObject.js.flow +25 -0
  81. package/util/recycleNodesInto.js.flow +11 -0
  82. 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 _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty"));
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(_objectSpread({}, record), {
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 _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty"));
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 _objectSpread({}, relayPayload, {
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
 
@@ -8,8 +8,4 @@
8
8
  * @format
9
9
  */
10
10
  // flowlint ambiguous-object-type:error
11
- 'use strict';
12
- /**
13
- * Represents a single operation used to processing and normalize runtime
14
- * request results.
15
- */
11
+ 'use strict';
@@ -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 _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty"));
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 = _objectSpread({}, response);
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
- return fragmentOwnerIdentifier + '/' + fragmentNode.name + '/' + JSON.stringify(stableCopy(fragmentVariables)) + '/' + ((_JSON$stringify = JSON.stringify(dataIDs)) !== null && _JSON$stringify !== void 0 ? _JSON$stringify : 'missing');
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 (optimisticResponse.hasOwnProperty(fieldName) === false) {
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
- (Object.hasOwnProperty(fieldName) &&
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.0.1",
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": "^1.0.0"
15
+ "fbjs": "^3.0.0"
16
16
  },
17
17
  "directories": {
18
18
  "": "./"
@@ -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,
@@ -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, cacheConfig})
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
  }