relay-runtime 7.0.0 → 9.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/handlers/RelayDefaultHandlerProvider.js.flow +34 -0
- package/handlers/connection/ConnectionHandler.js.flow +549 -0
- package/handlers/connection/ConnectionInterface.js.flow +92 -0
- package/index.js +1 -1
- package/index.js.flow +314 -0
- package/lib/handlers/RelayDefaultHandlerProvider.js +3 -2
- package/lib/handlers/connection/{RelayConnectionHandler.js → ConnectionHandler.js} +34 -35
- package/lib/handlers/connection/{RelayConnectionInterface.js → ConnectionInterface.js} +3 -30
- package/lib/index.js +29 -27
- package/lib/mutations/RelayDeclarativeMutationConfig.js +30 -52
- package/lib/mutations/RelayRecordProxy.js +6 -3
- package/lib/mutations/RelayRecordSourceMutator.js +3 -9
- package/lib/mutations/RelayRecordSourceProxy.js +21 -24
- package/lib/mutations/RelayRecordSourceSelectorProxy.js +18 -14
- package/lib/mutations/applyOptimisticMutation.js +2 -1
- package/lib/mutations/commitLocalUpdate.js +1 -0
- package/lib/mutations/commitMutation.js +26 -8
- package/lib/mutations/validateMutation.js +21 -11
- package/lib/network/ConvertToExecuteFunction.js +1 -0
- package/lib/network/RelayNetwork.js +1 -0
- package/lib/network/RelayNetworkTypes.js +1 -0
- package/lib/network/RelayObservable.js +10 -9
- package/lib/network/RelayQueryResponseCache.js +9 -7
- package/lib/query/{RelayModernGraphQLTag.js → GraphQLTag.js} +15 -8
- package/lib/query/fetchQuery.js +2 -1
- package/lib/query/fetchQueryInternal.js +30 -20
- package/lib/store/ClientID.js +1 -0
- package/lib/store/DataChecker.js +47 -97
- package/lib/store/RelayConcreteVariables.js +7 -2
- package/lib/store/RelayModernEnvironment.js +82 -41
- package/lib/store/RelayModernFragmentSpecResolver.js +61 -21
- package/lib/store/RelayModernOperationDescriptor.js +2 -1
- package/lib/store/RelayModernQueryExecutor.js +476 -333
- package/lib/store/RelayModernRecord.js +39 -9
- package/lib/store/RelayModernSelector.js +2 -1
- package/lib/store/RelayModernStore.js +359 -371
- package/lib/store/RelayOperationTracker.js +36 -78
- package/lib/store/RelayOptimisticRecordSource.js +8 -5
- package/lib/store/RelayPublishQueue.js +66 -53
- package/lib/store/RelayReader.js +2 -24
- package/lib/store/RelayRecordSource.js +3 -9
- package/lib/store/RelayRecordSourceMapImpl.js +14 -18
- package/lib/store/RelayRecordState.js +1 -0
- package/lib/store/RelayReferenceMarker.js +8 -58
- package/lib/store/RelayResponseNormalizer.js +15 -144
- package/lib/store/RelayStoreTypes.js +1 -0
- package/lib/store/RelayStoreUtils.js +34 -10
- package/lib/store/StoreInspector.js +11 -5
- package/lib/store/ViewerPattern.js +1 -0
- package/lib/store/cloneRelayHandleSourceField.js +1 -0
- package/lib/store/createFragmentSpecResolver.js +1 -0
- package/lib/store/createRelayContext.js +1 -0
- package/lib/store/defaultGetDataID.js +1 -0
- package/lib/store/hasOverlappingIDs.js +1 -0
- package/lib/store/isRelayModernEnvironment.js +1 -0
- package/lib/store/normalizeRelayPayload.js +8 -4
- package/lib/store/readInlineData.js +2 -1
- package/lib/subscription/requestSubscription.js +6 -3
- package/lib/util/JSResourceTypes.flow.js +12 -0
- package/lib/util/NormalizationNode.js +1 -0
- package/lib/util/ReaderNode.js +1 -0
- package/lib/util/RelayConcreteNode.js +3 -0
- package/lib/util/RelayDefaultHandleKey.js +1 -0
- package/lib/util/RelayError.js +2 -1
- package/lib/util/RelayFeatureFlags.js +3 -2
- package/lib/util/RelayProfiler.js +1 -0
- package/lib/util/RelayReplaySubject.js +2 -3
- package/lib/util/RelayRuntimeTypes.js +1 -0
- package/lib/util/createPayloadFor3DField.js +34 -0
- package/lib/util/deepFreeze.js +1 -0
- package/lib/util/generateID.js +1 -0
- package/lib/util/getFragmentIdentifier.js +1 -0
- package/lib/util/getRelayHandleKey.js +1 -0
- package/lib/util/getRequestIdentifier.js +1 -0
- package/lib/util/isPromise.js +1 -0
- package/lib/util/isScalarAndEqual.js +1 -0
- package/lib/util/recycleNodesInto.js +1 -0
- package/lib/util/resolveImmediate.js +1 -0
- package/lib/util/stableCopy.js +1 -0
- package/mutations/RelayDeclarativeMutationConfig.js.flow +380 -0
- package/mutations/RelayRecordProxy.js.flow +165 -0
- package/mutations/RelayRecordSourceMutator.js.flow +238 -0
- package/mutations/RelayRecordSourceProxy.js.flow +164 -0
- package/mutations/RelayRecordSourceSelectorProxy.js.flow +119 -0
- package/mutations/applyOptimisticMutation.js.flow +76 -0
- package/mutations/commitLocalUpdate.js.flow +24 -0
- package/mutations/commitMutation.js.flow +184 -0
- package/mutations/validateMutation.js.flow +211 -0
- package/network/ConvertToExecuteFunction.js.flow +49 -0
- package/network/RelayNetwork.js.flow +84 -0
- package/network/RelayNetworkTypes.js.flow +123 -0
- package/network/RelayObservable.js.flow +634 -0
- package/network/RelayQueryResponseCache.js.flow +111 -0
- package/package.json +1 -1
- package/query/GraphQLTag.js.flow +166 -0
- package/query/fetchQuery.js.flow +47 -0
- package/query/fetchQueryInternal.js.flow +349 -0
- package/relay-runtime.js +2 -2
- package/relay-runtime.min.js +2 -2
- package/store/ClientID.js.flow +43 -0
- package/store/DataChecker.js.flow +426 -0
- package/store/RelayConcreteVariables.js.flow +96 -0
- package/store/RelayModernEnvironment.js.flow +526 -0
- package/store/RelayModernFragmentSpecResolver.js.flow +426 -0
- package/store/RelayModernOperationDescriptor.js.flow +88 -0
- package/store/RelayModernQueryExecutor.js.flow +1327 -0
- package/store/RelayModernRecord.js.flow +403 -0
- package/store/RelayModernSelector.js.flow +444 -0
- package/store/RelayModernStore.js.flow +757 -0
- package/store/RelayOperationTracker.js.flow +164 -0
- package/store/RelayOptimisticRecordSource.js.flow +119 -0
- package/store/RelayPublishQueue.js.flow +401 -0
- package/store/RelayReader.js.flow +376 -0
- package/store/RelayRecordSource.js.flow +29 -0
- package/store/RelayRecordSourceMapImpl.js.flow +87 -0
- package/store/RelayRecordState.js.flow +37 -0
- package/store/RelayReferenceMarker.js.flow +236 -0
- package/store/RelayResponseNormalizer.js.flow +556 -0
- package/store/RelayStoreTypes.js.flow +873 -0
- package/store/RelayStoreUtils.js.flow +218 -0
- package/store/StoreInspector.js.flow +173 -0
- package/store/ViewerPattern.js.flow +26 -0
- package/store/cloneRelayHandleSourceField.js.flow +66 -0
- package/store/createFragmentSpecResolver.js.flow +55 -0
- package/store/createRelayContext.js.flow +44 -0
- package/store/defaultGetDataID.js.flow +27 -0
- package/store/hasOverlappingIDs.js.flow +34 -0
- package/store/isRelayModernEnvironment.js.flow +27 -0
- package/store/normalizeRelayPayload.js.flow +51 -0
- package/store/readInlineData.js.flow +75 -0
- package/subscription/requestSubscription.js.flow +100 -0
- package/util/JSResourceTypes.flow.js.flow +20 -0
- package/util/NormalizationNode.js.flow +191 -0
- package/util/ReaderNode.js.flow +208 -0
- package/util/RelayConcreteNode.js.flow +80 -0
- package/util/RelayDefaultHandleKey.js.flow +17 -0
- package/util/RelayError.js.flow +33 -0
- package/util/RelayFeatureFlags.js.flow +30 -0
- package/util/RelayProfiler.js.flow +284 -0
- package/util/RelayReplaySubject.js.flow +134 -0
- package/util/RelayRuntimeTypes.js.flow +70 -0
- package/util/createPayloadFor3DField.js.flow +43 -0
- package/util/deepFreeze.js.flow +36 -0
- package/util/generateID.js.flow +21 -0
- package/util/getFragmentIdentifier.js.flow +52 -0
- package/util/getRelayHandleKey.js.flow +41 -0
- package/util/getRequestIdentifier.js.flow +41 -0
- package/util/isPromise.js.flow +21 -0
- package/util/isScalarAndEqual.js.flow +26 -0
- package/util/recycleNodesInto.js.flow +80 -0
- package/util/resolveImmediate.js.flow +30 -0
- package/util/stableCopy.js.flow +35 -0
- package/lib/handlers/RelayDefaultMissingFieldHandlers.js +0 -26
- package/lib/store/RelayConnection.js +0 -36
- package/lib/store/RelayConnectionResolver.js +0 -177
- package/lib/store/RelayRecordSourceObjectImpl.js +0 -78
- package/lib/util/getFragmentSpecIdentifier.js +0 -26
|
@@ -0,0 +1,376 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright (c) Facebook, Inc. and its affiliates.
|
|
3
|
+
*
|
|
4
|
+
* This source code is licensed under the MIT license found in the
|
|
5
|
+
* LICENSE file in the root directory of this source tree.
|
|
6
|
+
*
|
|
7
|
+
* @flow strict-local
|
|
8
|
+
* @format
|
|
9
|
+
*/
|
|
10
|
+
|
|
11
|
+
// flowlint ambiguous-object-type:error
|
|
12
|
+
|
|
13
|
+
'use strict';
|
|
14
|
+
|
|
15
|
+
const RelayModernRecord = require('./RelayModernRecord');
|
|
16
|
+
|
|
17
|
+
const invariant = require('invariant');
|
|
18
|
+
|
|
19
|
+
const {
|
|
20
|
+
CLIENT_EXTENSION,
|
|
21
|
+
CONDITION,
|
|
22
|
+
DEFER,
|
|
23
|
+
FRAGMENT_SPREAD,
|
|
24
|
+
INLINE_DATA_FRAGMENT_SPREAD,
|
|
25
|
+
INLINE_FRAGMENT,
|
|
26
|
+
LINKED_FIELD,
|
|
27
|
+
MODULE_IMPORT,
|
|
28
|
+
SCALAR_FIELD,
|
|
29
|
+
STREAM,
|
|
30
|
+
} = require('../util/RelayConcreteNode');
|
|
31
|
+
const {
|
|
32
|
+
FRAGMENTS_KEY,
|
|
33
|
+
FRAGMENT_OWNER_KEY,
|
|
34
|
+
FRAGMENT_PROP_NAME_KEY,
|
|
35
|
+
ID_KEY,
|
|
36
|
+
MODULE_COMPONENT_KEY,
|
|
37
|
+
getArgumentValues,
|
|
38
|
+
getStorageKey,
|
|
39
|
+
getModuleComponentKey,
|
|
40
|
+
} = require('./RelayStoreUtils');
|
|
41
|
+
|
|
42
|
+
import type {
|
|
43
|
+
ReaderFragmentSpread,
|
|
44
|
+
ReaderInlineDataFragmentSpread,
|
|
45
|
+
ReaderLinkedField,
|
|
46
|
+
ReaderModuleImport,
|
|
47
|
+
ReaderNode,
|
|
48
|
+
ReaderScalarField,
|
|
49
|
+
ReaderSelection,
|
|
50
|
+
} from '../util/ReaderNode';
|
|
51
|
+
import type {DataID, Variables} from '../util/RelayRuntimeTypes';
|
|
52
|
+
import type {
|
|
53
|
+
Record,
|
|
54
|
+
RecordSource,
|
|
55
|
+
RequestDescriptor,
|
|
56
|
+
SelectorData,
|
|
57
|
+
SingularReaderSelector,
|
|
58
|
+
Snapshot,
|
|
59
|
+
} from './RelayStoreTypes';
|
|
60
|
+
|
|
61
|
+
function read(
|
|
62
|
+
recordSource: RecordSource,
|
|
63
|
+
selector: SingularReaderSelector,
|
|
64
|
+
): Snapshot {
|
|
65
|
+
const reader = new RelayReader(recordSource, selector);
|
|
66
|
+
return reader.read();
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
/**
|
|
70
|
+
* @private
|
|
71
|
+
*/
|
|
72
|
+
class RelayReader {
|
|
73
|
+
_isMissingData: boolean;
|
|
74
|
+
_owner: RequestDescriptor;
|
|
75
|
+
_recordSource: RecordSource;
|
|
76
|
+
_seenRecords: {[dataID: DataID]: ?Record, ...};
|
|
77
|
+
_selector: SingularReaderSelector;
|
|
78
|
+
_variables: Variables;
|
|
79
|
+
|
|
80
|
+
constructor(recordSource: RecordSource, selector: SingularReaderSelector) {
|
|
81
|
+
this._isMissingData = false;
|
|
82
|
+
this._owner = selector.owner;
|
|
83
|
+
this._recordSource = recordSource;
|
|
84
|
+
this._seenRecords = {};
|
|
85
|
+
this._selector = selector;
|
|
86
|
+
this._variables = selector.variables;
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
read(): Snapshot {
|
|
90
|
+
const {node, dataID} = this._selector;
|
|
91
|
+
const data = this._traverse(node, dataID, null);
|
|
92
|
+
return {
|
|
93
|
+
data,
|
|
94
|
+
isMissingData: this._isMissingData,
|
|
95
|
+
seenRecords: this._seenRecords,
|
|
96
|
+
selector: this._selector,
|
|
97
|
+
};
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
_traverse(
|
|
101
|
+
node: ReaderNode,
|
|
102
|
+
dataID: DataID,
|
|
103
|
+
prevData: ?SelectorData,
|
|
104
|
+
): ?SelectorData {
|
|
105
|
+
const record = this._recordSource.get(dataID);
|
|
106
|
+
this._seenRecords[dataID] = record;
|
|
107
|
+
if (record == null) {
|
|
108
|
+
if (record === undefined) {
|
|
109
|
+
this._isMissingData = true;
|
|
110
|
+
}
|
|
111
|
+
return record;
|
|
112
|
+
}
|
|
113
|
+
const data = prevData || {};
|
|
114
|
+
this._traverseSelections(node.selections, record, data);
|
|
115
|
+
return data;
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
_getVariableValue(name: string): mixed {
|
|
119
|
+
invariant(
|
|
120
|
+
this._variables.hasOwnProperty(name),
|
|
121
|
+
'RelayReader(): Undefined variable `%s`.',
|
|
122
|
+
name,
|
|
123
|
+
);
|
|
124
|
+
return this._variables[name];
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
_traverseSelections(
|
|
128
|
+
selections: $ReadOnlyArray<ReaderSelection>,
|
|
129
|
+
record: Record,
|
|
130
|
+
data: SelectorData,
|
|
131
|
+
): void {
|
|
132
|
+
for (let i = 0; i < selections.length; i++) {
|
|
133
|
+
const selection = selections[i];
|
|
134
|
+
switch (selection.kind) {
|
|
135
|
+
case SCALAR_FIELD:
|
|
136
|
+
this._readScalar(selection, record, data);
|
|
137
|
+
break;
|
|
138
|
+
case LINKED_FIELD:
|
|
139
|
+
if (selection.plural) {
|
|
140
|
+
this._readPluralLink(selection, record, data);
|
|
141
|
+
} else {
|
|
142
|
+
this._readLink(selection, record, data);
|
|
143
|
+
}
|
|
144
|
+
break;
|
|
145
|
+
case CONDITION:
|
|
146
|
+
const conditionValue = this._getVariableValue(selection.condition);
|
|
147
|
+
if (conditionValue === selection.passingValue) {
|
|
148
|
+
this._traverseSelections(selection.selections, record, data);
|
|
149
|
+
}
|
|
150
|
+
break;
|
|
151
|
+
case INLINE_FRAGMENT:
|
|
152
|
+
const typeName = RelayModernRecord.getType(record);
|
|
153
|
+
if (typeName != null && typeName === selection.type) {
|
|
154
|
+
this._traverseSelections(selection.selections, record, data);
|
|
155
|
+
}
|
|
156
|
+
break;
|
|
157
|
+
case FRAGMENT_SPREAD:
|
|
158
|
+
this._createFragmentPointer(selection, record, data);
|
|
159
|
+
break;
|
|
160
|
+
case MODULE_IMPORT:
|
|
161
|
+
this._readModuleImport(selection, record, data);
|
|
162
|
+
break;
|
|
163
|
+
case INLINE_DATA_FRAGMENT_SPREAD:
|
|
164
|
+
this._createInlineDataFragmentPointer(selection, record, data);
|
|
165
|
+
break;
|
|
166
|
+
case DEFER:
|
|
167
|
+
case CLIENT_EXTENSION:
|
|
168
|
+
const isMissingData = this._isMissingData;
|
|
169
|
+
this._traverseSelections(selection.selections, record, data);
|
|
170
|
+
this._isMissingData = isMissingData;
|
|
171
|
+
break;
|
|
172
|
+
case STREAM:
|
|
173
|
+
this._traverseSelections(selection.selections, record, data);
|
|
174
|
+
break;
|
|
175
|
+
default:
|
|
176
|
+
(selection: empty);
|
|
177
|
+
invariant(
|
|
178
|
+
false,
|
|
179
|
+
'RelayReader(): Unexpected ast kind `%s`.',
|
|
180
|
+
selection.kind,
|
|
181
|
+
);
|
|
182
|
+
}
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
_readScalar(
|
|
187
|
+
field: ReaderScalarField,
|
|
188
|
+
record: Record,
|
|
189
|
+
data: SelectorData,
|
|
190
|
+
): void {
|
|
191
|
+
const applicationName = field.alias ?? field.name;
|
|
192
|
+
const storageKey = getStorageKey(field, this._variables);
|
|
193
|
+
const value = RelayModernRecord.getValue(record, storageKey);
|
|
194
|
+
if (value === undefined) {
|
|
195
|
+
this._isMissingData = true;
|
|
196
|
+
}
|
|
197
|
+
data[applicationName] = value;
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
_readLink(
|
|
201
|
+
field: ReaderLinkedField,
|
|
202
|
+
record: Record,
|
|
203
|
+
data: SelectorData,
|
|
204
|
+
): void {
|
|
205
|
+
const applicationName = field.alias ?? field.name;
|
|
206
|
+
const storageKey = getStorageKey(field, this._variables);
|
|
207
|
+
const linkedID = RelayModernRecord.getLinkedRecordID(record, storageKey);
|
|
208
|
+
if (linkedID == null) {
|
|
209
|
+
data[applicationName] = linkedID;
|
|
210
|
+
if (linkedID === undefined) {
|
|
211
|
+
this._isMissingData = true;
|
|
212
|
+
}
|
|
213
|
+
return;
|
|
214
|
+
}
|
|
215
|
+
|
|
216
|
+
const prevData = data[applicationName];
|
|
217
|
+
invariant(
|
|
218
|
+
prevData == null || typeof prevData === 'object',
|
|
219
|
+
'RelayReader(): Expected data for field `%s` on record `%s` ' +
|
|
220
|
+
'to be an object, got `%s`.',
|
|
221
|
+
applicationName,
|
|
222
|
+
RelayModernRecord.getDataID(record),
|
|
223
|
+
prevData,
|
|
224
|
+
);
|
|
225
|
+
/* $FlowFixMe(>=0.98.0 site=www,mobile,react_native_fb,oss) This comment
|
|
226
|
+
* suppresses an error found when Flow v0.98 was deployed. To see the error
|
|
227
|
+
* delete this comment and run Flow. */
|
|
228
|
+
data[applicationName] = this._traverse(field, linkedID, prevData);
|
|
229
|
+
}
|
|
230
|
+
|
|
231
|
+
_readPluralLink(
|
|
232
|
+
field: ReaderLinkedField,
|
|
233
|
+
record: Record,
|
|
234
|
+
data: SelectorData,
|
|
235
|
+
): void {
|
|
236
|
+
const applicationName = field.alias ?? field.name;
|
|
237
|
+
const storageKey = getStorageKey(field, this._variables);
|
|
238
|
+
const linkedIDs = RelayModernRecord.getLinkedRecordIDs(record, storageKey);
|
|
239
|
+
|
|
240
|
+
if (linkedIDs == null) {
|
|
241
|
+
data[applicationName] = linkedIDs;
|
|
242
|
+
if (linkedIDs === undefined) {
|
|
243
|
+
this._isMissingData = true;
|
|
244
|
+
}
|
|
245
|
+
return;
|
|
246
|
+
}
|
|
247
|
+
|
|
248
|
+
const prevData = data[applicationName];
|
|
249
|
+
invariant(
|
|
250
|
+
prevData == null || Array.isArray(prevData),
|
|
251
|
+
'RelayReader(): Expected data for field `%s` on record `%s` ' +
|
|
252
|
+
'to be an array, got `%s`.',
|
|
253
|
+
applicationName,
|
|
254
|
+
RelayModernRecord.getDataID(record),
|
|
255
|
+
prevData,
|
|
256
|
+
);
|
|
257
|
+
const linkedArray = prevData || [];
|
|
258
|
+
linkedIDs.forEach((linkedID, nextIndex) => {
|
|
259
|
+
if (linkedID == null) {
|
|
260
|
+
if (linkedID === undefined) {
|
|
261
|
+
this._isMissingData = true;
|
|
262
|
+
}
|
|
263
|
+
/* $FlowFixMe(>=0.98.0 site=www,mobile,react_native_fb,oss) This comment
|
|
264
|
+
* suppresses an error found when Flow v0.98 was deployed. To see the
|
|
265
|
+
* error delete this comment and run Flow. */
|
|
266
|
+
linkedArray[nextIndex] = linkedID;
|
|
267
|
+
return;
|
|
268
|
+
}
|
|
269
|
+
const prevItem = linkedArray[nextIndex];
|
|
270
|
+
invariant(
|
|
271
|
+
prevItem == null || typeof prevItem === 'object',
|
|
272
|
+
'RelayReader(): Expected data for field `%s` on record `%s` ' +
|
|
273
|
+
'to be an object, got `%s`.',
|
|
274
|
+
applicationName,
|
|
275
|
+
RelayModernRecord.getDataID(record),
|
|
276
|
+
prevItem,
|
|
277
|
+
);
|
|
278
|
+
/* $FlowFixMe(>=0.98.0 site=www,mobile,react_native_fb,oss) This comment
|
|
279
|
+
* suppresses an error found when Flow v0.98 was deployed. To see the
|
|
280
|
+
* error delete this comment and run Flow. */
|
|
281
|
+
linkedArray[nextIndex] = this._traverse(field, linkedID, prevItem);
|
|
282
|
+
});
|
|
283
|
+
data[applicationName] = linkedArray;
|
|
284
|
+
}
|
|
285
|
+
|
|
286
|
+
/**
|
|
287
|
+
* Reads a ReaderModuleImport, which was generated from using the @module
|
|
288
|
+
* directive.
|
|
289
|
+
*/
|
|
290
|
+
_readModuleImport(
|
|
291
|
+
moduleImport: ReaderModuleImport,
|
|
292
|
+
record: Record,
|
|
293
|
+
data: SelectorData,
|
|
294
|
+
): void {
|
|
295
|
+
// Determine the component module from the store: if the field is missing
|
|
296
|
+
// it means we don't know what component to render the match with.
|
|
297
|
+
const componentKey = getModuleComponentKey(moduleImport.documentName);
|
|
298
|
+
const component = RelayModernRecord.getValue(record, componentKey);
|
|
299
|
+
if (component == null) {
|
|
300
|
+
if (component === undefined) {
|
|
301
|
+
this._isMissingData = true;
|
|
302
|
+
}
|
|
303
|
+
return;
|
|
304
|
+
}
|
|
305
|
+
|
|
306
|
+
// Otherwise, read the fragment and module associated to the concrete
|
|
307
|
+
// type, and put that data with the result:
|
|
308
|
+
// - For the matched fragment, create the relevant fragment pointer and add
|
|
309
|
+
// the expected fragmentPropName
|
|
310
|
+
// - For the matched module, create a reference to the module
|
|
311
|
+
this._createFragmentPointer(
|
|
312
|
+
{
|
|
313
|
+
kind: 'FragmentSpread',
|
|
314
|
+
name: moduleImport.fragmentName,
|
|
315
|
+
args: null,
|
|
316
|
+
},
|
|
317
|
+
record,
|
|
318
|
+
data,
|
|
319
|
+
);
|
|
320
|
+
data[FRAGMENT_PROP_NAME_KEY] = moduleImport.fragmentPropName;
|
|
321
|
+
data[MODULE_COMPONENT_KEY] = component;
|
|
322
|
+
}
|
|
323
|
+
|
|
324
|
+
_createFragmentPointer(
|
|
325
|
+
fragmentSpread: ReaderFragmentSpread,
|
|
326
|
+
record: Record,
|
|
327
|
+
data: SelectorData,
|
|
328
|
+
): void {
|
|
329
|
+
let fragmentPointers = data[FRAGMENTS_KEY];
|
|
330
|
+
if (fragmentPointers == null) {
|
|
331
|
+
fragmentPointers = data[FRAGMENTS_KEY] = {};
|
|
332
|
+
}
|
|
333
|
+
invariant(
|
|
334
|
+
typeof fragmentPointers === 'object' && fragmentPointers != null,
|
|
335
|
+
'RelayReader: Expected fragment spread data to be an object, got `%s`.',
|
|
336
|
+
fragmentPointers,
|
|
337
|
+
);
|
|
338
|
+
if (data[ID_KEY] == null) {
|
|
339
|
+
data[ID_KEY] = RelayModernRecord.getDataID(record);
|
|
340
|
+
}
|
|
341
|
+
// $FlowFixMe - writing into read-only field
|
|
342
|
+
fragmentPointers[fragmentSpread.name] = fragmentSpread.args
|
|
343
|
+
? getArgumentValues(fragmentSpread.args, this._variables)
|
|
344
|
+
: {};
|
|
345
|
+
data[FRAGMENT_OWNER_KEY] = this._owner;
|
|
346
|
+
}
|
|
347
|
+
|
|
348
|
+
_createInlineDataFragmentPointer(
|
|
349
|
+
inlineDataFragmentSpread: ReaderInlineDataFragmentSpread,
|
|
350
|
+
record: Record,
|
|
351
|
+
data: SelectorData,
|
|
352
|
+
): void {
|
|
353
|
+
let fragmentPointers = data[FRAGMENTS_KEY];
|
|
354
|
+
if (fragmentPointers == null) {
|
|
355
|
+
fragmentPointers = data[FRAGMENTS_KEY] = {};
|
|
356
|
+
}
|
|
357
|
+
invariant(
|
|
358
|
+
typeof fragmentPointers === 'object' && fragmentPointers != null,
|
|
359
|
+
'RelayReader: Expected fragment spread data to be an object, got `%s`.',
|
|
360
|
+
fragmentPointers,
|
|
361
|
+
);
|
|
362
|
+
if (data[ID_KEY] == null) {
|
|
363
|
+
data[ID_KEY] = RelayModernRecord.getDataID(record);
|
|
364
|
+
}
|
|
365
|
+
const inlineData = {};
|
|
366
|
+
this._traverseSelections(
|
|
367
|
+
inlineDataFragmentSpread.selections,
|
|
368
|
+
record,
|
|
369
|
+
inlineData,
|
|
370
|
+
);
|
|
371
|
+
// $FlowFixMe - writing into read-only field
|
|
372
|
+
fragmentPointers[inlineDataFragmentSpread.name] = inlineData;
|
|
373
|
+
}
|
|
374
|
+
}
|
|
375
|
+
|
|
376
|
+
module.exports = {read};
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright (c) Facebook, Inc. and its affiliates.
|
|
3
|
+
*
|
|
4
|
+
* This source code is licensed under the MIT license found in the
|
|
5
|
+
* LICENSE file in the root directory of this source tree.
|
|
6
|
+
*
|
|
7
|
+
* @flow strict-local
|
|
8
|
+
* @format
|
|
9
|
+
*/
|
|
10
|
+
|
|
11
|
+
// flowlint ambiguous-object-type:error
|
|
12
|
+
|
|
13
|
+
'use strict';
|
|
14
|
+
|
|
15
|
+
const RelayRecordSourceMapImpl = require('./RelayRecordSourceMapImpl');
|
|
16
|
+
|
|
17
|
+
import type {MutableRecordSource, RecordMap} from './RelayStoreTypes';
|
|
18
|
+
|
|
19
|
+
class RelayRecordSource {
|
|
20
|
+
constructor(records?: RecordMap): MutableRecordSource {
|
|
21
|
+
return RelayRecordSource.create(records);
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
static create(records?: RecordMap): MutableRecordSource {
|
|
25
|
+
return new RelayRecordSourceMapImpl(records);
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
module.exports = RelayRecordSource;
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright (c) Facebook, Inc. and its affiliates.
|
|
3
|
+
*
|
|
4
|
+
* This source code is licensed under the MIT license found in the
|
|
5
|
+
* LICENSE file in the root directory of this source tree.
|
|
6
|
+
*
|
|
7
|
+
* @flow strict-local
|
|
8
|
+
* @format
|
|
9
|
+
*/
|
|
10
|
+
|
|
11
|
+
// flowlint ambiguous-object-type:error
|
|
12
|
+
|
|
13
|
+
'use strict';
|
|
14
|
+
|
|
15
|
+
const RelayRecordState = require('./RelayRecordState');
|
|
16
|
+
|
|
17
|
+
import type {DataID} from '../util/RelayRuntimeTypes';
|
|
18
|
+
import type {RecordState} from './RelayRecordState';
|
|
19
|
+
import type {MutableRecordSource, Record, RecordMap} from './RelayStoreTypes';
|
|
20
|
+
|
|
21
|
+
const {EXISTENT, NONEXISTENT, UNKNOWN} = RelayRecordState;
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* An implementation of the `MutableRecordSource` interface (defined in
|
|
25
|
+
* `RelayStoreTypes`) that holds all records in memory (JS Map).
|
|
26
|
+
*/
|
|
27
|
+
class RelayMapRecordSourceMapImpl implements MutableRecordSource {
|
|
28
|
+
_records: Map<DataID, ?Record>;
|
|
29
|
+
|
|
30
|
+
constructor(records?: RecordMap) {
|
|
31
|
+
this._records = new Map();
|
|
32
|
+
if (records != null) {
|
|
33
|
+
Object.keys(records).forEach(key => {
|
|
34
|
+
this._records.set(key, records[key]);
|
|
35
|
+
});
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
clear(): void {
|
|
40
|
+
this._records = new Map();
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
delete(dataID: DataID): void {
|
|
44
|
+
this._records.set(dataID, null);
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
get(dataID: DataID): ?Record {
|
|
48
|
+
return this._records.get(dataID);
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
getRecordIDs(): Array<DataID> {
|
|
52
|
+
return Array.from(this._records.keys());
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
getStatus(dataID: DataID): RecordState {
|
|
56
|
+
if (!this._records.has(dataID)) {
|
|
57
|
+
return UNKNOWN;
|
|
58
|
+
}
|
|
59
|
+
return this._records.get(dataID) == null ? NONEXISTENT : EXISTENT;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
has(dataID: DataID): boolean {
|
|
63
|
+
return this._records.has(dataID);
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
remove(dataID: DataID): void {
|
|
67
|
+
this._records.delete(dataID);
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
set(dataID: DataID, record: Record): void {
|
|
71
|
+
this._records.set(dataID, record);
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
size(): number {
|
|
75
|
+
return this._records.size;
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
toJSON(): {[DataID]: ?Record, ...} {
|
|
79
|
+
const obj = {};
|
|
80
|
+
for (const [key, value] of this._records) {
|
|
81
|
+
obj[key] = value;
|
|
82
|
+
}
|
|
83
|
+
return obj;
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
module.exports = RelayMapRecordSourceMapImpl;
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright (c) Facebook, Inc. and its affiliates.
|
|
3
|
+
*
|
|
4
|
+
* This source code is licensed under the MIT license found in the
|
|
5
|
+
* LICENSE file in the root directory of this source tree.
|
|
6
|
+
*
|
|
7
|
+
* @flow strict
|
|
8
|
+
* @format
|
|
9
|
+
*/
|
|
10
|
+
|
|
11
|
+
// flowlint ambiguous-object-type:error
|
|
12
|
+
|
|
13
|
+
'use strict';
|
|
14
|
+
|
|
15
|
+
export type RecordState = $Keys<typeof RelayRecordState>;
|
|
16
|
+
|
|
17
|
+
const RelayRecordState = {
|
|
18
|
+
/**
|
|
19
|
+
* Record exists (either fetched from the server or produced by a local,
|
|
20
|
+
* optimistic update).
|
|
21
|
+
*/
|
|
22
|
+
EXISTENT: 'EXISTENT',
|
|
23
|
+
|
|
24
|
+
/**
|
|
25
|
+
* Record is known not to exist (either as the result of a mutation, or
|
|
26
|
+
* because the server returned `null` when queried for the record).
|
|
27
|
+
*/
|
|
28
|
+
NONEXISTENT: 'NONEXISTENT',
|
|
29
|
+
|
|
30
|
+
/**
|
|
31
|
+
* Record State is unknown because it has not yet been fetched from the
|
|
32
|
+
* server.
|
|
33
|
+
*/
|
|
34
|
+
UNKNOWN: 'UNKNOWN',
|
|
35
|
+
};
|
|
36
|
+
|
|
37
|
+
module.exports = RelayRecordState;
|