relay-runtime 20.1.0 → 21.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/experimental.js +1 -1
- package/experimental.js.flow +8 -8
- package/handlers/connection/ConnectionHandler.js.flow +5 -5
- package/handlers/connection/ConnectionInterface.js.flow +1 -1
- package/index.js +1 -1
- package/index.js.flow +125 -62
- package/lib/experimental.js +3 -3
- package/lib/index.js +105 -57
- package/lib/multi-actor-environment/ActorIdentifier.js +2 -2
- package/lib/multi-actor-environment/MultiActorEnvironment.js +3 -1
- package/lib/mutations/commitMutation.js +8 -8
- package/lib/mutations/validateMutation.js +4 -4
- package/lib/query/GraphQLTag.js +3 -3
- package/lib/query/fetchQuery.js +15 -3
- package/lib/store/DataChecker.js +38 -4
- package/lib/store/NormalizationEngine.js +373 -0
- package/lib/store/OperationExecutor.js +172 -113
- package/lib/store/RelayConcreteVariables.js +1 -1
- package/lib/store/RelayErrorTrie.js +2 -2
- package/lib/store/RelayExperimentalGraphResponseTransform.js +8 -8
- package/lib/store/RelayModernEnvironment.js +26 -19
- package/lib/store/RelayModernRecord.js +18 -8
- package/lib/store/RelayModernSelector.js +9 -9
- package/lib/store/RelayModernStore.js +152 -43
- package/lib/store/RelayPublishQueue.js +1 -1
- package/lib/store/RelayReader.js +76 -38
- package/lib/store/RelayRecordSource.js +6 -0
- package/lib/store/RelayReferenceMarker.js +2 -1
- package/lib/store/RelayResponseNormalizer.js +88 -55
- package/lib/store/RelayStoreSubscriptions.js +34 -10
- package/lib/store/RelayStoreUtils.js +8 -1
- package/lib/store/ResolverFragments.js +2 -2
- package/lib/store/live-resolvers/LiveResolverCache.js +25 -9
- package/lib/store/observeFragmentExperimental.js +17 -1
- package/lib/store/observeQueryExperimental.js +2 -2
- package/lib/subscription/requestSubscription.js +3 -3
- package/lib/util/RelayError.js +3 -0
- package/lib/util/RelayFeatureFlags.js +6 -2
- package/lib/util/RelayReplaySubject.js +4 -4
- package/lib/util/handlePotentialSnapshotErrors.js +2 -2
- package/lib/util/stableCopy.js +2 -2
- package/llm-docs/api-reference/entrypoint-apis/entrypoint-container.mdx +38 -0
- package/llm-docs/api-reference/entrypoint-apis/load-entrypoint.mdx +77 -0
- package/llm-docs/api-reference/entrypoint-apis/use-entrypoint-loader.mdx +99 -0
- package/llm-docs/api-reference/graphql/graphql-directives.mdx +378 -0
- package/llm-docs/api-reference/hooks/_use-lazy-load-query-extra.mdx +16 -0
- package/llm-docs/api-reference/hooks/load-query.mdx +84 -0
- package/llm-docs/api-reference/hooks/relay-environment-provider.mdx +78 -0
- package/llm-docs/api-reference/hooks/use-client-query.mdx +65 -0
- package/llm-docs/api-reference/hooks/use-fragment.mdx +69 -0
- package/llm-docs/api-reference/hooks/use-lazy-load-query.mdx +62 -0
- package/llm-docs/api-reference/hooks/use-mutation.mdx +94 -0
- package/llm-docs/api-reference/hooks/use-pagination-fragment.mdx +166 -0
- package/llm-docs/api-reference/hooks/use-prefetchable-forward-pagination-fragment.mdx +134 -0
- package/llm-docs/api-reference/hooks/use-preloaded-query.mdx +84 -0
- package/llm-docs/api-reference/hooks/use-query-loader.mdx +95 -0
- package/llm-docs/api-reference/hooks/use-refetchable-fragment.mdx +122 -0
- package/llm-docs/api-reference/hooks/use-relay-environment.mdx +37 -0
- package/llm-docs/api-reference/hooks/use-subscription.mdx +66 -0
- package/llm-docs/api-reference/relay-resolvers/docblock-format.mdx +321 -0
- package/llm-docs/api-reference/relay-resolvers/runtime-functions.mdx +94 -0
- package/llm-docs/api-reference/relay-runtime/commit-mutation.mdx +65 -0
- package/llm-docs/api-reference/relay-runtime/fetch-query.mdx +113 -0
- package/llm-docs/api-reference/relay-runtime/field-logger.mdx +170 -0
- package/llm-docs/api-reference/relay-runtime/observe-fragment.mdx +92 -0
- package/llm-docs/api-reference/relay-runtime/relay-environment.mdx +53 -0
- package/llm-docs/api-reference/relay-runtime/request-subscription.mdx +54 -0
- package/llm-docs/api-reference/relay-runtime/runtime-configuration.mdx +52 -0
- package/llm-docs/api-reference/relay-runtime/store.mdx +734 -0
- package/llm-docs/api-reference/relay-runtime/wait-for-fragment-data.mdx +89 -0
- package/llm-docs/api-reference/types/CacheConfig.mdx +8 -0
- package/llm-docs/api-reference/types/Disposable.mdx +4 -0
- package/llm-docs/api-reference/types/GraphQLSubscriptionConfig.mdx +17 -0
- package/llm-docs/api-reference/types/MutationConfig.mdx +31 -0
- package/llm-docs/api-reference/types/SelectorStoreUpdater.mdx +6 -0
- package/llm-docs/api-reference/types/UploadableMap.mdx +3 -0
- package/llm-docs/community/learning-resources.mdx +64 -0
- package/llm-docs/debugging/declarative-mutation-directives.mdx +34 -0
- package/llm-docs/debugging/disallowed-id-types-error.mdx +43 -0
- package/llm-docs/debugging/inconsistent-typename-error.mdx +47 -0
- package/llm-docs/debugging/relay-devtools.mdx +73 -0
- package/llm-docs/debugging/why-null.mdx +116 -0
- package/llm-docs/editor-support.mdx +55 -0
- package/llm-docs/error-reference/unknown-field.mdx +36 -0
- package/llm-docs/getting-started/babel-plugin.mdx +31 -0
- package/llm-docs/getting-started/compiler-config.mdx +25 -0
- package/llm-docs/getting-started/compiler.mdx +82 -0
- package/llm-docs/getting-started/lint-rules.mdx +87 -0
- package/llm-docs/getting-started/production.mdx +30 -0
- package/llm-docs/getting-started/quick-start.mdx +213 -0
- package/llm-docs/glossary/glossary.mdx +1040 -0
- package/llm-docs/guided-tour/list-data/advanced-pagination.mdx +157 -0
- package/llm-docs/guided-tour/list-data/connections.mdx +81 -0
- package/llm-docs/guided-tour/list-data/pagination.mdx +193 -0
- package/llm-docs/guided-tour/list-data/rendering-connections.mdx +112 -0
- package/llm-docs/guided-tour/list-data/streaming-pagination.mdx +87 -0
- package/llm-docs/guided-tour/managing-data-outside-react/retaining-queries.mdx +51 -0
- package/llm-docs/guided-tour/refetching/refetching-queries-with-different-data.mdx +337 -0
- package/llm-docs/guided-tour/refetching/refreshing-queries.mdx +350 -0
- package/llm-docs/guided-tour/rendering/environment.mdx +59 -0
- package/llm-docs/guided-tour/rendering/error-states.mdx +295 -0
- package/llm-docs/guided-tour/rendering/fragments.mdx +354 -0
- package/llm-docs/guided-tour/rendering/loading-states.mdx +245 -0
- package/llm-docs/guided-tour/rendering/queries.mdx +261 -0
- package/llm-docs/guided-tour/rendering/variables.mdx +233 -0
- package/llm-docs/guided-tour/reusing-cached-data/fetch-policies.mdx +56 -0
- package/llm-docs/guided-tour/reusing-cached-data/filling-in-missing-data.mdx +102 -0
- package/llm-docs/guided-tour/reusing-cached-data/introduction.mdx +22 -0
- package/llm-docs/guided-tour/reusing-cached-data/presence-of-data.mdx +93 -0
- package/llm-docs/guided-tour/reusing-cached-data/rendering-partially-cached-data.mdx +175 -0
- package/llm-docs/guided-tour/reusing-cached-data/staleness-of-data.mdx +116 -0
- package/llm-docs/guided-tour/updating-data/client-only-data.mdx +115 -0
- package/llm-docs/guided-tour/updating-data/graphql-mutations.mdx +334 -0
- package/llm-docs/guided-tour/updating-data/graphql-subscriptions.mdx +279 -0
- package/llm-docs/guided-tour/updating-data/imperatively-modifying-linked-fields.mdx +511 -0
- package/llm-docs/guided-tour/updating-data/imperatively-modifying-store-data-legacy.mdx +142 -0
- package/llm-docs/guided-tour/updating-data/imperatively-modifying-store-data.mdx +275 -0
- package/llm-docs/guided-tour/updating-data/introduction.mdx +25 -0
- package/llm-docs/guided-tour/updating-data/local-data-updates.mdx +71 -0
- package/llm-docs/guided-tour/updating-data/typesafe-updaters-faq.mdx +83 -0
- package/llm-docs/guided-tour/updating-data/updating-connections.mdx +592 -0
- package/llm-docs/guides/alias-directive.mdx +160 -0
- package/llm-docs/guides/catch-directive.mdx +167 -0
- package/llm-docs/guides/client-schema-extensions.mdx +208 -0
- package/llm-docs/guides/codemods.mdx +66 -0
- package/llm-docs/guides/data-driven-dependencies/client-3d.mdx +255 -0
- package/llm-docs/guides/data-driven-dependencies/configuration.mdx +127 -0
- package/llm-docs/guides/data-driven-dependencies/introduction.mdx +39 -0
- package/llm-docs/guides/data-driven-dependencies/server-3d.mdx +664 -0
- package/llm-docs/guides/document-comparison.mdx +106 -0
- package/llm-docs/guides/graphql-server-specification.mdx +453 -0
- package/llm-docs/guides/network-layer.mdx +69 -0
- package/llm-docs/guides/persisted-queries.mdx +328 -0
- package/llm-docs/guides/relay-resolvers/context.mdx +99 -0
- package/llm-docs/guides/relay-resolvers/defining-fields.mdx +151 -0
- package/llm-docs/guides/relay-resolvers/defining-types.mdx +164 -0
- package/llm-docs/guides/relay-resolvers/deprecated.mdx +27 -0
- package/llm-docs/guides/relay-resolvers/derived-fields.mdx +127 -0
- package/llm-docs/guides/relay-resolvers/descriptions.mdx +44 -0
- package/llm-docs/guides/relay-resolvers/enabling.mdx +41 -0
- package/llm-docs/guides/relay-resolvers/errors.mdx +64 -0
- package/llm-docs/guides/relay-resolvers/field-arguments.mdx +63 -0
- package/llm-docs/guides/relay-resolvers/introduction.mdx +62 -0
- package/llm-docs/guides/relay-resolvers/limitations.mdx +30 -0
- package/llm-docs/guides/relay-resolvers/live-fields.mdx +164 -0
- package/llm-docs/guides/relay-resolvers/return-types.mdx +161 -0
- package/llm-docs/guides/relay-resolvers/suspense.mdx +41 -0
- package/llm-docs/guides/required-directive.mdx +240 -0
- package/llm-docs/guides/semantic-nullability.mdx +93 -0
- package/llm-docs/guides/testing-relay-components.mdx +642 -0
- package/llm-docs/guides/testing-relay-with-preloaded-queries.mdx +160 -0
- package/llm-docs/guides/throw-on-field-error-directive.mdx +58 -0
- package/llm-docs/guides/type-emission.mdx +414 -0
- package/llm-docs/home.mdx +32 -0
- package/llm-docs/principles-and-architecture/architecture-overview.mdx +24 -0
- package/llm-docs/principles-and-architecture/compiler-architecture.mdx +106 -0
- package/llm-docs/principles-and-architecture/runtime-architecture.mdx +249 -0
- package/llm-docs/principles-and-architecture/thinking-in-graphql.mdx +309 -0
- package/llm-docs/principles-and-architecture/thinking-in-relay.mdx +104 -0
- package/llm-docs/principles-and-architecture/videos.mdx +50 -0
- package/llm-docs/tutorial/arrays-lists.mdx +126 -0
- package/llm-docs/tutorial/fragments-1.mdx +487 -0
- package/llm-docs/tutorial/graphql.mdx +172 -0
- package/llm-docs/tutorial/interfaces-polymorphism.mdx +161 -0
- package/llm-docs/tutorial/intro.mdx +58 -0
- package/llm-docs/tutorial/mutations-updates.mdx +624 -0
- package/llm-docs/tutorial/organizing-mutations-queries-and-subscriptions.mdx +13 -0
- package/llm-docs/tutorial/queries-1.mdx +267 -0
- package/llm-docs/tutorial/queries-2.mdx +389 -0
- package/llm-docs/tutorial/refetchable-fragments.mdx +352 -0
- package/multi-actor-environment/ActorIdentifier.js.flow +2 -2
- package/multi-actor-environment/ActorSpecificEnvironment.js.flow +7 -7
- package/multi-actor-environment/ActorUtils.js.flow +1 -1
- package/multi-actor-environment/MultiActorEnvironment.js.flow +12 -8
- package/multi-actor-environment/MultiActorEnvironmentTypes.js.flow +3 -3
- package/mutations/RelayDeclarativeMutationConfig.js.flow +9 -9
- package/mutations/RelayRecordProxy.js.flow +8 -11
- package/mutations/RelayRecordSourceMutator.js.flow +4 -4
- package/mutations/RelayRecordSourceProxy.js.flow +4 -4
- package/mutations/RelayRecordSourceSelectorProxy.js.flow +6 -6
- package/mutations/applyOptimisticMutation.js.flow +2 -2
- package/mutations/commitMutation.js.flow +20 -16
- package/mutations/createUpdatableProxy.js.flow +19 -19
- package/mutations/readUpdatableFragment.js.flow +3 -3
- package/mutations/readUpdatableQuery.js.flow +3 -3
- package/mutations/validateMutation.js.flow +7 -7
- package/network/RelayNetworkTypes.js.flow +4 -4
- package/network/RelayObservable.js.flow +16 -14
- package/network/RelayQueryResponseCache.js.flow +3 -3
- package/network/wrapNetworkWithLogObserver.js.flow +1 -1
- package/package.json +2 -1
- package/query/GraphQLTag.js.flow +22 -10
- package/query/fetchQuery.js.flow +23 -10
- package/query/fetchQuery_DEPRECATED.js.flow +1 -1
- package/store/DataChecker.js.flow +43 -9
- package/store/NormalizationEngine.js.flow +779 -0
- package/store/OperationExecutor.js.flow +173 -70
- package/store/RelayConcreteVariables.js.flow +5 -5
- package/store/RelayErrorTrie.js.flow +12 -12
- package/store/RelayExperimentalGraphResponseHandler.js.flow +3 -3
- package/store/RelayExperimentalGraphResponseTransform.js.flow +10 -10
- package/store/RelayModernEnvironment.js.flow +41 -26
- package/store/RelayModernFragmentSpecResolver.js.flow +1 -1
- package/store/RelayModernOperationDescriptor.js.flow +1 -1
- package/store/RelayModernRecord.js.flow +46 -22
- package/store/RelayModernSelector.js.flow +21 -21
- package/store/RelayModernStore.js.flow +219 -58
- package/store/RelayOperationTracker.js.flow +2 -2
- package/store/RelayOptimisticRecordSource.js.flow +2 -2
- package/store/RelayPublishQueue.js.flow +21 -12
- package/store/RelayReader.js.flow +130 -58
- package/store/RelayRecordSource.js.flow +10 -0
- package/store/RelayRecordState.js.flow +1 -1
- package/store/RelayReferenceMarker.js.flow +5 -4
- package/store/RelayResponseNormalizer.js.flow +130 -54
- package/store/RelayStoreSubscriptions.js.flow +52 -8
- package/store/RelayStoreTypes.js.flow +153 -64
- package/store/RelayStoreUtils.js.flow +15 -7
- package/store/ResolverCache.js.flow +2 -2
- package/store/ResolverFragments.js.flow +12 -12
- package/store/StoreInspector.js.flow +6 -7
- package/store/cloneRelayHandleSourceField.js.flow +1 -1
- package/store/cloneRelayScalarHandleSourceField.js.flow +1 -1
- package/store/createRelayContext.js.flow +1 -1
- package/store/createRelayLoggingContext.js.flow +4 -4
- package/store/defaultGetDataID.js.flow +2 -2
- package/store/isRelayModernEnvironment.js.flow +4 -2
- package/store/live-resolvers/LiveResolverCache.js.flow +55 -20
- package/store/live-resolvers/LiveResolverSuspenseSentinel.js.flow +3 -3
- package/store/live-resolvers/getOutputTypeRecordIDs.js.flow +1 -1
- package/store/live-resolvers/isLiveStateValue.js.flow +2 -2
- package/store/live-resolvers/resolverDataInjector.js.flow +8 -5
- package/store/observeFragmentExperimental.js.flow +49 -20
- package/store/observeQueryExperimental.js.flow +5 -5
- package/store/readInlineData.js.flow +4 -4
- package/store/waitForFragmentExperimental.js.flow +3 -3
- package/subscription/requestSubscription.js.flow +7 -7
- package/util/NormalizationNode.js.flow +34 -32
- package/util/ReaderNode.js.flow +32 -30
- package/util/RelayConcreteNode.js.flow +5 -5
- package/util/RelayError.js.flow +4 -1
- package/util/RelayFeatureFlags.js.flow +21 -1
- package/util/RelayProfiler.js.flow +1 -1
- package/util/RelayReplaySubject.js.flow +3 -3
- package/util/RelayRuntimeTypes.js.flow +11 -11
- package/util/createPayloadFor3DField.js.flow +9 -5
- package/util/deepFreeze.js.flow +2 -2
- package/util/getFragmentIdentifier.js.flow +1 -1
- package/util/getPaginationMetadata.js.flow +1 -1
- package/util/getPaginationVariables.js.flow +1 -1
- package/util/getPendingOperationsForFragment.js.flow +2 -2
- package/util/getRefetchMetadata.js.flow +6 -5
- package/util/getValueAtPath.js.flow +3 -3
- package/util/handlePotentialSnapshotErrors.js.flow +5 -5
- package/util/isEmptyObject.js.flow +1 -1
- package/util/isPromise.js.flow +2 -2
- package/util/isScalarAndEqual.js.flow +1 -1
- package/util/recycleNodesInto.js.flow +2 -2
- package/util/registerEnvironmentWithDevTools.js.flow +1 -1
- package/util/shallowFreeze.js.flow +1 -1
- package/util/stableCopy.js.flow +5 -5
- package/util/withProvidedVariables.js.flow +14 -10
|
@@ -66,7 +66,7 @@ const warning = require('warning');
|
|
|
66
66
|
*/
|
|
67
67
|
function getSingularSelector(
|
|
68
68
|
fragment: ReaderFragment,
|
|
69
|
-
item:
|
|
69
|
+
item: unknown,
|
|
70
70
|
): ?SingularReaderSelector {
|
|
71
71
|
invariant(
|
|
72
72
|
typeof item === 'object' && item !== null && !Array.isArray(item),
|
|
@@ -90,9 +90,9 @@ function getSingularSelector(
|
|
|
90
90
|
(mixedClientEdgeTraversalPath == null ||
|
|
91
91
|
Array.isArray(mixedClientEdgeTraversalPath))
|
|
92
92
|
) {
|
|
93
|
-
const owner: RequestDescriptor =
|
|
93
|
+
const owner: RequestDescriptor = mixedOwner as $FlowFixMe;
|
|
94
94
|
const clientEdgeTraversalPath: ?ClientEdgeTraversalPath =
|
|
95
|
-
|
|
95
|
+
mixedClientEdgeTraversalPath as $FlowFixMe;
|
|
96
96
|
|
|
97
97
|
const argumentVariables = fragments[fragment.name];
|
|
98
98
|
const fragmentVariables = getFragmentVariables(
|
|
@@ -146,7 +146,7 @@ function getSingularSelector(
|
|
|
146
146
|
*/
|
|
147
147
|
function getPluralSelector(
|
|
148
148
|
fragment: ReaderFragment,
|
|
149
|
-
items:
|
|
149
|
+
items: ReadonlyArray<unknown>,
|
|
150
150
|
): ?PluralReaderSelector {
|
|
151
151
|
let selectors: null | Array<SingularReaderSelector> = null;
|
|
152
152
|
items.forEach((item, ii) => {
|
|
@@ -168,7 +168,7 @@ function getPluralSelector(
|
|
|
168
168
|
|
|
169
169
|
function getSelector(
|
|
170
170
|
fragment: ReaderFragment,
|
|
171
|
-
item:
|
|
171
|
+
item: unknown | Array<unknown>,
|
|
172
172
|
): ?ReaderSelector {
|
|
173
173
|
if (item == null) {
|
|
174
174
|
return item;
|
|
@@ -207,7 +207,7 @@ function getSelector(
|
|
|
207
207
|
*/
|
|
208
208
|
function getSelectorsFromObject(
|
|
209
209
|
fragments: {[key: string]: ReaderFragment, ...},
|
|
210
|
-
object: {[key: string]:
|
|
210
|
+
object: {[key: string]: unknown, ...},
|
|
211
211
|
): {[key: string]: ?ReaderSelector, ...} {
|
|
212
212
|
const selectors: {[string]: ?ReaderSelector} = {};
|
|
213
213
|
for (const key in fragments) {
|
|
@@ -231,7 +231,7 @@ function getSelectorsFromObject(
|
|
|
231
231
|
*/
|
|
232
232
|
function getDataIDsFromObject(
|
|
233
233
|
fragments: {[key: string]: ReaderFragment, ...},
|
|
234
|
-
object: {[key: string]:
|
|
234
|
+
object: {[key: string]: unknown, ...},
|
|
235
235
|
): {[key: string]: ?(DataID | Array<DataID>), ...} {
|
|
236
236
|
const ids: {[string]: ?(DataID | Array<DataID>)} = {};
|
|
237
237
|
for (const key in fragments) {
|
|
@@ -246,7 +246,7 @@ function getDataIDsFromObject(
|
|
|
246
246
|
|
|
247
247
|
function getDataIDsFromFragment(
|
|
248
248
|
fragment: ReaderFragment,
|
|
249
|
-
item:
|
|
249
|
+
item: unknown | Array<unknown>,
|
|
250
250
|
): ?DataID | ?Array<DataID> {
|
|
251
251
|
if (item == null) {
|
|
252
252
|
return item;
|
|
@@ -278,7 +278,7 @@ function getDataIDsFromFragment(
|
|
|
278
278
|
*/
|
|
279
279
|
function getDataIDs(
|
|
280
280
|
fragment: ReaderFragment,
|
|
281
|
-
items:
|
|
281
|
+
items: ReadonlyArray<unknown>,
|
|
282
282
|
): ?Array<DataID> {
|
|
283
283
|
let ids: null | Array<DataID> = null;
|
|
284
284
|
items.forEach(item => {
|
|
@@ -294,7 +294,7 @@ function getDataIDs(
|
|
|
294
294
|
/**
|
|
295
295
|
* @internal
|
|
296
296
|
*/
|
|
297
|
-
function getDataID(fragment: ReaderFragment, item:
|
|
297
|
+
function getDataID(fragment: ReaderFragment, item: unknown): ?DataID {
|
|
298
298
|
invariant(
|
|
299
299
|
typeof item === 'object' && item !== null && !Array.isArray(item),
|
|
300
300
|
'RelayModernSelector: Expected value for fragment `%s` to be an object, got ' +
|
|
@@ -332,7 +332,7 @@ function getDataID(fragment: ReaderFragment, item: mixed): ?DataID {
|
|
|
332
332
|
*/
|
|
333
333
|
function getVariablesFromObject(
|
|
334
334
|
fragments: {[key: string]: ReaderFragment, ...},
|
|
335
|
-
object: {[key: string]:
|
|
335
|
+
object: {[key: string]: unknown, ...},
|
|
336
336
|
): Variables {
|
|
337
337
|
const variables = {};
|
|
338
338
|
for (const key in fragments) {
|
|
@@ -349,7 +349,7 @@ function getVariablesFromObject(
|
|
|
349
349
|
|
|
350
350
|
function getVariablesFromFragment(
|
|
351
351
|
fragment: ReaderFragment,
|
|
352
|
-
item:
|
|
352
|
+
item: unknown | ReadonlyArray<unknown>,
|
|
353
353
|
): Variables {
|
|
354
354
|
if (item == null) {
|
|
355
355
|
return {};
|
|
@@ -380,7 +380,7 @@ function getVariablesFromFragment(
|
|
|
380
380
|
|
|
381
381
|
function getVariablesFromSingularFragment(
|
|
382
382
|
fragment: ReaderFragment,
|
|
383
|
-
item:
|
|
383
|
+
item: unknown,
|
|
384
384
|
): ?Variables {
|
|
385
385
|
const selector = getSingularSelector(fragment, item);
|
|
386
386
|
if (!selector) {
|
|
@@ -391,7 +391,7 @@ function getVariablesFromSingularFragment(
|
|
|
391
391
|
|
|
392
392
|
function getVariablesFromPluralFragment(
|
|
393
393
|
fragment: ReaderFragment,
|
|
394
|
-
items:
|
|
394
|
+
items: ReadonlyArray<unknown>,
|
|
395
395
|
): Variables {
|
|
396
396
|
const variables = {};
|
|
397
397
|
items.forEach((value, ii) => {
|
|
@@ -519,13 +519,13 @@ function createReaderSelector(
|
|
|
519
519
|
clientEdgeTraversalPath: ?ClientEdgeTraversalPath,
|
|
520
520
|
): SingularReaderSelector {
|
|
521
521
|
return {
|
|
522
|
-
|
|
522
|
+
clientEdgeTraversalPath: clientEdgeTraversalPath ?? null,
|
|
523
523
|
dataID,
|
|
524
524
|
isWithinUnmatchedTypeRefinement,
|
|
525
|
-
|
|
525
|
+
kind: 'SingularReaderSelector',
|
|
526
526
|
node: fragment,
|
|
527
|
-
variables,
|
|
528
527
|
owner: request,
|
|
528
|
+
variables,
|
|
529
529
|
};
|
|
530
530
|
}
|
|
531
531
|
|
|
@@ -539,16 +539,16 @@ function createNormalizationSelector(
|
|
|
539
539
|
|
|
540
540
|
module.exports = {
|
|
541
541
|
areEqualSelectors,
|
|
542
|
-
createReaderSelector,
|
|
543
542
|
createNormalizationSelector,
|
|
543
|
+
createReaderSelector,
|
|
544
544
|
getDataIDsFromFragment,
|
|
545
545
|
getDataIDsFromObject,
|
|
546
|
-
getSingularSelector,
|
|
547
546
|
getPluralSelector,
|
|
548
547
|
getSelector,
|
|
549
548
|
getSelectorsFromObject,
|
|
550
|
-
|
|
551
|
-
getVariablesFromPluralFragment,
|
|
549
|
+
getSingularSelector,
|
|
552
550
|
getVariablesFromFragment,
|
|
553
551
|
getVariablesFromObject,
|
|
552
|
+
getVariablesFromPluralFragment,
|
|
553
|
+
getVariablesFromSingularFragment,
|
|
554
554
|
};
|
|
@@ -40,6 +40,7 @@ const {
|
|
|
40
40
|
assertInternalActorIdentifier,
|
|
41
41
|
} = require('../multi-actor-environment/ActorIdentifier');
|
|
42
42
|
const deepFreeze = require('../util/deepFreeze');
|
|
43
|
+
const RelayFeatureFlags = require('../util/RelayFeatureFlags');
|
|
43
44
|
const resolveImmediate = require('../util/resolveImmediate');
|
|
44
45
|
const DataChecker = require('./DataChecker');
|
|
45
46
|
const defaultGetDataID = require('./defaultGetDataID');
|
|
@@ -54,11 +55,16 @@ const RelayReader = require('./RelayReader');
|
|
|
54
55
|
const RelayReferenceMarker = require('./RelayReferenceMarker');
|
|
55
56
|
const RelayStoreSubscriptions = require('./RelayStoreSubscriptions');
|
|
56
57
|
const RelayStoreUtils = require('./RelayStoreUtils');
|
|
57
|
-
const {
|
|
58
|
+
const {
|
|
59
|
+
FIELD_GRANULAR_NOTIFICATIONS_KEY,
|
|
60
|
+
ROOT_ID,
|
|
61
|
+
ROOT_TYPE,
|
|
62
|
+
getFieldNotificationKey,
|
|
63
|
+
} = require('./RelayStoreUtils');
|
|
58
64
|
const invariant = require('invariant');
|
|
59
65
|
|
|
60
66
|
export opaque type InvalidationState = {
|
|
61
|
-
dataIDs:
|
|
67
|
+
dataIDs: ReadonlyArray<DataID>,
|
|
62
68
|
invalidations: Map<DataID, ?number>,
|
|
63
69
|
};
|
|
64
70
|
|
|
@@ -67,6 +73,11 @@ type InvalidationSubscription = {
|
|
|
67
73
|
invalidationState: InvalidationState,
|
|
68
74
|
};
|
|
69
75
|
|
|
76
|
+
type Batch = {
|
|
77
|
+
sourceOperations: Array<OperationDescriptor>,
|
|
78
|
+
invalidateStore: boolean,
|
|
79
|
+
};
|
|
80
|
+
|
|
70
81
|
const DEFAULT_RELEASE_BUFFER_SIZE = 10;
|
|
71
82
|
|
|
72
83
|
/**
|
|
@@ -115,6 +126,8 @@ class RelayModernStore implements Store {
|
|
|
115
126
|
_resolverContext: ?ResolverContext;
|
|
116
127
|
_actorIdentifier: ?ActorIdentifier;
|
|
117
128
|
_treatMissingFieldsAsNull: boolean;
|
|
129
|
+
_deferDeduplicatedFields: boolean;
|
|
130
|
+
_batch: Batch | null;
|
|
118
131
|
|
|
119
132
|
constructor(
|
|
120
133
|
source: MutableRecordSource,
|
|
@@ -134,6 +147,7 @@ class RelayModernStore implements Store {
|
|
|
134
147
|
// These additional config options are only used if the experimental
|
|
135
148
|
// @outputType resolver feature is used
|
|
136
149
|
treatMissingFieldsAsNull?: ?boolean,
|
|
150
|
+
deferDeduplicatedFields?: ?boolean,
|
|
137
151
|
actorIdentifier?: ?ActorIdentifier,
|
|
138
152
|
},
|
|
139
153
|
) {
|
|
@@ -182,7 +196,9 @@ class RelayModernStore implements Store {
|
|
|
182
196
|
options?.shouldProcessClientComponents ?? false;
|
|
183
197
|
|
|
184
198
|
this._treatMissingFieldsAsNull = options?.treatMissingFieldsAsNull ?? false;
|
|
199
|
+
this._deferDeduplicatedFields = options?.deferDeduplicatedFields ?? false;
|
|
185
200
|
this._actorIdentifier = options?.actorIdentifier;
|
|
201
|
+
this._batch = null;
|
|
186
202
|
|
|
187
203
|
initializeRecordSource(this._recordSource);
|
|
188
204
|
}
|
|
@@ -235,6 +251,60 @@ class RelayModernStore implements Store {
|
|
|
235
251
|
}
|
|
236
252
|
}
|
|
237
253
|
|
|
254
|
+
/**
|
|
255
|
+
* Batch multiple store updates into a single notification pass.
|
|
256
|
+
*
|
|
257
|
+
* Fragments will still correctly Suspend on their own parent query during
|
|
258
|
+
* a batch. However, cross-operation Suspense (a fragment suspending on a
|
|
259
|
+
* *different* in-flight operation) may not work correctly for operations
|
|
260
|
+
* that complete during the batch.
|
|
261
|
+
*/
|
|
262
|
+
experimental_batchUpdates(callback: () => void): void {
|
|
263
|
+
if (this._batch != null) {
|
|
264
|
+
throw new Error(
|
|
265
|
+
'RelayModernStore: Cannot batch updates while already batching updates.',
|
|
266
|
+
);
|
|
267
|
+
}
|
|
268
|
+
const log = this.__log;
|
|
269
|
+
if (log != null) {
|
|
270
|
+
log({name: 'store.batch.start'});
|
|
271
|
+
}
|
|
272
|
+
const batch: Batch = {sourceOperations: [], invalidateStore: false};
|
|
273
|
+
this._batch = batch;
|
|
274
|
+
try {
|
|
275
|
+
callback();
|
|
276
|
+
} finally {
|
|
277
|
+
this._batch = null;
|
|
278
|
+
this.notify(undefined, batch.invalidateStore);
|
|
279
|
+
for (const sourceOperation of batch.sourceOperations) {
|
|
280
|
+
this._recordSourceOperation(sourceOperation);
|
|
281
|
+
}
|
|
282
|
+
if (log != null) {
|
|
283
|
+
log({
|
|
284
|
+
name: 'store.batch.complete',
|
|
285
|
+
sourceOperations: batch.sourceOperations,
|
|
286
|
+
invalidateStore: batch.invalidateStore,
|
|
287
|
+
});
|
|
288
|
+
}
|
|
289
|
+
}
|
|
290
|
+
}
|
|
291
|
+
|
|
292
|
+
batchLiveStateUpdatesWithoutNotify(callback: () => void): boolean {
|
|
293
|
+
if (this.__log != null) {
|
|
294
|
+
this.__log({name: 'liveresolver.batch.start'});
|
|
295
|
+
}
|
|
296
|
+
let hasPublished = false;
|
|
297
|
+
try {
|
|
298
|
+
hasPublished =
|
|
299
|
+
this._resolverCache.batchLiveStateUpdatesWithoutNotify(callback);
|
|
300
|
+
} finally {
|
|
301
|
+
if (this.__log != null) {
|
|
302
|
+
this.__log({name: 'liveresolver.batch.end'});
|
|
303
|
+
}
|
|
304
|
+
}
|
|
305
|
+
return hasPublished;
|
|
306
|
+
}
|
|
307
|
+
|
|
238
308
|
check(
|
|
239
309
|
operation: OperationDescriptor,
|
|
240
310
|
options?: CheckOptions,
|
|
@@ -341,7 +411,7 @@ class RelayModernStore implements Store {
|
|
|
341
411
|
if (this._releaseBuffer.length > this._gcReleaseBufferSize) {
|
|
342
412
|
const _id = this._releaseBuffer.shift();
|
|
343
413
|
if (!this._shouldRetainWithinTTL_EXPERIMENTAL) {
|
|
344
|
-
// $FlowFixMe[incompatible-
|
|
414
|
+
// $FlowFixMe[incompatible-type]
|
|
345
415
|
this._roots.delete(_id);
|
|
346
416
|
}
|
|
347
417
|
this.scheduleGC();
|
|
@@ -385,6 +455,7 @@ class RelayModernStore implements Store {
|
|
|
385
455
|
const snapshot = RelayReader.read(
|
|
386
456
|
source,
|
|
387
457
|
selector,
|
|
458
|
+
log,
|
|
388
459
|
this._resolverCache,
|
|
389
460
|
this._resolverContext,
|
|
390
461
|
);
|
|
@@ -404,7 +475,22 @@ class RelayModernStore implements Store {
|
|
|
404
475
|
notify(
|
|
405
476
|
sourceOperation?: OperationDescriptor,
|
|
406
477
|
invalidateStore?: boolean,
|
|
407
|
-
):
|
|
478
|
+
): ReadonlyArray<RequestDescriptor> {
|
|
479
|
+
// If we're inside a batchUpdates() call, defer notification.
|
|
480
|
+
const batch = this._batch;
|
|
481
|
+
if (batch != null) {
|
|
482
|
+
if (sourceOperation != null) {
|
|
483
|
+
batch.sourceOperations.push(sourceOperation);
|
|
484
|
+
}
|
|
485
|
+
if (invalidateStore === true) {
|
|
486
|
+
batch.invalidateStore = true;
|
|
487
|
+
}
|
|
488
|
+
// Returning [] here means the OperationExecutor's _updateOperationTracker
|
|
489
|
+
// will be a no-op for this call, since it relies on notify() returning
|
|
490
|
+
// the list of affected owners. See the experimental_batchUpdates JSDoc.
|
|
491
|
+
return [];
|
|
492
|
+
}
|
|
493
|
+
|
|
408
494
|
const log = this.__log;
|
|
409
495
|
if (log != null) {
|
|
410
496
|
log({
|
|
@@ -413,69 +499,78 @@ class RelayModernStore implements Store {
|
|
|
413
499
|
});
|
|
414
500
|
}
|
|
415
501
|
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
502
|
+
if (!RelayFeatureFlags.OPTIMIZE_NOTIFY) {
|
|
503
|
+
// Increment the current write when notifying after executing
|
|
504
|
+
// a set of changes to the store.
|
|
505
|
+
this._currentWriteEpoch++;
|
|
419
506
|
|
|
420
|
-
|
|
421
|
-
|
|
507
|
+
if (invalidateStore === true) {
|
|
508
|
+
this._globalInvalidationEpoch = this._currentWriteEpoch;
|
|
509
|
+
}
|
|
422
510
|
}
|
|
423
511
|
|
|
424
512
|
// When a record is updated, we need to also handle records that depend on it,
|
|
425
513
|
// specifically Relay Resolver result records containing results based on the
|
|
426
514
|
// updated records. This both adds to updatedRecordIDs and invalidates any
|
|
427
515
|
// cached data as needed.
|
|
428
|
-
|
|
516
|
+
if (!RelayFeatureFlags.OPTIMIZE_NOTIFY || this._updatedRecordIDs.size > 0) {
|
|
517
|
+
this._resolverCache.invalidateDataIDs(this._updatedRecordIDs);
|
|
518
|
+
}
|
|
429
519
|
|
|
430
520
|
const source = this.getSource();
|
|
431
521
|
const updatedOwners: Array<RequestDescriptor> = [];
|
|
432
|
-
this.
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
this._invalidationSubscriptions.forEach(subscription => {
|
|
439
|
-
this._updateInvalidationSubscription(
|
|
440
|
-
subscription,
|
|
441
|
-
invalidateStore === true,
|
|
522
|
+
if (!RelayFeatureFlags.OPTIMIZE_NOTIFY || this._updatedRecordIDs.size > 0) {
|
|
523
|
+
this._storeSubscriptions.updateSubscriptions(
|
|
524
|
+
source,
|
|
525
|
+
this._updatedRecordIDs,
|
|
526
|
+
updatedOwners,
|
|
527
|
+
sourceOperation,
|
|
442
528
|
);
|
|
443
|
-
}
|
|
529
|
+
} else {
|
|
530
|
+
// If no record is updated, we still need to traverse stale subscriptions for
|
|
531
|
+
// subscriptions that were using values from optimistic updates
|
|
532
|
+
this._storeSubscriptions.updateStaleSubscriptions(
|
|
533
|
+
source,
|
|
534
|
+
this._updatedRecordIDs,
|
|
535
|
+
updatedOwners,
|
|
536
|
+
sourceOperation,
|
|
537
|
+
);
|
|
538
|
+
}
|
|
444
539
|
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
//
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
} else if (
|
|
460
|
-
sourceOperation.request.node.params.operationKind === 'query' &&
|
|
461
|
-
this._gcReleaseBufferSize > 0 &&
|
|
462
|
-
this._releaseBuffer.length < this._gcReleaseBufferSize
|
|
463
|
-
) {
|
|
464
|
-
// The operation isn't retained but there is space in the release buffer:
|
|
465
|
-
// temporarily track this operation in case the data can be reused soon.
|
|
466
|
-
const temporaryRootEntry = {
|
|
467
|
-
operation: sourceOperation,
|
|
468
|
-
refCount: 0,
|
|
469
|
-
epoch: this._currentWriteEpoch,
|
|
470
|
-
fetchTime: Date.now(),
|
|
471
|
-
};
|
|
472
|
-
this._releaseBuffer.push(id);
|
|
473
|
-
/* $FlowFixMe[incompatible-call] Natural Inference rollout. See
|
|
474
|
-
* https://fburl.com/gdoc/y8dn025u */
|
|
475
|
-
this._roots.set(id, temporaryRootEntry);
|
|
540
|
+
if (
|
|
541
|
+
RelayFeatureFlags.OPTIMIZE_NOTIFY &&
|
|
542
|
+
(this._updatedRecordIDs.size > 0 ||
|
|
543
|
+
updatedOwners.length > 0 ||
|
|
544
|
+
this._invalidatedRecordIDs.size > 0 ||
|
|
545
|
+
invalidateStore === true ||
|
|
546
|
+
this._globalInvalidationEpoch === this._currentWriteEpoch)
|
|
547
|
+
) {
|
|
548
|
+
// Increment the current write when notifying after executing
|
|
549
|
+
// a set of changes to the store.
|
|
550
|
+
this._currentWriteEpoch++;
|
|
551
|
+
|
|
552
|
+
if (invalidateStore === true) {
|
|
553
|
+
this._globalInvalidationEpoch = this._currentWriteEpoch;
|
|
476
554
|
}
|
|
477
555
|
}
|
|
478
556
|
|
|
557
|
+
if (
|
|
558
|
+
!RelayFeatureFlags.OPTIMIZE_NOTIFY ||
|
|
559
|
+
this._invalidatedRecordIDs.size > 0 ||
|
|
560
|
+
invalidateStore === true
|
|
561
|
+
) {
|
|
562
|
+
this._invalidationSubscriptions.forEach(subscription => {
|
|
563
|
+
this._updateInvalidationSubscription(
|
|
564
|
+
subscription,
|
|
565
|
+
invalidateStore === true,
|
|
566
|
+
);
|
|
567
|
+
});
|
|
568
|
+
}
|
|
569
|
+
|
|
570
|
+
if (sourceOperation != null) {
|
|
571
|
+
this._recordSourceOperation(sourceOperation);
|
|
572
|
+
}
|
|
573
|
+
|
|
479
574
|
if (log != null) {
|
|
480
575
|
log({
|
|
481
576
|
name: 'store.notify.complete',
|
|
@@ -493,6 +588,40 @@ class RelayModernStore implements Store {
|
|
|
493
588
|
return updatedOwners;
|
|
494
589
|
}
|
|
495
590
|
|
|
591
|
+
/**
|
|
592
|
+
* Record that a source operation was written at the current epoch.
|
|
593
|
+
* We only track the epoch at which the operation was written if
|
|
594
|
+
* it was previously retained, to keep the size of our operation
|
|
595
|
+
* epoch map bounded. If a query wasn't retained, we assume it can
|
|
596
|
+
* be deleted at any moment and thus is not relevant for us to track
|
|
597
|
+
* for the purposes of invalidation.
|
|
598
|
+
*/
|
|
599
|
+
_recordSourceOperation(sourceOperation: OperationDescriptor): void {
|
|
600
|
+
const id = sourceOperation.request.identifier;
|
|
601
|
+
const rootEntry = this._roots.get(id);
|
|
602
|
+
if (rootEntry != null) {
|
|
603
|
+
rootEntry.epoch = this._currentWriteEpoch;
|
|
604
|
+
rootEntry.fetchTime = Date.now();
|
|
605
|
+
} else if (
|
|
606
|
+
sourceOperation.request.node.params.operationKind === 'query' &&
|
|
607
|
+
this._gcReleaseBufferSize > 0 &&
|
|
608
|
+
this._releaseBuffer.length < this._gcReleaseBufferSize
|
|
609
|
+
) {
|
|
610
|
+
// The operation isn't retained but there is space in the release buffer:
|
|
611
|
+
// temporarily track this operation in case the data can be reused soon.
|
|
612
|
+
const temporaryRootEntry = {
|
|
613
|
+
operation: sourceOperation,
|
|
614
|
+
refCount: 0,
|
|
615
|
+
epoch: this._currentWriteEpoch,
|
|
616
|
+
fetchTime: Date.now(),
|
|
617
|
+
};
|
|
618
|
+
this._releaseBuffer.push(id);
|
|
619
|
+
/* $FlowFixMe[incompatible-type] Natural Inference rollout. See
|
|
620
|
+
* https://fburl.com/gdoc/y8dn025u */
|
|
621
|
+
this._roots.set(id, temporaryRootEntry);
|
|
622
|
+
}
|
|
623
|
+
}
|
|
624
|
+
|
|
496
625
|
publish(source: RecordSource, idsMarkedForInvalidation?: DataIDSet): void {
|
|
497
626
|
const target = this._getMutableRecordSource();
|
|
498
627
|
updateTargetFromSource(
|
|
@@ -543,7 +672,7 @@ class RelayModernStore implements Store {
|
|
|
543
672
|
return {dispose};
|
|
544
673
|
}
|
|
545
674
|
|
|
546
|
-
toJSON():
|
|
675
|
+
toJSON(): unknown {
|
|
547
676
|
return 'RelayModernStore()';
|
|
548
677
|
}
|
|
549
678
|
|
|
@@ -556,7 +685,7 @@ class RelayModernStore implements Store {
|
|
|
556
685
|
return this._updatedRecordIDs;
|
|
557
686
|
}
|
|
558
687
|
|
|
559
|
-
lookupInvalidationState(dataIDs:
|
|
688
|
+
lookupInvalidationState(dataIDs: ReadonlyArray<DataID>): InvalidationState {
|
|
560
689
|
const invalidations = new Map<DataID, ?number>();
|
|
561
690
|
dataIDs.forEach(dataID => {
|
|
562
691
|
const record = this.getSource().get(dataID);
|
|
@@ -795,7 +924,7 @@ class RelayModernStore implements Store {
|
|
|
795
924
|
RELAY_RESOLVER_LIVE_STATE_SUBSCRIPTION_KEY,
|
|
796
925
|
);
|
|
797
926
|
if (maybeResolverSubscription != null) {
|
|
798
|
-
// $FlowFixMe - this value if it is not null, it is a function
|
|
927
|
+
// $FlowFixMe[not-a-function] - this value if it is not null, it is a function
|
|
799
928
|
maybeResolverSubscription();
|
|
800
929
|
}
|
|
801
930
|
}
|
|
@@ -819,14 +948,13 @@ class RelayModernStore implements Store {
|
|
|
819
948
|
}
|
|
820
949
|
|
|
821
950
|
// Internal API for normalizing @outputType payloads in LiveResolverCache.
|
|
822
|
-
__getNormalizationOptions(
|
|
823
|
-
path: $ReadOnlyArray<string>,
|
|
824
|
-
): NormalizationOptions {
|
|
951
|
+
__getNormalizationOptions(path: ReadonlyArray<string>): NormalizationOptions {
|
|
825
952
|
return {
|
|
826
953
|
path,
|
|
827
954
|
getDataID: this._getDataID,
|
|
828
955
|
log: this.__log,
|
|
829
956
|
treatMissingFieldsAsNull: this._treatMissingFieldsAsNull,
|
|
957
|
+
deferDeduplicatedFields: this._deferDeduplicatedFields,
|
|
830
958
|
shouldProcessClientComponents: this._shouldProcessClientComponents,
|
|
831
959
|
actorIdentifier: this._actorIdentifier,
|
|
832
960
|
};
|
|
@@ -846,6 +974,13 @@ class RelayModernStore implements Store {
|
|
|
846
974
|
function initializeRecordSource(target: MutableRecordSource) {
|
|
847
975
|
if (!target.has(ROOT_ID)) {
|
|
848
976
|
const rootRecord = RelayModernRecord.create(ROOT_ID, ROOT_TYPE);
|
|
977
|
+
if (RelayFeatureFlags.ENABLE_FIELD_GRANULAR_NOTIFICATIONS) {
|
|
978
|
+
RelayModernRecord.setValue(
|
|
979
|
+
rootRecord,
|
|
980
|
+
FIELD_GRANULAR_NOTIFICATIONS_KEY,
|
|
981
|
+
true,
|
|
982
|
+
);
|
|
983
|
+
}
|
|
849
984
|
target.set(ROOT_ID, rootRecord);
|
|
850
985
|
}
|
|
851
986
|
}
|
|
@@ -930,6 +1065,32 @@ function updateTargetFromSource(
|
|
|
930
1065
|
}
|
|
931
1066
|
updatedRecordIDs.add(dataID);
|
|
932
1067
|
target.set(dataID, nextRecord);
|
|
1068
|
+
|
|
1069
|
+
// Add per-field notification keys for field-granular records
|
|
1070
|
+
if (
|
|
1071
|
+
RelayModernRecord.getValue(
|
|
1072
|
+
nextRecord,
|
|
1073
|
+
FIELD_GRANULAR_NOTIFICATIONS_KEY,
|
|
1074
|
+
)
|
|
1075
|
+
) {
|
|
1076
|
+
const fields = RelayModernRecord.getFields(nextRecord);
|
|
1077
|
+
for (let jj = 0; jj < fields.length; jj++) {
|
|
1078
|
+
const storageKey = fields[jj];
|
|
1079
|
+
// Skip internal metadata keys (all start with '__')
|
|
1080
|
+
if (storageKey.startsWith('__')) {
|
|
1081
|
+
continue;
|
|
1082
|
+
}
|
|
1083
|
+
if (
|
|
1084
|
+
RelayModernRecord.hasFieldChanged(
|
|
1085
|
+
targetRecord,
|
|
1086
|
+
nextRecord,
|
|
1087
|
+
storageKey,
|
|
1088
|
+
)
|
|
1089
|
+
) {
|
|
1090
|
+
updatedRecordIDs.add(getFieldNotificationKey(dataID, storageKey));
|
|
1091
|
+
}
|
|
1092
|
+
}
|
|
1093
|
+
}
|
|
933
1094
|
}
|
|
934
1095
|
} else if (sourceRecord === null) {
|
|
935
1096
|
target.delete(dataID);
|
|
@@ -23,7 +23,7 @@ class RelayOperationTracker {
|
|
|
23
23
|
{
|
|
24
24
|
promise: Promise<void>,
|
|
25
25
|
resolve: () => void,
|
|
26
|
-
pendingOperations:
|
|
26
|
+
pendingOperations: ReadonlyArray<RequestDescriptor>,
|
|
27
27
|
},
|
|
28
28
|
>;
|
|
29
29
|
|
|
@@ -150,7 +150,7 @@ class RelayOperationTracker {
|
|
|
150
150
|
|
|
151
151
|
getPendingOperationsAffectingOwner(owner: RequestDescriptor): {
|
|
152
152
|
promise: Promise<void>,
|
|
153
|
-
pendingOperations:
|
|
153
|
+
pendingOperations: ReadonlyArray<RequestDescriptor>,
|
|
154
154
|
} | null {
|
|
155
155
|
const ownerIdentifier = owner.identifier;
|
|
156
156
|
const pendingOperationsForOwner =
|
|
@@ -25,7 +25,7 @@ const RelayRecordSource = require('./RelayRecordSource');
|
|
|
25
25
|
const invariant = require('invariant');
|
|
26
26
|
|
|
27
27
|
const UNPUBLISH_RECORD_SENTINEL = RelayModernRecord.fromObject(
|
|
28
|
-
// $FlowFixMe[incompatible-
|
|
28
|
+
// $FlowFixMe[incompatible-type] frozen objects are readonly
|
|
29
29
|
Object.freeze({
|
|
30
30
|
__UNPUBLISH_RECORD_SENTINEL: true,
|
|
31
31
|
}),
|
|
@@ -88,7 +88,7 @@ class RelayOptimisticRecordSource implements MutableRecordSource {
|
|
|
88
88
|
}
|
|
89
89
|
|
|
90
90
|
remove(dataID: DataID): void {
|
|
91
|
-
// $FlowFixMe[incompatible-
|
|
91
|
+
// $FlowFixMe[incompatible-type] frozen objects are readonly
|
|
92
92
|
this._sink.set(dataID, UNPUBLISH_RECORD_SENTINEL);
|
|
93
93
|
}
|
|
94
94
|
|