react-relay 2.0.0-rc.2 → 5.0.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.
- package/index.js +2 -2
- package/lib/ReactRelayContext.js +6 -3
- package/lib/ReactRelayFragmentContainer.js +48 -46
- package/lib/ReactRelayFragmentMockRenderer.js +5 -1
- package/lib/ReactRelayPaginationContainer.js +102 -68
- package/lib/ReactRelayQueryFetcher.js +54 -28
- package/lib/ReactRelayQueryRenderer.js +28 -20
- package/lib/ReactRelayRefetchContainer.js +70 -58
- package/lib/ReactRelayTestMocker.js +56 -43
- package/lib/ReactRelayTypes.js +1 -1
- package/lib/RelayContext.js +8 -2
- package/lib/assertFragmentMap.js +9 -7
- package/lib/buildReactRelayContainer.js +32 -23
- package/lib/index.js +41 -0
- package/lib/isRelayEnvironment.js +1 -1
- package/lib/isRelayVariables.js +1 -1
- package/lib/readContext.js +7 -4
- package/package.json +4 -4
- package/react-relay.js +2 -2
- package/react-relay.min.js +2 -2
- package/classic.js +0 -10
- package/compat.js +0 -10
- package/lib/ConcreteQuery.js +0 -10
- package/lib/GraphQLQueryRunner.js +0 -264
- package/lib/GraphQLRange.js +0 -1124
- package/lib/GraphQLSegment.js +0 -743
- package/lib/GraphQLStoreChangeEmitter.js +0 -141
- package/lib/GraphQLStoreQueryResolver.js +0 -288
- package/lib/GraphQLStoreRangeUtils.js +0 -126
- package/lib/QueryBuilder.js +0 -228
- package/lib/ReactRelayClassicExports.js +0 -29
- package/lib/ReactRelayCompatContainerBuilder.js +0 -175
- package/lib/ReactRelayCompatPublic.js +0 -28
- package/lib/ReactRelayContainerProfiler.js +0 -30
- package/lib/ReactRelayFragmentContainer-flowtest.js +0 -201
- package/lib/ReactRelayPaginationContainer-flowtest.js +0 -213
- package/lib/ReactRelayPublic.js +0 -29
- package/lib/ReactRelayRefetchContainer-flowtest.js +0 -191
- package/lib/RelayCacheProcessor.js +0 -196
- package/lib/RelayChangeTracker.js +0 -83
- package/lib/RelayClassicContainerUtils.js +0 -49
- package/lib/RelayClassicCore.js +0 -34
- package/lib/RelayClassicRecordState.js +0 -31
- package/lib/RelayCompatContainer.js +0 -25
- package/lib/RelayCompatEnvironment.js +0 -27
- package/lib/RelayCompatMutations.js +0 -133
- package/lib/RelayCompatPaginationContainer.js +0 -27
- package/lib/RelayCompatRefetchContainer.js +0 -27
- package/lib/RelayCompatTypes.js +0 -10
- package/lib/RelayContainer.js +0 -889
- package/lib/RelayContainerComparators.js +0 -75
- package/lib/RelayContainerProxy.js +0 -21
- package/lib/RelayDefaultNetworkLayer.js +0 -192
- package/lib/RelayEnvironment.js +0 -449
- package/lib/RelayEnvironmentTypes.js +0 -10
- package/lib/RelayFetchMode.js +0 -17
- package/lib/RelayFragmentPointer.js +0 -161
- package/lib/RelayFragmentReference.js +0 -249
- package/lib/RelayFragmentSpecResolver.js +0 -305
- package/lib/RelayGraphQLMutation.js +0 -288
- package/lib/RelayGraphQLTag.js +0 -42
- package/lib/RelayInternalTypes.js +0 -15
- package/lib/RelayInternals.js +0 -24
- package/lib/RelayMetaRoute.js +0 -35
- package/lib/RelayMockRenderer.js +0 -71
- package/lib/RelayModern-flowtest.js +0 -342
- package/lib/RelayModernFlowtest_badref.graphql.js +0 -10
- package/lib/RelayModernFlowtest_notref.graphql.js +0 -10
- package/lib/RelayModernFlowtest_user.graphql.js +0 -10
- package/lib/RelayModernFlowtest_users.graphql.js +0 -10
- package/lib/RelayMutation.js +0 -322
- package/lib/RelayMutationDebugPrinter.js +0 -47
- package/lib/RelayMutationQuery.js +0 -558
- package/lib/RelayMutationQueue.js +0 -530
- package/lib/RelayMutationRequest.js +0 -103
- package/lib/RelayMutationTracker.js +0 -113
- package/lib/RelayMutationTransaction.js +0 -92
- package/lib/RelayMutationTransactionStatus.js +0 -55
- package/lib/RelayNetworkDebug.js +0 -131
- package/lib/RelayNetworkLayer.js +0 -185
- package/lib/RelayNodeInterface.js +0 -104
- package/lib/RelayOperationDescriptor.js +0 -40
- package/lib/RelayOptimisticMutationUtils.js +0 -208
- package/lib/RelayPendingQueryTracker.js +0 -166
- package/lib/RelayPropTypes.js +0 -57
- package/lib/RelayPublic.js +0 -44
- package/lib/RelayQL.js +0 -128
- package/lib/RelayQuery.js +0 -1584
- package/lib/RelayQueryCaching.js +0 -33
- package/lib/RelayQueryConfig.js +0 -58
- package/lib/RelayQueryPath.js +0 -204
- package/lib/RelayQueryRequest.js +0 -103
- package/lib/RelayQueryTracker.js +0 -86
- package/lib/RelayQueryTransform.js +0 -91
- package/lib/RelayQueryVisitor.js +0 -93
- package/lib/RelayQueryWriter.js +0 -573
- package/lib/RelayReadyState.js +0 -83
- package/lib/RelayReadyStateRenderer.js +0 -145
- package/lib/RelayRecord.js +0 -75
- package/lib/RelayRecordStatusMap.js +0 -57
- package/lib/RelayRecordStore.js +0 -433
- package/lib/RelayRecordWriter.js +0 -601
- package/lib/RelayRefQueryDescriptor.js +0 -27
- package/lib/RelayRenderer.js +0 -268
- package/lib/RelayRootContainer.js +0 -125
- package/lib/RelayRoute.js +0 -92
- package/lib/RelayRouteFragment.js +0 -44
- package/lib/RelaySelector.js +0 -201
- package/lib/RelayShallowMock.js +0 -69
- package/lib/RelayStaticContainer.js +0 -38
- package/lib/RelayStore.js +0 -12
- package/lib/RelayStoreConstants.js +0 -20
- package/lib/RelayStoreData.js +0 -660
- package/lib/RelayTaskQueue.js +0 -189
- package/lib/RelayTypes.js +0 -13
- package/lib/RelayVariable.js +0 -32
- package/lib/RelayVariables.js +0 -92
- package/lib/buildRQL.js +0 -160
- package/lib/callsFromGraphQL.js +0 -74
- package/lib/callsToGraphQL.js +0 -34
- package/lib/checkRelayQueryData.js +0 -250
- package/lib/createRelayQuery.js +0 -17
- package/lib/dedent.js +0 -49
- package/lib/diffRelayQuery.js +0 -757
- package/lib/directivesToGraphQL.js +0 -39
- package/lib/filterRelayQuery.js +0 -29
- package/lib/findRelayQueryLeaves.js +0 -293
- package/lib/flattenRelayQuery.js +0 -121
- package/lib/flattenSplitRelayQueries.js +0 -44
- package/lib/forEachRootCallArg.js +0 -40
- package/lib/fromGraphQL.js +0 -48
- package/lib/generateClientEdgeID.js +0 -22
- package/lib/generateClientID.js +0 -27
- package/lib/generateConcreteFragmentID.js +0 -30
- package/lib/generateForceIndex.js +0 -24
- package/lib/generateRQLFieldAlias.js +0 -39
- package/lib/getRangeBehavior.js +0 -58
- package/lib/getRelayQueries.js +0 -83
- package/lib/intersectRelayQuery.js +0 -149
- package/lib/isClassicRelayContext.js +0 -20
- package/lib/isClassicRelayEnvironment.js +0 -20
- package/lib/isCompatibleRelayFragmentType.js +0 -27
- package/lib/isRelayContainer.js +0 -16
- package/lib/makeLegacyStringishComponentRef.js +0 -52
- package/lib/printRelayOSSQuery.js +0 -329
- package/lib/printRelayQuery.js +0 -26
- package/lib/rangeOperationToMetadataKey.js +0 -25
- package/lib/readRelayQueryData.js +0 -551
- package/lib/relayUnstableBatchedUpdates.js +0 -12
- package/lib/relayUnstableBatchedUpdates.native.js +0 -11
- package/lib/restoreRelayCacheData.js +0 -188
- package/lib/serializeRelayQueryCall.js +0 -42
- package/lib/splitDeferredRelayQueries.js +0 -298
- package/lib/stableStringify.js +0 -85
- package/lib/testEditDistance.js +0 -112
- package/lib/throwFailedPromise.js +0 -26
- package/lib/toGraphQL.js +0 -94
- package/lib/transformRelayQueryPayload.js +0 -145
- package/lib/validateMutationConfig.js +0 -117
- package/lib/validateRelayReadQuery.js +0 -112
- package/lib/writeRelayQueryPayload.js +0 -44
- package/lib/writeRelayUpdatePayload.js +0 -513
- package/react-relay-classic.js +0 -4
- package/react-relay-classic.min.js +0 -9
- package/react-relay-compat.js +0 -4
- package/react-relay-compat.min.js +0 -9
package/lib/GraphQLRange.js
DELETED
|
@@ -1,1124 +0,0 @@
|
|
|
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
|
-
* @format
|
|
8
|
-
*/
|
|
9
|
-
'use strict';
|
|
10
|
-
|
|
11
|
-
var _objectSpread2 = require("@babel/runtime/helpers/interopRequireDefault")(require("@babel/runtime/helpers/objectSpread"));
|
|
12
|
-
|
|
13
|
-
var _defineProperty2 = require("@babel/runtime/helpers/interopRequireDefault")(require("@babel/runtime/helpers/defineProperty"));
|
|
14
|
-
|
|
15
|
-
var _toConsumableArray2 = require("@babel/runtime/helpers/interopRequireDefault")(require("@babel/runtime/helpers/toConsumableArray"));
|
|
16
|
-
|
|
17
|
-
/**
|
|
18
|
-
* @param {array<object>} queryCalls
|
|
19
|
-
* @return {object}
|
|
20
|
-
*/
|
|
21
|
-
function callsArrayToObject(queryCalls) {
|
|
22
|
-
var calls = {};
|
|
23
|
-
|
|
24
|
-
for (var ii = 0; ii < queryCalls.length; ii++) {
|
|
25
|
-
if (require("relay-runtime").ConnectionInterface.isConnectionCall(queryCalls[ii])) {
|
|
26
|
-
var queryCall = queryCalls[ii];
|
|
27
|
-
var value = queryCall.value; // assuming that range calls will only have a single argument
|
|
28
|
-
|
|
29
|
-
if (Array.isArray(value) && value.length) {
|
|
30
|
-
value = value[0];
|
|
31
|
-
} // Ignore the whole call when the value is null
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
if (value === null) {
|
|
35
|
-
continue;
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
calls[queryCall.name] = value;
|
|
39
|
-
}
|
|
40
|
-
} // update first and last call values to be numbers
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
if (calls.first) {
|
|
44
|
-
!!isNaN(calls.first) ? process.env.NODE_ENV !== "production" ? require("fbjs/lib/invariant")(false, 'GraphQLRange: Expected `first` argument to be a number, got `%s`.', calls.first) : require("fbjs/lib/invariant")(false) : void 0;
|
|
45
|
-
calls.first = +calls.first;
|
|
46
|
-
} else if (calls.last) {
|
|
47
|
-
!!isNaN(calls.last) ? process.env.NODE_ENV !== "production" ? require("fbjs/lib/invariant")(false, 'GraphQLRange: Expected `last` argument to be a number, got `%s`.', calls.last) : require("fbjs/lib/invariant")(false) : void 0;
|
|
48
|
-
calls.last = +calls.last;
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
return calls;
|
|
52
|
-
}
|
|
53
|
-
/**
|
|
54
|
-
* Returns whether this is currently a set of static calls that GraphQLRange
|
|
55
|
-
* supports. Static calls define ranges that do not change over a period
|
|
56
|
-
* of time, given the same set of arguments.
|
|
57
|
-
*
|
|
58
|
-
* @param {object} calls
|
|
59
|
-
* @return {?boolean}
|
|
60
|
-
*/
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
function isStaticCall(calls) {
|
|
64
|
-
return calls.hasOwnProperty('surrounds') || calls.hasOwnProperty('find');
|
|
65
|
-
}
|
|
66
|
-
/**
|
|
67
|
-
* Returns whether this is currently a set of calls that GraphQLRange
|
|
68
|
-
* supports
|
|
69
|
-
*
|
|
70
|
-
* @param {object} calls
|
|
71
|
-
* @return {boolean}
|
|
72
|
-
*/
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
function isValidRangeCall(calls) {
|
|
76
|
-
var hasFirst = calls.hasOwnProperty('first');
|
|
77
|
-
var hasLast = calls.hasOwnProperty('last'); // Currently only supports: first(), after().first(), last(), before().last()
|
|
78
|
-
// before().first(), after().last(), after().before().first(), and
|
|
79
|
-
// after().before().last()
|
|
80
|
-
// first() can never be called with last().
|
|
81
|
-
|
|
82
|
-
return (hasFirst || hasLast) && !(hasFirst && hasLast);
|
|
83
|
-
}
|
|
84
|
-
/**
|
|
85
|
-
* Returns whether the call values are supported by GraphQLRange
|
|
86
|
-
*
|
|
87
|
-
* @param {object} calls
|
|
88
|
-
* @return {boolean}
|
|
89
|
-
*/
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
function isValidRangeCallValues(calls) {
|
|
93
|
-
return calls.hasOwnProperty('first') && calls.first > 0 || calls.hasOwnProperty('last') && calls.last > 0;
|
|
94
|
-
}
|
|
95
|
-
/**
|
|
96
|
-
* Validates edge to ensure it has all the fields needed to be store properly.
|
|
97
|
-
*
|
|
98
|
-
* @param {object} edge
|
|
99
|
-
*/
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
function validateEdge(edge) {
|
|
103
|
-
!(require("./RelayRecord").getDataIDForObject(edge) !== undefined) ? process.env.NODE_ENV !== "production" ? require("fbjs/lib/invariant")(false, 'GraphQLStore: `edge` must have a data id') : require("fbjs/lib/invariant")(false) : void 0;
|
|
104
|
-
!(edge.node !== undefined) ? process.env.NODE_ENV !== "production" ? require("fbjs/lib/invariant")(false, 'GraphQLStore: `edge` must have `node` field') : require("fbjs/lib/invariant")(false) : void 0;
|
|
105
|
-
}
|
|
106
|
-
/**
|
|
107
|
-
* @param {array<object>} edges
|
|
108
|
-
*/
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
function validateEdges(edges) {
|
|
112
|
-
edges.forEach(validateEdge);
|
|
113
|
-
}
|
|
114
|
-
/**
|
|
115
|
-
* @internal
|
|
116
|
-
*
|
|
117
|
-
* A range represents an ordered set of edges. Methods are provided for adding
|
|
118
|
-
* edges (`appendEdge`, `prependEdge`, `addItems`) and removing them
|
|
119
|
-
* (`removeEdgeWithID`).
|
|
120
|
-
*
|
|
121
|
-
* Within a range, each contiguous group of edges is modeled using a
|
|
122
|
-
* `GraphQLSegment`, but this is an implementation detail that `GraphQLRange`
|
|
123
|
-
* hides from its callers.
|
|
124
|
-
*
|
|
125
|
-
* Ranges model GraphQL connections, which are the means of traversing from a
|
|
126
|
-
* node to a set of associated objects; for example, in the following query the
|
|
127
|
-
* "friends" connection produces a range containing edges that lead to the
|
|
128
|
-
* requested friend nodes:
|
|
129
|
-
*
|
|
130
|
-
* node(4) {
|
|
131
|
-
* friends.first(2) {
|
|
132
|
-
* edges {
|
|
133
|
-
* node {
|
|
134
|
-
* id,
|
|
135
|
-
* name,
|
|
136
|
-
* },
|
|
137
|
-
* },
|
|
138
|
-
* },
|
|
139
|
-
* }
|
|
140
|
-
*
|
|
141
|
-
* @see `GraphQLSegment`
|
|
142
|
-
* @see http://facebook.github.io/relay/docs/graphql-connections.html
|
|
143
|
-
*/
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
var GraphQLRange =
|
|
147
|
-
/*#__PURE__*/
|
|
148
|
-
function () {
|
|
149
|
-
function GraphQLRange() {
|
|
150
|
-
this.reset();
|
|
151
|
-
}
|
|
152
|
-
|
|
153
|
-
var _proto = GraphQLRange.prototype;
|
|
154
|
-
|
|
155
|
-
_proto.reset = function reset() {
|
|
156
|
-
// List of segments where each segment is a continuous chunk.
|
|
157
|
-
// There are gaps in between the segments. The first segment in the list
|
|
158
|
-
// should be cursors beginning at the top of the range (i.e. first(N)).
|
|
159
|
-
// The last segment in the list should be cursors at the bottom of
|
|
160
|
-
// the range (i.e. last(N)).
|
|
161
|
-
this._orderedSegments = [new (require("./GraphQLSegment"))(), new (require("./GraphQLSegment"))()]; // GraphQLRange nodes can also support static queries like surrounds,
|
|
162
|
-
// find, whose contents won't ever change for a given set of arguments.
|
|
163
|
-
// Store these queries' results in this map, since you can't do first()
|
|
164
|
-
// or last() queries on these ranges.
|
|
165
|
-
|
|
166
|
-
this._staticQueriesMap = {};
|
|
167
|
-
this._hasFirst = false;
|
|
168
|
-
this._hasLast = false;
|
|
169
|
-
};
|
|
170
|
-
/**
|
|
171
|
-
* @param {number} index
|
|
172
|
-
*/
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
_proto._resetSegment = function _resetSegment(index) {
|
|
176
|
-
!(index >= 0 && index < this._orderedSegments.length) ? process.env.NODE_ENV !== "production" ? require("fbjs/lib/invariant")(false, 'cannot reset non-existent segment') : require("fbjs/lib/invariant")(false) : void 0;
|
|
177
|
-
this._orderedSegments[index] = new (require("./GraphQLSegment"))();
|
|
178
|
-
};
|
|
179
|
-
/**
|
|
180
|
-
* @param {string} cursor
|
|
181
|
-
* @return {?number}
|
|
182
|
-
*/
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
_proto._getSegmentIndexByCursor = function _getSegmentIndexByCursor(cursor) {
|
|
186
|
-
var deletedIndex = null; // TODO: revisit if we end up having too many segments
|
|
187
|
-
|
|
188
|
-
for (var ii = 0; ii < this._orderedSegments.length; ii++) {
|
|
189
|
-
if (this._orderedSegments[ii].containsEdgeWithCursor(cursor)) {
|
|
190
|
-
return ii;
|
|
191
|
-
} else if (this._orderedSegments[ii].containsEdgeWithCursor(cursor, true)) {
|
|
192
|
-
deletedIndex = ii;
|
|
193
|
-
}
|
|
194
|
-
}
|
|
195
|
-
|
|
196
|
-
return deletedIndex;
|
|
197
|
-
};
|
|
198
|
-
/**
|
|
199
|
-
* @param {string} id
|
|
200
|
-
* @return {?number}
|
|
201
|
-
*/
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
_proto._getSegmentIndexByID = function _getSegmentIndexByID(id) {
|
|
205
|
-
// TODO: revisit if we end up having too many segments
|
|
206
|
-
for (var ii = 0; ii < this._orderedSegments.length; ii++) {
|
|
207
|
-
if (this._orderedSegments[ii].containsEdgeWithID(id)) {
|
|
208
|
-
return ii;
|
|
209
|
-
}
|
|
210
|
-
}
|
|
211
|
-
|
|
212
|
-
return null;
|
|
213
|
-
};
|
|
214
|
-
/**
|
|
215
|
-
* Add edges' data into the static queries map for the query calls,
|
|
216
|
-
* overwriting any previously existing data for these calls.
|
|
217
|
-
* @param {array<object>} queryCalls
|
|
218
|
-
* @param {array} edges
|
|
219
|
-
*/
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
_proto._addStaticEdges = function _addStaticEdges(queryCalls, edges) {
|
|
223
|
-
var calls = _callsToString(queryCalls);
|
|
224
|
-
|
|
225
|
-
var edgeIDsToStore = [];
|
|
226
|
-
var cursorsToStore = [];
|
|
227
|
-
|
|
228
|
-
for (var ii = 0; ii < edges.length; ii++) {
|
|
229
|
-
var edge = edges[ii];
|
|
230
|
-
edgeIDsToStore.push(require("./RelayRecord").getDataIDForObject(edge));
|
|
231
|
-
cursorsToStore.push(edge.cursor);
|
|
232
|
-
}
|
|
233
|
-
|
|
234
|
-
this._staticQueriesMap[calls] = {
|
|
235
|
-
edgeIDs: edgeIDsToStore,
|
|
236
|
-
cursors: cursorsToStore
|
|
237
|
-
};
|
|
238
|
-
};
|
|
239
|
-
/**
|
|
240
|
-
* Add edges into the range based on the query calls. New edges will replace
|
|
241
|
-
* previous edges in the range.
|
|
242
|
-
* @param {array<object>} queryCalls
|
|
243
|
-
* @param {array} edges
|
|
244
|
-
* @param {object} pageInfo
|
|
245
|
-
*/
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
_proto.addItems = function addItems(queryCalls, edges, pageInfo) {
|
|
249
|
-
validateEdges(edges);
|
|
250
|
-
var calls = callsArrayToObject(queryCalls);
|
|
251
|
-
var segmentCount, segmentIndex;
|
|
252
|
-
|
|
253
|
-
if (isStaticCall(calls)) {
|
|
254
|
-
this._addStaticEdges(queryCalls, edges);
|
|
255
|
-
|
|
256
|
-
return;
|
|
257
|
-
}
|
|
258
|
-
|
|
259
|
-
if (!isValidRangeCall(calls)) {
|
|
260
|
-
console.error('GraphQLRange.addItems only handles first(<count>), ' + 'after(<cursor>).first(<count>), last(<count>), ' + 'before(<cursor>).last(<count>), before(<cursor>).first(<count>), ' + 'and after(<cursor>).last(<count>)');
|
|
261
|
-
return;
|
|
262
|
-
} // Skip the update if cursors are invalid
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
if (calls.before === null || calls.after === null) {
|
|
266
|
-
console.error('GraphQLRange received null as a cursor.');
|
|
267
|
-
return;
|
|
268
|
-
}
|
|
269
|
-
|
|
270
|
-
var _ConnectionInterface$ = require("relay-runtime").ConnectionInterface.get(),
|
|
271
|
-
HAS_NEXT_PAGE = _ConnectionInterface$.HAS_NEXT_PAGE,
|
|
272
|
-
HAS_PREV_PAGE = _ConnectionInterface$.HAS_PREV_PAGE;
|
|
273
|
-
|
|
274
|
-
if (calls.first) {
|
|
275
|
-
// before().first() calls can produce gaps
|
|
276
|
-
if (calls.before && !calls.after) {
|
|
277
|
-
// make a new segment if there is a gap and there are new edges
|
|
278
|
-
if (pageInfo[HAS_NEXT_PAGE] === true && edges.length !== 0) {
|
|
279
|
-
if (this._getSegmentIndexByCursor(calls.before) === 0) {
|
|
280
|
-
this._orderedSegments.unshift(new (require("./GraphQLSegment"))());
|
|
281
|
-
} // When there is a gap from before().first() query, this is the same
|
|
282
|
-
// as just storing a first().
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
this._addAfterFirstItems(edges, pageInfo[HAS_NEXT_PAGE], undefined, calls.before);
|
|
286
|
-
} else {
|
|
287
|
-
// Since there is no gap, we can stitch into the beginning
|
|
288
|
-
// of existing segment
|
|
289
|
-
this._addBeforeLastItems(edges, pageInfo[HAS_PREV_PAGE], calls.before);
|
|
290
|
-
}
|
|
291
|
-
} else {
|
|
292
|
-
// These elements are added from paging to extend the the range.
|
|
293
|
-
if (!calls.after) {
|
|
294
|
-
segmentIndex = 0;
|
|
295
|
-
segmentCount = this.getFirstSegment().getCount();
|
|
296
|
-
|
|
297
|
-
if (segmentCount && (calls.first > segmentCount || edges.length > segmentCount) && !this.getFirstSegment().getFirstCursor()) {
|
|
298
|
-
// this is a range for which we don't have a cursor, and we've
|
|
299
|
-
// fetched more data by increasing the `first(N)` variable; we
|
|
300
|
-
// blow away and replace the first segment in order to side-step
|
|
301
|
-
// issues where the order of IDs in the range may change between
|
|
302
|
-
// queries
|
|
303
|
-
this._resetSegment(segmentIndex);
|
|
304
|
-
}
|
|
305
|
-
}
|
|
306
|
-
|
|
307
|
-
this._addAfterFirstItems(edges, pageInfo[HAS_NEXT_PAGE], calls.after, calls.before);
|
|
308
|
-
}
|
|
309
|
-
} else if (calls.last) {
|
|
310
|
-
// after().last() calls can produce gaps
|
|
311
|
-
if (calls.after && !calls.before) {
|
|
312
|
-
// make a new segment if there is a gap and there are new edges
|
|
313
|
-
if (pageInfo[HAS_PREV_PAGE] === true && edges.length !== 0) {
|
|
314
|
-
if (this._getSegmentIndexByCursor(calls.after) === this._orderedSegments.length - 1) {
|
|
315
|
-
this._orderedSegments.push(new (require("./GraphQLSegment"))());
|
|
316
|
-
} // When there is a gap from after().last() query, this is the same as
|
|
317
|
-
// just storing a last().
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
this._addBeforeLastItems(edges, pageInfo[HAS_PREV_PAGE], undefined, calls.after);
|
|
321
|
-
} else {
|
|
322
|
-
// Since there is no gap, we can stitch to the end
|
|
323
|
-
// of existing segment
|
|
324
|
-
this._addAfterFirstItems(edges, pageInfo[HAS_NEXT_PAGE], calls.after);
|
|
325
|
-
}
|
|
326
|
-
} else {
|
|
327
|
-
// These elements are added from paging to extend the the range.
|
|
328
|
-
if (!calls.before) {
|
|
329
|
-
segmentIndex = this._orderedSegments.length - 1;
|
|
330
|
-
segmentCount = this.getLastSegment().getCount();
|
|
331
|
-
|
|
332
|
-
if (segmentCount && (calls.last > segmentCount || edges.length > segmentCount) && !this.getLastSegment().getLastCursor()) {
|
|
333
|
-
// this is a range for which we don't have a cursor, and we've
|
|
334
|
-
// fetched more data by increasing the `last(N)` variable; we
|
|
335
|
-
// blow away and replace the last segment in order to side-step
|
|
336
|
-
// issues where the order of IDs in the range may change between
|
|
337
|
-
// queries
|
|
338
|
-
this._resetSegment(segmentIndex);
|
|
339
|
-
}
|
|
340
|
-
}
|
|
341
|
-
|
|
342
|
-
this._addBeforeLastItems(edges, pageInfo[HAS_PREV_PAGE], calls.before, calls.after);
|
|
343
|
-
}
|
|
344
|
-
}
|
|
345
|
-
};
|
|
346
|
-
/**
|
|
347
|
-
* @return {GraphQLSegment}
|
|
348
|
-
*/
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
_proto.getFirstSegment = function getFirstSegment() {
|
|
352
|
-
return this._orderedSegments[0];
|
|
353
|
-
};
|
|
354
|
-
/**
|
|
355
|
-
* @return {GraphQLSegment}
|
|
356
|
-
*/
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
_proto.getLastSegment = function getLastSegment() {
|
|
360
|
-
return this._orderedSegments[this._orderedSegments.length - 1];
|
|
361
|
-
};
|
|
362
|
-
/**
|
|
363
|
-
* Tries to concat segments at segmentIndex and segmentIndex + 1.
|
|
364
|
-
* This is an all or nothing operation.
|
|
365
|
-
* If concat is successful, we'll remove the segment at segmentIndex + 1
|
|
366
|
-
* from the orderedSegments after all elements has been added to the segment
|
|
367
|
-
* at segmentIndex.
|
|
368
|
-
* If concat is unsuccessful, nothing will be changed.
|
|
369
|
-
* @param {number} segmentIndex
|
|
370
|
-
*/
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
_proto._concatSegments = function _concatSegments(segmentIndex) {
|
|
374
|
-
!(segmentIndex + 1 < this._orderedSegments.length && segmentIndex >= 0) ? process.env.NODE_ENV !== "production" ? require("fbjs/lib/invariant")(false, 'GraphQLRange cannot concat segments outside the range ' + 'of orderedSegments') : require("fbjs/lib/invariant")(false) : void 0;
|
|
375
|
-
var firstSegment = this._orderedSegments[segmentIndex];
|
|
376
|
-
var secondSegment = this._orderedSegments[segmentIndex + 1];
|
|
377
|
-
|
|
378
|
-
if (firstSegment.concatSegment(secondSegment)) {
|
|
379
|
-
this._orderedSegments.splice(segmentIndex + 1, 1);
|
|
380
|
-
} else {
|
|
381
|
-
console.warn('GraphQLRange was unable to concat segment %d and segment %d', segmentIndex, segmentIndex + 1);
|
|
382
|
-
}
|
|
383
|
-
};
|
|
384
|
-
/**
|
|
385
|
-
* Adds the edge to the front of the range. New edge will replace previous
|
|
386
|
-
* edge that have the same id.
|
|
387
|
-
* @param {object} edge
|
|
388
|
-
*/
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
_proto.prependEdge = function prependEdge(edge) {
|
|
392
|
-
validateEdge(edge);
|
|
393
|
-
this._hasFirst = true;
|
|
394
|
-
|
|
395
|
-
this._removeEdgeIfApplicable(edge);
|
|
396
|
-
|
|
397
|
-
var segment = this.getFirstSegment();
|
|
398
|
-
segment.prependEdge(edge);
|
|
399
|
-
};
|
|
400
|
-
/**
|
|
401
|
-
* Adds the edge to the end of the range. New edge will replace previous
|
|
402
|
-
* edge that have the same id.
|
|
403
|
-
* @param {object} edge
|
|
404
|
-
*/
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
_proto.appendEdge = function appendEdge(edge) {
|
|
408
|
-
validateEdge(edge);
|
|
409
|
-
this._hasLast = true;
|
|
410
|
-
|
|
411
|
-
this._removeEdgeIfApplicable(edge);
|
|
412
|
-
|
|
413
|
-
var segment = this.getLastSegment();
|
|
414
|
-
segment.appendEdge(edge);
|
|
415
|
-
};
|
|
416
|
-
/**
|
|
417
|
-
* Removes edge in range if it matches id in input edge.
|
|
418
|
-
* @param {object} edge
|
|
419
|
-
*/
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
_proto._removeEdgeIfApplicable = function _removeEdgeIfApplicable(edge) {
|
|
423
|
-
var id = require("./RelayRecord").getDataIDForObject(edge);
|
|
424
|
-
|
|
425
|
-
var index = this._getSegmentIndexByID(id);
|
|
426
|
-
|
|
427
|
-
if (index != null) {
|
|
428
|
-
this._orderedSegments[index].removeEdge(id);
|
|
429
|
-
}
|
|
430
|
-
};
|
|
431
|
-
/**
|
|
432
|
-
* Filter out edges that are already in the range to keep a stable ordering.
|
|
433
|
-
*
|
|
434
|
-
* @param {array} edges
|
|
435
|
-
* @return {array} filtered edges
|
|
436
|
-
*/
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
_proto._dedupEdgesAgainstRange = function _dedupEdgesAgainstRange(edges) {
|
|
440
|
-
var _this = this;
|
|
441
|
-
|
|
442
|
-
return edges.filter(function (edge) {
|
|
443
|
-
var id = require("./RelayRecord").getDataIDForObject(edge);
|
|
444
|
-
|
|
445
|
-
return _this._getSegmentIndexByID(id) == null;
|
|
446
|
-
});
|
|
447
|
-
};
|
|
448
|
-
/**
|
|
449
|
-
* Add items into the correct segment with the cursor. If no cursor
|
|
450
|
-
* is present, items are added to the very first segment.
|
|
451
|
-
*
|
|
452
|
-
* @param {array} edges
|
|
453
|
-
* @param {boolean} hasNextPage
|
|
454
|
-
* @param {?string} afterCursor
|
|
455
|
-
* @param {?string} beforeCursor
|
|
456
|
-
*/
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
_proto._addAfterFirstItems = function _addAfterFirstItems(edges, hasNextPage, afterCursor, beforeCursor) {
|
|
460
|
-
var segment;
|
|
461
|
-
var segmentIndex;
|
|
462
|
-
var lastCursor;
|
|
463
|
-
|
|
464
|
-
if (afterCursor !== undefined) {
|
|
465
|
-
segmentIndex = this._getSegmentIndexByCursor(afterCursor);
|
|
466
|
-
|
|
467
|
-
if (segmentIndex == null) {
|
|
468
|
-
process.env.NODE_ENV !== "production" ? require("fbjs/lib/warning")(false, 'GraphQLRange cannot find a segment that has the cursor: %s', afterCursor) : void 0;
|
|
469
|
-
return;
|
|
470
|
-
}
|
|
471
|
-
|
|
472
|
-
segment = this._orderedSegments[segmentIndex];
|
|
473
|
-
lastCursor = segment.getLastCursor();
|
|
474
|
-
|
|
475
|
-
if (lastCursor !== afterCursor) {
|
|
476
|
-
edges = this._reconcileAfterFirstEdges(segment, edges, afterCursor);
|
|
477
|
-
afterCursor = lastCursor;
|
|
478
|
-
|
|
479
|
-
if (!edges) {
|
|
480
|
-
return;
|
|
481
|
-
}
|
|
482
|
-
}
|
|
483
|
-
} else {
|
|
484
|
-
segmentIndex = 0;
|
|
485
|
-
segment = this._orderedSegments[segmentIndex];
|
|
486
|
-
lastCursor = segment.getLastCursor();
|
|
487
|
-
|
|
488
|
-
if (lastCursor !== undefined) {
|
|
489
|
-
edges = this._reconcileAfterFirstEdges(segment, edges);
|
|
490
|
-
afterCursor = lastCursor;
|
|
491
|
-
|
|
492
|
-
if (!edges) {
|
|
493
|
-
return;
|
|
494
|
-
}
|
|
495
|
-
}
|
|
496
|
-
}
|
|
497
|
-
|
|
498
|
-
var nextSegment = this._orderedSegments[segmentIndex + 1];
|
|
499
|
-
|
|
500
|
-
if (beforeCursor !== undefined) {
|
|
501
|
-
if (segmentIndex === this._orderedSegments.length - 1) {
|
|
502
|
-
console.warn('GraphQLRange cannot add because there is no next segment');
|
|
503
|
-
return;
|
|
504
|
-
} else if (!nextSegment.isFirstCursor(beforeCursor)) {
|
|
505
|
-
process.env.NODE_ENV !== "production" ? require("fbjs/lib/warning")(false, 'GraphQLRange cannot add because beforeCursor does not match first ' + 'cursor of the next segment') : void 0;
|
|
506
|
-
return;
|
|
507
|
-
}
|
|
508
|
-
}
|
|
509
|
-
|
|
510
|
-
if (afterCursor === undefined) {
|
|
511
|
-
this._hasFirst = true;
|
|
512
|
-
}
|
|
513
|
-
|
|
514
|
-
var filteredEdges = this._dedupEdgesAgainstRange(edges);
|
|
515
|
-
|
|
516
|
-
segment.addEdgesAfterCursor(filteredEdges, afterCursor);
|
|
517
|
-
|
|
518
|
-
if (!hasNextPage) {
|
|
519
|
-
if (beforeCursor !== undefined) {
|
|
520
|
-
// If we have a beforeCursor and there is no next page,
|
|
521
|
-
// then there is no gap between the current segment and the next.
|
|
522
|
-
// We can concat the two segments when there is no gap.
|
|
523
|
-
this._concatSegments(segmentIndex);
|
|
524
|
-
} else {
|
|
525
|
-
this._hasLast = true; // If this segment already has the last element, we don't
|
|
526
|
-
// need any segments after this.
|
|
527
|
-
|
|
528
|
-
this._orderedSegments.splice(segmentIndex + 1, this._orderedSegments.length - 1 - segmentIndex);
|
|
529
|
-
}
|
|
530
|
-
}
|
|
531
|
-
};
|
|
532
|
-
/**
|
|
533
|
-
* In the case the cursor does not correspond last cursor,
|
|
534
|
-
* walk through the edges to see if we can trim edges to
|
|
535
|
-
* only those after the last cursor. Returns undefined when
|
|
536
|
-
* the input cannot be reconciled.
|
|
537
|
-
*
|
|
538
|
-
* @param {GraphQLSegment} segment
|
|
539
|
-
* @param {array} edges
|
|
540
|
-
* @param {?string} cursor
|
|
541
|
-
* @return {?array} trimmed edges
|
|
542
|
-
*/
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
_proto._reconcileAfterFirstEdges = function _reconcileAfterFirstEdges(segment, edges, cursor) {
|
|
546
|
-
var metadata = segment.getMetadataAfterCursor(edges.length + 1, cursor);
|
|
547
|
-
var edgeIDs = metadata.edgeIDs;
|
|
548
|
-
|
|
549
|
-
if (edgeIDs.length > edges.length) {
|
|
550
|
-
// Already have more edges than the input.
|
|
551
|
-
return undefined;
|
|
552
|
-
}
|
|
553
|
-
|
|
554
|
-
for (var ii = 0; ii < edgeIDs.length; ii++) {
|
|
555
|
-
if (edgeIDs[ii] !== require("./RelayRecord").getDataIDForObject(edges[ii])) {
|
|
556
|
-
process.env.NODE_ENV !== "production" ? require("fbjs/lib/warning")(false, 'Relay was unable to reconcile edges on a connection. This most ' + 'likely occurred while trying to handle a server response that ' + 'includes connection edges with nodes that lack an `id` field.') : void 0;
|
|
557
|
-
return undefined;
|
|
558
|
-
}
|
|
559
|
-
}
|
|
560
|
-
|
|
561
|
-
return edges.slice(edgeIDs.length);
|
|
562
|
-
};
|
|
563
|
-
/**
|
|
564
|
-
* Add items into the correct segment with the cursor. If no cursor
|
|
565
|
-
* is present, items are added to the very last segment.
|
|
566
|
-
* @param {array} edges
|
|
567
|
-
* @param {boolean} hasPrevPage
|
|
568
|
-
* @param {?string} beforeCursor
|
|
569
|
-
* @param {?string} afterCursor
|
|
570
|
-
*/
|
|
571
|
-
|
|
572
|
-
|
|
573
|
-
_proto._addBeforeLastItems = function _addBeforeLastItems(edges, hasPrevPage, beforeCursor, afterCursor) {
|
|
574
|
-
var segment;
|
|
575
|
-
var segmentIndex;
|
|
576
|
-
var firstCursor;
|
|
577
|
-
|
|
578
|
-
if (beforeCursor !== undefined) {
|
|
579
|
-
segmentIndex = this._getSegmentIndexByCursor(beforeCursor);
|
|
580
|
-
|
|
581
|
-
if (segmentIndex == null) {
|
|
582
|
-
process.env.NODE_ENV !== "production" ? require("fbjs/lib/warning")(false, 'GraphQLRange cannot find a segment that has the cursor: %s', beforeCursor) : void 0;
|
|
583
|
-
return;
|
|
584
|
-
}
|
|
585
|
-
|
|
586
|
-
segment = this._orderedSegments[segmentIndex];
|
|
587
|
-
firstCursor = segment.getFirstCursor();
|
|
588
|
-
|
|
589
|
-
if (firstCursor !== beforeCursor) {
|
|
590
|
-
edges = this._reconcileBeforeLastEdges(segment, edges, beforeCursor);
|
|
591
|
-
beforeCursor = firstCursor;
|
|
592
|
-
|
|
593
|
-
if (!edges) {
|
|
594
|
-
return;
|
|
595
|
-
}
|
|
596
|
-
}
|
|
597
|
-
} else {
|
|
598
|
-
segmentIndex = this._orderedSegments.length - 1;
|
|
599
|
-
segment = this._orderedSegments[segmentIndex];
|
|
600
|
-
firstCursor = segment.getFirstCursor();
|
|
601
|
-
|
|
602
|
-
if (firstCursor !== undefined) {
|
|
603
|
-
edges = this._reconcileBeforeLastEdges(segment, edges, beforeCursor);
|
|
604
|
-
beforeCursor = firstCursor;
|
|
605
|
-
|
|
606
|
-
if (!edges) {
|
|
607
|
-
return;
|
|
608
|
-
}
|
|
609
|
-
}
|
|
610
|
-
}
|
|
611
|
-
|
|
612
|
-
var prevSegment = this._orderedSegments[segmentIndex - 1];
|
|
613
|
-
|
|
614
|
-
if (afterCursor !== undefined) {
|
|
615
|
-
if (segmentIndex === 0) {
|
|
616
|
-
console.warn('GraphQLRange cannot add because there is no previous segment');
|
|
617
|
-
return;
|
|
618
|
-
} else if (!prevSegment.isLastCursor(afterCursor)) {
|
|
619
|
-
process.env.NODE_ENV !== "production" ? require("fbjs/lib/warning")(false, 'GraphQLRange cannot add because afterCursor does not match last ' + 'cursor of the previous segment') : void 0;
|
|
620
|
-
return;
|
|
621
|
-
}
|
|
622
|
-
}
|
|
623
|
-
|
|
624
|
-
if (beforeCursor === undefined) {
|
|
625
|
-
this._hasLast = true;
|
|
626
|
-
}
|
|
627
|
-
|
|
628
|
-
var filteredEdges = this._dedupEdgesAgainstRange(edges);
|
|
629
|
-
|
|
630
|
-
segment.addEdgesBeforeCursor(filteredEdges, beforeCursor);
|
|
631
|
-
|
|
632
|
-
if (!hasPrevPage) {
|
|
633
|
-
if (afterCursor !== undefined) {
|
|
634
|
-
// If we have an afterCursor and there is no previous page,
|
|
635
|
-
// then there is no gap between the current segment and the previous.
|
|
636
|
-
// We can concat the two segments when there is no gap.
|
|
637
|
-
this._concatSegments(segmentIndex - 1);
|
|
638
|
-
} else {
|
|
639
|
-
this._hasFirst = true; // If this segment already has the first element, we don't
|
|
640
|
-
// need any segments before this.
|
|
641
|
-
|
|
642
|
-
this._orderedSegments.splice(0, segmentIndex);
|
|
643
|
-
}
|
|
644
|
-
}
|
|
645
|
-
};
|
|
646
|
-
/**
|
|
647
|
-
* In the case the cursor does not correspond first cursor,
|
|
648
|
-
* walk through the edges to see if we can trim edges to
|
|
649
|
-
* only those before the first cursor. Returns undefined when
|
|
650
|
-
* the input cannot be reconciled.
|
|
651
|
-
*
|
|
652
|
-
* @param {GraphQLSegment} segment
|
|
653
|
-
* @param {array} edges
|
|
654
|
-
* @param {?string} cursor
|
|
655
|
-
* @return {?array} trimmed edges
|
|
656
|
-
*/
|
|
657
|
-
|
|
658
|
-
|
|
659
|
-
_proto._reconcileBeforeLastEdges = function _reconcileBeforeLastEdges(segment, edges, cursor) {
|
|
660
|
-
var metadata = segment.getMetadataBeforeCursor(edges.length + 1, cursor);
|
|
661
|
-
var edgeIDs = metadata.edgeIDs;
|
|
662
|
-
|
|
663
|
-
if (edgeIDs.length > edges.length) {
|
|
664
|
-
// Already have more edges than the input.
|
|
665
|
-
return undefined;
|
|
666
|
-
}
|
|
667
|
-
|
|
668
|
-
for (var ii = 1; ii <= edgeIDs.length; ii++) {
|
|
669
|
-
if (edgeIDs[edgeIDs.length - ii] !== require("./RelayRecord").getDataIDForObject(edges[edges.length - ii])) {
|
|
670
|
-
process.env.NODE_ENV !== "production" ? require("fbjs/lib/warning")(false, 'Relay was unable to reconcile edges on a connection. This most ' + 'likely occurred while trying to handle a server response that ' + 'includes connection edges with nodes that lack an `id` field.') : void 0;
|
|
671
|
-
return undefined;
|
|
672
|
-
}
|
|
673
|
-
}
|
|
674
|
-
|
|
675
|
-
return edges.slice(0, edges.length - edgeIDs.length);
|
|
676
|
-
};
|
|
677
|
-
/**
|
|
678
|
-
* Removes an edge from this range such that the edge will never be reachable
|
|
679
|
-
* regardless of the client session. This is used by delete mutations.
|
|
680
|
-
*
|
|
681
|
-
* @param {string} id
|
|
682
|
-
*/
|
|
683
|
-
|
|
684
|
-
|
|
685
|
-
_proto.removeEdgeWithID = function removeEdgeWithID(id) {
|
|
686
|
-
for (var ii = 0; ii < this._orderedSegments.length; ii++) {
|
|
687
|
-
this._orderedSegments[ii].removeAllEdges(id);
|
|
688
|
-
}
|
|
689
|
-
};
|
|
690
|
-
/**
|
|
691
|
-
* @param {array<object>} queryCalls
|
|
692
|
-
* @param {?object} queuedRecord
|
|
693
|
-
* @return {object} includes fields: requestedEdgeIDs, diffCalls
|
|
694
|
-
*/
|
|
695
|
-
|
|
696
|
-
|
|
697
|
-
_proto.retrieveRangeInfoForQuery = function retrieveRangeInfoForQuery(queryCalls, queuedRecord) {
|
|
698
|
-
var calls = callsArrayToObject(queryCalls);
|
|
699
|
-
|
|
700
|
-
if (isStaticCall(calls)) {
|
|
701
|
-
return this._retrieveRangeInfoForStaticCalls(queryCalls);
|
|
702
|
-
} // Convert to name => true, so we can test for whether the key exists
|
|
703
|
-
// without comparing to undefined
|
|
704
|
-
|
|
705
|
-
|
|
706
|
-
if (!isValidRangeCall(calls)) {
|
|
707
|
-
console.error('GraphQLRange.retrieveRangeInfoForQuery only handles first(<count>), ' + 'after(<cursor>).first(<count>), last(<count>), ' + 'before(<cursor>).last(<count>), before(<cursor>).first(<count>), ' + 'and after(<cursor>).last(<count>)');
|
|
708
|
-
return {
|
|
709
|
-
requestedEdgeIDs: [],
|
|
710
|
-
diffCalls: [],
|
|
711
|
-
pageInfo: require("relay-runtime").ConnectionInterface.getDefaultPageInfo()
|
|
712
|
-
};
|
|
713
|
-
}
|
|
714
|
-
|
|
715
|
-
if (calls.first && calls.before || calls.last && calls.after) {
|
|
716
|
-
// TODO #7556678: add support for first/before and last/after
|
|
717
|
-
return {
|
|
718
|
-
requestedEdgeIDs: [],
|
|
719
|
-
diffCalls: [],
|
|
720
|
-
pageInfo: require("relay-runtime").ConnectionInterface.getDefaultPageInfo()
|
|
721
|
-
};
|
|
722
|
-
}
|
|
723
|
-
|
|
724
|
-
if (!isValidRangeCallValues(calls)) {
|
|
725
|
-
console.error('GraphQLRange only supports first(<count>) or last(<count>) ' + 'where count is greater than 0');
|
|
726
|
-
return {
|
|
727
|
-
requestedEdgeIDs: [],
|
|
728
|
-
diffCalls: [],
|
|
729
|
-
pageInfo: require("relay-runtime").ConnectionInterface.getDefaultPageInfo()
|
|
730
|
-
};
|
|
731
|
-
}
|
|
732
|
-
|
|
733
|
-
if (calls.first) {
|
|
734
|
-
return this._retrieveRangeInfoForFirstQuery(queryCalls, queuedRecord);
|
|
735
|
-
} else if (calls.last) {
|
|
736
|
-
return this._retrieveRangeInfoForLastQuery(queryCalls, queuedRecord);
|
|
737
|
-
}
|
|
738
|
-
};
|
|
739
|
-
/**
|
|
740
|
-
* @param {array<object>} queryCalls
|
|
741
|
-
* @return {object} includes fields: requestedEdgeIDs, diffCalls
|
|
742
|
-
*/
|
|
743
|
-
|
|
744
|
-
|
|
745
|
-
_proto._retrieveRangeInfoForStaticCalls = function _retrieveRangeInfoForStaticCalls(queryCalls) {
|
|
746
|
-
var calls = _callsToString(queryCalls);
|
|
747
|
-
|
|
748
|
-
var storedInfo = this._staticQueriesMap[calls];
|
|
749
|
-
|
|
750
|
-
if (storedInfo) {
|
|
751
|
-
var _pageInfo;
|
|
752
|
-
|
|
753
|
-
var _ConnectionInterface$2 = require("relay-runtime").ConnectionInterface.get(),
|
|
754
|
-
END_CURSOR = _ConnectionInterface$2.END_CURSOR,
|
|
755
|
-
HAS_NEXT_PAGE = _ConnectionInterface$2.HAS_NEXT_PAGE,
|
|
756
|
-
HAS_PREV_PAGE = _ConnectionInterface$2.HAS_PREV_PAGE,
|
|
757
|
-
START_CURSOR = _ConnectionInterface$2.START_CURSOR;
|
|
758
|
-
|
|
759
|
-
return {
|
|
760
|
-
requestedEdgeIDs: storedInfo.edgeIDs,
|
|
761
|
-
diffCalls: [],
|
|
762
|
-
pageInfo: (_pageInfo = {}, (0, _defineProperty2["default"])(_pageInfo, START_CURSOR, storedInfo.cursors[0]), (0, _defineProperty2["default"])(_pageInfo, END_CURSOR, storedInfo.cursors[storedInfo.cursors.length - 1]), (0, _defineProperty2["default"])(_pageInfo, HAS_NEXT_PAGE, true), (0, _defineProperty2["default"])(_pageInfo, HAS_PREV_PAGE, true), _pageInfo)
|
|
763
|
-
};
|
|
764
|
-
} // if we don't have the data for this static call already,
|
|
765
|
-
// return empty arrays with the corresponding diffCalls
|
|
766
|
-
|
|
767
|
-
|
|
768
|
-
return {
|
|
769
|
-
requestedEdgeIDs: [],
|
|
770
|
-
diffCalls: queryCalls,
|
|
771
|
-
pageInfo: require("relay-runtime").ConnectionInterface.getDefaultPageInfo()
|
|
772
|
-
};
|
|
773
|
-
};
|
|
774
|
-
/**
|
|
775
|
-
* @param {object} queuedRecord
|
|
776
|
-
* @return {?array<string>}
|
|
777
|
-
*/
|
|
778
|
-
|
|
779
|
-
|
|
780
|
-
_proto._getAppendedIDsForQueuedRecord = function _getAppendedIDsForQueuedRecord(queuedRecord) {
|
|
781
|
-
return queuedRecord[require("./rangeOperationToMetadataKey")[require("relay-runtime").RangeOperations.APPEND]];
|
|
782
|
-
};
|
|
783
|
-
/**
|
|
784
|
-
* @param {object} queuedRecord
|
|
785
|
-
* @return {?array<string>}
|
|
786
|
-
*/
|
|
787
|
-
|
|
788
|
-
|
|
789
|
-
_proto._getRemovedIDsForQueuedRecord = function _getRemovedIDsForQueuedRecord(queuedRecord) {
|
|
790
|
-
return queuedRecord[require("./rangeOperationToMetadataKey")[require("relay-runtime").RangeOperations.REMOVE]];
|
|
791
|
-
};
|
|
792
|
-
/**
|
|
793
|
-
* @param {object} queuedRecord
|
|
794
|
-
* @return {?array<string>}
|
|
795
|
-
*/
|
|
796
|
-
|
|
797
|
-
|
|
798
|
-
_proto._getPrependedIDsForQueuedRecord = function _getPrependedIDsForQueuedRecord(queuedRecord) {
|
|
799
|
-
return queuedRecord[require("./rangeOperationToMetadataKey")[require("relay-runtime").RangeOperations.PREPEND]];
|
|
800
|
-
};
|
|
801
|
-
/**
|
|
802
|
-
* @param {array<object>} queryCalls
|
|
803
|
-
* @param {?object} queuedRecord
|
|
804
|
-
* @return {object} includes fields: requestedEdgeIDs, diffCalls
|
|
805
|
-
*/
|
|
806
|
-
|
|
807
|
-
|
|
808
|
-
_proto._retrieveRangeInfoForFirstQuery = function _retrieveRangeInfoForFirstQuery(queryCalls, queuedRecord) {
|
|
809
|
-
var _ConnectionInterface$3 = require("relay-runtime").ConnectionInterface.get(),
|
|
810
|
-
END_CURSOR = _ConnectionInterface$3.END_CURSOR,
|
|
811
|
-
HAS_NEXT_PAGE = _ConnectionInterface$3.HAS_NEXT_PAGE,
|
|
812
|
-
START_CURSOR = _ConnectionInterface$3.START_CURSOR;
|
|
813
|
-
|
|
814
|
-
var appendEdgeIDs;
|
|
815
|
-
var prependEdgeIDs;
|
|
816
|
-
var removeIDs;
|
|
817
|
-
|
|
818
|
-
if (queuedRecord) {
|
|
819
|
-
appendEdgeIDs = this._getAppendedIDsForQueuedRecord(queuedRecord);
|
|
820
|
-
prependEdgeIDs = this._getPrependedIDsForQueuedRecord(queuedRecord);
|
|
821
|
-
removeIDs = this._getRemovedIDsForQueuedRecord(queuedRecord);
|
|
822
|
-
}
|
|
823
|
-
|
|
824
|
-
var calls = callsArrayToObject(queryCalls);
|
|
825
|
-
var countNeeded = calls.first + (removeIDs ? removeIDs.length : 0);
|
|
826
|
-
var segment;
|
|
827
|
-
var segmentIndex;
|
|
828
|
-
var pageInfo = (0, _objectSpread2["default"])({}, require("relay-runtime").ConnectionInterface.getDefaultPageInfo());
|
|
829
|
-
var afterCursor = calls.after;
|
|
830
|
-
|
|
831
|
-
if (afterCursor !== undefined) {
|
|
832
|
-
segmentIndex = this._getSegmentIndexByCursor(afterCursor);
|
|
833
|
-
|
|
834
|
-
if (segmentIndex == null) {
|
|
835
|
-
console.warn('GraphQLRange cannot find a segment that has the cursor: ' + afterCursor);
|
|
836
|
-
return {
|
|
837
|
-
requestedEdgeIDs: [],
|
|
838
|
-
diffCalls: [],
|
|
839
|
-
pageInfo: pageInfo
|
|
840
|
-
};
|
|
841
|
-
}
|
|
842
|
-
|
|
843
|
-
segment = this._orderedSegments[segmentIndex];
|
|
844
|
-
} else {
|
|
845
|
-
var prependEdgesCount = prependEdgeIDs ? prependEdgeIDs.length : 0;
|
|
846
|
-
countNeeded -= prependEdgesCount;
|
|
847
|
-
segmentIndex = 0;
|
|
848
|
-
segment = this._orderedSegments[segmentIndex];
|
|
849
|
-
}
|
|
850
|
-
|
|
851
|
-
var requestedMetadata = segment.getMetadataAfterCursor(countNeeded, afterCursor);
|
|
852
|
-
var requestedEdgeIDs = requestedMetadata.edgeIDs;
|
|
853
|
-
var requestedCursors = requestedMetadata.cursors;
|
|
854
|
-
var diffCalls = [];
|
|
855
|
-
|
|
856
|
-
if (requestedCursors.length) {
|
|
857
|
-
pageInfo[START_CURSOR] = requestedCursors[0];
|
|
858
|
-
pageInfo[END_CURSOR] = requestedCursors[requestedCursors.length - 1];
|
|
859
|
-
}
|
|
860
|
-
|
|
861
|
-
var lastID = requestedEdgeIDs[requestedEdgeIDs.length - 1]; // Only requested segment that does not include very last item from
|
|
862
|
-
// the range can have next page and diff calls
|
|
863
|
-
|
|
864
|
-
if (!this._hasLast || segmentIndex !== this._orderedSegments.length - 1 || lastID && lastID !== segment.getLastID()) {
|
|
865
|
-
pageInfo[HAS_NEXT_PAGE] = true;
|
|
866
|
-
|
|
867
|
-
if (requestedEdgeIDs.length < countNeeded) {
|
|
868
|
-
countNeeded -= requestedEdgeIDs.length;
|
|
869
|
-
var lastCursor = segment.getLastCursor(); // If segment has null cursors, retrieve whole range.
|
|
870
|
-
|
|
871
|
-
if (lastCursor === null) {
|
|
872
|
-
diffCalls.push({
|
|
873
|
-
name: 'first',
|
|
874
|
-
value: calls.first
|
|
875
|
-
});
|
|
876
|
-
} else {
|
|
877
|
-
if (lastCursor !== undefined) {
|
|
878
|
-
diffCalls.push({
|
|
879
|
-
name: 'after',
|
|
880
|
-
value: lastCursor
|
|
881
|
-
});
|
|
882
|
-
} // If this is not the last segment, we should not request edges
|
|
883
|
-
// that would overlap the first element of the next segment.
|
|
884
|
-
|
|
885
|
-
|
|
886
|
-
if (segmentIndex !== this._orderedSegments.length - 1) {
|
|
887
|
-
var nextSegment = this._orderedSegments[segmentIndex + 1];
|
|
888
|
-
var firstCursor = nextSegment.getFirstCursor();
|
|
889
|
-
|
|
890
|
-
if (firstCursor !== undefined) {
|
|
891
|
-
diffCalls.push({
|
|
892
|
-
name: 'before',
|
|
893
|
-
value: firstCursor
|
|
894
|
-
});
|
|
895
|
-
}
|
|
896
|
-
}
|
|
897
|
-
|
|
898
|
-
diffCalls.push({
|
|
899
|
-
name: 'first',
|
|
900
|
-
value: countNeeded
|
|
901
|
-
});
|
|
902
|
-
}
|
|
903
|
-
}
|
|
904
|
-
}
|
|
905
|
-
|
|
906
|
-
if (queuedRecord) {
|
|
907
|
-
if (prependEdgeIDs && prependEdgeIDs.length && !calls.after) {
|
|
908
|
-
requestedEdgeIDs = prependEdgeIDs.concat(requestedEdgeIDs);
|
|
909
|
-
}
|
|
910
|
-
|
|
911
|
-
if (appendEdgeIDs && appendEdgeIDs.length && !pageInfo[HAS_NEXT_PAGE]) {
|
|
912
|
-
requestedEdgeIDs = requestedEdgeIDs.concat(appendEdgeIDs);
|
|
913
|
-
}
|
|
914
|
-
|
|
915
|
-
if (removeIDs && removeIDs.length) {
|
|
916
|
-
requestedEdgeIDs = requestedEdgeIDs.filter(function (edgeID) {
|
|
917
|
-
return removeIDs.indexOf(edgeID) === -1;
|
|
918
|
-
});
|
|
919
|
-
}
|
|
920
|
-
|
|
921
|
-
if (requestedEdgeIDs.length > calls.first) {
|
|
922
|
-
requestedEdgeIDs = requestedEdgeIDs.slice(0, calls.first);
|
|
923
|
-
}
|
|
924
|
-
}
|
|
925
|
-
|
|
926
|
-
return {
|
|
927
|
-
requestedEdgeIDs: requestedEdgeIDs,
|
|
928
|
-
diffCalls: diffCalls,
|
|
929
|
-
pageInfo: pageInfo
|
|
930
|
-
};
|
|
931
|
-
};
|
|
932
|
-
/**
|
|
933
|
-
* @param {array<object>} queryCalls
|
|
934
|
-
* @param {?object} queuedRecord
|
|
935
|
-
* @return {object} includes fields: requestedEdgeIDs, diffCalls
|
|
936
|
-
*/
|
|
937
|
-
|
|
938
|
-
|
|
939
|
-
_proto._retrieveRangeInfoForLastQuery = function _retrieveRangeInfoForLastQuery(queryCalls, queuedRecord) {
|
|
940
|
-
var _ConnectionInterface$4 = require("relay-runtime").ConnectionInterface.get(),
|
|
941
|
-
END_CURSOR = _ConnectionInterface$4.END_CURSOR,
|
|
942
|
-
HAS_PREV_PAGE = _ConnectionInterface$4.HAS_PREV_PAGE,
|
|
943
|
-
START_CURSOR = _ConnectionInterface$4.START_CURSOR;
|
|
944
|
-
|
|
945
|
-
var appendEdgeIDs;
|
|
946
|
-
var prependEdgeIDs;
|
|
947
|
-
var removeIDs;
|
|
948
|
-
|
|
949
|
-
if (queuedRecord) {
|
|
950
|
-
appendEdgeIDs = this._getAppendedIDsForQueuedRecord(queuedRecord);
|
|
951
|
-
prependEdgeIDs = this._getPrependedIDsForQueuedRecord(queuedRecord);
|
|
952
|
-
removeIDs = this._getRemovedIDsForQueuedRecord(queuedRecord);
|
|
953
|
-
}
|
|
954
|
-
|
|
955
|
-
var calls = callsArrayToObject(queryCalls);
|
|
956
|
-
var countNeeded = calls.last + (removeIDs ? removeIDs.length : 0);
|
|
957
|
-
var segment;
|
|
958
|
-
var segmentIndex;
|
|
959
|
-
var pageInfo = (0, _objectSpread2["default"])({}, require("relay-runtime").ConnectionInterface.getDefaultPageInfo());
|
|
960
|
-
var beforeCursor = calls.before;
|
|
961
|
-
|
|
962
|
-
if (beforeCursor !== undefined) {
|
|
963
|
-
segmentIndex = this._getSegmentIndexByCursor(beforeCursor);
|
|
964
|
-
|
|
965
|
-
if (segmentIndex == null) {
|
|
966
|
-
console.warn('GraphQLRange cannot find a segment that has the cursor: ' + beforeCursor);
|
|
967
|
-
return {
|
|
968
|
-
requestedEdgeIDs: [],
|
|
969
|
-
diffCalls: [],
|
|
970
|
-
pageInfo: pageInfo
|
|
971
|
-
};
|
|
972
|
-
}
|
|
973
|
-
|
|
974
|
-
segment = this._orderedSegments[segmentIndex];
|
|
975
|
-
} else {
|
|
976
|
-
var appendEdgesCount = appendEdgeIDs ? appendEdgeIDs.length : 0;
|
|
977
|
-
countNeeded -= appendEdgesCount;
|
|
978
|
-
segmentIndex = this._orderedSegments.length - 1;
|
|
979
|
-
segment = this._orderedSegments[segmentIndex];
|
|
980
|
-
}
|
|
981
|
-
|
|
982
|
-
var requestedMetadata = segment.getMetadataBeforeCursor(countNeeded, beforeCursor);
|
|
983
|
-
var requestedEdgeIDs = requestedMetadata.edgeIDs;
|
|
984
|
-
var requestedCursors = requestedMetadata.cursors;
|
|
985
|
-
var diffCalls = [];
|
|
986
|
-
|
|
987
|
-
if (requestedCursors.length) {
|
|
988
|
-
pageInfo[START_CURSOR] = requestedCursors[0];
|
|
989
|
-
pageInfo[END_CURSOR] = requestedCursors[requestedCursors.length - 1];
|
|
990
|
-
}
|
|
991
|
-
|
|
992
|
-
var firstID = requestedEdgeIDs[0]; // Only requested segment that does not include very first item from
|
|
993
|
-
// the range can have next page and diff calls
|
|
994
|
-
|
|
995
|
-
if (!this._hasFirst || segmentIndex !== 0 || firstID && firstID !== segment.getFirstID()) {
|
|
996
|
-
pageInfo[HAS_PREV_PAGE] = true;
|
|
997
|
-
|
|
998
|
-
if (requestedEdgeIDs.length < countNeeded) {
|
|
999
|
-
countNeeded -= requestedEdgeIDs.length;
|
|
1000
|
-
var firstCursor = segment.getFirstCursor(); // If segment has null cursors, retrieve whole range.
|
|
1001
|
-
|
|
1002
|
-
if (firstCursor === null) {
|
|
1003
|
-
diffCalls.push({
|
|
1004
|
-
name: 'last',
|
|
1005
|
-
value: calls.last
|
|
1006
|
-
});
|
|
1007
|
-
} else {
|
|
1008
|
-
if (firstCursor !== undefined) {
|
|
1009
|
-
diffCalls.push({
|
|
1010
|
-
name: 'before',
|
|
1011
|
-
value: firstCursor
|
|
1012
|
-
});
|
|
1013
|
-
} // If this is not the first segment, we should not request edges
|
|
1014
|
-
// that would overlap the last element of the previous segment.
|
|
1015
|
-
|
|
1016
|
-
|
|
1017
|
-
if (segmentIndex !== 0) {
|
|
1018
|
-
var prevSegment = this._orderedSegments[segmentIndex - 1];
|
|
1019
|
-
var lastCursor = prevSegment.getLastCursor();
|
|
1020
|
-
|
|
1021
|
-
if (lastCursor !== undefined) {
|
|
1022
|
-
diffCalls.push({
|
|
1023
|
-
name: 'after',
|
|
1024
|
-
value: lastCursor
|
|
1025
|
-
});
|
|
1026
|
-
}
|
|
1027
|
-
}
|
|
1028
|
-
|
|
1029
|
-
diffCalls.push({
|
|
1030
|
-
name: 'last',
|
|
1031
|
-
value: countNeeded
|
|
1032
|
-
});
|
|
1033
|
-
}
|
|
1034
|
-
}
|
|
1035
|
-
}
|
|
1036
|
-
|
|
1037
|
-
if (queuedRecord) {
|
|
1038
|
-
if (appendEdgeIDs && appendEdgeIDs.length && !calls.before) {
|
|
1039
|
-
requestedEdgeIDs = requestedEdgeIDs.concat(appendEdgeIDs);
|
|
1040
|
-
}
|
|
1041
|
-
|
|
1042
|
-
if (prependEdgeIDs && prependEdgeIDs.length && !pageInfo[HAS_PREV_PAGE]) {
|
|
1043
|
-
requestedEdgeIDs = prependEdgeIDs.concat(requestedEdgeIDs);
|
|
1044
|
-
}
|
|
1045
|
-
|
|
1046
|
-
if (removeIDs && removeIDs.length) {
|
|
1047
|
-
requestedEdgeIDs = requestedEdgeIDs.filter(function (edgeID) {
|
|
1048
|
-
return removeIDs.indexOf(edgeID) === -1;
|
|
1049
|
-
});
|
|
1050
|
-
}
|
|
1051
|
-
|
|
1052
|
-
if (requestedEdgeIDs.length > calls.last) {
|
|
1053
|
-
var length = requestedEdgeIDs.length;
|
|
1054
|
-
requestedEdgeIDs = requestedEdgeIDs.slice(length - calls.last, length);
|
|
1055
|
-
}
|
|
1056
|
-
}
|
|
1057
|
-
|
|
1058
|
-
return {
|
|
1059
|
-
requestedEdgeIDs: requestedEdgeIDs,
|
|
1060
|
-
diffCalls: diffCalls,
|
|
1061
|
-
pageInfo: pageInfo
|
|
1062
|
-
};
|
|
1063
|
-
};
|
|
1064
|
-
|
|
1065
|
-
GraphQLRange.fromJSON = function fromJSON(descriptor) {
|
|
1066
|
-
var hasFirst = descriptor[0],
|
|
1067
|
-
hasLast = descriptor[1],
|
|
1068
|
-
staticQueriesMap = descriptor[2],
|
|
1069
|
-
orderedSegments = descriptor[3];
|
|
1070
|
-
var range = new GraphQLRange();
|
|
1071
|
-
range._hasFirst = hasFirst;
|
|
1072
|
-
range._hasLast = hasLast;
|
|
1073
|
-
range._staticQueriesMap = staticQueriesMap;
|
|
1074
|
-
range._orderedSegments = orderedSegments.map(function (segmentDescriptor) {
|
|
1075
|
-
return require("./GraphQLSegment").fromJSON(segmentDescriptor);
|
|
1076
|
-
});
|
|
1077
|
-
return range;
|
|
1078
|
-
};
|
|
1079
|
-
|
|
1080
|
-
_proto.toJSON = function toJSON() {
|
|
1081
|
-
return [this._hasFirst, this._hasLast, this._staticQueriesMap, this._orderedSegments];
|
|
1082
|
-
};
|
|
1083
|
-
|
|
1084
|
-
_proto.__debug = function __debug() {
|
|
1085
|
-
return {
|
|
1086
|
-
orderedSegments: this._orderedSegments
|
|
1087
|
-
};
|
|
1088
|
-
};
|
|
1089
|
-
|
|
1090
|
-
_proto.getEdgeIDs = function getEdgeIDs() {
|
|
1091
|
-
var edgeIDs = [];
|
|
1092
|
-
|
|
1093
|
-
this._orderedSegments.forEach(function (segment) {
|
|
1094
|
-
edgeIDs.push.apply(edgeIDs, (0, _toConsumableArray2["default"])(segment.getEdgeIDs()));
|
|
1095
|
-
});
|
|
1096
|
-
|
|
1097
|
-
require("fbjs/lib/forEachObject")(this._staticQueriesMap, function (query) {
|
|
1098
|
-
edgeIDs.push.apply(edgeIDs, (0, _toConsumableArray2["default"])(query.edgeIDs));
|
|
1099
|
-
});
|
|
1100
|
-
|
|
1101
|
-
return edgeIDs;
|
|
1102
|
-
};
|
|
1103
|
-
|
|
1104
|
-
_proto.getSegmentedEdgeIDs = function getSegmentedEdgeIDs() {
|
|
1105
|
-
return this._orderedSegments.map(function (segment) {
|
|
1106
|
-
return segment.getEdgeIDs();
|
|
1107
|
-
});
|
|
1108
|
-
};
|
|
1109
|
-
|
|
1110
|
-
return GraphQLRange;
|
|
1111
|
-
}();
|
|
1112
|
-
/**
|
|
1113
|
-
* @param {array<object>} calls
|
|
1114
|
-
* @return {string}
|
|
1115
|
-
*/
|
|
1116
|
-
|
|
1117
|
-
|
|
1118
|
-
function _callsToString(calls) {
|
|
1119
|
-
return calls.map(function (call) {
|
|
1120
|
-
return require("./serializeRelayQueryCall")(call).substring(1);
|
|
1121
|
-
}).join(',');
|
|
1122
|
-
}
|
|
1123
|
-
|
|
1124
|
-
module.exports = GraphQLRange;
|