relay-runtime 0.0.0-main-c3ad9027 → 0.0.0-main-74926b6f
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/RelayModernSelector.js +7 -2
- package/lib/store/RelayReader.js +118 -24
- package/lib/store/RelayStoreSubscriptions.js +2 -0
- package/lib/store/RelayStoreUtils.js +1 -0
- package/lib/util/RelayConcreteNode.js +1 -0
- package/lib/util/RelayFeatureFlags.js +2 -0
- package/package.json +1 -1
- package/relay-runtime.js +2 -2
- package/relay-runtime.min.js +2 -2
- package/store/RelayModernSelector.js.flow +13 -2
- package/store/RelayReader.js.flow +139 -14
- package/store/RelayStoreSubscriptions.js.flow +2 -0
- package/store/RelayStoreTypes.js.flow +16 -1
- package/store/RelayStoreUtils.js.flow +1 -0
- package/util/ReaderNode.js.flow +8 -0
- package/util/RelayConcreteNode.js.flow +1 -0
- package/util/RelayFeatureFlags.js.flow +5 -1
|
@@ -16,6 +16,7 @@ import type {NormalizationSelectableNode} from '../util/NormalizationNode';
|
|
|
16
16
|
import type {ReaderFragment} from '../util/ReaderNode';
|
|
17
17
|
import type {DataID, Variables} from '../util/RelayRuntimeTypes';
|
|
18
18
|
import type {
|
|
19
|
+
ClientEdgeTraversalPath,
|
|
19
20
|
NormalizationSelector,
|
|
20
21
|
PluralReaderSelector,
|
|
21
22
|
ReaderSelector,
|
|
@@ -25,6 +26,7 @@ import type {
|
|
|
25
26
|
|
|
26
27
|
const {getFragmentVariables} = require('./RelayConcreteVariables');
|
|
27
28
|
const {
|
|
29
|
+
CLIENT_EDGE_TRAVERSAL_PATH,
|
|
28
30
|
FRAGMENT_OWNER_KEY,
|
|
29
31
|
FRAGMENTS_KEY,
|
|
30
32
|
ID_KEY,
|
|
@@ -79,6 +81,7 @@ function getSingularSelector(
|
|
|
79
81
|
const mixedOwner = item[FRAGMENT_OWNER_KEY];
|
|
80
82
|
const isWithinUnmatchedTypeRefinement =
|
|
81
83
|
item[IS_WITHIN_UNMATCHED_TYPE_REFINEMENT] === true;
|
|
84
|
+
const mixedClientEdgeTraversalPath = item[CLIENT_EDGE_TRAVERSAL_PATH];
|
|
82
85
|
if (
|
|
83
86
|
typeof dataID === 'string' &&
|
|
84
87
|
typeof fragments === 'object' &&
|
|
@@ -86,22 +89,28 @@ function getSingularSelector(
|
|
|
86
89
|
typeof fragments[fragment.name] === 'object' &&
|
|
87
90
|
fragments[fragment.name] !== null &&
|
|
88
91
|
typeof mixedOwner === 'object' &&
|
|
89
|
-
mixedOwner !== null
|
|
92
|
+
mixedOwner !== null &&
|
|
93
|
+
(mixedClientEdgeTraversalPath == null ||
|
|
94
|
+
Array.isArray(mixedClientEdgeTraversalPath))
|
|
90
95
|
) {
|
|
91
96
|
const owner: RequestDescriptor = (mixedOwner: $FlowFixMe);
|
|
92
|
-
const
|
|
97
|
+
const clientEdgeTraversalPath: ?ClientEdgeTraversalPath =
|
|
98
|
+
(mixedClientEdgeTraversalPath: $FlowFixMe);
|
|
93
99
|
|
|
100
|
+
const argumentVariables = fragments[fragment.name];
|
|
94
101
|
const fragmentVariables = getFragmentVariables(
|
|
95
102
|
fragment,
|
|
96
103
|
owner.variables,
|
|
97
104
|
argumentVariables,
|
|
98
105
|
);
|
|
106
|
+
|
|
99
107
|
return createReaderSelector(
|
|
100
108
|
fragment,
|
|
101
109
|
dataID,
|
|
102
110
|
fragmentVariables,
|
|
103
111
|
owner,
|
|
104
112
|
isWithinUnmatchedTypeRefinement,
|
|
113
|
+
clientEdgeTraversalPath,
|
|
105
114
|
);
|
|
106
115
|
}
|
|
107
116
|
|
|
@@ -418,11 +427,13 @@ function createReaderSelector(
|
|
|
418
427
|
variables: Variables,
|
|
419
428
|
request: RequestDescriptor,
|
|
420
429
|
isWithinUnmatchedTypeRefinement: boolean = false,
|
|
430
|
+
clientEdgeTraversalPath: ?ClientEdgeTraversalPath,
|
|
421
431
|
): SingularReaderSelector {
|
|
422
432
|
return {
|
|
423
433
|
kind: 'SingularReaderSelector',
|
|
424
434
|
dataID,
|
|
425
435
|
isWithinUnmatchedTypeRefinement,
|
|
436
|
+
clientEdgeTraversalPath: clientEdgeTraversalPath ?? null,
|
|
426
437
|
node: fragment,
|
|
427
438
|
variables,
|
|
428
439
|
owner: request,
|
|
@@ -14,6 +14,7 @@
|
|
|
14
14
|
|
|
15
15
|
import type {
|
|
16
16
|
ReaderActorChange,
|
|
17
|
+
ReaderClientEdge,
|
|
17
18
|
ReaderFlightField,
|
|
18
19
|
ReaderFragment,
|
|
19
20
|
ReaderFragmentSpread,
|
|
@@ -28,7 +29,9 @@ import type {
|
|
|
28
29
|
} from '../util/ReaderNode';
|
|
29
30
|
import type {DataID, Variables} from '../util/RelayRuntimeTypes';
|
|
30
31
|
import type {
|
|
32
|
+
ClientEdgeTraversalInfo,
|
|
31
33
|
DataIDSet,
|
|
34
|
+
MissingClientEdgeRequestInfo,
|
|
32
35
|
MissingRequiredFields,
|
|
33
36
|
Record,
|
|
34
37
|
RecordSource,
|
|
@@ -41,6 +44,7 @@ import type {ResolverCache} from './ResolverCache';
|
|
|
41
44
|
|
|
42
45
|
const {
|
|
43
46
|
ACTOR_CHANGE,
|
|
47
|
+
CLIENT_EDGE,
|
|
44
48
|
CLIENT_EXTENSION,
|
|
45
49
|
CONDITION,
|
|
46
50
|
DEFER,
|
|
@@ -60,6 +64,7 @@ const ClientID = require('./ClientID');
|
|
|
60
64
|
const RelayModernRecord = require('./RelayModernRecord');
|
|
61
65
|
const {getReactFlightClientResponse} = require('./RelayStoreReactFlightUtils');
|
|
62
66
|
const {
|
|
67
|
+
CLIENT_EDGE_TRAVERSAL_PATH,
|
|
63
68
|
FRAGMENT_OWNER_KEY,
|
|
64
69
|
FRAGMENT_PROP_NAME_KEY,
|
|
65
70
|
FRAGMENTS_KEY,
|
|
@@ -93,7 +98,9 @@ function read(
|
|
|
93
98
|
* @private
|
|
94
99
|
*/
|
|
95
100
|
class RelayReader {
|
|
101
|
+
_clientEdgeTraversalPath: Array<ClientEdgeTraversalInfo | null>;
|
|
96
102
|
_isMissingData: boolean;
|
|
103
|
+
_missingClientEdges: Array<MissingClientEdgeRequestInfo>;
|
|
97
104
|
_isWithinUnmatchedTypeRefinement: boolean;
|
|
98
105
|
_missingRequiredFields: ?MissingRequiredFields;
|
|
99
106
|
_owner: RequestDescriptor;
|
|
@@ -108,6 +115,12 @@ class RelayReader {
|
|
|
108
115
|
selector: SingularReaderSelector,
|
|
109
116
|
resolverCache: ResolverCache,
|
|
110
117
|
) {
|
|
118
|
+
this._clientEdgeTraversalPath =
|
|
119
|
+
RelayFeatureFlags.ENABLE_CLIENT_EDGES &&
|
|
120
|
+
selector.clientEdgeTraversalPath?.length
|
|
121
|
+
? [...selector.clientEdgeTraversalPath]
|
|
122
|
+
: [];
|
|
123
|
+
this._missingClientEdges = [];
|
|
111
124
|
this._isMissingData = false;
|
|
112
125
|
this._isWithinUnmatchedTypeRefinement = false;
|
|
113
126
|
this._missingRequiredFields = null;
|
|
@@ -182,12 +195,36 @@ class RelayReader {
|
|
|
182
195
|
return {
|
|
183
196
|
data,
|
|
184
197
|
isMissingData: this._isMissingData && isDataExpectedToBePresent,
|
|
198
|
+
missingClientEdges:
|
|
199
|
+
RelayFeatureFlags.ENABLE_CLIENT_EDGES && this._missingClientEdges.length
|
|
200
|
+
? this._missingClientEdges
|
|
201
|
+
: null,
|
|
185
202
|
seenRecords: this._seenRecords,
|
|
186
203
|
selector: this._selector,
|
|
187
204
|
missingRequiredFields: this._missingRequiredFields,
|
|
188
205
|
};
|
|
189
206
|
}
|
|
190
207
|
|
|
208
|
+
_markDataAsMissing(): void {
|
|
209
|
+
this._isMissingData = true;
|
|
210
|
+
if (
|
|
211
|
+
RelayFeatureFlags.ENABLE_CLIENT_EDGES &&
|
|
212
|
+
this._clientEdgeTraversalPath.length
|
|
213
|
+
) {
|
|
214
|
+
const top =
|
|
215
|
+
this._clientEdgeTraversalPath[this._clientEdgeTraversalPath.length - 1];
|
|
216
|
+
// Top can be null if we've traversed past a client edge into an ordinary
|
|
217
|
+
// client extension field; we never want to fetch in response to missing
|
|
218
|
+
// data off of a client extension field.
|
|
219
|
+
if (top !== null) {
|
|
220
|
+
this._missingClientEdges.push({
|
|
221
|
+
request: top.readerClientEdge.operation,
|
|
222
|
+
clientEdgeDestinationID: top.clientEdgeDestinationID,
|
|
223
|
+
});
|
|
224
|
+
}
|
|
225
|
+
}
|
|
226
|
+
}
|
|
227
|
+
|
|
191
228
|
_traverse(
|
|
192
229
|
node: ReaderNode,
|
|
193
230
|
dataID: DataID,
|
|
@@ -197,7 +234,7 @@ class RelayReader {
|
|
|
197
234
|
this._seenRecords.add(dataID);
|
|
198
235
|
if (record == null) {
|
|
199
236
|
if (record === undefined) {
|
|
200
|
-
this.
|
|
237
|
+
this._markDataAsMissing();
|
|
201
238
|
}
|
|
202
239
|
return record;
|
|
203
240
|
}
|
|
@@ -344,7 +381,7 @@ class RelayReader {
|
|
|
344
381
|
this._isMissingData = parentIsMissingData;
|
|
345
382
|
} else if (implementsInterface == null) {
|
|
346
383
|
// Don't know if the type implements the interface or not
|
|
347
|
-
this.
|
|
384
|
+
this._markDataAsMissing();
|
|
348
385
|
}
|
|
349
386
|
}
|
|
350
387
|
break;
|
|
@@ -372,12 +409,24 @@ class RelayReader {
|
|
|
372
409
|
case DEFER:
|
|
373
410
|
case CLIENT_EXTENSION: {
|
|
374
411
|
const isMissingData = this._isMissingData;
|
|
412
|
+
const alreadyMissingClientEdges = this._missingClientEdges.length;
|
|
413
|
+
if (RelayFeatureFlags.ENABLE_CLIENT_EDGES) {
|
|
414
|
+
this._clientEdgeTraversalPath.push(null);
|
|
415
|
+
}
|
|
375
416
|
const hasExpectedData = this._traverseSelections(
|
|
376
417
|
selection.selections,
|
|
377
418
|
record,
|
|
378
419
|
data,
|
|
379
420
|
);
|
|
380
|
-
|
|
421
|
+
// The only case where we want to suspend due to missing data off of
|
|
422
|
+
// a client extension is if we reached a client edge that we might be
|
|
423
|
+
// able to fetch:
|
|
424
|
+
this._isMissingData =
|
|
425
|
+
isMissingData ||
|
|
426
|
+
this._missingClientEdges.length > alreadyMissingClientEdges;
|
|
427
|
+
if (RelayFeatureFlags.ENABLE_CLIENT_EDGES) {
|
|
428
|
+
this._clientEdgeTraversalPath.pop();
|
|
429
|
+
}
|
|
381
430
|
if (!hasExpectedData) {
|
|
382
431
|
return false;
|
|
383
432
|
}
|
|
@@ -404,6 +453,13 @@ class RelayReader {
|
|
|
404
453
|
case ACTOR_CHANGE:
|
|
405
454
|
this._readActorChange(selection, record, data);
|
|
406
455
|
break;
|
|
456
|
+
case CLIENT_EDGE:
|
|
457
|
+
if (RelayFeatureFlags.ENABLE_CLIENT_EDGES) {
|
|
458
|
+
this._readClientEdge(selection, record, data);
|
|
459
|
+
} else {
|
|
460
|
+
throw new Error('Client edges are not yet supported.');
|
|
461
|
+
}
|
|
462
|
+
break;
|
|
407
463
|
default:
|
|
408
464
|
(selection: empty);
|
|
409
465
|
invariant(
|
|
@@ -450,7 +506,7 @@ class RelayReader {
|
|
|
450
506
|
field: ReaderRelayResolver,
|
|
451
507
|
record: Record,
|
|
452
508
|
data: SelectorData,
|
|
453
|
-
):
|
|
509
|
+
): void {
|
|
454
510
|
const {resolverModule, fragment} = field;
|
|
455
511
|
const storageKey = getStorageKey(field, this._variables);
|
|
456
512
|
const resolverID = ClientID.generateClientID(
|
|
@@ -523,8 +579,66 @@ class RelayReader {
|
|
|
523
579
|
if (seenRecord != null) {
|
|
524
580
|
this._seenRecords.add(seenRecord);
|
|
525
581
|
}
|
|
526
|
-
|
|
527
|
-
|
|
582
|
+
|
|
583
|
+
const applicationName = field.alias ?? field.name;
|
|
584
|
+
data[applicationName] = result;
|
|
585
|
+
}
|
|
586
|
+
|
|
587
|
+
_readClientEdge(
|
|
588
|
+
field: ReaderClientEdge,
|
|
589
|
+
record: Record,
|
|
590
|
+
data: SelectorData,
|
|
591
|
+
): void {
|
|
592
|
+
const backingField = field.backingField;
|
|
593
|
+
|
|
594
|
+
// Because ReaderClientExtension doesn't have `alias` or `name` and so I don't know
|
|
595
|
+
// how to get its applicationName or storageKey yet:
|
|
596
|
+
invariant(
|
|
597
|
+
backingField.kind !== 'ClientExtension',
|
|
598
|
+
'Client extension client edges are not yet implemented.',
|
|
599
|
+
);
|
|
600
|
+
|
|
601
|
+
const applicationName = backingField.alias ?? backingField.name;
|
|
602
|
+
|
|
603
|
+
const backingFieldData = {};
|
|
604
|
+
this._traverseSelections([backingField], record, backingFieldData);
|
|
605
|
+
const destinationDataID = backingFieldData[applicationName];
|
|
606
|
+
|
|
607
|
+
if (destinationDataID == null) {
|
|
608
|
+
data[applicationName] = destinationDataID;
|
|
609
|
+
return;
|
|
610
|
+
}
|
|
611
|
+
|
|
612
|
+
invariant(
|
|
613
|
+
typeof destinationDataID === 'string',
|
|
614
|
+
'Plural client edges not are yet implemented',
|
|
615
|
+
); // FIXME support plural
|
|
616
|
+
|
|
617
|
+
// Not wrapping the push/pop in a try/finally because if we throw, the
|
|
618
|
+
// Reader object is not usable after that anyway.
|
|
619
|
+
this._clientEdgeTraversalPath.push({
|
|
620
|
+
readerClientEdge: field,
|
|
621
|
+
clientEdgeDestinationID: destinationDataID,
|
|
622
|
+
});
|
|
623
|
+
|
|
624
|
+
const prevData = data[applicationName];
|
|
625
|
+
invariant(
|
|
626
|
+
prevData == null || typeof prevData === 'object',
|
|
627
|
+
'RelayReader(): Expected data for field `%s` on record `%s` ' +
|
|
628
|
+
'to be an object, got `%s`.',
|
|
629
|
+
applicationName,
|
|
630
|
+
RelayModernRecord.getDataID(record),
|
|
631
|
+
prevData,
|
|
632
|
+
);
|
|
633
|
+
const value = this._traverse(
|
|
634
|
+
field.linkedField,
|
|
635
|
+
destinationDataID,
|
|
636
|
+
// $FlowFixMe[incompatible-variance]
|
|
637
|
+
prevData,
|
|
638
|
+
);
|
|
639
|
+
data[applicationName] = value;
|
|
640
|
+
|
|
641
|
+
this._clientEdgeTraversalPath.pop();
|
|
528
642
|
}
|
|
529
643
|
|
|
530
644
|
_readFlightField(
|
|
@@ -539,7 +653,7 @@ class RelayReader {
|
|
|
539
653
|
if (reactFlightClientResponseRecordID == null) {
|
|
540
654
|
data[applicationName] = reactFlightClientResponseRecordID;
|
|
541
655
|
if (reactFlightClientResponseRecordID === undefined) {
|
|
542
|
-
this.
|
|
656
|
+
this._markDataAsMissing();
|
|
543
657
|
}
|
|
544
658
|
return reactFlightClientResponseRecordID;
|
|
545
659
|
}
|
|
@@ -550,7 +664,7 @@ class RelayReader {
|
|
|
550
664
|
if (reactFlightClientResponseRecord == null) {
|
|
551
665
|
data[applicationName] = reactFlightClientResponseRecord;
|
|
552
666
|
if (reactFlightClientResponseRecord === undefined) {
|
|
553
|
-
this.
|
|
667
|
+
this._markDataAsMissing();
|
|
554
668
|
}
|
|
555
669
|
return reactFlightClientResponseRecord;
|
|
556
670
|
}
|
|
@@ -570,7 +684,7 @@ class RelayReader {
|
|
|
570
684
|
const storageKey = getStorageKey(field, this._variables);
|
|
571
685
|
const value = RelayModernRecord.getValue(record, storageKey);
|
|
572
686
|
if (value === undefined) {
|
|
573
|
-
this.
|
|
687
|
+
this._markDataAsMissing();
|
|
574
688
|
}
|
|
575
689
|
data[applicationName] = value;
|
|
576
690
|
return value;
|
|
@@ -587,7 +701,7 @@ class RelayReader {
|
|
|
587
701
|
if (linkedID == null) {
|
|
588
702
|
data[applicationName] = linkedID;
|
|
589
703
|
if (linkedID === undefined) {
|
|
590
|
-
this.
|
|
704
|
+
this._markDataAsMissing();
|
|
591
705
|
}
|
|
592
706
|
return linkedID;
|
|
593
707
|
}
|
|
@@ -622,7 +736,7 @@ class RelayReader {
|
|
|
622
736
|
if (externalRef == null) {
|
|
623
737
|
data[applicationName] = externalRef;
|
|
624
738
|
if (externalRef === undefined) {
|
|
625
|
-
this.
|
|
739
|
+
this._markDataAsMissing();
|
|
626
740
|
}
|
|
627
741
|
return data[applicationName];
|
|
628
742
|
}
|
|
@@ -655,7 +769,7 @@ class RelayReader {
|
|
|
655
769
|
if (linkedIDs == null) {
|
|
656
770
|
data[applicationName] = linkedIDs;
|
|
657
771
|
if (linkedIDs === undefined) {
|
|
658
|
-
this.
|
|
772
|
+
this._markDataAsMissing();
|
|
659
773
|
}
|
|
660
774
|
return linkedIDs;
|
|
661
775
|
}
|
|
@@ -673,7 +787,7 @@ class RelayReader {
|
|
|
673
787
|
linkedIDs.forEach((linkedID, nextIndex) => {
|
|
674
788
|
if (linkedID == null) {
|
|
675
789
|
if (linkedID === undefined) {
|
|
676
|
-
this.
|
|
790
|
+
this._markDataAsMissing();
|
|
677
791
|
}
|
|
678
792
|
// $FlowFixMe[cannot-write]
|
|
679
793
|
linkedArray[nextIndex] = linkedID;
|
|
@@ -711,7 +825,7 @@ class RelayReader {
|
|
|
711
825
|
const component = RelayModernRecord.getValue(record, componentKey);
|
|
712
826
|
if (component == null) {
|
|
713
827
|
if (component === undefined) {
|
|
714
|
-
this.
|
|
828
|
+
this._markDataAsMissing();
|
|
715
829
|
}
|
|
716
830
|
return;
|
|
717
831
|
}
|
|
@@ -758,6 +872,17 @@ class RelayReader {
|
|
|
758
872
|
data[FRAGMENT_OWNER_KEY] = this._owner;
|
|
759
873
|
data[IS_WITHIN_UNMATCHED_TYPE_REFINEMENT] =
|
|
760
874
|
this._isWithinUnmatchedTypeRefinement;
|
|
875
|
+
|
|
876
|
+
if (RelayFeatureFlags.ENABLE_CLIENT_EDGES) {
|
|
877
|
+
if (
|
|
878
|
+
this._clientEdgeTraversalPath.length > 0 &&
|
|
879
|
+
this._clientEdgeTraversalPath[
|
|
880
|
+
this._clientEdgeTraversalPath.length - 1
|
|
881
|
+
] !== null
|
|
882
|
+
) {
|
|
883
|
+
data[CLIENT_EDGE_TRAVERSAL_PATH] = [...this._clientEdgeTraversalPath];
|
|
884
|
+
}
|
|
885
|
+
}
|
|
761
886
|
}
|
|
762
887
|
|
|
763
888
|
_createInlineDataOrResolverFragmentPointer(
|
|
@@ -101,6 +101,7 @@ class RelayStoreSubscriptions implements StoreSubscriptions {
|
|
|
101
101
|
subscription.snapshot = {
|
|
102
102
|
data: subscription.snapshot.data,
|
|
103
103
|
isMissingData: backup.isMissingData,
|
|
104
|
+
missingClientEdges: backup.missingClientEdges,
|
|
104
105
|
seenRecords: backup.seenRecords,
|
|
105
106
|
selector: backup.selector,
|
|
106
107
|
missingRequiredFields: backup.missingRequiredFields,
|
|
@@ -162,6 +163,7 @@ class RelayStoreSubscriptions implements StoreSubscriptions {
|
|
|
162
163
|
nextSnapshot = ({
|
|
163
164
|
data: nextData,
|
|
164
165
|
isMissingData: nextSnapshot.isMissingData,
|
|
166
|
+
missingClientEdges: nextSnapshot.missingClientEdges,
|
|
165
167
|
seenRecords: nextSnapshot.seenRecords,
|
|
166
168
|
selector: nextSnapshot.selector,
|
|
167
169
|
missingRequiredFields: nextSnapshot.missingRequiredFields,
|
|
@@ -35,7 +35,7 @@ import type {
|
|
|
35
35
|
NormalizationScalarField,
|
|
36
36
|
NormalizationSelectableNode,
|
|
37
37
|
} from '../util/NormalizationNode';
|
|
38
|
-
import type {ReaderFragment} from '../util/ReaderNode';
|
|
38
|
+
import type {ReaderClientEdge, ReaderFragment} from '../util/ReaderNode';
|
|
39
39
|
import type {
|
|
40
40
|
ConcreteRequest,
|
|
41
41
|
RequestParameters,
|
|
@@ -82,6 +82,7 @@ export type SingularReaderSelector = {|
|
|
|
82
82
|
+kind: 'SingularReaderSelector',
|
|
83
83
|
+dataID: DataID,
|
|
84
84
|
+isWithinUnmatchedTypeRefinement: boolean,
|
|
85
|
+
+clientEdgeTraversalPath: ClientEdgeTraversalPath | null,
|
|
85
86
|
+node: ReaderFragment,
|
|
86
87
|
+owner: RequestDescriptor,
|
|
87
88
|
+variables: Variables,
|
|
@@ -120,12 +121,26 @@ export type MissingRequiredFields =
|
|
|
120
121
|
| {|action: 'THROW', field: MissingRequiredField|}
|
|
121
122
|
| {|action: 'LOG', fields: Array<MissingRequiredField>|};
|
|
122
123
|
|
|
124
|
+
export type ClientEdgeTraversalInfo = {|
|
|
125
|
+
+readerClientEdge: ReaderClientEdge,
|
|
126
|
+
+clientEdgeDestinationID: DataID,
|
|
127
|
+
|};
|
|
128
|
+
|
|
129
|
+
export type ClientEdgeTraversalPath =
|
|
130
|
+
$ReadOnlyArray<ClientEdgeTraversalInfo | null>;
|
|
131
|
+
|
|
132
|
+
export type MissingClientEdgeRequestInfo = {|
|
|
133
|
+
+request: ConcreteRequest,
|
|
134
|
+
+clientEdgeDestinationID: DataID,
|
|
135
|
+
|};
|
|
136
|
+
|
|
123
137
|
/**
|
|
124
138
|
* A representation of a selector and its results at a particular point in time.
|
|
125
139
|
*/
|
|
126
140
|
export type Snapshot = {|
|
|
127
141
|
+data: ?SelectorData,
|
|
128
142
|
+isMissingData: boolean,
|
|
143
|
+
+missingClientEdges: null | $ReadOnlyArray<MissingClientEdgeRequestInfo>,
|
|
129
144
|
+seenRecords: DataIDSet,
|
|
130
145
|
+selector: SingularReaderSelector,
|
|
131
146
|
+missingRequiredFields: ?MissingRequiredFields,
|
|
@@ -202,6 +202,7 @@ function getModuleOperationKey(documentName: string): string {
|
|
|
202
202
|
*/
|
|
203
203
|
const RelayStoreUtils = {
|
|
204
204
|
ACTOR_IDENTIFIER_KEY: '__actorIdentifier',
|
|
205
|
+
CLIENT_EDGE_TRAVERSAL_PATH: '__clientEdgeTraversalPath',
|
|
205
206
|
FRAGMENTS_KEY: '__fragments',
|
|
206
207
|
FRAGMENT_OWNER_KEY: '__fragmentOwner',
|
|
207
208
|
FRAGMENT_PROP_NAME_KEY: '__fragmentPropName',
|
package/util/ReaderNode.js.flow
CHANGED
|
@@ -232,8 +232,16 @@ export type ReaderRelayResolver = {|
|
|
|
232
232
|
}) => mixed,
|
|
233
233
|
|};
|
|
234
234
|
|
|
235
|
+
export type ReaderClientEdge = {|
|
|
236
|
+
+kind: 'ClientEdge',
|
|
237
|
+
+linkedField: ReaderLinkedField,
|
|
238
|
+
+operation: ConcreteRequest,
|
|
239
|
+
+backingField: ReaderRelayResolver | ReaderClientExtension,
|
|
240
|
+
|};
|
|
241
|
+
|
|
235
242
|
export type ReaderSelection =
|
|
236
243
|
| ReaderCondition
|
|
244
|
+
| ReaderClientEdge
|
|
237
245
|
| ReaderClientExtension
|
|
238
246
|
| ReaderDefer
|
|
239
247
|
| ReaderField
|
|
@@ -14,8 +14,9 @@
|
|
|
14
14
|
|
|
15
15
|
import type {Disposable} from '../util/RelayRuntimeTypes';
|
|
16
16
|
|
|
17
|
-
type FeatureFlags = {|
|
|
17
|
+
export type FeatureFlags = {|
|
|
18
18
|
DELAY_CLEANUP_OF_PENDING_PRELOAD_QUERIES: boolean,
|
|
19
|
+
ENABLE_CLIENT_EDGES: boolean,
|
|
19
20
|
ENABLE_VARIABLE_CONNECTION_KEY: boolean,
|
|
20
21
|
ENABLE_PARTIAL_RENDERING_DEFAULT: boolean,
|
|
21
22
|
ENABLE_REACT_FLIGHT_COMPONENT_FIELD: boolean,
|
|
@@ -30,12 +31,14 @@ type FeatureFlags = {|
|
|
|
30
31
|
ENABLE_CONTAINERS_SUBSCRIBE_ON_COMMIT: boolean,
|
|
31
32
|
ENABLE_QUERY_RENDERER_OFFSCREEN_SUPPORT: boolean,
|
|
32
33
|
MAX_DATA_ID_LENGTH: ?number,
|
|
34
|
+
REFACTOR_SUSPENSE_RESOURCE: boolean,
|
|
33
35
|
STRING_INTERN_LEVEL: number,
|
|
34
36
|
USE_REACT_CACHE: boolean,
|
|
35
37
|
|};
|
|
36
38
|
|
|
37
39
|
const RelayFeatureFlags: FeatureFlags = {
|
|
38
40
|
DELAY_CLEANUP_OF_PENDING_PRELOAD_QUERIES: false,
|
|
41
|
+
ENABLE_CLIENT_EDGES: false,
|
|
39
42
|
ENABLE_VARIABLE_CONNECTION_KEY: false,
|
|
40
43
|
ENABLE_PARTIAL_RENDERING_DEFAULT: true,
|
|
41
44
|
ENABLE_REACT_FLIGHT_COMPONENT_FIELD: false,
|
|
@@ -50,6 +53,7 @@ const RelayFeatureFlags: FeatureFlags = {
|
|
|
50
53
|
ENABLE_CONTAINERS_SUBSCRIBE_ON_COMMIT: false,
|
|
51
54
|
ENABLE_QUERY_RENDERER_OFFSCREEN_SUPPORT: false,
|
|
52
55
|
MAX_DATA_ID_LENGTH: null,
|
|
56
|
+
REFACTOR_SUSPENSE_RESOURCE: true,
|
|
53
57
|
STRING_INTERN_LEVEL: 0,
|
|
54
58
|
USE_REACT_CACHE: false,
|
|
55
59
|
};
|