relay-runtime 7.0.0 → 9.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/handlers/RelayDefaultHandlerProvider.js.flow +34 -0
- package/handlers/connection/ConnectionHandler.js.flow +549 -0
- package/handlers/connection/ConnectionInterface.js.flow +92 -0
- package/index.js +1 -1
- package/index.js.flow +314 -0
- package/lib/handlers/RelayDefaultHandlerProvider.js +3 -2
- package/lib/handlers/connection/{RelayConnectionHandler.js → ConnectionHandler.js} +34 -35
- package/lib/handlers/connection/{RelayConnectionInterface.js → ConnectionInterface.js} +3 -30
- package/lib/index.js +29 -27
- package/lib/mutations/RelayDeclarativeMutationConfig.js +30 -52
- package/lib/mutations/RelayRecordProxy.js +6 -3
- package/lib/mutations/RelayRecordSourceMutator.js +3 -9
- package/lib/mutations/RelayRecordSourceProxy.js +21 -24
- package/lib/mutations/RelayRecordSourceSelectorProxy.js +18 -14
- package/lib/mutations/applyOptimisticMutation.js +2 -1
- package/lib/mutations/commitLocalUpdate.js +1 -0
- package/lib/mutations/commitMutation.js +26 -8
- package/lib/mutations/validateMutation.js +21 -11
- package/lib/network/ConvertToExecuteFunction.js +1 -0
- package/lib/network/RelayNetwork.js +1 -0
- package/lib/network/RelayNetworkTypes.js +1 -0
- package/lib/network/RelayObservable.js +10 -9
- package/lib/network/RelayQueryResponseCache.js +9 -7
- package/lib/query/{RelayModernGraphQLTag.js → GraphQLTag.js} +15 -8
- package/lib/query/fetchQuery.js +2 -1
- package/lib/query/fetchQueryInternal.js +30 -20
- package/lib/store/ClientID.js +1 -0
- package/lib/store/DataChecker.js +47 -97
- package/lib/store/RelayConcreteVariables.js +7 -2
- package/lib/store/RelayModernEnvironment.js +82 -41
- package/lib/store/RelayModernFragmentSpecResolver.js +61 -21
- package/lib/store/RelayModernOperationDescriptor.js +2 -1
- package/lib/store/RelayModernQueryExecutor.js +476 -333
- package/lib/store/RelayModernRecord.js +39 -9
- package/lib/store/RelayModernSelector.js +2 -1
- package/lib/store/RelayModernStore.js +359 -371
- package/lib/store/RelayOperationTracker.js +36 -78
- package/lib/store/RelayOptimisticRecordSource.js +8 -5
- package/lib/store/RelayPublishQueue.js +66 -53
- package/lib/store/RelayReader.js +2 -24
- package/lib/store/RelayRecordSource.js +3 -9
- package/lib/store/RelayRecordSourceMapImpl.js +14 -18
- package/lib/store/RelayRecordState.js +1 -0
- package/lib/store/RelayReferenceMarker.js +8 -58
- package/lib/store/RelayResponseNormalizer.js +15 -144
- package/lib/store/RelayStoreTypes.js +1 -0
- package/lib/store/RelayStoreUtils.js +34 -10
- package/lib/store/StoreInspector.js +11 -5
- package/lib/store/ViewerPattern.js +1 -0
- package/lib/store/cloneRelayHandleSourceField.js +1 -0
- package/lib/store/createFragmentSpecResolver.js +1 -0
- package/lib/store/createRelayContext.js +1 -0
- package/lib/store/defaultGetDataID.js +1 -0
- package/lib/store/hasOverlappingIDs.js +1 -0
- package/lib/store/isRelayModernEnvironment.js +1 -0
- package/lib/store/normalizeRelayPayload.js +8 -4
- package/lib/store/readInlineData.js +2 -1
- package/lib/subscription/requestSubscription.js +6 -3
- package/lib/util/JSResourceTypes.flow.js +12 -0
- package/lib/util/NormalizationNode.js +1 -0
- package/lib/util/ReaderNode.js +1 -0
- package/lib/util/RelayConcreteNode.js +3 -0
- package/lib/util/RelayDefaultHandleKey.js +1 -0
- package/lib/util/RelayError.js +2 -1
- package/lib/util/RelayFeatureFlags.js +3 -2
- package/lib/util/RelayProfiler.js +1 -0
- package/lib/util/RelayReplaySubject.js +2 -3
- package/lib/util/RelayRuntimeTypes.js +1 -0
- package/lib/util/createPayloadFor3DField.js +34 -0
- package/lib/util/deepFreeze.js +1 -0
- package/lib/util/generateID.js +1 -0
- package/lib/util/getFragmentIdentifier.js +1 -0
- package/lib/util/getRelayHandleKey.js +1 -0
- package/lib/util/getRequestIdentifier.js +1 -0
- package/lib/util/isPromise.js +1 -0
- package/lib/util/isScalarAndEqual.js +1 -0
- package/lib/util/recycleNodesInto.js +1 -0
- package/lib/util/resolveImmediate.js +1 -0
- package/lib/util/stableCopy.js +1 -0
- package/mutations/RelayDeclarativeMutationConfig.js.flow +380 -0
- package/mutations/RelayRecordProxy.js.flow +165 -0
- package/mutations/RelayRecordSourceMutator.js.flow +238 -0
- package/mutations/RelayRecordSourceProxy.js.flow +164 -0
- package/mutations/RelayRecordSourceSelectorProxy.js.flow +119 -0
- package/mutations/applyOptimisticMutation.js.flow +76 -0
- package/mutations/commitLocalUpdate.js.flow +24 -0
- package/mutations/commitMutation.js.flow +184 -0
- package/mutations/validateMutation.js.flow +211 -0
- package/network/ConvertToExecuteFunction.js.flow +49 -0
- package/network/RelayNetwork.js.flow +84 -0
- package/network/RelayNetworkTypes.js.flow +123 -0
- package/network/RelayObservable.js.flow +634 -0
- package/network/RelayQueryResponseCache.js.flow +111 -0
- package/package.json +1 -1
- package/query/GraphQLTag.js.flow +166 -0
- package/query/fetchQuery.js.flow +47 -0
- package/query/fetchQueryInternal.js.flow +349 -0
- package/relay-runtime.js +2 -2
- package/relay-runtime.min.js +2 -2
- package/store/ClientID.js.flow +43 -0
- package/store/DataChecker.js.flow +426 -0
- package/store/RelayConcreteVariables.js.flow +96 -0
- package/store/RelayModernEnvironment.js.flow +526 -0
- package/store/RelayModernFragmentSpecResolver.js.flow +426 -0
- package/store/RelayModernOperationDescriptor.js.flow +88 -0
- package/store/RelayModernQueryExecutor.js.flow +1327 -0
- package/store/RelayModernRecord.js.flow +403 -0
- package/store/RelayModernSelector.js.flow +444 -0
- package/store/RelayModernStore.js.flow +757 -0
- package/store/RelayOperationTracker.js.flow +164 -0
- package/store/RelayOptimisticRecordSource.js.flow +119 -0
- package/store/RelayPublishQueue.js.flow +401 -0
- package/store/RelayReader.js.flow +376 -0
- package/store/RelayRecordSource.js.flow +29 -0
- package/store/RelayRecordSourceMapImpl.js.flow +87 -0
- package/store/RelayRecordState.js.flow +37 -0
- package/store/RelayReferenceMarker.js.flow +236 -0
- package/store/RelayResponseNormalizer.js.flow +556 -0
- package/store/RelayStoreTypes.js.flow +873 -0
- package/store/RelayStoreUtils.js.flow +218 -0
- package/store/StoreInspector.js.flow +173 -0
- package/store/ViewerPattern.js.flow +26 -0
- package/store/cloneRelayHandleSourceField.js.flow +66 -0
- package/store/createFragmentSpecResolver.js.flow +55 -0
- package/store/createRelayContext.js.flow +44 -0
- package/store/defaultGetDataID.js.flow +27 -0
- package/store/hasOverlappingIDs.js.flow +34 -0
- package/store/isRelayModernEnvironment.js.flow +27 -0
- package/store/normalizeRelayPayload.js.flow +51 -0
- package/store/readInlineData.js.flow +75 -0
- package/subscription/requestSubscription.js.flow +100 -0
- package/util/JSResourceTypes.flow.js.flow +20 -0
- package/util/NormalizationNode.js.flow +191 -0
- package/util/ReaderNode.js.flow +208 -0
- package/util/RelayConcreteNode.js.flow +80 -0
- package/util/RelayDefaultHandleKey.js.flow +17 -0
- package/util/RelayError.js.flow +33 -0
- package/util/RelayFeatureFlags.js.flow +30 -0
- package/util/RelayProfiler.js.flow +284 -0
- package/util/RelayReplaySubject.js.flow +134 -0
- package/util/RelayRuntimeTypes.js.flow +70 -0
- package/util/createPayloadFor3DField.js.flow +43 -0
- package/util/deepFreeze.js.flow +36 -0
- package/util/generateID.js.flow +21 -0
- package/util/getFragmentIdentifier.js.flow +52 -0
- package/util/getRelayHandleKey.js.flow +41 -0
- package/util/getRequestIdentifier.js.flow +41 -0
- package/util/isPromise.js.flow +21 -0
- package/util/isScalarAndEqual.js.flow +26 -0
- package/util/recycleNodesInto.js.flow +80 -0
- package/util/resolveImmediate.js.flow +30 -0
- package/util/stableCopy.js.flow +35 -0
- package/lib/handlers/RelayDefaultMissingFieldHandlers.js +0 -26
- package/lib/store/RelayConnection.js +0 -36
- package/lib/store/RelayConnectionResolver.js +0 -177
- package/lib/store/RelayRecordSourceObjectImpl.js +0 -78
- package/lib/util/getFragmentSpecIdentifier.js +0 -26
|
@@ -7,15 +7,16 @@
|
|
|
7
7
|
*
|
|
8
8
|
* @format
|
|
9
9
|
*/
|
|
10
|
+
// flowlint ambiguous-object-type:error
|
|
10
11
|
'use strict';
|
|
11
12
|
|
|
12
|
-
var
|
|
13
|
+
function _createForOfIteratorHelper(o) { if (typeof Symbol === "undefined" || o[Symbol.iterator] == null) { if (Array.isArray(o) || (o = _unsupportedIterableToArray(o))) { var i = 0; var F = function F() {}; return { s: F, n: function n() { if (i >= o.length) return { done: true }; return { done: false, value: o[i++] }; }, e: function e(_e) { throw _e; }, f: F }; } throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); } var it, normalCompletion = true, didErr = false, err; return { s: function s() { it = o[Symbol.iterator](); }, n: function n() { var step = it.next(); normalCompletion = step.done; return step; }, e: function e(_e2) { didErr = true; err = _e2; }, f: function f() { try { if (!normalCompletion && it["return"] != null) it["return"](); } finally { if (didErr) throw err; } } }; }
|
|
13
14
|
|
|
14
|
-
var
|
|
15
|
+
function _unsupportedIterableToArray(o, minLen) { if (!o) return; if (typeof o === "string") return _arrayLikeToArray(o, minLen); var n = Object.prototype.toString.call(o).slice(8, -1); if (n === "Object" && o.constructor) n = o.constructor.name; if (n === "Map" || n === "Set") return Array.from(n); if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen); }
|
|
15
16
|
|
|
16
|
-
var
|
|
17
|
+
function _arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len = arr.length; for (var i = 0, arr2 = new Array(len); i < len; i++) { arr2[i] = arr[i]; } return arr2; }
|
|
17
18
|
|
|
18
|
-
var
|
|
19
|
+
var DataChecker = require('./DataChecker');
|
|
19
20
|
|
|
20
21
|
var RelayModernRecord = require('./RelayModernRecord');
|
|
21
22
|
|
|
@@ -27,6 +28,8 @@ var RelayReader = require('./RelayReader');
|
|
|
27
28
|
|
|
28
29
|
var RelayReferenceMarker = require('./RelayReferenceMarker');
|
|
29
30
|
|
|
31
|
+
var RelayStoreUtils = require('./RelayStoreUtils');
|
|
32
|
+
|
|
30
33
|
var deepFreeze = require('../util/deepFreeze');
|
|
31
34
|
|
|
32
35
|
var defaultGetDataID = require('./defaultGetDataID');
|
|
@@ -39,8 +42,9 @@ var recycleNodesInto = require('../util/recycleNodesInto');
|
|
|
39
42
|
|
|
40
43
|
var resolveImmediate = require('../util/resolveImmediate');
|
|
41
44
|
|
|
42
|
-
var _require = require('./
|
|
43
|
-
|
|
45
|
+
var _require = require('./RelayStoreUtils'),
|
|
46
|
+
ROOT_ID = _require.ROOT_ID,
|
|
47
|
+
ROOT_TYPE = _require.ROOT_TYPE;
|
|
44
48
|
|
|
45
49
|
var DEFAULT_RELEASE_BUFFER_SIZE = 0;
|
|
46
50
|
/**
|
|
@@ -56,11 +60,9 @@ var DEFAULT_RELEASE_BUFFER_SIZE = 0;
|
|
|
56
60
|
* is also enforced in development mode by freezing all records passed to a store.
|
|
57
61
|
*/
|
|
58
62
|
|
|
59
|
-
var RelayModernStore =
|
|
60
|
-
/*#__PURE__*/
|
|
61
|
-
function () {
|
|
63
|
+
var RelayModernStore = /*#__PURE__*/function () {
|
|
62
64
|
function RelayModernStore(source, options) {
|
|
63
|
-
var
|
|
65
|
+
var _options$gcReleaseBuf, _options$gcScheduler, _options$UNSTABLE_DO_, _options$operationLoa;
|
|
64
66
|
|
|
65
67
|
// Prevent mutation of a record from outside the store.
|
|
66
68
|
if (process.env.NODE_ENV !== "production") {
|
|
@@ -75,23 +77,26 @@ function () {
|
|
|
75
77
|
}
|
|
76
78
|
}
|
|
77
79
|
|
|
78
|
-
this.
|
|
79
|
-
this._connectionSubscriptions = new Map();
|
|
80
|
+
this._currentWriteEpoch = 0;
|
|
80
81
|
this._gcHoldCounter = 0;
|
|
81
|
-
this._gcReleaseBufferSize = (
|
|
82
|
-
this._gcScheduler = (
|
|
83
|
-
this._getDataID = (
|
|
82
|
+
this._gcReleaseBufferSize = (_options$gcReleaseBuf = options === null || options === void 0 ? void 0 : options.gcReleaseBufferSize) !== null && _options$gcReleaseBuf !== void 0 ? _options$gcReleaseBuf : DEFAULT_RELEASE_BUFFER_SIZE;
|
|
83
|
+
this._gcScheduler = (_options$gcScheduler = options === null || options === void 0 ? void 0 : options.gcScheduler) !== null && _options$gcScheduler !== void 0 ? _options$gcScheduler : resolveImmediate;
|
|
84
|
+
this._getDataID = (_options$UNSTABLE_DO_ = options === null || options === void 0 ? void 0 : options.UNSTABLE_DO_NOT_USE_getDataID) !== null && _options$UNSTABLE_DO_ !== void 0 ? _options$UNSTABLE_DO_ : defaultGetDataID;
|
|
85
|
+
this._globalInvalidationEpoch = null;
|
|
84
86
|
this._hasScheduledGC = false;
|
|
85
87
|
this._index = 0;
|
|
86
|
-
this.
|
|
88
|
+
this._invalidationSubscriptions = new Set();
|
|
89
|
+
this._invalidatedRecordIDs = new Set();
|
|
90
|
+
this._queryCacheExpirationTime = options === null || options === void 0 ? void 0 : options.queryCacheExpirationTime;
|
|
91
|
+
this._operationLoader = (_options$operationLoa = options === null || options === void 0 ? void 0 : options.operationLoader) !== null && _options$operationLoa !== void 0 ? _options$operationLoa : null;
|
|
87
92
|
this._optimisticSource = null;
|
|
88
93
|
this._recordSource = source;
|
|
89
94
|
this._releaseBuffer = [];
|
|
90
95
|
this._roots = new Map();
|
|
91
96
|
this._shouldScheduleGC = false;
|
|
92
97
|
this._subscriptions = new Set();
|
|
93
|
-
this._updatedConnectionIDs = {};
|
|
94
98
|
this._updatedRecordIDs = {};
|
|
99
|
+
initializeRecordSource(this._recordSource);
|
|
95
100
|
}
|
|
96
101
|
|
|
97
102
|
var _proto = RelayModernStore.prototype;
|
|
@@ -102,48 +107,110 @@ function () {
|
|
|
102
107
|
return (_this$_optimisticSour = this._optimisticSource) !== null && _this$_optimisticSour !== void 0 ? _this$_optimisticSour : this._recordSource;
|
|
103
108
|
};
|
|
104
109
|
|
|
105
|
-
_proto.
|
|
106
|
-
var
|
|
107
|
-
|
|
108
|
-
if (events != null) {
|
|
109
|
-
var _events$optimistic;
|
|
110
|
+
_proto.check = function check(operation, options) {
|
|
111
|
+
var _this$_optimisticSour2, _options$target, _options$handlers;
|
|
110
112
|
|
|
111
|
-
|
|
113
|
+
var selector = operation.root;
|
|
114
|
+
var source = (_this$_optimisticSour2 = this._optimisticSource) !== null && _this$_optimisticSour2 !== void 0 ? _this$_optimisticSour2 : this._recordSource;
|
|
115
|
+
var globalInvalidationEpoch = this._globalInvalidationEpoch;
|
|
116
|
+
|
|
117
|
+
var rootEntry = this._roots.get(operation.request.identifier);
|
|
118
|
+
|
|
119
|
+
var operationLastWrittenAt = rootEntry != null ? rootEntry.epoch : null; // Check if store has been globally invalidated
|
|
120
|
+
|
|
121
|
+
if (globalInvalidationEpoch != null) {
|
|
122
|
+
// If so, check if the operation we're checking was last written
|
|
123
|
+
// before or after invalidation occured.
|
|
124
|
+
if (operationLastWrittenAt == null || operationLastWrittenAt <= globalInvalidationEpoch) {
|
|
125
|
+
// If the operation was written /before/ global invalidation occurred,
|
|
126
|
+
// or if this operation has never been written to the store before,
|
|
127
|
+
// we will consider the data for this operation to be stale
|
|
128
|
+
// (i.e. not resolvable from the store).
|
|
129
|
+
return {
|
|
130
|
+
status: 'stale'
|
|
131
|
+
};
|
|
132
|
+
}
|
|
112
133
|
}
|
|
134
|
+
|
|
135
|
+
var target = (_options$target = options === null || options === void 0 ? void 0 : options.target) !== null && _options$target !== void 0 ? _options$target : source;
|
|
136
|
+
var handlers = (_options$handlers = options === null || options === void 0 ? void 0 : options.handlers) !== null && _options$handlers !== void 0 ? _options$handlers : [];
|
|
137
|
+
var operationAvailability = DataChecker.check(source, target, selector, handlers, this._operationLoader, this._getDataID);
|
|
138
|
+
return getAvailabilityStatus(operationAvailability, operationLastWrittenAt, rootEntry === null || rootEntry === void 0 ? void 0 : rootEntry.fetchTime, this._queryCacheExpirationTime);
|
|
113
139
|
};
|
|
114
140
|
|
|
115
|
-
_proto.
|
|
141
|
+
_proto.retain = function retain(operation) {
|
|
116
142
|
var _this = this;
|
|
117
143
|
|
|
118
|
-
var
|
|
144
|
+
var id = operation.request.identifier;
|
|
145
|
+
var disposed = false;
|
|
119
146
|
|
|
120
|
-
var
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
147
|
+
var dispose = function dispose() {
|
|
148
|
+
// Ensure each retain can only dispose once
|
|
149
|
+
if (disposed) {
|
|
150
|
+
return;
|
|
151
|
+
}
|
|
125
152
|
|
|
126
|
-
|
|
127
|
-
var _this2 = this;
|
|
153
|
+
disposed = true; // For Flow: guard against the entry somehow not existing
|
|
128
154
|
|
|
129
|
-
|
|
155
|
+
var rootEntry = _this._roots.get(id);
|
|
130
156
|
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
// release
|
|
157
|
+
if (rootEntry == null) {
|
|
158
|
+
return;
|
|
159
|
+
} // Decrement the ref count: if it becomes zero it is eligible
|
|
160
|
+
// for release.
|
|
161
|
+
|
|
162
|
+
|
|
163
|
+
rootEntry.refCount--;
|
|
164
|
+
|
|
165
|
+
if (rootEntry.refCount === 0) {
|
|
166
|
+
var _queryCacheExpirationTime = _this._queryCacheExpirationTime;
|
|
167
|
+
|
|
168
|
+
var rootEntryIsStale = rootEntry.fetchTime != null && _queryCacheExpirationTime != null && rootEntry.fetchTime <= Date.now() - _queryCacheExpirationTime;
|
|
135
169
|
|
|
170
|
+
if (rootEntryIsStale) {
|
|
171
|
+
_this._roots["delete"](id);
|
|
136
172
|
|
|
137
|
-
|
|
138
|
-
|
|
173
|
+
_this._scheduleGC();
|
|
174
|
+
} else {
|
|
175
|
+
_this._releaseBuffer.push(id); // If the release buffer is now over-full, remove the least-recently
|
|
176
|
+
// added entry and schedule a GC. Note that all items in the release
|
|
177
|
+
// buffer have a refCount of 0.
|
|
139
178
|
|
|
140
|
-
_this2._roots["delete"](idx);
|
|
141
179
|
|
|
142
|
-
|
|
180
|
+
if (_this._releaseBuffer.length > _this._gcReleaseBufferSize) {
|
|
181
|
+
var _id = _this._releaseBuffer.shift();
|
|
182
|
+
|
|
183
|
+
_this._roots["delete"](_id);
|
|
184
|
+
|
|
185
|
+
_this._scheduleGC();
|
|
186
|
+
}
|
|
187
|
+
}
|
|
143
188
|
}
|
|
144
189
|
};
|
|
145
190
|
|
|
146
|
-
this._roots.
|
|
191
|
+
var rootEntry = this._roots.get(id);
|
|
192
|
+
|
|
193
|
+
if (rootEntry != null) {
|
|
194
|
+
if (rootEntry.refCount === 0) {
|
|
195
|
+
// This entry should be in the release buffer, but it no longer belongs
|
|
196
|
+
// there since it's retained. Remove it to maintain the invariant that
|
|
197
|
+
// all release buffer entries have a refCount of 0.
|
|
198
|
+
this._releaseBuffer = this._releaseBuffer.filter(function (_id) {
|
|
199
|
+
return _id !== id;
|
|
200
|
+
});
|
|
201
|
+
} // If we've previously retained this operation, increment the refCount
|
|
202
|
+
|
|
203
|
+
|
|
204
|
+
rootEntry.refCount += 1;
|
|
205
|
+
} else {
|
|
206
|
+
// Otherwise create a new entry for the operation
|
|
207
|
+
this._roots.set(id, {
|
|
208
|
+
operation: operation,
|
|
209
|
+
refCount: 1,
|
|
210
|
+
epoch: null,
|
|
211
|
+
fetchTime: null
|
|
212
|
+
});
|
|
213
|
+
}
|
|
147
214
|
|
|
148
215
|
return {
|
|
149
216
|
dispose: dispose
|
|
@@ -159,61 +226,86 @@ function () {
|
|
|
159
226
|
}
|
|
160
227
|
|
|
161
228
|
return snapshot;
|
|
162
|
-
} // This method will return a list of updated owners
|
|
229
|
+
} // This method will return a list of updated owners from the subscriptions
|
|
163
230
|
;
|
|
164
231
|
|
|
165
|
-
_proto.notify = function notify() {
|
|
166
|
-
var
|
|
232
|
+
_proto.notify = function notify(sourceOperation, invalidateStore) {
|
|
233
|
+
var _this2 = this;
|
|
234
|
+
|
|
235
|
+
// Increment the current write when notifying after executing
|
|
236
|
+
// a set of changes to the store.
|
|
237
|
+
this._currentWriteEpoch++;
|
|
238
|
+
|
|
239
|
+
if (invalidateStore === true) {
|
|
240
|
+
this._globalInvalidationEpoch = this._currentWriteEpoch;
|
|
241
|
+
}
|
|
167
242
|
|
|
168
243
|
var source = this.getSource();
|
|
169
244
|
var updatedOwners = [];
|
|
170
245
|
|
|
171
246
|
this._subscriptions.forEach(function (subscription) {
|
|
172
|
-
var owner =
|
|
247
|
+
var owner = _this2._updateSubscription(source, subscription);
|
|
173
248
|
|
|
174
249
|
if (owner != null) {
|
|
175
250
|
updatedOwners.push(owner);
|
|
176
251
|
}
|
|
177
252
|
});
|
|
178
253
|
|
|
179
|
-
this.
|
|
180
|
-
|
|
181
|
-
subscription.stale = false;
|
|
182
|
-
subscription.callback(subscription.snapshot);
|
|
183
|
-
}
|
|
254
|
+
this._invalidationSubscriptions.forEach(function (subscription) {
|
|
255
|
+
_this2._updateInvalidationSubscription(subscription, invalidateStore === true);
|
|
184
256
|
});
|
|
185
257
|
|
|
186
|
-
this._updatedConnectionIDs = {};
|
|
187
258
|
this._updatedRecordIDs = {};
|
|
188
|
-
return updatedOwners;
|
|
189
|
-
};
|
|
190
259
|
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
260
|
+
this._invalidatedRecordIDs.clear(); // If a source operation was provided (indicating the operation
|
|
261
|
+
// that produced this update to the store), record the current epoch
|
|
262
|
+
// at which this operation was written.
|
|
263
|
+
|
|
264
|
+
|
|
265
|
+
if (sourceOperation != null) {
|
|
266
|
+
// We only track the epoch at which the operation was written if
|
|
267
|
+
// it was previously retained, to keep the size of our operation
|
|
268
|
+
// epoch map bounded. If a query wasn't retained, we assume it can
|
|
269
|
+
// may be deleted at any moment and thus is not relevant for us to track
|
|
270
|
+
// for the purposes of invalidation.
|
|
271
|
+
var id = sourceOperation.request.identifier;
|
|
272
|
+
|
|
273
|
+
var rootEntry = this._roots.get(id);
|
|
274
|
+
|
|
275
|
+
if (rootEntry != null) {
|
|
276
|
+
rootEntry.epoch = this._currentWriteEpoch;
|
|
277
|
+
rootEntry.fetchTime = Date.now();
|
|
278
|
+
} else if (sourceOperation.request.node.params.operationKind === 'query' && this._gcReleaseBufferSize > 0 && this._releaseBuffer.length < this._gcReleaseBufferSize) {
|
|
279
|
+
// The operation isn't retained but there is space in the release buffer:
|
|
280
|
+
// temporarily track this operation in case the data can be reused soon.
|
|
281
|
+
var temporaryRootEntry = {
|
|
282
|
+
operation: sourceOperation,
|
|
283
|
+
refCount: 0,
|
|
284
|
+
epoch: this._currentWriteEpoch,
|
|
285
|
+
fetchTime: Date.now()
|
|
286
|
+
};
|
|
198
287
|
|
|
199
|
-
|
|
200
|
-
var hasStoreUpdates = hasOverlappingIDs(subscription.snapshot.seenRecords, _this4._updatedRecordIDs);
|
|
288
|
+
this._releaseBuffer.push(id);
|
|
201
289
|
|
|
202
|
-
|
|
203
|
-
return;
|
|
290
|
+
this._roots.set(id, temporaryRootEntry);
|
|
204
291
|
}
|
|
292
|
+
}
|
|
205
293
|
|
|
206
|
-
|
|
294
|
+
return updatedOwners;
|
|
295
|
+
};
|
|
207
296
|
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
297
|
+
_proto.publish = function publish(source, idsMarkedForInvalidation) {
|
|
298
|
+
var _this$_optimisticSour3;
|
|
299
|
+
|
|
300
|
+
var target = (_this$_optimisticSour3 = this._optimisticSource) !== null && _this$_optimisticSour3 !== void 0 ? _this$_optimisticSour3 : this._recordSource;
|
|
301
|
+
updateTargetFromSource(target, source, // We increment the current epoch at the end of the set of updates,
|
|
302
|
+
// in notify(). Here, we pass what will be the incremented value of
|
|
303
|
+
// the epoch to use to write to invalidated records.
|
|
304
|
+
this._currentWriteEpoch + 1, idsMarkedForInvalidation, this._updatedRecordIDs, this._invalidatedRecordIDs);
|
|
213
305
|
};
|
|
214
306
|
|
|
215
307
|
_proto.subscribe = function subscribe(snapshot, callback) {
|
|
216
|
-
var
|
|
308
|
+
var _this3 = this;
|
|
217
309
|
|
|
218
310
|
var subscription = {
|
|
219
311
|
backup: null,
|
|
@@ -223,7 +315,7 @@ function () {
|
|
|
223
315
|
};
|
|
224
316
|
|
|
225
317
|
var dispose = function dispose() {
|
|
226
|
-
|
|
318
|
+
_this3._subscriptions["delete"](subscription);
|
|
227
319
|
};
|
|
228
320
|
|
|
229
321
|
this._subscriptions.add(subscription);
|
|
@@ -234,18 +326,18 @@ function () {
|
|
|
234
326
|
};
|
|
235
327
|
|
|
236
328
|
_proto.holdGC = function holdGC() {
|
|
237
|
-
var
|
|
329
|
+
var _this4 = this;
|
|
238
330
|
|
|
239
331
|
this._gcHoldCounter++;
|
|
240
332
|
|
|
241
333
|
var dispose = function dispose() {
|
|
242
|
-
if (
|
|
243
|
-
|
|
334
|
+
if (_this4._gcHoldCounter > 0) {
|
|
335
|
+
_this4._gcHoldCounter--;
|
|
244
336
|
|
|
245
|
-
if (
|
|
246
|
-
|
|
337
|
+
if (_this4._gcHoldCounter === 0 && _this4._shouldScheduleGC) {
|
|
338
|
+
_this4._scheduleGC();
|
|
247
339
|
|
|
248
|
-
|
|
340
|
+
_this4._shouldScheduleGC = false;
|
|
249
341
|
}
|
|
250
342
|
}
|
|
251
343
|
};
|
|
@@ -299,271 +391,128 @@ function () {
|
|
|
299
391
|
}
|
|
300
392
|
};
|
|
301
393
|
|
|
302
|
-
_proto.
|
|
303
|
-
var
|
|
394
|
+
_proto.lookupInvalidationState = function lookupInvalidationState(dataIDs) {
|
|
395
|
+
var _this5 = this;
|
|
304
396
|
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
397
|
+
var invalidations = new Map();
|
|
398
|
+
dataIDs.forEach(function (dataID) {
|
|
399
|
+
var _RelayModernRecord$ge;
|
|
308
400
|
|
|
309
|
-
|
|
401
|
+
var record = _this5.getSource().get(dataID);
|
|
310
402
|
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
state: initialState
|
|
403
|
+
invalidations.set(dataID, (_RelayModernRecord$ge = RelayModernRecord.getInvalidationEpoch(record)) !== null && _RelayModernRecord$ge !== void 0 ? _RelayModernRecord$ge : null);
|
|
404
|
+
});
|
|
405
|
+
invalidations.set('global', this._globalInvalidationEpoch);
|
|
406
|
+
return {
|
|
407
|
+
dataIDs: dataIDs,
|
|
408
|
+
invalidations: invalidations
|
|
318
409
|
};
|
|
410
|
+
};
|
|
411
|
+
|
|
412
|
+
_proto.checkInvalidationState = function checkInvalidationState(prevInvalidationState) {
|
|
413
|
+
var latestInvalidationState = this.lookupInvalidationState(prevInvalidationState.dataIDs);
|
|
414
|
+
var currentInvalidations = latestInvalidationState.invalidations;
|
|
415
|
+
var prevInvalidations = prevInvalidationState.invalidations; // Check if global invalidation has changed
|
|
416
|
+
|
|
417
|
+
if (currentInvalidations.get('global') !== prevInvalidations.get('global')) {
|
|
418
|
+
return true;
|
|
419
|
+
} // Check if the invalidation state for any of the ids has changed.
|
|
420
|
+
|
|
421
|
+
|
|
422
|
+
var _iterator = _createForOfIteratorHelper(prevInvalidationState.dataIDs),
|
|
423
|
+
_step;
|
|
319
424
|
|
|
320
|
-
|
|
321
|
-
|
|
425
|
+
try {
|
|
426
|
+
for (_iterator.s(); !(_step = _iterator.n()).done;) {
|
|
427
|
+
var dataID = _step.value;
|
|
428
|
+
|
|
429
|
+
if (currentInvalidations.get(dataID) !== prevInvalidations.get(dataID)) {
|
|
430
|
+
return true;
|
|
431
|
+
}
|
|
432
|
+
}
|
|
433
|
+
} catch (err) {
|
|
434
|
+
_iterator.e(err);
|
|
435
|
+
} finally {
|
|
436
|
+
_iterator.f();
|
|
322
437
|
}
|
|
323
438
|
|
|
324
|
-
return
|
|
439
|
+
return false;
|
|
325
440
|
};
|
|
326
441
|
|
|
327
|
-
_proto.
|
|
328
|
-
var
|
|
442
|
+
_proto.subscribeToInvalidationState = function subscribeToInvalidationState(invalidationState, callback) {
|
|
443
|
+
var _this6 = this;
|
|
329
444
|
|
|
330
|
-
!RelayFeatureFlags.ENABLE_CONNECTION_RESOLVERS ? process.env.NODE_ENV !== "production" ? invariant(false, 'RelayModernStore: Connection resolvers are not yet supported.') : invariant(false) : void 0;
|
|
331
|
-
var id = String(this._index++);
|
|
332
445
|
var subscription = {
|
|
333
|
-
backup: null,
|
|
334
446
|
callback: callback,
|
|
335
|
-
|
|
336
|
-
resolver: resolver,
|
|
337
|
-
snapshot: snapshot,
|
|
338
|
-
stale: false
|
|
447
|
+
invalidationState: invalidationState
|
|
339
448
|
};
|
|
340
449
|
|
|
341
450
|
var dispose = function dispose() {
|
|
342
|
-
|
|
451
|
+
_this6._invalidationSubscriptions["delete"](subscription);
|
|
343
452
|
};
|
|
344
453
|
|
|
345
|
-
this.
|
|
454
|
+
this._invalidationSubscriptions.add(subscription);
|
|
346
455
|
|
|
347
456
|
return {
|
|
348
457
|
dispose: dispose
|
|
349
458
|
};
|
|
350
459
|
};
|
|
351
460
|
|
|
352
|
-
_proto.
|
|
353
|
-
var
|
|
354
|
-
|
|
355
|
-
if (events.length === 0) {
|
|
356
|
-
return;
|
|
357
|
-
}
|
|
358
|
-
|
|
359
|
-
!RelayFeatureFlags.ENABLE_CONNECTION_RESOLVERS ? process.env.NODE_ENV !== "production" ? invariant(false, 'RelayModernStore: Connection resolvers are not yet supported.') : invariant(false) : void 0;
|
|
360
|
-
var pendingConnectionEvents = new Map();
|
|
361
|
-
events.forEach(function (event) {
|
|
362
|
-
var connectionID = event.connectionID;
|
|
363
|
-
var pendingEvents = pendingConnectionEvents.get(connectionID);
|
|
364
|
-
|
|
365
|
-
if (pendingEvents == null) {
|
|
366
|
-
pendingEvents = [];
|
|
367
|
-
pendingConnectionEvents.set(connectionID, pendingEvents);
|
|
368
|
-
}
|
|
369
|
-
|
|
370
|
-
pendingEvents.push(event);
|
|
371
|
-
|
|
372
|
-
var connectionEvents = _this8._connectionEvents.get(connectionID);
|
|
373
|
-
|
|
374
|
-
if (connectionEvents == null) {
|
|
375
|
-
connectionEvents = {
|
|
376
|
-
"final": [],
|
|
377
|
-
optimistic: null
|
|
378
|
-
};
|
|
379
|
-
|
|
380
|
-
_this8._connectionEvents.set(connectionID, connectionEvents);
|
|
381
|
-
}
|
|
382
|
-
|
|
383
|
-
if (final) {
|
|
384
|
-
connectionEvents["final"].push(event);
|
|
385
|
-
} else {
|
|
386
|
-
var optimisticEvents = connectionEvents.optimistic;
|
|
387
|
-
|
|
388
|
-
if (optimisticEvents == null) {
|
|
389
|
-
optimisticEvents = connectionEvents["final"].slice();
|
|
390
|
-
connectionEvents.optimistic = optimisticEvents;
|
|
391
|
-
}
|
|
392
|
-
|
|
393
|
-
optimisticEvents.push(event);
|
|
394
|
-
}
|
|
395
|
-
});
|
|
396
|
-
|
|
397
|
-
this._connectionSubscriptions.forEach(function (subscription, id) {
|
|
398
|
-
var pendingEvents = pendingConnectionEvents.get(subscription.snapshot.reference.id);
|
|
399
|
-
|
|
400
|
-
if (pendingEvents == null) {
|
|
401
|
-
return;
|
|
402
|
-
}
|
|
403
|
-
|
|
404
|
-
var nextSnapshot = _this8._updateConnection_UNSTABLE(subscription.resolver, subscription.snapshot, null, pendingEvents);
|
|
461
|
+
_proto._updateInvalidationSubscription = function _updateInvalidationSubscription(subscription, invalidatedStore) {
|
|
462
|
+
var _this7 = this;
|
|
405
463
|
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
464
|
+
var callback = subscription.callback,
|
|
465
|
+
invalidationState = subscription.invalidationState;
|
|
466
|
+
var dataIDs = invalidationState.dataIDs;
|
|
467
|
+
var isSubscribedToInvalidatedIDs = invalidatedStore || dataIDs.some(function (dataID) {
|
|
468
|
+
return _this7._invalidatedRecordIDs.has(dataID);
|
|
410
469
|
});
|
|
411
|
-
};
|
|
412
|
-
|
|
413
|
-
_proto._updateConnection_UNSTABLE = function _updateConnection_UNSTABLE(resolver, snapshot, source, pendingEvents) {
|
|
414
|
-
var _pendingEvents;
|
|
415
|
-
|
|
416
|
-
var nextSnapshot = this._reduceConnection_UNSTABLE(resolver, snapshot.reference, snapshot, (_pendingEvents = pendingEvents) !== null && _pendingEvents !== void 0 ? _pendingEvents : [], source);
|
|
417
470
|
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
if (process.env.NODE_ENV !== "production") {
|
|
421
|
-
deepFreeze(nextSnapshot);
|
|
471
|
+
if (!isSubscribedToInvalidatedIDs) {
|
|
472
|
+
return;
|
|
422
473
|
}
|
|
423
474
|
|
|
424
|
-
|
|
425
|
-
return (0, _objectSpread2["default"])({}, nextSnapshot, {
|
|
426
|
-
state: state
|
|
427
|
-
});
|
|
428
|
-
}
|
|
475
|
+
callback();
|
|
429
476
|
};
|
|
430
477
|
|
|
431
|
-
_proto.
|
|
432
|
-
var
|
|
433
|
-
|
|
434
|
-
var _edgesField$concreteT;
|
|
435
|
-
|
|
436
|
-
var source = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : null;
|
|
437
|
-
var edgesField = connectionReference.edgesField,
|
|
438
|
-
id = connectionReference.id,
|
|
439
|
-
variables = connectionReference.variables;
|
|
440
|
-
var fragment = {
|
|
441
|
-
kind: 'Fragment',
|
|
442
|
-
name: edgesField.name,
|
|
443
|
-
type: (_edgesField$concreteT = edgesField.concreteType) !== null && _edgesField$concreteT !== void 0 ? _edgesField$concreteT : '__Any',
|
|
444
|
-
metadata: null,
|
|
445
|
-
argumentDefinitions: [],
|
|
446
|
-
selections: edgesField.selections
|
|
447
|
-
};
|
|
448
|
-
var seenRecords = {};
|
|
449
|
-
var edgeSnapshots = (0, _objectSpread2["default"])({}, snapshot.edgeSnapshots);
|
|
450
|
-
var initialState = snapshot.state;
|
|
451
|
-
|
|
452
|
-
if (source) {
|
|
453
|
-
var edgeData = {};
|
|
454
|
-
Object.keys(edgeSnapshots).forEach(function (edgeID) {
|
|
455
|
-
var prevSnapshot = edgeSnapshots[edgeID];
|
|
456
|
-
var nextSnapshot = RelayReader.read(_this9.getSource(), createReaderSelector(fragment, edgeID, variables, prevSnapshot.selector.owner));
|
|
457
|
-
var data = recycleNodesInto(prevSnapshot.data, nextSnapshot.data);
|
|
458
|
-
nextSnapshot = {
|
|
459
|
-
data: data,
|
|
460
|
-
isMissingData: nextSnapshot.isMissingData,
|
|
461
|
-
seenRecords: nextSnapshot.seenRecords,
|
|
462
|
-
selector: nextSnapshot.selector
|
|
463
|
-
};
|
|
464
|
-
|
|
465
|
-
if (data !== prevSnapshot.data) {
|
|
466
|
-
edgeData[edgeID] = data;
|
|
467
|
-
edgeSnapshots[edgeID] = nextSnapshot;
|
|
468
|
-
}
|
|
469
|
-
});
|
|
470
|
-
|
|
471
|
-
if (Object.keys(edgeData).length !== 0) {
|
|
472
|
-
initialState = resolver.reduce(initialState, {
|
|
473
|
-
kind: 'update',
|
|
474
|
-
edgeData: edgeData
|
|
475
|
-
});
|
|
476
|
-
}
|
|
477
|
-
}
|
|
478
|
+
_proto.snapshot = function snapshot() {
|
|
479
|
+
var _this8 = this;
|
|
478
480
|
|
|
479
|
-
|
|
480
|
-
if (event.kind === 'fetch') {
|
|
481
|
-
var edges = [];
|
|
482
|
-
event.edgeIDs.forEach(function (edgeID) {
|
|
483
|
-
if (edgeID == null) {
|
|
484
|
-
edges.push(edgeID);
|
|
485
|
-
return;
|
|
486
|
-
}
|
|
481
|
+
!(this._optimisticSource == null) ? process.env.NODE_ENV !== "production" ? invariant(false, 'RelayModernStore: Unexpected call to snapshot() while a previous ' + 'snapshot exists.') : invariant(false) : void 0;
|
|
487
482
|
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
var itemData = edgeSnapshot.data;
|
|
505
|
-
edgeSnapshots[event.edgeID] = edgeSnapshot;
|
|
506
|
-
return resolver.reduce(prevState, {
|
|
507
|
-
args: event.args,
|
|
508
|
-
edge: itemData,
|
|
509
|
-
kind: 'insert'
|
|
510
|
-
});
|
|
511
|
-
} else if (event.kind === 'stream.edge') {
|
|
512
|
-
var _edgeSnapshot = RelayReader.read(_this9.getSource(), createReaderSelector(fragment, event.edgeID, variables, event.request));
|
|
513
|
-
|
|
514
|
-
Object.assign(seenRecords, _edgeSnapshot.seenRecords);
|
|
515
|
-
var _itemData = _edgeSnapshot.data;
|
|
516
|
-
edgeSnapshots[event.edgeID] = _edgeSnapshot;
|
|
517
|
-
return resolver.reduce(prevState, {
|
|
518
|
-
args: event.args,
|
|
519
|
-
edge: _itemData,
|
|
520
|
-
index: event.index,
|
|
521
|
-
kind: 'stream.edge'
|
|
522
|
-
});
|
|
523
|
-
} else if (event.kind === 'stream.pageInfo') {
|
|
524
|
-
return resolver.reduce(prevState, {
|
|
525
|
-
args: event.args,
|
|
526
|
-
kind: 'stream.pageInfo',
|
|
527
|
-
pageInfo: event.pageInfo
|
|
528
|
-
});
|
|
529
|
-
} else {
|
|
530
|
-
event.kind;
|
|
531
|
-
!false ? process.env.NODE_ENV !== "production" ? invariant(false, 'RelayModernStore: Unexpected connection event kind `%s`.', event.kind) : invariant(false) : void 0;
|
|
483
|
+
this._subscriptions.forEach(function (subscription) {
|
|
484
|
+
// Backup occurs after writing a new "final" payload(s) and before (re)applying
|
|
485
|
+
// optimistic changes. Each subscription's `snapshot` represents what was *last
|
|
486
|
+
// published to the subscriber*, which notably may include previous optimistic
|
|
487
|
+
// updates. Therefore a subscription can be in any of the following states:
|
|
488
|
+
// - stale=true: This subscription was restored to a different value than
|
|
489
|
+
// `snapshot`. That means this subscription has changes relative to its base,
|
|
490
|
+
// but its base has changed (we just applied a final payload): recompute
|
|
491
|
+
// a backup so that we can later restore to the state the subscription
|
|
492
|
+
// should be in.
|
|
493
|
+
// - stale=false: This subscription was restored to the same value than
|
|
494
|
+
// `snapshot`. That means this subscription does *not* have changes relative
|
|
495
|
+
// to its base, so the current `snapshot` is valid to use as a backup.
|
|
496
|
+
if (!subscription.stale) {
|
|
497
|
+
subscription.backup = subscription.snapshot;
|
|
498
|
+
return;
|
|
532
499
|
}
|
|
533
|
-
}, initialState);
|
|
534
|
-
return {
|
|
535
|
-
edgeSnapshots: edgeSnapshots,
|
|
536
|
-
id: id,
|
|
537
|
-
reference: connectionReference,
|
|
538
|
-
seenRecords: seenRecords,
|
|
539
|
-
state: state
|
|
540
|
-
};
|
|
541
|
-
};
|
|
542
500
|
|
|
543
|
-
|
|
544
|
-
|
|
501
|
+
var snapshot = subscription.snapshot;
|
|
502
|
+
var backup = RelayReader.read(_this8.getSource(), snapshot.selector);
|
|
503
|
+
var nextData = recycleNodesInto(snapshot.data, backup.data);
|
|
504
|
+
backup.data = nextData; // backup owns the snapshot and can safely mutate
|
|
545
505
|
|
|
546
|
-
|
|
547
|
-
subscription.backup = subscription.snapshot;
|
|
548
|
-
});
|
|
549
|
-
|
|
550
|
-
this._subscriptions.forEach(function (subscription) {
|
|
551
|
-
subscription.backup = subscription.snapshot;
|
|
506
|
+
subscription.backup = backup;
|
|
552
507
|
});
|
|
553
508
|
|
|
554
509
|
this._optimisticSource = RelayOptimisticRecordSource.create(this.getSource());
|
|
555
510
|
};
|
|
556
511
|
|
|
557
512
|
_proto.restore = function restore() {
|
|
558
|
-
var _this10 = this;
|
|
559
|
-
|
|
560
513
|
!(this._optimisticSource != null) ? process.env.NODE_ENV !== "production" ? invariant(false, 'RelayModernStore: Unexpected call to restore(), expected a snapshot ' + 'to exist (make sure to call snapshot()).') : invariant(false) : void 0;
|
|
561
514
|
this._optimisticSource = null;
|
|
562
515
|
|
|
563
|
-
this._connectionEvents.forEach(function (events) {
|
|
564
|
-
events.optimistic = null;
|
|
565
|
-
});
|
|
566
|
-
|
|
567
516
|
this._subscriptions.forEach(function (subscription) {
|
|
568
517
|
var backup = subscription.backup;
|
|
569
518
|
subscription.backup = null;
|
|
@@ -583,38 +532,10 @@ function () {
|
|
|
583
532
|
subscription.stale = true;
|
|
584
533
|
}
|
|
585
534
|
});
|
|
586
|
-
|
|
587
|
-
this._connectionSubscriptions.forEach(function (subscription) {
|
|
588
|
-
var backup = subscription.backup;
|
|
589
|
-
subscription.backup = null;
|
|
590
|
-
|
|
591
|
-
if (backup) {
|
|
592
|
-
if (backup.state !== subscription.snapshot.state) {
|
|
593
|
-
subscription.stale = true;
|
|
594
|
-
}
|
|
595
|
-
|
|
596
|
-
subscription.snapshot = backup;
|
|
597
|
-
} else {
|
|
598
|
-
// This subscription was established after the creation of the
|
|
599
|
-
// connection snapshot so there's nothing to restore to. Recreate the
|
|
600
|
-
// connection from scratch and check ifs value changes.
|
|
601
|
-
var baseSnapshot = _this10.lookupConnection_UNSTABLE(subscription.snapshot.reference, subscription.resolver);
|
|
602
|
-
|
|
603
|
-
var nextState = recycleNodesInto(subscription.snapshot.state, baseSnapshot.state);
|
|
604
|
-
|
|
605
|
-
if (nextState !== subscription.snapshot.state) {
|
|
606
|
-
subscription.stale = true;
|
|
607
|
-
}
|
|
608
|
-
|
|
609
|
-
subscription.snapshot = (0, _objectSpread2["default"])({}, baseSnapshot, {
|
|
610
|
-
state: nextState
|
|
611
|
-
});
|
|
612
|
-
}
|
|
613
|
-
});
|
|
614
535
|
};
|
|
615
536
|
|
|
616
537
|
_proto._scheduleGC = function _scheduleGC() {
|
|
617
|
-
var
|
|
538
|
+
var _this9 = this;
|
|
618
539
|
|
|
619
540
|
if (this._gcHoldCounter > 0) {
|
|
620
541
|
this._shouldScheduleGC = true;
|
|
@@ -628,27 +549,26 @@ function () {
|
|
|
628
549
|
this._hasScheduledGC = true;
|
|
629
550
|
|
|
630
551
|
this._gcScheduler(function () {
|
|
631
|
-
|
|
552
|
+
_this9.__gc();
|
|
632
553
|
|
|
633
|
-
|
|
554
|
+
_this9._hasScheduledGC = false;
|
|
634
555
|
});
|
|
635
556
|
};
|
|
636
557
|
|
|
637
558
|
_proto.__gc = function __gc() {
|
|
638
|
-
var
|
|
559
|
+
var _this10 = this;
|
|
639
560
|
|
|
640
561
|
// Don't run GC while there are optimistic updates applied
|
|
641
562
|
if (this._optimisticSource != null) {
|
|
642
563
|
return;
|
|
643
564
|
}
|
|
644
565
|
|
|
645
|
-
var references = new Set();
|
|
646
|
-
var connectionReferences = new Set(); // Mark all records that are traversable from a root
|
|
566
|
+
var references = new Set(); // Mark all records that are traversable from a root
|
|
647
567
|
|
|
648
|
-
this._roots.forEach(function (
|
|
649
|
-
|
|
650
|
-
|
|
651
|
-
|
|
568
|
+
this._roots.forEach(function (_ref) {
|
|
569
|
+
var operation = _ref.operation;
|
|
570
|
+
var selector = operation.root;
|
|
571
|
+
RelayReferenceMarker.mark(_this10._recordSource, selector, references, _this10._operationLoader);
|
|
652
572
|
});
|
|
653
573
|
|
|
654
574
|
if (references.size === 0) {
|
|
@@ -666,49 +586,68 @@ function () {
|
|
|
666
586
|
}
|
|
667
587
|
}
|
|
668
588
|
}
|
|
669
|
-
|
|
670
|
-
if (connectionReferences.size === 0) {
|
|
671
|
-
this._connectionEvents.clear();
|
|
672
|
-
} else {
|
|
673
|
-
// Evict any unreferenced connections
|
|
674
|
-
var _iteratorNormalCompletion = true;
|
|
675
|
-
var _didIteratorError = false;
|
|
676
|
-
var _iteratorError = undefined;
|
|
677
|
-
|
|
678
|
-
try {
|
|
679
|
-
for (var _iterator = this._connectionEvents.keys()[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) {
|
|
680
|
-
var connectionID = _step.value;
|
|
681
|
-
|
|
682
|
-
if (!connectionReferences.has(connectionID)) {
|
|
683
|
-
this._connectionEvents["delete"](connectionID);
|
|
684
|
-
}
|
|
685
|
-
}
|
|
686
|
-
} catch (err) {
|
|
687
|
-
_didIteratorError = true;
|
|
688
|
-
_iteratorError = err;
|
|
689
|
-
} finally {
|
|
690
|
-
try {
|
|
691
|
-
if (!_iteratorNormalCompletion && _iterator["return"] != null) {
|
|
692
|
-
_iterator["return"]();
|
|
693
|
-
}
|
|
694
|
-
} finally {
|
|
695
|
-
if (_didIteratorError) {
|
|
696
|
-
throw _iteratorError;
|
|
697
|
-
}
|
|
698
|
-
}
|
|
699
|
-
}
|
|
700
|
-
}
|
|
701
589
|
};
|
|
702
590
|
|
|
703
591
|
return RelayModernStore;
|
|
704
592
|
}();
|
|
593
|
+
|
|
594
|
+
function initializeRecordSource(target) {
|
|
595
|
+
if (!target.has(ROOT_ID)) {
|
|
596
|
+
var rootRecord = RelayModernRecord.create(ROOT_ID, ROOT_TYPE);
|
|
597
|
+
target.set(ROOT_ID, rootRecord);
|
|
598
|
+
}
|
|
599
|
+
}
|
|
705
600
|
/**
|
|
706
601
|
* Updates the target with information from source, also updating a mapping of
|
|
707
602
|
* which records in the target were changed as a result.
|
|
603
|
+
* Additionally, will marc records as invalidated at the current write epoch
|
|
604
|
+
* given the set of record ids marked as stale in this update.
|
|
708
605
|
*/
|
|
709
606
|
|
|
710
607
|
|
|
711
|
-
function updateTargetFromSource(target, source, updatedRecordIDs) {
|
|
608
|
+
function updateTargetFromSource(target, source, currentWriteEpoch, idsMarkedForInvalidation, updatedRecordIDs, invalidatedRecordIDs) {
|
|
609
|
+
// First, update any records that were marked for invalidation.
|
|
610
|
+
// For each provided dataID that was invalidated, we write the
|
|
611
|
+
// INVALIDATED_AT_KEY on the record, indicating
|
|
612
|
+
// the epoch at which the record was invalidated.
|
|
613
|
+
if (idsMarkedForInvalidation) {
|
|
614
|
+
idsMarkedForInvalidation.forEach(function (dataID) {
|
|
615
|
+
var targetRecord = target.get(dataID);
|
|
616
|
+
var sourceRecord = source.get(dataID); // If record was deleted during the update (and also invalidated),
|
|
617
|
+
// we don't need to count it as an invalidated id
|
|
618
|
+
|
|
619
|
+
if (sourceRecord === null) {
|
|
620
|
+
return;
|
|
621
|
+
}
|
|
622
|
+
|
|
623
|
+
var nextRecord;
|
|
624
|
+
|
|
625
|
+
if (targetRecord != null) {
|
|
626
|
+
// If the target record exists, use it to set the epoch
|
|
627
|
+
// at which it was invalidated. This record will be updated with
|
|
628
|
+
// any changes from source in the section below
|
|
629
|
+
// where we update the target records based on the source.
|
|
630
|
+
nextRecord = RelayModernRecord.clone(targetRecord);
|
|
631
|
+
} else {
|
|
632
|
+
// If the target record doesn't exist, it means that a new record
|
|
633
|
+
// in the source was created (and also invalidated), so we use that
|
|
634
|
+
// record to set the epoch at which it was invalidated. This record
|
|
635
|
+
// will be updated with any changes from source in the section below
|
|
636
|
+
// where we update the target records based on the source.
|
|
637
|
+
nextRecord = sourceRecord != null ? RelayModernRecord.clone(sourceRecord) : null;
|
|
638
|
+
}
|
|
639
|
+
|
|
640
|
+
if (!nextRecord) {
|
|
641
|
+
return;
|
|
642
|
+
}
|
|
643
|
+
|
|
644
|
+
RelayModernRecord.setValue(nextRecord, RelayStoreUtils.INVALIDATED_AT_KEY, currentWriteEpoch);
|
|
645
|
+
invalidatedRecordIDs.add(dataID);
|
|
646
|
+
target.set(dataID, nextRecord);
|
|
647
|
+
});
|
|
648
|
+
} // Update the target based on the changes present in source
|
|
649
|
+
|
|
650
|
+
|
|
712
651
|
var dataIDs = source.getRecordIDs();
|
|
713
652
|
|
|
714
653
|
for (var ii = 0; ii < dataIDs.length; ii++) {
|
|
@@ -747,6 +686,55 @@ function updateTargetFromSource(target, source, updatedRecordIDs) {
|
|
|
747
686
|
|
|
748
687
|
}
|
|
749
688
|
}
|
|
689
|
+
/**
|
|
690
|
+
* Returns an OperationAvailability given the Availability returned
|
|
691
|
+
* by checking an operation, and when that operation was last written to the store.
|
|
692
|
+
* Specifically, the provided Availability of an operation will contain the
|
|
693
|
+
* value of when a record referenced by the operation was most recently
|
|
694
|
+
* invalidated; given that value, and given when this operation was last
|
|
695
|
+
* written to the store, this function will return the overall
|
|
696
|
+
* OperationAvailability for the operation.
|
|
697
|
+
*/
|
|
698
|
+
|
|
699
|
+
|
|
700
|
+
function getAvailabilityStatus(operationAvailability, operationLastWrittenAt, operationFetchTime, queryCacheExpirationTime) {
|
|
701
|
+
var mostRecentlyInvalidatedAt = operationAvailability.mostRecentlyInvalidatedAt,
|
|
702
|
+
status = operationAvailability.status;
|
|
703
|
+
|
|
704
|
+
if (typeof mostRecentlyInvalidatedAt === 'number') {
|
|
705
|
+
// If some record referenced by this operation is stale, then the operation itself is stale
|
|
706
|
+
// if either the operation itself was never written *or* the operation was last written
|
|
707
|
+
// before the most recent invalidation of its reachable records.
|
|
708
|
+
if (operationLastWrittenAt == null || mostRecentlyInvalidatedAt > operationLastWrittenAt) {
|
|
709
|
+
return {
|
|
710
|
+
status: 'stale'
|
|
711
|
+
};
|
|
712
|
+
}
|
|
713
|
+
}
|
|
714
|
+
|
|
715
|
+
if (status === 'missing') {
|
|
716
|
+
return {
|
|
717
|
+
status: 'missing'
|
|
718
|
+
};
|
|
719
|
+
}
|
|
720
|
+
|
|
721
|
+
if (operationFetchTime != null && queryCacheExpirationTime != null) {
|
|
722
|
+
var isStale = operationFetchTime <= Date.now() - queryCacheExpirationTime;
|
|
723
|
+
|
|
724
|
+
if (isStale) {
|
|
725
|
+
return {
|
|
726
|
+
status: 'stale'
|
|
727
|
+
};
|
|
728
|
+
}
|
|
729
|
+
} // There were no invalidations of any reachable records *or* the operation is known to have
|
|
730
|
+
// been fetched after the most recent record invalidation.
|
|
731
|
+
|
|
732
|
+
|
|
733
|
+
return {
|
|
734
|
+
status: 'available',
|
|
735
|
+
fetchTime: operationFetchTime !== null && operationFetchTime !== void 0 ? operationFetchTime : null
|
|
736
|
+
};
|
|
737
|
+
}
|
|
750
738
|
|
|
751
739
|
RelayProfiler.instrumentMethods(RelayModernStore.prototype, {
|
|
752
740
|
lookup: 'RelayModernStore.prototype.lookup',
|