relay-runtime 11.0.1 → 13.0.0-rc.1
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 +2 -2
- package/handlers/connection/ConnectionHandler.js.flow +8 -17
- package/handlers/connection/MutationHandlers.js.flow +7 -11
- package/index.js +1 -1
- package/index.js.flow +60 -36
- package/lib/handlers/RelayDefaultHandlerProvider.js +1 -1
- package/lib/handlers/connection/ConnectionHandler.js +13 -19
- package/lib/handlers/connection/MutationHandlers.js +4 -7
- package/lib/index.js +58 -43
- package/lib/multi-actor-environment/ActorIdentifier.js +33 -0
- package/lib/multi-actor-environment/ActorSpecificEnvironment.js +152 -0
- package/lib/multi-actor-environment/ActorUtils.js +27 -0
- package/lib/multi-actor-environment/MultiActorEnvironment.js +419 -0
- package/lib/multi-actor-environment/MultiActorEnvironmentTypes.js +11 -0
- package/lib/multi-actor-environment/index.js +21 -0
- package/lib/mutations/RelayDeclarativeMutationConfig.js +4 -1
- package/lib/mutations/RelayRecordProxy.js +3 -2
- package/lib/mutations/RelayRecordSourceMutator.js +3 -2
- package/lib/mutations/RelayRecordSourceProxy.js +12 -4
- package/lib/mutations/RelayRecordSourceSelectorProxy.js +18 -5
- package/lib/mutations/applyOptimisticMutation.js +6 -6
- package/lib/mutations/commitMutation.js +14 -10
- package/lib/mutations/readUpdatableQuery_EXPERIMENTAL.js +238 -0
- package/lib/mutations/validateMutation.js +10 -5
- package/lib/network/ConvertToExecuteFunction.js +2 -1
- package/lib/network/RelayNetwork.js +3 -2
- package/lib/network/RelayQueryResponseCache.js +21 -5
- package/lib/network/wrapNetworkWithLogObserver.js +79 -0
- package/lib/query/GraphQLTag.js +3 -2
- package/lib/query/fetchQuery.js +6 -5
- package/lib/query/fetchQueryInternal.js +1 -1
- package/lib/query/fetchQuery_DEPRECATED.js +2 -1
- package/lib/store/ClientID.js +7 -1
- package/lib/store/DataChecker.js +123 -54
- package/lib/store/{RelayModernQueryExecutor.js → OperationExecutor.js} +518 -200
- package/lib/store/RelayConcreteVariables.js +26 -8
- package/lib/store/RelayExperimentalGraphResponseHandler.js +153 -0
- package/lib/store/RelayExperimentalGraphResponseTransform.js +391 -0
- package/lib/store/RelayModernEnvironment.js +175 -240
- package/lib/store/RelayModernFragmentSpecResolver.js +52 -26
- package/lib/store/RelayModernOperationDescriptor.js +2 -1
- package/lib/store/RelayModernRecord.js +47 -12
- package/lib/store/RelayModernSelector.js +14 -8
- package/lib/store/RelayModernStore.js +56 -28
- package/lib/store/RelayOperationTracker.js +34 -24
- package/lib/store/RelayPublishQueue.js +41 -13
- package/lib/store/RelayReader.js +288 -48
- package/lib/store/RelayRecordSource.js +87 -3
- package/lib/store/RelayReferenceMarker.js +34 -22
- package/lib/store/RelayResponseNormalizer.js +211 -110
- package/lib/store/RelayStoreReactFlightUtils.js +4 -10
- package/lib/store/RelayStoreSubscriptions.js +14 -9
- package/lib/store/RelayStoreUtils.js +12 -7
- package/lib/store/ResolverCache.js +213 -0
- package/lib/store/ResolverFragments.js +61 -0
- package/lib/store/cloneRelayHandleSourceField.js +5 -4
- package/lib/store/cloneRelayScalarHandleSourceField.js +5 -4
- package/lib/store/createRelayContext.js +4 -2
- package/lib/store/readInlineData.js +6 -2
- package/lib/subscription/requestSubscription.js +34 -25
- package/lib/util/RelayConcreteNode.js +3 -0
- package/lib/util/RelayFeatureFlags.js +10 -4
- package/lib/util/RelayProfiler.js +17 -187
- package/lib/util/RelayReplaySubject.js +22 -7
- package/lib/util/RelayRuntimeTypes.js +0 -6
- package/lib/util/StringInterner.js +71 -0
- package/lib/util/getFragmentIdentifier.js +15 -7
- package/lib/util/getOperation.js +2 -1
- package/lib/util/getPaginationMetadata.js +41 -0
- package/lib/util/getPaginationVariables.js +66 -0
- package/lib/util/getPendingOperationsForFragment.js +55 -0
- package/lib/util/getRefetchMetadata.js +36 -0
- package/lib/util/getRelayHandleKey.js +2 -2
- package/lib/util/getRequestIdentifier.js +2 -2
- 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 +43 -0
- package/multi-actor-environment/ActorSpecificEnvironment.js.flow +225 -0
- package/multi-actor-environment/ActorUtils.js.flow +33 -0
- package/multi-actor-environment/MultiActorEnvironment.js.flow +506 -0
- package/multi-actor-environment/MultiActorEnvironmentTypes.js.flow +261 -0
- package/multi-actor-environment/index.js.flow +26 -0
- package/mutations/RelayDeclarativeMutationConfig.js.flow +32 -26
- package/mutations/RelayRecordProxy.js.flow +4 -5
- package/mutations/RelayRecordSourceMutator.js.flow +4 -6
- package/mutations/RelayRecordSourceProxy.js.flow +19 -10
- package/mutations/RelayRecordSourceSelectorProxy.js.flow +22 -7
- package/mutations/applyOptimisticMutation.js.flow +13 -14
- package/mutations/commitLocalUpdate.js.flow +1 -1
- package/mutations/commitMutation.js.flow +35 -46
- package/mutations/readUpdatableQuery_EXPERIMENTAL.js.flow +309 -0
- package/mutations/validateMutation.js.flow +26 -16
- package/network/ConvertToExecuteFunction.js.flow +2 -2
- package/network/RelayNetwork.js.flow +4 -5
- package/network/RelayNetworkTypes.js.flow +5 -4
- package/network/RelayObservable.js.flow +1 -1
- package/network/RelayQueryResponseCache.js.flow +34 -21
- package/network/wrapNetworkWithLogObserver.js.flow +100 -0
- package/package.json +3 -2
- package/query/GraphQLTag.js.flow +9 -9
- package/query/PreloadableQueryRegistry.js.flow +2 -1
- package/query/fetchQuery.js.flow +11 -13
- package/query/fetchQueryInternal.js.flow +6 -9
- package/query/fetchQuery_DEPRECATED.js.flow +6 -6
- package/relay-runtime.js +2 -2
- package/relay-runtime.min.js +2 -2
- package/store/ClientID.js.flow +14 -3
- package/store/DataChecker.js.flow +141 -59
- package/store/{RelayModernQueryExecutor.js.flow → OperationExecutor.js.flow} +605 -303
- package/store/RelayConcreteVariables.js.flow +27 -8
- package/store/RelayExperimentalGraphResponseHandler.js.flow +124 -0
- package/store/RelayExperimentalGraphResponseTransform.js.flow +475 -0
- package/store/RelayModernEnvironment.js.flow +173 -240
- package/store/RelayModernFragmentSpecResolver.js.flow +55 -31
- package/store/RelayModernOperationDescriptor.js.flow +12 -7
- package/store/RelayModernRecord.js.flow +67 -11
- package/store/RelayModernSelector.js.flow +24 -14
- package/store/RelayModernStore.js.flow +66 -36
- package/store/RelayOperationTracker.js.flow +59 -43
- package/store/RelayOptimisticRecordSource.js.flow +2 -2
- package/store/RelayPublishQueue.js.flow +79 -34
- package/store/RelayReader.js.flow +351 -73
- package/store/RelayRecordSource.js.flow +72 -6
- package/store/RelayReferenceMarker.js.flow +40 -26
- package/store/RelayResponseNormalizer.js.flow +258 -99
- package/store/RelayStoreReactFlightUtils.js.flow +4 -11
- package/store/RelayStoreSubscriptions.js.flow +19 -11
- package/store/RelayStoreTypes.js.flow +209 -43
- package/store/RelayStoreUtils.js.flow +24 -11
- package/store/ResolverCache.js.flow +249 -0
- package/store/ResolverFragments.js.flow +121 -0
- package/store/StoreInspector.js.flow +2 -2
- package/store/TypeID.js.flow +1 -1
- package/store/ViewerPattern.js.flow +2 -2
- package/store/cloneRelayHandleSourceField.js.flow +5 -6
- package/store/cloneRelayScalarHandleSourceField.js.flow +5 -6
- package/store/createFragmentSpecResolver.js.flow +3 -4
- package/store/createRelayContext.js.flow +3 -3
- package/store/normalizeRelayPayload.js.flow +6 -7
- package/store/readInlineData.js.flow +7 -8
- package/subscription/requestSubscription.js.flow +53 -41
- package/util/NormalizationNode.js.flow +10 -3
- package/util/ReaderNode.js.flow +38 -2
- package/util/RelayConcreteNode.js.flow +5 -0
- package/util/RelayFeatureFlags.js.flow +24 -10
- package/util/RelayProfiler.js.flow +22 -194
- package/util/RelayReplaySubject.js.flow +9 -9
- package/util/RelayRuntimeTypes.js.flow +72 -3
- package/util/StringInterner.js.flow +69 -0
- package/util/createPayloadFor3DField.js.flow +3 -3
- package/util/getFragmentIdentifier.js.flow +27 -15
- package/util/getOperation.js.flow +2 -2
- package/util/getPaginationMetadata.js.flow +72 -0
- package/util/getPaginationVariables.js.flow +108 -0
- package/util/getPendingOperationsForFragment.js.flow +62 -0
- package/util/getRefetchMetadata.js.flow +79 -0
- package/util/getRelayHandleKey.js.flow +1 -2
- package/util/getRequestIdentifier.js.flow +3 -3
- package/util/getValueAtPath.js.flow +46 -0
- package/util/isEmptyObject.js.flow +1 -0
- package/util/registerEnvironmentWithDevTools.js.flow +33 -0
- package/util/resolveImmediate.js.flow +1 -1
- 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
|
@@ -12,29 +12,13 @@
|
|
|
12
12
|
|
|
13
13
|
'use strict';
|
|
14
14
|
|
|
15
|
-
const RelayFeatureFlags = require('../util/RelayFeatureFlags');
|
|
16
|
-
|
|
17
|
-
const areEqual = require('areEqual');
|
|
18
|
-
const invariant = require('invariant');
|
|
19
|
-
const isScalarAndEqual = require('../util/isScalarAndEqual');
|
|
20
|
-
const reportMissingRequiredFields = require('../util/reportMissingRequiredFields');
|
|
21
|
-
const warning = require('warning');
|
|
22
|
-
|
|
23
|
-
const {getPromiseForActiveRequest} = require('../query/fetchQueryInternal');
|
|
24
|
-
const {createRequestDescriptor} = require('./RelayModernOperationDescriptor');
|
|
25
|
-
const {
|
|
26
|
-
areEqualSelectors,
|
|
27
|
-
createReaderSelector,
|
|
28
|
-
getSelectorsFromObject,
|
|
29
|
-
} = require('./RelayModernSelector');
|
|
30
|
-
|
|
31
15
|
import type {ConcreteRequest} from '../util/RelayConcreteNode';
|
|
32
16
|
import type {Disposable, Variables} from '../util/RelayRuntimeTypes';
|
|
33
17
|
import type {
|
|
34
|
-
IEnvironment,
|
|
35
18
|
FragmentMap,
|
|
36
19
|
FragmentSpecResolver,
|
|
37
20
|
FragmentSpecResults,
|
|
21
|
+
IEnvironment,
|
|
38
22
|
MissingRequiredFields,
|
|
39
23
|
PluralReaderSelector,
|
|
40
24
|
RelayContext,
|
|
@@ -43,10 +27,25 @@ import type {
|
|
|
43
27
|
Snapshot,
|
|
44
28
|
} from './RelayStoreTypes';
|
|
45
29
|
|
|
30
|
+
const getPendingOperationsForFragment = require('../util/getPendingOperationsForFragment');
|
|
31
|
+
const isScalarAndEqual = require('../util/isScalarAndEqual');
|
|
32
|
+
const recycleNodesInto = require('../util/recycleNodesInto');
|
|
33
|
+
const RelayFeatureFlags = require('../util/RelayFeatureFlags');
|
|
34
|
+
const reportMissingRequiredFields = require('../util/reportMissingRequiredFields');
|
|
35
|
+
const {createRequestDescriptor} = require('./RelayModernOperationDescriptor');
|
|
36
|
+
const {
|
|
37
|
+
areEqualSelectors,
|
|
38
|
+
createReaderSelector,
|
|
39
|
+
getSelectorsFromObject,
|
|
40
|
+
} = require('./RelayModernSelector');
|
|
41
|
+
const areEqual = require('areEqual');
|
|
42
|
+
const invariant = require('invariant');
|
|
43
|
+
const warning = require('warning');
|
|
44
|
+
|
|
46
45
|
type Props = {[key: string]: mixed, ...};
|
|
47
46
|
type Resolvers = {
|
|
48
47
|
[key: string]: ?(SelectorListResolver | SelectorResolver),
|
|
49
|
-
|
|
48
|
+
...
|
|
50
49
|
};
|
|
51
50
|
|
|
52
51
|
/**
|
|
@@ -137,13 +136,16 @@ class RelayModernFragmentSpecResolver implements FragmentSpecResolver {
|
|
|
137
136
|
return this._data;
|
|
138
137
|
}
|
|
139
138
|
|
|
140
|
-
setCallback(callback: () => void): void {
|
|
139
|
+
setCallback(props: Props, callback: () => void): void {
|
|
141
140
|
this._callback = callback;
|
|
141
|
+
if (RelayFeatureFlags.ENABLE_CONTAINERS_SUBSCRIBE_ON_COMMIT === true) {
|
|
142
|
+
this.setProps(props);
|
|
143
|
+
}
|
|
142
144
|
}
|
|
143
145
|
|
|
144
146
|
setProps(props: Props): void {
|
|
145
|
-
const ownedSelectors = getSelectorsFromObject(this._fragments, props);
|
|
146
147
|
this._props = {};
|
|
148
|
+
const ownedSelectors = getSelectorsFromObject(this._fragments, props);
|
|
147
149
|
|
|
148
150
|
for (const key in ownedSelectors) {
|
|
149
151
|
if (ownedSelectors.hasOwnProperty(key)) {
|
|
@@ -160,6 +162,7 @@ class RelayModernFragmentSpecResolver implements FragmentSpecResolver {
|
|
|
160
162
|
this._context.environment,
|
|
161
163
|
this._rootIsQueryRenderer,
|
|
162
164
|
ownedSelector,
|
|
165
|
+
this._callback != null,
|
|
163
166
|
this._onChange,
|
|
164
167
|
);
|
|
165
168
|
} else {
|
|
@@ -176,6 +179,7 @@ class RelayModernFragmentSpecResolver implements FragmentSpecResolver {
|
|
|
176
179
|
this._context.environment,
|
|
177
180
|
this._rootIsQueryRenderer,
|
|
178
181
|
ownedSelector,
|
|
182
|
+
this._callback != null,
|
|
179
183
|
this._onChange,
|
|
180
184
|
);
|
|
181
185
|
} else {
|
|
@@ -232,6 +236,7 @@ class SelectorResolver {
|
|
|
232
236
|
environment: IEnvironment,
|
|
233
237
|
rootIsQueryRenderer: boolean,
|
|
234
238
|
selector: SingularReaderSelector,
|
|
239
|
+
subscribeOnConstruction: boolean,
|
|
235
240
|
callback: () => void,
|
|
236
241
|
) {
|
|
237
242
|
const snapshot = environment.lookup(selector);
|
|
@@ -242,7 +247,13 @@ class SelectorResolver {
|
|
|
242
247
|
this._environment = environment;
|
|
243
248
|
this._rootIsQueryRenderer = rootIsQueryRenderer;
|
|
244
249
|
this._selector = selector;
|
|
245
|
-
|
|
250
|
+
if (RelayFeatureFlags.ENABLE_CONTAINERS_SUBSCRIBE_ON_COMMIT === true) {
|
|
251
|
+
if (subscribeOnConstruction) {
|
|
252
|
+
this._subscription = environment.subscribe(snapshot, this._onChange);
|
|
253
|
+
}
|
|
254
|
+
} else {
|
|
255
|
+
this._subscription = environment.subscribe(snapshot, this._onChange);
|
|
256
|
+
}
|
|
246
257
|
}
|
|
247
258
|
|
|
248
259
|
dispose(): void {
|
|
@@ -253,10 +264,7 @@ class SelectorResolver {
|
|
|
253
264
|
}
|
|
254
265
|
|
|
255
266
|
resolve(): ?Object {
|
|
256
|
-
if (
|
|
257
|
-
RelayFeatureFlags.ENABLE_RELAY_CONTAINERS_SUSPENSE === true &&
|
|
258
|
-
this._isMissingData === true
|
|
259
|
-
) {
|
|
267
|
+
if (this._isMissingData === true) {
|
|
260
268
|
// NOTE: This branch exists to handle the case in which:
|
|
261
269
|
// - A RelayModern container is rendered as a descendant of a Relay Hook
|
|
262
270
|
// root using a "partial" renderPolicy (this means that eargerly
|
|
@@ -278,11 +286,12 @@ class SelectorResolver {
|
|
|
278
286
|
// This should eventually go away with something like @optional, where we only
|
|
279
287
|
// suspend at specific boundaries depending on whether the boundary
|
|
280
288
|
// can be fulfilled or not.
|
|
281
|
-
const
|
|
282
|
-
|
|
283
|
-
this.
|
|
284
|
-
|
|
285
|
-
|
|
289
|
+
const pendingOperationsResult = getPendingOperationsForFragment(
|
|
290
|
+
this._environment,
|
|
291
|
+
this._selector.node,
|
|
292
|
+
this._selector.owner,
|
|
293
|
+
);
|
|
294
|
+
const promise: void | Promise<void> = pendingOperationsResult?.promise;
|
|
286
295
|
if (promise != null) {
|
|
287
296
|
if (this._rootIsQueryRenderer) {
|
|
288
297
|
warning(
|
|
@@ -293,6 +302,8 @@ class SelectorResolver {
|
|
|
293
302
|
this._selector.node.name,
|
|
294
303
|
);
|
|
295
304
|
} else {
|
|
305
|
+
const pendingOperations =
|
|
306
|
+
pendingOperationsResult?.pendingOperations ?? [];
|
|
296
307
|
warning(
|
|
297
308
|
false,
|
|
298
309
|
'Relay: Relay Container for fragment `%s` suspended. When using ' +
|
|
@@ -300,6 +311,15 @@ class SelectorResolver {
|
|
|
300
311
|
'of a Relay Container.',
|
|
301
312
|
this._selector.node.name,
|
|
302
313
|
);
|
|
314
|
+
this._environment.__log({
|
|
315
|
+
name: 'suspense.fragment',
|
|
316
|
+
data: this._data,
|
|
317
|
+
fragment: this._selector.node,
|
|
318
|
+
isRelayHooks: false,
|
|
319
|
+
isMissingData: this._isMissingData,
|
|
320
|
+
isPromiseCached: false,
|
|
321
|
+
pendingOperations,
|
|
322
|
+
});
|
|
303
323
|
throw promise;
|
|
304
324
|
}
|
|
305
325
|
}
|
|
@@ -322,7 +342,7 @@ class SelectorResolver {
|
|
|
322
342
|
}
|
|
323
343
|
this.dispose();
|
|
324
344
|
const snapshot = this._environment.lookup(selector);
|
|
325
|
-
this._data = snapshot.data;
|
|
345
|
+
this._data = recycleNodesInto(this._data, snapshot.data);
|
|
326
346
|
this._isMissingData = snapshot.isMissingData;
|
|
327
347
|
this._missingRequiredFields = snapshot.missingRequiredFields;
|
|
328
348
|
this._selector = selector;
|
|
@@ -375,11 +395,13 @@ class SelectorListResolver {
|
|
|
375
395
|
_resolvers: Array<SelectorResolver>;
|
|
376
396
|
_rootIsQueryRenderer: boolean;
|
|
377
397
|
_stale: boolean;
|
|
398
|
+
_subscribeOnConstruction: boolean;
|
|
378
399
|
|
|
379
400
|
constructor(
|
|
380
401
|
environment: IEnvironment,
|
|
381
402
|
rootIsQueryRenderer: boolean,
|
|
382
403
|
selector: PluralReaderSelector,
|
|
404
|
+
subscribeOnConstruction: boolean,
|
|
383
405
|
callback: () => void,
|
|
384
406
|
) {
|
|
385
407
|
this._callback = callback;
|
|
@@ -388,6 +410,7 @@ class SelectorListResolver {
|
|
|
388
410
|
this._resolvers = [];
|
|
389
411
|
this._stale = true;
|
|
390
412
|
this._rootIsQueryRenderer = rootIsQueryRenderer;
|
|
413
|
+
this._subscribeOnConstruction = subscribeOnConstruction;
|
|
391
414
|
|
|
392
415
|
this.setSelector(selector);
|
|
393
416
|
}
|
|
@@ -433,6 +456,7 @@ class SelectorListResolver {
|
|
|
433
456
|
this._environment,
|
|
434
457
|
this._rootIsQueryRenderer,
|
|
435
458
|
selectors[ii],
|
|
459
|
+
this._subscribeOnConstruction,
|
|
436
460
|
this._onChange,
|
|
437
461
|
);
|
|
438
462
|
}
|
|
@@ -12,9 +12,18 @@
|
|
|
12
12
|
|
|
13
13
|
'use strict';
|
|
14
14
|
|
|
15
|
+
import type {ConcreteRequest} from '../util/RelayConcreteNode';
|
|
16
|
+
import type {
|
|
17
|
+
CacheConfig,
|
|
18
|
+
DataID,
|
|
19
|
+
OperationType,
|
|
20
|
+
Variables,
|
|
21
|
+
VariablesOf,
|
|
22
|
+
} from '../util/RelayRuntimeTypes';
|
|
23
|
+
import type {OperationDescriptor, RequestDescriptor} from './RelayStoreTypes';
|
|
24
|
+
|
|
15
25
|
const deepFreeze = require('../util/deepFreeze');
|
|
16
26
|
const getRequestIdentifier = require('../util/getRequestIdentifier');
|
|
17
|
-
|
|
18
27
|
const {getOperationVariables} = require('./RelayConcreteVariables');
|
|
19
28
|
const {
|
|
20
29
|
createNormalizationSelector,
|
|
@@ -22,19 +31,15 @@ const {
|
|
|
22
31
|
} = require('./RelayModernSelector');
|
|
23
32
|
const {ROOT_ID} = require('./RelayStoreUtils');
|
|
24
33
|
|
|
25
|
-
import type {ConcreteRequest} from '../util/RelayConcreteNode';
|
|
26
|
-
import type {CacheConfig, DataID, Variables} from '../util/RelayRuntimeTypes';
|
|
27
|
-
import type {OperationDescriptor, RequestDescriptor} from './RelayStoreTypes';
|
|
28
|
-
|
|
29
34
|
/**
|
|
30
35
|
* Creates an instance of the `OperationDescriptor` type defined in
|
|
31
36
|
* `RelayStoreTypes` given an operation and some variables. The input variables
|
|
32
37
|
* are filtered to exclude variables that do not match defined arguments on the
|
|
33
38
|
* operation, and default values are populated for null values.
|
|
34
39
|
*/
|
|
35
|
-
function createOperationDescriptor(
|
|
40
|
+
function createOperationDescriptor<TQuery: OperationType>(
|
|
36
41
|
request: ConcreteRequest,
|
|
37
|
-
variables:
|
|
42
|
+
variables: VariablesOf<TQuery>,
|
|
38
43
|
cacheConfig?: ?CacheConfig,
|
|
39
44
|
dataID?: DataID = ROOT_ID,
|
|
40
45
|
): OperationDescriptor {
|
|
@@ -12,23 +12,24 @@
|
|
|
12
12
|
|
|
13
13
|
'use strict';
|
|
14
14
|
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
const warning = require('warning');
|
|
15
|
+
import type {ActorIdentifier} from '../multi-actor-environment/ActorIdentifier';
|
|
16
|
+
import type {DataID} from '../util/RelayRuntimeTypes';
|
|
17
|
+
import type {Record} from './RelayStoreTypes';
|
|
19
18
|
|
|
19
|
+
const deepFreeze = require('../util/deepFreeze');
|
|
20
20
|
const {isClientID} = require('./ClientID');
|
|
21
21
|
const {
|
|
22
|
+
ACTOR_IDENTIFIER_KEY,
|
|
22
23
|
ID_KEY,
|
|
24
|
+
INVALIDATED_AT_KEY,
|
|
23
25
|
REF_KEY,
|
|
24
26
|
REFS_KEY,
|
|
25
|
-
TYPENAME_KEY,
|
|
26
|
-
INVALIDATED_AT_KEY,
|
|
27
27
|
ROOT_ID,
|
|
28
|
+
TYPENAME_KEY,
|
|
28
29
|
} = require('./RelayStoreUtils');
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
30
|
+
const areEqual = require('areEqual');
|
|
31
|
+
const invariant = require('invariant');
|
|
32
|
+
const warning = require('warning');
|
|
32
33
|
|
|
33
34
|
/**
|
|
34
35
|
* @public
|
|
@@ -172,10 +173,14 @@ function getLinkedRecordID(record: Record, storageKey: string): ?DataID {
|
|
|
172
173
|
invariant(
|
|
173
174
|
typeof link === 'object' && link && typeof link[REF_KEY] === 'string',
|
|
174
175
|
'RelayModernRecord.getLinkedRecordID(): Expected `%s.%s` to be a linked ID, ' +
|
|
175
|
-
'was `%s
|
|
176
|
+
'was `%s`.%s',
|
|
176
177
|
record[ID_KEY],
|
|
177
178
|
storageKey,
|
|
178
179
|
JSON.stringify(link),
|
|
180
|
+
typeof link === 'object' && link[REFS_KEY] !== undefined
|
|
181
|
+
? ' It appears to be a plural linked record: did you mean to call ' +
|
|
182
|
+
'getLinkedRecords() instead of getLinkedRecord()?'
|
|
183
|
+
: '',
|
|
179
184
|
);
|
|
180
185
|
return link[REF_KEY];
|
|
181
186
|
}
|
|
@@ -197,10 +202,14 @@ function getLinkedRecordIDs(
|
|
|
197
202
|
invariant(
|
|
198
203
|
typeof links === 'object' && Array.isArray(links[REFS_KEY]),
|
|
199
204
|
'RelayModernRecord.getLinkedRecordIDs(): Expected `%s.%s` to contain an array ' +
|
|
200
|
-
'of linked IDs, got `%s
|
|
205
|
+
'of linked IDs, got `%s`.%s',
|
|
201
206
|
record[ID_KEY],
|
|
202
207
|
storageKey,
|
|
203
208
|
JSON.stringify(links),
|
|
209
|
+
typeof links === 'object' && links[REF_KEY] !== undefined
|
|
210
|
+
? ' It appears to be a singular linked record: did you mean to call ' +
|
|
211
|
+
'getLinkedRecord() instead of getLinkedRecords()?'
|
|
212
|
+
: '',
|
|
204
213
|
);
|
|
205
214
|
// assume items of the array are ids
|
|
206
215
|
return (links[REFS_KEY]: any);
|
|
@@ -384,6 +393,51 @@ function setLinkedRecordIDs(
|
|
|
384
393
|
record[storageKey] = links;
|
|
385
394
|
}
|
|
386
395
|
|
|
396
|
+
/**
|
|
397
|
+
* @public
|
|
398
|
+
*
|
|
399
|
+
* Set the value of a field to a reference to another record in the actor specific store.
|
|
400
|
+
*/
|
|
401
|
+
function setActorLinkedRecordID(
|
|
402
|
+
record: Record,
|
|
403
|
+
storageKey: string,
|
|
404
|
+
actorIdentifier: ActorIdentifier,
|
|
405
|
+
linkedID: DataID,
|
|
406
|
+
): void {
|
|
407
|
+
// See perf note above for why we aren't using computed property access.
|
|
408
|
+
const link = {};
|
|
409
|
+
link[REF_KEY] = linkedID;
|
|
410
|
+
link[ACTOR_IDENTIFIER_KEY] = actorIdentifier;
|
|
411
|
+
record[storageKey] = link;
|
|
412
|
+
}
|
|
413
|
+
|
|
414
|
+
/**
|
|
415
|
+
* @public
|
|
416
|
+
*
|
|
417
|
+
* Get link to a record and the actor identifier for the store.
|
|
418
|
+
*/
|
|
419
|
+
function getActorLinkedRecordID(
|
|
420
|
+
record: Record,
|
|
421
|
+
storageKey: string,
|
|
422
|
+
): ?[ActorIdentifier, DataID] {
|
|
423
|
+
const link = record[storageKey];
|
|
424
|
+
if (link == null) {
|
|
425
|
+
return link;
|
|
426
|
+
}
|
|
427
|
+
invariant(
|
|
428
|
+
typeof link === 'object' &&
|
|
429
|
+
typeof link[REF_KEY] === 'string' &&
|
|
430
|
+
link[ACTOR_IDENTIFIER_KEY] != null,
|
|
431
|
+
'RelayModernRecord.getActorLinkedRecordID(): Expected `%s.%s` to be an actor specific linked ID, ' +
|
|
432
|
+
'was `%s`.',
|
|
433
|
+
record[ID_KEY],
|
|
434
|
+
storageKey,
|
|
435
|
+
JSON.stringify(link),
|
|
436
|
+
);
|
|
437
|
+
|
|
438
|
+
return [(link[ACTOR_IDENTIFIER_KEY]: any), (link[REF_KEY]: any)];
|
|
439
|
+
}
|
|
440
|
+
|
|
387
441
|
module.exports = {
|
|
388
442
|
clone,
|
|
389
443
|
copyFields,
|
|
@@ -400,4 +454,6 @@ module.exports = {
|
|
|
400
454
|
setLinkedRecordID,
|
|
401
455
|
setLinkedRecordIDs,
|
|
402
456
|
update,
|
|
457
|
+
getActorLinkedRecordID,
|
|
458
|
+
setActorLinkedRecordID,
|
|
403
459
|
};
|
|
@@ -12,22 +12,11 @@
|
|
|
12
12
|
|
|
13
13
|
'use strict';
|
|
14
14
|
|
|
15
|
-
const areEqual = require('areEqual');
|
|
16
|
-
const invariant = require('invariant');
|
|
17
|
-
const warning = require('warning');
|
|
18
|
-
|
|
19
|
-
const {getFragmentVariables} = require('./RelayConcreteVariables');
|
|
20
|
-
const {
|
|
21
|
-
FRAGMENT_OWNER_KEY,
|
|
22
|
-
FRAGMENTS_KEY,
|
|
23
|
-
ID_KEY,
|
|
24
|
-
IS_WITHIN_UNMATCHED_TYPE_REFINEMENT,
|
|
25
|
-
} = require('./RelayStoreUtils');
|
|
26
|
-
|
|
27
15
|
import type {NormalizationSelectableNode} from '../util/NormalizationNode';
|
|
28
16
|
import type {ReaderFragment} from '../util/ReaderNode';
|
|
29
17
|
import type {DataID, Variables} from '../util/RelayRuntimeTypes';
|
|
30
18
|
import type {
|
|
19
|
+
ClientEdgeTraversalPath,
|
|
31
20
|
NormalizationSelector,
|
|
32
21
|
PluralReaderSelector,
|
|
33
22
|
ReaderSelector,
|
|
@@ -35,6 +24,18 @@ import type {
|
|
|
35
24
|
SingularReaderSelector,
|
|
36
25
|
} from './RelayStoreTypes';
|
|
37
26
|
|
|
27
|
+
const {getFragmentVariables} = require('./RelayConcreteVariables');
|
|
28
|
+
const {
|
|
29
|
+
CLIENT_EDGE_TRAVERSAL_PATH,
|
|
30
|
+
FRAGMENT_OWNER_KEY,
|
|
31
|
+
FRAGMENTS_KEY,
|
|
32
|
+
ID_KEY,
|
|
33
|
+
IS_WITHIN_UNMATCHED_TYPE_REFINEMENT,
|
|
34
|
+
} = require('./RelayStoreUtils');
|
|
35
|
+
const areEqual = require('areEqual');
|
|
36
|
+
const invariant = require('invariant');
|
|
37
|
+
const warning = require('warning');
|
|
38
|
+
|
|
38
39
|
/**
|
|
39
40
|
* @public
|
|
40
41
|
*
|
|
@@ -80,6 +81,7 @@ function getSingularSelector(
|
|
|
80
81
|
const mixedOwner = item[FRAGMENT_OWNER_KEY];
|
|
81
82
|
const isWithinUnmatchedTypeRefinement =
|
|
82
83
|
item[IS_WITHIN_UNMATCHED_TYPE_REFINEMENT] === true;
|
|
84
|
+
const mixedClientEdgeTraversalPath = item[CLIENT_EDGE_TRAVERSAL_PATH];
|
|
83
85
|
if (
|
|
84
86
|
typeof dataID === 'string' &&
|
|
85
87
|
typeof fragments === 'object' &&
|
|
@@ -87,22 +89,28 @@ function getSingularSelector(
|
|
|
87
89
|
typeof fragments[fragment.name] === 'object' &&
|
|
88
90
|
fragments[fragment.name] !== null &&
|
|
89
91
|
typeof mixedOwner === 'object' &&
|
|
90
|
-
mixedOwner !== null
|
|
92
|
+
mixedOwner !== null &&
|
|
93
|
+
(mixedClientEdgeTraversalPath == null ||
|
|
94
|
+
Array.isArray(mixedClientEdgeTraversalPath))
|
|
91
95
|
) {
|
|
92
96
|
const owner: RequestDescriptor = (mixedOwner: $FlowFixMe);
|
|
93
|
-
const
|
|
97
|
+
const clientEdgeTraversalPath: ?ClientEdgeTraversalPath =
|
|
98
|
+
(mixedClientEdgeTraversalPath: $FlowFixMe);
|
|
94
99
|
|
|
100
|
+
const argumentVariables = fragments[fragment.name];
|
|
95
101
|
const fragmentVariables = getFragmentVariables(
|
|
96
102
|
fragment,
|
|
97
103
|
owner.variables,
|
|
98
104
|
argumentVariables,
|
|
99
105
|
);
|
|
106
|
+
|
|
100
107
|
return createReaderSelector(
|
|
101
108
|
fragment,
|
|
102
109
|
dataID,
|
|
103
110
|
fragmentVariables,
|
|
104
111
|
owner,
|
|
105
112
|
isWithinUnmatchedTypeRefinement,
|
|
113
|
+
clientEdgeTraversalPath,
|
|
106
114
|
);
|
|
107
115
|
}
|
|
108
116
|
|
|
@@ -419,11 +427,13 @@ function createReaderSelector(
|
|
|
419
427
|
variables: Variables,
|
|
420
428
|
request: RequestDescriptor,
|
|
421
429
|
isWithinUnmatchedTypeRefinement: boolean = false,
|
|
430
|
+
clientEdgeTraversalPath: ?ClientEdgeTraversalPath,
|
|
422
431
|
): SingularReaderSelector {
|
|
423
432
|
return {
|
|
424
433
|
kind: 'SingularReaderSelector',
|
|
425
434
|
dataID,
|
|
426
435
|
isWithinUnmatchedTypeRefinement,
|
|
436
|
+
clientEdgeTraversalPath: clientEdgeTraversalPath ?? null,
|
|
427
437
|
node: fragment,
|
|
428
438
|
variables,
|
|
429
439
|
owner: request,
|
|
@@ -12,30 +12,13 @@
|
|
|
12
12
|
|
|
13
13
|
'use strict';
|
|
14
14
|
|
|
15
|
-
|
|
16
|
-
const RelayFeatureFlags = require('../util/RelayFeatureFlags');
|
|
17
|
-
const RelayModernRecord = require('./RelayModernRecord');
|
|
18
|
-
const RelayOptimisticRecordSource = require('./RelayOptimisticRecordSource');
|
|
19
|
-
const RelayProfiler = require('../util/RelayProfiler');
|
|
20
|
-
const RelayReader = require('./RelayReader');
|
|
21
|
-
const RelayReferenceMarker = require('./RelayReferenceMarker');
|
|
22
|
-
const RelayStoreReactFlightUtils = require('./RelayStoreReactFlightUtils');
|
|
23
|
-
const RelayStoreSubscriptions = require('./RelayStoreSubscriptions');
|
|
24
|
-
const RelayStoreSubscriptionsUsingMapByID = require('./RelayStoreSubscriptionsUsingMapByID');
|
|
25
|
-
const RelayStoreUtils = require('./RelayStoreUtils');
|
|
26
|
-
|
|
27
|
-
const deepFreeze = require('../util/deepFreeze');
|
|
28
|
-
const defaultGetDataID = require('./defaultGetDataID');
|
|
29
|
-
const invariant = require('invariant');
|
|
30
|
-
const resolveImmediate = require('../util/resolveImmediate');
|
|
31
|
-
|
|
32
|
-
const {ROOT_ID, ROOT_TYPE} = require('./RelayStoreUtils');
|
|
33
|
-
|
|
15
|
+
import type {ActorIdentifier} from '../multi-actor-environment/ActorIdentifier';
|
|
34
16
|
import type {DataID, Disposable} from '../util/RelayRuntimeTypes';
|
|
35
17
|
import type {Availability} from './DataChecker';
|
|
36
18
|
import type {GetDataID} from './RelayResponseNormalizer';
|
|
37
19
|
import type {
|
|
38
20
|
CheckOptions,
|
|
21
|
+
DataIDSet,
|
|
39
22
|
LogFunction,
|
|
40
23
|
MutableRecordSource,
|
|
41
24
|
OperationAvailability,
|
|
@@ -48,8 +31,28 @@ import type {
|
|
|
48
31
|
Snapshot,
|
|
49
32
|
Store,
|
|
50
33
|
StoreSubscriptions,
|
|
51
|
-
DataIDSet,
|
|
52
34
|
} from './RelayStoreTypes';
|
|
35
|
+
import type {ResolverCache} from './ResolverCache';
|
|
36
|
+
|
|
37
|
+
const {
|
|
38
|
+
INTERNAL_ACTOR_IDENTIFIER_DO_NOT_USE,
|
|
39
|
+
assertInternalActorIndentifier,
|
|
40
|
+
} = require('../multi-actor-environment/ActorIdentifier');
|
|
41
|
+
const deepFreeze = require('../util/deepFreeze');
|
|
42
|
+
const RelayFeatureFlags = require('../util/RelayFeatureFlags');
|
|
43
|
+
const resolveImmediate = require('../util/resolveImmediate');
|
|
44
|
+
const DataChecker = require('./DataChecker');
|
|
45
|
+
const defaultGetDataID = require('./defaultGetDataID');
|
|
46
|
+
const RelayModernRecord = require('./RelayModernRecord');
|
|
47
|
+
const RelayOptimisticRecordSource = require('./RelayOptimisticRecordSource');
|
|
48
|
+
const RelayReader = require('./RelayReader');
|
|
49
|
+
const RelayReferenceMarker = require('./RelayReferenceMarker');
|
|
50
|
+
const RelayStoreReactFlightUtils = require('./RelayStoreReactFlightUtils');
|
|
51
|
+
const RelayStoreSubscriptions = require('./RelayStoreSubscriptions');
|
|
52
|
+
const RelayStoreUtils = require('./RelayStoreUtils');
|
|
53
|
+
const {ROOT_ID, ROOT_TYPE} = require('./RelayStoreUtils');
|
|
54
|
+
const {RecordResolverCache} = require('./ResolverCache');
|
|
55
|
+
const invariant = require('invariant');
|
|
53
56
|
|
|
54
57
|
export opaque type InvalidationState = {|
|
|
55
58
|
dataIDs: $ReadOnlyArray<DataID>,
|
|
@@ -90,6 +93,7 @@ class RelayModernStore implements Store {
|
|
|
90
93
|
_operationLoader: ?OperationLoader;
|
|
91
94
|
_optimisticSource: ?MutableRecordSource;
|
|
92
95
|
_recordSource: MutableRecordSource;
|
|
96
|
+
_resolverCache: ResolverCache;
|
|
93
97
|
_releaseBuffer: Array<string>;
|
|
94
98
|
_roots: Map<
|
|
95
99
|
string,
|
|
@@ -145,10 +149,13 @@ class RelayModernStore implements Store {
|
|
|
145
149
|
this._releaseBuffer = [];
|
|
146
150
|
this._roots = new Map();
|
|
147
151
|
this._shouldScheduleGC = false;
|
|
148
|
-
this.
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
+
this._resolverCache = new RecordResolverCache(() =>
|
|
153
|
+
this._getMutableRecordSource(),
|
|
154
|
+
);
|
|
155
|
+
this._storeSubscriptions = new RelayStoreSubscriptions(
|
|
156
|
+
options?.log,
|
|
157
|
+
this._resolverCache,
|
|
158
|
+
);
|
|
152
159
|
this._updatedRecordIDs = new Set();
|
|
153
160
|
this._shouldProcessClientComponents =
|
|
154
161
|
options?.shouldProcessClientComponents;
|
|
@@ -160,12 +167,16 @@ class RelayModernStore implements Store {
|
|
|
160
167
|
return this._optimisticSource ?? this._recordSource;
|
|
161
168
|
}
|
|
162
169
|
|
|
170
|
+
_getMutableRecordSource(): MutableRecordSource {
|
|
171
|
+
return this._optimisticSource ?? this._recordSource;
|
|
172
|
+
}
|
|
173
|
+
|
|
163
174
|
check(
|
|
164
175
|
operation: OperationDescriptor,
|
|
165
176
|
options?: CheckOptions,
|
|
166
177
|
): OperationAvailability {
|
|
167
178
|
const selector = operation.root;
|
|
168
|
-
const source = this.
|
|
179
|
+
const source = this._getMutableRecordSource();
|
|
169
180
|
const globalInvalidationEpoch = this._globalInvalidationEpoch;
|
|
170
181
|
|
|
171
182
|
const rootEntry = this._roots.get(operation.request.identifier);
|
|
@@ -174,7 +185,7 @@ class RelayModernStore implements Store {
|
|
|
174
185
|
// Check if store has been globally invalidated
|
|
175
186
|
if (globalInvalidationEpoch != null) {
|
|
176
187
|
// If so, check if the operation we're checking was last written
|
|
177
|
-
// before or after invalidation
|
|
188
|
+
// before or after invalidation occurred.
|
|
178
189
|
if (
|
|
179
190
|
operationLastWrittenAt == null ||
|
|
180
191
|
operationLastWrittenAt <= globalInvalidationEpoch
|
|
@@ -187,11 +198,24 @@ class RelayModernStore implements Store {
|
|
|
187
198
|
}
|
|
188
199
|
}
|
|
189
200
|
|
|
190
|
-
const target = options?.target ?? source;
|
|
191
201
|
const handlers = options?.handlers ?? [];
|
|
202
|
+
const getSourceForActor =
|
|
203
|
+
options?.getSourceForActor ??
|
|
204
|
+
(actorIdentifier => {
|
|
205
|
+
assertInternalActorIndentifier(actorIdentifier);
|
|
206
|
+
return source;
|
|
207
|
+
});
|
|
208
|
+
const getTargetForActor =
|
|
209
|
+
options?.getTargetForActor ??
|
|
210
|
+
(actorIdentifier => {
|
|
211
|
+
assertInternalActorIndentifier(actorIdentifier);
|
|
212
|
+
return source;
|
|
213
|
+
});
|
|
214
|
+
|
|
192
215
|
const operationAvailability = DataChecker.check(
|
|
193
|
-
|
|
194
|
-
|
|
216
|
+
getSourceForActor,
|
|
217
|
+
getTargetForActor,
|
|
218
|
+
options?.defaultActorIdentifier ?? INTERNAL_ACTOR_IDENTIFIER_DO_NOT_USE,
|
|
195
219
|
selector,
|
|
196
220
|
handlers,
|
|
197
221
|
this._operationLoader,
|
|
@@ -275,7 +299,7 @@ class RelayModernStore implements Store {
|
|
|
275
299
|
|
|
276
300
|
lookup(selector: SingularReaderSelector): Snapshot {
|
|
277
301
|
const source = this.getSource();
|
|
278
|
-
const snapshot = RelayReader.read(source, selector);
|
|
302
|
+
const snapshot = RelayReader.read(source, selector, this._resolverCache);
|
|
279
303
|
if (__DEV__) {
|
|
280
304
|
deepFreeze(snapshot);
|
|
281
305
|
}
|
|
@@ -303,6 +327,13 @@ class RelayModernStore implements Store {
|
|
|
303
327
|
this._globalInvalidationEpoch = this._currentWriteEpoch;
|
|
304
328
|
}
|
|
305
329
|
|
|
330
|
+
if (RelayFeatureFlags.ENABLE_RELAY_RESOLVERS) {
|
|
331
|
+
// When a record is updated, we need to also handle records that depend on it,
|
|
332
|
+
// specifically Relay Resolver result records containing results based on the
|
|
333
|
+
// updated records. This both adds to updatedRecordIDs and invalidates any
|
|
334
|
+
// cached data as needed.
|
|
335
|
+
this._resolverCache.invalidateDataIDs(this._updatedRecordIDs);
|
|
336
|
+
}
|
|
306
337
|
const source = this.getSource();
|
|
307
338
|
const updatedOwners = [];
|
|
308
339
|
this._storeSubscriptions.updateSubscriptions(
|
|
@@ -365,7 +396,7 @@ class RelayModernStore implements Store {
|
|
|
365
396
|
}
|
|
366
397
|
|
|
367
398
|
publish(source: RecordSource, idsMarkedForInvalidation?: DataIDSet): void {
|
|
368
|
-
const target = this.
|
|
399
|
+
const target = this._getMutableRecordSource();
|
|
369
400
|
updateTargetFromSource(
|
|
370
401
|
target,
|
|
371
402
|
source,
|
|
@@ -418,6 +449,10 @@ class RelayModernStore implements Store {
|
|
|
418
449
|
return 'RelayModernStore()';
|
|
419
450
|
}
|
|
420
451
|
|
|
452
|
+
getEpoch(): number {
|
|
453
|
+
return this._currentWriteEpoch;
|
|
454
|
+
}
|
|
455
|
+
|
|
421
456
|
// Internal API
|
|
422
457
|
__getUpdatedRecordIDs(): DataIDSet {
|
|
423
458
|
return this._updatedRecordIDs;
|
|
@@ -678,7 +713,6 @@ function updateTargetFromSource(
|
|
|
678
713
|
currentWriteEpoch,
|
|
679
714
|
);
|
|
680
715
|
invalidatedRecordIDs.add(dataID);
|
|
681
|
-
// $FlowFixMe[incompatible-call]
|
|
682
716
|
target.set(dataID, nextRecord);
|
|
683
717
|
});
|
|
684
718
|
}
|
|
@@ -770,8 +804,4 @@ function getAvailabilityStatus(
|
|
|
770
804
|
return {status: 'available', fetchTime: operationFetchTime ?? null};
|
|
771
805
|
}
|
|
772
806
|
|
|
773
|
-
RelayProfiler.instrumentMethods(RelayModernStore.prototype, {
|
|
774
|
-
lookup: 'RelayModernStore.prototype.lookup',
|
|
775
|
-
});
|
|
776
|
-
|
|
777
807
|
module.exports = RelayModernStore;
|