relay-runtime 20.1.1 → 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 +44 -20
- 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 +129 -57
- 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 +125 -57
- 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
|
@@ -15,7 +15,9 @@ import type {ActorIdentifier} from '../multi-actor-environment/ActorIdentifier';
|
|
|
15
15
|
import type {PayloadData, PayloadError} from '../network/RelayNetworkTypes';
|
|
16
16
|
import type {
|
|
17
17
|
NormalizationActorChange,
|
|
18
|
+
NormalizationClientEdgeToClientObject,
|
|
18
19
|
NormalizationDefer,
|
|
20
|
+
NormalizationInlineFragment,
|
|
19
21
|
NormalizationLinkedField,
|
|
20
22
|
NormalizationLiveResolverField,
|
|
21
23
|
NormalizationModuleImport,
|
|
@@ -54,6 +56,7 @@ const RelayModernRecord = require('./RelayModernRecord');
|
|
|
54
56
|
const {createNormalizationSelector} = require('./RelayModernSelector');
|
|
55
57
|
const {
|
|
56
58
|
ROOT_ID,
|
|
59
|
+
ROOT_TYPE,
|
|
57
60
|
TYPENAME_KEY,
|
|
58
61
|
getArgumentValues,
|
|
59
62
|
getHandleStorageKey,
|
|
@@ -67,15 +70,16 @@ const invariant = require('invariant');
|
|
|
67
70
|
const warning = require('warning');
|
|
68
71
|
|
|
69
72
|
export type GetDataID = (
|
|
70
|
-
fieldValue: {+[string]:
|
|
73
|
+
fieldValue: {+[string]: unknown},
|
|
71
74
|
typeName: string,
|
|
72
|
-
) =>
|
|
75
|
+
) => unknown;
|
|
73
76
|
|
|
74
77
|
export type NormalizationOptions = {
|
|
75
78
|
+getDataID: GetDataID,
|
|
76
79
|
+treatMissingFieldsAsNull: boolean,
|
|
80
|
+
+deferDeduplicatedFields: boolean,
|
|
77
81
|
+log: ?LogFunction,
|
|
78
|
-
+path?:
|
|
82
|
+
+path?: ReadonlyArray<string>,
|
|
79
83
|
+shouldProcessClientComponents?: ?boolean,
|
|
80
84
|
+actorIdentifier?: ?ActorIdentifier,
|
|
81
85
|
};
|
|
@@ -112,6 +116,7 @@ class RelayResponseNormalizer {
|
|
|
112
116
|
_getDataId: GetDataID;
|
|
113
117
|
_handleFieldPayloads: Array<HandleFieldPayload>;
|
|
114
118
|
_treatMissingFieldsAsNull: boolean;
|
|
119
|
+
_deferDeduplicatedFields: boolean;
|
|
115
120
|
_incrementalPlaceholders: Array<IncrementalDataPlaceholder>;
|
|
116
121
|
_isClientExtension: boolean;
|
|
117
122
|
_isUnmatchedAbstractType: boolean;
|
|
@@ -123,6 +128,17 @@ class RelayResponseNormalizer {
|
|
|
123
128
|
_shouldProcessClientComponents: ?boolean;
|
|
124
129
|
_errorTrie: RelayErrorTrie | null;
|
|
125
130
|
_log: ?LogFunction;
|
|
131
|
+
_s2cExecutions: Map<
|
|
132
|
+
DataID,
|
|
133
|
+
{
|
|
134
|
+
selections: Array<
|
|
135
|
+
| NormalizationClientEdgeToClientObject
|
|
136
|
+
| NormalizationLiveResolverField
|
|
137
|
+
| NormalizationResolverField,
|
|
138
|
+
>,
|
|
139
|
+
typeName: string,
|
|
140
|
+
},
|
|
141
|
+
>;
|
|
126
142
|
|
|
127
143
|
constructor(
|
|
128
144
|
recordSource: MutableRecordSource,
|
|
@@ -134,6 +150,7 @@ class RelayResponseNormalizer {
|
|
|
134
150
|
this._getDataId = options.getDataID;
|
|
135
151
|
this._handleFieldPayloads = [];
|
|
136
152
|
this._treatMissingFieldsAsNull = options.treatMissingFieldsAsNull;
|
|
153
|
+
this._deferDeduplicatedFields = options.deferDeduplicatedFields;
|
|
137
154
|
this._incrementalPlaceholders = [];
|
|
138
155
|
this._isClientExtension = false;
|
|
139
156
|
this._isUnmatchedAbstractType = false;
|
|
@@ -144,6 +161,7 @@ class RelayResponseNormalizer {
|
|
|
144
161
|
this._variables = variables;
|
|
145
162
|
this._shouldProcessClientComponents = options.shouldProcessClientComponents;
|
|
146
163
|
this._log = options.log;
|
|
164
|
+
this._s2cExecutions = new Map();
|
|
147
165
|
}
|
|
148
166
|
|
|
149
167
|
normalizeResponse(
|
|
@@ -164,10 +182,20 @@ class RelayResponseNormalizer {
|
|
|
164
182
|
return {
|
|
165
183
|
errors,
|
|
166
184
|
fieldPayloads: this._handleFieldPayloads,
|
|
167
|
-
incrementalPlaceholders: this._incrementalPlaceholders,
|
|
168
185
|
followupPayloads: this._followupPayloads,
|
|
169
|
-
|
|
186
|
+
incrementalPlaceholders: this._incrementalPlaceholders,
|
|
170
187
|
isFinal: false,
|
|
188
|
+
s2cExecutions:
|
|
189
|
+
this._s2cExecutions.size > 0
|
|
190
|
+
? Array.from(this._s2cExecutions.entries()).map(
|
|
191
|
+
([recordID, entry]) => ({
|
|
192
|
+
recordID,
|
|
193
|
+
selections: entry.selections,
|
|
194
|
+
typeName: entry.typeName,
|
|
195
|
+
}),
|
|
196
|
+
)
|
|
197
|
+
: undefined,
|
|
198
|
+
source: this._recordSource,
|
|
171
199
|
};
|
|
172
200
|
}
|
|
173
201
|
|
|
@@ -192,7 +220,7 @@ class RelayResponseNormalizer {
|
|
|
192
220
|
}
|
|
193
221
|
}
|
|
194
222
|
|
|
195
|
-
_getVariableValue(name: string):
|
|
223
|
+
_getVariableValue(name: string): unknown {
|
|
196
224
|
invariant(
|
|
197
225
|
this._variables.hasOwnProperty(name),
|
|
198
226
|
'RelayResponseNormalizer(): Undefined variable `%s`.',
|
|
@@ -202,7 +230,7 @@ class RelayResponseNormalizer {
|
|
|
202
230
|
}
|
|
203
231
|
|
|
204
232
|
_getRecordType(data: PayloadData): string {
|
|
205
|
-
const typeName = (data
|
|
233
|
+
const typeName = (data as any)[TYPENAME_KEY];
|
|
206
234
|
invariant(
|
|
207
235
|
typeName != null,
|
|
208
236
|
'RelayResponseNormalizer(): Expected a typename for record `%s`.',
|
|
@@ -243,34 +271,7 @@ class RelayResponseNormalizer {
|
|
|
243
271
|
break;
|
|
244
272
|
}
|
|
245
273
|
case 'InlineFragment': {
|
|
246
|
-
|
|
247
|
-
if (abstractKey == null) {
|
|
248
|
-
const typeName = RelayModernRecord.getType(record);
|
|
249
|
-
if (typeName === selection.type) {
|
|
250
|
-
this._traverseSelections(selection, record, data);
|
|
251
|
-
}
|
|
252
|
-
} else {
|
|
253
|
-
// $FlowFixMe[method-unbinding] - data could be prototype less
|
|
254
|
-
const implementsInterface = Object.prototype.hasOwnProperty.call(
|
|
255
|
-
data,
|
|
256
|
-
abstractKey,
|
|
257
|
-
);
|
|
258
|
-
const typeName = RelayModernRecord.getType(record);
|
|
259
|
-
const typeID = generateTypeID(typeName);
|
|
260
|
-
let typeRecord = this._recordSource.get(typeID);
|
|
261
|
-
if (typeRecord == null) {
|
|
262
|
-
typeRecord = RelayModernRecord.create(typeID, TYPE_SCHEMA_TYPE);
|
|
263
|
-
this._recordSource.set(typeID, typeRecord);
|
|
264
|
-
}
|
|
265
|
-
RelayModernRecord.setValue(
|
|
266
|
-
typeRecord,
|
|
267
|
-
abstractKey,
|
|
268
|
-
implementsInterface,
|
|
269
|
-
);
|
|
270
|
-
if (implementsInterface) {
|
|
271
|
-
this._traverseSelections(selection, record, data);
|
|
272
|
-
}
|
|
273
|
-
}
|
|
274
|
+
this._normalizeInlineFragment(selection, record, data);
|
|
274
275
|
break;
|
|
275
276
|
}
|
|
276
277
|
case 'TypeDiscriminator': {
|
|
@@ -306,10 +307,10 @@ class RelayResponseNormalizer {
|
|
|
306
307
|
dataID: RelayModernRecord.getDataID(record),
|
|
307
308
|
fieldKey,
|
|
308
309
|
handle: selection.handle,
|
|
309
|
-
handleKey,
|
|
310
310
|
handleArgs: selection.handleArgs
|
|
311
311
|
? getArgumentValues(selection.handleArgs, this._variables)
|
|
312
312
|
: {},
|
|
313
|
+
handleKey,
|
|
313
314
|
});
|
|
314
315
|
break;
|
|
315
316
|
case 'ModuleImport':
|
|
@@ -340,15 +341,21 @@ class RelayResponseNormalizer {
|
|
|
340
341
|
case 'RelayLiveResolver':
|
|
341
342
|
if (!this._useExecTimeResolvers) {
|
|
342
343
|
this._normalizeResolver(selection, record, data);
|
|
344
|
+
} else if (selection.resolverInfo?.rootFragment != null) {
|
|
345
|
+
this._collectS2CExecution(selection, record);
|
|
343
346
|
}
|
|
344
347
|
break;
|
|
345
348
|
case 'ClientEdgeToClientObject':
|
|
346
349
|
if (!this._useExecTimeResolvers) {
|
|
347
350
|
this._normalizeResolver(selection.backingField, record, data);
|
|
351
|
+
} else if (
|
|
352
|
+
selection.backingField.resolverInfo?.rootFragment != null
|
|
353
|
+
) {
|
|
354
|
+
this._collectS2CExecution(selection, record);
|
|
348
355
|
}
|
|
349
356
|
break;
|
|
350
357
|
default:
|
|
351
|
-
|
|
358
|
+
selection as empty;
|
|
352
359
|
invariant(
|
|
353
360
|
false,
|
|
354
361
|
'RelayResponseNormalizer(): Unexpected ast kind `%s`.',
|
|
@@ -358,14 +365,73 @@ class RelayResponseNormalizer {
|
|
|
358
365
|
}
|
|
359
366
|
}
|
|
360
367
|
|
|
368
|
+
_normalizeInlineFragment(
|
|
369
|
+
selection: NormalizationInlineFragment,
|
|
370
|
+
record: Record,
|
|
371
|
+
data: PayloadData,
|
|
372
|
+
) {
|
|
373
|
+
const {abstractKey} = selection;
|
|
374
|
+
if (abstractKey == null) {
|
|
375
|
+
const typeName = RelayModernRecord.getType(record);
|
|
376
|
+
if (
|
|
377
|
+
typeName === selection.type ||
|
|
378
|
+
// The root record type is a special `__Root` type and may not match the
|
|
379
|
+
// type on the ast, so ignore type mismatches at the root. We currently
|
|
380
|
+
// detect whether we're at the root by checking against ROOT_ID, but this
|
|
381
|
+
// does not work for mutations/subscriptions which generate unique root
|
|
382
|
+
// ids. This is acceptable in practice as we don't read data for
|
|
383
|
+
// mutations/subscriptions in a situation where we would use
|
|
384
|
+
// isMissingData to decide whether to suspend or not.
|
|
385
|
+
// TODO T96653810: Correctly detect reading from root of mutation/subscription
|
|
386
|
+
typeName === ROOT_TYPE
|
|
387
|
+
) {
|
|
388
|
+
this._traverseSelections(selection, record, data);
|
|
389
|
+
}
|
|
390
|
+
} else {
|
|
391
|
+
// $FlowFixMe[method-unbinding] - data could be prototype less
|
|
392
|
+
const implementsInterface = Object.prototype.hasOwnProperty.call(
|
|
393
|
+
data,
|
|
394
|
+
abstractKey,
|
|
395
|
+
);
|
|
396
|
+
const typeName = RelayModernRecord.getType(record);
|
|
397
|
+
const typeID = generateTypeID(typeName);
|
|
398
|
+
let typeRecord = this._recordSource.get(typeID);
|
|
399
|
+
if (typeRecord == null) {
|
|
400
|
+
typeRecord = RelayModernRecord.create(typeID, TYPE_SCHEMA_TYPE);
|
|
401
|
+
this._recordSource.set(typeID, typeRecord);
|
|
402
|
+
}
|
|
403
|
+
RelayModernRecord.setValue(typeRecord, abstractKey, implementsInterface);
|
|
404
|
+
if (implementsInterface) {
|
|
405
|
+
this._traverseSelections(selection, record, data);
|
|
406
|
+
}
|
|
407
|
+
}
|
|
408
|
+
}
|
|
409
|
+
|
|
361
410
|
_normalizeResolver(
|
|
362
411
|
resolver: NormalizationResolverField | NormalizationLiveResolverField,
|
|
363
412
|
record: Record,
|
|
364
413
|
data: PayloadData,
|
|
365
414
|
) {
|
|
366
415
|
if (resolver.fragment != null) {
|
|
367
|
-
this.
|
|
416
|
+
this._normalizeInlineFragment(resolver.fragment, record, data);
|
|
417
|
+
}
|
|
418
|
+
}
|
|
419
|
+
|
|
420
|
+
_collectS2CExecution(
|
|
421
|
+
selection:
|
|
422
|
+
| NormalizationClientEdgeToClientObject
|
|
423
|
+
| NormalizationLiveResolverField
|
|
424
|
+
| NormalizationResolverField,
|
|
425
|
+
record: Record,
|
|
426
|
+
): void {
|
|
427
|
+
const recordID = RelayModernRecord.getDataID(record);
|
|
428
|
+
const typeName = RelayModernRecord.getType(record);
|
|
429
|
+
let entry = this._s2cExecutions.get(recordID);
|
|
430
|
+
if (entry == null) {
|
|
431
|
+
entry = {selections: [], typeName};
|
|
432
|
+
this._s2cExecutions.set(recordID, entry);
|
|
368
433
|
}
|
|
434
|
+
entry.selections.push(selection);
|
|
369
435
|
}
|
|
370
436
|
|
|
371
437
|
_normalizeDefer(
|
|
@@ -390,8 +456,9 @@ class RelayResponseNormalizer {
|
|
|
390
456
|
// Otherwise data *for this selection* should not be present: enqueue
|
|
391
457
|
// metadata to process the subsequent response chunk.
|
|
392
458
|
this._incrementalPlaceholders.push({
|
|
393
|
-
|
|
459
|
+
actorIdentifier: this._actorIdentifier,
|
|
394
460
|
data,
|
|
461
|
+
kind: 'defer',
|
|
395
462
|
label: defer.label,
|
|
396
463
|
path: [...this._path],
|
|
397
464
|
selector: createNormalizationSelector(
|
|
@@ -400,7 +467,6 @@ class RelayResponseNormalizer {
|
|
|
400
467
|
this._variables,
|
|
401
468
|
),
|
|
402
469
|
typeName: RelayModernRecord.getType(record),
|
|
403
|
-
actorIdentifier: this._actorIdentifier,
|
|
404
470
|
});
|
|
405
471
|
}
|
|
406
472
|
}
|
|
@@ -427,13 +493,13 @@ class RelayResponseNormalizer {
|
|
|
427
493
|
// If streaming is enabled, *also* emit metadata to process any
|
|
428
494
|
// response chunks that may be delivered.
|
|
429
495
|
this._incrementalPlaceholders.push({
|
|
496
|
+
actorIdentifier: this._actorIdentifier,
|
|
430
497
|
kind: 'stream',
|
|
431
498
|
label: stream.label,
|
|
432
|
-
path: [...this._path],
|
|
433
|
-
parentID: RelayModernRecord.getDataID(record),
|
|
434
499
|
node: stream,
|
|
500
|
+
parentID: RelayModernRecord.getDataID(record),
|
|
501
|
+
path: [...this._path],
|
|
435
502
|
variables: this._variables,
|
|
436
|
-
actorIdentifier: this._actorIdentifier,
|
|
437
503
|
});
|
|
438
504
|
}
|
|
439
505
|
}
|
|
@@ -466,15 +532,15 @@ class RelayResponseNormalizer {
|
|
|
466
532
|
);
|
|
467
533
|
if (operationReference != null) {
|
|
468
534
|
this._followupPayloads.push({
|
|
469
|
-
|
|
535
|
+
actorIdentifier: this._actorIdentifier,
|
|
470
536
|
args: moduleImport.args,
|
|
471
537
|
data,
|
|
472
538
|
dataID: RelayModernRecord.getDataID(record),
|
|
539
|
+
kind: 'ModuleImportPayload',
|
|
473
540
|
operationReference,
|
|
474
541
|
path: [...this._path],
|
|
475
542
|
typeName,
|
|
476
543
|
variables: this._variables,
|
|
477
|
-
actorIdentifier: this._actorIdentifier,
|
|
478
544
|
});
|
|
479
545
|
}
|
|
480
546
|
}
|
|
@@ -508,7 +574,9 @@ class RelayResponseNormalizer {
|
|
|
508
574
|
// client is assumed to be correctly configured with
|
|
509
575
|
// treatMissingFieldsAsNull=true.
|
|
510
576
|
const isOptionalField =
|
|
511
|
-
this._isClientExtension ||
|
|
577
|
+
this._isClientExtension ||
|
|
578
|
+
this._isUnmatchedAbstractType ||
|
|
579
|
+
this._deferDeduplicatedFields;
|
|
512
580
|
|
|
513
581
|
if (isOptionalField) {
|
|
514
582
|
// Field not expected to exist regardless of whether the server is pruning null
|
|
@@ -583,7 +651,7 @@ class RelayResponseNormalizer {
|
|
|
583
651
|
this._errorTrie = oldErrorTrie;
|
|
584
652
|
this._path.pop();
|
|
585
653
|
} else {
|
|
586
|
-
|
|
654
|
+
selection as empty;
|
|
587
655
|
invariant(
|
|
588
656
|
false,
|
|
589
657
|
'RelayResponseNormalizer(): Unexpected ast kind `%s` during normalization.',
|
|
@@ -648,11 +716,11 @@ class RelayResponseNormalizer {
|
|
|
648
716
|
return;
|
|
649
717
|
}
|
|
650
718
|
|
|
651
|
-
// $FlowFixMe[incompatible-
|
|
719
|
+
// $FlowFixMe[incompatible-type]
|
|
652
720
|
const typeName = field.concreteType ?? this._getRecordType(fieldValue);
|
|
653
721
|
const nextID =
|
|
654
722
|
this._getDataId(
|
|
655
|
-
// $FlowFixMe[incompatible-
|
|
723
|
+
// $FlowFixMe[incompatible-type]
|
|
656
724
|
fieldValue,
|
|
657
725
|
typeName,
|
|
658
726
|
) ||
|
|
@@ -673,14 +741,14 @@ class RelayResponseNormalizer {
|
|
|
673
741
|
);
|
|
674
742
|
|
|
675
743
|
this._followupPayloads.push({
|
|
676
|
-
|
|
677
|
-
data:
|
|
744
|
+
actorIdentifier,
|
|
745
|
+
data: fieldValue as $FlowFixMe,
|
|
678
746
|
dataID: nextID,
|
|
747
|
+
kind: 'ActorPayload',
|
|
748
|
+
node: field,
|
|
679
749
|
path: [...this._path, responseKey],
|
|
680
750
|
typeName,
|
|
681
751
|
variables: this._variables,
|
|
682
|
-
node: field,
|
|
683
|
-
actorIdentifier,
|
|
684
752
|
});
|
|
685
753
|
}
|
|
686
754
|
|
|
@@ -688,7 +756,7 @@ class RelayResponseNormalizer {
|
|
|
688
756
|
field: NormalizationLinkedField,
|
|
689
757
|
record: Record,
|
|
690
758
|
storageKey: string,
|
|
691
|
-
fieldValue:
|
|
759
|
+
fieldValue: unknown,
|
|
692
760
|
): void {
|
|
693
761
|
invariant(
|
|
694
762
|
typeof fieldValue === 'object' && fieldValue,
|
|
@@ -733,7 +801,7 @@ class RelayResponseNormalizer {
|
|
|
733
801
|
field: NormalizationLinkedField,
|
|
734
802
|
record: Record,
|
|
735
803
|
storageKey: string,
|
|
736
|
-
fieldValue:
|
|
804
|
+
fieldValue: unknown,
|
|
737
805
|
): void {
|
|
738
806
|
invariant(
|
|
739
807
|
Array.isArray(fieldValue),
|
|
@@ -823,8 +891,8 @@ class RelayResponseNormalizer {
|
|
|
823
891
|
if (!expected) {
|
|
824
892
|
const logEvent: IdCollisionTypenameLogEvent = {
|
|
825
893
|
name: 'idCollision.typename',
|
|
826
|
-
previous_typename: RelayModernRecord.getType(record),
|
|
827
894
|
new_typename: typeName,
|
|
895
|
+
previous_typename: RelayModernRecord.getType(record),
|
|
828
896
|
};
|
|
829
897
|
if (this._log != null) {
|
|
830
898
|
this._log(logEvent);
|
|
@@ -858,7 +926,7 @@ class RelayResponseNormalizer {
|
|
|
858
926
|
_validateConflictingFieldsWithIdenticalId(
|
|
859
927
|
record: Record,
|
|
860
928
|
storageKey: string,
|
|
861
|
-
fieldValue:
|
|
929
|
+
fieldValue: unknown,
|
|
862
930
|
): void {
|
|
863
931
|
// NOTE: Only emit a warning in DEV
|
|
864
932
|
if (__DEV__) {
|
|
@@ -43,6 +43,9 @@ class RelayStoreSubscriptions implements StoreSubscriptions {
|
|
|
43
43
|
__log: ?LogFunction;
|
|
44
44
|
_resolverCache: ResolverCache;
|
|
45
45
|
_resolverContext: ?ResolverContext;
|
|
46
|
+
// Stores `subscriptions` with stale snapshots, used for reducing the traversal
|
|
47
|
+
// that has to happen on `notify`
|
|
48
|
+
_staleSubscriptions: Set<Subscription>;
|
|
46
49
|
|
|
47
50
|
constructor(
|
|
48
51
|
log?: ?LogFunction,
|
|
@@ -50,6 +53,7 @@ class RelayStoreSubscriptions implements StoreSubscriptions {
|
|
|
50
53
|
resolverContext?: ResolverContext,
|
|
51
54
|
) {
|
|
52
55
|
this._subscriptions = new Set();
|
|
56
|
+
this._staleSubscriptions = new Set();
|
|
53
57
|
this.__log = log;
|
|
54
58
|
this._resolverCache = resolverCache;
|
|
55
59
|
this._resolverContext = resolverContext;
|
|
@@ -59,9 +63,17 @@ class RelayStoreSubscriptions implements StoreSubscriptions {
|
|
|
59
63
|
snapshot: Snapshot,
|
|
60
64
|
callback: (snapshot: Snapshot) => void,
|
|
61
65
|
): Disposable {
|
|
62
|
-
const subscription = {
|
|
66
|
+
const subscription: Subscription = {
|
|
67
|
+
backup: null,
|
|
68
|
+
callback,
|
|
69
|
+
snapshot,
|
|
70
|
+
stale: false,
|
|
71
|
+
};
|
|
63
72
|
const dispose = () => {
|
|
64
73
|
this._subscriptions.delete(subscription);
|
|
74
|
+
if (RelayFeatureFlags.OPTIMIZE_NOTIFY && subscription.stale) {
|
|
75
|
+
this._staleSubscriptions.delete(subscription);
|
|
76
|
+
}
|
|
65
77
|
};
|
|
66
78
|
this._subscriptions.add(subscription);
|
|
67
79
|
return {dispose};
|
|
@@ -89,11 +101,12 @@ class RelayStoreSubscriptions implements StoreSubscriptions {
|
|
|
89
101
|
const backup = RelayReader.read(
|
|
90
102
|
source,
|
|
91
103
|
snapshot.selector,
|
|
104
|
+
this.__log,
|
|
92
105
|
this._resolverCache,
|
|
93
106
|
this._resolverContext,
|
|
94
107
|
);
|
|
95
108
|
const nextData = recycleNodesInto(snapshot.data, backup.data);
|
|
96
|
-
(backup
|
|
109
|
+
(backup as $FlowFixMe).data = nextData; // backup owns the snapshot and can safely mutate
|
|
97
110
|
subscription.backup = backup;
|
|
98
111
|
});
|
|
99
112
|
}
|
|
@@ -107,20 +120,26 @@ class RelayStoreSubscriptions implements StoreSubscriptions {
|
|
|
107
120
|
// This subscription's data changed in the optimistic state. We will
|
|
108
121
|
// need to re-read.
|
|
109
122
|
subscription.stale = true;
|
|
123
|
+
if (RelayFeatureFlags.OPTIMIZE_NOTIFY) {
|
|
124
|
+
this._staleSubscriptions.add(subscription);
|
|
125
|
+
}
|
|
110
126
|
}
|
|
111
127
|
subscription.snapshot = {
|
|
112
128
|
data: subscription.snapshot.data,
|
|
129
|
+
fieldErrors: backup.fieldErrors,
|
|
113
130
|
isMissingData: backup.isMissingData,
|
|
114
131
|
missingClientEdges: backup.missingClientEdges,
|
|
115
132
|
missingLiveResolverFields: backup.missingLiveResolverFields,
|
|
116
133
|
seenRecords: backup.seenRecords,
|
|
117
134
|
selector: backup.selector,
|
|
118
|
-
fieldErrors: backup.fieldErrors,
|
|
119
135
|
};
|
|
120
136
|
} else {
|
|
121
137
|
// This subscription was created during the optimisitic state. We should
|
|
122
138
|
// re-read.
|
|
123
139
|
subscription.stale = true;
|
|
140
|
+
if (RelayFeatureFlags.OPTIMIZE_NOTIFY) {
|
|
141
|
+
this._staleSubscriptions.add(subscription);
|
|
142
|
+
}
|
|
124
143
|
}
|
|
125
144
|
});
|
|
126
145
|
}
|
|
@@ -146,6 +165,27 @@ class RelayStoreSubscriptions implements StoreSubscriptions {
|
|
|
146
165
|
});
|
|
147
166
|
}
|
|
148
167
|
|
|
168
|
+
updateStaleSubscriptions(
|
|
169
|
+
source: RecordSource,
|
|
170
|
+
updatedRecordIDs: DataIDSet,
|
|
171
|
+
updatedOwners: Array<RequestDescriptor>,
|
|
172
|
+
sourceOperation?: OperationDescriptor,
|
|
173
|
+
) {
|
|
174
|
+
const hasUpdatedRecords = updatedRecordIDs.size !== 0;
|
|
175
|
+
this._staleSubscriptions.forEach(subscription => {
|
|
176
|
+
const owner = this._updateSubscription(
|
|
177
|
+
source,
|
|
178
|
+
subscription,
|
|
179
|
+
updatedRecordIDs,
|
|
180
|
+
hasUpdatedRecords,
|
|
181
|
+
sourceOperation,
|
|
182
|
+
);
|
|
183
|
+
if (owner != null) {
|
|
184
|
+
updatedOwners.push(owner);
|
|
185
|
+
}
|
|
186
|
+
});
|
|
187
|
+
}
|
|
188
|
+
|
|
149
189
|
/**
|
|
150
190
|
* Notifies the callback for the subscription if the data for the associated
|
|
151
191
|
* snapshot has changed.
|
|
@@ -173,32 +213,36 @@ class RelayStoreSubscriptions implements StoreSubscriptions {
|
|
|
173
213
|
? RelayReader.read(
|
|
174
214
|
source,
|
|
175
215
|
snapshot.selector,
|
|
216
|
+
this.__log,
|
|
176
217
|
this._resolverCache,
|
|
177
218
|
this._resolverContext,
|
|
178
219
|
)
|
|
179
220
|
: backup;
|
|
180
221
|
const nextData = recycleNodesInto(snapshot.data, nextSnapshot.data);
|
|
181
|
-
nextSnapshot =
|
|
222
|
+
nextSnapshot = {
|
|
182
223
|
data: nextData,
|
|
224
|
+
fieldErrors: nextSnapshot.fieldErrors,
|
|
183
225
|
isMissingData: nextSnapshot.isMissingData,
|
|
184
226
|
missingClientEdges: nextSnapshot.missingClientEdges,
|
|
185
227
|
missingLiveResolverFields: nextSnapshot.missingLiveResolverFields,
|
|
186
228
|
seenRecords: nextSnapshot.seenRecords,
|
|
187
229
|
selector: nextSnapshot.selector,
|
|
188
|
-
|
|
189
|
-
}: Snapshot);
|
|
230
|
+
} as Snapshot;
|
|
190
231
|
if (__DEV__) {
|
|
191
232
|
deepFreeze(nextSnapshot);
|
|
192
233
|
}
|
|
193
234
|
subscription.snapshot = nextSnapshot;
|
|
194
235
|
subscription.stale = false;
|
|
236
|
+
if (RelayFeatureFlags.OPTIMIZE_NOTIFY && stale) {
|
|
237
|
+
this._staleSubscriptions.delete(subscription);
|
|
238
|
+
}
|
|
195
239
|
if (nextSnapshot.data !== snapshot.data) {
|
|
196
240
|
if (this.__log && RelayFeatureFlags.ENABLE_NOTIFY_SUBSCRIPTION) {
|
|
197
241
|
this.__log({
|
|
198
242
|
name: 'store.notify.subscription',
|
|
199
|
-
sourceOperation,
|
|
200
|
-
snapshot,
|
|
201
243
|
nextSnapshot,
|
|
244
|
+
snapshot,
|
|
245
|
+
sourceOperation,
|
|
202
246
|
});
|
|
203
247
|
}
|
|
204
248
|
callback(nextSnapshot);
|