react-relay 0.0.0-main-c3ad9027 → 0.0.0-main-74926b6f
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/ReactRelayContext.js +1 -1
- package/hooks.js +1 -1
- package/index.js +1 -1
- package/legacy.js +1 -1
- package/lib/relay-hooks/FragmentResource.js +241 -45
- package/lib/relay-hooks/QueryResource.js +81 -2
- package/lib/relay-hooks/SuspenseResource.js +130 -0
- package/package.json +2 -2
- package/react-relay-hooks.js +2 -2
- package/react-relay-hooks.min.js +2 -2
- package/react-relay-legacy.js +1 -1
- package/react-relay-legacy.min.js +1 -1
- package/react-relay.js +2 -2
- package/react-relay.min.js +2 -2
- package/relay-hooks/FragmentResource.js.flow +202 -14
- package/relay-hooks/QueryResource.js.flow +110 -4
- package/relay-hooks/SuspenseResource.js.flow +115 -0
package/ReactRelayContext.js
CHANGED
package/hooks.js
CHANGED
package/index.js
CHANGED
package/legacy.js
CHANGED
@@ -15,19 +15,32 @@ var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefau
|
|
15
15
|
|
16
16
|
var _objectSpread2 = _interopRequireDefault(require("@babel/runtime/helpers/objectSpread2"));
|
17
17
|
|
18
|
+
var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty"));
|
19
|
+
|
18
20
|
var _toConsumableArray2 = _interopRequireDefault(require("@babel/runtime/helpers/toConsumableArray"));
|
19
21
|
|
20
22
|
var LRUCache = require('./LRUCache');
|
21
23
|
|
24
|
+
var _require = require('./QueryResource'),
|
25
|
+
getQueryResourceForEnvironment = _require.getQueryResourceForEnvironment;
|
26
|
+
|
27
|
+
var SuspenseResource = require('./SuspenseResource');
|
28
|
+
|
22
29
|
var invariant = require('invariant');
|
23
30
|
|
24
|
-
var
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
+
var _require2 = require('relay-runtime'),
|
32
|
+
RelayFeatureFlags = _require2.RelayFeatureFlags,
|
33
|
+
_require2$__internal = _require2.__internal,
|
34
|
+
fetchQuery = _require2$__internal.fetchQuery,
|
35
|
+
getPromiseForActiveRequest = _require2$__internal.getPromiseForActiveRequest,
|
36
|
+
createOperationDescriptor = _require2.createOperationDescriptor,
|
37
|
+
getFragmentIdentifier = _require2.getFragmentIdentifier,
|
38
|
+
getPendingOperationsForFragment = _require2.getPendingOperationsForFragment,
|
39
|
+
getSelector = _require2.getSelector,
|
40
|
+
getVariablesFromFragment = _require2.getVariablesFromFragment,
|
41
|
+
isPromise = _require2.isPromise,
|
42
|
+
recycleNodesInto = _require2.recycleNodesInto,
|
43
|
+
reportMissingRequiredFields = _require2.reportMissingRequiredFields;
|
31
44
|
|
32
45
|
var WEAKMAP_SUPPORTED = typeof WeakMap === 'function';
|
33
46
|
// TODO: Fix to not rely on LRU. If the number of active fragments exceeds this
|
@@ -47,6 +60,28 @@ function isMissingData(snapshot) {
|
|
47
60
|
return snapshot.isMissingData;
|
48
61
|
}
|
49
62
|
|
63
|
+
function hasMissingClientEdges(snapshot) {
|
64
|
+
var _snapshot$missingClie, _snapshot$missingClie2;
|
65
|
+
|
66
|
+
if (Array.isArray(snapshot)) {
|
67
|
+
return snapshot.some(function (s) {
|
68
|
+
var _s$missingClientEdges, _s$missingClientEdges2;
|
69
|
+
|
70
|
+
return ((_s$missingClientEdges = (_s$missingClientEdges2 = s.missingClientEdges) === null || _s$missingClientEdges2 === void 0 ? void 0 : _s$missingClientEdges2.length) !== null && _s$missingClientEdges !== void 0 ? _s$missingClientEdges : 0) > 0;
|
71
|
+
});
|
72
|
+
}
|
73
|
+
|
74
|
+
return ((_snapshot$missingClie = (_snapshot$missingClie2 = snapshot.missingClientEdges) === null || _snapshot$missingClie2 === void 0 ? void 0 : _snapshot$missingClie2.length) !== null && _snapshot$missingClie !== void 0 ? _snapshot$missingClie : 0) > 0;
|
75
|
+
}
|
76
|
+
|
77
|
+
function singularOrPluralForEach(snapshot, f) {
|
78
|
+
if (Array.isArray(snapshot)) {
|
79
|
+
snapshot.forEach(f);
|
80
|
+
} else {
|
81
|
+
f(snapshot);
|
82
|
+
}
|
83
|
+
}
|
84
|
+
|
50
85
|
function getFragmentResult(cacheKey, snapshot, storeEpoch) {
|
51
86
|
if (Array.isArray(snapshot)) {
|
52
87
|
return {
|
@@ -68,11 +103,90 @@ function getFragmentResult(cacheKey, snapshot, storeEpoch) {
|
|
68
103
|
storeEpoch: storeEpoch
|
69
104
|
};
|
70
105
|
}
|
106
|
+
/**
|
107
|
+
* The purpose of this cache is to allow information to be passed from an
|
108
|
+
* initial read which suspends through to the commit that follows a subsequent
|
109
|
+
* successful read. Specifically, the QueryResource result for the data fetch
|
110
|
+
* is passed through so that that query can be retained on commit.
|
111
|
+
*/
|
112
|
+
|
113
|
+
|
114
|
+
var ClientEdgeQueryResultsCache = /*#__PURE__*/function () {
|
115
|
+
function ClientEdgeQueryResultsCache(environment) {
|
116
|
+
(0, _defineProperty2["default"])(this, "_cache", new Map());
|
117
|
+
(0, _defineProperty2["default"])(this, "_retainCounts", new Map());
|
118
|
+
this._environment = environment;
|
119
|
+
}
|
120
|
+
|
121
|
+
var _proto = ClientEdgeQueryResultsCache.prototype;
|
122
|
+
|
123
|
+
_proto.get = function get(fragmentIdentifier) {
|
124
|
+
var _this$_cache$get$, _this$_cache$get;
|
125
|
+
|
126
|
+
return (_this$_cache$get$ = (_this$_cache$get = this._cache.get(fragmentIdentifier)) === null || _this$_cache$get === void 0 ? void 0 : _this$_cache$get[0]) !== null && _this$_cache$get$ !== void 0 ? _this$_cache$get$ : undefined;
|
127
|
+
};
|
128
|
+
|
129
|
+
_proto.recordQueryResults = function recordQueryResults(fragmentIdentifier, value) {
|
130
|
+
var _this = this;
|
131
|
+
|
132
|
+
var existing = this._cache.get(fragmentIdentifier);
|
133
|
+
|
134
|
+
if (!existing) {
|
135
|
+
var suspenseResource = new SuspenseResource(function () {
|
136
|
+
return _this._retain(fragmentIdentifier);
|
137
|
+
});
|
138
|
+
|
139
|
+
this._cache.set(fragmentIdentifier, [value, suspenseResource]);
|
140
|
+
|
141
|
+
suspenseResource.temporaryRetain(this._environment);
|
142
|
+
} else {
|
143
|
+
var existingResults = existing[0],
|
144
|
+
_suspenseResource = existing[1];
|
145
|
+
value.forEach(function (queryResult) {
|
146
|
+
existingResults.push(queryResult);
|
147
|
+
});
|
148
|
+
|
149
|
+
_suspenseResource.temporaryRetain(this._environment);
|
150
|
+
}
|
151
|
+
};
|
152
|
+
|
153
|
+
_proto._retain = function _retain(id) {
|
154
|
+
var _this2 = this;
|
155
|
+
|
156
|
+
var _this$_retainCounts$g;
|
157
|
+
|
158
|
+
var retainCount = ((_this$_retainCounts$g = this._retainCounts.get(id)) !== null && _this$_retainCounts$g !== void 0 ? _this$_retainCounts$g : 0) + 1;
|
159
|
+
|
160
|
+
this._retainCounts.set(id, retainCount);
|
161
|
+
|
162
|
+
return {
|
163
|
+
dispose: function dispose() {
|
164
|
+
var _this$_retainCounts$g2;
|
165
|
+
|
166
|
+
var newRetainCount = ((_this$_retainCounts$g2 = _this2._retainCounts.get(id)) !== null && _this$_retainCounts$g2 !== void 0 ? _this$_retainCounts$g2 : 0) - 1;
|
167
|
+
|
168
|
+
if (newRetainCount > 0) {
|
169
|
+
_this2._retainCounts.set(id, newRetainCount);
|
170
|
+
} else {
|
171
|
+
_this2._retainCounts["delete"](id);
|
172
|
+
|
173
|
+
_this2._cache["delete"](id);
|
174
|
+
}
|
175
|
+
}
|
176
|
+
};
|
177
|
+
};
|
178
|
+
|
179
|
+
return ClientEdgeQueryResultsCache;
|
180
|
+
}();
|
71
181
|
|
72
182
|
var FragmentResourceImpl = /*#__PURE__*/function () {
|
73
183
|
function FragmentResourceImpl(environment) {
|
74
184
|
this._environment = environment;
|
75
185
|
this._cache = LRUCache.create(CACHE_CAPACITY);
|
186
|
+
|
187
|
+
if (RelayFeatureFlags.ENABLE_CLIENT_EDGES) {
|
188
|
+
this._clientEdgeQueryResultsCache = new ClientEdgeQueryResultsCache(environment);
|
189
|
+
}
|
76
190
|
}
|
77
191
|
/**
|
78
192
|
* This function should be called during a Component's render function,
|
@@ -81,9 +195,9 @@ var FragmentResourceImpl = /*#__PURE__*/function () {
|
|
81
195
|
*/
|
82
196
|
|
83
197
|
|
84
|
-
var
|
198
|
+
var _proto2 = FragmentResourceImpl.prototype;
|
85
199
|
|
86
|
-
|
200
|
+
_proto2.read = function read(fragmentNode, fragmentRef, componentDisplayName, fragmentKey) {
|
87
201
|
return this.readWithIdentifier(fragmentNode, fragmentRef, getFragmentIdentifier(fragmentNode, fragmentRef), componentDisplayName, fragmentKey);
|
88
202
|
}
|
89
203
|
/**
|
@@ -93,8 +207,10 @@ var FragmentResourceImpl = /*#__PURE__*/function () {
|
|
93
207
|
*/
|
94
208
|
;
|
95
209
|
|
96
|
-
|
97
|
-
var
|
210
|
+
_proto2.readWithIdentifier = function readWithIdentifier(fragmentNode, fragmentRef, fragmentIdentifier, componentDisplayName, fragmentKey) {
|
211
|
+
var _this3 = this;
|
212
|
+
|
213
|
+
var _fragmentNode$metadat, _clientEdgePromises;
|
98
214
|
|
99
215
|
var environment = this._environment; // If fragmentRef is null or undefined, pass it directly through.
|
100
216
|
// This is a convenience when consuming fragments via a HOC API, when the
|
@@ -171,18 +287,67 @@ var FragmentResourceImpl = /*#__PURE__*/function () {
|
|
171
287
|
});
|
172
288
|
|
173
289
|
return fragmentResult;
|
174
|
-
} // 3. If we don't have data in the store,
|
175
|
-
//
|
176
|
-
//
|
177
|
-
//
|
178
|
-
//
|
290
|
+
} // 3. If we don't have data in the store, there's two cases where we should
|
291
|
+
// suspend to await the data: First if any client edges were traversed where
|
292
|
+
// the destination record was missing data; in that case we initiate a query
|
293
|
+
// here to fetch the missing data. Second, there may already be a request
|
294
|
+
// in flight for the fragment's parent query, or for another operation that
|
295
|
+
// may affect the parent's query data, such as a mutation or subscription.
|
296
|
+
// For any of these cases we can get a promise, which we will cache and
|
297
|
+
// suspend on.
|
298
|
+
// First, initiate a query for any client edges that were missing data:
|
299
|
+
|
300
|
+
|
301
|
+
var clientEdgeRequests = null;
|
302
|
+
|
303
|
+
if (RelayFeatureFlags.ENABLE_CLIENT_EDGES && hasMissingClientEdges(snapshot)) {
|
304
|
+
clientEdgeRequests = [];
|
305
|
+
var queryResource = getQueryResourceForEnvironment(this._environment);
|
306
|
+
var queryResults = [];
|
307
|
+
singularOrPluralForEach(snapshot, function (snap) {
|
308
|
+
var _snap$missingClientEd;
|
309
|
+
|
310
|
+
(_snap$missingClientEd = snap.missingClientEdges) === null || _snap$missingClientEd === void 0 ? void 0 : _snap$missingClientEd.forEach(function (_ref) {
|
311
|
+
var _clientEdgeRequests;
|
312
|
+
|
313
|
+
var request = _ref.request,
|
314
|
+
clientEdgeDestinationID = _ref.clientEdgeDestinationID;
|
315
|
+
|
316
|
+
var _this3$_performClient = _this3._performClientEdgeQuery(queryResource, fragmentNode, fragmentRef, request, clientEdgeDestinationID),
|
317
|
+
queryResult = _this3$_performClient.queryResult,
|
318
|
+
requestDescriptor = _this3$_performClient.requestDescriptor;
|
319
|
+
|
320
|
+
queryResults.push(queryResult);
|
321
|
+
(_clientEdgeRequests = clientEdgeRequests) === null || _clientEdgeRequests === void 0 ? void 0 : _clientEdgeRequests.push(requestDescriptor);
|
322
|
+
});
|
323
|
+
}); // Store the query so that it can be retained when our own fragment is
|
324
|
+
// subscribed to. This merges with any existing query results:
|
325
|
+
|
326
|
+
!(this._clientEdgeQueryResultsCache != null) ? process.env.NODE_ENV !== "production" ? invariant(false, 'Client edge query result cache should exist when ENABLE_CLIENT_EDGES is on.') : invariant(false) : void 0;
|
327
|
+
|
328
|
+
this._clientEdgeQueryResultsCache.recordQueryResults(fragmentIdentifier, queryResults);
|
329
|
+
}
|
330
|
+
|
331
|
+
var clientEdgePromises = null;
|
332
|
+
|
333
|
+
if (RelayFeatureFlags.ENABLE_CLIENT_EDGES && clientEdgeRequests) {
|
334
|
+
clientEdgePromises = clientEdgeRequests.map(function (request) {
|
335
|
+
return getPromiseForActiveRequest(_this3._environment, request);
|
336
|
+
}).filter(function (p) {
|
337
|
+
return p != null;
|
338
|
+
});
|
339
|
+
} // Finally look for operations in flight for our parent query:
|
179
340
|
|
180
341
|
|
181
342
|
var fragmentOwner = fragmentSelector.kind === 'PluralReaderSelector' ? fragmentSelector.selectors[0].owner : fragmentSelector.owner;
|
182
343
|
|
183
|
-
var
|
344
|
+
var parentQueryPromiseResult = this._getAndSavePromiseForFragmentRequestInFlight(fragmentIdentifier, fragmentNode, fragmentOwner, fragmentResult);
|
345
|
+
|
346
|
+
var parentQueryPromiseResultPromise = parentQueryPromiseResult === null || parentQueryPromiseResult === void 0 ? void 0 : parentQueryPromiseResult.promise; // for refinement
|
347
|
+
|
348
|
+
if (((_clientEdgePromises = clientEdgePromises) === null || _clientEdgePromises === void 0 ? void 0 : _clientEdgePromises.length) || isPromise(parentQueryPromiseResultPromise)) {
|
349
|
+
var _parentQueryPromiseRe, _clientEdgeRequests2, _clientEdgePromises2;
|
184
350
|
|
185
|
-
if (networkPromiseResult != null && isPromise(networkPromiseResult.promise)) {
|
186
351
|
environment.__log({
|
187
352
|
name: 'suspense.fragment',
|
188
353
|
data: fragmentResult.data,
|
@@ -190,10 +355,10 @@ var FragmentResourceImpl = /*#__PURE__*/function () {
|
|
190
355
|
isRelayHooks: true,
|
191
356
|
isPromiseCached: false,
|
192
357
|
isMissingData: fragmentResult.isMissingData,
|
193
|
-
pendingOperations:
|
358
|
+
pendingOperations: [].concat((0, _toConsumableArray2["default"])((_parentQueryPromiseRe = parentQueryPromiseResult === null || parentQueryPromiseResult === void 0 ? void 0 : parentQueryPromiseResult.pendingOperations) !== null && _parentQueryPromiseRe !== void 0 ? _parentQueryPromiseRe : []), (0, _toConsumableArray2["default"])((_clientEdgeRequests2 = clientEdgeRequests) !== null && _clientEdgeRequests2 !== void 0 ? _clientEdgeRequests2 : []))
|
194
359
|
});
|
195
360
|
|
196
|
-
throw
|
361
|
+
throw ((_clientEdgePromises2 = clientEdgePromises) === null || _clientEdgePromises2 === void 0 ? void 0 : _clientEdgePromises2.length) ? Promise.all([parentQueryPromiseResultPromise].concat((0, _toConsumableArray2["default"])(clientEdgePromises))) : parentQueryPromiseResultPromise;
|
197
362
|
}
|
198
363
|
|
199
364
|
this._reportMissingRequiredFieldsInSnapshot(snapshot);
|
@@ -201,13 +366,30 @@ var FragmentResourceImpl = /*#__PURE__*/function () {
|
|
201
366
|
return getFragmentResult(fragmentIdentifier, snapshot, storeEpoch);
|
202
367
|
};
|
203
368
|
|
204
|
-
|
205
|
-
var
|
369
|
+
_proto2._performClientEdgeQuery = function _performClientEdgeQuery(queryResource, fragmentNode, fragmentRef, request, clientEdgeDestinationID) {
|
370
|
+
var originalVariables = getVariablesFromFragment(fragmentNode, fragmentRef);
|
371
|
+
var variables = (0, _objectSpread2["default"])((0, _objectSpread2["default"])({}, originalVariables), {}, {
|
372
|
+
id: clientEdgeDestinationID // TODO should be a reserved name
|
373
|
+
|
374
|
+
});
|
375
|
+
var operation = createOperationDescriptor(request, variables, {} // TODO cacheConfig should probably inherent from parent operation
|
376
|
+
);
|
377
|
+
var fetchObservable = fetchQuery(this._environment, operation);
|
378
|
+
var queryResult = queryResource.prepare(operation, fetchObservable // TODO should inherent render policy etc. from parent operation
|
379
|
+
);
|
380
|
+
return {
|
381
|
+
requestDescriptor: operation.request,
|
382
|
+
queryResult: queryResult
|
383
|
+
};
|
384
|
+
};
|
385
|
+
|
386
|
+
_proto2._reportMissingRequiredFieldsInSnapshot = function _reportMissingRequiredFieldsInSnapshot(snapshot) {
|
387
|
+
var _this4 = this;
|
206
388
|
|
207
389
|
if (Array.isArray(snapshot)) {
|
208
390
|
snapshot.forEach(function (s) {
|
209
391
|
if (s.missingRequiredFields != null) {
|
210
|
-
reportMissingRequiredFields(
|
392
|
+
reportMissingRequiredFields(_this4._environment, s.missingRequiredFields);
|
211
393
|
}
|
212
394
|
});
|
213
395
|
} else {
|
@@ -217,7 +399,7 @@ var FragmentResourceImpl = /*#__PURE__*/function () {
|
|
217
399
|
}
|
218
400
|
};
|
219
401
|
|
220
|
-
|
402
|
+
_proto2.readSpec = function readSpec(fragmentNodes, fragmentRefs, componentDisplayName) {
|
221
403
|
var result = {};
|
222
404
|
|
223
405
|
for (var _key in fragmentNodes) {
|
@@ -227,8 +409,8 @@ var FragmentResourceImpl = /*#__PURE__*/function () {
|
|
227
409
|
return result;
|
228
410
|
};
|
229
411
|
|
230
|
-
|
231
|
-
var
|
412
|
+
_proto2.subscribe = function subscribe(fragmentResult, callback) {
|
413
|
+
var _this5 = this;
|
232
414
|
|
233
415
|
var environment = this._environment;
|
234
416
|
var cacheKey = fragmentResult.cacheKey;
|
@@ -253,25 +435,25 @@ var FragmentResourceImpl = /*#__PURE__*/function () {
|
|
253
435
|
} // 3. Establish subscriptions on the snapshot(s)
|
254
436
|
|
255
437
|
|
256
|
-
var
|
438
|
+
var disposables = [];
|
257
439
|
|
258
440
|
if (Array.isArray(renderedSnapshot)) {
|
259
441
|
!Array.isArray(currentSnapshot) ? process.env.NODE_ENV !== "production" ? invariant(false, 'Relay: Expected snapshots to be plural. ' + "If you're seeing this, this is likely a bug in Relay.") : invariant(false) : void 0;
|
260
442
|
currentSnapshot.forEach(function (snapshot, idx) {
|
261
|
-
|
443
|
+
disposables.push(environment.subscribe(snapshot, function (latestSnapshot) {
|
262
444
|
var storeEpoch = environment.getStore().getEpoch();
|
263
445
|
|
264
|
-
|
446
|
+
_this5._updatePluralSnapshot(cacheKey, currentSnapshot, latestSnapshot, idx, storeEpoch);
|
265
447
|
|
266
448
|
callback();
|
267
449
|
}));
|
268
450
|
});
|
269
451
|
} else {
|
270
452
|
!(currentSnapshot != null && !Array.isArray(currentSnapshot)) ? process.env.NODE_ENV !== "production" ? invariant(false, 'Relay: Expected snapshot to be singular. ' + "If you're seeing this, this is likely a bug in Relay.") : invariant(false) : void 0;
|
271
|
-
|
453
|
+
disposables.push(environment.subscribe(currentSnapshot, function (latestSnapshot) {
|
272
454
|
var storeEpoch = environment.getStore().getEpoch();
|
273
455
|
|
274
|
-
|
456
|
+
_this5._cache.set(cacheKey, {
|
275
457
|
kind: 'done',
|
276
458
|
result: getFragmentResult(cacheKey, latestSnapshot, storeEpoch)
|
277
459
|
});
|
@@ -280,22 +462,35 @@ var FragmentResourceImpl = /*#__PURE__*/function () {
|
|
280
462
|
}));
|
281
463
|
}
|
282
464
|
|
465
|
+
if (RelayFeatureFlags.ENABLE_CLIENT_EDGES) {
|
466
|
+
var _this$_clientEdgeQuer, _this$_clientEdgeQuer2;
|
467
|
+
|
468
|
+
var clientEdgeQueryResults = (_this$_clientEdgeQuer = (_this$_clientEdgeQuer2 = this._clientEdgeQueryResultsCache) === null || _this$_clientEdgeQuer2 === void 0 ? void 0 : _this$_clientEdgeQuer2.get(cacheKey)) !== null && _this$_clientEdgeQuer !== void 0 ? _this$_clientEdgeQuer : undefined;
|
469
|
+
|
470
|
+
if (clientEdgeQueryResults === null || clientEdgeQueryResults === void 0 ? void 0 : clientEdgeQueryResults.length) {
|
471
|
+
var queryResource = getQueryResourceForEnvironment(this._environment);
|
472
|
+
clientEdgeQueryResults.forEach(function (queryResult) {
|
473
|
+
disposables.push(queryResource.retain(queryResult));
|
474
|
+
});
|
475
|
+
}
|
476
|
+
}
|
477
|
+
|
283
478
|
return {
|
284
479
|
dispose: function dispose() {
|
285
|
-
|
480
|
+
disposables.forEach(function (s) {
|
286
481
|
return s.dispose();
|
287
482
|
});
|
288
483
|
|
289
|
-
|
484
|
+
_this5._cache["delete"](cacheKey);
|
290
485
|
}
|
291
486
|
};
|
292
487
|
};
|
293
488
|
|
294
|
-
|
295
|
-
var
|
489
|
+
_proto2.subscribeSpec = function subscribeSpec(fragmentResults, callback) {
|
490
|
+
var _this6 = this;
|
296
491
|
|
297
492
|
var disposables = Object.keys(fragmentResults).map(function (key) {
|
298
|
-
return
|
493
|
+
return _this6.subscribe(fragmentResults[key], callback);
|
299
494
|
});
|
300
495
|
return {
|
301
496
|
dispose: function dispose() {
|
@@ -306,7 +501,7 @@ var FragmentResourceImpl = /*#__PURE__*/function () {
|
|
306
501
|
};
|
307
502
|
};
|
308
503
|
|
309
|
-
|
504
|
+
_proto2.checkMissedUpdates = function checkMissedUpdates(fragmentResult) {
|
310
505
|
var environment = this._environment;
|
311
506
|
var renderedSnapshot = fragmentResult.snapshot;
|
312
507
|
|
@@ -361,6 +556,7 @@ var FragmentResourceImpl = /*#__PURE__*/function () {
|
|
361
556
|
var updatedCurrentSnapshot = {
|
362
557
|
data: updatedData,
|
363
558
|
isMissingData: currentSnapshot.isMissingData,
|
559
|
+
missingClientEdges: currentSnapshot.missingClientEdges,
|
364
560
|
seenRecords: currentSnapshot.seenRecords,
|
365
561
|
selector: currentSnapshot.selector,
|
366
562
|
missingRequiredFields: currentSnapshot.missingRequiredFields
|
@@ -376,16 +572,16 @@ var FragmentResourceImpl = /*#__PURE__*/function () {
|
|
376
572
|
return [updatedData !== renderData, updatedCurrentSnapshot];
|
377
573
|
};
|
378
574
|
|
379
|
-
|
380
|
-
var
|
575
|
+
_proto2.checkMissedUpdatesSpec = function checkMissedUpdatesSpec(fragmentResults) {
|
576
|
+
var _this7 = this;
|
381
577
|
|
382
578
|
return Object.keys(fragmentResults).some(function (key) {
|
383
|
-
return
|
579
|
+
return _this7.checkMissedUpdates(fragmentResults[key])[0];
|
384
580
|
});
|
385
581
|
};
|
386
582
|
|
387
|
-
|
388
|
-
var
|
583
|
+
_proto2._getAndSavePromiseForFragmentRequestInFlight = function _getAndSavePromiseForFragmentRequestInFlight(cacheKey, fragmentNode, fragmentOwner, fragmentResult) {
|
584
|
+
var _this8 = this;
|
389
585
|
|
390
586
|
var pendingOperationsResult = getPendingOperationsForFragment(this._environment, fragmentNode, fragmentOwner);
|
391
587
|
|
@@ -399,9 +595,9 @@ var FragmentResourceImpl = /*#__PURE__*/function () {
|
|
399
595
|
var networkPromise = pendingOperationsResult.promise;
|
400
596
|
var pendingOperations = pendingOperationsResult.pendingOperations;
|
401
597
|
var promise = networkPromise.then(function () {
|
402
|
-
|
598
|
+
_this8._cache["delete"](cacheKey);
|
403
599
|
})["catch"](function (error) {
|
404
|
-
|
600
|
+
_this8._cache["delete"](cacheKey);
|
405
601
|
}); // $FlowExpectedError[prop-missing] Expando to annotate Promises.
|
406
602
|
|
407
603
|
promise.displayName = networkPromise.displayName;
|
@@ -419,7 +615,7 @@ var FragmentResourceImpl = /*#__PURE__*/function () {
|
|
419
615
|
};
|
420
616
|
};
|
421
617
|
|
422
|
-
|
618
|
+
_proto2._updatePluralSnapshot = function _updatePluralSnapshot(cacheKey, baseSnapshots, latestSnapshot, idx, storeEpoch) {
|
423
619
|
var _currentFragmentResul;
|
424
620
|
|
425
621
|
var currentFragmentResult = this._cache.get(cacheKey);
|
@@ -19,16 +19,18 @@ var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/de
|
|
19
19
|
|
20
20
|
var LRUCache = require('./LRUCache');
|
21
21
|
|
22
|
+
var SuspenseResource = require('./SuspenseResource');
|
23
|
+
|
22
24
|
var invariant = require('invariant');
|
23
25
|
|
24
26
|
var _require = require('relay-runtime'),
|
27
|
+
RelayFeatureFlags = _require.RelayFeatureFlags,
|
25
28
|
isPromise = _require.isPromise;
|
26
29
|
|
27
30
|
var warning = require("fbjs/lib/warning");
|
28
31
|
|
29
32
|
var CACHE_CAPACITY = 1000;
|
30
33
|
var DEFAULT_FETCH_POLICY = 'store-or-network';
|
31
|
-
var DATA_RETENTION_TIMEOUT = 5 * 60 * 1000;
|
32
34
|
var WEAKMAP_SUPPORTED = typeof WeakMap === 'function';
|
33
35
|
|
34
36
|
function operationIsLiveQuery(operation) {
|
@@ -64,6 +66,77 @@ function getQueryResult(operation, cacheIdentifier) {
|
|
64
66
|
var nextID = 200000;
|
65
67
|
|
66
68
|
function createCacheEntry(cacheIdentifier, operation, operationAvailability, value, networkSubscription, onDispose) {
|
69
|
+
// There should be no behavior difference between createCacheEntry_new and
|
70
|
+
// createCacheEntry_old, and it doesn't directly relate to Client Edges.
|
71
|
+
// It was just a refactoring that was needed for Client Edges but that
|
72
|
+
// is behind the feature flag just in case there is any accidental breakage.
|
73
|
+
if (RelayFeatureFlags.REFACTOR_SUSPENSE_RESOURCE) {
|
74
|
+
return createCacheEntry_new(cacheIdentifier, operation, operationAvailability, value, networkSubscription, onDispose);
|
75
|
+
} else {
|
76
|
+
return createCacheEntry_old(cacheIdentifier, operation, operationAvailability, value, networkSubscription, onDispose);
|
77
|
+
}
|
78
|
+
}
|
79
|
+
|
80
|
+
function createCacheEntry_new(cacheIdentifier, operation, operationAvailability, value, networkSubscription, onDispose) {
|
81
|
+
var isLiveQuery = operationIsLiveQuery(operation);
|
82
|
+
var currentValue = value;
|
83
|
+
var currentNetworkSubscription = networkSubscription;
|
84
|
+
var suspenseResource = new SuspenseResource(function (environment) {
|
85
|
+
var retention = environment.retain(operation);
|
86
|
+
return {
|
87
|
+
dispose: function dispose() {
|
88
|
+
// Normally if this entry never commits, the request would've ended by the
|
89
|
+
// time this timeout expires and the temporary retain is released. However,
|
90
|
+
// we need to do this for live queries which remain open indefinitely.
|
91
|
+
if (isLiveQuery && currentNetworkSubscription != null) {
|
92
|
+
currentNetworkSubscription.unsubscribe();
|
93
|
+
}
|
94
|
+
|
95
|
+
retention.dispose();
|
96
|
+
onDispose(cacheEntry);
|
97
|
+
}
|
98
|
+
};
|
99
|
+
});
|
100
|
+
var cacheEntry = {
|
101
|
+
cacheIdentifier: cacheIdentifier,
|
102
|
+
id: nextID++,
|
103
|
+
processedPayloadsCount: 0,
|
104
|
+
operationAvailability: operationAvailability,
|
105
|
+
getValue: function getValue() {
|
106
|
+
return currentValue;
|
107
|
+
},
|
108
|
+
setValue: function setValue(val) {
|
109
|
+
currentValue = val;
|
110
|
+
},
|
111
|
+
getRetainCount: function getRetainCount() {
|
112
|
+
return suspenseResource.getRetainCount();
|
113
|
+
},
|
114
|
+
getNetworkSubscription: function getNetworkSubscription() {
|
115
|
+
return currentNetworkSubscription;
|
116
|
+
},
|
117
|
+
setNetworkSubscription: function setNetworkSubscription(subscription) {
|
118
|
+
if (isLiveQuery && currentNetworkSubscription != null) {
|
119
|
+
currentNetworkSubscription.unsubscribe();
|
120
|
+
}
|
121
|
+
|
122
|
+
currentNetworkSubscription = subscription;
|
123
|
+
},
|
124
|
+
temporaryRetain: function temporaryRetain(environment) {
|
125
|
+
return suspenseResource.temporaryRetain(environment);
|
126
|
+
},
|
127
|
+
permanentRetain: function permanentRetain(environment) {
|
128
|
+
return suspenseResource.permanentRetain(environment);
|
129
|
+
},
|
130
|
+
releaseTemporaryRetain: function releaseTemporaryRetain() {
|
131
|
+
suspenseResource.releaseTemporaryRetain();
|
132
|
+
}
|
133
|
+
};
|
134
|
+
return cacheEntry;
|
135
|
+
}
|
136
|
+
|
137
|
+
var DATA_RETENTION_TIMEOUT = 5 * 60 * 1000;
|
138
|
+
|
139
|
+
function createCacheEntry_old(cacheIdentifier, operation, operationAvailability, value, networkSubscription, onDispose) {
|
67
140
|
var isLiveQuery = operationIsLiveQuery(operation);
|
68
141
|
var currentValue = value;
|
69
142
|
var retainCount = 0;
|
@@ -202,8 +275,14 @@ var QueryResourceImpl = /*#__PURE__*/function () {
|
|
202
275
|
var _this = this;
|
203
276
|
|
204
277
|
(0, _defineProperty2["default"])(this, "_clearCacheEntry", function (cacheEntry) {
|
205
|
-
|
278
|
+
// The new code does this retainCount <= 0 check within SuspenseResource
|
279
|
+
// before calling _clearCacheEntry, whereas with the old code we do it here.
|
280
|
+
if (RelayFeatureFlags.REFACTOR_SUSPENSE_RESOURCE) {
|
206
281
|
_this._cache["delete"](cacheEntry.cacheIdentifier);
|
282
|
+
} else {
|
283
|
+
if (cacheEntry.getRetainCount() <= 0) {
|
284
|
+
_this._cache["delete"](cacheEntry.cacheIdentifier);
|
285
|
+
}
|
207
286
|
}
|
208
287
|
});
|
209
288
|
this._environment = environment;
|