relay-runtime 7.0.0 → 9.1.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.
Files changed (157) hide show
  1. package/handlers/RelayDefaultHandlerProvider.js.flow +34 -0
  2. package/handlers/connection/ConnectionHandler.js.flow +549 -0
  3. package/handlers/connection/ConnectionInterface.js.flow +92 -0
  4. package/index.js +1 -1
  5. package/index.js.flow +314 -0
  6. package/lib/handlers/RelayDefaultHandlerProvider.js +3 -2
  7. package/lib/handlers/connection/{RelayConnectionHandler.js → ConnectionHandler.js} +34 -35
  8. package/lib/handlers/connection/{RelayConnectionInterface.js → ConnectionInterface.js} +3 -30
  9. package/lib/index.js +29 -27
  10. package/lib/mutations/RelayDeclarativeMutationConfig.js +30 -52
  11. package/lib/mutations/RelayRecordProxy.js +6 -3
  12. package/lib/mutations/RelayRecordSourceMutator.js +3 -9
  13. package/lib/mutations/RelayRecordSourceProxy.js +21 -24
  14. package/lib/mutations/RelayRecordSourceSelectorProxy.js +18 -14
  15. package/lib/mutations/applyOptimisticMutation.js +2 -1
  16. package/lib/mutations/commitLocalUpdate.js +1 -0
  17. package/lib/mutations/commitMutation.js +26 -8
  18. package/lib/mutations/validateMutation.js +21 -11
  19. package/lib/network/ConvertToExecuteFunction.js +1 -0
  20. package/lib/network/RelayNetwork.js +1 -0
  21. package/lib/network/RelayNetworkTypes.js +1 -0
  22. package/lib/network/RelayObservable.js +10 -9
  23. package/lib/network/RelayQueryResponseCache.js +9 -7
  24. package/lib/query/{RelayModernGraphQLTag.js → GraphQLTag.js} +15 -8
  25. package/lib/query/fetchQuery.js +2 -1
  26. package/lib/query/fetchQueryInternal.js +30 -20
  27. package/lib/store/ClientID.js +1 -0
  28. package/lib/store/DataChecker.js +47 -97
  29. package/lib/store/RelayConcreteVariables.js +7 -2
  30. package/lib/store/RelayModernEnvironment.js +82 -41
  31. package/lib/store/RelayModernFragmentSpecResolver.js +61 -21
  32. package/lib/store/RelayModernOperationDescriptor.js +2 -1
  33. package/lib/store/RelayModernQueryExecutor.js +476 -333
  34. package/lib/store/RelayModernRecord.js +39 -9
  35. package/lib/store/RelayModernSelector.js +2 -1
  36. package/lib/store/RelayModernStore.js +359 -371
  37. package/lib/store/RelayOperationTracker.js +36 -78
  38. package/lib/store/RelayOptimisticRecordSource.js +8 -5
  39. package/lib/store/RelayPublishQueue.js +66 -53
  40. package/lib/store/RelayReader.js +2 -24
  41. package/lib/store/RelayRecordSource.js +3 -9
  42. package/lib/store/RelayRecordSourceMapImpl.js +14 -18
  43. package/lib/store/RelayRecordState.js +1 -0
  44. package/lib/store/RelayReferenceMarker.js +8 -58
  45. package/lib/store/RelayResponseNormalizer.js +15 -144
  46. package/lib/store/RelayStoreTypes.js +1 -0
  47. package/lib/store/RelayStoreUtils.js +34 -10
  48. package/lib/store/StoreInspector.js +11 -5
  49. package/lib/store/ViewerPattern.js +1 -0
  50. package/lib/store/cloneRelayHandleSourceField.js +1 -0
  51. package/lib/store/createFragmentSpecResolver.js +1 -0
  52. package/lib/store/createRelayContext.js +1 -0
  53. package/lib/store/defaultGetDataID.js +1 -0
  54. package/lib/store/hasOverlappingIDs.js +1 -0
  55. package/lib/store/isRelayModernEnvironment.js +1 -0
  56. package/lib/store/normalizeRelayPayload.js +8 -4
  57. package/lib/store/readInlineData.js +2 -1
  58. package/lib/subscription/requestSubscription.js +6 -3
  59. package/lib/util/JSResourceTypes.flow.js +12 -0
  60. package/lib/util/NormalizationNode.js +1 -0
  61. package/lib/util/ReaderNode.js +1 -0
  62. package/lib/util/RelayConcreteNode.js +3 -0
  63. package/lib/util/RelayDefaultHandleKey.js +1 -0
  64. package/lib/util/RelayError.js +2 -1
  65. package/lib/util/RelayFeatureFlags.js +3 -2
  66. package/lib/util/RelayProfiler.js +1 -0
  67. package/lib/util/RelayReplaySubject.js +2 -3
  68. package/lib/util/RelayRuntimeTypes.js +1 -0
  69. package/lib/util/createPayloadFor3DField.js +34 -0
  70. package/lib/util/deepFreeze.js +1 -0
  71. package/lib/util/generateID.js +1 -0
  72. package/lib/util/getFragmentIdentifier.js +1 -0
  73. package/lib/util/getRelayHandleKey.js +1 -0
  74. package/lib/util/getRequestIdentifier.js +1 -0
  75. package/lib/util/isPromise.js +1 -0
  76. package/lib/util/isScalarAndEqual.js +1 -0
  77. package/lib/util/recycleNodesInto.js +1 -0
  78. package/lib/util/resolveImmediate.js +1 -0
  79. package/lib/util/stableCopy.js +1 -0
  80. package/mutations/RelayDeclarativeMutationConfig.js.flow +380 -0
  81. package/mutations/RelayRecordProxy.js.flow +165 -0
  82. package/mutations/RelayRecordSourceMutator.js.flow +238 -0
  83. package/mutations/RelayRecordSourceProxy.js.flow +164 -0
  84. package/mutations/RelayRecordSourceSelectorProxy.js.flow +119 -0
  85. package/mutations/applyOptimisticMutation.js.flow +76 -0
  86. package/mutations/commitLocalUpdate.js.flow +24 -0
  87. package/mutations/commitMutation.js.flow +184 -0
  88. package/mutations/validateMutation.js.flow +211 -0
  89. package/network/ConvertToExecuteFunction.js.flow +49 -0
  90. package/network/RelayNetwork.js.flow +84 -0
  91. package/network/RelayNetworkTypes.js.flow +123 -0
  92. package/network/RelayObservable.js.flow +634 -0
  93. package/network/RelayQueryResponseCache.js.flow +111 -0
  94. package/package.json +1 -1
  95. package/query/GraphQLTag.js.flow +166 -0
  96. package/query/fetchQuery.js.flow +47 -0
  97. package/query/fetchQueryInternal.js.flow +349 -0
  98. package/relay-runtime.js +2 -2
  99. package/relay-runtime.min.js +2 -2
  100. package/store/ClientID.js.flow +43 -0
  101. package/store/DataChecker.js.flow +426 -0
  102. package/store/RelayConcreteVariables.js.flow +96 -0
  103. package/store/RelayModernEnvironment.js.flow +526 -0
  104. package/store/RelayModernFragmentSpecResolver.js.flow +426 -0
  105. package/store/RelayModernOperationDescriptor.js.flow +88 -0
  106. package/store/RelayModernQueryExecutor.js.flow +1327 -0
  107. package/store/RelayModernRecord.js.flow +403 -0
  108. package/store/RelayModernSelector.js.flow +444 -0
  109. package/store/RelayModernStore.js.flow +757 -0
  110. package/store/RelayOperationTracker.js.flow +164 -0
  111. package/store/RelayOptimisticRecordSource.js.flow +119 -0
  112. package/store/RelayPublishQueue.js.flow +401 -0
  113. package/store/RelayReader.js.flow +376 -0
  114. package/store/RelayRecordSource.js.flow +29 -0
  115. package/store/RelayRecordSourceMapImpl.js.flow +87 -0
  116. package/store/RelayRecordState.js.flow +37 -0
  117. package/store/RelayReferenceMarker.js.flow +236 -0
  118. package/store/RelayResponseNormalizer.js.flow +556 -0
  119. package/store/RelayStoreTypes.js.flow +873 -0
  120. package/store/RelayStoreUtils.js.flow +218 -0
  121. package/store/StoreInspector.js.flow +173 -0
  122. package/store/ViewerPattern.js.flow +26 -0
  123. package/store/cloneRelayHandleSourceField.js.flow +66 -0
  124. package/store/createFragmentSpecResolver.js.flow +55 -0
  125. package/store/createRelayContext.js.flow +44 -0
  126. package/store/defaultGetDataID.js.flow +27 -0
  127. package/store/hasOverlappingIDs.js.flow +34 -0
  128. package/store/isRelayModernEnvironment.js.flow +27 -0
  129. package/store/normalizeRelayPayload.js.flow +51 -0
  130. package/store/readInlineData.js.flow +75 -0
  131. package/subscription/requestSubscription.js.flow +100 -0
  132. package/util/JSResourceTypes.flow.js.flow +20 -0
  133. package/util/NormalizationNode.js.flow +191 -0
  134. package/util/ReaderNode.js.flow +208 -0
  135. package/util/RelayConcreteNode.js.flow +80 -0
  136. package/util/RelayDefaultHandleKey.js.flow +17 -0
  137. package/util/RelayError.js.flow +33 -0
  138. package/util/RelayFeatureFlags.js.flow +30 -0
  139. package/util/RelayProfiler.js.flow +284 -0
  140. package/util/RelayReplaySubject.js.flow +134 -0
  141. package/util/RelayRuntimeTypes.js.flow +70 -0
  142. package/util/createPayloadFor3DField.js.flow +43 -0
  143. package/util/deepFreeze.js.flow +36 -0
  144. package/util/generateID.js.flow +21 -0
  145. package/util/getFragmentIdentifier.js.flow +52 -0
  146. package/util/getRelayHandleKey.js.flow +41 -0
  147. package/util/getRequestIdentifier.js.flow +41 -0
  148. package/util/isPromise.js.flow +21 -0
  149. package/util/isScalarAndEqual.js.flow +26 -0
  150. package/util/recycleNodesInto.js.flow +80 -0
  151. package/util/resolveImmediate.js.flow +30 -0
  152. package/util/stableCopy.js.flow +35 -0
  153. package/lib/handlers/RelayDefaultMissingFieldHandlers.js +0 -26
  154. package/lib/store/RelayConnection.js +0 -36
  155. package/lib/store/RelayConnectionResolver.js +0 -177
  156. package/lib/store/RelayRecordSourceObjectImpl.js +0 -78
  157. package/lib/util/getFragmentSpecIdentifier.js +0 -26
@@ -0,0 +1,12 @@
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
+ * @emails oncall+relay
8
+ *
9
+ * @format
10
+ */
11
+ // flowlint ambiguous-object-type:error
12
+ 'use strict';
@@ -7,6 +7,7 @@
7
7
  *
8
8
  * @format
9
9
  */
10
+ // flowlint ambiguous-object-type:error
10
11
  'use strict';
11
12
  /**
12
13
  * Represents a single operation used to processing and normalize runtime
@@ -7,4 +7,5 @@
7
7
  *
8
8
  * @format
9
9
  */
10
+ // flowlint ambiguous-object-type:error
10
11
  'use strict';
@@ -7,6 +7,7 @@
7
7
  *
8
8
  * @format
9
9
  */
10
+ // flowlint ambiguous-object-type:error
10
11
  'use strict';
11
12
 
12
13
  /**
@@ -33,8 +34,10 @@ var RelayConcreteNode = {
33
34
  LINKED_FIELD: 'LinkedField',
34
35
  LINKED_HANDLE: 'LinkedHandle',
35
36
  LITERAL: 'Literal',
37
+ LIST_VALUE: 'ListValue',
36
38
  LOCAL_ARGUMENT: 'LocalArgument',
37
39
  MODULE_IMPORT: 'ModuleImport',
40
+ OBJECT_VALUE: 'ObjectValue',
38
41
  OPERATION: 'Operation',
39
42
  REQUEST: 'Request',
40
43
  ROOT_ARGUMENT: 'RootArgument',
@@ -7,6 +7,7 @@
7
7
  *
8
8
  * @format
9
9
  */
10
+ // flowlint ambiguous-object-type:error
10
11
  'use strict';
11
12
 
12
13
  module.exports = {
@@ -7,6 +7,7 @@
7
7
  *
8
8
  * @format
9
9
  */
10
+ // flowlint ambiguous-object-type:error
10
11
  'use strict';
11
12
  /**
12
13
  * @private
@@ -22,7 +23,7 @@ function createError(type, name, message) {
22
23
 
23
24
  module.exports = {
24
25
  create: function create(name, message) {
25
- return createError('mustfix', name, message);
26
+ return createError('error', name, message);
26
27
  },
27
28
  createWarning: function createWarning(name, message) {
28
29
  return createError('warn', name, message);
@@ -7,13 +7,14 @@
7
7
  *
8
8
  * @format
9
9
  */
10
+ // flowlint ambiguous-object-type:error
10
11
  'use strict';
11
12
 
12
13
  var RelayFeatureFlags = {
13
14
  // T45504512: new connection model
14
15
  ENABLE_VARIABLE_CONNECTION_KEY: false,
15
- ENABLE_CONNECTION_RESOLVERS: false,
16
16
  ENABLE_PARTIAL_RENDERING_DEFAULT: false,
17
- USE_RECORD_SOURCE_MAP_IMPL: false
17
+ ENABLE_RELAY_CONTAINERS_SUSPENSE: false,
18
+ ENABLE_UNIQUE_MUTATION_ROOT: true
18
19
  };
19
20
  module.exports = RelayFeatureFlags;
@@ -7,6 +7,7 @@
7
7
  *
8
8
  * @format
9
9
  */
10
+ // flowlint ambiguous-object-type:error
10
11
  'use strict';
11
12
 
12
13
  function emptyFunction() {}
@@ -7,6 +7,7 @@
7
7
  *
8
8
  * @format
9
9
  */
10
+ // flowlint ambiguous-object-type:error
10
11
  'use strict';
11
12
 
12
13
  var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
@@ -23,9 +24,7 @@ var invariant = require("fbjs/lib/invariant");
23
24
  * Records events provided and synchronously plays them back to new subscribers,
24
25
  * as well as forwarding new asynchronous events.
25
26
  */
26
- var RelayReplaySubject =
27
- /*#__PURE__*/
28
- function () {
27
+ var RelayReplaySubject = /*#__PURE__*/function () {
29
28
  function RelayReplaySubject() {
30
29
  var _this = this;
31
30
 
@@ -7,6 +7,7 @@
7
7
  *
8
8
  * @format
9
9
  */
10
+ // flowlint ambiguous-object-type:error
10
11
  'use strict';
11
12
  /**
12
13
  * Basic types used throughout Relay.
@@ -0,0 +1,34 @@
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
+ * @emails oncall+relay
8
+ *
9
+ * @format
10
+ */
11
+ // flowlint ambiguous-object-type:error
12
+ 'use strict';
13
+
14
+ var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
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; }
21
+
22
+ var _require = require('../store/RelayStoreUtils'),
23
+ getModuleComponentKey = _require.getModuleComponentKey,
24
+ getModuleOperationKey = _require.getModuleOperationKey;
25
+
26
+ function createPayloadFor3DField(name, operation, component, response) {
27
+ var data = _objectSpread({}, response);
28
+
29
+ data[getModuleComponentKey(name)] = component;
30
+ data[getModuleOperationKey(name)] = operation;
31
+ return data;
32
+ }
33
+
34
+ module.exports = createPayloadFor3DField;
@@ -7,6 +7,7 @@
7
7
  *
8
8
  * @format
9
9
  */
10
+ // flowlint ambiguous-object-type:error
10
11
  'use strict';
11
12
  /**
12
13
  * Recursively "deep" freezes the supplied object.
@@ -7,6 +7,7 @@
7
7
  *
8
8
  * @format
9
9
  */
10
+ // flowlint ambiguous-object-type:error
10
11
  'use strict';
11
12
 
12
13
  var id = 100000;
@@ -8,6 +8,7 @@
8
8
  * @format
9
9
  * @emails oncall+relay
10
10
  */
11
+ // flowlint ambiguous-object-type:error
11
12
  'use strict';
12
13
 
13
14
  var stableCopy = require('./stableCopy');
@@ -7,6 +7,7 @@
7
7
  *
8
8
  * @format
9
9
  */
10
+ // flowlint ambiguous-object-type:error
10
11
  'use strict';
11
12
 
12
13
  var invariant = require("fbjs/lib/invariant");
@@ -7,6 +7,7 @@
7
7
  *
8
8
  * @format
9
9
  */
10
+ // flowlint ambiguous-object-type:error
10
11
  'use strict';
11
12
 
12
13
  var invariant = require("fbjs/lib/invariant");
@@ -7,6 +7,7 @@
7
7
  *
8
8
  * @format
9
9
  */
10
+ // flowlint ambiguous-object-type:error
10
11
  'use strict';
11
12
 
12
13
  function isPromise(p) {
@@ -7,6 +7,7 @@
7
7
  *
8
8
  * @format
9
9
  */
10
+ // flowlint ambiguous-object-type:error
10
11
  'use strict';
11
12
  /**
12
13
  * A fast test to determine if two values are equal scalars:
@@ -7,6 +7,7 @@
7
7
  *
8
8
  * @format
9
9
  */
10
+ // flowlint ambiguous-object-type:error
10
11
  'use strict';
11
12
  /**
12
13
  * Recycles subtrees from `prevData` by replacing equal subtrees in `nextData`.
@@ -7,6 +7,7 @@
7
7
  *
8
8
  * @format
9
9
  */
10
+ // flowlint ambiguous-object-type:error
10
11
  'use strict';
11
12
 
12
13
  var resolvedPromise = Promise.resolve();
@@ -7,6 +7,7 @@
7
7
  *
8
8
  * @format
9
9
  */
10
+ // flowlint ambiguous-object-type:error
10
11
  'use strict';
11
12
  /**
12
13
  * Creates a copy of the provided value, ensuring any nested objects have their
@@ -0,0 +1,380 @@
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
+ * @flow
8
+ * @format
9
+ */
10
+
11
+ // flowlint ambiguous-object-type:error
12
+
13
+ 'use strict';
14
+
15
+ const ConnectionHandler = require('../handlers/connection/ConnectionHandler');
16
+
17
+ const warning = require('warning');
18
+
19
+ import type {
20
+ RecordSourceSelectorProxy,
21
+ SelectorData,
22
+ SelectorStoreUpdater,
23
+ } from '../store/RelayStoreTypes';
24
+ import type {ConcreteRequest} from '../util/RelayConcreteNode';
25
+ import type {Variables} from '../util/RelayRuntimeTypes';
26
+
27
+ const MutationTypes = Object.freeze({
28
+ RANGE_ADD: 'RANGE_ADD',
29
+ RANGE_DELETE: 'RANGE_DELETE',
30
+ NODE_DELETE: 'NODE_DELETE',
31
+ });
32
+ export type MutationType = $Values<typeof MutationTypes>;
33
+
34
+ const RangeOperations = Object.freeze({
35
+ APPEND: 'append',
36
+ PREPEND: 'prepend',
37
+ });
38
+ export type RangeOperation = $Values<typeof RangeOperations>;
39
+
40
+ type RangeBehaviorsFunction = (connectionArgs: {
41
+ [name: string]: $FlowFixMe,
42
+ ...,
43
+ }) => RangeOperation;
44
+ type RangeBehaviorsObject = {[key: string]: RangeOperation, ...};
45
+ export type RangeBehaviors = RangeBehaviorsFunction | RangeBehaviorsObject;
46
+
47
+ type RangeAddConfig = {|
48
+ type: 'RANGE_ADD',
49
+ parentName?: string,
50
+ parentID?: string,
51
+ connectionInfo?: Array<{|
52
+ key: string,
53
+ filters?: Variables,
54
+ rangeBehavior: string,
55
+ |}>,
56
+ connectionName?: string,
57
+ edgeName: string,
58
+ rangeBehaviors?: RangeBehaviors,
59
+ |};
60
+
61
+ type RangeDeleteConfig = {|
62
+ type: 'RANGE_DELETE',
63
+ parentName?: string,
64
+ parentID?: string,
65
+ connectionKeys?: Array<{|
66
+ key: string,
67
+ filters?: Variables,
68
+ |}>,
69
+ connectionName?: string,
70
+ deletedIDFieldName: string | Array<string>,
71
+ pathToConnection: Array<string>,
72
+ |};
73
+
74
+ type NodeDeleteConfig = {|
75
+ type: 'NODE_DELETE',
76
+ parentName?: string,
77
+ parentID?: string,
78
+ connectionName?: string,
79
+ deletedIDFieldName: string,
80
+ |};
81
+
82
+ export type DeclarativeMutationConfig =
83
+ | RangeAddConfig
84
+ | RangeDeleteConfig
85
+ | NodeDeleteConfig;
86
+
87
+ function convert(
88
+ configs: Array<DeclarativeMutationConfig>,
89
+ request: ConcreteRequest,
90
+ optimisticUpdater?: ?SelectorStoreUpdater,
91
+ updater?: ?SelectorStoreUpdater,
92
+ ): {
93
+ optimisticUpdater: SelectorStoreUpdater,
94
+ updater: SelectorStoreUpdater,
95
+ ...
96
+ } {
97
+ const configOptimisticUpdates = optimisticUpdater ? [optimisticUpdater] : [];
98
+ const configUpdates = updater ? [updater] : [];
99
+ configs.forEach(config => {
100
+ switch (config.type) {
101
+ case 'NODE_DELETE':
102
+ const nodeDeleteResult = nodeDelete(config, request);
103
+ if (nodeDeleteResult) {
104
+ configOptimisticUpdates.push(nodeDeleteResult);
105
+ configUpdates.push(nodeDeleteResult);
106
+ }
107
+ break;
108
+ case 'RANGE_ADD':
109
+ const rangeAddResult = rangeAdd(config, request);
110
+ if (rangeAddResult) {
111
+ configOptimisticUpdates.push(rangeAddResult);
112
+ configUpdates.push(rangeAddResult);
113
+ }
114
+ break;
115
+ case 'RANGE_DELETE':
116
+ const rangeDeleteResult = rangeDelete(config, request);
117
+ if (rangeDeleteResult) {
118
+ configOptimisticUpdates.push(rangeDeleteResult);
119
+ configUpdates.push(rangeDeleteResult);
120
+ }
121
+ break;
122
+ }
123
+ });
124
+ return {
125
+ optimisticUpdater: (
126
+ store: RecordSourceSelectorProxy,
127
+ data: ?SelectorData,
128
+ ) => {
129
+ configOptimisticUpdates.forEach(eachOptimisticUpdater => {
130
+ eachOptimisticUpdater(store, data);
131
+ });
132
+ },
133
+ updater: (store: RecordSourceSelectorProxy, data: ?SelectorData) => {
134
+ configUpdates.forEach(eachUpdater => {
135
+ eachUpdater(store, data);
136
+ });
137
+ },
138
+ };
139
+ }
140
+
141
+ function nodeDelete(
142
+ config: NodeDeleteConfig,
143
+ request: ConcreteRequest,
144
+ ): ?SelectorStoreUpdater {
145
+ const {deletedIDFieldName} = config;
146
+ const rootField = getRootField(request);
147
+ if (!rootField) {
148
+ return null;
149
+ }
150
+ return (store: RecordSourceSelectorProxy, data: ?SelectorData) => {
151
+ const payload = store.getRootField(rootField);
152
+ if (!payload) {
153
+ return;
154
+ }
155
+ const deleteID = payload.getValue(deletedIDFieldName);
156
+ const deleteIDs = Array.isArray(deleteID) ? deleteID : [deleteID];
157
+ deleteIDs.forEach(id => {
158
+ if (id && typeof id === 'string') {
159
+ store.delete(id);
160
+ }
161
+ });
162
+ };
163
+ }
164
+
165
+ function rangeAdd(
166
+ config: RangeAddConfig,
167
+ request: ConcreteRequest,
168
+ ): ?SelectorStoreUpdater {
169
+ const {parentID, connectionInfo, edgeName} = config;
170
+ if (!parentID) {
171
+ warning(
172
+ false,
173
+ 'RelayDeclarativeMutationConfig: For mutation config RANGE_ADD ' +
174
+ 'to work you must include a parentID',
175
+ );
176
+ return null;
177
+ }
178
+ const rootField = getRootField(request);
179
+ if (!connectionInfo || !rootField) {
180
+ return null;
181
+ }
182
+ return (store: RecordSourceSelectorProxy, data: ?SelectorData) => {
183
+ const parent = store.get(parentID);
184
+ if (!parent) {
185
+ return;
186
+ }
187
+ const payload = store.getRootField(rootField);
188
+ if (!payload) {
189
+ return;
190
+ }
191
+ const serverEdge = payload.getLinkedRecord(edgeName);
192
+ for (const info of connectionInfo) {
193
+ if (!serverEdge) {
194
+ continue;
195
+ }
196
+ const connection = ConnectionHandler.getConnection(
197
+ parent,
198
+ info.key,
199
+ info.filters,
200
+ );
201
+ if (!connection) {
202
+ continue;
203
+ }
204
+ const clientEdge = ConnectionHandler.buildConnectionEdge(
205
+ store,
206
+ connection,
207
+ serverEdge,
208
+ );
209
+ if (!clientEdge) {
210
+ continue;
211
+ }
212
+ switch (info.rangeBehavior) {
213
+ case 'append':
214
+ ConnectionHandler.insertEdgeAfter(connection, clientEdge);
215
+ break;
216
+ case 'prepend':
217
+ ConnectionHandler.insertEdgeBefore(connection, clientEdge);
218
+ break;
219
+ default:
220
+ warning(
221
+ false,
222
+ 'RelayDeclarativeMutationConfig: RANGE_ADD range behavior `%s` ' +
223
+ 'will not work as expected in RelayModern, supported range ' +
224
+ "behaviors are 'append', 'prepend'.",
225
+ info.rangeBehavior,
226
+ );
227
+ break;
228
+ }
229
+ }
230
+ };
231
+ }
232
+
233
+ function rangeDelete(
234
+ config: RangeDeleteConfig,
235
+ request: ConcreteRequest,
236
+ ): ?SelectorStoreUpdater {
237
+ const {
238
+ parentID,
239
+ connectionKeys,
240
+ pathToConnection,
241
+ deletedIDFieldName,
242
+ } = config;
243
+ if (!parentID) {
244
+ warning(
245
+ false,
246
+ 'RelayDeclarativeMutationConfig: For mutation config RANGE_DELETE ' +
247
+ 'to work you must include a parentID',
248
+ );
249
+ return null;
250
+ }
251
+ const rootField = getRootField(request);
252
+ if (!rootField) {
253
+ return null;
254
+ }
255
+ return (store: RecordSourceSelectorProxy, data: ?SelectorData) => {
256
+ if (!data) {
257
+ return;
258
+ }
259
+ const deleteIDs = [];
260
+ let deletedIDField = data[rootField];
261
+ if (deletedIDField && Array.isArray(deletedIDFieldName)) {
262
+ for (const eachField of deletedIDFieldName) {
263
+ if (deletedIDField && typeof deletedIDField === 'object') {
264
+ deletedIDField = deletedIDField[eachField];
265
+ }
266
+ }
267
+ if (Array.isArray(deletedIDField)) {
268
+ deletedIDField.forEach(idObject => {
269
+ if (
270
+ idObject &&
271
+ idObject.id &&
272
+ typeof idObject === 'object' &&
273
+ typeof idObject.id === 'string'
274
+ ) {
275
+ deleteIDs.push(idObject.id);
276
+ }
277
+ });
278
+ } else if (
279
+ deletedIDField &&
280
+ deletedIDField.id &&
281
+ typeof deletedIDField.id === 'string'
282
+ ) {
283
+ deleteIDs.push(deletedIDField.id);
284
+ }
285
+ } else if (
286
+ deletedIDField &&
287
+ typeof deletedIDFieldName === 'string' &&
288
+ typeof deletedIDField === 'object'
289
+ ) {
290
+ deletedIDField = deletedIDField[deletedIDFieldName];
291
+ if (typeof deletedIDField === 'string') {
292
+ deleteIDs.push(deletedIDField);
293
+ } else if (Array.isArray(deletedIDField)) {
294
+ deletedIDField.forEach(id => {
295
+ if (typeof id === 'string') {
296
+ deleteIDs.push(id);
297
+ }
298
+ });
299
+ }
300
+ }
301
+ deleteNode(parentID, connectionKeys, pathToConnection, store, deleteIDs);
302
+ };
303
+ }
304
+
305
+ function deleteNode(
306
+ parentID: string,
307
+ connectionKeys: ?Array<{|
308
+ key: string,
309
+ filters?: Variables,
310
+ |}>,
311
+ pathToConnection: Array<string>,
312
+ store: RecordSourceSelectorProxy,
313
+ deleteIDs: Array<string>,
314
+ ): void {
315
+ warning(
316
+ connectionKeys != null,
317
+ 'RelayDeclarativeMutationConfig: RANGE_DELETE must provide a ' +
318
+ 'connectionKeys',
319
+ );
320
+ const parent = store.get(parentID);
321
+ if (!parent) {
322
+ return;
323
+ }
324
+ if (pathToConnection.length < 2) {
325
+ warning(
326
+ false,
327
+ 'RelayDeclarativeMutationConfig: RANGE_DELETE ' +
328
+ 'pathToConnection must include at least parent and connection',
329
+ );
330
+ return;
331
+ }
332
+ let recordProxy = parent;
333
+ for (let i = 1; i < pathToConnection.length - 1; i++) {
334
+ if (recordProxy) {
335
+ recordProxy = recordProxy.getLinkedRecord(pathToConnection[i]);
336
+ }
337
+ }
338
+ // Should never enter loop except edge cases
339
+ if (!connectionKeys || !recordProxy) {
340
+ warning(
341
+ false,
342
+ 'RelayDeclarativeMutationConfig: RANGE_DELETE ' +
343
+ 'pathToConnection is incorrect. Unable to find connection with ' +
344
+ 'parentID: %s and path: %s',
345
+ parentID,
346
+ pathToConnection.toString(),
347
+ );
348
+ return;
349
+ }
350
+ for (const key of connectionKeys) {
351
+ const connection = ConnectionHandler.getConnection(
352
+ recordProxy,
353
+ key.key,
354
+ key.filters,
355
+ );
356
+ if (connection) {
357
+ deleteIDs.forEach(deleteID => {
358
+ ConnectionHandler.deleteNode(connection, deleteID);
359
+ });
360
+ }
361
+ }
362
+ }
363
+
364
+ function getRootField(request: ConcreteRequest): ?string {
365
+ if (
366
+ request.fragment.selections &&
367
+ request.fragment.selections.length > 0 &&
368
+ request.fragment.selections[0].kind === 'LinkedField'
369
+ ) {
370
+ return request.fragment.selections[0].name;
371
+ }
372
+ return null;
373
+ }
374
+
375
+ module.exports = {
376
+ MutationTypes,
377
+ RangeOperations,
378
+
379
+ convert,
380
+ };