relay-runtime 10.0.1 → 10.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 (70) hide show
  1. package/handlers/RelayDefaultHandlerProvider.js.flow +6 -0
  2. package/handlers/connection/MutationHandlers.js.flow +114 -3
  3. package/index.js +1 -1
  4. package/index.js.flow +16 -1
  5. package/lib/handlers/RelayDefaultHandlerProvider.js +9 -0
  6. package/lib/handlers/connection/MutationHandlers.js +138 -12
  7. package/lib/index.js +7 -0
  8. package/lib/mutations/RelayDeclarativeMutationConfig.js +2 -2
  9. package/lib/mutations/commitMutation.js +1 -4
  10. package/lib/mutations/validateMutation.js +27 -7
  11. package/lib/network/RelayQueryResponseCache.js +2 -2
  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 +82 -5
  16. package/lib/store/RelayModernEnvironment.js +18 -6
  17. package/lib/store/RelayModernFragmentSpecResolver.js +10 -1
  18. package/lib/store/RelayModernOperationDescriptor.js +6 -5
  19. package/lib/store/RelayModernQueryExecutor.js +44 -23
  20. package/lib/store/RelayModernStore.js +25 -14
  21. package/lib/store/RelayOperationTracker.js +2 -2
  22. package/lib/store/RelayPublishQueue.js +1 -1
  23. package/lib/store/RelayReader.js +196 -33
  24. package/lib/store/RelayRecordSourceMapImpl.js +2 -2
  25. package/lib/store/RelayReferenceMarker.js +89 -5
  26. package/lib/store/RelayResponseNormalizer.js +119 -19
  27. package/lib/store/RelayStoreReactFlightUtils.js +47 -0
  28. package/lib/store/defaultRequiredFieldLogger.js +18 -0
  29. package/lib/store/normalizeRelayPayload.js +1 -1
  30. package/lib/subscription/requestSubscription.js +2 -3
  31. package/lib/util/NormalizationNode.js +1 -5
  32. package/lib/util/RelayConcreteNode.js +2 -0
  33. package/lib/util/RelayFeatureFlags.js +5 -2
  34. package/lib/util/getFragmentIdentifier.js +12 -3
  35. package/lib/util/getOperation.js +33 -0
  36. package/lib/util/isEmptyObject.js +25 -0
  37. package/lib/util/recycleNodesInto.js +4 -1
  38. package/lib/util/reportMissingRequiredFields.js +48 -0
  39. package/mutations/commitMutation.js.flow +1 -2
  40. package/mutations/validateMutation.js.flow +34 -5
  41. package/network/RelayNetworkTypes.js.flow +22 -0
  42. package/package.json +2 -2
  43. package/query/GraphQLTag.js.flow +3 -1
  44. package/query/fetchQuery.js.flow +2 -2
  45. package/query/fetchQueryInternal.js.flow +0 -5
  46. package/relay-runtime.js +2 -2
  47. package/relay-runtime.min.js +2 -2
  48. package/store/DataChecker.js.flow +68 -2
  49. package/store/RelayModernEnvironment.js.flow +29 -9
  50. package/store/RelayModernFragmentSpecResolver.js.flow +13 -1
  51. package/store/RelayModernOperationDescriptor.js.flow +5 -1
  52. package/store/RelayModernQueryExecutor.js.flow +47 -23
  53. package/store/RelayModernStore.js.flow +31 -15
  54. package/store/RelayPublishQueue.js.flow +1 -1
  55. package/store/RelayReader.js.flow +180 -15
  56. package/store/RelayReferenceMarker.js.flow +72 -5
  57. package/store/RelayResponseNormalizer.js.flow +130 -19
  58. package/store/RelayStoreReactFlightUtils.js.flow +64 -0
  59. package/store/RelayStoreTypes.js.flow +90 -31
  60. package/store/defaultRequiredFieldLogger.js.flow +23 -0
  61. package/subscription/requestSubscription.js.flow +5 -2
  62. package/util/NormalizationNode.js.flow +17 -2
  63. package/util/ReaderNode.js.flow +20 -1
  64. package/util/RelayConcreteNode.js.flow +6 -0
  65. package/util/RelayFeatureFlags.js.flow +8 -1
  66. package/util/getFragmentIdentifier.js.flow +33 -9
  67. package/util/getOperation.js.flow +40 -0
  68. package/util/isEmptyObject.js.flow +25 -0
  69. package/util/recycleNodesInto.js.flow +11 -0
  70. package/util/reportMissingRequiredFields.js.flow +51 -0
@@ -26,10 +26,16 @@ function RelayDefaultHandlerProvider(handle: string): Handler {
26
26
  return ConnectionHandler;
27
27
  case 'deleteRecord':
28
28
  return MutationHandlers.DeleteRecordHandler;
29
+ case 'deleteEdge':
30
+ return MutationHandlers.DeleteEdgeHandler;
29
31
  case 'appendEdge':
30
32
  return MutationHandlers.AppendEdgeHandler;
31
33
  case 'prependEdge':
32
34
  return MutationHandlers.PrependEdgeHandler;
35
+ case 'appendNode':
36
+ return MutationHandlers.AppendNodeHandler;
37
+ case 'prependNode':
38
+ return MutationHandlers.PrependNodeHandler;
33
39
  }
34
40
  invariant(
35
41
  false,
@@ -27,15 +27,54 @@ import type {
27
27
  const DeleteRecordHandler = {
28
28
  update: (store: RecordSourceProxy, payload: HandleFieldPayload) => {
29
29
  const record = store.get(payload.dataID);
30
+
30
31
  if (record != null) {
31
- const id = record.getValue(payload.fieldKey);
32
- if (typeof id === 'string') {
33
- store.delete(id);
32
+ const idOrIds = record.getValue(payload.fieldKey);
33
+
34
+ if (typeof idOrIds === 'string') {
35
+ store.delete(idOrIds);
36
+ } else if (Array.isArray(idOrIds)) {
37
+ idOrIds.forEach(id => {
38
+ if (typeof id === 'string') {
39
+ store.delete(id);
40
+ }
41
+ });
34
42
  }
35
43
  }
36
44
  },
37
45
  };
38
46
 
47
+ const DeleteEdgeHandler = {
48
+ update: (store: RecordSourceProxy, payload: HandleFieldPayload) => {
49
+ const record = store.get(payload.dataID);
50
+ if (record == null) {
51
+ return;
52
+ }
53
+ const {connections} = payload.handleArgs;
54
+ invariant(
55
+ connections != null,
56
+ 'MutationHandlers: Expected connection IDs to be specified.',
57
+ );
58
+ const idOrIds = record.getValue(payload.fieldKey);
59
+ const idList = Array.isArray(idOrIds) ? idOrIds : [idOrIds];
60
+ idList.forEach(id => {
61
+ if (typeof id === 'string') {
62
+ for (const connectionID of connections) {
63
+ const connection = store.get(connectionID);
64
+ if (connection == null) {
65
+ warning(
66
+ false,
67
+ `[Relay][Mutation] The connection with id '${connectionID}' doesn't exist.`,
68
+ );
69
+ continue;
70
+ }
71
+ ConnectionHandler.deleteNode(connection, id);
72
+ }
73
+ }
74
+ });
75
+ },
76
+ };
77
+
39
78
  const AppendEdgeHandler: Handler = {
40
79
  update: edgeUpdater(ConnectionHandler.insertEdgeAfter),
41
80
  };
@@ -44,6 +83,14 @@ const PrependEdgeHandler: Handler = {
44
83
  update: edgeUpdater(ConnectionHandler.insertEdgeBefore),
45
84
  };
46
85
 
86
+ const AppendNodeHandler: Handler = {
87
+ update: nodeUpdater(ConnectionHandler.insertEdgeAfter),
88
+ };
89
+
90
+ const PrependNodeHandler: Handler = {
91
+ update: nodeUpdater(ConnectionHandler.insertEdgeBefore),
92
+ };
93
+
47
94
  function edgeUpdater(
48
95
  insertFn: (RecordProxy, RecordProxy, ?string) => void,
49
96
  ): (RecordSourceProxy, HandleFieldPayload) => void {
@@ -81,8 +128,72 @@ function edgeUpdater(
81
128
  };
82
129
  }
83
130
 
131
+ function nodeUpdater(
132
+ insertFn: (RecordProxy, RecordProxy, ?string) => void,
133
+ ): (RecordSourceProxy, HandleFieldPayload) => void {
134
+ return (store: RecordSourceProxy, payload: HandleFieldPayload) => {
135
+ const record = store.get(payload.dataID);
136
+ if (record == null) {
137
+ return;
138
+ }
139
+ const {connections, edgeTypeName} = payload.handleArgs;
140
+ invariant(
141
+ connections != null,
142
+ 'MutationHandlers: Expected connection IDs to be specified.',
143
+ );
144
+ invariant(
145
+ edgeTypeName != null,
146
+ 'MutationHandlers: Expected edge typename to be specified.',
147
+ );
148
+ let singleServerNode;
149
+ let serverNodes;
150
+ try {
151
+ singleServerNode = record.getLinkedRecord(payload.fieldKey, payload.args);
152
+ } catch {}
153
+ if (!singleServerNode) {
154
+ try {
155
+ serverNodes = record.getLinkedRecords(payload.fieldKey, payload.args);
156
+ } catch {}
157
+ }
158
+ invariant(
159
+ singleServerNode != null || serverNodes != null,
160
+ 'MutationHandlers: Expected target node to exist.',
161
+ );
162
+ const serverNodeList = serverNodes ?? [singleServerNode];
163
+ for (const serverNode of serverNodeList) {
164
+ if (serverNode == null) {
165
+ continue;
166
+ }
167
+ for (const connectionID of connections) {
168
+ const connection = store.get(connectionID);
169
+ if (connection == null) {
170
+ warning(
171
+ false,
172
+ `[Relay][Mutation] The connection with id '${connectionID}' doesn't exist.`,
173
+ );
174
+ continue;
175
+ }
176
+ const clientEdge = ConnectionHandler.createEdge(
177
+ store,
178
+ connection,
179
+ serverNode,
180
+ edgeTypeName,
181
+ );
182
+ invariant(
183
+ clientEdge != null,
184
+ 'MutationHandlers: Failed to build the edge.',
185
+ );
186
+ insertFn(connection, clientEdge);
187
+ }
188
+ }
189
+ };
190
+ }
191
+
84
192
  module.exports = {
85
193
  AppendEdgeHandler,
86
194
  DeleteRecordHandler,
87
195
  PrependEdgeHandler,
196
+ AppendNodeHandler,
197
+ PrependNodeHandler,
198
+ DeleteEdgeHandler,
88
199
  };
package/index.js CHANGED
@@ -1,5 +1,5 @@
1
1
  /**
2
- * Relay v10.0.1
2
+ * Relay v10.1.0
3
3
  *
4
4
  * Copyright (c) Facebook, Inc. and its affiliates.
5
5
  *
package/index.js.flow CHANGED
@@ -56,6 +56,7 @@ const isRelayModernEnvironment = require('./store/isRelayModernEnvironment');
56
56
  const isScalarAndEqual = require('./util/isScalarAndEqual');
57
57
  const readInlineData = require('./store/readInlineData');
58
58
  const recycleNodesInto = require('./util/recycleNodesInto');
59
+ const reportMissingRequiredFields = require('./util/reportMissingRequiredFields');
59
60
  const requestSubscription = require('./subscription/requestSubscription');
60
61
  const stableCopy = require('./util/stableCopy');
61
62
 
@@ -93,6 +94,9 @@ export type {
93
94
  LogRequestInfoFunction,
94
95
  PayloadData,
95
96
  PayloadError,
97
+ ReactFlightPayloadData,
98
+ ReactFlightPayloadQuery,
99
+ ReactFlightServerTree,
96
100
  SubscribeFunction,
97
101
  Uploadable,
98
102
  UploadableMap,
@@ -109,7 +113,6 @@ export type {TaskScheduler} from './store/RelayModernQueryExecutor';
109
113
  export type {RecordState} from './store/RelayRecordState';
110
114
  export type {
111
115
  FragmentMap,
112
- FragmentPointer,
113
116
  FragmentReference,
114
117
  FragmentSpecResolver,
115
118
  HandleFieldPayload,
@@ -118,6 +121,7 @@ export type {
118
121
  LogEvent,
119
122
  LogFunction,
120
123
  MissingFieldHandler,
124
+ MissingRequiredFields,
121
125
  ModuleImportPointer,
122
126
  NormalizationSelector,
123
127
  OperationAvailability,
@@ -130,6 +134,8 @@ export type {
130
134
  PluralReaderSelector,
131
135
  Props,
132
136
  PublishQueue,
137
+ ReactFlightPayloadDeserializer,
138
+ ReactFlightClientResponse,
133
139
  ReaderSelector,
134
140
  ReadOnlyRecordProxy,
135
141
  RecordProxy,
@@ -149,6 +155,7 @@ export type {
149
155
  NormalizationArgument,
150
156
  NormalizationDefer,
151
157
  NormalizationField,
158
+ NormalizationFlightField,
152
159
  NormalizationLinkedField,
153
160
  NormalizationLinkedHandle,
154
161
  NormalizationLocalArgumentDefinition,
@@ -164,6 +171,7 @@ export type {
164
171
  ReaderArgument,
165
172
  ReaderArgumentDefinition,
166
173
  ReaderField,
174
+ ReaderFlightField,
167
175
  ReaderFragment,
168
176
  ReaderInlineDataFragment,
169
177
  ReaderInlineDataFragmentSpread,
@@ -172,8 +180,10 @@ export type {
172
180
  ReaderPaginationMetadata,
173
181
  ReaderRefetchableFragment,
174
182
  ReaderRefetchMetadata,
183
+ ReaderRequiredField,
175
184
  ReaderScalarField,
176
185
  ReaderSelection,
186
+ RequiredFieldAction,
177
187
  } from './util/ReaderNode';
178
188
  export type {
179
189
  ConcreteRequest,
@@ -234,6 +244,7 @@ module.exports = {
234
244
  RelayModernOperationDescriptor.createRequestDescriptor,
235
245
  getDataIDsFromFragment: RelayModernSelector.getDataIDsFromFragment,
236
246
  getDataIDsFromObject: RelayModernSelector.getDataIDsFromObject,
247
+ getNode: GraphQLTag.getNode,
237
248
  getFragment: GraphQLTag.getFragment,
238
249
  getInlineDataFragment: GraphQLTag.getInlineDataFragment,
239
250
  getModuleComponentKey: RelayStoreUtils.getModuleComponentKey,
@@ -253,7 +264,11 @@ module.exports = {
253
264
  RelayModernSelector.getVariablesFromPluralFragment,
254
265
  getVariablesFromSingularFragment:
255
266
  RelayModernSelector.getVariablesFromSingularFragment,
267
+ reportMissingRequiredFields,
256
268
  graphql: GraphQLTag.graphql,
269
+ isFragment: GraphQLTag.isFragment,
270
+ isInlineDataFragment: GraphQLTag.isInlineDataFragment,
271
+ isRequest: GraphQLTag.isRequest,
257
272
  readInlineData,
258
273
 
259
274
  // Declarative mutation API
@@ -24,11 +24,20 @@ function RelayDefaultHandlerProvider(handle) {
24
24
  case 'deleteRecord':
25
25
  return MutationHandlers.DeleteRecordHandler;
26
26
 
27
+ case 'deleteEdge':
28
+ return MutationHandlers.DeleteEdgeHandler;
29
+
27
30
  case 'appendEdge':
28
31
  return MutationHandlers.AppendEdgeHandler;
29
32
 
30
33
  case 'prependEdge':
31
34
  return MutationHandlers.PrependEdgeHandler;
35
+
36
+ case 'appendNode':
37
+ return MutationHandlers.AppendNodeHandler;
38
+
39
+ case 'prependNode':
40
+ return MutationHandlers.PrependNodeHandler;
32
41
  }
33
42
 
34
43
  !false ? process.env.NODE_ENV !== "production" ? invariant(false, 'RelayDefaultHandlerProvider: No handler provided for `%s`.', handle) : invariant(false) : void 0;
@@ -10,9 +10,9 @@
10
10
  // flowlint ambiguous-object-type:error
11
11
  'use strict';
12
12
 
13
- function _createForOfIteratorHelper(o) { if (typeof Symbol === "undefined" || o[Symbol.iterator] == null) { if (Array.isArray(o) || (o = _unsupportedIterableToArray(o))) { var i = 0; var F = function F() {}; return { s: F, n: function n() { if (i >= o.length) return { done: true }; return { done: false, value: o[i++] }; }, e: function e(_e) { throw _e; }, f: F }; } throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); } var it, normalCompletion = true, didErr = false, err; return { s: function s() { it = o[Symbol.iterator](); }, n: function n() { var step = it.next(); normalCompletion = step.done; return step; }, e: function e(_e2) { didErr = true; err = _e2; }, f: function f() { try { if (!normalCompletion && it["return"] != null) it["return"](); } finally { if (didErr) throw err; } } }; }
13
+ function _createForOfIteratorHelper(o, allowArrayLike) { var it; if (typeof Symbol === "undefined" || o[Symbol.iterator] == null) { if (Array.isArray(o) || (it = _unsupportedIterableToArray(o)) || allowArrayLike && o && typeof o.length === "number") { if (it) o = it; var i = 0; var F = function F() {}; return { s: F, n: function n() { if (i >= o.length) return { done: true }; return { done: false, value: o[i++] }; }, e: function e(_e) { throw _e; }, f: F }; } throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); } var normalCompletion = true, didErr = false, err; return { s: function s() { it = o[Symbol.iterator](); }, n: function n() { var step = it.next(); normalCompletion = step.done; return step; }, e: function e(_e2) { didErr = true; err = _e2; }, f: function f() { try { if (!normalCompletion && it["return"] != null) it["return"](); } finally { if (didErr) throw err; } } }; }
14
14
 
15
- function _unsupportedIterableToArray(o, minLen) { if (!o) return; if (typeof o === "string") return _arrayLikeToArray(o, minLen); var n = Object.prototype.toString.call(o).slice(8, -1); if (n === "Object" && o.constructor) n = o.constructor.name; if (n === "Map" || n === "Set") return Array.from(n); if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen); }
15
+ function _unsupportedIterableToArray(o, minLen) { if (!o) return; if (typeof o === "string") return _arrayLikeToArray(o, minLen); var n = Object.prototype.toString.call(o).slice(8, -1); if (n === "Object" && o.constructor) n = o.constructor.name; if (n === "Map" || n === "Set") return Array.from(o); if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen); }
16
16
 
17
17
  function _arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len = arr.length; for (var i = 0, arr2 = new Array(len); i < len; i++) { arr2[i] = arr[i]; } return arr2; }
18
18
 
@@ -27,12 +27,56 @@ var DeleteRecordHandler = {
27
27
  var record = store.get(payload.dataID);
28
28
 
29
29
  if (record != null) {
30
- var id = record.getValue(payload.fieldKey);
30
+ var idOrIds = record.getValue(payload.fieldKey);
31
+
32
+ if (typeof idOrIds === 'string') {
33
+ store["delete"](idOrIds);
34
+ } else if (Array.isArray(idOrIds)) {
35
+ idOrIds.forEach(function (id) {
36
+ if (typeof id === 'string') {
37
+ store["delete"](id);
38
+ }
39
+ });
40
+ }
41
+ }
42
+ }
43
+ };
44
+ var DeleteEdgeHandler = {
45
+ update: function update(store, payload) {
46
+ var record = store.get(payload.dataID);
31
47
 
48
+ if (record == null) {
49
+ return;
50
+ }
51
+
52
+ var connections = payload.handleArgs.connections;
53
+ !(connections != null) ? process.env.NODE_ENV !== "production" ? invariant(false, 'MutationHandlers: Expected connection IDs to be specified.') : invariant(false) : void 0;
54
+ var idOrIds = record.getValue(payload.fieldKey);
55
+ var idList = Array.isArray(idOrIds) ? idOrIds : [idOrIds];
56
+ idList.forEach(function (id) {
32
57
  if (typeof id === 'string') {
33
- store["delete"](id);
58
+ var _iterator = _createForOfIteratorHelper(connections),
59
+ _step;
60
+
61
+ try {
62
+ for (_iterator.s(); !(_step = _iterator.n()).done;) {
63
+ var connectionID = _step.value;
64
+ var connection = store.get(connectionID);
65
+
66
+ if (connection == null) {
67
+ process.env.NODE_ENV !== "production" ? warning(false, "[Relay][Mutation] The connection with id '".concat(connectionID, "' doesn't exist.")) : void 0;
68
+ continue;
69
+ }
70
+
71
+ ConnectionHandler.deleteNode(connection, id);
72
+ }
73
+ } catch (err) {
74
+ _iterator.e(err);
75
+ } finally {
76
+ _iterator.f();
77
+ }
34
78
  }
35
- }
79
+ });
36
80
  }
37
81
  };
38
82
  var AppendEdgeHandler = {
@@ -41,6 +85,12 @@ var AppendEdgeHandler = {
41
85
  var PrependEdgeHandler = {
42
86
  update: edgeUpdater(ConnectionHandler.insertEdgeBefore)
43
87
  };
88
+ var AppendNodeHandler = {
89
+ update: nodeUpdater(ConnectionHandler.insertEdgeAfter)
90
+ };
91
+ var PrependNodeHandler = {
92
+ update: nodeUpdater(ConnectionHandler.insertEdgeBefore)
93
+ };
44
94
 
45
95
  function edgeUpdater(insertFn) {
46
96
  return function (store, payload) {
@@ -54,12 +104,12 @@ function edgeUpdater(insertFn) {
54
104
  !(connections != null) ? process.env.NODE_ENV !== "production" ? invariant(false, 'MutationHandlers: Expected connection IDs to be specified.') : invariant(false) : void 0;
55
105
  var serverEdge = record.getLinkedRecord(payload.fieldKey, payload.args);
56
106
 
57
- var _iterator = _createForOfIteratorHelper(connections),
58
- _step;
107
+ var _iterator2 = _createForOfIteratorHelper(connections),
108
+ _step2;
59
109
 
60
110
  try {
61
- for (_iterator.s(); !(_step = _iterator.n()).done;) {
62
- var connectionID = _step.value;
111
+ for (_iterator2.s(); !(_step2 = _iterator2.n()).done;) {
112
+ var connectionID = _step2.value;
63
113
  var connection = store.get(connectionID);
64
114
 
65
115
  if (connection == null) {
@@ -72,9 +122,82 @@ function edgeUpdater(insertFn) {
72
122
  insertFn(connection, clientEdge);
73
123
  }
74
124
  } catch (err) {
75
- _iterator.e(err);
125
+ _iterator2.e(err);
126
+ } finally {
127
+ _iterator2.f();
128
+ }
129
+ };
130
+ }
131
+
132
+ function nodeUpdater(insertFn) {
133
+ return function (store, payload) {
134
+ var _serverNodes;
135
+
136
+ var record = store.get(payload.dataID);
137
+
138
+ if (record == null) {
139
+ return;
140
+ }
141
+
142
+ var _payload$handleArgs = payload.handleArgs,
143
+ connections = _payload$handleArgs.connections,
144
+ edgeTypeName = _payload$handleArgs.edgeTypeName;
145
+ !(connections != null) ? process.env.NODE_ENV !== "production" ? invariant(false, 'MutationHandlers: Expected connection IDs to be specified.') : invariant(false) : void 0;
146
+ !(edgeTypeName != null) ? process.env.NODE_ENV !== "production" ? invariant(false, 'MutationHandlers: Expected edge typename to be specified.') : invariant(false) : void 0;
147
+ var singleServerNode;
148
+ var serverNodes;
149
+
150
+ try {
151
+ singleServerNode = record.getLinkedRecord(payload.fieldKey, payload.args);
152
+ } catch (_unused) {}
153
+
154
+ if (!singleServerNode) {
155
+ try {
156
+ serverNodes = record.getLinkedRecords(payload.fieldKey, payload.args);
157
+ } catch (_unused2) {}
158
+ }
159
+
160
+ !(singleServerNode != null || serverNodes != null) ? process.env.NODE_ENV !== "production" ? invariant(false, 'MutationHandlers: Expected target node to exist.') : invariant(false) : void 0;
161
+ var serverNodeList = (_serverNodes = serverNodes) !== null && _serverNodes !== void 0 ? _serverNodes : [singleServerNode];
162
+
163
+ var _iterator3 = _createForOfIteratorHelper(serverNodeList),
164
+ _step3;
165
+
166
+ try {
167
+ for (_iterator3.s(); !(_step3 = _iterator3.n()).done;) {
168
+ var serverNode = _step3.value;
169
+
170
+ if (serverNode == null) {
171
+ continue;
172
+ }
173
+
174
+ var _iterator4 = _createForOfIteratorHelper(connections),
175
+ _step4;
176
+
177
+ try {
178
+ for (_iterator4.s(); !(_step4 = _iterator4.n()).done;) {
179
+ var connectionID = _step4.value;
180
+ var connection = store.get(connectionID);
181
+
182
+ if (connection == null) {
183
+ process.env.NODE_ENV !== "production" ? warning(false, "[Relay][Mutation] The connection with id '".concat(connectionID, "' doesn't exist.")) : void 0;
184
+ continue;
185
+ }
186
+
187
+ var clientEdge = ConnectionHandler.createEdge(store, connection, serverNode, edgeTypeName);
188
+ !(clientEdge != null) ? process.env.NODE_ENV !== "production" ? invariant(false, 'MutationHandlers: Failed to build the edge.') : invariant(false) : void 0;
189
+ insertFn(connection, clientEdge);
190
+ }
191
+ } catch (err) {
192
+ _iterator4.e(err);
193
+ } finally {
194
+ _iterator4.f();
195
+ }
196
+ }
197
+ } catch (err) {
198
+ _iterator3.e(err);
76
199
  } finally {
77
- _iterator.f();
200
+ _iterator3.f();
78
201
  }
79
202
  };
80
203
  }
@@ -82,5 +205,8 @@ function edgeUpdater(insertFn) {
82
205
  module.exports = {
83
206
  AppendEdgeHandler: AppendEdgeHandler,
84
207
  DeleteRecordHandler: DeleteRecordHandler,
85
- PrependEdgeHandler: PrependEdgeHandler
208
+ PrependEdgeHandler: PrependEdgeHandler,
209
+ AppendNodeHandler: AppendNodeHandler,
210
+ PrependNodeHandler: PrependNodeHandler,
211
+ DeleteEdgeHandler: DeleteEdgeHandler
86
212
  };
package/lib/index.js CHANGED
@@ -96,6 +96,8 @@ var readInlineData = require('./store/readInlineData');
96
96
 
97
97
  var recycleNodesInto = require('./util/recycleNodesInto');
98
98
 
99
+ var reportMissingRequiredFields = require('./util/reportMissingRequiredFields');
100
+
99
101
  var requestSubscription = require('./subscription/requestSubscription');
100
102
 
101
103
  var stableCopy = require('./util/stableCopy');
@@ -140,6 +142,7 @@ module.exports = {
140
142
  createRequestDescriptor: RelayModernOperationDescriptor.createRequestDescriptor,
141
143
  getDataIDsFromFragment: RelayModernSelector.getDataIDsFromFragment,
142
144
  getDataIDsFromObject: RelayModernSelector.getDataIDsFromObject,
145
+ getNode: GraphQLTag.getNode,
143
146
  getFragment: GraphQLTag.getFragment,
144
147
  getInlineDataFragment: GraphQLTag.getInlineDataFragment,
145
148
  getModuleComponentKey: RelayStoreUtils.getModuleComponentKey,
@@ -157,7 +160,11 @@ module.exports = {
157
160
  getVariablesFromObject: RelayModernSelector.getVariablesFromObject,
158
161
  getVariablesFromPluralFragment: RelayModernSelector.getVariablesFromPluralFragment,
159
162
  getVariablesFromSingularFragment: RelayModernSelector.getVariablesFromSingularFragment,
163
+ reportMissingRequiredFields: reportMissingRequiredFields,
160
164
  graphql: GraphQLTag.graphql,
165
+ isFragment: GraphQLTag.isFragment,
166
+ isInlineDataFragment: GraphQLTag.isInlineDataFragment,
167
+ isRequest: GraphQLTag.isRequest,
161
168
  readInlineData: readInlineData,
162
169
  // Declarative mutation API
163
170
  MutationTypes: RelayDeclarativeMutationConfig.MutationTypes,
@@ -10,9 +10,9 @@
10
10
  // flowlint ambiguous-object-type:error
11
11
  'use strict';
12
12
 
13
- function _createForOfIteratorHelper(o) { if (typeof Symbol === "undefined" || o[Symbol.iterator] == null) { if (Array.isArray(o) || (o = _unsupportedIterableToArray(o))) { var i = 0; var F = function F() {}; return { s: F, n: function n() { if (i >= o.length) return { done: true }; return { done: false, value: o[i++] }; }, e: function e(_e) { throw _e; }, f: F }; } throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); } var it, normalCompletion = true, didErr = false, err; return { s: function s() { it = o[Symbol.iterator](); }, n: function n() { var step = it.next(); normalCompletion = step.done; return step; }, e: function e(_e2) { didErr = true; err = _e2; }, f: function f() { try { if (!normalCompletion && it["return"] != null) it["return"](); } finally { if (didErr) throw err; } } }; }
13
+ function _createForOfIteratorHelper(o, allowArrayLike) { var it; if (typeof Symbol === "undefined" || o[Symbol.iterator] == null) { if (Array.isArray(o) || (it = _unsupportedIterableToArray(o)) || allowArrayLike && o && typeof o.length === "number") { if (it) o = it; var i = 0; var F = function F() {}; return { s: F, n: function n() { if (i >= o.length) return { done: true }; return { done: false, value: o[i++] }; }, e: function e(_e) { throw _e; }, f: F }; } throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); } var normalCompletion = true, didErr = false, err; return { s: function s() { it = o[Symbol.iterator](); }, n: function n() { var step = it.next(); normalCompletion = step.done; return step; }, e: function e(_e2) { didErr = true; err = _e2; }, f: function f() { try { if (!normalCompletion && it["return"] != null) it["return"](); } finally { if (didErr) throw err; } } }; }
14
14
 
15
- function _unsupportedIterableToArray(o, minLen) { if (!o) return; if (typeof o === "string") return _arrayLikeToArray(o, minLen); var n = Object.prototype.toString.call(o).slice(8, -1); if (n === "Object" && o.constructor) n = o.constructor.name; if (n === "Map" || n === "Set") return Array.from(n); if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen); }
15
+ function _unsupportedIterableToArray(o, minLen) { if (!o) return; if (typeof o === "string") return _arrayLikeToArray(o, minLen); var n = Object.prototype.toString.call(o).slice(8, -1); if (n === "Object" && o.constructor) n = o.constructor.name; if (n === "Map" || n === "Set") return Array.from(o); if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen); }
16
16
 
17
17
  function _arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len = arr.length; for (var i = 0, arr2 = new Array(len); i < len; i++) { arr2[i] = arr[i]; } return arr2; }
18
18
 
@@ -16,8 +16,6 @@ var _toConsumableArray2 = _interopRequireDefault(require("@babel/runtime/helpers
16
16
 
17
17
  var RelayDeclarativeMutationConfig = require('./RelayDeclarativeMutationConfig');
18
18
 
19
- var RelayFeatureFlags = require('../util/RelayFeatureFlags');
20
-
21
19
  var invariant = require("fbjs/lib/invariant");
22
20
 
23
21
  var isRelayModernEnvironment = require('../store/isRelayModernEnvironment');
@@ -60,7 +58,7 @@ function commitMutation(environment, config) {
60
58
  onUnsubscribe = config.onUnsubscribe,
61
59
  variables = config.variables,
62
60
  uploadables = config.uploadables;
63
- var operation = createOperationDescriptor(mutation, variables, generateUniqueClientID()); // TODO: remove this check after we fix flow.
61
+ var operation = createOperationDescriptor(mutation, variables, cacheConfig, generateUniqueClientID()); // TODO: remove this check after we fix flow.
64
62
 
65
63
  if (typeof optimisticResponse === 'function') {
66
64
  optimisticResponse = optimisticResponse();
@@ -82,7 +80,6 @@ function commitMutation(environment, config) {
82
80
 
83
81
  var errors = [];
84
82
  var subscription = environment.executeMutation({
85
- cacheConfig: cacheConfig,
86
83
  operation: operation,
87
84
  optimisticResponse: optimisticResponse,
88
85
  optimisticUpdater: optimisticUpdater,
@@ -20,6 +20,8 @@ function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { va
20
20
 
21
21
  var warning = require("fbjs/lib/warning");
22
22
 
23
+ var hasOwnProperty = Object.prototype.hasOwnProperty;
24
+
23
25
  var validateMutation = function validateMutation() {};
24
26
 
25
27
  if (process.env.NODE_ENV !== "production") {
@@ -45,7 +47,8 @@ if (process.env.NODE_ENV !== "production") {
45
47
  visitedPaths: new Set(),
46
48
  variables: variables || {},
47
49
  missingDiff: {},
48
- extraDiff: {}
50
+ extraDiff: {},
51
+ moduleImportPaths: new Set()
49
52
  };
50
53
  validateSelections(optimisticResponse, mutation.operation.selections, context);
51
54
  validateOptimisticResponse(optimisticResponse, context);
@@ -67,6 +70,7 @@ if (process.env.NODE_ENV !== "production") {
67
70
 
68
71
  case 'ScalarField':
69
72
  case 'LinkedField':
73
+ case 'FlightField':
70
74
  return validateField(optimisticResponse, selection, context);
71
75
 
72
76
  case 'InlineFragment':
@@ -88,6 +92,8 @@ if (process.env.NODE_ENV !== "production") {
88
92
  return;
89
93
 
90
94
  case 'ModuleImport':
95
+ return validateModuleImport(context);
96
+
91
97
  case 'LinkedHandle':
92
98
  case 'ScalarHandle':
93
99
  case 'Defer':
@@ -104,6 +110,10 @@ if (process.env.NODE_ENV !== "production") {
104
110
  }
105
111
  };
106
112
 
113
+ var validateModuleImport = function validateModuleImport(context) {
114
+ context.moduleImportPaths.add(context.path);
115
+ };
116
+
107
117
  var validateField = function validateField(optimisticResponse, field, context) {
108
118
  var fieldName = field.alias || field.name;
109
119
  var path = "".concat(context.path, ".").concat(fieldName);
@@ -111,7 +121,7 @@ if (process.env.NODE_ENV !== "production") {
111
121
 
112
122
  switch (field.kind) {
113
123
  case 'ScalarField':
114
- if (optimisticResponse.hasOwnProperty(fieldName) === false) {
124
+ if (hasOwnProperty.call(optimisticResponse, fieldName) === false) {
115
125
  addFieldToDiff(path, context.missingDiff, true);
116
126
  }
117
127
 
@@ -120,7 +130,7 @@ if (process.env.NODE_ENV !== "production") {
120
130
  case 'LinkedField':
121
131
  var selections = field.selections;
122
132
 
123
- if (optimisticResponse[fieldName] === null || Object.hasOwnProperty(fieldName) && optimisticResponse[fieldName] === undefined) {
133
+ if (optimisticResponse[fieldName] === null || hasOwnProperty.call(optimisticResponse, fieldName) && optimisticResponse[fieldName] === undefined) {
124
134
  return;
125
135
  }
126
136
 
@@ -128,7 +138,7 @@ if (process.env.NODE_ENV !== "production") {
128
138
  if (Array.isArray(optimisticResponse[fieldName])) {
129
139
  optimisticResponse[fieldName].forEach(function (r) {
130
140
  if (r !== null) {
131
- validateSelections(r, selections, _objectSpread({}, context, {
141
+ validateSelections(r, selections, _objectSpread(_objectSpread({}, context), {}, {
132
142
  path: path
133
143
  }));
134
144
  }
@@ -140,7 +150,7 @@ if (process.env.NODE_ENV !== "production") {
140
150
  }
141
151
  } else {
142
152
  if (optimisticResponse[fieldName] instanceof Object) {
143
- validateSelections(optimisticResponse[fieldName], selections, _objectSpread({}, context, {
153
+ validateSelections(optimisticResponse[fieldName], selections, _objectSpread(_objectSpread({}, context), {}, {
144
154
  path: path
145
155
  }));
146
156
  return;
@@ -150,6 +160,12 @@ if (process.env.NODE_ENV !== "production") {
150
160
  }
151
161
  }
152
162
 
163
+ case 'FlightField':
164
+ if (optimisticResponse[fieldName] === null || hasOwnProperty.call(optimisticResponse, fieldName) && optimisticResponse[fieldName] === undefined) {
165
+ return;
166
+ }
167
+
168
+ throw new Error('validateMutation: Flight fields are not compatible with ' + 'optimistic updates, as React does not have the component code ' + 'necessary to process new data on the client. Instead, you ' + 'should update your code to require a full refetch of the Flight ' + 'field so your UI can be updated.');
153
169
  }
154
170
  };
155
171
 
@@ -165,7 +181,11 @@ if (process.env.NODE_ENV !== "production") {
165
181
 
166
182
  Object.keys(optimisticResponse).forEach(function (key) {
167
183
  var value = optimisticResponse[key];
168
- var path = "".concat(context.path, ".").concat(key);
184
+ var path = "".concat(context.path, ".").concat(key); // if it's a module import path we don't have an ast so we cannot validate it
185
+
186
+ if (context.moduleImportPaths.has(path)) {
187
+ return;
188
+ }
169
189
 
170
190
  if (!context.visitedPaths.has(path)) {
171
191
  addFieldToDiff(path, context.extraDiff);
@@ -173,7 +193,7 @@ if (process.env.NODE_ENV !== "production") {
173
193
  }
174
194
 
175
195
  if (value instanceof Object) {
176
- validateOptimisticResponse(value, _objectSpread({}, context, {
196
+ validateOptimisticResponse(value, _objectSpread(_objectSpread({}, context), {}, {
177
197
  path: path
178
198
  }));
179
199
  }
@@ -57,8 +57,8 @@ var RelayQueryResponseCache = /*#__PURE__*/function () {
57
57
 
58
58
  var response = this._responses.get(cacheKey);
59
59
 
60
- return response != null ? _objectSpread({}, response.payload, {
61
- extensions: _objectSpread({}, response.payload.extensions, {
60
+ return response != null ? _objectSpread(_objectSpread({}, response.payload), {}, {
61
+ extensions: _objectSpread(_objectSpread({}, response.payload.extensions), {}, {
62
62
  cacheTimestamp: response.fetchTime
63
63
  })
64
64
  }) : null;