relay-runtime 10.1.3 → 11.0.2
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/connection/ConnectionHandler.js.flow +60 -0
- package/handlers/connection/MutationHandlers.js.flow +28 -0
- package/index.js +1 -1
- package/index.js.flow +9 -3
- package/lib/handlers/RelayDefaultHandlerProvider.js +1 -1
- package/lib/handlers/connection/ConnectionHandler.js +68 -6
- package/lib/handlers/connection/MutationHandlers.js +67 -8
- package/lib/index.js +3 -0
- package/lib/multi-actor-environment/ActorIdentifier.js +23 -0
- package/lib/multi-actor-environment/ActorSpecificEnvironment.js +108 -0
- package/lib/multi-actor-environment/MultiActorEnvironment.js +156 -0
- package/lib/multi-actor-environment/MultiActorEnvironmentTypes.js +11 -0
- package/lib/multi-actor-environment/index.js +17 -0
- package/lib/mutations/RelayRecordProxy.js +1 -1
- package/lib/mutations/RelayRecordSourceMutator.js +1 -1
- package/lib/mutations/RelayRecordSourceProxy.js +1 -1
- package/lib/mutations/RelayRecordSourceSelectorProxy.js +1 -1
- package/lib/mutations/applyOptimisticMutation.js +1 -1
- package/lib/mutations/commitMutation.js +1 -1
- package/lib/mutations/validateMutation.js +36 -15
- package/lib/network/RelayNetwork.js +1 -1
- package/lib/network/RelayQueryResponseCache.js +3 -2
- package/lib/query/GraphQLTag.js +1 -1
- package/lib/query/fetchQuery.js +129 -13
- package/lib/query/fetchQueryInternal.js +3 -4
- package/lib/query/fetchQuery_DEPRECATED.js +39 -0
- package/lib/store/DataChecker.js +26 -14
- package/lib/store/{RelayModernQueryExecutor.js → OperationExecutor.js} +117 -47
- package/lib/store/RelayConcreteVariables.js +8 -4
- package/lib/store/RelayModernEnvironment.js +105 -136
- package/lib/store/RelayModernFragmentSpecResolver.js +16 -9
- package/lib/store/RelayModernRecord.js +1 -1
- package/lib/store/RelayModernSelector.js +1 -1
- package/lib/store/RelayModernStore.js +19 -20
- package/lib/store/RelayOperationTracker.js +55 -49
- package/lib/store/RelayPublishQueue.js +9 -5
- package/lib/store/RelayReader.js +68 -14
- package/lib/store/RelayReferenceMarker.js +28 -14
- package/lib/store/RelayResponseNormalizer.js +109 -15
- package/lib/store/RelayStoreReactFlightUtils.js +6 -4
- package/lib/store/RelayStoreSubscriptions.js +18 -8
- package/lib/store/RelayStoreSubscriptionsUsingMapByID.js +90 -30
- package/lib/store/RelayStoreUtils.js +3 -2
- package/lib/store/ResolverFragments.js +57 -0
- package/lib/store/cloneRelayHandleSourceField.js +1 -1
- package/lib/store/cloneRelayScalarHandleSourceField.js +1 -1
- package/lib/store/createFragmentSpecResolver.js +2 -2
- package/lib/store/createRelayContext.js +1 -1
- package/lib/store/defaultGetDataID.js +3 -1
- package/lib/store/hasOverlappingIDs.js +11 -3
- package/lib/store/readInlineData.js +1 -1
- package/lib/subscription/requestSubscription.js +33 -5
- package/lib/util/RelayConcreteNode.js +2 -0
- package/lib/util/RelayFeatureFlags.js +8 -3
- package/lib/util/RelayProfiler.js +17 -187
- package/lib/util/RelayReplaySubject.js +1 -1
- package/lib/util/deepFreeze.js +1 -0
- package/lib/util/getRelayHandleKey.js +1 -1
- package/lib/util/getRequestIdentifier.js +1 -1
- package/multi-actor-environment/ActorIdentifier.js.flow +27 -0
- package/multi-actor-environment/ActorSpecificEnvironment.js.flow +189 -0
- package/multi-actor-environment/MultiActorEnvironment.js.flow +233 -0
- package/multi-actor-environment/MultiActorEnvironmentTypes.js.flow +196 -0
- package/multi-actor-environment/index.js.flow +24 -0
- package/mutations/RelayRecordSourceProxy.js.flow +3 -2
- package/mutations/commitMutation.js.flow +1 -1
- package/mutations/validateMutation.js.flow +40 -15
- package/network/RelayNetworkTypes.js.flow +31 -11
- package/network/RelayQueryResponseCache.js.flow +2 -1
- package/package.json +3 -2
- package/query/fetchQuery.js.flow +147 -20
- package/query/fetchQueryInternal.js.flow +2 -3
- package/query/fetchQuery_DEPRECATED.js.flow +47 -0
- package/relay-runtime.js +2 -2
- package/relay-runtime.min.js +2 -2
- package/store/DataChecker.js.flow +23 -15
- package/store/{RelayModernQueryExecutor.js.flow → OperationExecutor.js.flow} +128 -40
- package/store/RelayConcreteVariables.js.flow +5 -0
- package/store/RelayModernEnvironment.js.flow +100 -130
- package/store/RelayModernFragmentSpecResolver.js.flow +30 -8
- package/store/RelayModernStore.js.flow +28 -24
- package/store/RelayOperationTracker.js.flow +69 -56
- package/store/RelayPublishQueue.js.flow +7 -4
- package/store/RelayReader.js.flow +63 -11
- package/store/RelayRecordSource.js.flow +3 -3
- package/store/RelayRecordSourceMapImpl.js.flow +6 -2
- package/store/RelayReferenceMarker.js.flow +28 -18
- package/store/RelayResponseNormalizer.js.flow +134 -23
- package/store/RelayStoreReactFlightUtils.js.flow +9 -4
- package/store/RelayStoreSubscriptions.js.flow +22 -7
- package/store/RelayStoreSubscriptionsUsingMapByID.js.flow +36 -12
- package/store/RelayStoreTypes.js.flow +51 -22
- package/store/RelayStoreUtils.js.flow +2 -1
- package/store/ResolverFragments.js.flow +125 -0
- package/store/createFragmentSpecResolver.js.flow +2 -0
- package/store/defaultGetDataID.js.flow +3 -1
- package/store/hasOverlappingIDs.js.flow +11 -9
- package/subscription/requestSubscription.js.flow +25 -2
- package/util/NormalizationNode.js.flow +13 -0
- package/util/ReaderNode.js.flow +14 -1
- package/util/RelayConcreteNode.js.flow +2 -0
- package/util/RelayFeatureFlags.js.flow +12 -2
- package/util/RelayProfiler.js.flow +22 -194
- package/util/RelayRuntimeTypes.js.flow +4 -5
- package/util/deepFreeze.js.flow +2 -1
- package/util/isEmptyObject.js.flow +1 -1
|
@@ -17,17 +17,17 @@ const invariant = require('invariant');
|
|
|
17
17
|
import type {RequestDescriptor} from './RelayStoreTypes';
|
|
18
18
|
|
|
19
19
|
class RelayOperationTracker {
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
20
|
+
_ownersToPendingOperationsIdentifier: Map<string, Set<string>>;
|
|
21
|
+
_pendingOperationsToOwnersIdentifier: Map<string, Set<string>>;
|
|
22
|
+
_ownersIdentifierToPromise: Map<
|
|
23
|
+
string,
|
|
24
24
|
{|promise: Promise<void>, resolve: () => void|},
|
|
25
25
|
>;
|
|
26
26
|
|
|
27
27
|
constructor() {
|
|
28
|
-
this.
|
|
29
|
-
this.
|
|
30
|
-
this.
|
|
28
|
+
this._ownersToPendingOperationsIdentifier = new Map();
|
|
29
|
+
this._pendingOperationsToOwnersIdentifier = new Map();
|
|
30
|
+
this._ownersIdentifierToPromise = new Map();
|
|
31
31
|
}
|
|
32
32
|
|
|
33
33
|
/**
|
|
@@ -41,43 +41,50 @@ class RelayOperationTracker {
|
|
|
41
41
|
if (affectedOwners.size === 0) {
|
|
42
42
|
return;
|
|
43
43
|
}
|
|
44
|
-
const
|
|
44
|
+
const pendingOperationIdentifier = pendingOperation.identifier;
|
|
45
|
+
const newlyAffectedOwnersIdentifier = new Set();
|
|
45
46
|
for (const owner of affectedOwners) {
|
|
46
|
-
const
|
|
47
|
-
|
|
47
|
+
const ownerIdentifier = owner.identifier;
|
|
48
|
+
const pendingOperationsAffectingOwner = this._ownersToPendingOperationsIdentifier.get(
|
|
49
|
+
ownerIdentifier,
|
|
48
50
|
);
|
|
49
51
|
if (pendingOperationsAffectingOwner != null) {
|
|
50
|
-
// In this case the `
|
|
52
|
+
// In this case the `ownerIdentifier` already affected by some operations
|
|
51
53
|
// We just need to detect, is it the same operation that we already
|
|
52
54
|
// have in the list, or it's a new operation
|
|
53
|
-
if (!pendingOperationsAffectingOwner.has(
|
|
54
|
-
pendingOperationsAffectingOwner.add(
|
|
55
|
-
|
|
55
|
+
if (!pendingOperationsAffectingOwner.has(pendingOperationIdentifier)) {
|
|
56
|
+
pendingOperationsAffectingOwner.add(pendingOperationIdentifier);
|
|
57
|
+
newlyAffectedOwnersIdentifier.add(ownerIdentifier);
|
|
56
58
|
}
|
|
57
59
|
} else {
|
|
58
|
-
// This is a new `
|
|
59
|
-
this.
|
|
60
|
-
|
|
60
|
+
// This is a new `ownerIdentifier` that is affected by the operation
|
|
61
|
+
this._ownersToPendingOperationsIdentifier.set(
|
|
62
|
+
ownerIdentifier,
|
|
63
|
+
new Set([pendingOperationIdentifier]),
|
|
64
|
+
);
|
|
65
|
+
newlyAffectedOwnersIdentifier.add(ownerIdentifier);
|
|
61
66
|
}
|
|
62
67
|
}
|
|
63
68
|
|
|
64
69
|
// No new owners were affected by this operation, we may stop here
|
|
65
|
-
if (
|
|
70
|
+
if (newlyAffectedOwnersIdentifier.size === 0) {
|
|
66
71
|
return;
|
|
67
72
|
}
|
|
68
73
|
|
|
69
74
|
// But, if some owners were affected we need to add them to
|
|
70
|
-
// the `
|
|
71
|
-
const
|
|
72
|
-
this.
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
75
|
+
// the `_pendingOperationsToOwnersIdentifier` set
|
|
76
|
+
const ownersAffectedByOperationIdentifier =
|
|
77
|
+
this._pendingOperationsToOwnersIdentifier.get(
|
|
78
|
+
pendingOperationIdentifier,
|
|
79
|
+
) || new Set();
|
|
80
|
+
|
|
81
|
+
for (const ownerIdentifier of newlyAffectedOwnersIdentifier) {
|
|
82
|
+
this._resolveOwnerResolvers(ownerIdentifier);
|
|
83
|
+
ownersAffectedByOperationIdentifier.add(ownerIdentifier);
|
|
77
84
|
}
|
|
78
|
-
this.
|
|
79
|
-
|
|
80
|
-
|
|
85
|
+
this._pendingOperationsToOwnersIdentifier.set(
|
|
86
|
+
pendingOperationIdentifier,
|
|
87
|
+
ownersAffectedByOperationIdentifier,
|
|
81
88
|
);
|
|
82
89
|
}
|
|
83
90
|
|
|
@@ -86,64 +93,70 @@ class RelayOperationTracker {
|
|
|
86
93
|
* from all tracking maps
|
|
87
94
|
*/
|
|
88
95
|
complete(pendingOperation: RequestDescriptor): void {
|
|
89
|
-
const
|
|
90
|
-
|
|
96
|
+
const pendingOperationIdentifier = pendingOperation.identifier;
|
|
97
|
+
const affectedOwnersIdentifier = this._pendingOperationsToOwnersIdentifier.get(
|
|
98
|
+
pendingOperationIdentifier,
|
|
91
99
|
);
|
|
92
|
-
if (
|
|
100
|
+
if (affectedOwnersIdentifier == null) {
|
|
93
101
|
return;
|
|
94
102
|
}
|
|
95
|
-
// These were the owners affected only by `
|
|
96
|
-
const
|
|
103
|
+
// These were the owners affected only by `pendingOperationIdentifier`
|
|
104
|
+
const completedOwnersIdentifier = new Set();
|
|
97
105
|
|
|
98
|
-
// These were the owners affected by `
|
|
106
|
+
// These were the owners affected by `pendingOperationIdentifier`
|
|
99
107
|
// and some other operations
|
|
100
|
-
const
|
|
101
|
-
for (const
|
|
102
|
-
const pendingOperationsAffectingOwner = this.
|
|
103
|
-
|
|
108
|
+
const updatedOwnersIdentifier = new Set();
|
|
109
|
+
for (const ownerIdentifier of affectedOwnersIdentifier) {
|
|
110
|
+
const pendingOperationsAffectingOwner = this._ownersToPendingOperationsIdentifier.get(
|
|
111
|
+
ownerIdentifier,
|
|
104
112
|
);
|
|
105
113
|
if (!pendingOperationsAffectingOwner) {
|
|
106
114
|
continue;
|
|
107
115
|
}
|
|
108
|
-
pendingOperationsAffectingOwner.delete(
|
|
116
|
+
pendingOperationsAffectingOwner.delete(pendingOperationIdentifier);
|
|
109
117
|
if (pendingOperationsAffectingOwner.size > 0) {
|
|
110
|
-
|
|
118
|
+
updatedOwnersIdentifier.add(ownerIdentifier);
|
|
111
119
|
} else {
|
|
112
|
-
|
|
120
|
+
completedOwnersIdentifier.add(ownerIdentifier);
|
|
113
121
|
}
|
|
114
122
|
}
|
|
115
123
|
|
|
116
|
-
// Complete subscriptions for all owners, affected by `
|
|
117
|
-
for (const
|
|
118
|
-
this._resolveOwnerResolvers(
|
|
119
|
-
this.
|
|
124
|
+
// Complete subscriptions for all owners, affected by `pendingOperationIdentifier`
|
|
125
|
+
for (const ownerIdentifier of completedOwnersIdentifier) {
|
|
126
|
+
this._resolveOwnerResolvers(ownerIdentifier);
|
|
127
|
+
this._ownersToPendingOperationsIdentifier.delete(ownerIdentifier);
|
|
120
128
|
}
|
|
121
129
|
|
|
122
|
-
// Update all
|
|
130
|
+
// Update all ownerIdentifier that were updated by `pendingOperationIdentifier` but still
|
|
123
131
|
// are affected by other operations
|
|
124
|
-
for (const
|
|
125
|
-
this._resolveOwnerResolvers(
|
|
132
|
+
for (const ownerIdentifier of updatedOwnersIdentifier) {
|
|
133
|
+
this._resolveOwnerResolvers(ownerIdentifier);
|
|
126
134
|
}
|
|
127
135
|
|
|
128
|
-
// Finally, remove pending operation
|
|
129
|
-
this.
|
|
136
|
+
// Finally, remove pending operation identifier
|
|
137
|
+
this._pendingOperationsToOwnersIdentifier.delete(
|
|
138
|
+
pendingOperationIdentifier,
|
|
139
|
+
);
|
|
130
140
|
}
|
|
131
141
|
|
|
132
|
-
_resolveOwnerResolvers(
|
|
133
|
-
const promiseEntry = this.
|
|
142
|
+
_resolveOwnerResolvers(ownerIdentifier: string): void {
|
|
143
|
+
const promiseEntry = this._ownersIdentifierToPromise.get(ownerIdentifier);
|
|
134
144
|
if (promiseEntry != null) {
|
|
135
145
|
promiseEntry.resolve();
|
|
136
146
|
}
|
|
137
|
-
this.
|
|
147
|
+
this._ownersIdentifierToPromise.delete(ownerIdentifier);
|
|
138
148
|
}
|
|
139
149
|
|
|
140
150
|
getPromiseForPendingOperationsAffectingOwner(
|
|
141
151
|
owner: RequestDescriptor,
|
|
142
152
|
): Promise<void> | null {
|
|
143
|
-
|
|
153
|
+
const ownerIdentifier = owner.identifier;
|
|
154
|
+
if (!this._ownersToPendingOperationsIdentifier.has(ownerIdentifier)) {
|
|
144
155
|
return null;
|
|
145
156
|
}
|
|
146
|
-
const cachedPromiseEntry = this.
|
|
157
|
+
const cachedPromiseEntry = this._ownersIdentifierToPromise.get(
|
|
158
|
+
ownerIdentifier,
|
|
159
|
+
);
|
|
147
160
|
if (cachedPromiseEntry != null) {
|
|
148
161
|
return cachedPromiseEntry.promise;
|
|
149
162
|
}
|
|
@@ -156,7 +169,7 @@ class RelayOperationTracker {
|
|
|
156
169
|
'RelayOperationTracker: Expected resolver to be defined. If you' +
|
|
157
170
|
'are seeing this, it is likely a bug in Relay.',
|
|
158
171
|
);
|
|
159
|
-
this.
|
|
172
|
+
this._ownersIdentifierToPromise.set(ownerIdentifier, {promise, resolve});
|
|
160
173
|
return promise;
|
|
161
174
|
}
|
|
162
175
|
}
|
|
@@ -12,7 +12,6 @@
|
|
|
12
12
|
|
|
13
13
|
'use strict';
|
|
14
14
|
|
|
15
|
-
const ErrorUtils = require('ErrorUtils');
|
|
16
15
|
const RelayReader = require('./RelayReader');
|
|
17
16
|
const RelayRecordSource = require('./RelayRecordSource');
|
|
18
17
|
const RelayRecordSourceMutator = require('../mutations/RelayRecordSourceMutator');
|
|
@@ -55,6 +54,10 @@ type PendingUpdater = {|
|
|
|
55
54
|
+updater: StoreUpdater,
|
|
56
55
|
|};
|
|
57
56
|
|
|
57
|
+
const applyWithGuard =
|
|
58
|
+
global.ErrorUtils?.applyWithGuard ??
|
|
59
|
+
((callback, context, args, onError, name) => callback.apply(context, args));
|
|
60
|
+
|
|
58
61
|
/**
|
|
59
62
|
* Coordinates the concurrent modification of a `Store` due to optimistic and
|
|
60
63
|
* non-revertable client updates and server payloads:
|
|
@@ -299,7 +302,7 @@ class RelayPublishQueue implements PublishQueue {
|
|
|
299
302
|
mutator,
|
|
300
303
|
this._getDataID,
|
|
301
304
|
);
|
|
302
|
-
|
|
305
|
+
applyWithGuard(
|
|
303
306
|
updater,
|
|
304
307
|
null,
|
|
305
308
|
[recordSourceProxy],
|
|
@@ -334,7 +337,7 @@ class RelayPublishQueue implements PublishQueue {
|
|
|
334
337
|
const processUpdate = optimisticUpdate => {
|
|
335
338
|
if (optimisticUpdate.storeUpdater) {
|
|
336
339
|
const {storeUpdater} = optimisticUpdate;
|
|
337
|
-
|
|
340
|
+
applyWithGuard(
|
|
338
341
|
storeUpdater,
|
|
339
342
|
null,
|
|
340
343
|
[recordSourceProxy],
|
|
@@ -355,7 +358,7 @@ class RelayPublishQueue implements PublishQueue {
|
|
|
355
358
|
selectorData = lookupSelector(source, operation.fragment);
|
|
356
359
|
}
|
|
357
360
|
if (updater) {
|
|
358
|
-
|
|
361
|
+
applyWithGuard(
|
|
359
362
|
updater,
|
|
360
363
|
null,
|
|
361
364
|
[recordSourceSelectorProxy, selectorData],
|
|
@@ -28,6 +28,7 @@ const {
|
|
|
28
28
|
LINKED_FIELD,
|
|
29
29
|
MODULE_IMPORT,
|
|
30
30
|
REQUIRED_FIELD,
|
|
31
|
+
RELAY_RESOLVER,
|
|
31
32
|
SCALAR_FIELD,
|
|
32
33
|
STREAM,
|
|
33
34
|
} = require('../util/RelayConcreteNode');
|
|
@@ -44,15 +45,18 @@ const {
|
|
|
44
45
|
getStorageKey,
|
|
45
46
|
getModuleComponentKey,
|
|
46
47
|
} = require('./RelayStoreUtils');
|
|
48
|
+
const {withResolverContext} = require('./ResolverFragments');
|
|
47
49
|
const {generateTypeID} = require('./TypeID');
|
|
48
50
|
|
|
49
51
|
import type {
|
|
50
52
|
ReaderFlightField,
|
|
53
|
+
ReaderFragment,
|
|
51
54
|
ReaderFragmentSpread,
|
|
52
55
|
ReaderInlineDataFragmentSpread,
|
|
53
56
|
ReaderLinkedField,
|
|
54
57
|
ReaderModuleImport,
|
|
55
58
|
ReaderNode,
|
|
59
|
+
ReaderRelayResolver,
|
|
56
60
|
ReaderRequiredField,
|
|
57
61
|
ReaderScalarField,
|
|
58
62
|
ReaderSelection,
|
|
@@ -66,6 +70,7 @@ import type {
|
|
|
66
70
|
SingularReaderSelector,
|
|
67
71
|
Snapshot,
|
|
68
72
|
MissingRequiredFields,
|
|
73
|
+
DataIDSet,
|
|
69
74
|
} from './RelayStoreTypes';
|
|
70
75
|
|
|
71
76
|
function read(
|
|
@@ -85,7 +90,7 @@ class RelayReader {
|
|
|
85
90
|
_missingRequiredFields: ?MissingRequiredFields;
|
|
86
91
|
_owner: RequestDescriptor;
|
|
87
92
|
_recordSource: RecordSource;
|
|
88
|
-
_seenRecords:
|
|
93
|
+
_seenRecords: DataIDSet;
|
|
89
94
|
_selector: SingularReaderSelector;
|
|
90
95
|
_variables: Variables;
|
|
91
96
|
|
|
@@ -95,7 +100,7 @@ class RelayReader {
|
|
|
95
100
|
this._missingRequiredFields = null;
|
|
96
101
|
this._owner = selector.owner;
|
|
97
102
|
this._recordSource = recordSource;
|
|
98
|
-
this._seenRecords =
|
|
103
|
+
this._seenRecords = new Set();
|
|
99
104
|
this._selector = selector;
|
|
100
105
|
this._variables = selector.variables;
|
|
101
106
|
}
|
|
@@ -169,7 +174,7 @@ class RelayReader {
|
|
|
169
174
|
prevData: ?SelectorData,
|
|
170
175
|
): ?SelectorData {
|
|
171
176
|
const record = this._recordSource.get(dataID);
|
|
172
|
-
this._seenRecords
|
|
177
|
+
this._seenRecords.add(dataID);
|
|
173
178
|
if (record == null) {
|
|
174
179
|
if (record === undefined) {
|
|
175
180
|
this._isMissingData = true;
|
|
@@ -191,6 +196,7 @@ class RelayReader {
|
|
|
191
196
|
'RelayReader(): Undefined variable `%s`.',
|
|
192
197
|
name,
|
|
193
198
|
);
|
|
199
|
+
// $FlowFixMe[cannot-write]
|
|
194
200
|
return this._variables[name];
|
|
195
201
|
}
|
|
196
202
|
|
|
@@ -325,6 +331,13 @@ class RelayReader {
|
|
|
325
331
|
}
|
|
326
332
|
break;
|
|
327
333
|
}
|
|
334
|
+
case RELAY_RESOLVER: {
|
|
335
|
+
if (!RelayFeatureFlags.ENABLE_RELAY_RESOLVERS) {
|
|
336
|
+
throw new Error('Relay Resolver fields are not yet supported.');
|
|
337
|
+
}
|
|
338
|
+
this._readResolverField(selection, record, data);
|
|
339
|
+
break;
|
|
340
|
+
}
|
|
328
341
|
case FRAGMENT_SPREAD:
|
|
329
342
|
this._createFragmentPointer(selection, record, data);
|
|
330
343
|
break;
|
|
@@ -332,7 +345,11 @@ class RelayReader {
|
|
|
332
345
|
this._readModuleImport(selection, record, data);
|
|
333
346
|
break;
|
|
334
347
|
case INLINE_DATA_FRAGMENT_SPREAD:
|
|
335
|
-
this.
|
|
348
|
+
this._createInlineDataOrResolverFragmentPointer(
|
|
349
|
+
selection,
|
|
350
|
+
record,
|
|
351
|
+
data,
|
|
352
|
+
);
|
|
336
353
|
break;
|
|
337
354
|
case DEFER:
|
|
338
355
|
case CLIENT_EXTENSION: {
|
|
@@ -402,6 +419,43 @@ class RelayReader {
|
|
|
402
419
|
}
|
|
403
420
|
}
|
|
404
421
|
|
|
422
|
+
_readResolverField(
|
|
423
|
+
selection: ReaderRelayResolver,
|
|
424
|
+
record: Record,
|
|
425
|
+
data: SelectorData,
|
|
426
|
+
): ?mixed {
|
|
427
|
+
const {name, alias, resolverModule, fragment} = selection;
|
|
428
|
+
const key = {
|
|
429
|
+
__id: RelayModernRecord.getDataID(record),
|
|
430
|
+
__fragmentOwner: this._owner,
|
|
431
|
+
__fragments: {
|
|
432
|
+
[fragment.name]: {}, // Arguments to this fragment; not yet supported.
|
|
433
|
+
},
|
|
434
|
+
};
|
|
435
|
+
const resolverContext = {
|
|
436
|
+
getDataForResolverFragment: singularReaderSelector => {
|
|
437
|
+
const resolverFragmentData = {};
|
|
438
|
+
this._createInlineDataOrResolverFragmentPointer(
|
|
439
|
+
singularReaderSelector.node,
|
|
440
|
+
record,
|
|
441
|
+
resolverFragmentData,
|
|
442
|
+
);
|
|
443
|
+
const answer = resolverFragmentData[FRAGMENTS_KEY]?.[fragment.name];
|
|
444
|
+
invariant(
|
|
445
|
+
typeof answer === 'object' && answer !== null,
|
|
446
|
+
`Expected reader data to contain a __fragments property with a property for the fragment named ${fragment.name}, but it is missing.`,
|
|
447
|
+
);
|
|
448
|
+
return answer;
|
|
449
|
+
},
|
|
450
|
+
};
|
|
451
|
+
const resolverResult = withResolverContext(resolverContext, () =>
|
|
452
|
+
// $FlowFixMe[prop-missing] - resolver module's type signature is a lie
|
|
453
|
+
resolverModule(key),
|
|
454
|
+
);
|
|
455
|
+
data[alias ?? name] = resolverResult;
|
|
456
|
+
return resolverResult;
|
|
457
|
+
}
|
|
458
|
+
|
|
405
459
|
_readFlightField(
|
|
406
460
|
field: ReaderFlightField,
|
|
407
461
|
record: Record,
|
|
@@ -423,9 +477,7 @@ class RelayReader {
|
|
|
423
477
|
const reactFlightClientResponseRecord = this._recordSource.get(
|
|
424
478
|
reactFlightClientResponseRecordID,
|
|
425
479
|
);
|
|
426
|
-
this._seenRecords
|
|
427
|
-
reactFlightClientResponseRecordID
|
|
428
|
-
] = reactFlightClientResponseRecord;
|
|
480
|
+
this._seenRecords.add(reactFlightClientResponseRecordID);
|
|
429
481
|
if (reactFlightClientResponseRecord == null) {
|
|
430
482
|
data[applicationName] = reactFlightClientResponseRecord;
|
|
431
483
|
if (reactFlightClientResponseRecord === undefined) {
|
|
@@ -607,8 +659,8 @@ class RelayReader {
|
|
|
607
659
|
}
|
|
608
660
|
}
|
|
609
661
|
|
|
610
|
-
|
|
611
|
-
|
|
662
|
+
_createInlineDataOrResolverFragmentPointer(
|
|
663
|
+
fragmentSpreadOrFragment: ReaderInlineDataFragmentSpread | ReaderFragment,
|
|
612
664
|
record: Record,
|
|
613
665
|
data: SelectorData,
|
|
614
666
|
): void {
|
|
@@ -626,12 +678,12 @@ class RelayReader {
|
|
|
626
678
|
}
|
|
627
679
|
const inlineData = {};
|
|
628
680
|
this._traverseSelections(
|
|
629
|
-
|
|
681
|
+
fragmentSpreadOrFragment.selections,
|
|
630
682
|
record,
|
|
631
683
|
inlineData,
|
|
632
684
|
);
|
|
633
685
|
// $FlowFixMe[cannot-write] - writing into read-only field
|
|
634
|
-
fragmentPointers[
|
|
686
|
+
fragmentPointers[fragmentSpreadOrFragment.name] = inlineData;
|
|
635
687
|
}
|
|
636
688
|
}
|
|
637
689
|
|
|
@@ -14,14 +14,14 @@
|
|
|
14
14
|
|
|
15
15
|
const RelayRecordSourceMapImpl = require('./RelayRecordSourceMapImpl');
|
|
16
16
|
|
|
17
|
-
import type {MutableRecordSource,
|
|
17
|
+
import type {MutableRecordSource, RecordObjectMap} from './RelayStoreTypes';
|
|
18
18
|
|
|
19
19
|
class RelayRecordSource {
|
|
20
|
-
constructor(records?:
|
|
20
|
+
constructor(records?: RecordObjectMap): MutableRecordSource {
|
|
21
21
|
return RelayRecordSource.create(records);
|
|
22
22
|
}
|
|
23
23
|
|
|
24
|
-
static create(records?:
|
|
24
|
+
static create(records?: RecordObjectMap): MutableRecordSource {
|
|
25
25
|
return new RelayRecordSourceMapImpl(records);
|
|
26
26
|
}
|
|
27
27
|
}
|
|
@@ -16,7 +16,11 @@ const RelayRecordState = require('./RelayRecordState');
|
|
|
16
16
|
|
|
17
17
|
import type {DataID} from '../util/RelayRuntimeTypes';
|
|
18
18
|
import type {RecordState} from './RelayRecordState';
|
|
19
|
-
import type {
|
|
19
|
+
import type {
|
|
20
|
+
MutableRecordSource,
|
|
21
|
+
Record,
|
|
22
|
+
RecordObjectMap,
|
|
23
|
+
} from './RelayStoreTypes';
|
|
20
24
|
|
|
21
25
|
const {EXISTENT, NONEXISTENT, UNKNOWN} = RelayRecordState;
|
|
22
26
|
|
|
@@ -27,7 +31,7 @@ const {EXISTENT, NONEXISTENT, UNKNOWN} = RelayRecordState;
|
|
|
27
31
|
class RelayMapRecordSourceMapImpl implements MutableRecordSource {
|
|
28
32
|
_records: Map<DataID, ?Record>;
|
|
29
33
|
|
|
30
|
-
constructor(records?:
|
|
34
|
+
constructor(records?: RecordObjectMap) {
|
|
31
35
|
this._records = new Map();
|
|
32
36
|
if (records != null) {
|
|
33
37
|
Object.keys(records).forEach(key => {
|
|
@@ -24,7 +24,6 @@ const invariant = require('invariant');
|
|
|
24
24
|
|
|
25
25
|
const {generateTypeID} = require('./TypeID');
|
|
26
26
|
|
|
27
|
-
import type {ReactFlightPayloadQuery} from '../network/RelayNetworkTypes';
|
|
28
27
|
import type {
|
|
29
28
|
NormalizationFlightField,
|
|
30
29
|
NormalizationLinkedField,
|
|
@@ -34,14 +33,17 @@ import type {
|
|
|
34
33
|
} from '../util/NormalizationNode';
|
|
35
34
|
import type {DataID, Variables} from '../util/RelayRuntimeTypes';
|
|
36
35
|
import type {
|
|
36
|
+
DataIDSet,
|
|
37
37
|
NormalizationSelector,
|
|
38
38
|
OperationLoader,
|
|
39
39
|
Record,
|
|
40
40
|
RecordSource,
|
|
41
|
+
ReactFlightReachableExecutableDefinitions,
|
|
41
42
|
} from './RelayStoreTypes';
|
|
42
43
|
|
|
43
44
|
const {
|
|
44
45
|
CONDITION,
|
|
46
|
+
CLIENT_COMPONENT,
|
|
45
47
|
CLIENT_EXTENSION,
|
|
46
48
|
DEFER,
|
|
47
49
|
FLIGHT_FIELD,
|
|
@@ -60,8 +62,9 @@ const {ROOT_ID, getStorageKey, getModuleOperationKey} = RelayStoreUtils;
|
|
|
60
62
|
function mark(
|
|
61
63
|
recordSource: RecordSource,
|
|
62
64
|
selector: NormalizationSelector,
|
|
63
|
-
references:
|
|
65
|
+
references: DataIDSet,
|
|
64
66
|
operationLoader: ?OperationLoader,
|
|
67
|
+
shouldProcessClientComponents: ?boolean,
|
|
65
68
|
): void {
|
|
66
69
|
const {dataID, node, variables} = selector;
|
|
67
70
|
const marker = new RelayReferenceMarker(
|
|
@@ -69,6 +72,7 @@ function mark(
|
|
|
69
72
|
variables,
|
|
70
73
|
references,
|
|
71
74
|
operationLoader,
|
|
75
|
+
shouldProcessClientComponents,
|
|
72
76
|
);
|
|
73
77
|
marker.mark(node, dataID);
|
|
74
78
|
}
|
|
@@ -80,20 +84,23 @@ class RelayReferenceMarker {
|
|
|
80
84
|
_operationLoader: OperationLoader | null;
|
|
81
85
|
_operationName: ?string;
|
|
82
86
|
_recordSource: RecordSource;
|
|
83
|
-
_references:
|
|
87
|
+
_references: DataIDSet;
|
|
84
88
|
_variables: Variables;
|
|
89
|
+
_shouldProcessClientComponents: ?boolean;
|
|
85
90
|
|
|
86
91
|
constructor(
|
|
87
92
|
recordSource: RecordSource,
|
|
88
93
|
variables: Variables,
|
|
89
|
-
references:
|
|
94
|
+
references: DataIDSet,
|
|
90
95
|
operationLoader: ?OperationLoader,
|
|
96
|
+
shouldProcessClientComponents: ?boolean,
|
|
91
97
|
) {
|
|
92
98
|
this._operationLoader = operationLoader ?? null;
|
|
93
99
|
this._operationName = null;
|
|
94
100
|
this._recordSource = recordSource;
|
|
95
101
|
this._references = references;
|
|
96
102
|
this._variables = variables;
|
|
103
|
+
this._shouldProcessClientComponents = shouldProcessClientComponents;
|
|
97
104
|
}
|
|
98
105
|
|
|
99
106
|
mark(node: NormalizationNode, dataID: DataID): void {
|
|
@@ -118,6 +125,7 @@ class RelayReferenceMarker {
|
|
|
118
125
|
'RelayReferenceMarker(): Undefined variable `%s`.',
|
|
119
126
|
name,
|
|
120
127
|
);
|
|
128
|
+
// $FlowFixMe[cannot-write]
|
|
121
129
|
return this._variables[name];
|
|
122
130
|
}
|
|
123
131
|
|
|
@@ -158,12 +166,8 @@ class RelayReferenceMarker {
|
|
|
158
166
|
break;
|
|
159
167
|
// $FlowFixMe[incompatible-type]
|
|
160
168
|
case FRAGMENT_SPREAD:
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
'RelayReferenceMarker(): Unexpected fragment spread `...%s`, ' +
|
|
164
|
-
'expected all fragments to be inlined.',
|
|
165
|
-
selection.name,
|
|
166
|
-
);
|
|
169
|
+
this._traverseSelections(selection.fragment.selections, record);
|
|
170
|
+
break;
|
|
167
171
|
case LINKED_HANDLE:
|
|
168
172
|
// The selections for a "handle" field are the same as those of the
|
|
169
173
|
// original linked field where the handle was applied. Reference marking
|
|
@@ -213,6 +217,12 @@ class RelayReferenceMarker {
|
|
|
213
217
|
throw new Error('Flight fields are not yet supported.');
|
|
214
218
|
}
|
|
215
219
|
break;
|
|
220
|
+
case CLIENT_COMPONENT:
|
|
221
|
+
if (this._shouldProcessClientComponents === false) {
|
|
222
|
+
break;
|
|
223
|
+
}
|
|
224
|
+
this._traverseSelections(selection.fragment.selections, record);
|
|
225
|
+
break;
|
|
216
226
|
default:
|
|
217
227
|
(selection: empty);
|
|
218
228
|
invariant(
|
|
@@ -289,12 +299,12 @@ class RelayReferenceMarker {
|
|
|
289
299
|
return;
|
|
290
300
|
}
|
|
291
301
|
|
|
292
|
-
const
|
|
302
|
+
const reachableExecutableDefinitions = RelayModernRecord.getValue(
|
|
293
303
|
reactFlightClientResponseRecord,
|
|
294
|
-
RelayStoreReactFlightUtils.
|
|
304
|
+
RelayStoreReactFlightUtils.REACT_FLIGHT_EXECUTABLE_DEFINITIONS_STORAGE_KEY,
|
|
295
305
|
);
|
|
296
306
|
|
|
297
|
-
if (!Array.isArray(
|
|
307
|
+
if (!Array.isArray(reachableExecutableDefinitions)) {
|
|
298
308
|
return;
|
|
299
309
|
}
|
|
300
310
|
|
|
@@ -304,13 +314,13 @@ class RelayReferenceMarker {
|
|
|
304
314
|
'DataChecker: Expected an operationLoader to be configured when using ' +
|
|
305
315
|
'React Flight',
|
|
306
316
|
);
|
|
307
|
-
// In Flight, the variables that are in scope for reachable
|
|
308
|
-
// the same as what's in scope for the outer query.
|
|
317
|
+
// In Flight, the variables that are in scope for reachable executable
|
|
318
|
+
// definitions aren't the same as what's in scope for the outer query.
|
|
309
319
|
const prevVariables = this._variables;
|
|
310
320
|
// $FlowFixMe[incompatible-cast]
|
|
311
|
-
for (const
|
|
312
|
-
this._variables =
|
|
313
|
-
const operationReference =
|
|
321
|
+
for (const definition of (reachableExecutableDefinitions: Array<ReactFlightReachableExecutableDefinitions>)) {
|
|
322
|
+
this._variables = definition.variables;
|
|
323
|
+
const operationReference = definition.module;
|
|
314
324
|
const normalizationRootNode = operationLoader.get(operationReference);
|
|
315
325
|
if (normalizationRootNode != null) {
|
|
316
326
|
const operation = getOperation(normalizationRootNode);
|