relay-runtime 10.1.3 → 11.0.2
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/connection/ConnectionHandler.js.flow +60 -0
- package/handlers/connection/MutationHandlers.js.flow +28 -0
- package/index.js +1 -1
- package/index.js.flow +9 -3
- package/lib/handlers/RelayDefaultHandlerProvider.js +1 -1
- package/lib/handlers/connection/ConnectionHandler.js +68 -6
- package/lib/handlers/connection/MutationHandlers.js +67 -8
- package/lib/index.js +3 -0
- package/lib/multi-actor-environment/ActorIdentifier.js +23 -0
- package/lib/multi-actor-environment/ActorSpecificEnvironment.js +108 -0
- package/lib/multi-actor-environment/MultiActorEnvironment.js +156 -0
- package/lib/multi-actor-environment/MultiActorEnvironmentTypes.js +11 -0
- package/lib/multi-actor-environment/index.js +17 -0
- package/lib/mutations/RelayRecordProxy.js +1 -1
- package/lib/mutations/RelayRecordSourceMutator.js +1 -1
- package/lib/mutations/RelayRecordSourceProxy.js +1 -1
- package/lib/mutations/RelayRecordSourceSelectorProxy.js +1 -1
- package/lib/mutations/applyOptimisticMutation.js +1 -1
- package/lib/mutations/commitMutation.js +1 -1
- package/lib/mutations/validateMutation.js +36 -15
- package/lib/network/RelayNetwork.js +1 -1
- package/lib/network/RelayQueryResponseCache.js +3 -2
- package/lib/query/GraphQLTag.js +1 -1
- package/lib/query/fetchQuery.js +129 -13
- package/lib/query/fetchQueryInternal.js +3 -4
- package/lib/query/fetchQuery_DEPRECATED.js +39 -0
- package/lib/store/DataChecker.js +26 -14
- package/lib/store/{RelayModernQueryExecutor.js → OperationExecutor.js} +117 -47
- package/lib/store/RelayConcreteVariables.js +8 -4
- package/lib/store/RelayModernEnvironment.js +105 -136
- package/lib/store/RelayModernFragmentSpecResolver.js +16 -9
- package/lib/store/RelayModernRecord.js +1 -1
- package/lib/store/RelayModernSelector.js +1 -1
- package/lib/store/RelayModernStore.js +19 -20
- package/lib/store/RelayOperationTracker.js +55 -49
- package/lib/store/RelayPublishQueue.js +9 -5
- package/lib/store/RelayReader.js +68 -14
- package/lib/store/RelayReferenceMarker.js +28 -14
- package/lib/store/RelayResponseNormalizer.js +109 -15
- package/lib/store/RelayStoreReactFlightUtils.js +6 -4
- package/lib/store/RelayStoreSubscriptions.js +18 -8
- package/lib/store/RelayStoreSubscriptionsUsingMapByID.js +90 -30
- package/lib/store/RelayStoreUtils.js +3 -2
- package/lib/store/ResolverFragments.js +57 -0
- package/lib/store/cloneRelayHandleSourceField.js +1 -1
- package/lib/store/cloneRelayScalarHandleSourceField.js +1 -1
- package/lib/store/createFragmentSpecResolver.js +2 -2
- package/lib/store/createRelayContext.js +1 -1
- package/lib/store/defaultGetDataID.js +3 -1
- package/lib/store/hasOverlappingIDs.js +11 -3
- package/lib/store/readInlineData.js +1 -1
- package/lib/subscription/requestSubscription.js +33 -5
- package/lib/util/RelayConcreteNode.js +2 -0
- package/lib/util/RelayFeatureFlags.js +8 -3
- package/lib/util/RelayProfiler.js +17 -187
- package/lib/util/RelayReplaySubject.js +1 -1
- package/lib/util/deepFreeze.js +1 -0
- package/lib/util/getRelayHandleKey.js +1 -1
- package/lib/util/getRequestIdentifier.js +1 -1
- package/multi-actor-environment/ActorIdentifier.js.flow +27 -0
- package/multi-actor-environment/ActorSpecificEnvironment.js.flow +189 -0
- package/multi-actor-environment/MultiActorEnvironment.js.flow +233 -0
- package/multi-actor-environment/MultiActorEnvironmentTypes.js.flow +196 -0
- package/multi-actor-environment/index.js.flow +24 -0
- package/mutations/RelayRecordSourceProxy.js.flow +3 -2
- package/mutations/commitMutation.js.flow +1 -1
- package/mutations/validateMutation.js.flow +40 -15
- package/network/RelayNetworkTypes.js.flow +31 -11
- package/network/RelayQueryResponseCache.js.flow +2 -1
- package/package.json +3 -2
- package/query/fetchQuery.js.flow +147 -20
- package/query/fetchQueryInternal.js.flow +2 -3
- package/query/fetchQuery_DEPRECATED.js.flow +47 -0
- package/relay-runtime.js +2 -2
- package/relay-runtime.min.js +2 -2
- package/store/DataChecker.js.flow +23 -15
- package/store/{RelayModernQueryExecutor.js.flow → OperationExecutor.js.flow} +128 -40
- package/store/RelayConcreteVariables.js.flow +5 -0
- package/store/RelayModernEnvironment.js.flow +100 -130
- package/store/RelayModernFragmentSpecResolver.js.flow +30 -8
- package/store/RelayModernStore.js.flow +28 -24
- package/store/RelayOperationTracker.js.flow +69 -56
- package/store/RelayPublishQueue.js.flow +7 -4
- package/store/RelayReader.js.flow +63 -11
- package/store/RelayRecordSource.js.flow +3 -3
- package/store/RelayRecordSourceMapImpl.js.flow +6 -2
- package/store/RelayReferenceMarker.js.flow +28 -18
- package/store/RelayResponseNormalizer.js.flow +134 -23
- package/store/RelayStoreReactFlightUtils.js.flow +9 -4
- package/store/RelayStoreSubscriptions.js.flow +22 -7
- package/store/RelayStoreSubscriptionsUsingMapByID.js.flow +36 -12
- package/store/RelayStoreTypes.js.flow +51 -22
- package/store/RelayStoreUtils.js.flow +2 -1
- package/store/ResolverFragments.js.flow +125 -0
- package/store/createFragmentSpecResolver.js.flow +2 -0
- package/store/defaultGetDataID.js.flow +3 -1
- package/store/hasOverlappingIDs.js.flow +11 -9
- package/subscription/requestSubscription.js.flow +25 -2
- package/util/NormalizationNode.js.flow +13 -0
- package/util/ReaderNode.js.flow +14 -1
- package/util/RelayConcreteNode.js.flow +2 -0
- package/util/RelayFeatureFlags.js.flow +12 -2
- package/util/RelayProfiler.js.flow +22 -194
- package/util/RelayRuntimeTypes.js.flow +4 -5
- package/util/deepFreeze.js.flow +2 -1
- package/util/isEmptyObject.js.flow +1 -1
|
@@ -19,6 +19,7 @@ const invariant = require('invariant');
|
|
|
19
19
|
const warning = require('warning');
|
|
20
20
|
|
|
21
21
|
const {generateClientID} = require('../../store/ClientID');
|
|
22
|
+
const {getStableStorageKey} = require('../../store/RelayStoreUtils');
|
|
22
23
|
|
|
23
24
|
import type {
|
|
24
25
|
HandleFieldPayload,
|
|
@@ -145,10 +146,12 @@ function update(store: RecordSourceProxy, payload: HandleFieldPayload): void {
|
|
|
145
146
|
let nextEdges = [];
|
|
146
147
|
const args = payload.args;
|
|
147
148
|
if (prevEdges && serverEdges) {
|
|
149
|
+
// $FlowFixMe[prop-missing]
|
|
148
150
|
if (args.after != null) {
|
|
149
151
|
// Forward pagination from the end of the connection: append edges
|
|
150
152
|
if (
|
|
151
153
|
clientPageInfo &&
|
|
154
|
+
// $FlowFixMe[prop-missing]
|
|
152
155
|
args.after === clientPageInfo.getValue(END_CURSOR)
|
|
153
156
|
) {
|
|
154
157
|
const nodeIDs = new Set();
|
|
@@ -164,10 +167,12 @@ function update(store: RecordSourceProxy, payload: HandleFieldPayload): void {
|
|
|
164
167
|
);
|
|
165
168
|
return;
|
|
166
169
|
}
|
|
170
|
+
// $FlowFixMe[prop-missing]
|
|
167
171
|
} else if (args.before != null) {
|
|
168
172
|
// Backward pagination from the start of the connection: prepend edges
|
|
169
173
|
if (
|
|
170
174
|
clientPageInfo &&
|
|
175
|
+
// $FlowFixMe[prop-missing]
|
|
171
176
|
args.before === clientPageInfo.getValue(START_CURSOR)
|
|
172
177
|
) {
|
|
173
178
|
const nodeIDs = new Set();
|
|
@@ -199,10 +204,12 @@ function update(store: RecordSourceProxy, payload: HandleFieldPayload): void {
|
|
|
199
204
|
}
|
|
200
205
|
// Page info should be updated even if no new edge were returned.
|
|
201
206
|
if (clientPageInfo && serverPageInfo) {
|
|
207
|
+
// $FlowFixMe[prop-missing]
|
|
202
208
|
if (args.after == null && args.before == null) {
|
|
203
209
|
// The connection was refetched from the beginning/end: replace
|
|
204
210
|
// page_info
|
|
205
211
|
clientPageInfo.copyFieldsFrom(serverPageInfo);
|
|
212
|
+
// $FlowFixMe[prop-missing]
|
|
206
213
|
} else if (args.before != null || (args.after == null && args.last)) {
|
|
207
214
|
clientPageInfo.setValue(
|
|
208
215
|
!!serverPageInfo.getValue(HAS_PREV_PAGE),
|
|
@@ -212,6 +219,7 @@ function update(store: RecordSourceProxy, payload: HandleFieldPayload): void {
|
|
|
212
219
|
if (typeof startCursor === 'string') {
|
|
213
220
|
clientPageInfo.setValue(startCursor, START_CURSOR);
|
|
214
221
|
}
|
|
222
|
+
// $FlowFixMe[prop-missing]
|
|
215
223
|
} else if (args.after != null || (args.before == null && args.first)) {
|
|
216
224
|
clientPageInfo.setValue(
|
|
217
225
|
!!serverPageInfo.getValue(HAS_NEXT_PAGE),
|
|
@@ -273,6 +281,47 @@ function getConnection(
|
|
|
273
281
|
return record.getLinkedRecord(handleKey, filters);
|
|
274
282
|
}
|
|
275
283
|
|
|
284
|
+
/**
|
|
285
|
+
* @public
|
|
286
|
+
*
|
|
287
|
+
* Given a record ID, the key of a connection field, and optional filters used
|
|
288
|
+
* to identify the connection, returns the connection ID.
|
|
289
|
+
*
|
|
290
|
+
* Example:
|
|
291
|
+
*
|
|
292
|
+
* Given that data has already been fetched on some user `<user-id>` on the `friends`
|
|
293
|
+
* field:
|
|
294
|
+
*
|
|
295
|
+
* ```
|
|
296
|
+
* fragment FriendsFragment on User {
|
|
297
|
+
* friends(first: 10) @connection(key: "FriendsFragment_friends") {
|
|
298
|
+
* edges {
|
|
299
|
+
* node {
|
|
300
|
+
* id
|
|
301
|
+
* }
|
|
302
|
+
* }
|
|
303
|
+
* }
|
|
304
|
+
* }
|
|
305
|
+
* ```
|
|
306
|
+
*
|
|
307
|
+
* The ID of the `friends` connection record can be accessed with:
|
|
308
|
+
*
|
|
309
|
+
* ```
|
|
310
|
+
* store => {
|
|
311
|
+
* const connectionID = ConnectionHandler.getConnectionID('<user-id>', 'FriendsFragment_friends');
|
|
312
|
+
* }
|
|
313
|
+
* ```
|
|
314
|
+
*/
|
|
315
|
+
function getConnectionID(
|
|
316
|
+
recordID: DataID,
|
|
317
|
+
key: string,
|
|
318
|
+
filters?: ?Variables,
|
|
319
|
+
): DataID {
|
|
320
|
+
const handleKey = getRelayHandleKey(CONNECTION, key, null);
|
|
321
|
+
const storageKey = getStableStorageKey(handleKey, filters);
|
|
322
|
+
return generateClientID(recordID, storageKey);
|
|
323
|
+
}
|
|
324
|
+
|
|
276
325
|
/**
|
|
277
326
|
* @public
|
|
278
327
|
*
|
|
@@ -369,6 +418,11 @@ function createEdge(
|
|
|
369
418
|
edge = store.create(edgeID, edgeType);
|
|
370
419
|
}
|
|
371
420
|
edge.setLinkedRecord(node, NODE);
|
|
421
|
+
if (edge.getValue('cursor') == null) {
|
|
422
|
+
// Always use null instead of undefined value for cursor
|
|
423
|
+
// to avoid considering it as missing data
|
|
424
|
+
edge.setValue(null, 'cursor');
|
|
425
|
+
}
|
|
372
426
|
return edge;
|
|
373
427
|
}
|
|
374
428
|
|
|
@@ -504,6 +558,11 @@ function buildConnectionEdge(
|
|
|
504
558
|
const edgeID = generateClientID(connection.getDataID(), EDGES, edgeIndex);
|
|
505
559
|
const connectionEdge = store.create(edgeID, edge.getType());
|
|
506
560
|
connectionEdge.copyFieldsFrom(edge);
|
|
561
|
+
if (connectionEdge.getValue('cursor') == null) {
|
|
562
|
+
// Always use null instead of undefined value for cursor
|
|
563
|
+
// to avoid considering it as missing data
|
|
564
|
+
connectionEdge.setValue(null, 'cursor');
|
|
565
|
+
}
|
|
507
566
|
connection.setValue(edgeIndex + 1, NEXT_EDGE_INDEX);
|
|
508
567
|
return connectionEdge;
|
|
509
568
|
}
|
|
@@ -543,6 +602,7 @@ module.exports = {
|
|
|
543
602
|
createEdge,
|
|
544
603
|
deleteNode,
|
|
545
604
|
getConnection,
|
|
605
|
+
getConnectionID,
|
|
546
606
|
insertEdgeAfter,
|
|
547
607
|
insertEdgeBefore,
|
|
548
608
|
update,
|
|
@@ -13,6 +13,7 @@
|
|
|
13
13
|
'use strict';
|
|
14
14
|
|
|
15
15
|
const ConnectionHandler = require('./ConnectionHandler');
|
|
16
|
+
const ConnectionInterface = require('./ConnectionInterface');
|
|
16
17
|
|
|
17
18
|
const invariant = require('invariant');
|
|
18
19
|
const warning = require('warning');
|
|
@@ -50,6 +51,7 @@ const DeleteEdgeHandler = {
|
|
|
50
51
|
if (record == null) {
|
|
51
52
|
return;
|
|
52
53
|
}
|
|
54
|
+
// $FlowFixMe[prop-missing]
|
|
53
55
|
const {connections} = payload.handleArgs;
|
|
54
56
|
invariant(
|
|
55
57
|
connections != null,
|
|
@@ -99,6 +101,7 @@ function edgeUpdater(
|
|
|
99
101
|
if (record == null) {
|
|
100
102
|
return;
|
|
101
103
|
}
|
|
104
|
+
// $FlowFixMe[prop-missing]
|
|
102
105
|
const {connections} = payload.handleArgs;
|
|
103
106
|
invariant(
|
|
104
107
|
connections != null,
|
|
@@ -120,11 +123,17 @@ function edgeUpdater(
|
|
|
120
123
|
);
|
|
121
124
|
return;
|
|
122
125
|
}
|
|
126
|
+
const {NODE, EDGES} = ConnectionInterface.get();
|
|
123
127
|
const serverEdgeList = serverEdges ?? [singleServerEdge];
|
|
124
128
|
for (const serverEdge of serverEdgeList) {
|
|
125
129
|
if (serverEdge == null) {
|
|
126
130
|
continue;
|
|
127
131
|
}
|
|
132
|
+
const serverNode = serverEdge.getLinkedRecord('node');
|
|
133
|
+
if (!serverNode) {
|
|
134
|
+
continue;
|
|
135
|
+
}
|
|
136
|
+
const serverNodeId = serverNode.getDataID();
|
|
128
137
|
for (const connectionID of connections) {
|
|
129
138
|
const connection = store.get(connectionID);
|
|
130
139
|
if (connection == null) {
|
|
@@ -134,6 +143,14 @@ function edgeUpdater(
|
|
|
134
143
|
);
|
|
135
144
|
continue;
|
|
136
145
|
}
|
|
146
|
+
const nodeAlreadyExistsInConnection = connection
|
|
147
|
+
.getLinkedRecords(EDGES)
|
|
148
|
+
?.some(
|
|
149
|
+
edge => edge?.getLinkedRecord(NODE)?.getDataID() === serverNodeId,
|
|
150
|
+
);
|
|
151
|
+
if (nodeAlreadyExistsInConnection) {
|
|
152
|
+
continue;
|
|
153
|
+
}
|
|
137
154
|
const clientEdge = ConnectionHandler.buildConnectionEdge(
|
|
138
155
|
store,
|
|
139
156
|
connection,
|
|
@@ -157,6 +174,7 @@ function nodeUpdater(
|
|
|
157
174
|
if (record == null) {
|
|
158
175
|
return;
|
|
159
176
|
}
|
|
177
|
+
// $FlowFixMe[prop-missing]
|
|
160
178
|
const {connections, edgeTypeName} = payload.handleArgs;
|
|
161
179
|
invariant(
|
|
162
180
|
connections != null,
|
|
@@ -180,11 +198,13 @@ function nodeUpdater(
|
|
|
180
198
|
warning(false, 'MutationHandlers: Expected target node to exist.');
|
|
181
199
|
return;
|
|
182
200
|
}
|
|
201
|
+
const {NODE, EDGES} = ConnectionInterface.get();
|
|
183
202
|
const serverNodeList = serverNodes ?? [singleServerNode];
|
|
184
203
|
for (const serverNode of serverNodeList) {
|
|
185
204
|
if (serverNode == null) {
|
|
186
205
|
continue;
|
|
187
206
|
}
|
|
207
|
+
const serverNodeId = serverNode.getDataID();
|
|
188
208
|
for (const connectionID of connections) {
|
|
189
209
|
const connection = store.get(connectionID);
|
|
190
210
|
if (connection == null) {
|
|
@@ -194,6 +214,14 @@ function nodeUpdater(
|
|
|
194
214
|
);
|
|
195
215
|
continue;
|
|
196
216
|
}
|
|
217
|
+
const nodeAlreadyExistsInConnection = connection
|
|
218
|
+
.getLinkedRecords(EDGES)
|
|
219
|
+
?.some(
|
|
220
|
+
edge => edge?.getLinkedRecord(NODE)?.getDataID() === serverNodeId,
|
|
221
|
+
);
|
|
222
|
+
if (nodeAlreadyExistsInConnection) {
|
|
223
|
+
continue;
|
|
224
|
+
}
|
|
197
225
|
const clientEdge = ConnectionHandler.createEdge(
|
|
198
226
|
store,
|
|
199
227
|
connection,
|
package/index.js
CHANGED
package/index.js.flow
CHANGED
|
@@ -48,6 +48,7 @@ const createRelayContext = require('./store/createRelayContext');
|
|
|
48
48
|
const deepFreeze = require('./util/deepFreeze');
|
|
49
49
|
const fetchQuery = require('./query/fetchQuery');
|
|
50
50
|
const fetchQueryInternal = require('./query/fetchQueryInternal');
|
|
51
|
+
const fetchQuery_DEPRECATED = require('./query/fetchQuery_DEPRECATED');
|
|
51
52
|
const getFragmentIdentifier = require('./util/getFragmentIdentifier');
|
|
52
53
|
const getRelayHandleKey = require('./util/getRelayHandleKey');
|
|
53
54
|
const getRequestIdentifier = require('./util/getRequestIdentifier');
|
|
@@ -97,6 +98,7 @@ export type {
|
|
|
97
98
|
ReactFlightPayloadData,
|
|
98
99
|
ReactFlightPayloadQuery,
|
|
99
100
|
ReactFlightServerTree,
|
|
101
|
+
ReactFlightServerError,
|
|
100
102
|
SubscribeFunction,
|
|
101
103
|
Uploadable,
|
|
102
104
|
UploadableMap,
|
|
@@ -108,10 +110,11 @@ export type {
|
|
|
108
110
|
Subscription,
|
|
109
111
|
} from './network/RelayObservable';
|
|
110
112
|
export type {GraphQLTaggedNode} from './query/GraphQLTag';
|
|
113
|
+
export type {TaskScheduler} from './store/OperationExecutor';
|
|
111
114
|
export type {EnvironmentConfig} from './store/RelayModernEnvironment';
|
|
112
|
-
export type {TaskScheduler} from './store/RelayModernQueryExecutor';
|
|
113
115
|
export type {RecordState} from './store/RelayRecordState';
|
|
114
116
|
export type {
|
|
117
|
+
ExecuteMutationConfig,
|
|
115
118
|
FragmentMap,
|
|
116
119
|
FragmentReference,
|
|
117
120
|
FragmentSpecResolver,
|
|
@@ -134,8 +137,9 @@ export type {
|
|
|
134
137
|
PluralReaderSelector,
|
|
135
138
|
Props,
|
|
136
139
|
PublishQueue,
|
|
137
|
-
ReactFlightPayloadDeserializer,
|
|
138
140
|
ReactFlightClientResponse,
|
|
141
|
+
ReactFlightPayloadDeserializer,
|
|
142
|
+
ReactFlightServerErrorHandler,
|
|
139
143
|
ReaderSelector,
|
|
140
144
|
ReadOnlyRecordProxy,
|
|
141
145
|
RecordProxy,
|
|
@@ -143,6 +147,7 @@ export type {
|
|
|
143
147
|
RecordSourceSelectorProxy,
|
|
144
148
|
RelayContext,
|
|
145
149
|
RequestDescriptor,
|
|
150
|
+
RequiredFieldLogger,
|
|
146
151
|
SelectorData,
|
|
147
152
|
SelectorStoreUpdater,
|
|
148
153
|
SingularReaderSelector,
|
|
@@ -287,7 +292,8 @@ module.exports = {
|
|
|
287
292
|
applyOptimisticMutation,
|
|
288
293
|
commitLocalUpdate,
|
|
289
294
|
commitMutation,
|
|
290
|
-
fetchQuery,
|
|
295
|
+
fetchQuery: fetchQuery,
|
|
296
|
+
fetchQuery_DEPRECATED,
|
|
291
297
|
isRelayModernEnvironment,
|
|
292
298
|
requestSubscription,
|
|
293
299
|
|
|
@@ -14,7 +14,7 @@ var ConnectionHandler = require('./connection/ConnectionHandler');
|
|
|
14
14
|
|
|
15
15
|
var MutationHandlers = require('./connection/MutationHandlers');
|
|
16
16
|
|
|
17
|
-
var invariant = require(
|
|
17
|
+
var invariant = require('invariant');
|
|
18
18
|
|
|
19
19
|
function RelayDefaultHandlerProvider(handle) {
|
|
20
20
|
switch (handle) {
|
|
@@ -14,13 +14,16 @@ var ConnectionInterface = require('./ConnectionInterface');
|
|
|
14
14
|
|
|
15
15
|
var getRelayHandleKey = require('../../util/getRelayHandleKey');
|
|
16
16
|
|
|
17
|
-
var invariant = require(
|
|
17
|
+
var invariant = require('invariant');
|
|
18
18
|
|
|
19
19
|
var warning = require("fbjs/lib/warning");
|
|
20
20
|
|
|
21
21
|
var _require = require('../../store/ClientID'),
|
|
22
22
|
generateClientID = _require.generateClientID;
|
|
23
23
|
|
|
24
|
+
var _require2 = require('../../store/RelayStoreUtils'),
|
|
25
|
+
getStableStorageKey = _require2.getStableStorageKey;
|
|
26
|
+
|
|
24
27
|
var CONNECTION = 'connection'; // Per-instance incrementing index used to generate unique edge IDs
|
|
25
28
|
|
|
26
29
|
var NEXT_EDGE_INDEX = '__connection_next_edge_index';
|
|
@@ -130,19 +133,23 @@ function update(store, payload) {
|
|
|
130
133
|
var args = payload.args;
|
|
131
134
|
|
|
132
135
|
if (prevEdges && _serverEdges) {
|
|
136
|
+
// $FlowFixMe[prop-missing]
|
|
133
137
|
if (args.after != null) {
|
|
134
138
|
// Forward pagination from the end of the connection: append edges
|
|
135
|
-
if (clientPageInfo &&
|
|
139
|
+
if (clientPageInfo && // $FlowFixMe[prop-missing]
|
|
140
|
+
args.after === clientPageInfo.getValue(END_CURSOR)) {
|
|
136
141
|
var nodeIDs = new Set();
|
|
137
142
|
mergeEdges(prevEdges, nextEdges, nodeIDs);
|
|
138
143
|
mergeEdges(_serverEdges, nextEdges, nodeIDs);
|
|
139
144
|
} else {
|
|
140
145
|
process.env.NODE_ENV !== "production" ? warning(false, 'Relay: Unexpected after cursor `%s`, edges must ' + 'be fetched from the end of the list (`%s`).', args.after, clientPageInfo && clientPageInfo.getValue(END_CURSOR)) : void 0;
|
|
141
146
|
return;
|
|
142
|
-
}
|
|
147
|
+
} // $FlowFixMe[prop-missing]
|
|
148
|
+
|
|
143
149
|
} else if (args.before != null) {
|
|
144
150
|
// Backward pagination from the start of the connection: prepend edges
|
|
145
|
-
if (clientPageInfo &&
|
|
151
|
+
if (clientPageInfo && // $FlowFixMe[prop-missing]
|
|
152
|
+
args.before === clientPageInfo.getValue(START_CURSOR)) {
|
|
146
153
|
var _nodeIDs = new Set();
|
|
147
154
|
|
|
148
155
|
mergeEdges(_serverEdges, nextEdges, _nodeIDs);
|
|
@@ -169,17 +176,19 @@ function update(store, payload) {
|
|
|
169
176
|
|
|
170
177
|
|
|
171
178
|
if (clientPageInfo && serverPageInfo) {
|
|
179
|
+
// $FlowFixMe[prop-missing]
|
|
172
180
|
if (args.after == null && args.before == null) {
|
|
173
181
|
// The connection was refetched from the beginning/end: replace
|
|
174
182
|
// page_info
|
|
175
|
-
clientPageInfo.copyFieldsFrom(serverPageInfo);
|
|
183
|
+
clientPageInfo.copyFieldsFrom(serverPageInfo); // $FlowFixMe[prop-missing]
|
|
176
184
|
} else if (args.before != null || args.after == null && args.last) {
|
|
177
185
|
clientPageInfo.setValue(!!serverPageInfo.getValue(HAS_PREV_PAGE), HAS_PREV_PAGE);
|
|
178
186
|
var startCursor = serverPageInfo.getValue(START_CURSOR);
|
|
179
187
|
|
|
180
188
|
if (typeof startCursor === 'string') {
|
|
181
189
|
clientPageInfo.setValue(startCursor, START_CURSOR);
|
|
182
|
-
}
|
|
190
|
+
} // $FlowFixMe[prop-missing]
|
|
191
|
+
|
|
183
192
|
} else if (args.after != null || args.before == null && args.first) {
|
|
184
193
|
clientPageInfo.setValue(!!serverPageInfo.getValue(HAS_NEXT_PAGE), HAS_NEXT_PAGE);
|
|
185
194
|
var endCursor = serverPageInfo.getValue(END_CURSOR);
|
|
@@ -235,6 +244,44 @@ function getConnection(record, key, filters) {
|
|
|
235
244
|
var handleKey = getRelayHandleKey(CONNECTION, key, null);
|
|
236
245
|
return record.getLinkedRecord(handleKey, filters);
|
|
237
246
|
}
|
|
247
|
+
/**
|
|
248
|
+
* @public
|
|
249
|
+
*
|
|
250
|
+
* Given a record ID, the key of a connection field, and optional filters used
|
|
251
|
+
* to identify the connection, returns the connection ID.
|
|
252
|
+
*
|
|
253
|
+
* Example:
|
|
254
|
+
*
|
|
255
|
+
* Given that data has already been fetched on some user `<user-id>` on the `friends`
|
|
256
|
+
* field:
|
|
257
|
+
*
|
|
258
|
+
* ```
|
|
259
|
+
* fragment FriendsFragment on User {
|
|
260
|
+
* friends(first: 10) @connection(key: "FriendsFragment_friends") {
|
|
261
|
+
* edges {
|
|
262
|
+
* node {
|
|
263
|
+
* id
|
|
264
|
+
* }
|
|
265
|
+
* }
|
|
266
|
+
* }
|
|
267
|
+
* }
|
|
268
|
+
* ```
|
|
269
|
+
*
|
|
270
|
+
* The ID of the `friends` connection record can be accessed with:
|
|
271
|
+
*
|
|
272
|
+
* ```
|
|
273
|
+
* store => {
|
|
274
|
+
* const connectionID = ConnectionHandler.getConnectionID('<user-id>', 'FriendsFragment_friends');
|
|
275
|
+
* }
|
|
276
|
+
* ```
|
|
277
|
+
*/
|
|
278
|
+
|
|
279
|
+
|
|
280
|
+
function getConnectionID(recordID, key, filters) {
|
|
281
|
+
var handleKey = getRelayHandleKey(CONNECTION, key, null);
|
|
282
|
+
var storageKey = getStableStorageKey(handleKey, filters);
|
|
283
|
+
return generateClientID(recordID, storageKey);
|
|
284
|
+
}
|
|
238
285
|
/**
|
|
239
286
|
* @public
|
|
240
287
|
*
|
|
@@ -339,6 +386,13 @@ function createEdge(store, record, node, edgeType) {
|
|
|
339
386
|
}
|
|
340
387
|
|
|
341
388
|
edge.setLinkedRecord(node, NODE);
|
|
389
|
+
|
|
390
|
+
if (edge.getValue('cursor') == null) {
|
|
391
|
+
// Always use null instead of undefined value for cursor
|
|
392
|
+
// to avoid considering it as missing data
|
|
393
|
+
edge.setValue(null, 'cursor');
|
|
394
|
+
}
|
|
395
|
+
|
|
342
396
|
return edge;
|
|
343
397
|
}
|
|
344
398
|
/**
|
|
@@ -484,6 +538,13 @@ function buildConnectionEdge(store, connection, edge) {
|
|
|
484
538
|
var edgeID = generateClientID(connection.getDataID(), EDGES, edgeIndex);
|
|
485
539
|
var connectionEdge = store.create(edgeID, edge.getType());
|
|
486
540
|
connectionEdge.copyFieldsFrom(edge);
|
|
541
|
+
|
|
542
|
+
if (connectionEdge.getValue('cursor') == null) {
|
|
543
|
+
// Always use null instead of undefined value for cursor
|
|
544
|
+
// to avoid considering it as missing data
|
|
545
|
+
connectionEdge.setValue(null, 'cursor');
|
|
546
|
+
}
|
|
547
|
+
|
|
487
548
|
connection.setValue(edgeIndex + 1, NEXT_EDGE_INDEX);
|
|
488
549
|
return connectionEdge;
|
|
489
550
|
}
|
|
@@ -526,6 +587,7 @@ module.exports = {
|
|
|
526
587
|
createEdge: createEdge,
|
|
527
588
|
deleteNode: deleteNode,
|
|
528
589
|
getConnection: getConnection,
|
|
590
|
+
getConnectionID: getConnectionID,
|
|
529
591
|
insertEdgeAfter: insertEdgeAfter,
|
|
530
592
|
insertEdgeBefore: insertEdgeBefore,
|
|
531
593
|
update: update
|
|
@@ -16,7 +16,9 @@ var _createForOfIteratorHelper2 = _interopRequireDefault(require("@babel/runtime
|
|
|
16
16
|
|
|
17
17
|
var ConnectionHandler = require('./ConnectionHandler');
|
|
18
18
|
|
|
19
|
-
var
|
|
19
|
+
var ConnectionInterface = require('./ConnectionInterface');
|
|
20
|
+
|
|
21
|
+
var invariant = require('invariant');
|
|
20
22
|
|
|
21
23
|
var warning = require("fbjs/lib/warning");
|
|
22
24
|
|
|
@@ -45,7 +47,8 @@ var DeleteEdgeHandler = {
|
|
|
45
47
|
|
|
46
48
|
if (record == null) {
|
|
47
49
|
return;
|
|
48
|
-
}
|
|
50
|
+
} // $FlowFixMe[prop-missing]
|
|
51
|
+
|
|
49
52
|
|
|
50
53
|
var connections = payload.handleArgs.connections;
|
|
51
54
|
!(connections != null) ? process.env.NODE_ENV !== "production" ? invariant(false, 'MutationHandlers: Expected connection IDs to be specified.') : invariant(false) : void 0;
|
|
@@ -98,7 +101,8 @@ function edgeUpdater(insertFn) {
|
|
|
98
101
|
|
|
99
102
|
if (record == null) {
|
|
100
103
|
return;
|
|
101
|
-
}
|
|
104
|
+
} // $FlowFixMe[prop-missing]
|
|
105
|
+
|
|
102
106
|
|
|
103
107
|
var connections = payload.handleArgs.connections;
|
|
104
108
|
!(connections != null) ? process.env.NODE_ENV !== "production" ? invariant(false, 'MutationHandlers: Expected connection IDs to be specified.') : invariant(false) : void 0;
|
|
@@ -119,19 +123,31 @@ function edgeUpdater(insertFn) {
|
|
|
119
123
|
return;
|
|
120
124
|
}
|
|
121
125
|
|
|
126
|
+
var _ConnectionInterface$ = ConnectionInterface.get(),
|
|
127
|
+
NODE = _ConnectionInterface$.NODE,
|
|
128
|
+
EDGES = _ConnectionInterface$.EDGES;
|
|
129
|
+
|
|
122
130
|
var serverEdgeList = (_serverEdges = serverEdges) !== null && _serverEdges !== void 0 ? _serverEdges : [singleServerEdge];
|
|
123
131
|
|
|
124
132
|
var _iterator2 = (0, _createForOfIteratorHelper2["default"])(serverEdgeList),
|
|
125
133
|
_step2;
|
|
126
134
|
|
|
127
135
|
try {
|
|
128
|
-
|
|
136
|
+
var _loop = function _loop() {
|
|
129
137
|
var serverEdge = _step2.value;
|
|
130
138
|
|
|
131
139
|
if (serverEdge == null) {
|
|
132
|
-
continue;
|
|
140
|
+
return "continue";
|
|
133
141
|
}
|
|
134
142
|
|
|
143
|
+
var serverNode = serverEdge.getLinkedRecord('node');
|
|
144
|
+
|
|
145
|
+
if (!serverNode) {
|
|
146
|
+
return "continue";
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
var serverNodeId = serverNode.getDataID();
|
|
150
|
+
|
|
135
151
|
var _iterator3 = (0, _createForOfIteratorHelper2["default"])(connections),
|
|
136
152
|
_step3;
|
|
137
153
|
|
|
@@ -145,6 +161,16 @@ function edgeUpdater(insertFn) {
|
|
|
145
161
|
continue;
|
|
146
162
|
}
|
|
147
163
|
|
|
164
|
+
var nodeAlreadyExistsInConnection = (_connection$getLinked = connection.getLinkedRecords(EDGES)) === null || _connection$getLinked === void 0 ? void 0 : _connection$getLinked.some(function (edge) {
|
|
165
|
+
var _edge$getLinkedRecord;
|
|
166
|
+
|
|
167
|
+
return (edge === null || edge === void 0 ? void 0 : (_edge$getLinkedRecord = edge.getLinkedRecord(NODE)) === null || _edge$getLinkedRecord === void 0 ? void 0 : _edge$getLinkedRecord.getDataID()) === serverNodeId;
|
|
168
|
+
});
|
|
169
|
+
|
|
170
|
+
if (nodeAlreadyExistsInConnection) {
|
|
171
|
+
continue;
|
|
172
|
+
}
|
|
173
|
+
|
|
148
174
|
var clientEdge = ConnectionHandler.buildConnectionEdge(store, connection, serverEdge);
|
|
149
175
|
!(clientEdge != null) ? process.env.NODE_ENV !== "production" ? invariant(false, 'MutationHandlers: Failed to build the edge.') : invariant(false) : void 0;
|
|
150
176
|
insertFn(connection, clientEdge);
|
|
@@ -154,6 +180,14 @@ function edgeUpdater(insertFn) {
|
|
|
154
180
|
} finally {
|
|
155
181
|
_iterator3.f();
|
|
156
182
|
}
|
|
183
|
+
};
|
|
184
|
+
|
|
185
|
+
for (_iterator2.s(); !(_step2 = _iterator2.n()).done;) {
|
|
186
|
+
var _connection$getLinked;
|
|
187
|
+
|
|
188
|
+
var _ret = _loop();
|
|
189
|
+
|
|
190
|
+
if (_ret === "continue") continue;
|
|
157
191
|
}
|
|
158
192
|
} catch (err) {
|
|
159
193
|
_iterator2.e(err);
|
|
@@ -171,7 +205,8 @@ function nodeUpdater(insertFn) {
|
|
|
171
205
|
|
|
172
206
|
if (record == null) {
|
|
173
207
|
return;
|
|
174
|
-
}
|
|
208
|
+
} // $FlowFixMe[prop-missing]
|
|
209
|
+
|
|
175
210
|
|
|
176
211
|
var _payload$handleArgs = payload.handleArgs,
|
|
177
212
|
connections = _payload$handleArgs.connections,
|
|
@@ -196,19 +231,25 @@ function nodeUpdater(insertFn) {
|
|
|
196
231
|
return;
|
|
197
232
|
}
|
|
198
233
|
|
|
234
|
+
var _ConnectionInterface$2 = ConnectionInterface.get(),
|
|
235
|
+
NODE = _ConnectionInterface$2.NODE,
|
|
236
|
+
EDGES = _ConnectionInterface$2.EDGES;
|
|
237
|
+
|
|
199
238
|
var serverNodeList = (_serverNodes = serverNodes) !== null && _serverNodes !== void 0 ? _serverNodes : [singleServerNode];
|
|
200
239
|
|
|
201
240
|
var _iterator4 = (0, _createForOfIteratorHelper2["default"])(serverNodeList),
|
|
202
241
|
_step4;
|
|
203
242
|
|
|
204
243
|
try {
|
|
205
|
-
|
|
244
|
+
var _loop2 = function _loop2() {
|
|
206
245
|
var serverNode = _step4.value;
|
|
207
246
|
|
|
208
247
|
if (serverNode == null) {
|
|
209
|
-
continue;
|
|
248
|
+
return "continue";
|
|
210
249
|
}
|
|
211
250
|
|
|
251
|
+
var serverNodeId = serverNode.getDataID();
|
|
252
|
+
|
|
212
253
|
var _iterator5 = (0, _createForOfIteratorHelper2["default"])(connections),
|
|
213
254
|
_step5;
|
|
214
255
|
|
|
@@ -222,6 +263,16 @@ function nodeUpdater(insertFn) {
|
|
|
222
263
|
continue;
|
|
223
264
|
}
|
|
224
265
|
|
|
266
|
+
var nodeAlreadyExistsInConnection = (_connection$getLinked2 = connection.getLinkedRecords(EDGES)) === null || _connection$getLinked2 === void 0 ? void 0 : _connection$getLinked2.some(function (edge) {
|
|
267
|
+
var _edge$getLinkedRecord2;
|
|
268
|
+
|
|
269
|
+
return (edge === null || edge === void 0 ? void 0 : (_edge$getLinkedRecord2 = edge.getLinkedRecord(NODE)) === null || _edge$getLinkedRecord2 === void 0 ? void 0 : _edge$getLinkedRecord2.getDataID()) === serverNodeId;
|
|
270
|
+
});
|
|
271
|
+
|
|
272
|
+
if (nodeAlreadyExistsInConnection) {
|
|
273
|
+
continue;
|
|
274
|
+
}
|
|
275
|
+
|
|
225
276
|
var clientEdge = ConnectionHandler.createEdge(store, connection, serverNode, edgeTypeName);
|
|
226
277
|
!(clientEdge != null) ? process.env.NODE_ENV !== "production" ? invariant(false, 'MutationHandlers: Failed to build the edge.') : invariant(false) : void 0;
|
|
227
278
|
insertFn(connection, clientEdge);
|
|
@@ -231,6 +282,14 @@ function nodeUpdater(insertFn) {
|
|
|
231
282
|
} finally {
|
|
232
283
|
_iterator5.f();
|
|
233
284
|
}
|
|
285
|
+
};
|
|
286
|
+
|
|
287
|
+
for (_iterator4.s(); !(_step4 = _iterator4.n()).done;) {
|
|
288
|
+
var _connection$getLinked2;
|
|
289
|
+
|
|
290
|
+
var _ret2 = _loop2();
|
|
291
|
+
|
|
292
|
+
if (_ret2 === "continue") continue;
|
|
234
293
|
}
|
|
235
294
|
} catch (err) {
|
|
236
295
|
_iterator4.e(err);
|
package/lib/index.js
CHANGED
|
@@ -80,6 +80,8 @@ var fetchQuery = require('./query/fetchQuery');
|
|
|
80
80
|
|
|
81
81
|
var fetchQueryInternal = require('./query/fetchQueryInternal');
|
|
82
82
|
|
|
83
|
+
var fetchQuery_DEPRECATED = require('./query/fetchQuery_DEPRECATED');
|
|
84
|
+
|
|
83
85
|
var getFragmentIdentifier = require('./util/getFragmentIdentifier');
|
|
84
86
|
|
|
85
87
|
var getRelayHandleKey = require('./util/getRelayHandleKey');
|
|
@@ -180,6 +182,7 @@ module.exports = {
|
|
|
180
182
|
commitLocalUpdate: commitLocalUpdate,
|
|
181
183
|
commitMutation: commitMutation,
|
|
182
184
|
fetchQuery: fetchQuery,
|
|
185
|
+
fetchQuery_DEPRECATED: fetchQuery_DEPRECATED,
|
|
183
186
|
isRelayModernEnvironment: isRelayModernEnvironment,
|
|
184
187
|
requestSubscription: requestSubscription,
|
|
185
188
|
// Configuration interface for legacy or special uses
|
|
@@ -0,0 +1,23 @@
|
|
|
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
|
+
'use strict';
|
|
12
|
+
/**
|
|
13
|
+
* A unique identifier of the current actor.
|
|
14
|
+
*/
|
|
15
|
+
|
|
16
|
+
module.exports = {
|
|
17
|
+
getActorIdentifier: function getActorIdentifier(actorID) {
|
|
18
|
+
return actorID;
|
|
19
|
+
},
|
|
20
|
+
getDefaultActorIdentifier: function getDefaultActorIdentifier() {
|
|
21
|
+
throw new Error('Not Implemented');
|
|
22
|
+
}
|
|
23
|
+
};
|