relay-runtime 11.0.2 → 12.0.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/index.js +1 -1
- package/index.js.flow +16 -1
- package/lib/index.js +15 -0
- package/lib/multi-actor-environment/ActorIdentifier.js +11 -1
- package/lib/multi-actor-environment/ActorSpecificEnvironment.js +59 -19
- package/lib/multi-actor-environment/ActorUtils.js +27 -0
- package/lib/multi-actor-environment/MultiActorEnvironment.js +305 -55
- package/lib/multi-actor-environment/index.js +5 -1
- package/lib/mutations/RelayRecordSourceSelectorProxy.js +6 -1
- package/lib/mutations/commitMutation.js +4 -1
- package/lib/mutations/validateMutation.js +6 -1
- package/lib/network/RelayObservable.js +3 -1
- package/lib/network/RelayQueryResponseCache.js +19 -3
- package/lib/network/wrapNetworkWithLogObserver.js +78 -0
- package/lib/store/DataChecker.js +110 -40
- package/lib/store/OperationExecutor.js +478 -204
- package/lib/store/RelayConcreteVariables.js +21 -0
- package/lib/store/RelayModernEnvironment.js +41 -85
- package/lib/store/RelayModernFragmentSpecResolver.js +48 -22
- package/lib/store/RelayModernRecord.js +35 -1
- package/lib/store/RelayModernStore.js +48 -14
- package/lib/store/RelayOperationTracker.js +33 -23
- package/lib/store/RelayPublishQueue.js +23 -5
- package/lib/store/RelayReader.js +138 -44
- package/lib/store/RelayRecordSource.js +87 -3
- package/lib/store/RelayReferenceMarker.js +28 -15
- package/lib/store/RelayResponseNormalizer.js +164 -91
- package/lib/store/RelayStoreReactFlightUtils.js +1 -7
- package/lib/store/RelayStoreSubscriptions.js +8 -5
- package/lib/store/RelayStoreUtils.js +7 -2
- package/lib/store/ResolverCache.js +213 -0
- package/lib/store/ResolverFragments.js +1 -1
- package/lib/store/createRelayContext.js +1 -1
- package/lib/subscription/requestSubscription.js +27 -29
- package/lib/util/RelayConcreteNode.js +1 -0
- package/lib/util/RelayFeatureFlags.js +3 -5
- package/lib/util/RelayReplaySubject.js +21 -6
- package/lib/util/getPaginationMetadata.js +41 -0
- package/lib/util/getPaginationVariables.js +67 -0
- package/lib/util/getPendingOperationsForFragment.js +55 -0
- package/lib/util/getRefetchMetadata.js +36 -0
- package/lib/util/getValueAtPath.js +51 -0
- package/lib/util/isEmptyObject.js +1 -1
- package/lib/util/registerEnvironmentWithDevTools.js +26 -0
- package/lib/util/withDuration.js +31 -0
- package/multi-actor-environment/ActorIdentifier.js.flow +17 -1
- package/multi-actor-environment/ActorSpecificEnvironment.js.flow +72 -44
- package/multi-actor-environment/ActorUtils.js.flow +33 -0
- package/multi-actor-environment/MultiActorEnvironment.js.flow +332 -80
- package/multi-actor-environment/MultiActorEnvironmentTypes.js.flow +61 -12
- package/multi-actor-environment/index.js.flow +3 -0
- package/mutations/RelayRecordSourceSelectorProxy.js.flow +7 -2
- package/mutations/commitMutation.js.flow +2 -0
- package/mutations/validateMutation.js.flow +8 -0
- package/network/RelayObservable.js.flow +2 -0
- package/network/RelayQueryResponseCache.js.flow +31 -18
- package/network/wrapNetworkWithLogObserver.js.flow +99 -0
- package/package.json +1 -1
- package/relay-runtime.js +2 -2
- package/relay-runtime.min.js +2 -2
- package/store/ClientID.js.flow +5 -1
- package/store/DataChecker.js.flow +126 -35
- package/store/OperationExecutor.js.flow +528 -265
- package/store/RelayConcreteVariables.js.flow +26 -1
- package/store/RelayModernEnvironment.js.flow +41 -94
- package/store/RelayModernFragmentSpecResolver.js.flow +40 -14
- package/store/RelayModernOperationDescriptor.js.flow +9 -3
- package/store/RelayModernRecord.js.flow +49 -0
- package/store/RelayModernStore.js.flow +50 -12
- package/store/RelayOperationTracker.js.flow +56 -34
- package/store/RelayPublishQueue.js.flow +31 -8
- package/store/RelayReader.js.flow +148 -42
- package/store/RelayRecordSource.js.flow +72 -6
- package/store/RelayReferenceMarker.js.flow +29 -12
- package/store/RelayResponseNormalizer.js.flow +164 -48
- package/store/RelayStoreReactFlightUtils.js.flow +1 -7
- package/store/RelayStoreSubscriptions.js.flow +10 -3
- package/store/RelayStoreTypes.js.flow +128 -12
- package/store/RelayStoreUtils.js.flow +17 -3
- package/store/ResolverCache.js.flow +247 -0
- package/store/ResolverFragments.js.flow +6 -3
- package/store/createRelayContext.js.flow +1 -1
- package/subscription/requestSubscription.js.flow +41 -29
- package/util/NormalizationNode.js.flow +10 -3
- package/util/ReaderNode.js.flow +15 -1
- package/util/RelayConcreteNode.js.flow +1 -0
- package/util/RelayFeatureFlags.js.flow +8 -10
- package/util/RelayReplaySubject.js.flow +7 -6
- package/util/getPaginationMetadata.js.flow +74 -0
- package/util/getPaginationVariables.js.flow +112 -0
- package/util/getPendingOperationsForFragment.js.flow +62 -0
- package/util/getRefetchMetadata.js.flow +80 -0
- package/util/getValueAtPath.js.flow +46 -0
- package/util/isEmptyObject.js.flow +1 -0
- package/util/registerEnvironmentWithDevTools.js.flow +33 -0
- package/util/withDuration.js.flow +32 -0
- package/lib/store/RelayRecordSourceMapImpl.js +0 -107
- package/lib/store/RelayStoreSubscriptionsUsingMapByID.js +0 -318
- package/store/RelayRecordSourceMapImpl.js.flow +0 -91
- package/store/RelayStoreSubscriptionsUsingMapByID.js.flow +0 -283
package/store/ClientID.js.flow
CHANGED
|
@@ -27,9 +27,11 @@ const getOperation = require('../util/getOperation');
|
|
|
27
27
|
const invariant = require('invariant');
|
|
28
28
|
|
|
29
29
|
const {isClientID} = require('./ClientID');
|
|
30
|
+
const {getLocalVariables} = require('./RelayConcreteVariables');
|
|
30
31
|
const {EXISTENT, UNKNOWN} = require('./RelayRecordState');
|
|
31
32
|
const {generateTypeID} = require('./TypeID');
|
|
32
33
|
|
|
34
|
+
import type {ActorIdentifier} from '../multi-actor-environment/ActorIdentifier';
|
|
33
35
|
import type {
|
|
34
36
|
NormalizationField,
|
|
35
37
|
NormalizationFlightField,
|
|
@@ -57,6 +59,7 @@ export type Availability = {|
|
|
|
57
59
|
|};
|
|
58
60
|
|
|
59
61
|
const {
|
|
62
|
+
ACTOR_CHANGE,
|
|
60
63
|
CONDITION,
|
|
61
64
|
CLIENT_COMPONENT,
|
|
62
65
|
CLIENT_EXTENSION,
|
|
@@ -90,8 +93,9 @@ const {
|
|
|
90
93
|
* If all records are present, returns `true`, otherwise `false`.
|
|
91
94
|
*/
|
|
92
95
|
function check(
|
|
93
|
-
|
|
94
|
-
|
|
96
|
+
getSourceForActor: (actorIdentifier: ActorIdentifier) => RecordSource,
|
|
97
|
+
getTargetForActor: (actorIdentifier: ActorIdentifier) => MutableRecordSource,
|
|
98
|
+
defaultActorIdentifier: ActorIdentifier,
|
|
95
99
|
selector: NormalizationSelector,
|
|
96
100
|
handlers: $ReadOnlyArray<MissingFieldHandler>,
|
|
97
101
|
operationLoader: ?OperationLoader,
|
|
@@ -100,8 +104,9 @@ function check(
|
|
|
100
104
|
): Availability {
|
|
101
105
|
const {dataID, node, variables} = selector;
|
|
102
106
|
const checker = new DataChecker(
|
|
103
|
-
|
|
104
|
-
|
|
107
|
+
getSourceForActor,
|
|
108
|
+
getTargetForActor,
|
|
109
|
+
defaultActorIdentifier,
|
|
105
110
|
variables,
|
|
106
111
|
handlers,
|
|
107
112
|
operationLoader,
|
|
@@ -125,28 +130,67 @@ class DataChecker {
|
|
|
125
130
|
_source: RecordSource;
|
|
126
131
|
_variables: Variables;
|
|
127
132
|
_shouldProcessClientComponents: ?boolean;
|
|
133
|
+
+_getSourceForActor: (actorIdentifier: ActorIdentifier) => RecordSource;
|
|
134
|
+
+_getTargetForActor: (
|
|
135
|
+
actorIdentifier: ActorIdentifier,
|
|
136
|
+
) => MutableRecordSource;
|
|
137
|
+
+_getDataID: GetDataID;
|
|
138
|
+
+_mutatorRecordSourceProxyCache: Map<
|
|
139
|
+
ActorIdentifier,
|
|
140
|
+
[RelayRecordSourceMutator, RelayRecordSourceProxy],
|
|
141
|
+
>;
|
|
128
142
|
|
|
129
143
|
constructor(
|
|
130
|
-
|
|
131
|
-
|
|
144
|
+
getSourceForActor: (actorIdentifier: ActorIdentifier) => RecordSource,
|
|
145
|
+
getTargetForActor: (
|
|
146
|
+
actorIdentifier: ActorIdentifier,
|
|
147
|
+
) => MutableRecordSource,
|
|
148
|
+
defaultActorIdentifier: ActorIdentifier,
|
|
132
149
|
variables: Variables,
|
|
133
150
|
handlers: $ReadOnlyArray<MissingFieldHandler>,
|
|
134
151
|
operationLoader: ?OperationLoader,
|
|
135
152
|
getDataID: GetDataID,
|
|
136
153
|
shouldProcessClientComponents: ?boolean,
|
|
137
154
|
) {
|
|
138
|
-
|
|
155
|
+
this._getSourceForActor = getSourceForActor;
|
|
156
|
+
this._getTargetForActor = getTargetForActor;
|
|
157
|
+
this._getDataID = getDataID;
|
|
158
|
+
this._source = getSourceForActor(defaultActorIdentifier);
|
|
159
|
+
this._mutatorRecordSourceProxyCache = new Map();
|
|
160
|
+
const [mutator, recordSourceProxy] = this._getMutatorAndRecordProxyForActor(
|
|
161
|
+
defaultActorIdentifier,
|
|
162
|
+
);
|
|
139
163
|
this._mostRecentlyInvalidatedAt = null;
|
|
140
164
|
this._handlers = handlers;
|
|
141
165
|
this._mutator = mutator;
|
|
142
166
|
this._operationLoader = operationLoader ?? null;
|
|
143
|
-
this._recordSourceProxy =
|
|
167
|
+
this._recordSourceProxy = recordSourceProxy;
|
|
144
168
|
this._recordWasMissing = false;
|
|
145
|
-
this._source = source;
|
|
146
169
|
this._variables = variables;
|
|
147
170
|
this._shouldProcessClientComponents = shouldProcessClientComponents;
|
|
148
171
|
}
|
|
149
172
|
|
|
173
|
+
_getMutatorAndRecordProxyForActor(
|
|
174
|
+
actorIdentifier: ActorIdentifier,
|
|
175
|
+
): [RelayRecordSourceMutator, RelayRecordSourceProxy] {
|
|
176
|
+
let tuple = this._mutatorRecordSourceProxyCache.get(actorIdentifier);
|
|
177
|
+
if (tuple == null) {
|
|
178
|
+
const target = this._getTargetForActor(actorIdentifier);
|
|
179
|
+
|
|
180
|
+
const mutator = new RelayRecordSourceMutator(
|
|
181
|
+
this._getSourceForActor(actorIdentifier),
|
|
182
|
+
target,
|
|
183
|
+
);
|
|
184
|
+
const recordSourceProxy = new RelayRecordSourceProxy(
|
|
185
|
+
mutator,
|
|
186
|
+
this._getDataID,
|
|
187
|
+
);
|
|
188
|
+
tuple = [mutator, recordSourceProxy];
|
|
189
|
+
this._mutatorRecordSourceProxyCache.set(actorIdentifier, tuple);
|
|
190
|
+
}
|
|
191
|
+
return tuple;
|
|
192
|
+
}
|
|
193
|
+
|
|
150
194
|
check(node: NormalizationNode, dataID: DataID): Availability {
|
|
151
195
|
this._traverse(node, dataID);
|
|
152
196
|
|
|
@@ -184,6 +228,8 @@ class DataChecker {
|
|
|
184
228
|
...
|
|
185
229
|
} {
|
|
186
230
|
return {
|
|
231
|
+
/* $FlowFixMe[class-object-subtyping] added when improving typing for
|
|
232
|
+
* this parameters */
|
|
187
233
|
args: field.args ? getArgumentValues(field.args, this._variables) : {},
|
|
188
234
|
// Getting a snapshot of the record state is potentially expensive since
|
|
189
235
|
// we will need to merge the sink and source records. Since we do not create
|
|
@@ -309,8 +355,13 @@ class DataChecker {
|
|
|
309
355
|
this._checkLink(selection, dataID);
|
|
310
356
|
}
|
|
311
357
|
break;
|
|
358
|
+
case ACTOR_CHANGE:
|
|
359
|
+
this._checkActorChange(selection.linkedField, dataID);
|
|
360
|
+
break;
|
|
312
361
|
case CONDITION:
|
|
313
|
-
const conditionValue =
|
|
362
|
+
const conditionValue = Boolean(
|
|
363
|
+
this._getVariableValue(selection.condition),
|
|
364
|
+
);
|
|
314
365
|
if (conditionValue === selection.passingValue) {
|
|
315
366
|
this._traverseSelections(selection.selections, dataID);
|
|
316
367
|
}
|
|
@@ -323,7 +374,7 @@ class DataChecker {
|
|
|
323
374
|
if (typeName === selection.type) {
|
|
324
375
|
this._traverseSelections(selection.selections, dataID);
|
|
325
376
|
}
|
|
326
|
-
} else
|
|
377
|
+
} else {
|
|
327
378
|
// Abstract refinement: check data depending on whether the type
|
|
328
379
|
// conforms to the interface/union or not:
|
|
329
380
|
// - Type known to _not_ implement the interface: don't check the selections.
|
|
@@ -349,10 +400,6 @@ class DataChecker {
|
|
|
349
400
|
// missing so don't bother reading the fragment
|
|
350
401
|
this._handleMissing();
|
|
351
402
|
} // else false: known to not implement the interface
|
|
352
|
-
} else {
|
|
353
|
-
// legacy behavior for abstract refinements: always check even
|
|
354
|
-
// if the type doesn't conform
|
|
355
|
-
this._traverseSelections(selection.selections, dataID);
|
|
356
403
|
}
|
|
357
404
|
break;
|
|
358
405
|
}
|
|
@@ -388,9 +435,15 @@ class DataChecker {
|
|
|
388
435
|
case STREAM:
|
|
389
436
|
this._traverseSelections(selection.selections, dataID);
|
|
390
437
|
break;
|
|
391
|
-
// $FlowFixMe[incompatible-type]
|
|
392
438
|
case FRAGMENT_SPREAD:
|
|
439
|
+
const prevVariables = this._variables;
|
|
440
|
+
this._variables = getLocalVariables(
|
|
441
|
+
this._variables,
|
|
442
|
+
selection.fragment.argumentDefinitions,
|
|
443
|
+
selection.args,
|
|
444
|
+
);
|
|
393
445
|
this._traverseSelections(selection.fragment.selections, dataID);
|
|
446
|
+
this._variables = prevVariables;
|
|
394
447
|
break;
|
|
395
448
|
case CLIENT_EXTENSION:
|
|
396
449
|
const recordWasMissing = this._recordWasMissing;
|
|
@@ -398,25 +451,23 @@ class DataChecker {
|
|
|
398
451
|
this._recordWasMissing = recordWasMissing;
|
|
399
452
|
break;
|
|
400
453
|
case TYPE_DISCRIMINATOR:
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
if
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
} // else: if it does or doesn't implement, we don't need to check or skip anything else
|
|
419
|
-
}
|
|
454
|
+
const {abstractKey} = selection;
|
|
455
|
+
const recordType = this._mutator.getType(dataID);
|
|
456
|
+
invariant(
|
|
457
|
+
recordType != null,
|
|
458
|
+
'DataChecker: Expected record `%s` to have a known type',
|
|
459
|
+
dataID,
|
|
460
|
+
);
|
|
461
|
+
const typeID = generateTypeID(recordType);
|
|
462
|
+
const implementsInterface = this._mutator.getValue(
|
|
463
|
+
typeID,
|
|
464
|
+
abstractKey,
|
|
465
|
+
);
|
|
466
|
+
if (implementsInterface == null) {
|
|
467
|
+
// unsure if the type implements the interface: data is
|
|
468
|
+
// missing
|
|
469
|
+
this._handleMissing();
|
|
470
|
+
} // else: if it does or doesn't implement, we don't need to check or skip anything else
|
|
420
471
|
break;
|
|
421
472
|
case FLIGHT_FIELD:
|
|
422
473
|
if (RelayFeatureFlags.ENABLE_REACT_FLIGHT_COMPONENT_FIELD) {
|
|
@@ -462,7 +513,14 @@ class DataChecker {
|
|
|
462
513
|
const normalizationRootNode = operationLoader.get(operationReference);
|
|
463
514
|
if (normalizationRootNode != null) {
|
|
464
515
|
const operation = getOperation(normalizationRootNode);
|
|
516
|
+
const prevVariables = this._variables;
|
|
517
|
+
this._variables = getLocalVariables(
|
|
518
|
+
this._variables,
|
|
519
|
+
operation.argumentDefinitions,
|
|
520
|
+
moduleImport.args,
|
|
521
|
+
);
|
|
465
522
|
this._traverse(operation, dataID);
|
|
523
|
+
this._variables = prevVariables;
|
|
466
524
|
} else {
|
|
467
525
|
// If the fragment is not available, we assume that the data cannot have been
|
|
468
526
|
// processed yet and must therefore be missing.
|
|
@@ -519,6 +577,39 @@ class DataChecker {
|
|
|
519
577
|
}
|
|
520
578
|
}
|
|
521
579
|
|
|
580
|
+
_checkActorChange(field: NormalizationLinkedField, dataID: DataID): void {
|
|
581
|
+
const storageKey = getStorageKey(field, this._variables);
|
|
582
|
+
const record = this._source.get(dataID);
|
|
583
|
+
const tuple =
|
|
584
|
+
record != null
|
|
585
|
+
? RelayModernRecord.getActorLinkedRecordID(record, storageKey)
|
|
586
|
+
: record;
|
|
587
|
+
|
|
588
|
+
if (tuple == null) {
|
|
589
|
+
if (tuple === undefined) {
|
|
590
|
+
this._handleMissing();
|
|
591
|
+
}
|
|
592
|
+
} else {
|
|
593
|
+
const [actorIdentifier, linkedID] = tuple;
|
|
594
|
+
const prevSource = this._source;
|
|
595
|
+
const prevMutator = this._mutator;
|
|
596
|
+
const prevRecordSourceProxy = this._recordSourceProxy;
|
|
597
|
+
|
|
598
|
+
const [
|
|
599
|
+
mutator,
|
|
600
|
+
recordSourceProxy,
|
|
601
|
+
] = this._getMutatorAndRecordProxyForActor(actorIdentifier);
|
|
602
|
+
|
|
603
|
+
this._source = this._getSourceForActor(actorIdentifier);
|
|
604
|
+
this._mutator = mutator;
|
|
605
|
+
this._recordSourceProxy = recordSourceProxy;
|
|
606
|
+
this._traverse(field, linkedID);
|
|
607
|
+
this._source = prevSource;
|
|
608
|
+
this._mutator = prevMutator;
|
|
609
|
+
this._recordSourceProxy = prevRecordSourceProxy;
|
|
610
|
+
}
|
|
611
|
+
}
|
|
612
|
+
|
|
522
613
|
_checkFlightField(field: NormalizationFlightField, dataID: DataID): void {
|
|
523
614
|
const storageKey = getStorageKey(field, this._variables);
|
|
524
615
|
const linkedID = this._mutator.getLinkedRecordID(dataID, storageKey);
|