@apollo/client 4.3.3 → 4.3.4

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.
Files changed (79) hide show
  1. package/CHANGELOG.md +20 -0
  2. package/__cjs/cache/core/cache.cjs +1 -1
  3. package/__cjs/cache/core/cache.cjs.map +1 -1
  4. package/__cjs/cache/core/cache.d.cts +4 -1
  5. package/__cjs/cache/core/types/Cache.d.cts +5 -0
  6. package/__cjs/cache/inmemory/entityStore.cjs +4 -4
  7. package/__cjs/cache/inmemory/inMemoryCache.cjs +15 -5
  8. package/__cjs/cache/inmemory/inMemoryCache.cjs.map +1 -1
  9. package/__cjs/cache/inmemory/inMemoryCache.d.cts +3 -1
  10. package/__cjs/cache/inmemory/key-extractor.cjs +1 -1
  11. package/__cjs/cache/inmemory/policies.cjs +5 -5
  12. package/__cjs/cache/inmemory/readFromStore.cjs +28 -10
  13. package/__cjs/cache/inmemory/readFromStore.cjs.map +1 -1
  14. package/__cjs/cache/inmemory/types.d.cts +7 -2
  15. package/__cjs/cache/inmemory/writeToStore.cjs +29 -14
  16. package/__cjs/cache/inmemory/writeToStore.cjs.map +1 -1
  17. package/__cjs/cache/inmemory/writeToStore.d.cts +5 -2
  18. package/__cjs/core/ApolloClient.cjs +14 -14
  19. package/__cjs/core/ObservableQuery.cjs +8 -8
  20. package/__cjs/core/QueryInfo.cjs +13 -32
  21. package/__cjs/core/QueryInfo.cjs.map +1 -1
  22. package/__cjs/core/QueryManager.cjs +12 -12
  23. package/__cjs/core/RefetchEventManager.cjs +3 -3
  24. package/__cjs/incremental/handlers/defer20220824.cjs +15 -2
  25. package/__cjs/incremental/handlers/defer20220824.cjs.map +1 -1
  26. package/__cjs/incremental/handlers/defer20220824.d.cts +5 -1
  27. package/__cjs/incremental/handlers/graphql17Alpha9.cjs +58 -14
  28. package/__cjs/incremental/handlers/graphql17Alpha9.cjs.map +1 -1
  29. package/__cjs/incremental/handlers/graphql17Alpha9.d.cts +23 -12
  30. package/__cjs/incremental/handlers/notImplemented.cjs +1 -1
  31. package/__cjs/incremental/types.d.cts +19 -1
  32. package/__cjs/invariantErrorCodes.cjs +64 -58
  33. package/__cjs/utilities/internal/index.cjs.map +1 -1
  34. package/__cjs/utilities/internal/index.d.cts +0 -1
  35. package/__cjs/version.cjs +1 -1
  36. package/cache/core/cache.d.ts +4 -1
  37. package/cache/core/cache.js +1 -1
  38. package/cache/core/cache.js.map +1 -1
  39. package/cache/core/types/Cache.d.ts +5 -0
  40. package/cache/core/types/Cache.js.map +1 -1
  41. package/cache/inmemory/entityStore.js +4 -4
  42. package/cache/inmemory/inMemoryCache.d.ts +3 -1
  43. package/cache/inmemory/inMemoryCache.js +15 -5
  44. package/cache/inmemory/inMemoryCache.js.map +1 -1
  45. package/cache/inmemory/key-extractor.js +1 -1
  46. package/cache/inmemory/policies.js +5 -5
  47. package/cache/inmemory/readFromStore.js +28 -10
  48. package/cache/inmemory/readFromStore.js.map +1 -1
  49. package/cache/inmemory/types.d.ts +7 -2
  50. package/cache/inmemory/types.js.map +1 -1
  51. package/cache/inmemory/writeToStore.d.ts +5 -2
  52. package/cache/inmemory/writeToStore.js +30 -15
  53. package/cache/inmemory/writeToStore.js.map +1 -1
  54. package/core/ApolloClient.js +14 -14
  55. package/core/ObservableQuery.js +8 -8
  56. package/core/QueryInfo.js +14 -33
  57. package/core/QueryInfo.js.map +1 -1
  58. package/core/QueryManager.js +12 -12
  59. package/core/RefetchEventManager.js +3 -3
  60. package/incremental/handlers/defer20220824.d.ts +5 -1
  61. package/incremental/handlers/defer20220824.js +15 -2
  62. package/incremental/handlers/defer20220824.js.map +1 -1
  63. package/incremental/handlers/graphql17Alpha9.d.ts +23 -12
  64. package/incremental/handlers/graphql17Alpha9.js +58 -14
  65. package/incremental/handlers/graphql17Alpha9.js.map +1 -1
  66. package/incremental/handlers/notImplemented.js +1 -1
  67. package/incremental/types.d.ts +19 -1
  68. package/incremental/types.js.map +1 -1
  69. package/invariantErrorCodes.js +64 -58
  70. package/package.json +1 -1
  71. package/utilities/internal/index.d.ts +0 -1
  72. package/utilities/internal/index.js.map +1 -1
  73. package/version.js +1 -1
  74. package/__cjs/utilities/internal/types/DeferInfo.cjs +0 -3
  75. package/__cjs/utilities/internal/types/DeferInfo.cjs.map +0 -1
  76. package/__cjs/utilities/internal/types/DeferInfo.d.cts +0 -10
  77. package/utilities/internal/types/DeferInfo.d.ts +0 -10
  78. package/utilities/internal/types/DeferInfo.js +0 -2
  79. package/utilities/internal/types/DeferInfo.js.map +0 -1
@@ -1,7 +1,8 @@
1
1
  import type { DocumentNode, FieldNode } from "graphql";
2
2
  import type { OperationVariables } from "@apollo/client";
3
+ import type { Incremental } from "@apollo/client/incremental";
3
4
  import type { Reference, StoreObject, StoreValue } from "@apollo/client/utilities";
4
- import type { DeferInfoTrie, ExtensionsWithStreamInfo, RemoveIndexSignature, StreamInfoTrie } from "@apollo/client/utilities/internal";
5
+ import type { ExtensionsWithStreamInfo, handleIncrementalSymbol, RemoveIndexSignature, StreamInfoTrie } from "@apollo/client/utilities/internal";
5
6
  import type { ApolloCache, Transaction } from "../core/cache.js";
6
7
  import type { AllFieldsModifier, CanReadFunction, Modifiers, ToReferenceFunction } from "../core/types/common.js";
7
8
  import type { FieldValueGetter } from "./entityStore.js";
@@ -86,7 +87,10 @@ export type ReadQueryOptions = {
86
87
  */
87
88
  export interface DiffIncrementalInfo {
88
89
  streamInfo?: StreamInfoTrie;
89
- deferInfo?: DeferInfoTrie;
90
+ isDeferPending?: (path: Incremental.Path, label: string | undefined) => boolean;
91
+ }
92
+ export interface WithHandleIncremental {
93
+ [handleIncrementalSymbol]?: DiffIncrementalInfo | undefined;
90
94
  }
91
95
  export type DiffQueryAgainstStoreOptions = ReadQueryOptions & {
92
96
  returnPartialData?: boolean;
@@ -128,6 +132,7 @@ export interface ReadMergeModifyContext {
128
132
  variables?: OperationVariables;
129
133
  varString?: string;
130
134
  extensions?: ExtensionsWithStreamInfo;
135
+ isDeferPending?: (path: Incremental.Path, label: string | undefined) => boolean;
131
136
  }
132
137
  type ListOf<T extends string> = `[${T}]`;
133
138
  type NestedScalarName<T extends string> = T | ListOf<T> | ListOf<ListOf<T>> | ListOf<ListOf<ListOf<T>>> | ListOf<ListOf<ListOf<ListOf<T>>>>;
@@ -1 +1 @@
1
- {"version":3,"file":"types.js","sourceRoot":"","sources":["../../../src/cache/inmemory/types.ts"],"names":[],"mappings":"","sourcesContent":["import type { DocumentNode, FieldNode } from \"graphql\";\n\nimport type { OperationVariables } from \"@apollo/client\";\nimport type {\n Reference,\n StoreObject,\n StoreValue,\n} from \"@apollo/client/utilities\";\nimport type {\n DeferInfoTrie,\n ExtensionsWithStreamInfo,\n RemoveIndexSignature,\n StreamInfoTrie,\n} from \"@apollo/client/utilities/internal\";\n\nimport type { ApolloCache, Transaction } from \"../core/cache.js\";\nimport type {\n AllFieldsModifier,\n CanReadFunction,\n Modifiers,\n ToReferenceFunction,\n} from \"../core/types/common.js\";\n\nimport type { FieldValueGetter } from \"./entityStore.js\";\nimport type { FragmentRegistryAPI } from \"./fragmentRegistry.js\";\nimport type { InMemoryCache } from \"./inMemoryCache.js\";\nimport type {\n FieldMergeFunction,\n KeyFieldsFunction,\n PossibleTypesMap,\n StorageType,\n TypePolicies,\n} from \"./policies.js\";\n\nexport type { Reference, StoreObject, StoreValue };\n\nexport interface IdGetterObj extends Object {\n __typename?: string;\n id?: string;\n _id?: string;\n}\n\nexport declare type IdGetter = (value: IdGetterObj) => string | undefined;\n\n/**\n * This is an interface used to access, set and remove\n * StoreObjects from the cache\n */\nexport interface NormalizedCache {\n has(dataId: string): boolean;\n get(dataId: string, fieldName: string): StoreValue;\n\n // The store.merge method allows either argument to be a string ID, but\n // the other argument has to be a StoreObject. Either way, newer fields\n // always take precedence over older fields.\n merge(olderId: string, newerObject: StoreObject): void;\n merge(olderObject: StoreObject, newerId: string): void;\n\n modify<Entity extends Record<string, any>>(\n dataId: string,\n fields: Modifiers<Entity> | AllFieldsModifier<Entity>,\n exact: boolean\n ): boolean;\n delete(dataId: string, fieldName?: string): boolean;\n clear(): void;\n\n // non-Map elements:\n /**\n * returns an Object with key-value pairs matching the contents of the store\n */\n toObject(): NormalizedCacheObject;\n /**\n * replace the state of the store\n */\n replace(newData: NormalizedCacheObject): void;\n\n /**\n * Retain (or release) a given root ID to protect (or expose) it and its\n * transitive child entities from (or to) garbage collection. The current\n * retainment count is returned by both methods. Note that releasing a root\n * ID does not cause that entity to be garbage collected, but merely removes\n * it from the set of root IDs that will be considered during the next\n * mark-and-sweep collection.\n */\n retain(rootId: string): number;\n release(rootId: string): number;\n\n getFieldValue: FieldValueGetter;\n toReference: ToReferenceFunction;\n canRead: CanReadFunction;\n\n getStorage(\n idOrObj: string | StoreObject,\n ...storeFieldNames: (string | number)[]\n ): StorageType;\n}\n\n/**\n * This is a normalized representation of the Apollo query result cache. It consists of\n * a flattened representation of query result trees.\n */\nexport interface NormalizedCacheObject {\n __META?: {\n // Well-known singleton IDs like ROOT_QUERY and ROOT_MUTATION are\n // always considered to be root IDs during cache.gc garbage\n // collection, but other IDs can become roots if they are written\n // directly with cache.writeFragment or retained explicitly with\n // cache.retain. When such IDs exist, we include them in the __META\n // section so that they can survive cache.{extract,restore}.\n extraRootIds: string[];\n };\n [dataId: string]: StoreObject | undefined;\n}\n\nexport type OptimisticStoreItem = {\n id: string;\n data: NormalizedCacheObject;\n transaction: Transaction;\n};\n\nexport type ReadQueryOptions = {\n /**\n * The Apollo Client store object.\n */\n store: NormalizedCache;\n /**\n * A parsed GraphQL query document.\n */\n query: DocumentNode;\n variables?: Object;\n previousResult?: any;\n rootId?: string;\n config?: ApolloReducerConfig;\n};\n\n/** @internal */\nexport interface DiffIncrementalInfo {\n streamInfo?: StreamInfoTrie;\n deferInfo?: DeferInfoTrie;\n}\n\nexport type DiffQueryAgainstStoreOptions = ReadQueryOptions & {\n returnPartialData?: boolean;\n};\n\nexport type ApolloReducerConfig = {\n dataIdFromObject?: KeyFieldsFunction;\n};\n\nexport interface InputObjectConfig {\n fields: Record<string, string>;\n}\n\nexport interface InputObjectsOption {\n [inputObjectName: string]: InputObjectConfig;\n}\n\nexport type InMemoryCacheConfig = ApolloReducerConfig & {\n resultCaching?: boolean;\n possibleTypes?: PossibleTypesMap;\n typePolicies?: TypePolicies;\n fragments?: FragmentRegistryAPI;\n inputObjects?: InputObjectsOption;\n} & ({} extends InMemoryCache.ScalarsOption ?\n InMemoryCache.ScalarsOption extends Record<string, never> ?\n {\n scalars?: Record<\n string,\n `Scalar types must be declared in ApolloCache.Scalars before usage. See https://www.apollographql.com/docs/react/data/typescript#declaring-scalar-types.`\n >;\n }\n : { scalars?: InMemoryCache.ScalarsOption }\n : { scalars: InMemoryCache.ScalarsOption });\n\nexport interface MergeInfo {\n field: FieldNode;\n typename: string | undefined;\n merge: FieldMergeFunction;\n path: Array<string | number>;\n}\n\nexport interface MergeTree {\n info?: MergeInfo;\n map: Map<string | number, MergeTree>;\n}\n\nexport interface ReadMergeModifyContext {\n store: NormalizedCache;\n variables?: OperationVariables;\n // A JSON.stringify-serialized version of context.variables.\n varString?: string;\n extensions?: ExtensionsWithStreamInfo;\n}\n\ntype ListOf<T extends string> = `[${T}]`;\n\ntype NestedScalarName<T extends string> =\n | T\n | ListOf<T>\n | ListOf<ListOf<T>>\n | ListOf<ListOf<ListOf<T>>>\n | ListOf<ListOf<ListOf<ListOf<T>>>>;\n\nexport type KnownScalars = RemoveIndexSignature<ApolloCache.Scalars>;\n\nexport type ScalarType =\n | NestedScalarName<keyof KnownScalars & string>\n | (string extends keyof ApolloCache.Scalars ? string & {} : never);\n"]}
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../../../src/cache/inmemory/types.ts"],"names":[],"mappings":"","sourcesContent":["import type { DocumentNode, FieldNode } from \"graphql\";\n\nimport type { OperationVariables } from \"@apollo/client\";\nimport type { Incremental } from \"@apollo/client/incremental\";\nimport type {\n Reference,\n StoreObject,\n StoreValue,\n} from \"@apollo/client/utilities\";\nimport type {\n ExtensionsWithStreamInfo,\n handleIncrementalSymbol,\n RemoveIndexSignature,\n StreamInfoTrie,\n} from \"@apollo/client/utilities/internal\";\n\nimport type { ApolloCache, Transaction } from \"../core/cache.js\";\nimport type {\n AllFieldsModifier,\n CanReadFunction,\n Modifiers,\n ToReferenceFunction,\n} from \"../core/types/common.js\";\n\nimport type { FieldValueGetter } from \"./entityStore.js\";\nimport type { FragmentRegistryAPI } from \"./fragmentRegistry.js\";\nimport type { InMemoryCache } from \"./inMemoryCache.js\";\nimport type {\n FieldMergeFunction,\n KeyFieldsFunction,\n PossibleTypesMap,\n StorageType,\n TypePolicies,\n} from \"./policies.js\";\n\nexport type { Reference, StoreObject, StoreValue };\n\nexport interface IdGetterObj extends Object {\n __typename?: string;\n id?: string;\n _id?: string;\n}\n\nexport declare type IdGetter = (value: IdGetterObj) => string | undefined;\n\n/**\n * This is an interface used to access, set and remove\n * StoreObjects from the cache\n */\nexport interface NormalizedCache {\n has(dataId: string): boolean;\n get(dataId: string, fieldName: string): StoreValue;\n\n // The store.merge method allows either argument to be a string ID, but\n // the other argument has to be a StoreObject. Either way, newer fields\n // always take precedence over older fields.\n merge(olderId: string, newerObject: StoreObject): void;\n merge(olderObject: StoreObject, newerId: string): void;\n\n modify<Entity extends Record<string, any>>(\n dataId: string,\n fields: Modifiers<Entity> | AllFieldsModifier<Entity>,\n exact: boolean\n ): boolean;\n delete(dataId: string, fieldName?: string): boolean;\n clear(): void;\n\n // non-Map elements:\n /**\n * returns an Object with key-value pairs matching the contents of the store\n */\n toObject(): NormalizedCacheObject;\n /**\n * replace the state of the store\n */\n replace(newData: NormalizedCacheObject): void;\n\n /**\n * Retain (or release) a given root ID to protect (or expose) it and its\n * transitive child entities from (or to) garbage collection. The current\n * retainment count is returned by both methods. Note that releasing a root\n * ID does not cause that entity to be garbage collected, but merely removes\n * it from the set of root IDs that will be considered during the next\n * mark-and-sweep collection.\n */\n retain(rootId: string): number;\n release(rootId: string): number;\n\n getFieldValue: FieldValueGetter;\n toReference: ToReferenceFunction;\n canRead: CanReadFunction;\n\n getStorage(\n idOrObj: string | StoreObject,\n ...storeFieldNames: (string | number)[]\n ): StorageType;\n}\n\n/**\n * This is a normalized representation of the Apollo query result cache. It consists of\n * a flattened representation of query result trees.\n */\nexport interface NormalizedCacheObject {\n __META?: {\n // Well-known singleton IDs like ROOT_QUERY and ROOT_MUTATION are\n // always considered to be root IDs during cache.gc garbage\n // collection, but other IDs can become roots if they are written\n // directly with cache.writeFragment or retained explicitly with\n // cache.retain. When such IDs exist, we include them in the __META\n // section so that they can survive cache.{extract,restore}.\n extraRootIds: string[];\n };\n [dataId: string]: StoreObject | undefined;\n}\n\nexport type OptimisticStoreItem = {\n id: string;\n data: NormalizedCacheObject;\n transaction: Transaction;\n};\n\nexport type ReadQueryOptions = {\n /**\n * The Apollo Client store object.\n */\n store: NormalizedCache;\n /**\n * A parsed GraphQL query document.\n */\n query: DocumentNode;\n variables?: Object;\n previousResult?: any;\n rootId?: string;\n config?: ApolloReducerConfig;\n};\n\n/** @internal */\nexport interface DiffIncrementalInfo {\n streamInfo?: StreamInfoTrie;\n isDeferPending?: (\n path: Incremental.Path,\n label: string | undefined\n ) => boolean;\n}\n\nexport interface WithHandleIncremental {\n [handleIncrementalSymbol]?: DiffIncrementalInfo | undefined;\n}\n\nexport type DiffQueryAgainstStoreOptions = ReadQueryOptions & {\n returnPartialData?: boolean;\n};\n\nexport type ApolloReducerConfig = {\n dataIdFromObject?: KeyFieldsFunction;\n};\n\nexport interface InputObjectConfig {\n fields: Record<string, string>;\n}\n\nexport interface InputObjectsOption {\n [inputObjectName: string]: InputObjectConfig;\n}\n\nexport type InMemoryCacheConfig = ApolloReducerConfig & {\n resultCaching?: boolean;\n possibleTypes?: PossibleTypesMap;\n typePolicies?: TypePolicies;\n fragments?: FragmentRegistryAPI;\n inputObjects?: InputObjectsOption;\n} & ({} extends InMemoryCache.ScalarsOption ?\n InMemoryCache.ScalarsOption extends Record<string, never> ?\n {\n scalars?: Record<\n string,\n `Scalar types must be declared in ApolloCache.Scalars before usage. See https://www.apollographql.com/docs/react/data/typescript#declaring-scalar-types.`\n >;\n }\n : { scalars?: InMemoryCache.ScalarsOption }\n : { scalars: InMemoryCache.ScalarsOption });\n\nexport interface MergeInfo {\n field: FieldNode;\n typename: string | undefined;\n merge: FieldMergeFunction;\n path: Array<string | number>;\n}\n\nexport interface MergeTree {\n info?: MergeInfo;\n map: Map<string | number, MergeTree>;\n}\n\nexport interface ReadMergeModifyContext {\n store: NormalizedCache;\n variables?: OperationVariables;\n // A JSON.stringify-serialized version of context.variables.\n varString?: string;\n extensions?: ExtensionsWithStreamInfo;\n isDeferPending?: (\n path: Incremental.Path,\n label: string | undefined\n ) => boolean;\n}\n\ntype ListOf<T extends string> = `[${T}]`;\n\ntype NestedScalarName<T extends string> =\n | T\n | ListOf<T>\n | ListOf<ListOf<T>>\n | ListOf<ListOf<ListOf<T>>>\n | ListOf<ListOf<ListOf<ListOf<T>>>>;\n\nexport type KnownScalars = RemoveIndexSignature<ApolloCache.Scalars>;\n\nexport type ScalarType =\n | NestedScalarName<keyof KnownScalars & string>\n | (string extends keyof ApolloCache.Scalars ? string & {} : never);\n"]}
@@ -2,9 +2,10 @@ import type { FieldNode, SelectionSetNode } from "graphql";
2
2
  import type { Cache, OperationVariables } from "@apollo/client";
3
3
  import type { Reference, StoreObject } from "@apollo/client/utilities";
4
4
  import type { FragmentMap, FragmentMapFunction } from "@apollo/client/utilities/internal";
5
+ import { handleIncrementalSymbol } from "@apollo/client/utilities/internal";
5
6
  import type { InMemoryCache } from "./inMemoryCache.js";
6
7
  import type { StoreReader } from "./readFromStore.js";
7
- import type { InMemoryCacheConfig, MergeTree, NormalizedCache, ReadMergeModifyContext } from "./types.js";
8
+ import type { DiffIncrementalInfo, InMemoryCacheConfig, MergeTree, NormalizedCache, ReadMergeModifyContext } from "./types.js";
8
9
  export interface WriteContext extends ReadMergeModifyContext {
9
10
  readonly written: {
10
11
  [dataId: string]: SelectionSetNode[];
@@ -28,7 +29,9 @@ export declare class StoreWriter {
28
29
  private reader?;
29
30
  private fragments?;
30
31
  constructor(cache: InMemoryCache, reader?: StoreReader | undefined, fragments?: InMemoryCacheConfig["fragments"]);
31
- writeToStore<TData = unknown, TVariables extends OperationVariables = OperationVariables>(store: NormalizedCache, { query, result, dataId, variables, overwrite, extensions, }: Cache.WriteOptions<TData, TVariables>): Reference | undefined;
32
+ writeToStore<TData = unknown, TVariables extends OperationVariables = OperationVariables>(store: NormalizedCache, { query, result, dataId, variables, overwrite, extensions, [handleIncrementalSymbol]: incrementalInfo, }: Cache.WriteOptions<TData, TVariables> & {
33
+ [handleIncrementalSymbol]?: DiffIncrementalInfo;
34
+ }): Reference | undefined;
32
35
  private processSelectionSet;
33
36
  private processFieldValue;
34
37
  private flattenFields;
@@ -3,7 +3,7 @@ import { Trie } from "@wry/trie";
3
3
  import { Kind } from "graphql";
4
4
  import { addTypenameToDocument, canonicalStringify, isReference, } from "@apollo/client/utilities";
5
5
  import { __DEV__ } from "@apollo/client/utilities/environment";
6
- import { argumentsObjectFromField, cloneDeep, getDefaultValues, getFragmentFromSelection, getOperationDefinition, isArray, isField, isNonEmptyArray, isStreamField, makeReference, resultKeyNameFromField, shouldInclude, streamInfoSymbol, } from "@apollo/client/utilities/internal";
6
+ import { argumentsObjectFromField, cloneDeep, getDefaultValues, getFragmentFromSelection, getOperationDefinition, handleIncrementalSymbol, isArray, isField, isNonEmptyArray, isStreamField, makeReference, resultKeyNameFromField, shouldInclude, streamInfoSymbol, } from "@apollo/client/utilities/internal";
7
7
  import { invariant, newInvariantError, } from "@apollo/client/utilities/invariant";
8
8
  import { extractFragmentContext, fieldNameFromStoreName, makeProcessedFieldsMerger, storeValueIsStoreObject, } from "./helpers.js";
9
9
  import { defaultStreamFieldMergeFn, normalizeReadFieldOptions, } from "./policies.js";
@@ -36,7 +36,7 @@ export class StoreWriter {
36
36
  this.reader = reader;
37
37
  this.fragments = fragments;
38
38
  }
39
- writeToStore(store, { query, result, dataId, variables, overwrite, extensions, }) {
39
+ writeToStore(store, { query, result, dataId, variables, overwrite, extensions, [handleIncrementalSymbol]: incrementalInfo, }) {
40
40
  const operationDefinition = getOperationDefinition(query);
41
41
  const merger = makeProcessedFieldsMerger();
42
42
  variables = {
@@ -58,6 +58,7 @@ export class StoreWriter {
58
58
  deferred: false,
59
59
  flavors: new Map(),
60
60
  extensions,
61
+ isDeferPending: incrementalInfo?.isDeferPending,
61
62
  };
62
63
  const ref = this.processSelectionSet({
63
64
  result: result || {},
@@ -68,7 +69,7 @@ export class StoreWriter {
68
69
  path: [],
69
70
  });
70
71
  if (!isReference(ref)) {
71
- throw newInvariantError(122, result);
72
+ throw newInvariantError(123, result);
72
73
  }
73
74
  // So far, the store has not been modified, so now it's time to process
74
75
  // context.incomingById and merge those incoming fields into context.store.
@@ -166,10 +167,10 @@ export class StoreWriter {
166
167
  // This WriteContext will be the default context value for fields returned
167
168
  // by the flattenFields method, but some fields may be assigned a modified
168
169
  // context, depending on the presence of @client and other directives.
169
- context, typename).forEach((context, field) => {
170
+ context, currentPath, typename).forEach((context, field) => {
170
171
  const resultFieldKey = resultKeyNameFromField(field);
171
172
  const value = result[resultFieldKey];
172
- const path = [...currentPath, field.name.value];
173
+ const path = [...currentPath, resultFieldKey];
173
174
  fieldNodeSet.add(field);
174
175
  if (value !== void 0) {
175
176
  const storeFieldName = policies.getStoreFieldName({
@@ -180,10 +181,15 @@ export class StoreWriter {
180
181
  });
181
182
  const childTree = getChildMergeTree(mergeTree, storeFieldName);
182
183
  let incomingValue = this.processFieldValue(value, field,
183
- // Reset context.clientOnly and context.deferred to their default
184
- // values before processing nested selection sets.
184
+ // Reset context.clientOnly to its default value before processing
185
+ // nested selection sets, but inherit context.deferred: a resolved
186
+ // parent field must not erase the fact that an ancestor @defer
187
+ // boundary is still pending, or nested fields reached only through
188
+ // that ancestor will incorrectly be treated as complete and report
189
+ // spurious "Missing field" errors when their own boundary hasn't
190
+ // arrived yet.
185
191
  field.selectionSet ?
186
- getContextFlavor(context, false, false)
192
+ getContextFlavor(context, false, context.deferred)
187
193
  : context, childTree, path);
188
194
  // To determine if this field holds a child object with a merge function
189
195
  // defined in its type policy (see PR #7070), we need to figure out the
@@ -230,7 +236,7 @@ export class StoreWriter {
230
236
  // provide a default value, so its absence from the written data should
231
237
  // not be cause for alarm.
232
238
  !policies.getReadFunction(typename, field.name.value)) {
233
- invariant.error(123, resultKeyNameFromField(field), result);
239
+ invariant.error(124, resultKeyNameFromField(field), result);
234
240
  }
235
241
  });
236
242
  // Identify the result object, even if dataId was already provided,
@@ -322,7 +328,7 @@ export class StoreWriter {
322
328
  }
323
329
  // Implements https://spec.graphql.org/draft/#sec-Field-Collection, but with
324
330
  // some additions for tracking @client and @defer directives.
325
- flattenFields(selectionSet, result, context, typename = getTypenameFromResult(result, selectionSet, context.fragmentMap)) {
331
+ flattenFields(selectionSet, result, context, path, typename = getTypenameFromResult(result, selectionSet, context.fragmentMap)) {
326
332
  const fieldMap = new Map();
327
333
  const { policies } = this.cache;
328
334
  const limitingTrie = new Trie(false); // No need for WeakMap, since limitingTrie does not escape.
@@ -357,10 +363,19 @@ export class StoreWriter {
357
363
  // @defer(if: false) does not make context.deferred false, but
358
364
  // instead behaves as if there was no @defer directive.
359
365
  if (!args || args.if !== false) {
360
- deferred = true;
366
+ // If we know (via context.isDeferPending) that this specific
367
+ // boundary has already been delivered, we don't need to mark
368
+ // it deferred, which allows fields under it to be validated
369
+ // normally instead of being silently exempted from the
370
+ // "Missing field" check below. When we can't determine
371
+ // whether the boundary is still pending (no callback, or the
372
+ // handler can't identify individual boundaries),
373
+ // conservatively assume it's still pending (`?? true`).
374
+ // `||=` (rather than `=`) preserves `deferred` if it was
375
+ // already true from an ancestor boundary.
376
+ deferred ||=
377
+ context.isDeferPending?.(path, args?.label) ?? true;
361
378
  }
362
- // TODO In the future, we may want to record args.label using
363
- // context.deferred, if a label is specified.
364
379
  }
365
380
  });
366
381
  }
@@ -378,7 +393,7 @@ export class StoreWriter {
378
393
  else {
379
394
  const fragment = getFragmentFromSelection(selection, context.lookupFragment);
380
395
  if (!fragment && selection.kind === Kind.FRAGMENT_SPREAD) {
381
- throw newInvariantError(124, selection.name.value);
396
+ throw newInvariantError(125, selection.name.value);
382
397
  }
383
398
  if (fragment &&
384
399
  policies.fragmentMatches(fragment, typename, result, context.variables)) {
@@ -550,7 +565,7 @@ function warnAboutDataLoss(existingRef, incomingObj, storeFieldName, store) {
550
565
  }
551
566
  });
552
567
  }
553
- __DEV__ && invariant.warn(125, fieldName, parentType, childTypenames.length ?
568
+ __DEV__ && invariant.warn(126, fieldName, parentType, childTypenames.length ?
554
569
  "either ensure all objects of type " +
555
570
  childTypenames.join(" and ") +
556
571
  " have an ID or a custom merge function, or "