relay-runtime 0.0.0-main-6cd701c5 → 0.0.0-main-e7cacf79
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/experimental.js +1 -1
- package/index.js +1 -1
- package/lib/multi-actor-environment/MultiActorEnvironment.js +3 -1
- package/lib/store/OperationExecutor.js +7 -0
- package/lib/store/RelayModernEnvironment.js +2 -0
- package/lib/store/RelayModernStore.js +4 -2
- package/lib/store/RelayPublishQueue.js +1 -1
- package/lib/store/RelayReader.js +22 -5
- package/lib/store/RelayResponseNormalizer.js +2 -1
- package/lib/store/RelayStoreSubscriptions.js +2 -2
- package/lib/util/RelayError.js +3 -0
- package/lib/util/RelayFeatureFlags.js +2 -1
- package/multi-actor-environment/MultiActorEnvironment.js.flow +4 -0
- package/package.json +1 -1
- package/store/OperationExecutor.js.flow +9 -0
- package/store/RelayModernEnvironment.js.flow +4 -0
- package/store/RelayModernStore.js.flow +5 -0
- package/store/RelayPublishQueue.js.flow +10 -1
- package/store/RelayReader.js.flow +33 -2
- package/store/RelayResponseNormalizer.js.flow +6 -1
- package/store/RelayStoreSubscriptions.js.flow +2 -0
- package/store/RelayStoreTypes.js.flow +14 -1
- package/util/RelayError.js.flow +3 -0
- package/util/RelayFeatureFlags.js.flow +4 -0
package/experimental.js
CHANGED
package/index.js
CHANGED
|
@@ -14,7 +14,7 @@ var RelayRecordSource = require('../store/RelayRecordSource');
|
|
|
14
14
|
var ActorSpecificEnvironment = require('./ActorSpecificEnvironment');
|
|
15
15
|
var MultiActorEnvironment = /*#__PURE__*/function () {
|
|
16
16
|
function MultiActorEnvironment(config) {
|
|
17
|
-
var _config$getDataID, _config$logFn, _config$relayFieldLog, _config$treatMissingF, _config$isServer, _config$missingFieldH, _config$defaultRender, _config$normalizeResp;
|
|
17
|
+
var _config$getDataID, _config$logFn, _config$relayFieldLog, _config$treatMissingF, _config$deferDeduplic, _config$isServer, _config$missingFieldH, _config$defaultRender, _config$normalizeResp;
|
|
18
18
|
this._actorEnvironments = new Map();
|
|
19
19
|
this._operationLoader = config.operationLoader;
|
|
20
20
|
this._createNetworkForActor = config.createNetworkForActor;
|
|
@@ -26,6 +26,7 @@ var MultiActorEnvironment = /*#__PURE__*/function () {
|
|
|
26
26
|
this._relayFieldLogger = (_config$relayFieldLog = config.relayFieldLogger) !== null && _config$relayFieldLog !== void 0 ? _config$relayFieldLog : defaultRelayFieldLogger;
|
|
27
27
|
this._shouldProcessClientComponents = config.shouldProcessClientComponents;
|
|
28
28
|
this._treatMissingFieldsAsNull = (_config$treatMissingF = config.treatMissingFieldsAsNull) !== null && _config$treatMissingF !== void 0 ? _config$treatMissingF : false;
|
|
29
|
+
this._deferDeduplicatedFields = (_config$deferDeduplic = config.deferDeduplicatedFields) !== null && _config$deferDeduplic !== void 0 ? _config$deferDeduplic : false;
|
|
29
30
|
this._isServer = (_config$isServer = config.isServer) !== null && _config$isServer !== void 0 ? _config$isServer : false;
|
|
30
31
|
this._missingFieldHandlers = (_config$missingFieldH = config.missingFieldHandlers) !== null && _config$missingFieldH !== void 0 ? _config$missingFieldH : [];
|
|
31
32
|
this._createStoreForActor = config.createStoreForActor;
|
|
@@ -288,6 +289,7 @@ var MultiActorEnvironment = /*#__PURE__*/function () {
|
|
|
288
289
|
return _this4.forActor(actorIdentifier).getStore();
|
|
289
290
|
},
|
|
290
291
|
treatMissingFieldsAsNull: _this4._treatMissingFieldsAsNull,
|
|
292
|
+
deferDeduplicatedFields: _this4._deferDeduplicatedFields,
|
|
291
293
|
updater: updater,
|
|
292
294
|
log: _this4._logFn,
|
|
293
295
|
normalizeResponse: _this4._normalizeResponse
|
|
@@ -49,12 +49,14 @@ var Executor = /*#__PURE__*/function () {
|
|
|
49
49
|
sink = _ref3.sink,
|
|
50
50
|
source = _ref3.source,
|
|
51
51
|
treatMissingFieldsAsNull = _ref3.treatMissingFieldsAsNull,
|
|
52
|
+
deferDeduplicatedFields = _ref3.deferDeduplicatedFields,
|
|
52
53
|
updater = _ref3.updater,
|
|
53
54
|
log = _ref3.log,
|
|
54
55
|
normalizeResponse = _ref3.normalizeResponse;
|
|
55
56
|
this._actorIdentifier = actorIdentifier;
|
|
56
57
|
this._getDataID = getDataID;
|
|
57
58
|
this._treatMissingFieldsAsNull = treatMissingFieldsAsNull;
|
|
59
|
+
this._deferDeduplicatedFields = deferDeduplicatedFields;
|
|
58
60
|
this._incrementalPayloadsPending = false;
|
|
59
61
|
this._incrementalResults = new Map();
|
|
60
62
|
this._log = log;
|
|
@@ -435,6 +437,7 @@ var Executor = /*#__PURE__*/function () {
|
|
|
435
437
|
if (response) {
|
|
436
438
|
var payload = this._normalizeResponse(response, this._operation.root, ROOT_TYPE, {
|
|
437
439
|
actorIdentifier: this._actorIdentifier,
|
|
440
|
+
deferDeduplicatedFields: false,
|
|
438
441
|
getDataID: this._getDataID,
|
|
439
442
|
log: this._log,
|
|
440
443
|
path: [],
|
|
@@ -521,6 +524,7 @@ var Executor = /*#__PURE__*/function () {
|
|
|
521
524
|
};
|
|
522
525
|
return this._normalizeResponse(nextResponse, selector, followupPayload.typeName, {
|
|
523
526
|
actorIdentifier: this._actorIdentifier,
|
|
527
|
+
deferDeduplicatedFields: false,
|
|
524
528
|
getDataID: this._getDataID,
|
|
525
529
|
log: this._log,
|
|
526
530
|
path: followupPayload.path,
|
|
@@ -578,6 +582,7 @@ var Executor = /*#__PURE__*/function () {
|
|
|
578
582
|
return responses.map(function (payloadPart) {
|
|
579
583
|
var relayPayload = _this8._normalizeResponse(payloadPart, _this8._operation.root, ROOT_TYPE, {
|
|
580
584
|
actorIdentifier: _this8._actorIdentifier,
|
|
585
|
+
deferDeduplicatedFields: false,
|
|
581
586
|
getDataID: _this8._getDataID,
|
|
582
587
|
log: _this8._log,
|
|
583
588
|
path: [],
|
|
@@ -868,6 +873,7 @@ var Executor = /*#__PURE__*/function () {
|
|
|
868
873
|
this._actorIdentifier = (_placeholder$actorIde = placeholder.actorIdentifier) !== null && _placeholder$actorIde !== void 0 ? _placeholder$actorIde : this._actorIdentifier;
|
|
869
874
|
var relayPayload = this._normalizeResponse(response, placeholder.selector, placeholder.typeName, {
|
|
870
875
|
actorIdentifier: this._actorIdentifier,
|
|
876
|
+
deferDeduplicatedFields: this._deferDeduplicatedFields,
|
|
871
877
|
getDataID: this._getDataID,
|
|
872
878
|
log: this._log,
|
|
873
879
|
path: placeholder.path,
|
|
@@ -971,6 +977,7 @@ var Executor = /*#__PURE__*/function () {
|
|
|
971
977
|
});
|
|
972
978
|
var relayPayload = this._normalizeResponse(response, selector, typeName, {
|
|
973
979
|
actorIdentifier: this._actorIdentifier,
|
|
980
|
+
deferDeduplicatedFields: false,
|
|
974
981
|
getDataID: this._getDataID,
|
|
975
982
|
log: this._log,
|
|
976
983
|
path: [].concat((0, _toConsumableArray2["default"])(normalizationPath), [responseKey, String(itemIndex)]),
|
|
@@ -24,6 +24,7 @@ var RelayModernEnvironment = /*#__PURE__*/function () {
|
|
|
24
24
|
var _config$store, _config$log, _config$relayFieldLog, _config$UNSTABLE_defa, _config$getDataID, _config$missingFieldH, _config$handlerProvid, _config$scheduler, _config$isServer, _config$normalizeResp, _config$operationTrac;
|
|
25
25
|
this.configName = config.configName;
|
|
26
26
|
this._treatMissingFieldsAsNull = config.treatMissingFieldsAsNull === true;
|
|
27
|
+
this._deferDeduplicatedFields = config.deferDeduplicatedFields === true;
|
|
27
28
|
var operationLoader = config.operationLoader;
|
|
28
29
|
if (process.env.NODE_ENV !== "production") {
|
|
29
30
|
if (operationLoader != null) {
|
|
@@ -308,6 +309,7 @@ var RelayModernEnvironment = /*#__PURE__*/function () {
|
|
|
308
309
|
sink: sink,
|
|
309
310
|
source: createSource(),
|
|
310
311
|
treatMissingFieldsAsNull: _this0._treatMissingFieldsAsNull,
|
|
312
|
+
deferDeduplicatedFields: _this0._deferDeduplicatedFields,
|
|
311
313
|
updater: updater
|
|
312
314
|
});
|
|
313
315
|
return function () {
|
|
@@ -29,7 +29,7 @@ var DEFAULT_RELEASE_BUFFER_SIZE = 10;
|
|
|
29
29
|
var RelayModernStore = /*#__PURE__*/function () {
|
|
30
30
|
function RelayModernStore(source, options) {
|
|
31
31
|
var _this = this;
|
|
32
|
-
var _options$gcReleaseBuf, _options$shouldRetain, _options$gcScheduler, _options$getDataID, _options$log, _options$operationLoa, _options$shouldProces, _options$treatMissing;
|
|
32
|
+
var _options$gcReleaseBuf, _options$shouldRetain, _options$gcScheduler, _options$getDataID, _options$log, _options$operationLoa, _options$shouldProces, _options$treatMissing, _options$deferDedupli;
|
|
33
33
|
(0, _defineProperty2["default"])(this, "_gcStep", function () {
|
|
34
34
|
if (_this._gcRun) {
|
|
35
35
|
if (_this._gcRun.next().done) {
|
|
@@ -74,6 +74,7 @@ var RelayModernStore = /*#__PURE__*/function () {
|
|
|
74
74
|
this._updatedRecordIDs = new Set();
|
|
75
75
|
this._shouldProcessClientComponents = (_options$shouldProces = options === null || options === void 0 ? void 0 : options.shouldProcessClientComponents) !== null && _options$shouldProces !== void 0 ? _options$shouldProces : false;
|
|
76
76
|
this._treatMissingFieldsAsNull = (_options$treatMissing = options === null || options === void 0 ? void 0 : options.treatMissingFieldsAsNull) !== null && _options$treatMissing !== void 0 ? _options$treatMissing : false;
|
|
77
|
+
this._deferDeduplicatedFields = (_options$deferDedupli = options === null || options === void 0 ? void 0 : options.deferDeduplicatedFields) !== null && _options$deferDedupli !== void 0 ? _options$deferDedupli : false;
|
|
77
78
|
this._actorIdentifier = options === null || options === void 0 ? void 0 : options.actorIdentifier;
|
|
78
79
|
initializeRecordSource(this._recordSource);
|
|
79
80
|
}
|
|
@@ -216,7 +217,7 @@ var RelayModernStore = /*#__PURE__*/function () {
|
|
|
216
217
|
});
|
|
217
218
|
}
|
|
218
219
|
var source = this.getSource();
|
|
219
|
-
var snapshot = RelayReader.read(source, selector, this._resolverCache, this._resolverContext);
|
|
220
|
+
var snapshot = RelayReader.read(source, selector, log, this._resolverCache, this._resolverContext);
|
|
220
221
|
if (process.env.NODE_ENV !== "production") {
|
|
221
222
|
deepFreeze(snapshot);
|
|
222
223
|
}
|
|
@@ -537,6 +538,7 @@ var RelayModernStore = /*#__PURE__*/function () {
|
|
|
537
538
|
getDataID: this._getDataID,
|
|
538
539
|
log: this.__log,
|
|
539
540
|
treatMissingFieldsAsNull: this._treatMissingFieldsAsNull,
|
|
541
|
+
deferDeduplicatedFields: this._deferDeduplicatedFields,
|
|
540
542
|
shouldProcessClientComponents: this._shouldProcessClientComponents,
|
|
541
543
|
actorIdentifier: this._actorIdentifier
|
|
542
544
|
};
|
|
@@ -203,7 +203,7 @@ var RelayPublishQueue = /*#__PURE__*/function () {
|
|
|
203
203
|
return RelayPublishQueue;
|
|
204
204
|
}();
|
|
205
205
|
function lookupSelector(source, selector) {
|
|
206
|
-
var selectorData = RelayReader.read(source, selector).data;
|
|
206
|
+
var selectorData = RelayReader.read(source, selector, null, undefined, undefined).data;
|
|
207
207
|
if (process.env.NODE_ENV !== "production") {
|
|
208
208
|
var deepFreeze = require('../util/deepFreeze');
|
|
209
209
|
if (selectorData) {
|
package/lib/store/RelayReader.js
CHANGED
|
@@ -30,12 +30,12 @@ var _require4 = require('./ResolverFragments'),
|
|
|
30
30
|
var _require5 = require('./TypeID'),
|
|
31
31
|
generateTypeID = _require5.generateTypeID;
|
|
32
32
|
var invariant = require('invariant');
|
|
33
|
-
function read(recordSource, selector, resolverCache, resolverContext) {
|
|
34
|
-
var reader = new RelayReader(recordSource, selector, resolverCache !== null && resolverCache !== void 0 ? resolverCache : new NoopResolverCache(), resolverContext);
|
|
33
|
+
function read(recordSource, selector, log, resolverCache, resolverContext) {
|
|
34
|
+
var reader = new RelayReader(recordSource, selector, log, resolverCache !== null && resolverCache !== void 0 ? resolverCache : new NoopResolverCache(), resolverContext);
|
|
35
35
|
return reader.read();
|
|
36
36
|
}
|
|
37
37
|
var RelayReader = /*#__PURE__*/function () {
|
|
38
|
-
function RelayReader(recordSource, selector, resolverCache, resolverContext) {
|
|
38
|
+
function RelayReader(recordSource, selector, log, resolverCache, resolverContext) {
|
|
39
39
|
var _selector$clientEdgeT, _ref, _this$_owner$node$ope, _this$_owner$node$ope2;
|
|
40
40
|
this._clientEdgeTraversalPath = (_selector$clientEdgeT = selector.clientEdgeTraversalPath) !== null && _selector$clientEdgeT !== void 0 && _selector$clientEdgeT.length ? (0, _toConsumableArray2["default"])(selector.clientEdgeTraversalPath) : [];
|
|
41
41
|
this._missingClientEdges = [];
|
|
@@ -53,6 +53,7 @@ var RelayReader = /*#__PURE__*/function () {
|
|
|
53
53
|
this._fragmentName = selector.node.name;
|
|
54
54
|
this._updatedDataIDs = new Set();
|
|
55
55
|
this._resolverContext = resolverContext;
|
|
56
|
+
this._log = log;
|
|
56
57
|
}
|
|
57
58
|
var _proto = RelayReader.prototype;
|
|
58
59
|
_proto.read = function read() {
|
|
@@ -85,6 +86,13 @@ var RelayReader = /*#__PURE__*/function () {
|
|
|
85
86
|
this._resolverCache.notifyUpdatedSubscribers(this._updatedDataIDs);
|
|
86
87
|
this._updatedDataIDs.clear();
|
|
87
88
|
}
|
|
89
|
+
if (RelayFeatureFlags.ENABLE_READER_FRAGMENTS_LOGGING) {
|
|
90
|
+
var _this$_log;
|
|
91
|
+
(_this$_log = this._log) === null || _this$_log === void 0 ? void 0 : _this$_log.call(this, {
|
|
92
|
+
name: 'reader.read',
|
|
93
|
+
selector: this._selector
|
|
94
|
+
});
|
|
95
|
+
}
|
|
88
96
|
return {
|
|
89
97
|
data: data,
|
|
90
98
|
fieldErrors: this._fieldErrors,
|
|
@@ -456,7 +464,7 @@ var RelayReader = /*#__PURE__*/function () {
|
|
|
456
464
|
isMissingData: snapshot.isMissingData
|
|
457
465
|
};
|
|
458
466
|
}
|
|
459
|
-
snapshot = read(_this._recordSource, singularReaderSelector, _this._resolverCache);
|
|
467
|
+
snapshot = read(_this._recordSource, singularReaderSelector, null, _this._resolverCache, undefined);
|
|
460
468
|
return {
|
|
461
469
|
data: snapshot.data,
|
|
462
470
|
fieldErrors: snapshot.fieldErrors,
|
|
@@ -860,11 +868,20 @@ var RelayReader = /*#__PURE__*/function () {
|
|
|
860
868
|
if (data[ID_KEY] == null) {
|
|
861
869
|
data[ID_KEY] = RelayModernRecord.getDataID(record);
|
|
862
870
|
}
|
|
863
|
-
|
|
871
|
+
var args = getArgumentValues(fragmentSpread.args, this._variables, this._isWithinUnmatchedTypeRefinement);
|
|
872
|
+
fragmentPointers[fragmentSpread.name] = args;
|
|
864
873
|
data[FRAGMENT_OWNER_KEY] = this._owner;
|
|
865
874
|
if (this._clientEdgeTraversalPath.length > 0 && this._clientEdgeTraversalPath[this._clientEdgeTraversalPath.length - 1] !== null) {
|
|
866
875
|
data[CLIENT_EDGE_TRAVERSAL_PATH] = (0, _toConsumableArray2["default"])(this._clientEdgeTraversalPath);
|
|
867
876
|
}
|
|
877
|
+
if (RelayFeatureFlags.ENABLE_READER_FRAGMENTS_LOGGING) {
|
|
878
|
+
var _this$_log2;
|
|
879
|
+
(_this$_log2 = this._log) === null || _this$_log2 === void 0 ? void 0 : _this$_log2.call(this, {
|
|
880
|
+
name: 'reader.fragmentSpread',
|
|
881
|
+
fragmentName: fragmentSpread.name,
|
|
882
|
+
data: data
|
|
883
|
+
});
|
|
884
|
+
}
|
|
868
885
|
};
|
|
869
886
|
_proto._createInlineDataOrResolverFragmentPointer = function _createInlineDataOrResolverFragmentPointer(fragmentSpreadOrFragment, record, data) {
|
|
870
887
|
var fragmentPointers = data[FRAGMENTS_KEY];
|
|
@@ -47,6 +47,7 @@ var RelayResponseNormalizer = /*#__PURE__*/function () {
|
|
|
47
47
|
this._getDataId = options.getDataID;
|
|
48
48
|
this._handleFieldPayloads = [];
|
|
49
49
|
this._treatMissingFieldsAsNull = options.treatMissingFieldsAsNull;
|
|
50
|
+
this._deferDeduplicatedFields = options.deferDeduplicatedFields;
|
|
50
51
|
this._incrementalPlaceholders = [];
|
|
51
52
|
this._isClientExtension = false;
|
|
52
53
|
this._isUnmatchedAbstractType = false;
|
|
@@ -300,7 +301,7 @@ var RelayResponseNormalizer = /*#__PURE__*/function () {
|
|
|
300
301
|
var isNoncompliantlyNullish = RelayFeatureFlags.ENABLE_NONCOMPLIANT_ERROR_HANDLING_ON_LISTS && Array.isArray(fieldValue) && fieldValue.length === 0;
|
|
301
302
|
if (fieldValue == null || isNoncompliantlyNullish) {
|
|
302
303
|
if (fieldValue === undefined) {
|
|
303
|
-
var isOptionalField = this._isClientExtension || this._isUnmatchedAbstractType;
|
|
304
|
+
var isOptionalField = this._isClientExtension || this._isUnmatchedAbstractType || this._deferDeduplicatedFields;
|
|
304
305
|
if (isOptionalField) {
|
|
305
306
|
return;
|
|
306
307
|
} else if (!this._treatMissingFieldsAsNull) {
|
|
@@ -42,7 +42,7 @@ var RelayStoreSubscriptions = /*#__PURE__*/function () {
|
|
|
42
42
|
return;
|
|
43
43
|
}
|
|
44
44
|
var snapshot = subscription.snapshot;
|
|
45
|
-
var backup = RelayReader.read(source, snapshot.selector, _this2._resolverCache, _this2._resolverContext);
|
|
45
|
+
var backup = RelayReader.read(source, snapshot.selector, _this2.__log, _this2._resolverCache, _this2._resolverContext);
|
|
46
46
|
var nextData = recycleNodesInto(snapshot.data, backup.data);
|
|
47
47
|
backup.data = nextData;
|
|
48
48
|
subscription.backup = backup;
|
|
@@ -106,7 +106,7 @@ var RelayStoreSubscriptions = /*#__PURE__*/function () {
|
|
|
106
106
|
if (!stale && !hasOverlappingUpdates) {
|
|
107
107
|
return;
|
|
108
108
|
}
|
|
109
|
-
var nextSnapshot = hasOverlappingUpdates || !backup ? RelayReader.read(source, snapshot.selector, this._resolverCache, this._resolverContext) : backup;
|
|
109
|
+
var nextSnapshot = hasOverlappingUpdates || !backup ? RelayReader.read(source, snapshot.selector, this.__log, this._resolverCache, this._resolverContext) : backup;
|
|
110
110
|
var nextData = recycleNodesInto(snapshot.data, nextSnapshot.data);
|
|
111
111
|
nextSnapshot = {
|
|
112
112
|
data: nextData,
|
package/lib/util/RelayError.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
3
|
function createError(type, name, messageFormat) {
|
|
4
|
+
var _messageParams$;
|
|
4
5
|
for (var _len = arguments.length, messageParams = new Array(_len > 3 ? _len - 3 : 0), _key = 3; _key < _len; _key++) {
|
|
5
6
|
messageParams[_key - 3] = arguments[_key];
|
|
6
7
|
}
|
|
@@ -9,11 +10,13 @@ function createError(type, name, messageFormat) {
|
|
|
9
10
|
return String(messageParams[index++]);
|
|
10
11
|
});
|
|
11
12
|
var err = new Error(message);
|
|
13
|
+
var operation = (_messageParams$ = messageParams[2]) !== null && _messageParams$ !== void 0 ? _messageParams$ : null;
|
|
12
14
|
var error = Object.assign(err, {
|
|
13
15
|
name: name,
|
|
14
16
|
messageFormat: messageFormat,
|
|
15
17
|
messageParams: messageParams,
|
|
16
18
|
type: type,
|
|
19
|
+
operation: operation,
|
|
17
20
|
taalOpcodes: [2, 2]
|
|
18
21
|
});
|
|
19
22
|
if (error.stack === undefined) {
|
|
@@ -28,6 +28,7 @@ var RelayFeatureFlags = {
|
|
|
28
28
|
ENABLE_UI_CONTEXT_ON_RELAY_LOGGER: false,
|
|
29
29
|
CHECK_ALL_FRAGMENTS_FOR_MISSING_CLIENT_EDGES: false,
|
|
30
30
|
FILTER_OUT_RELAY_RESOLVER_RECORDS: false,
|
|
31
|
-
OPTIMIZE_NOTIFY: false
|
|
31
|
+
OPTIMIZE_NOTIFY: false,
|
|
32
|
+
ENABLE_READER_FRAGMENTS_LOGGING: false
|
|
32
33
|
};
|
|
33
34
|
module.exports = RelayFeatureFlags;
|
|
@@ -71,6 +71,7 @@ export type MultiActorEnvironmentConfig = $ReadOnly<{
|
|
|
71
71
|
scheduler?: ?TaskScheduler,
|
|
72
72
|
shouldProcessClientComponents?: ?boolean,
|
|
73
73
|
treatMissingFieldsAsNull?: boolean,
|
|
74
|
+
deferDeduplicatedFields?: boolean,
|
|
74
75
|
}>;
|
|
75
76
|
|
|
76
77
|
class MultiActorEnvironment implements IMultiActorEnvironment {
|
|
@@ -91,6 +92,7 @@ class MultiActorEnvironment implements IMultiActorEnvironment {
|
|
|
91
92
|
+_scheduler: ?TaskScheduler;
|
|
92
93
|
+_shouldProcessClientComponents: ?boolean;
|
|
93
94
|
+_treatMissingFieldsAsNull: boolean;
|
|
95
|
+
+_deferDeduplicatedFields: boolean;
|
|
94
96
|
|
|
95
97
|
constructor(config: MultiActorEnvironmentConfig) {
|
|
96
98
|
this._actorEnvironments = new Map();
|
|
@@ -106,6 +108,7 @@ class MultiActorEnvironment implements IMultiActorEnvironment {
|
|
|
106
108
|
this._relayFieldLogger = config.relayFieldLogger ?? defaultRelayFieldLogger;
|
|
107
109
|
this._shouldProcessClientComponents = config.shouldProcessClientComponents;
|
|
108
110
|
this._treatMissingFieldsAsNull = config.treatMissingFieldsAsNull ?? false;
|
|
111
|
+
this._deferDeduplicatedFields = config.deferDeduplicatedFields ?? false;
|
|
109
112
|
this._isServer = config.isServer ?? false;
|
|
110
113
|
this._missingFieldHandlers = config.missingFieldHandlers ?? [];
|
|
111
114
|
this._createStoreForActor = config.createStoreForActor;
|
|
@@ -471,6 +474,7 @@ class MultiActorEnvironment implements IMultiActorEnvironment {
|
|
|
471
474
|
return this.forActor(actorIdentifier).getStore();
|
|
472
475
|
},
|
|
473
476
|
treatMissingFieldsAsNull: this._treatMissingFieldsAsNull,
|
|
477
|
+
deferDeduplicatedFields: this._deferDeduplicatedFields,
|
|
474
478
|
updater,
|
|
475
479
|
log: this._logFn,
|
|
476
480
|
normalizeResponse: this._normalizeResponse,
|
package/package.json
CHANGED
|
@@ -88,6 +88,7 @@ export type ExecuteConfig<TMutation: MutationParameters> = {
|
|
|
88
88
|
+sink: Sink<GraphQLResponse>,
|
|
89
89
|
+source: RelayObservable<GraphQLResponse>,
|
|
90
90
|
+treatMissingFieldsAsNull: boolean,
|
|
91
|
+
+deferDeduplicatedFields: boolean,
|
|
91
92
|
+updater?: ?SelectorStoreUpdater<TMutation['response']>,
|
|
92
93
|
+log: LogFunction,
|
|
93
94
|
};
|
|
@@ -127,6 +128,7 @@ class Executor<TMutation: MutationParameters> {
|
|
|
127
128
|
_actorIdentifier: ActorIdentifier;
|
|
128
129
|
_getDataID: GetDataID;
|
|
129
130
|
_treatMissingFieldsAsNull: boolean;
|
|
131
|
+
_deferDeduplicatedFields: boolean;
|
|
130
132
|
_incrementalPayloadsPending: boolean;
|
|
131
133
|
_incrementalResults: Map<Label, Map<PathKey, IncrementalResults>>;
|
|
132
134
|
_log: LogFunction;
|
|
@@ -178,6 +180,7 @@ class Executor<TMutation: MutationParameters> {
|
|
|
178
180
|
sink,
|
|
179
181
|
source,
|
|
180
182
|
treatMissingFieldsAsNull,
|
|
183
|
+
deferDeduplicatedFields,
|
|
181
184
|
updater,
|
|
182
185
|
log,
|
|
183
186
|
normalizeResponse,
|
|
@@ -185,6 +188,7 @@ class Executor<TMutation: MutationParameters> {
|
|
|
185
188
|
this._actorIdentifier = actorIdentifier;
|
|
186
189
|
this._getDataID = getDataID;
|
|
187
190
|
this._treatMissingFieldsAsNull = treatMissingFieldsAsNull;
|
|
191
|
+
this._deferDeduplicatedFields = deferDeduplicatedFields;
|
|
188
192
|
this._incrementalPayloadsPending = false;
|
|
189
193
|
this._incrementalResults = new Map();
|
|
190
194
|
this._log = log;
|
|
@@ -695,6 +699,7 @@ class Executor<TMutation: MutationParameters> {
|
|
|
695
699
|
ROOT_TYPE,
|
|
696
700
|
{
|
|
697
701
|
actorIdentifier: this._actorIdentifier,
|
|
702
|
+
deferDeduplicatedFields: false,
|
|
698
703
|
getDataID: this._getDataID,
|
|
699
704
|
log: this._log,
|
|
700
705
|
path: [],
|
|
@@ -813,6 +818,7 @@ class Executor<TMutation: MutationParameters> {
|
|
|
813
818
|
followupPayload.typeName,
|
|
814
819
|
{
|
|
815
820
|
actorIdentifier: this._actorIdentifier,
|
|
821
|
+
deferDeduplicatedFields: false,
|
|
816
822
|
getDataID: this._getDataID,
|
|
817
823
|
log: this._log,
|
|
818
824
|
path: followupPayload.path,
|
|
@@ -897,6 +903,7 @@ class Executor<TMutation: MutationParameters> {
|
|
|
897
903
|
ROOT_TYPE,
|
|
898
904
|
{
|
|
899
905
|
actorIdentifier: this._actorIdentifier,
|
|
906
|
+
deferDeduplicatedFields: false,
|
|
900
907
|
getDataID: this._getDataID,
|
|
901
908
|
log: this._log,
|
|
902
909
|
path: [],
|
|
@@ -1363,6 +1370,7 @@ class Executor<TMutation: MutationParameters> {
|
|
|
1363
1370
|
placeholder.typeName,
|
|
1364
1371
|
{
|
|
1365
1372
|
actorIdentifier: this._actorIdentifier,
|
|
1373
|
+
deferDeduplicatedFields: this._deferDeduplicatedFields,
|
|
1366
1374
|
getDataID: this._getDataID,
|
|
1367
1375
|
log: this._log,
|
|
1368
1376
|
path: placeholder.path,
|
|
@@ -1596,6 +1604,7 @@ class Executor<TMutation: MutationParameters> {
|
|
|
1596
1604
|
typeName,
|
|
1597
1605
|
{
|
|
1598
1606
|
actorIdentifier: this._actorIdentifier,
|
|
1607
|
+
deferDeduplicatedFields: false,
|
|
1599
1608
|
getDataID: this._getDataID,
|
|
1600
1609
|
log: this._log,
|
|
1601
1610
|
path: [...normalizationPath, responseKey, String(itemIndex)],
|
|
@@ -67,6 +67,7 @@ export type EnvironmentConfig = {
|
|
|
67
67
|
+configName?: string,
|
|
68
68
|
+handlerProvider?: ?HandlerProvider,
|
|
69
69
|
+treatMissingFieldsAsNull?: boolean,
|
|
70
|
+
+deferDeduplicatedFields?: boolean,
|
|
70
71
|
+log?: ?LogFunction,
|
|
71
72
|
+operationLoader?: ?OperationLoader,
|
|
72
73
|
+network: INetwork,
|
|
@@ -97,6 +98,7 @@ class RelayModernEnvironment implements IEnvironment {
|
|
|
97
98
|
_operationTracker: OperationTracker;
|
|
98
99
|
_getDataID: GetDataID;
|
|
99
100
|
_treatMissingFieldsAsNull: boolean;
|
|
101
|
+
_deferDeduplicatedFields: boolean;
|
|
100
102
|
_operationExecutions: Map<string, ActiveState>;
|
|
101
103
|
+options: mixed;
|
|
102
104
|
+_isServer: boolean;
|
|
@@ -106,6 +108,7 @@ class RelayModernEnvironment implements IEnvironment {
|
|
|
106
108
|
constructor(config: EnvironmentConfig) {
|
|
107
109
|
this.configName = config.configName;
|
|
108
110
|
this._treatMissingFieldsAsNull = config.treatMissingFieldsAsNull === true;
|
|
111
|
+
this._deferDeduplicatedFields = config.deferDeduplicatedFields === true;
|
|
109
112
|
const operationLoader = config.operationLoader;
|
|
110
113
|
if (__DEV__) {
|
|
111
114
|
if (operationLoader != null) {
|
|
@@ -501,6 +504,7 @@ class RelayModernEnvironment implements IEnvironment {
|
|
|
501
504
|
// when the Observable is executed.
|
|
502
505
|
source: createSource(),
|
|
503
506
|
treatMissingFieldsAsNull: this._treatMissingFieldsAsNull,
|
|
507
|
+
deferDeduplicatedFields: this._deferDeduplicatedFields,
|
|
504
508
|
updater,
|
|
505
509
|
});
|
|
506
510
|
return () => executor.cancel();
|
|
@@ -116,6 +116,7 @@ class RelayModernStore implements Store {
|
|
|
116
116
|
_resolverContext: ?ResolverContext;
|
|
117
117
|
_actorIdentifier: ?ActorIdentifier;
|
|
118
118
|
_treatMissingFieldsAsNull: boolean;
|
|
119
|
+
_deferDeduplicatedFields: boolean;
|
|
119
120
|
|
|
120
121
|
constructor(
|
|
121
122
|
source: MutableRecordSource,
|
|
@@ -135,6 +136,7 @@ class RelayModernStore implements Store {
|
|
|
135
136
|
// These additional config options are only used if the experimental
|
|
136
137
|
// @outputType resolver feature is used
|
|
137
138
|
treatMissingFieldsAsNull?: ?boolean,
|
|
139
|
+
deferDeduplicatedFields?: ?boolean,
|
|
138
140
|
actorIdentifier?: ?ActorIdentifier,
|
|
139
141
|
},
|
|
140
142
|
) {
|
|
@@ -183,6 +185,7 @@ class RelayModernStore implements Store {
|
|
|
183
185
|
options?.shouldProcessClientComponents ?? false;
|
|
184
186
|
|
|
185
187
|
this._treatMissingFieldsAsNull = options?.treatMissingFieldsAsNull ?? false;
|
|
188
|
+
this._deferDeduplicatedFields = options?.deferDeduplicatedFields ?? false;
|
|
186
189
|
this._actorIdentifier = options?.actorIdentifier;
|
|
187
190
|
|
|
188
191
|
initializeRecordSource(this._recordSource);
|
|
@@ -402,6 +405,7 @@ class RelayModernStore implements Store {
|
|
|
402
405
|
const snapshot = RelayReader.read(
|
|
403
406
|
source,
|
|
404
407
|
selector,
|
|
408
|
+
log,
|
|
405
409
|
this._resolverCache,
|
|
406
410
|
this._resolverContext,
|
|
407
411
|
);
|
|
@@ -883,6 +887,7 @@ class RelayModernStore implements Store {
|
|
|
883
887
|
getDataID: this._getDataID,
|
|
884
888
|
log: this.__log,
|
|
885
889
|
treatMissingFieldsAsNull: this._treatMissingFieldsAsNull,
|
|
890
|
+
deferDeduplicatedFields: this._deferDeduplicatedFields,
|
|
886
891
|
shouldProcessClientComponents: this._shouldProcessClientComponents,
|
|
887
892
|
actorIdentifier: this._actorIdentifier,
|
|
888
893
|
};
|
|
@@ -464,7 +464,16 @@ function lookupSelector(
|
|
|
464
464
|
source: RecordSource,
|
|
465
465
|
selector: SingularReaderSelector,
|
|
466
466
|
): ?SelectorData {
|
|
467
|
-
const selectorData = RelayReader.read(
|
|
467
|
+
const selectorData = RelayReader.read(
|
|
468
|
+
source,
|
|
469
|
+
selector,
|
|
470
|
+
// The reader here is used to read the selector data for the updater.
|
|
471
|
+
// It is normal to not use all data in the update, so we don't pass
|
|
472
|
+
// the logger to skip tracking usages.
|
|
473
|
+
null,
|
|
474
|
+
undefined,
|
|
475
|
+
undefined,
|
|
476
|
+
).data;
|
|
468
477
|
if (__DEV__) {
|
|
469
478
|
const deepFreeze = require('../util/deepFreeze');
|
|
470
479
|
if (selectorData) {
|
|
@@ -37,6 +37,7 @@ import type {
|
|
|
37
37
|
DataIDSet,
|
|
38
38
|
FieldError,
|
|
39
39
|
FieldErrors,
|
|
40
|
+
LogFunction,
|
|
40
41
|
MissingClientEdgeRequestInfo,
|
|
41
42
|
Record,
|
|
42
43
|
RecordSource,
|
|
@@ -78,12 +79,14 @@ const invariant = require('invariant');
|
|
|
78
79
|
function read(
|
|
79
80
|
recordSource: RecordSource,
|
|
80
81
|
selector: SingularReaderSelector,
|
|
82
|
+
log: ?LogFunction,
|
|
81
83
|
resolverCache?: ResolverCache,
|
|
82
84
|
resolverContext?: ResolverContext,
|
|
83
85
|
): Snapshot {
|
|
84
86
|
const reader = new RelayReader(
|
|
85
87
|
recordSource,
|
|
86
88
|
selector,
|
|
89
|
+
log,
|
|
87
90
|
resolverCache ?? new NoopResolverCache(),
|
|
88
91
|
resolverContext,
|
|
89
92
|
);
|
|
@@ -115,10 +118,15 @@ class RelayReader {
|
|
|
115
118
|
_resolverCache: ResolverCache;
|
|
116
119
|
_fragmentName: string;
|
|
117
120
|
_resolverContext: ?ResolverContext;
|
|
121
|
+
// The log function currently is only used to log fragment spread accesses for unused
|
|
122
|
+
// fragments detection, so it is not passed in from all callsites. If we decide to
|
|
123
|
+
// extend the logging, this needs to be updated.
|
|
124
|
+
_log: ?LogFunction;
|
|
118
125
|
|
|
119
126
|
constructor(
|
|
120
127
|
recordSource: RecordSource,
|
|
121
128
|
selector: SingularReaderSelector,
|
|
129
|
+
log: ?LogFunction,
|
|
122
130
|
resolverCache: ResolverCache,
|
|
123
131
|
resolverContext: ?ResolverContext,
|
|
124
132
|
) {
|
|
@@ -144,6 +152,7 @@ class RelayReader {
|
|
|
144
152
|
this._fragmentName = selector.node.name;
|
|
145
153
|
this._updatedDataIDs = new Set();
|
|
146
154
|
this._resolverContext = resolverContext;
|
|
155
|
+
this._log = log;
|
|
147
156
|
}
|
|
148
157
|
|
|
149
158
|
read(): Snapshot {
|
|
@@ -200,6 +209,14 @@ class RelayReader {
|
|
|
200
209
|
this._resolverCache.notifyUpdatedSubscribers(this._updatedDataIDs);
|
|
201
210
|
this._updatedDataIDs.clear();
|
|
202
211
|
}
|
|
212
|
+
|
|
213
|
+
if (RelayFeatureFlags.ENABLE_READER_FRAGMENTS_LOGGING) {
|
|
214
|
+
this._log?.({
|
|
215
|
+
name: 'reader.read',
|
|
216
|
+
selector: this._selector,
|
|
217
|
+
});
|
|
218
|
+
}
|
|
219
|
+
|
|
203
220
|
return {
|
|
204
221
|
data,
|
|
205
222
|
fieldErrors: this._fieldErrors,
|
|
@@ -770,7 +787,12 @@ class RelayReader {
|
|
|
770
787
|
snapshot = read(
|
|
771
788
|
this._recordSource,
|
|
772
789
|
singularReaderSelector,
|
|
790
|
+
// This reads data for a rootFragment in read time resolvers. There is no fragment
|
|
791
|
+
// spread created for it so the existing fragment spread logger can't be used to log
|
|
792
|
+
// unused rootFragments. Thus we skip passing the logger here for now.
|
|
793
|
+
null,
|
|
773
794
|
this._resolverCache,
|
|
795
|
+
undefined,
|
|
774
796
|
);
|
|
775
797
|
|
|
776
798
|
return {
|
|
@@ -1583,12 +1605,13 @@ class RelayReader {
|
|
|
1583
1605
|
if (data[ID_KEY] == null) {
|
|
1584
1606
|
data[ID_KEY] = RelayModernRecord.getDataID(record);
|
|
1585
1607
|
}
|
|
1586
|
-
|
|
1587
|
-
fragmentPointers[fragmentSpread.name] = getArgumentValues(
|
|
1608
|
+
const args = getArgumentValues(
|
|
1588
1609
|
fragmentSpread.args,
|
|
1589
1610
|
this._variables,
|
|
1590
1611
|
this._isWithinUnmatchedTypeRefinement,
|
|
1591
1612
|
);
|
|
1613
|
+
// $FlowFixMe[cannot-write] - writing into read-only field
|
|
1614
|
+
fragmentPointers[fragmentSpread.name] = args;
|
|
1592
1615
|
data[FRAGMENT_OWNER_KEY] = this._owner;
|
|
1593
1616
|
|
|
1594
1617
|
if (
|
|
@@ -1599,6 +1622,14 @@ class RelayReader {
|
|
|
1599
1622
|
) {
|
|
1600
1623
|
data[CLIENT_EDGE_TRAVERSAL_PATH] = [...this._clientEdgeTraversalPath];
|
|
1601
1624
|
}
|
|
1625
|
+
|
|
1626
|
+
if (RelayFeatureFlags.ENABLE_READER_FRAGMENTS_LOGGING) {
|
|
1627
|
+
this._log?.({
|
|
1628
|
+
name: 'reader.fragmentSpread',
|
|
1629
|
+
fragmentName: fragmentSpread.name,
|
|
1630
|
+
data,
|
|
1631
|
+
});
|
|
1632
|
+
}
|
|
1602
1633
|
}
|
|
1603
1634
|
|
|
1604
1635
|
_createInlineDataOrResolverFragmentPointer(
|
|
@@ -76,6 +76,7 @@ export type GetDataID = (
|
|
|
76
76
|
export type NormalizationOptions = {
|
|
77
77
|
+getDataID: GetDataID,
|
|
78
78
|
+treatMissingFieldsAsNull: boolean,
|
|
79
|
+
+deferDeduplicatedFields: boolean,
|
|
79
80
|
+log: ?LogFunction,
|
|
80
81
|
+path?: $ReadOnlyArray<string>,
|
|
81
82
|
+shouldProcessClientComponents?: ?boolean,
|
|
@@ -114,6 +115,7 @@ class RelayResponseNormalizer {
|
|
|
114
115
|
_getDataId: GetDataID;
|
|
115
116
|
_handleFieldPayloads: Array<HandleFieldPayload>;
|
|
116
117
|
_treatMissingFieldsAsNull: boolean;
|
|
118
|
+
_deferDeduplicatedFields: boolean;
|
|
117
119
|
_incrementalPlaceholders: Array<IncrementalDataPlaceholder>;
|
|
118
120
|
_isClientExtension: boolean;
|
|
119
121
|
_isUnmatchedAbstractType: boolean;
|
|
@@ -136,6 +138,7 @@ class RelayResponseNormalizer {
|
|
|
136
138
|
this._getDataId = options.getDataID;
|
|
137
139
|
this._handleFieldPayloads = [];
|
|
138
140
|
this._treatMissingFieldsAsNull = options.treatMissingFieldsAsNull;
|
|
141
|
+
this._deferDeduplicatedFields = options.deferDeduplicatedFields;
|
|
139
142
|
this._incrementalPlaceholders = [];
|
|
140
143
|
this._isClientExtension = false;
|
|
141
144
|
this._isUnmatchedAbstractType = false;
|
|
@@ -525,7 +528,9 @@ class RelayResponseNormalizer {
|
|
|
525
528
|
// client is assumed to be correctly configured with
|
|
526
529
|
// treatMissingFieldsAsNull=true.
|
|
527
530
|
const isOptionalField =
|
|
528
|
-
this._isClientExtension ||
|
|
531
|
+
this._isClientExtension ||
|
|
532
|
+
this._isUnmatchedAbstractType ||
|
|
533
|
+
this._deferDeduplicatedFields;
|
|
529
534
|
|
|
530
535
|
if (isOptionalField) {
|
|
531
536
|
// Field not expected to exist regardless of whether the server is pruning null
|
|
@@ -101,6 +101,7 @@ class RelayStoreSubscriptions implements StoreSubscriptions {
|
|
|
101
101
|
const backup = RelayReader.read(
|
|
102
102
|
source,
|
|
103
103
|
snapshot.selector,
|
|
104
|
+
this.__log,
|
|
104
105
|
this._resolverCache,
|
|
105
106
|
this._resolverContext,
|
|
106
107
|
);
|
|
@@ -212,6 +213,7 @@ class RelayStoreSubscriptions implements StoreSubscriptions {
|
|
|
212
213
|
? RelayReader.read(
|
|
213
214
|
source,
|
|
214
215
|
snapshot.selector,
|
|
216
|
+
this.__log,
|
|
215
217
|
this._resolverCache,
|
|
216
218
|
this._resolverContext,
|
|
217
219
|
)
|
|
@@ -777,6 +777,17 @@ export type StoreNotifySubscriptionLogEvent = {
|
|
|
777
777
|
+nextSnapshot: Snapshot,
|
|
778
778
|
};
|
|
779
779
|
|
|
780
|
+
export type ReaderReadFragmentSpread = {
|
|
781
|
+
+name: 'reader.fragmentSpread',
|
|
782
|
+
fragmentName: string,
|
|
783
|
+
data: SelectorData,
|
|
784
|
+
};
|
|
785
|
+
|
|
786
|
+
export type ReaderRead = {
|
|
787
|
+
name: 'reader.read',
|
|
788
|
+
selector: SingularReaderSelector,
|
|
789
|
+
};
|
|
790
|
+
|
|
780
791
|
export type EntrypointRootConsumeLogEvent = {
|
|
781
792
|
+name: 'entrypoint.root.consume',
|
|
782
793
|
+profilerContext: mixed,
|
|
@@ -855,7 +866,9 @@ export type LogEvent =
|
|
|
855
866
|
| LiveResolverBatchStartLogEvent
|
|
856
867
|
| LiveResolverBatchEndLogEvent
|
|
857
868
|
| UseFragmentSubscriptionMissedUpdates
|
|
858
|
-
| FetchQueryFetchLogEvent
|
|
869
|
+
| FetchQueryFetchLogEvent
|
|
870
|
+
| ReaderRead
|
|
871
|
+
| ReaderReadFragmentSpread;
|
|
859
872
|
|
|
860
873
|
export type LogFunction = LogEvent => void;
|
|
861
874
|
export type LogRequestInfoFunction = mixed => void;
|
package/util/RelayError.js.flow
CHANGED
|
@@ -25,12 +25,15 @@ function createError(
|
|
|
25
25
|
String(messageParams[index++]),
|
|
26
26
|
);
|
|
27
27
|
const err = new Error(message);
|
|
28
|
+
// messageParams[2] is the operation name
|
|
29
|
+
const operation = messageParams[2] ?? null;
|
|
28
30
|
// $FlowFixMe[unsafe-object-assign]
|
|
29
31
|
const error = Object.assign(err as any, {
|
|
30
32
|
name,
|
|
31
33
|
messageFormat,
|
|
32
34
|
messageParams,
|
|
33
35
|
type,
|
|
36
|
+
operation,
|
|
34
37
|
taalOpcodes: [2, 2], // skip frame (code=2) twice
|
|
35
38
|
});
|
|
36
39
|
// In V8, Error objects keep the closure scope chain alive until the
|
|
@@ -87,6 +87,9 @@ export type FeatureFlags = {
|
|
|
87
87
|
|
|
88
88
|
// Reduce the work on store.notify
|
|
89
89
|
OPTIMIZE_NOTIFY: boolean,
|
|
90
|
+
|
|
91
|
+
// Enable logging for reader reading fragment spreads and fragments. Useful for logging unused fragments.
|
|
92
|
+
ENABLE_READER_FRAGMENTS_LOGGING: boolean,
|
|
90
93
|
};
|
|
91
94
|
|
|
92
95
|
const RelayFeatureFlags: FeatureFlags = {
|
|
@@ -118,6 +121,7 @@ const RelayFeatureFlags: FeatureFlags = {
|
|
|
118
121
|
CHECK_ALL_FRAGMENTS_FOR_MISSING_CLIENT_EDGES: false,
|
|
119
122
|
FILTER_OUT_RELAY_RESOLVER_RECORDS: false,
|
|
120
123
|
OPTIMIZE_NOTIFY: false,
|
|
124
|
+
ENABLE_READER_FRAGMENTS_LOGGING: false,
|
|
121
125
|
};
|
|
122
126
|
|
|
123
127
|
module.exports = RelayFeatureFlags;
|