@apollo/client 4.3.3 → 4.3.5

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 (99) hide show
  1. package/CHANGELOG.md +30 -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/helpers.cjs +5 -0
  8. package/__cjs/cache/inmemory/helpers.cjs.map +1 -1
  9. package/__cjs/cache/inmemory/inMemoryCache.cjs +17 -6
  10. package/__cjs/cache/inmemory/inMemoryCache.cjs.map +1 -1
  11. package/__cjs/cache/inmemory/inMemoryCache.d.cts +3 -1
  12. package/__cjs/cache/inmemory/key-extractor.cjs +15 -3
  13. package/__cjs/cache/inmemory/key-extractor.cjs.map +1 -1
  14. package/__cjs/cache/inmemory/policies.cjs +21 -5
  15. package/__cjs/cache/inmemory/policies.cjs.map +1 -1
  16. package/__cjs/cache/inmemory/policies.d.cts +2 -0
  17. package/__cjs/cache/inmemory/readFromStore.cjs +28 -10
  18. package/__cjs/cache/inmemory/readFromStore.cjs.map +1 -1
  19. package/__cjs/cache/inmemory/types.d.cts +7 -2
  20. package/__cjs/cache/inmemory/writeToStore.cjs +32 -16
  21. package/__cjs/cache/inmemory/writeToStore.cjs.map +1 -1
  22. package/__cjs/cache/inmemory/writeToStore.d.cts +5 -2
  23. package/__cjs/core/ApolloClient.cjs +14 -14
  24. package/__cjs/core/ObservableQuery.cjs +8 -8
  25. package/__cjs/core/QueryInfo.cjs +22 -33
  26. package/__cjs/core/QueryInfo.cjs.map +1 -1
  27. package/__cjs/core/QueryInfo.d.cts +1 -1
  28. package/__cjs/core/QueryManager.cjs +22 -15
  29. package/__cjs/core/QueryManager.cjs.map +1 -1
  30. package/__cjs/core/RefetchEventManager.cjs +3 -3
  31. package/__cjs/incremental/handlers/defer20220824.cjs +15 -2
  32. package/__cjs/incremental/handlers/defer20220824.cjs.map +1 -1
  33. package/__cjs/incremental/handlers/defer20220824.d.cts +5 -1
  34. package/__cjs/incremental/handlers/graphql17Alpha9.cjs +58 -14
  35. package/__cjs/incremental/handlers/graphql17Alpha9.cjs.map +1 -1
  36. package/__cjs/incremental/handlers/graphql17Alpha9.d.cts +23 -12
  37. package/__cjs/incremental/handlers/notImplemented.cjs +1 -1
  38. package/__cjs/incremental/types.d.cts +19 -1
  39. package/__cjs/invariantErrorCodes.cjs +64 -58
  40. package/__cjs/react/hooks/useFragment.cjs.map +1 -1
  41. package/__cjs/react/hooks/useFragment.d.cts +42 -43
  42. package/__cjs/utilities/internal/index.cjs.map +1 -1
  43. package/__cjs/utilities/internal/index.d.cts +0 -1
  44. package/__cjs/version.cjs +1 -1
  45. package/cache/core/cache.d.ts +4 -1
  46. package/cache/core/cache.js +1 -1
  47. package/cache/core/cache.js.map +1 -1
  48. package/cache/core/types/Cache.d.ts +5 -0
  49. package/cache/core/types/Cache.js.map +1 -1
  50. package/cache/inmemory/entityStore.js +4 -4
  51. package/cache/inmemory/helpers.js +5 -0
  52. package/cache/inmemory/helpers.js.map +1 -1
  53. package/cache/inmemory/inMemoryCache.d.ts +3 -1
  54. package/cache/inmemory/inMemoryCache.js +17 -6
  55. package/cache/inmemory/inMemoryCache.js.map +1 -1
  56. package/cache/inmemory/key-extractor.js +15 -3
  57. package/cache/inmemory/key-extractor.js.map +1 -1
  58. package/cache/inmemory/policies.d.ts +2 -0
  59. package/cache/inmemory/policies.js +22 -6
  60. package/cache/inmemory/policies.js.map +1 -1
  61. package/cache/inmemory/readFromStore.js +28 -10
  62. package/cache/inmemory/readFromStore.js.map +1 -1
  63. package/cache/inmemory/types.d.ts +7 -2
  64. package/cache/inmemory/types.js.map +1 -1
  65. package/cache/inmemory/writeToStore.d.ts +5 -2
  66. package/cache/inmemory/writeToStore.js +33 -17
  67. package/cache/inmemory/writeToStore.js.map +1 -1
  68. package/core/ApolloClient.js +14 -14
  69. package/core/ObservableQuery.js +8 -8
  70. package/core/QueryInfo.d.ts +1 -1
  71. package/core/QueryInfo.js +23 -34
  72. package/core/QueryInfo.js.map +1 -1
  73. package/core/QueryManager.js +22 -15
  74. package/core/QueryManager.js.map +1 -1
  75. package/core/RefetchEventManager.js +3 -3
  76. package/incremental/handlers/defer20220824.d.ts +5 -1
  77. package/incremental/handlers/defer20220824.js +15 -2
  78. package/incremental/handlers/defer20220824.js.map +1 -1
  79. package/incremental/handlers/graphql17Alpha9.d.ts +23 -12
  80. package/incremental/handlers/graphql17Alpha9.js +58 -14
  81. package/incremental/handlers/graphql17Alpha9.js.map +1 -1
  82. package/incremental/handlers/notImplemented.js +1 -1
  83. package/incremental/types.d.ts +19 -1
  84. package/incremental/types.js.map +1 -1
  85. package/invariantErrorCodes.js +64 -58
  86. package/package.json +1 -1
  87. package/react/hooks/useFragment.d.ts +42 -43
  88. package/react/hooks/useFragment.js.map +1 -1
  89. package/react/hooks-compiled/useFragment.d.ts +42 -43
  90. package/react/hooks-compiled/useFragment.js.map +1 -1
  91. package/utilities/internal/index.d.ts +0 -1
  92. package/utilities/internal/index.js.map +1 -1
  93. package/version.js +1 -1
  94. package/__cjs/utilities/internal/types/DeferInfo.cjs +0 -3
  95. package/__cjs/utilities/internal/types/DeferInfo.cjs.map +0 -1
  96. package/__cjs/utilities/internal/types/DeferInfo.d.cts +0 -10
  97. package/utilities/internal/types/DeferInfo.d.ts +0 -10
  98. package/utilities/internal/types/DeferInfo.js +0 -2
  99. 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,
@@ -249,8 +255,9 @@ export class StoreWriter {
249
255
  // Write any key fields that were used during identification, even if
250
256
  // they were not mentioned in the original query.
251
257
  if (keyObject) {
252
- // TODO Reverse the order of the arguments?
253
- incoming = context.merge(incoming, keyObject);
258
+ // Values in incoming take precedence over keyObject, which may contain
259
+ // serialized values used to compute the ID.
260
+ incoming = context.merge(keyObject, incoming);
254
261
  }
255
262
  }
256
263
  catch (e) {
@@ -322,7 +329,7 @@ export class StoreWriter {
322
329
  }
323
330
  // Implements https://spec.graphql.org/draft/#sec-Field-Collection, but with
324
331
  // some additions for tracking @client and @defer directives.
325
- flattenFields(selectionSet, result, context, typename = getTypenameFromResult(result, selectionSet, context.fragmentMap)) {
332
+ flattenFields(selectionSet, result, context, path, typename = getTypenameFromResult(result, selectionSet, context.fragmentMap)) {
326
333
  const fieldMap = new Map();
327
334
  const { policies } = this.cache;
328
335
  const limitingTrie = new Trie(false); // No need for WeakMap, since limitingTrie does not escape.
@@ -357,10 +364,19 @@ export class StoreWriter {
357
364
  // @defer(if: false) does not make context.deferred false, but
358
365
  // instead behaves as if there was no @defer directive.
359
366
  if (!args || args.if !== false) {
360
- deferred = true;
367
+ // If we know (via context.isDeferPending) that this specific
368
+ // boundary has already been delivered, we don't need to mark
369
+ // it deferred, which allows fields under it to be validated
370
+ // normally instead of being silently exempted from the
371
+ // "Missing field" check below. When we can't determine
372
+ // whether the boundary is still pending (no callback, or the
373
+ // handler can't identify individual boundaries),
374
+ // conservatively assume it's still pending (`?? true`).
375
+ // `||=` (rather than `=`) preserves `deferred` if it was
376
+ // already true from an ancestor boundary.
377
+ deferred ||=
378
+ context.isDeferPending?.(path, args?.label) ?? true;
361
379
  }
362
- // TODO In the future, we may want to record args.label using
363
- // context.deferred, if a label is specified.
364
380
  }
365
381
  });
366
382
  }
@@ -378,7 +394,7 @@ export class StoreWriter {
378
394
  else {
379
395
  const fragment = getFragmentFromSelection(selection, context.lookupFragment);
380
396
  if (!fragment && selection.kind === Kind.FRAGMENT_SPREAD) {
381
- throw newInvariantError(124, selection.name.value);
397
+ throw newInvariantError(125, selection.name.value);
382
398
  }
383
399
  if (fragment &&
384
400
  policies.fragmentMatches(fragment, typename, result, context.variables)) {
@@ -550,7 +566,7 @@ function warnAboutDataLoss(existingRef, incomingObj, storeFieldName, store) {
550
566
  }
551
567
  });
552
568
  }
553
- __DEV__ && invariant.warn(125, fieldName, parentType, childTypenames.length ?
569
+ __DEV__ && invariant.warn(126, fieldName, parentType, childTypenames.length ?
554
570
  "either ensure all objects of type " +
555
571
  childTypenames.join(" and ") +
556
572
  " have an ID or a custom merge function, or "