relay-runtime 8.0.0 → 10.0.1
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 +41 -0
- package/handlers/connection/ConnectionHandler.js.flow +549 -0
- package/handlers/connection/ConnectionInterface.js.flow +92 -0
- package/handlers/connection/MutationHandlers.js.flow +88 -0
- package/index.js +1 -1
- package/index.js.flow +320 -0
- package/lib/handlers/RelayDefaultHandlerProvider.js +13 -2
- package/lib/handlers/connection/{RelayConnectionHandler.js → ConnectionHandler.js} +33 -35
- package/lib/handlers/connection/{RelayConnectionInterface.js → ConnectionInterface.js} +2 -2
- package/lib/handlers/connection/MutationHandlers.js +86 -0
- package/lib/index.js +15 -19
- package/lib/mutations/RelayDeclarativeMutationConfig.js +29 -52
- package/lib/mutations/RelayRecordProxy.js +1 -3
- package/lib/mutations/RelayRecordSourceMutator.js +2 -9
- package/lib/mutations/RelayRecordSourceProxy.js +2 -4
- package/lib/mutations/RelayRecordSourceSelectorProxy.js +1 -13
- package/lib/mutations/commitMutation.js +13 -3
- package/lib/mutations/validateMutation.js +16 -9
- package/lib/network/RelayObservable.js +9 -9
- package/lib/network/RelayQueryResponseCache.js +8 -6
- package/lib/query/PreloadableQueryRegistry.js +70 -0
- package/lib/query/fetchQueryInternal.js +31 -23
- package/lib/store/DataChecker.js +122 -110
- package/lib/store/RelayConcreteVariables.js +6 -2
- package/lib/store/RelayModernEnvironment.js +121 -67
- package/lib/store/RelayModernFragmentSpecResolver.js +12 -16
- package/lib/store/RelayModernQueryExecutor.js +389 -314
- package/lib/store/RelayModernRecord.js +14 -9
- package/lib/store/RelayModernSelector.js +7 -3
- package/lib/store/RelayModernStore.js +289 -484
- package/lib/store/RelayOperationTracker.js +35 -78
- package/lib/store/RelayOptimisticRecordSource.js +7 -5
- package/lib/store/RelayPublishQueue.js +6 -33
- package/lib/store/RelayReader.js +113 -45
- package/lib/store/RelayRecordSource.js +2 -9
- package/lib/store/RelayRecordSourceMapImpl.js +13 -18
- package/lib/store/RelayReferenceMarker.js +40 -60
- package/lib/store/RelayResponseNormalizer.js +158 -193
- package/lib/store/RelayStoreUtils.js +1 -0
- package/lib/store/StoreInspector.js +8 -8
- package/lib/store/TypeID.js +28 -0
- package/lib/store/cloneRelayScalarHandleSourceField.js +44 -0
- package/lib/store/normalizeRelayPayload.js +6 -2
- package/lib/store/readInlineData.js +1 -1
- package/lib/subscription/requestSubscription.js +5 -3
- package/lib/util/RelayConcreteNode.js +9 -6
- package/lib/util/RelayError.js +39 -9
- package/lib/util/RelayFeatureFlags.js +2 -5
- package/lib/util/RelayReplaySubject.js +3 -3
- package/lib/util/createPayloadFor3DField.js +7 -2
- package/lib/util/getRequestIdentifier.js +2 -2
- package/lib/util/recycleNodesInto.js +2 -6
- 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 +182 -0
- package/mutations/validateMutation.js.flow +213 -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/PreloadableQueryRegistry.js.flow +65 -0
- package/query/fetchQuery.js.flow +47 -0
- package/query/fetchQueryInternal.js.flow +348 -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 +502 -0
- package/store/RelayConcreteVariables.js.flow +96 -0
- package/store/RelayModernEnvironment.js.flow +551 -0
- package/store/RelayModernFragmentSpecResolver.js.flow +426 -0
- package/store/RelayModernOperationDescriptor.js.flow +88 -0
- package/store/RelayModernQueryExecutor.js.flow +1321 -0
- package/store/RelayModernRecord.js.flow +403 -0
- package/store/RelayModernSelector.js.flow +455 -0
- package/store/RelayModernStore.js.flow +842 -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 +473 -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 +257 -0
- package/store/RelayResponseNormalizer.js.flow +680 -0
- package/store/RelayStoreTypes.js.flow +899 -0
- package/store/RelayStoreUtils.js.flow +219 -0
- package/store/StoreInspector.js.flow +171 -0
- package/store/TypeID.js.flow +28 -0
- package/store/ViewerPattern.js.flow +26 -0
- package/store/cloneRelayHandleSourceField.js.flow +66 -0
- package/store/cloneRelayScalarHandleSourceField.js.flow +62 -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 +198 -0
- package/util/ReaderNode.js.flow +208 -0
- package/util/RelayConcreteNode.js.flow +93 -0
- package/util/RelayDefaultHandleKey.js.flow +17 -0
- package/util/RelayError.js.flow +62 -0
- package/util/RelayFeatureFlags.js.flow +30 -0
- package/util/RelayProfiler.js.flow +284 -0
- package/util/RelayReplaySubject.js.flow +135 -0
- package/util/RelayRuntimeTypes.js.flow +72 -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 +42 -0
- package/util/isPromise.js.flow +21 -0
- package/util/isScalarAndEqual.js.flow +26 -0
- package/util/recycleNodesInto.js.flow +76 -0
- package/util/resolveImmediate.js.flow +30 -0
- package/util/stableCopy.js.flow +35 -0
- package/lib/handlers/RelayDefaultMissingFieldHandlers.js +0 -26
- package/lib/handlers/getRelayDefaultMissingFieldHandlers.js +0 -36
- package/lib/query/RelayModernGraphQLTag.js +0 -104
- package/lib/store/RelayConnection.js +0 -37
- package/lib/store/RelayConnectionResolver.js +0 -178
- package/lib/store/RelayRecordSourceObjectImpl.js +0 -79
- package/lib/util/getFragmentSpecIdentifier.js +0 -27
|
@@ -12,11 +12,15 @@
|
|
|
12
12
|
|
|
13
13
|
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
|
|
14
14
|
|
|
15
|
-
var
|
|
15
|
+
var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty"));
|
|
16
16
|
|
|
17
|
-
var
|
|
17
|
+
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; } } }; }
|
|
18
|
+
|
|
19
|
+
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); }
|
|
18
20
|
|
|
19
|
-
var
|
|
21
|
+
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; }
|
|
22
|
+
|
|
23
|
+
var DataChecker = require('./DataChecker');
|
|
20
24
|
|
|
21
25
|
var RelayModernRecord = require('./RelayModernRecord');
|
|
22
26
|
|
|
@@ -42,8 +46,9 @@ var recycleNodesInto = require('../util/recycleNodesInto');
|
|
|
42
46
|
|
|
43
47
|
var resolveImmediate = require('../util/resolveImmediate');
|
|
44
48
|
|
|
45
|
-
var _require = require('./
|
|
46
|
-
|
|
49
|
+
var _require = require('./RelayStoreUtils'),
|
|
50
|
+
ROOT_ID = _require.ROOT_ID,
|
|
51
|
+
ROOT_TYPE = _require.ROOT_TYPE;
|
|
47
52
|
|
|
48
53
|
var DEFAULT_RELEASE_BUFFER_SIZE = 0;
|
|
49
54
|
/**
|
|
@@ -59,11 +64,21 @@ var DEFAULT_RELEASE_BUFFER_SIZE = 0;
|
|
|
59
64
|
* is also enforced in development mode by freezing all records passed to a store.
|
|
60
65
|
*/
|
|
61
66
|
|
|
62
|
-
var RelayModernStore =
|
|
63
|
-
/*#__PURE__*/
|
|
64
|
-
function () {
|
|
67
|
+
var RelayModernStore = /*#__PURE__*/function () {
|
|
65
68
|
function RelayModernStore(source, options) {
|
|
66
|
-
var
|
|
69
|
+
var _this = this;
|
|
70
|
+
|
|
71
|
+
var _options$gcReleaseBuf, _options$gcScheduler, _options$UNSTABLE_DO_, _options$log, _options$operationLoa;
|
|
72
|
+
|
|
73
|
+
(0, _defineProperty2["default"])(this, "_gcStep", function () {
|
|
74
|
+
if (_this._gcRun) {
|
|
75
|
+
if (_this._gcRun.next().done) {
|
|
76
|
+
_this._gcRun = null;
|
|
77
|
+
} else {
|
|
78
|
+
_this._gcScheduler(_this._gcStep);
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
});
|
|
67
82
|
|
|
68
83
|
// Prevent mutation of a record from outside the store.
|
|
69
84
|
if (process.env.NODE_ENV !== "production") {
|
|
@@ -78,27 +93,26 @@ function () {
|
|
|
78
93
|
}
|
|
79
94
|
}
|
|
80
95
|
|
|
81
|
-
this._connectionEvents = new Map();
|
|
82
|
-
this._connectionSubscriptions = new Map();
|
|
83
96
|
this._currentWriteEpoch = 0;
|
|
84
97
|
this._gcHoldCounter = 0;
|
|
85
|
-
this._gcReleaseBufferSize = (
|
|
86
|
-
this.
|
|
87
|
-
this.
|
|
98
|
+
this._gcReleaseBufferSize = (_options$gcReleaseBuf = options === null || options === void 0 ? void 0 : options.gcReleaseBufferSize) !== null && _options$gcReleaseBuf !== void 0 ? _options$gcReleaseBuf : DEFAULT_RELEASE_BUFFER_SIZE;
|
|
99
|
+
this._gcRun = null;
|
|
100
|
+
this._gcScheduler = (_options$gcScheduler = options === null || options === void 0 ? void 0 : options.gcScheduler) !== null && _options$gcScheduler !== void 0 ? _options$gcScheduler : resolveImmediate;
|
|
101
|
+
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;
|
|
88
102
|
this._globalInvalidationEpoch = null;
|
|
89
|
-
this._hasScheduledGC = false;
|
|
90
|
-
this._index = 0;
|
|
91
103
|
this._invalidationSubscriptions = new Set();
|
|
92
104
|
this._invalidatedRecordIDs = new Set();
|
|
93
|
-
this.
|
|
105
|
+
this.__log = (_options$log = options === null || options === void 0 ? void 0 : options.log) !== null && _options$log !== void 0 ? _options$log : null;
|
|
106
|
+
this._queryCacheExpirationTime = options === null || options === void 0 ? void 0 : options.queryCacheExpirationTime;
|
|
107
|
+
this._operationLoader = (_options$operationLoa = options === null || options === void 0 ? void 0 : options.operationLoader) !== null && _options$operationLoa !== void 0 ? _options$operationLoa : null;
|
|
94
108
|
this._optimisticSource = null;
|
|
95
109
|
this._recordSource = source;
|
|
96
110
|
this._releaseBuffer = [];
|
|
97
111
|
this._roots = new Map();
|
|
98
112
|
this._shouldScheduleGC = false;
|
|
99
113
|
this._subscriptions = new Set();
|
|
100
|
-
this._updatedConnectionIDs = {};
|
|
101
114
|
this._updatedRecordIDs = {};
|
|
115
|
+
initializeRecordSource(this._recordSource);
|
|
102
116
|
}
|
|
103
117
|
|
|
104
118
|
var _proto = RelayModernStore.prototype;
|
|
@@ -109,20 +123,8 @@ function () {
|
|
|
109
123
|
return (_this$_optimisticSour = this._optimisticSource) !== null && _this$_optimisticSour !== void 0 ? _this$_optimisticSour : this._recordSource;
|
|
110
124
|
};
|
|
111
125
|
|
|
112
|
-
_proto.getConnectionEvents_UNSTABLE = function getConnectionEvents_UNSTABLE(connectionID) {
|
|
113
|
-
var events = this._connectionEvents.get(connectionID);
|
|
114
|
-
|
|
115
|
-
if (events != null) {
|
|
116
|
-
var _events$optimistic;
|
|
117
|
-
|
|
118
|
-
return (_events$optimistic = events.optimistic) !== null && _events$optimistic !== void 0 ? _events$optimistic : events["final"];
|
|
119
|
-
}
|
|
120
|
-
};
|
|
121
|
-
|
|
122
126
|
_proto.check = function check(operation, options) {
|
|
123
|
-
var _this
|
|
124
|
-
|
|
125
|
-
var _this$_optimisticSour2, _ref5, _ref6;
|
|
127
|
+
var _this$_optimisticSour2, _options$target, _options$handlers;
|
|
126
128
|
|
|
127
129
|
var selector = operation.root;
|
|
128
130
|
var source = (_this$_optimisticSour2 = this._optimisticSource) !== null && _this$_optimisticSour2 !== void 0 ? _this$_optimisticSour2 : this._recordSource;
|
|
@@ -136,58 +138,68 @@ function () {
|
|
|
136
138
|
// If so, check if the operation we're checking was last written
|
|
137
139
|
// before or after invalidation occured.
|
|
138
140
|
if (operationLastWrittenAt == null || operationLastWrittenAt <= globalInvalidationEpoch) {
|
|
139
|
-
// If the operation was written /before/ global invalidation
|
|
141
|
+
// If the operation was written /before/ global invalidation occurred,
|
|
140
142
|
// or if this operation has never been written to the store before,
|
|
141
143
|
// we will consider the data for this operation to be stale
|
|
142
|
-
//
|
|
143
|
-
return
|
|
144
|
+
// (i.e. not resolvable from the store).
|
|
145
|
+
return {
|
|
146
|
+
status: 'stale'
|
|
147
|
+
};
|
|
144
148
|
}
|
|
145
149
|
}
|
|
146
150
|
|
|
147
|
-
var target = (
|
|
148
|
-
var handlers = (
|
|
149
|
-
var operationAvailability = DataChecker.check(source, target, selector, handlers, this._operationLoader, this._getDataID
|
|
150
|
-
|
|
151
|
-
});
|
|
152
|
-
return getAvailablityStatus(operationAvailability, operationLastWrittenAt);
|
|
151
|
+
var target = (_options$target = options === null || options === void 0 ? void 0 : options.target) !== null && _options$target !== void 0 ? _options$target : source;
|
|
152
|
+
var handlers = (_options$handlers = options === null || options === void 0 ? void 0 : options.handlers) !== null && _options$handlers !== void 0 ? _options$handlers : [];
|
|
153
|
+
var operationAvailability = DataChecker.check(source, target, selector, handlers, this._operationLoader, this._getDataID);
|
|
154
|
+
return getAvailabilityStatus(operationAvailability, operationLastWrittenAt, rootEntry === null || rootEntry === void 0 ? void 0 : rootEntry.fetchTime, this._queryCacheExpirationTime);
|
|
153
155
|
};
|
|
154
156
|
|
|
155
157
|
_proto.retain = function retain(operation) {
|
|
156
158
|
var _this2 = this;
|
|
157
159
|
|
|
158
160
|
var id = operation.request.identifier;
|
|
161
|
+
var disposed = false;
|
|
159
162
|
|
|
160
163
|
var dispose = function dispose() {
|
|
161
|
-
//
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
_this2._releaseBuffer.push(id); // Only when the release buffer is full do we actually:
|
|
166
|
-
// - extract the least recent operation in the release buffer
|
|
167
|
-
// - attempt to release it and run GC if it's no longer referenced
|
|
168
|
-
// (refCount reached 0).
|
|
164
|
+
// Ensure each retain can only dispose once
|
|
165
|
+
if (disposed) {
|
|
166
|
+
return;
|
|
167
|
+
}
|
|
169
168
|
|
|
169
|
+
disposed = true; // For Flow: guard against the entry somehow not existing
|
|
170
170
|
|
|
171
|
-
|
|
172
|
-
var _id = _this2._releaseBuffer.shift();
|
|
171
|
+
var rootEntry = _this2._roots.get(id);
|
|
173
172
|
|
|
174
|
-
|
|
173
|
+
if (rootEntry == null) {
|
|
174
|
+
return;
|
|
175
|
+
} // Decrement the ref count: if it becomes zero it is eligible
|
|
176
|
+
// for release.
|
|
175
177
|
|
|
176
|
-
if (_rootEntry == null) {
|
|
177
|
-
// If operation has already been fully released, we don't need
|
|
178
|
-
// to do anything.
|
|
179
|
-
return;
|
|
180
|
-
}
|
|
181
178
|
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
179
|
+
rootEntry.refCount--;
|
|
180
|
+
|
|
181
|
+
if (rootEntry.refCount === 0) {
|
|
182
|
+
var _queryCacheExpirationTime = _this2._queryCacheExpirationTime;
|
|
183
|
+
|
|
184
|
+
var rootEntryIsStale = rootEntry.fetchTime != null && _queryCacheExpirationTime != null && rootEntry.fetchTime <= Date.now() - _queryCacheExpirationTime;
|
|
185
|
+
|
|
186
|
+
if (rootEntryIsStale) {
|
|
187
|
+
_this2._roots["delete"](id);
|
|
189
188
|
|
|
190
189
|
_this2._scheduleGC();
|
|
190
|
+
} else {
|
|
191
|
+
_this2._releaseBuffer.push(id); // If the release buffer is now over-full, remove the least-recently
|
|
192
|
+
// added entry and schedule a GC. Note that all items in the release
|
|
193
|
+
// buffer have a refCount of 0.
|
|
194
|
+
|
|
195
|
+
|
|
196
|
+
if (_this2._releaseBuffer.length > _this2._gcReleaseBufferSize) {
|
|
197
|
+
var _id = _this2._releaseBuffer.shift();
|
|
198
|
+
|
|
199
|
+
_this2._roots["delete"](_id);
|
|
200
|
+
|
|
201
|
+
_this2._scheduleGC();
|
|
202
|
+
}
|
|
191
203
|
}
|
|
192
204
|
}
|
|
193
205
|
};
|
|
@@ -195,14 +207,24 @@ function () {
|
|
|
195
207
|
var rootEntry = this._roots.get(id);
|
|
196
208
|
|
|
197
209
|
if (rootEntry != null) {
|
|
198
|
-
|
|
210
|
+
if (rootEntry.refCount === 0) {
|
|
211
|
+
// This entry should be in the release buffer, but it no longer belongs
|
|
212
|
+
// there since it's retained. Remove it to maintain the invariant that
|
|
213
|
+
// all release buffer entries have a refCount of 0.
|
|
214
|
+
this._releaseBuffer = this._releaseBuffer.filter(function (_id) {
|
|
215
|
+
return _id !== id;
|
|
216
|
+
});
|
|
217
|
+
} // If we've previously retained this operation, increment the refCount
|
|
218
|
+
|
|
219
|
+
|
|
199
220
|
rootEntry.refCount += 1;
|
|
200
221
|
} else {
|
|
201
222
|
// Otherwise create a new entry for the operation
|
|
202
223
|
this._roots.set(id, {
|
|
203
224
|
operation: operation,
|
|
204
|
-
refCount:
|
|
205
|
-
epoch: null
|
|
225
|
+
refCount: 1,
|
|
226
|
+
epoch: null,
|
|
227
|
+
fetchTime: null
|
|
206
228
|
});
|
|
207
229
|
}
|
|
208
230
|
|
|
@@ -220,14 +242,22 @@ function () {
|
|
|
220
242
|
}
|
|
221
243
|
|
|
222
244
|
return snapshot;
|
|
223
|
-
} // This method will return a list of updated owners
|
|
245
|
+
} // This method will return a list of updated owners from the subscriptions
|
|
224
246
|
;
|
|
225
247
|
|
|
226
248
|
_proto.notify = function notify(sourceOperation, invalidateStore) {
|
|
227
249
|
var _this3 = this;
|
|
228
250
|
|
|
229
|
-
|
|
251
|
+
var log = this.__log;
|
|
252
|
+
|
|
253
|
+
if (log != null) {
|
|
254
|
+
log({
|
|
255
|
+
name: 'store.notify.start'
|
|
256
|
+
});
|
|
257
|
+
} // Increment the current write when notifying after executing
|
|
230
258
|
// a set of changes to the store.
|
|
259
|
+
|
|
260
|
+
|
|
231
261
|
this._currentWriteEpoch++;
|
|
232
262
|
|
|
233
263
|
if (invalidateStore === true) {
|
|
@@ -249,14 +279,14 @@ function () {
|
|
|
249
279
|
_this3._updateInvalidationSubscription(subscription, invalidateStore === true);
|
|
250
280
|
});
|
|
251
281
|
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
282
|
+
if (log != null) {
|
|
283
|
+
log({
|
|
284
|
+
name: 'store.notify.complete',
|
|
285
|
+
updatedRecordIDs: this._updatedRecordIDs,
|
|
286
|
+
invalidatedRecordIDs: this._invalidatedRecordIDs
|
|
287
|
+
});
|
|
288
|
+
}
|
|
258
289
|
|
|
259
|
-
this._updatedConnectionIDs = {};
|
|
260
290
|
this._updatedRecordIDs = {};
|
|
261
291
|
|
|
262
292
|
this._invalidatedRecordIDs.clear(); // If a source operation was provided (indicating the operation
|
|
@@ -276,6 +306,20 @@ function () {
|
|
|
276
306
|
|
|
277
307
|
if (rootEntry != null) {
|
|
278
308
|
rootEntry.epoch = this._currentWriteEpoch;
|
|
309
|
+
rootEntry.fetchTime = Date.now();
|
|
310
|
+
} else if (sourceOperation.request.node.params.operationKind === 'query' && this._gcReleaseBufferSize > 0 && this._releaseBuffer.length < this._gcReleaseBufferSize) {
|
|
311
|
+
// The operation isn't retained but there is space in the release buffer:
|
|
312
|
+
// temporarily track this operation in case the data can be reused soon.
|
|
313
|
+
var temporaryRootEntry = {
|
|
314
|
+
operation: sourceOperation,
|
|
315
|
+
refCount: 0,
|
|
316
|
+
epoch: this._currentWriteEpoch,
|
|
317
|
+
fetchTime: Date.now()
|
|
318
|
+
};
|
|
319
|
+
|
|
320
|
+
this._releaseBuffer.push(id);
|
|
321
|
+
|
|
322
|
+
this._roots.set(id, temporaryRootEntry);
|
|
279
323
|
}
|
|
280
324
|
}
|
|
281
325
|
|
|
@@ -283,34 +327,28 @@ function () {
|
|
|
283
327
|
};
|
|
284
328
|
|
|
285
329
|
_proto.publish = function publish(source, idsMarkedForInvalidation) {
|
|
286
|
-
var _this4 = this;
|
|
287
|
-
|
|
288
330
|
var _this$_optimisticSour3;
|
|
289
331
|
|
|
290
332
|
var target = (_this$_optimisticSour3 = this._optimisticSource) !== null && _this$_optimisticSour3 !== void 0 ? _this$_optimisticSour3 : this._recordSource;
|
|
291
333
|
updateTargetFromSource(target, source, // We increment the current epoch at the end of the set of updates,
|
|
292
334
|
// in notify(). Here, we pass what will be the incremented value of
|
|
293
335
|
// the epoch to use to write to invalidated records.
|
|
294
|
-
this._currentWriteEpoch + 1, idsMarkedForInvalidation, this._updatedRecordIDs, this._invalidatedRecordIDs);
|
|
295
|
-
|
|
296
|
-
this._connectionSubscriptions.forEach(function (subscription, id) {
|
|
297
|
-
var hasStoreUpdates = hasOverlappingIDs(subscription.snapshot.seenRecords, _this4._updatedRecordIDs);
|
|
298
|
-
|
|
299
|
-
if (!hasStoreUpdates) {
|
|
300
|
-
return;
|
|
301
|
-
}
|
|
336
|
+
this._currentWriteEpoch + 1, idsMarkedForInvalidation, this._updatedRecordIDs, this._invalidatedRecordIDs); // NOTE: log *after* processing the source so that even if a bad log function
|
|
337
|
+
// mutates the source, it doesn't affect Relay processing of it.
|
|
302
338
|
|
|
303
|
-
|
|
339
|
+
var log = this.__log;
|
|
304
340
|
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
341
|
+
if (log != null) {
|
|
342
|
+
log({
|
|
343
|
+
name: 'store.publish',
|
|
344
|
+
source: source,
|
|
345
|
+
optimistic: target === this._optimisticSource
|
|
346
|
+
});
|
|
347
|
+
}
|
|
310
348
|
};
|
|
311
349
|
|
|
312
350
|
_proto.subscribe = function subscribe(snapshot, callback) {
|
|
313
|
-
var
|
|
351
|
+
var _this4 = this;
|
|
314
352
|
|
|
315
353
|
var subscription = {
|
|
316
354
|
backup: null,
|
|
@@ -320,7 +358,7 @@ function () {
|
|
|
320
358
|
};
|
|
321
359
|
|
|
322
360
|
var dispose = function dispose() {
|
|
323
|
-
|
|
361
|
+
_this4._subscriptions["delete"](subscription);
|
|
324
362
|
};
|
|
325
363
|
|
|
326
364
|
this._subscriptions.add(subscription);
|
|
@@ -331,18 +369,23 @@ function () {
|
|
|
331
369
|
};
|
|
332
370
|
|
|
333
371
|
_proto.holdGC = function holdGC() {
|
|
334
|
-
var
|
|
372
|
+
var _this5 = this;
|
|
373
|
+
|
|
374
|
+
if (this._gcRun) {
|
|
375
|
+
this._gcRun = null;
|
|
376
|
+
this._shouldScheduleGC = true;
|
|
377
|
+
}
|
|
335
378
|
|
|
336
379
|
this._gcHoldCounter++;
|
|
337
380
|
|
|
338
381
|
var dispose = function dispose() {
|
|
339
|
-
if (
|
|
340
|
-
|
|
382
|
+
if (_this5._gcHoldCounter > 0) {
|
|
383
|
+
_this5._gcHoldCounter--;
|
|
341
384
|
|
|
342
|
-
if (
|
|
343
|
-
|
|
385
|
+
if (_this5._gcHoldCounter === 0 && _this5._shouldScheduleGC) {
|
|
386
|
+
_this5._scheduleGC();
|
|
344
387
|
|
|
345
|
-
|
|
388
|
+
_this5._shouldScheduleGC = false;
|
|
346
389
|
}
|
|
347
390
|
}
|
|
348
391
|
};
|
|
@@ -397,13 +440,13 @@ function () {
|
|
|
397
440
|
};
|
|
398
441
|
|
|
399
442
|
_proto.lookupInvalidationState = function lookupInvalidationState(dataIDs) {
|
|
400
|
-
var
|
|
443
|
+
var _this6 = this;
|
|
401
444
|
|
|
402
445
|
var invalidations = new Map();
|
|
403
446
|
dataIDs.forEach(function (dataID) {
|
|
404
447
|
var _RelayModernRecord$ge;
|
|
405
448
|
|
|
406
|
-
var record =
|
|
449
|
+
var record = _this6.getSource().get(dataID);
|
|
407
450
|
|
|
408
451
|
invalidations.set(dataID, (_RelayModernRecord$ge = RelayModernRecord.getInvalidationEpoch(record)) !== null && _RelayModernRecord$ge !== void 0 ? _RelayModernRecord$ge : null);
|
|
409
452
|
});
|
|
@@ -424,12 +467,11 @@ function () {
|
|
|
424
467
|
} // Check if the invalidation state for any of the ids has changed.
|
|
425
468
|
|
|
426
469
|
|
|
427
|
-
var
|
|
428
|
-
|
|
429
|
-
var _iteratorError = undefined;
|
|
470
|
+
var _iterator = _createForOfIteratorHelper(prevInvalidationState.dataIDs),
|
|
471
|
+
_step;
|
|
430
472
|
|
|
431
473
|
try {
|
|
432
|
-
for (
|
|
474
|
+
for (_iterator.s(); !(_step = _iterator.n()).done;) {
|
|
433
475
|
var dataID = _step.value;
|
|
434
476
|
|
|
435
477
|
if (currentInvalidations.get(dataID) !== prevInvalidations.get(dataID)) {
|
|
@@ -437,25 +479,16 @@ function () {
|
|
|
437
479
|
}
|
|
438
480
|
}
|
|
439
481
|
} catch (err) {
|
|
440
|
-
|
|
441
|
-
_iteratorError = err;
|
|
482
|
+
_iterator.e(err);
|
|
442
483
|
} finally {
|
|
443
|
-
|
|
444
|
-
if (!_iteratorNormalCompletion && _iterator["return"] != null) {
|
|
445
|
-
_iterator["return"]();
|
|
446
|
-
}
|
|
447
|
-
} finally {
|
|
448
|
-
if (_didIteratorError) {
|
|
449
|
-
throw _iteratorError;
|
|
450
|
-
}
|
|
451
|
-
}
|
|
484
|
+
_iterator.f();
|
|
452
485
|
}
|
|
453
486
|
|
|
454
487
|
return false;
|
|
455
488
|
};
|
|
456
489
|
|
|
457
490
|
_proto.subscribeToInvalidationState = function subscribeToInvalidationState(invalidationState, callback) {
|
|
458
|
-
var
|
|
491
|
+
var _this7 = this;
|
|
459
492
|
|
|
460
493
|
var subscription = {
|
|
461
494
|
callback: callback,
|
|
@@ -463,7 +496,7 @@ function () {
|
|
|
463
496
|
};
|
|
464
497
|
|
|
465
498
|
var dispose = function dispose() {
|
|
466
|
-
|
|
499
|
+
_this7._invalidationSubscriptions["delete"](subscription);
|
|
467
500
|
};
|
|
468
501
|
|
|
469
502
|
this._invalidationSubscriptions.add(subscription);
|
|
@@ -474,13 +507,13 @@ function () {
|
|
|
474
507
|
};
|
|
475
508
|
|
|
476
509
|
_proto._updateInvalidationSubscription = function _updateInvalidationSubscription(subscription, invalidatedStore) {
|
|
477
|
-
var
|
|
510
|
+
var _this8 = this;
|
|
478
511
|
|
|
479
512
|
var callback = subscription.callback,
|
|
480
513
|
invalidationState = subscription.invalidationState;
|
|
481
514
|
var dataIDs = invalidationState.dataIDs;
|
|
482
515
|
var isSubscribedToInvalidatedIDs = invalidatedStore || dataIDs.some(function (dataID) {
|
|
483
|
-
return
|
|
516
|
+
return _this8._invalidatedRecordIDs.has(dataID);
|
|
484
517
|
});
|
|
485
518
|
|
|
486
519
|
if (!isSubscribedToInvalidatedIDs) {
|
|
@@ -490,286 +523,67 @@ function () {
|
|
|
490
523
|
callback();
|
|
491
524
|
};
|
|
492
525
|
|
|
493
|
-
_proto.
|
|
494
|
-
var
|
|
495
|
-
|
|
496
|
-
!RelayFeatureFlags.ENABLE_CONNECTION_RESOLVERS ? process.env.NODE_ENV !== "production" ? invariant(false, 'RelayModernStore: Connection resolvers are not yet supported.') : invariant(false) : void 0;
|
|
497
|
-
var id = connectionReference.id;
|
|
498
|
-
var initialState = resolver.initialize();
|
|
499
|
-
|
|
500
|
-
var connectionEvents = this._connectionEvents.get(id);
|
|
501
|
-
|
|
502
|
-
var events = connectionEvents != null ? (_connectionEvents$opt = connectionEvents.optimistic) !== null && _connectionEvents$opt !== void 0 ? _connectionEvents$opt : connectionEvents["final"] : null;
|
|
503
|
-
var initialSnapshot = {
|
|
504
|
-
edgeSnapshots: {},
|
|
505
|
-
id: id,
|
|
506
|
-
reference: connectionReference,
|
|
507
|
-
seenRecords: {},
|
|
508
|
-
state: initialState
|
|
509
|
-
};
|
|
510
|
-
|
|
511
|
-
if (events == null || events.length === 0) {
|
|
512
|
-
return initialSnapshot;
|
|
513
|
-
}
|
|
514
|
-
|
|
515
|
-
return this._reduceConnection_UNSTABLE(resolver, connectionReference, initialSnapshot, events);
|
|
516
|
-
};
|
|
517
|
-
|
|
518
|
-
_proto.subscribeConnection_UNSTABLE = function subscribeConnection_UNSTABLE(snapshot, resolver, callback) {
|
|
519
|
-
var _this10 = this;
|
|
520
|
-
|
|
521
|
-
!RelayFeatureFlags.ENABLE_CONNECTION_RESOLVERS ? process.env.NODE_ENV !== "production" ? invariant(false, 'RelayModernStore: Connection resolvers are not yet supported.') : invariant(false) : void 0;
|
|
522
|
-
var id = String(this._index++);
|
|
523
|
-
var subscription = {
|
|
524
|
-
backup: null,
|
|
525
|
-
callback: callback,
|
|
526
|
-
id: id,
|
|
527
|
-
resolver: resolver,
|
|
528
|
-
snapshot: snapshot,
|
|
529
|
-
stale: false
|
|
530
|
-
};
|
|
531
|
-
|
|
532
|
-
var dispose = function dispose() {
|
|
533
|
-
_this10._connectionSubscriptions["delete"](id);
|
|
534
|
-
};
|
|
535
|
-
|
|
536
|
-
this._connectionSubscriptions.set(id, subscription);
|
|
537
|
-
|
|
538
|
-
return {
|
|
539
|
-
dispose: dispose
|
|
540
|
-
};
|
|
541
|
-
};
|
|
526
|
+
_proto.snapshot = function snapshot() {
|
|
527
|
+
var _this9 = this;
|
|
542
528
|
|
|
543
|
-
|
|
544
|
-
var
|
|
529
|
+
!(this._optimisticSource == null) ? process.env.NODE_ENV !== "production" ? invariant(false, 'RelayModernStore: Unexpected call to snapshot() while a previous ' + 'snapshot exists.') : invariant(false) : void 0;
|
|
530
|
+
var log = this.__log;
|
|
545
531
|
|
|
546
|
-
if (
|
|
547
|
-
|
|
532
|
+
if (log != null) {
|
|
533
|
+
log({
|
|
534
|
+
name: 'store.snapshot'
|
|
535
|
+
});
|
|
548
536
|
}
|
|
549
537
|
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
|
|
562
|
-
|
|
563
|
-
|
|
564
|
-
|
|
565
|
-
if (connectionEvents == null) {
|
|
566
|
-
connectionEvents = {
|
|
567
|
-
"final": [],
|
|
568
|
-
optimistic: null
|
|
569
|
-
};
|
|
570
|
-
|
|
571
|
-
_this11._connectionEvents.set(connectionID, connectionEvents);
|
|
572
|
-
}
|
|
573
|
-
|
|
574
|
-
if (final) {
|
|
575
|
-
connectionEvents["final"].push(event);
|
|
576
|
-
} else {
|
|
577
|
-
var optimisticEvents = connectionEvents.optimistic;
|
|
578
|
-
|
|
579
|
-
if (optimisticEvents == null) {
|
|
580
|
-
optimisticEvents = connectionEvents["final"].slice();
|
|
581
|
-
connectionEvents.optimistic = optimisticEvents;
|
|
582
|
-
}
|
|
583
|
-
|
|
584
|
-
optimisticEvents.push(event);
|
|
585
|
-
}
|
|
586
|
-
});
|
|
587
|
-
|
|
588
|
-
this._connectionSubscriptions.forEach(function (subscription, id) {
|
|
589
|
-
var pendingEvents = pendingConnectionEvents.get(subscription.snapshot.reference.id);
|
|
590
|
-
|
|
591
|
-
if (pendingEvents == null) {
|
|
538
|
+
this._subscriptions.forEach(function (subscription) {
|
|
539
|
+
// Backup occurs after writing a new "final" payload(s) and before (re)applying
|
|
540
|
+
// optimistic changes. Each subscription's `snapshot` represents what was *last
|
|
541
|
+
// published to the subscriber*, which notably may include previous optimistic
|
|
542
|
+
// updates. Therefore a subscription can be in any of the following states:
|
|
543
|
+
// - stale=true: This subscription was restored to a different value than
|
|
544
|
+
// `snapshot`. That means this subscription has changes relative to its base,
|
|
545
|
+
// but its base has changed (we just applied a final payload): recompute
|
|
546
|
+
// a backup so that we can later restore to the state the subscription
|
|
547
|
+
// should be in.
|
|
548
|
+
// - stale=false: This subscription was restored to the same value than
|
|
549
|
+
// `snapshot`. That means this subscription does *not* have changes relative
|
|
550
|
+
// to its base, so the current `snapshot` is valid to use as a backup.
|
|
551
|
+
if (!subscription.stale) {
|
|
552
|
+
subscription.backup = subscription.snapshot;
|
|
592
553
|
return;
|
|
593
554
|
}
|
|
594
555
|
|
|
595
|
-
var
|
|
556
|
+
var snapshot = subscription.snapshot;
|
|
557
|
+
var backup = RelayReader.read(_this9.getSource(), snapshot.selector);
|
|
558
|
+
var nextData = recycleNodesInto(snapshot.data, backup.data);
|
|
559
|
+
backup.data = nextData; // backup owns the snapshot and can safely mutate
|
|
596
560
|
|
|
597
|
-
|
|
598
|
-
subscription.snapshot = nextSnapshot;
|
|
599
|
-
subscription.stale = true;
|
|
600
|
-
}
|
|
561
|
+
subscription.backup = backup;
|
|
601
562
|
});
|
|
602
|
-
};
|
|
603
|
-
|
|
604
|
-
_proto._updateConnection_UNSTABLE = function _updateConnection_UNSTABLE(resolver, snapshot, source, pendingEvents) {
|
|
605
|
-
var _pendingEvents;
|
|
606
563
|
|
|
607
|
-
|
|
608
|
-
|
|
609
|
-
|
|
610
|
-
|
|
611
|
-
if (process.env.NODE_ENV !== "production") {
|
|
612
|
-
deepFreeze(nextSnapshot);
|
|
564
|
+
if (this._gcRun) {
|
|
565
|
+
this._gcRun = null;
|
|
566
|
+
this._shouldScheduleGC = true;
|
|
613
567
|
}
|
|
614
568
|
|
|
615
|
-
|
|
616
|
-
return (0, _objectSpread2["default"])({}, nextSnapshot, {
|
|
617
|
-
state: state
|
|
618
|
-
});
|
|
619
|
-
}
|
|
569
|
+
this._optimisticSource = RelayOptimisticRecordSource.create(this.getSource());
|
|
620
570
|
};
|
|
621
571
|
|
|
622
|
-
_proto.
|
|
623
|
-
|
|
624
|
-
|
|
625
|
-
var _edgesField$concreteT;
|
|
626
|
-
|
|
627
|
-
var source = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : null;
|
|
628
|
-
var edgesField = connectionReference.edgesField,
|
|
629
|
-
id = connectionReference.id,
|
|
630
|
-
variables = connectionReference.variables;
|
|
631
|
-
var fragment = {
|
|
632
|
-
kind: 'Fragment',
|
|
633
|
-
name: edgesField.name,
|
|
634
|
-
type: (_edgesField$concreteT = edgesField.concreteType) !== null && _edgesField$concreteT !== void 0 ? _edgesField$concreteT : '__Any',
|
|
635
|
-
metadata: null,
|
|
636
|
-
argumentDefinitions: [],
|
|
637
|
-
selections: edgesField.selections
|
|
638
|
-
};
|
|
639
|
-
var seenRecords = {};
|
|
640
|
-
var edgeSnapshots = (0, _objectSpread2["default"])({}, snapshot.edgeSnapshots);
|
|
641
|
-
var initialState = snapshot.state;
|
|
642
|
-
|
|
643
|
-
if (source) {
|
|
644
|
-
var edgeData = {};
|
|
645
|
-
Object.keys(edgeSnapshots).forEach(function (edgeID) {
|
|
646
|
-
var prevSnapshot = edgeSnapshots[edgeID];
|
|
647
|
-
var nextSnapshot = RelayReader.read(_this12.getSource(), createReaderSelector(fragment, edgeID, variables, prevSnapshot.selector.owner));
|
|
648
|
-
var data = recycleNodesInto(prevSnapshot.data, nextSnapshot.data);
|
|
649
|
-
nextSnapshot = {
|
|
650
|
-
data: data,
|
|
651
|
-
isMissingData: nextSnapshot.isMissingData,
|
|
652
|
-
seenRecords: nextSnapshot.seenRecords,
|
|
653
|
-
selector: nextSnapshot.selector
|
|
654
|
-
};
|
|
655
|
-
|
|
656
|
-
if (data !== prevSnapshot.data) {
|
|
657
|
-
edgeData[edgeID] = data;
|
|
658
|
-
/* $FlowFixMe(>=0.111.0) This comment suppresses an error found when
|
|
659
|
-
* Flow v0.111.0 was deployed. To see the error, delete this comment
|
|
660
|
-
* and run Flow. */
|
|
572
|
+
_proto.restore = function restore() {
|
|
573
|
+
!(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;
|
|
574
|
+
var log = this.__log;
|
|
661
575
|
|
|
662
|
-
|
|
663
|
-
|
|
576
|
+
if (log != null) {
|
|
577
|
+
log({
|
|
578
|
+
name: 'store.restore'
|
|
664
579
|
});
|
|
665
|
-
|
|
666
|
-
if (Object.keys(edgeData).length !== 0) {
|
|
667
|
-
initialState = resolver.reduce(initialState, {
|
|
668
|
-
kind: 'update',
|
|
669
|
-
edgeData: edgeData
|
|
670
|
-
});
|
|
671
|
-
}
|
|
672
580
|
}
|
|
673
581
|
|
|
674
|
-
var state = events.reduce(function (prevState, event) {
|
|
675
|
-
if (event.kind === 'fetch') {
|
|
676
|
-
var edges = [];
|
|
677
|
-
event.edgeIDs.forEach(function (edgeID) {
|
|
678
|
-
if (edgeID == null) {
|
|
679
|
-
edges.push(edgeID);
|
|
680
|
-
return;
|
|
681
|
-
}
|
|
682
|
-
|
|
683
|
-
var edgeSnapshot = RelayReader.read(_this12.getSource(), createReaderSelector(fragment, edgeID, variables, event.request));
|
|
684
|
-
Object.assign(seenRecords, edgeSnapshot.seenRecords);
|
|
685
|
-
var itemData = edgeSnapshot.data;
|
|
686
|
-
/* $FlowFixMe(>=0.111.0) This comment suppresses an error found
|
|
687
|
-
* when Flow v0.111.0 was deployed. To see the error, delete this
|
|
688
|
-
* comment and run Flow. */
|
|
689
|
-
|
|
690
|
-
edgeSnapshots[edgeID] = edgeSnapshot;
|
|
691
|
-
edges.push(itemData);
|
|
692
|
-
});
|
|
693
|
-
return resolver.reduce(prevState, {
|
|
694
|
-
kind: 'fetch',
|
|
695
|
-
args: event.args,
|
|
696
|
-
edges: edges,
|
|
697
|
-
pageInfo: event.pageInfo,
|
|
698
|
-
stream: event.stream
|
|
699
|
-
});
|
|
700
|
-
} else if (event.kind === 'insert') {
|
|
701
|
-
var edgeSnapshot = RelayReader.read(_this12.getSource(), createReaderSelector(fragment, event.edgeID, variables, event.request));
|
|
702
|
-
Object.assign(seenRecords, edgeSnapshot.seenRecords);
|
|
703
|
-
var itemData = edgeSnapshot.data;
|
|
704
|
-
/* $FlowFixMe(>=0.111.0) This comment suppresses an error found when
|
|
705
|
-
* Flow v0.111.0 was deployed. To see the error, delete this comment
|
|
706
|
-
* and run Flow. */
|
|
707
|
-
|
|
708
|
-
edgeSnapshots[event.edgeID] = edgeSnapshot;
|
|
709
|
-
return resolver.reduce(prevState, {
|
|
710
|
-
args: event.args,
|
|
711
|
-
edge: itemData,
|
|
712
|
-
kind: 'insert'
|
|
713
|
-
});
|
|
714
|
-
} else if (event.kind === 'stream.edge') {
|
|
715
|
-
var _edgeSnapshot = RelayReader.read(_this12.getSource(), createReaderSelector(fragment, event.edgeID, variables, event.request));
|
|
716
|
-
|
|
717
|
-
Object.assign(seenRecords, _edgeSnapshot.seenRecords);
|
|
718
|
-
var _itemData = _edgeSnapshot.data;
|
|
719
|
-
/* $FlowFixMe(>=0.111.0) This comment suppresses an error found when
|
|
720
|
-
* Flow v0.111.0 was deployed. To see the error, delete this comment
|
|
721
|
-
* and run Flow. */
|
|
722
|
-
|
|
723
|
-
edgeSnapshots[event.edgeID] = _edgeSnapshot;
|
|
724
|
-
return resolver.reduce(prevState, {
|
|
725
|
-
args: event.args,
|
|
726
|
-
edge: _itemData,
|
|
727
|
-
index: event.index,
|
|
728
|
-
kind: 'stream.edge'
|
|
729
|
-
});
|
|
730
|
-
} else if (event.kind === 'stream.pageInfo') {
|
|
731
|
-
return resolver.reduce(prevState, {
|
|
732
|
-
args: event.args,
|
|
733
|
-
kind: 'stream.pageInfo',
|
|
734
|
-
pageInfo: event.pageInfo
|
|
735
|
-
});
|
|
736
|
-
} else {
|
|
737
|
-
event.kind;
|
|
738
|
-
!false ? process.env.NODE_ENV !== "production" ? invariant(false, 'RelayModernStore: Unexpected connection event kind `%s`.', event.kind) : invariant(false) : void 0;
|
|
739
|
-
}
|
|
740
|
-
}, initialState);
|
|
741
|
-
return {
|
|
742
|
-
edgeSnapshots: edgeSnapshots,
|
|
743
|
-
id: id,
|
|
744
|
-
reference: connectionReference,
|
|
745
|
-
seenRecords: seenRecords,
|
|
746
|
-
state: state
|
|
747
|
-
};
|
|
748
|
-
};
|
|
749
|
-
|
|
750
|
-
_proto.snapshot = function snapshot() {
|
|
751
|
-
!(this._optimisticSource == null) ? process.env.NODE_ENV !== "production" ? invariant(false, 'RelayModernStore: Unexpected call to snapshot() while a previous ' + 'snapshot exists.') : invariant(false) : void 0;
|
|
752
|
-
|
|
753
|
-
this._connectionSubscriptions.forEach(function (subscription) {
|
|
754
|
-
subscription.backup = subscription.snapshot;
|
|
755
|
-
});
|
|
756
|
-
|
|
757
|
-
this._subscriptions.forEach(function (subscription) {
|
|
758
|
-
subscription.backup = subscription.snapshot;
|
|
759
|
-
});
|
|
760
|
-
|
|
761
|
-
this._optimisticSource = RelayOptimisticRecordSource.create(this.getSource());
|
|
762
|
-
};
|
|
763
|
-
|
|
764
|
-
_proto.restore = function restore() {
|
|
765
|
-
var _this13 = this;
|
|
766
|
-
|
|
767
|
-
!(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;
|
|
768
582
|
this._optimisticSource = null;
|
|
769
583
|
|
|
770
|
-
this.
|
|
771
|
-
|
|
772
|
-
}
|
|
584
|
+
if (this._shouldScheduleGC) {
|
|
585
|
+
this._scheduleGC();
|
|
586
|
+
}
|
|
773
587
|
|
|
774
588
|
this._subscriptions.forEach(function (subscription) {
|
|
775
589
|
var backup = subscription.backup;
|
|
@@ -790,127 +604,104 @@ function () {
|
|
|
790
604
|
subscription.stale = true;
|
|
791
605
|
}
|
|
792
606
|
});
|
|
793
|
-
|
|
794
|
-
this._connectionSubscriptions.forEach(function (subscription) {
|
|
795
|
-
var backup = subscription.backup;
|
|
796
|
-
subscription.backup = null;
|
|
797
|
-
|
|
798
|
-
if (backup) {
|
|
799
|
-
if (backup.state !== subscription.snapshot.state) {
|
|
800
|
-
subscription.stale = true;
|
|
801
|
-
}
|
|
802
|
-
|
|
803
|
-
subscription.snapshot = backup;
|
|
804
|
-
} else {
|
|
805
|
-
// This subscription was established after the creation of the
|
|
806
|
-
// connection snapshot so there's nothing to restore to. Recreate the
|
|
807
|
-
// connection from scratch and check ifs value changes.
|
|
808
|
-
var baseSnapshot = _this13.lookupConnection_UNSTABLE(subscription.snapshot.reference, subscription.resolver);
|
|
809
|
-
|
|
810
|
-
var nextState = recycleNodesInto(subscription.snapshot.state, baseSnapshot.state);
|
|
811
|
-
|
|
812
|
-
if (nextState !== subscription.snapshot.state) {
|
|
813
|
-
subscription.stale = true;
|
|
814
|
-
}
|
|
815
|
-
|
|
816
|
-
subscription.snapshot = (0, _objectSpread2["default"])({}, baseSnapshot, {
|
|
817
|
-
state: nextState
|
|
818
|
-
});
|
|
819
|
-
}
|
|
820
|
-
});
|
|
821
607
|
};
|
|
822
608
|
|
|
823
609
|
_proto._scheduleGC = function _scheduleGC() {
|
|
824
|
-
var _this14 = this;
|
|
825
|
-
|
|
826
610
|
if (this._gcHoldCounter > 0) {
|
|
827
611
|
this._shouldScheduleGC = true;
|
|
828
612
|
return;
|
|
829
613
|
}
|
|
830
614
|
|
|
831
|
-
if (this.
|
|
615
|
+
if (this._gcRun) {
|
|
832
616
|
return;
|
|
833
617
|
}
|
|
834
618
|
|
|
835
|
-
this.
|
|
836
|
-
|
|
837
|
-
this._gcScheduler(function () {
|
|
838
|
-
_this14.__gc();
|
|
619
|
+
this._gcRun = this._collect();
|
|
839
620
|
|
|
840
|
-
|
|
841
|
-
|
|
842
|
-
|
|
621
|
+
this._gcScheduler(this._gcStep);
|
|
622
|
+
}
|
|
623
|
+
/**
|
|
624
|
+
* Run a full GC synchronously.
|
|
625
|
+
*/
|
|
626
|
+
;
|
|
843
627
|
|
|
844
628
|
_proto.__gc = function __gc() {
|
|
845
|
-
var _this15 = this;
|
|
846
|
-
|
|
847
629
|
// Don't run GC while there are optimistic updates applied
|
|
848
630
|
if (this._optimisticSource != null) {
|
|
849
631
|
return;
|
|
850
632
|
}
|
|
851
633
|
|
|
852
|
-
var
|
|
853
|
-
var connectionReferences = new Set(); // Mark all records that are traversable from a root
|
|
854
|
-
|
|
855
|
-
this._roots.forEach(function (_ref7) {
|
|
856
|
-
var operation = _ref7.operation;
|
|
857
|
-
var selector = operation.root;
|
|
858
|
-
RelayReferenceMarker.mark(_this15._recordSource, selector, references, connectionReferences, function (id) {
|
|
859
|
-
return _this15.getConnectionEvents_UNSTABLE(id);
|
|
860
|
-
}, _this15._operationLoader);
|
|
861
|
-
});
|
|
634
|
+
var gcRun = this._collect();
|
|
862
635
|
|
|
863
|
-
|
|
864
|
-
|
|
865
|
-
this._recordSource.clear();
|
|
866
|
-
} else {
|
|
867
|
-
// Evict any unreferenced nodes
|
|
868
|
-
var storeIDs = this._recordSource.getRecordIDs();
|
|
869
|
-
|
|
870
|
-
for (var ii = 0; ii < storeIDs.length; ii++) {
|
|
871
|
-
var dataID = storeIDs[ii];
|
|
636
|
+
while (!gcRun.next().done) {}
|
|
637
|
+
};
|
|
872
638
|
|
|
873
|
-
|
|
874
|
-
|
|
875
|
-
|
|
876
|
-
|
|
877
|
-
|
|
639
|
+
_proto._collect = function* _collect() {
|
|
640
|
+
/* eslint-disable no-labels */
|
|
641
|
+
top: while (true) {
|
|
642
|
+
var startEpoch = this._currentWriteEpoch;
|
|
643
|
+
var references = new Set(); // Mark all records that are traversable from a root
|
|
878
644
|
|
|
879
|
-
|
|
880
|
-
|
|
881
|
-
} else {
|
|
882
|
-
// Evict any unreferenced connections
|
|
883
|
-
var _iteratorNormalCompletion2 = true;
|
|
884
|
-
var _didIteratorError2 = false;
|
|
885
|
-
var _iteratorError2 = undefined;
|
|
645
|
+
var _iterator2 = _createForOfIteratorHelper(this._roots.values()),
|
|
646
|
+
_step2;
|
|
886
647
|
|
|
887
648
|
try {
|
|
888
|
-
for (
|
|
889
|
-
var
|
|
649
|
+
for (_iterator2.s(); !(_step2 = _iterator2.n()).done;) {
|
|
650
|
+
var operation = _step2.value.operation;
|
|
651
|
+
var selector = operation.root;
|
|
652
|
+
RelayReferenceMarker.mark(this._recordSource, selector, references, this._operationLoader); // Yield for other work after each operation
|
|
653
|
+
|
|
654
|
+
yield; // If the store was updated, restart
|
|
890
655
|
|
|
891
|
-
if (
|
|
892
|
-
|
|
656
|
+
if (startEpoch !== this._currentWriteEpoch) {
|
|
657
|
+
continue top;
|
|
893
658
|
}
|
|
894
659
|
}
|
|
895
660
|
} catch (err) {
|
|
896
|
-
|
|
897
|
-
_iteratorError2 = err;
|
|
661
|
+
_iterator2.e(err);
|
|
898
662
|
} finally {
|
|
899
|
-
|
|
900
|
-
|
|
901
|
-
|
|
902
|
-
|
|
903
|
-
|
|
904
|
-
|
|
905
|
-
|
|
663
|
+
_iterator2.f();
|
|
664
|
+
}
|
|
665
|
+
|
|
666
|
+
var log = this.__log;
|
|
667
|
+
|
|
668
|
+
if (log != null) {
|
|
669
|
+
log({
|
|
670
|
+
name: 'store.gc',
|
|
671
|
+
references: references
|
|
672
|
+
});
|
|
673
|
+
} // Sweep records without references
|
|
674
|
+
|
|
675
|
+
|
|
676
|
+
if (references.size === 0) {
|
|
677
|
+
// Short-circuit if *nothing* is referenced
|
|
678
|
+
this._recordSource.clear();
|
|
679
|
+
} else {
|
|
680
|
+
// Evict any unreferenced nodes
|
|
681
|
+
var storeIDs = this._recordSource.getRecordIDs();
|
|
682
|
+
|
|
683
|
+
for (var ii = 0; ii < storeIDs.length; ii++) {
|
|
684
|
+
var dataID = storeIDs[ii];
|
|
685
|
+
|
|
686
|
+
if (!references.has(dataID)) {
|
|
687
|
+
this._recordSource.remove(dataID);
|
|
906
688
|
}
|
|
907
689
|
}
|
|
908
690
|
}
|
|
691
|
+
|
|
692
|
+
return;
|
|
909
693
|
}
|
|
910
694
|
};
|
|
911
695
|
|
|
912
696
|
return RelayModernStore;
|
|
913
697
|
}();
|
|
698
|
+
|
|
699
|
+
function initializeRecordSource(target) {
|
|
700
|
+
if (!target.has(ROOT_ID)) {
|
|
701
|
+
var rootRecord = RelayModernRecord.create(ROOT_ID, ROOT_TYPE);
|
|
702
|
+
target.set(ROOT_ID, rootRecord);
|
|
703
|
+
}
|
|
704
|
+
}
|
|
914
705
|
/**
|
|
915
706
|
* Updates the target with information from source, also updating a mapping of
|
|
916
707
|
* which records in the target were changed as a result.
|
|
@@ -1003,7 +794,7 @@ function updateTargetFromSource(target, source, currentWriteEpoch, idsMarkedForI
|
|
|
1003
794
|
/**
|
|
1004
795
|
* Returns an OperationAvailability given the Availability returned
|
|
1005
796
|
* by checking an operation, and when that operation was last written to the store.
|
|
1006
|
-
* Specifically, the provided
|
|
797
|
+
* Specifically, the provided Availability of an operation will contain the
|
|
1007
798
|
* value of when a record referenced by the operation was most recently
|
|
1008
799
|
* invalidated; given that value, and given when this operation was last
|
|
1009
800
|
* written to the store, this function will return the overall
|
|
@@ -1011,32 +802,46 @@ function updateTargetFromSource(target, source, currentWriteEpoch, idsMarkedForI
|
|
|
1011
802
|
*/
|
|
1012
803
|
|
|
1013
804
|
|
|
1014
|
-
function
|
|
1015
|
-
var mostRecentlyInvalidatedAt =
|
|
1016
|
-
status =
|
|
805
|
+
function getAvailabilityStatus(operationAvailability, operationLastWrittenAt, operationFetchTime, queryCacheExpirationTime) {
|
|
806
|
+
var mostRecentlyInvalidatedAt = operationAvailability.mostRecentlyInvalidatedAt,
|
|
807
|
+
status = operationAvailability.status;
|
|
808
|
+
|
|
809
|
+
if (typeof mostRecentlyInvalidatedAt === 'number') {
|
|
810
|
+
// If some record referenced by this operation is stale, then the operation itself is stale
|
|
811
|
+
// if either the operation itself was never written *or* the operation was last written
|
|
812
|
+
// before the most recent invalidation of its reachable records.
|
|
813
|
+
if (operationLastWrittenAt == null || mostRecentlyInvalidatedAt > operationLastWrittenAt) {
|
|
814
|
+
return {
|
|
815
|
+
status: 'stale'
|
|
816
|
+
};
|
|
817
|
+
}
|
|
818
|
+
}
|
|
1017
819
|
|
|
1018
|
-
if (
|
|
1019
|
-
|
|
1020
|
-
|
|
1021
|
-
|
|
820
|
+
if (status === 'missing') {
|
|
821
|
+
return {
|
|
822
|
+
status: 'missing'
|
|
823
|
+
};
|
|
1022
824
|
}
|
|
1023
825
|
|
|
1024
|
-
if (
|
|
1025
|
-
|
|
1026
|
-
|
|
1027
|
-
|
|
1028
|
-
|
|
1029
|
-
|
|
1030
|
-
|
|
826
|
+
if (operationFetchTime != null && queryCacheExpirationTime != null) {
|
|
827
|
+
var isStale = operationFetchTime <= Date.now() - queryCacheExpirationTime;
|
|
828
|
+
|
|
829
|
+
if (isStale) {
|
|
830
|
+
return {
|
|
831
|
+
status: 'stale'
|
|
832
|
+
};
|
|
833
|
+
}
|
|
834
|
+
} // There were no invalidations of any reachable records *or* the operation is known to have
|
|
835
|
+
// been fetched after the most recent record invalidation.
|
|
1031
836
|
|
|
1032
837
|
|
|
1033
|
-
return
|
|
838
|
+
return {
|
|
839
|
+
status: 'available',
|
|
840
|
+
fetchTime: operationFetchTime !== null && operationFetchTime !== void 0 ? operationFetchTime : null
|
|
841
|
+
};
|
|
1034
842
|
}
|
|
1035
843
|
|
|
1036
844
|
RelayProfiler.instrumentMethods(RelayModernStore.prototype, {
|
|
1037
|
-
lookup: 'RelayModernStore.prototype.lookup'
|
|
1038
|
-
notify: 'RelayModernStore.prototype.notify',
|
|
1039
|
-
publish: 'RelayModernStore.prototype.publish',
|
|
1040
|
-
__gc: 'RelayModernStore.prototype.__gc'
|
|
845
|
+
lookup: 'RelayModernStore.prototype.lookup'
|
|
1041
846
|
});
|
|
1042
847
|
module.exports = RelayModernStore;
|