relay-runtime 0.0.0-main-dbe0cbb6 → 0.0.0-main-a70cd064
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/index.js +1 -1
- package/lib/store/RelayReader.js +53 -10
- package/lib/store/RelayStoreUtils.js +1 -0
- package/lib/store/ResolverCache.js +10 -2
- package/package.json +1 -1
- package/relay-runtime.js +2 -2
- package/relay-runtime.min.js +2 -2
- package/store/RelayReader.js.flow +75 -28
- package/store/RelayStoreTypes.js.flow +3 -2
- package/store/RelayStoreUtils.js.flow +1 -0
- package/store/ResolverCache.js.flow +18 -5
|
@@ -109,6 +109,7 @@ class RelayReader {
|
|
|
109
109
|
_selector: SingularReaderSelector;
|
|
110
110
|
_variables: Variables;
|
|
111
111
|
_resolverCache: ResolverCache;
|
|
112
|
+
_fragmentName: string;
|
|
112
113
|
|
|
113
114
|
constructor(
|
|
114
115
|
recordSource: RecordSource,
|
|
@@ -130,6 +131,7 @@ class RelayReader {
|
|
|
130
131
|
this._selector = selector;
|
|
131
132
|
this._variables = selector.variables;
|
|
132
133
|
this._resolverCache = resolverCache;
|
|
134
|
+
this._fragmentName = selector.node.name;
|
|
133
135
|
}
|
|
134
136
|
|
|
135
137
|
read(): Snapshot {
|
|
@@ -267,7 +269,7 @@ class RelayReader {
|
|
|
267
269
|
// encounter is likely to be the root cause of the error.
|
|
268
270
|
return;
|
|
269
271
|
}
|
|
270
|
-
const owner = this.
|
|
272
|
+
const owner = this._fragmentName;
|
|
271
273
|
|
|
272
274
|
switch (action) {
|
|
273
275
|
case 'THROW':
|
|
@@ -275,9 +277,19 @@ class RelayReader {
|
|
|
275
277
|
return;
|
|
276
278
|
case 'LOG':
|
|
277
279
|
if (this._missingRequiredFields == null) {
|
|
278
|
-
this._missingRequiredFields = {
|
|
280
|
+
this._missingRequiredFields = {
|
|
281
|
+
action,
|
|
282
|
+
fields: [{path: fieldPath, owner}],
|
|
283
|
+
};
|
|
284
|
+
} else {
|
|
285
|
+
this._missingRequiredFields = {
|
|
286
|
+
action,
|
|
287
|
+
fields: [
|
|
288
|
+
...this._missingRequiredFields.fields,
|
|
289
|
+
{path: fieldPath, owner},
|
|
290
|
+
],
|
|
291
|
+
};
|
|
279
292
|
}
|
|
280
|
-
this._missingRequiredFields.fields.push({path: fieldPath, owner});
|
|
281
293
|
return;
|
|
282
294
|
default:
|
|
283
295
|
(action: empty);
|
|
@@ -511,6 +523,8 @@ class RelayReader {
|
|
|
511
523
|
// inputs have changed since a previous evaluation:
|
|
512
524
|
let fragmentValue;
|
|
513
525
|
let fragmentReaderSelector;
|
|
526
|
+
let fragmentMissingRequiredFields: ?MissingRequiredFields;
|
|
527
|
+
let previousMissingRequriedFields: ?MissingRequiredFields;
|
|
514
528
|
const fragmentSeenRecordIDs = new Set();
|
|
515
529
|
|
|
516
530
|
const getDataForResolverFragment = singularReaderSelector => {
|
|
@@ -525,11 +539,14 @@ class RelayReader {
|
|
|
525
539
|
try {
|
|
526
540
|
this._seenRecords = fragmentSeenRecordIDs;
|
|
527
541
|
const resolverFragmentData = {};
|
|
542
|
+
previousMissingRequriedFields = this._missingRequiredFields;
|
|
543
|
+
this._missingRequiredFields = null;
|
|
528
544
|
this._createInlineDataOrResolverFragmentPointer(
|
|
529
545
|
singularReaderSelector.node,
|
|
530
546
|
record,
|
|
531
547
|
resolverFragmentData,
|
|
532
548
|
);
|
|
549
|
+
fragmentMissingRequiredFields = this._missingRequiredFields;
|
|
533
550
|
fragmentValue = resolverFragmentData[FRAGMENTS_KEY]?.[fragment.name];
|
|
534
551
|
invariant(
|
|
535
552
|
typeof fragmentValue === 'object' && fragmentValue !== null,
|
|
@@ -538,36 +555,43 @@ class RelayReader {
|
|
|
538
555
|
return fragmentValue;
|
|
539
556
|
} finally {
|
|
540
557
|
this._seenRecords = existingSeenRecords;
|
|
558
|
+
this._missingRequiredFields = previousMissingRequriedFields;
|
|
541
559
|
}
|
|
542
560
|
};
|
|
543
561
|
const resolverContext = {getDataForResolverFragment};
|
|
544
562
|
|
|
545
|
-
const [result, seenRecord] =
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
return withResolverContext(resolverContext, () => {
|
|
558
|
-
// $FlowFixMe[prop-missing] - resolver module's type signature is a lie
|
|
559
|
-
const resolverResult = resolverModule(key);
|
|
560
|
-
return {
|
|
561
|
-
resolverResult,
|
|
562
|
-
fragmentValue,
|
|
563
|
-
resolverID,
|
|
564
|
-
seenRecordIDs: fragmentSeenRecordIDs,
|
|
565
|
-
readerSelector: fragmentReaderSelector,
|
|
563
|
+
const [result, seenRecord, missingRequiredFields] =
|
|
564
|
+
this._resolverCache.readFromCacheOrEvaluate(
|
|
565
|
+
record,
|
|
566
|
+
field,
|
|
567
|
+
this._variables,
|
|
568
|
+
() => {
|
|
569
|
+
const key = {
|
|
570
|
+
__id: RelayModernRecord.getDataID(record),
|
|
571
|
+
__fragmentOwner: this._owner,
|
|
572
|
+
__fragments: {
|
|
573
|
+
[fragment.name]: {}, // Arguments to this fragment; not yet supported.
|
|
574
|
+
},
|
|
566
575
|
};
|
|
567
|
-
|
|
568
|
-
|
|
569
|
-
|
|
570
|
-
|
|
576
|
+
return withResolverContext(resolverContext, () => {
|
|
577
|
+
// $FlowFixMe[prop-missing] - resolver module's type signature is a lie
|
|
578
|
+
const resolverResult = resolverModule(key);
|
|
579
|
+
return {
|
|
580
|
+
resolverResult,
|
|
581
|
+
fragmentValue,
|
|
582
|
+
resolverID,
|
|
583
|
+
seenRecordIDs: fragmentSeenRecordIDs,
|
|
584
|
+
readerSelector: fragmentReaderSelector,
|
|
585
|
+
missingRequiredFields: fragmentMissingRequiredFields,
|
|
586
|
+
};
|
|
587
|
+
});
|
|
588
|
+
},
|
|
589
|
+
getDataForResolverFragment,
|
|
590
|
+
);
|
|
591
|
+
|
|
592
|
+
if (missingRequiredFields != null) {
|
|
593
|
+
this._addMissingRequiredFields(missingRequiredFields);
|
|
594
|
+
}
|
|
571
595
|
if (seenRecord != null) {
|
|
572
596
|
this._seenRecords.add(seenRecord);
|
|
573
597
|
}
|
|
@@ -896,14 +920,37 @@ class RelayReader {
|
|
|
896
920
|
data[ID_KEY] = RelayModernRecord.getDataID(record);
|
|
897
921
|
}
|
|
898
922
|
const inlineData = {};
|
|
923
|
+
const parentFragmentName = this._fragmentName;
|
|
924
|
+
this._fragmentName = fragmentSpreadOrFragment.name;
|
|
899
925
|
this._traverseSelections(
|
|
900
926
|
fragmentSpreadOrFragment.selections,
|
|
901
927
|
record,
|
|
902
928
|
inlineData,
|
|
903
929
|
);
|
|
930
|
+
this._fragmentName = parentFragmentName;
|
|
904
931
|
// $FlowFixMe[cannot-write] - writing into read-only field
|
|
905
932
|
fragmentPointers[fragmentSpreadOrFragment.name] = inlineData;
|
|
906
933
|
}
|
|
934
|
+
|
|
935
|
+
_addMissingRequiredFields(additional: MissingRequiredFields) {
|
|
936
|
+
if (this._missingRequiredFields == null) {
|
|
937
|
+
this._missingRequiredFields = additional;
|
|
938
|
+
return;
|
|
939
|
+
}
|
|
940
|
+
|
|
941
|
+
if (this._missingRequiredFields.action === 'THROW') {
|
|
942
|
+
return;
|
|
943
|
+
}
|
|
944
|
+
if (additional.action === 'THROW') {
|
|
945
|
+
this._missingRequiredFields = additional;
|
|
946
|
+
return;
|
|
947
|
+
}
|
|
948
|
+
|
|
949
|
+
this._missingRequiredFields = {
|
|
950
|
+
action: 'LOG',
|
|
951
|
+
fields: [...this._missingRequiredFields.fields, ...additional.fields],
|
|
952
|
+
};
|
|
953
|
+
}
|
|
907
954
|
}
|
|
908
955
|
|
|
909
956
|
module.exports = {read};
|
|
@@ -117,9 +117,10 @@ type MissingRequiredField = {|
|
|
|
117
117
|
owner: string,
|
|
118
118
|
|};
|
|
119
119
|
|
|
120
|
-
export type MissingRequiredFields =
|
|
120
|
+
export type MissingRequiredFields = $ReadOnly<
|
|
121
121
|
| {|action: 'THROW', field: MissingRequiredField|}
|
|
122
|
-
| {|action: 'LOG', fields: Array<MissingRequiredField>|}
|
|
122
|
+
| {|action: 'LOG', fields: Array<MissingRequiredField>|},
|
|
123
|
+
>;
|
|
123
124
|
|
|
124
125
|
export type ClientEdgeTraversalInfo = {|
|
|
125
126
|
+readerClientEdge: ReaderClientEdge,
|
|
@@ -219,6 +219,7 @@ const RelayStoreUtils = {
|
|
|
219
219
|
RELAY_RESOLVER_INVALIDATION_KEY: '__resolverValueMayBeInvalid',
|
|
220
220
|
RELAY_RESOLVER_INPUTS_KEY: '__resolverInputValues',
|
|
221
221
|
RELAY_RESOLVER_READER_SELECTOR_KEY: '__resolverReaderSelector',
|
|
222
|
+
RELAY_RESOLVER_MISSING_REQUIRED_FIELDS_KEY: '__resolverMissingRequiredFields',
|
|
222
223
|
|
|
223
224
|
formatStorageKey,
|
|
224
225
|
getArgumentValue,
|
|
@@ -15,6 +15,7 @@
|
|
|
15
15
|
import type {ReaderRelayResolver} from '../util/ReaderNode';
|
|
16
16
|
import type {DataID, Variables} from '../util/RelayRuntimeTypes';
|
|
17
17
|
import type {
|
|
18
|
+
MissingRequiredFields,
|
|
18
19
|
MutableRecordSource,
|
|
19
20
|
Record,
|
|
20
21
|
SingularReaderSelector,
|
|
@@ -26,6 +27,7 @@ const RelayModernRecord = require('./RelayModernRecord');
|
|
|
26
27
|
const {
|
|
27
28
|
RELAY_RESOLVER_INPUTS_KEY,
|
|
28
29
|
RELAY_RESOLVER_INVALIDATION_KEY,
|
|
30
|
+
RELAY_RESOLVER_MISSING_REQUIRED_FIELDS_KEY,
|
|
29
31
|
RELAY_RESOLVER_READER_SELECTOR_KEY,
|
|
30
32
|
RELAY_RESOLVER_VALUE_KEY,
|
|
31
33
|
getStorageKey,
|
|
@@ -40,6 +42,7 @@ type EvaluationResult<T> = {|
|
|
|
40
42
|
resolverID: ResolverID,
|
|
41
43
|
seenRecordIDs: Set<DataID>,
|
|
42
44
|
readerSelector: SingularReaderSelector,
|
|
45
|
+
missingRequiredFields: ?MissingRequiredFields,
|
|
43
46
|
|};
|
|
44
47
|
|
|
45
48
|
export interface ResolverCache {
|
|
@@ -49,7 +52,7 @@ export interface ResolverCache {
|
|
|
49
52
|
variables: Variables,
|
|
50
53
|
evaluate: () => EvaluationResult<T>,
|
|
51
54
|
getDataForResolverFragment: (SingularReaderSelector) => mixed,
|
|
52
|
-
): [T /* Answer */, ?DataID /* Seen record
|
|
55
|
+
): [T /* Answer */, ?DataID /* Seen record */, ?MissingRequiredFields];
|
|
53
56
|
invalidateDataIDs(
|
|
54
57
|
updatedDataIDs: Set<DataID>, // Mutated in place
|
|
55
58
|
): void;
|
|
@@ -65,8 +68,9 @@ class NoopResolverCache implements ResolverCache {
|
|
|
65
68
|
variables: Variables,
|
|
66
69
|
evaluate: () => EvaluationResult<T>,
|
|
67
70
|
getDataForResolverFragment: SingularReaderSelector => mixed,
|
|
68
|
-
): [T /* Answer */, ?DataID /* Seen record
|
|
69
|
-
|
|
71
|
+
): [T /* Answer */, ?DataID /* Seen record */, ?MissingRequiredFields] {
|
|
72
|
+
const {resolverResult, missingRequiredFields} = evaluate();
|
|
73
|
+
return [resolverResult, undefined, missingRequiredFields];
|
|
70
74
|
}
|
|
71
75
|
invalidateDataIDs(updatedDataIDs: Set<DataID>): void {}
|
|
72
76
|
}
|
|
@@ -102,7 +106,7 @@ class RecordResolverCache implements ResolverCache {
|
|
|
102
106
|
variables: Variables,
|
|
103
107
|
evaluate: () => EvaluationResult<T>,
|
|
104
108
|
getDataForResolverFragment: SingularReaderSelector => mixed,
|
|
105
|
-
): [T /* Answer */, ?DataID /* Seen record
|
|
109
|
+
): [T /* Answer */, ?DataID /* Seen record */, ?MissingRequiredFields] {
|
|
106
110
|
const recordSource = this._getRecordSource();
|
|
107
111
|
const recordID = RelayModernRecord.getDataID(record);
|
|
108
112
|
|
|
@@ -133,6 +137,11 @@ class RecordResolverCache implements ResolverCache {
|
|
|
133
137
|
RELAY_RESOLVER_READER_SELECTOR_KEY,
|
|
134
138
|
evaluationResult.readerSelector,
|
|
135
139
|
);
|
|
140
|
+
RelayModernRecord.setValue(
|
|
141
|
+
linkedRecord,
|
|
142
|
+
RELAY_RESOLVER_MISSING_REQUIRED_FIELDS_KEY,
|
|
143
|
+
evaluationResult.missingRequiredFields,
|
|
144
|
+
);
|
|
136
145
|
recordSource.set(linkedID, linkedRecord);
|
|
137
146
|
|
|
138
147
|
// Link the resolver value record to the resolver field of the record being read:
|
|
@@ -155,7 +164,11 @@ class RecordResolverCache implements ResolverCache {
|
|
|
155
164
|
|
|
156
165
|
// $FlowFixMe[incompatible-type] - will always be empty
|
|
157
166
|
const answer: T = linkedRecord[RELAY_RESOLVER_VALUE_KEY];
|
|
158
|
-
|
|
167
|
+
|
|
168
|
+
const missingRequiredFields: ?MissingRequiredFields =
|
|
169
|
+
// $FlowFixMe[incompatible-type] - casting mixed
|
|
170
|
+
linkedRecord[RELAY_RESOLVER_MISSING_REQUIRED_FIELDS_KEY];
|
|
171
|
+
return [answer, linkedID, missingRequiredFields];
|
|
159
172
|
}
|
|
160
173
|
|
|
161
174
|
invalidateDataIDs(
|