@apollo/client 4.3.0-alpha.1 → 4.3.0-alpha.11

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 (416) hide show
  1. package/CHANGELOG.md +503 -0
  2. package/README.md +3 -7
  3. package/__cjs/cache/core/Scalar.cjs +36 -0
  4. package/__cjs/cache/core/Scalar.cjs.map +1 -0
  5. package/__cjs/cache/core/Scalar.d.cts +19 -0
  6. package/__cjs/cache/core/cache.cjs +32 -1
  7. package/__cjs/cache/core/cache.cjs.map +1 -1
  8. package/__cjs/cache/core/cache.d.cts +89 -6
  9. package/__cjs/cache/core/types/Cache.d.cts +25 -0
  10. package/__cjs/cache/index.cjs +3 -1
  11. package/__cjs/cache/index.cjs.map +1 -1
  12. package/__cjs/cache/index.d.cts +3 -2
  13. package/__cjs/cache/inmemory/entityStore.cjs +48 -5
  14. package/__cjs/cache/inmemory/entityStore.cjs.map +1 -1
  15. package/__cjs/cache/inmemory/entityStore.d.cts +3 -0
  16. package/__cjs/cache/inmemory/helpers.d.cts +9 -1
  17. package/__cjs/cache/inmemory/inMemoryCache.cjs +83 -4
  18. package/__cjs/cache/inmemory/inMemoryCache.cjs.map +1 -1
  19. package/__cjs/cache/inmemory/inMemoryCache.d.cts +44 -5
  20. package/__cjs/cache/inmemory/key-extractor.cjs +1 -1
  21. package/__cjs/cache/inmemory/policies.cjs +35 -6
  22. package/__cjs/cache/inmemory/policies.cjs.map +1 -1
  23. package/__cjs/cache/inmemory/policies.d.cts +4 -1
  24. package/__cjs/cache/inmemory/readFromStore.cjs +490 -49
  25. package/__cjs/cache/inmemory/readFromStore.cjs.map +1 -1
  26. package/__cjs/cache/inmemory/readFromStore.d.cts +11 -2
  27. package/__cjs/cache/inmemory/types.d.cts +29 -4
  28. package/__cjs/cache/inmemory/writeToStore.cjs +6 -6
  29. package/__cjs/cache/inmemory/writeToStore.cjs.map +1 -1
  30. package/__cjs/core/ApolloClient.cjs +37 -38
  31. package/__cjs/core/ApolloClient.cjs.map +1 -1
  32. package/__cjs/core/ApolloClient.d.cts +44 -10
  33. package/__cjs/core/ObservableQuery.cjs +228 -76
  34. package/__cjs/core/ObservableQuery.cjs.map +1 -1
  35. package/__cjs/core/ObservableQuery.d.cts +16 -8
  36. package/__cjs/core/QueryInfo.cjs +178 -190
  37. package/__cjs/core/QueryInfo.cjs.map +1 -1
  38. package/__cjs/core/QueryInfo.d.cts +16 -21
  39. package/__cjs/core/QueryManager.cjs +88 -59
  40. package/__cjs/core/QueryManager.cjs.map +1 -1
  41. package/__cjs/core/QueryManager.d.cts +1 -3
  42. package/__cjs/core/RefetchEventManager.cjs +3 -3
  43. package/__cjs/core/dataStateErrorCache.cjs +12 -0
  44. package/__cjs/core/dataStateErrorCache.cjs.map +1 -0
  45. package/__cjs/core/dataStateErrorCache.d.cts +3 -0
  46. package/__cjs/core/index.cjs +2 -1
  47. package/__cjs/core/index.cjs.map +1 -1
  48. package/__cjs/core/index.d.cts +4 -3
  49. package/__cjs/core/types.d.cts +10 -3
  50. package/__cjs/incremental/GraphQLCodegenIncremental.cjs +3 -0
  51. package/__cjs/incremental/GraphQLCodegenIncremental.cjs.map +1 -0
  52. package/__cjs/incremental/GraphQLCodegenIncremental.d.cts +55 -0
  53. package/__cjs/incremental/handlers/defer20220824.cjs.map +1 -1
  54. package/__cjs/incremental/handlers/defer20220824.d.cts +2 -4
  55. package/__cjs/incremental/handlers/graphql17Alpha9.cjs +47 -16
  56. package/__cjs/incremental/handlers/graphql17Alpha9.cjs.map +1 -1
  57. package/__cjs/incremental/handlers/graphql17Alpha9.d.cts +29 -6
  58. package/__cjs/incremental/handlers/notImplemented.cjs +1 -1
  59. package/__cjs/incremental/index.cjs.map +1 -1
  60. package/__cjs/incremental/index.d.cts +1 -0
  61. package/__cjs/{utilities/internal/types/NoInfer.cjs → incremental/internal/types.cjs} +1 -1
  62. package/__cjs/incremental/internal/types.cjs.map +1 -0
  63. package/__cjs/incremental/internal/types.d.cts +17 -0
  64. package/__cjs/incremental/types.d.cts +55 -4
  65. package/__cjs/invariantErrorCodes.cjs +167 -112
  66. package/__cjs/link/core/ApolloLink.cjs +3 -3
  67. package/__cjs/link/http/checkFetcher.cjs +1 -1
  68. package/__cjs/link/http/parseAndCheckHttpResponse.cjs +2 -2
  69. package/__cjs/link/http/parseAndCheckHttpResponse.cjs.map +1 -1
  70. package/__cjs/link/persisted-queries/index.cjs +2 -2
  71. package/__cjs/link/ws/index.cjs +1 -1
  72. package/__cjs/local-state/LocalState.cjs +11 -11
  73. package/__cjs/local-state/LocalState.cjs.map +1 -1
  74. package/__cjs/local-state/LocalState.d.cts +1 -1
  75. package/__cjs/masking/internal/types.d.cts +1 -2
  76. package/__cjs/masking/maskDefinition.cjs +2 -2
  77. package/__cjs/masking/maskFragment.cjs +2 -2
  78. package/__cjs/masking/maskOperation.cjs +1 -1
  79. package/__cjs/masking/utils.cjs +3 -3
  80. package/__cjs/react/context/ApolloContext.cjs +1 -1
  81. package/__cjs/react/context/ApolloProvider.cjs +1 -1
  82. package/__cjs/react/hooks/internal/validateSuspenseHookOptions.cjs +2 -2
  83. package/__cjs/react/hooks/useApolloClient.cjs +1 -1
  84. package/__cjs/react/hooks/useBackgroundQuery.cjs.map +1 -1
  85. package/__cjs/react/hooks/useBackgroundQuery.d.cts +100 -47
  86. package/__cjs/react/hooks/useFragment.cjs.map +1 -1
  87. package/__cjs/react/hooks/useFragment.d.cts +0 -1
  88. package/__cjs/react/hooks/useLazyQuery.cjs +2 -2
  89. package/__cjs/react/hooks/useLazyQuery.cjs.map +1 -1
  90. package/__cjs/react/hooks/useLazyQuery.d.cts +40 -34
  91. package/__cjs/react/hooks/useLoadableQuery.cjs +2 -2
  92. package/__cjs/react/hooks/useLoadableQuery.cjs.map +1 -1
  93. package/__cjs/react/hooks/useLoadableQuery.d.cts +23 -15
  94. package/__cjs/react/hooks/useMutation.cjs.map +1 -1
  95. package/__cjs/react/hooks/useMutation.d.cts +10 -7
  96. package/__cjs/react/hooks/useQuery.cjs.map +1 -1
  97. package/__cjs/react/hooks/useQuery.d.cts +74 -32
  98. package/__cjs/react/hooks/useQueryRefHandlers.cjs.map +1 -1
  99. package/__cjs/react/hooks/useSubscription.cjs +7 -3
  100. package/__cjs/react/hooks/useSubscription.cjs.map +1 -1
  101. package/__cjs/react/hooks/useSubscription.d.cts +7 -4
  102. package/__cjs/react/hooks/useSuspenseFragment.cjs.map +1 -1
  103. package/__cjs/react/hooks/useSuspenseFragment.d.cts +1 -1
  104. package/__cjs/react/hooks/useSuspenseQuery.cjs.map +1 -1
  105. package/__cjs/react/hooks/useSuspenseQuery.d.cts +83 -34
  106. package/__cjs/react/hooks/useSyncExternalStore.cjs +1 -1
  107. package/__cjs/react/internal/cache/QueryReference.cjs +1 -1
  108. package/__cjs/react/internal/cache/QueryReference.cjs.map +1 -1
  109. package/__cjs/react/internal/types.d.cts +14 -3
  110. package/__cjs/react/query-preloader/createQueryPreloader.cjs.map +1 -1
  111. package/__cjs/react/query-preloader/createQueryPreloader.d.cts +20 -5
  112. package/__cjs/react/ssr/prerenderStatic.cjs +2 -2
  113. package/__cjs/testing/core/mocking/mockLink.cjs +25 -5
  114. package/__cjs/testing/core/mocking/mockLink.cjs.map +1 -1
  115. package/__cjs/testing/core/mocking/mockLink.d.cts +1 -2
  116. package/__cjs/utilities/caching/sizes.cjs.map +1 -1
  117. package/__cjs/utilities/caching/sizes.d.cts +39 -1
  118. package/__cjs/utilities/graphql/DocumentTransform.cjs +1 -1
  119. package/__cjs/utilities/index.cjs.map +1 -1
  120. package/__cjs/utilities/index.d.cts +1 -0
  121. package/__cjs/utilities/internal/StreamArrayState.cjs +27 -0
  122. package/__cjs/utilities/internal/StreamArrayState.cjs.map +1 -0
  123. package/__cjs/utilities/internal/StreamArrayState.d.cts +12 -0
  124. package/__cjs/utilities/internal/addDeferFragmentLabels.cjs +33 -0
  125. package/__cjs/utilities/internal/addDeferFragmentLabels.cjs.map +1 -0
  126. package/__cjs/utilities/internal/addDeferFragmentLabels.d.cts +3 -0
  127. package/__cjs/utilities/internal/capitalize.cjs +12 -0
  128. package/__cjs/utilities/internal/capitalize.cjs.map +1 -0
  129. package/__cjs/utilities/internal/capitalize.d.cts +7 -0
  130. package/__cjs/utilities/internal/coerceScalarFieldsToParsed.cjs +69 -0
  131. package/__cjs/utilities/internal/coerceScalarFieldsToParsed.cjs.map +1 -0
  132. package/__cjs/utilities/internal/coerceScalarFieldsToParsed.d.cts +9 -0
  133. package/__cjs/utilities/internal/constants.cjs +20 -1
  134. package/__cjs/utilities/internal/constants.cjs.map +1 -1
  135. package/__cjs/utilities/internal/constants.d.cts +19 -0
  136. package/__cjs/utilities/internal/getDirectiveArgValue.cjs +19 -0
  137. package/__cjs/utilities/internal/getDirectiveArgValue.cjs.map +1 -0
  138. package/__cjs/utilities/internal/getDirectiveArgValue.d.cts +9 -0
  139. package/__cjs/utilities/internal/getFragmentDefinition.cjs +3 -3
  140. package/__cjs/utilities/internal/getFragmentFromSelection.cjs +2 -2
  141. package/__cjs/utilities/internal/getFragmentFromSelection.cjs.map +1 -1
  142. package/__cjs/utilities/internal/getFragmentQueryDocument.cjs +2 -2
  143. package/__cjs/utilities/internal/getMainDefinition.cjs +1 -1
  144. package/__cjs/utilities/internal/getMemoryInternals.cjs +6 -0
  145. package/__cjs/utilities/internal/getMemoryInternals.cjs.map +1 -1
  146. package/__cjs/utilities/internal/getMemoryInternals.d.cts +4 -0
  147. package/__cjs/utilities/internal/getQueryDefinition.cjs +1 -1
  148. package/__cjs/utilities/internal/getUnwrappedType.cjs +20 -0
  149. package/__cjs/utilities/internal/getUnwrappedType.cjs.map +1 -0
  150. package/__cjs/utilities/internal/getUnwrappedType.d.cts +8 -0
  151. package/__cjs/utilities/internal/index.cjs +25 -2
  152. package/__cjs/utilities/internal/index.cjs.map +1 -1
  153. package/__cjs/utilities/internal/index.d.cts +16 -2
  154. package/__cjs/utilities/internal/isDeferredFragment.cjs +38 -0
  155. package/__cjs/utilities/internal/isDeferredFragment.cjs.map +1 -0
  156. package/__cjs/utilities/internal/isDeferredFragment.d.cts +9 -0
  157. package/__cjs/utilities/internal/isStreamField.cjs +37 -0
  158. package/__cjs/utilities/internal/isStreamField.cjs.map +1 -0
  159. package/__cjs/utilities/internal/isStreamField.d.cts +9 -0
  160. package/__cjs/utilities/internal/isTypenameField.cjs +7 -0
  161. package/__cjs/utilities/internal/isTypenameField.cjs.map +1 -0
  162. package/__cjs/utilities/internal/isTypenameField.d.cts +3 -0
  163. package/__cjs/utilities/internal/makeStreamInfoTrie.cjs +17 -0
  164. package/__cjs/utilities/internal/makeStreamInfoTrie.cjs.map +1 -0
  165. package/__cjs/utilities/internal/makeStreamInfoTrie.d.cts +8 -0
  166. package/__cjs/utilities/internal/removeDirectivesFromDocument.cjs +1 -1
  167. package/__cjs/utilities/internal/shouldInclude.cjs +4 -4
  168. package/__cjs/utilities/internal/toDiffWithDataState.cjs +20 -0
  169. package/__cjs/utilities/internal/toDiffWithDataState.cjs.map +1 -0
  170. package/__cjs/utilities/internal/toDiffWithDataState.d.cts +8 -0
  171. package/__cjs/utilities/internal/types/DeferInfo.cjs +3 -0
  172. package/__cjs/utilities/internal/types/DeferInfo.cjs.map +1 -0
  173. package/__cjs/utilities/internal/types/DeferInfo.d.cts +10 -0
  174. package/__cjs/utilities/internal/types/Exact.cjs +3 -0
  175. package/__cjs/utilities/internal/types/Exact.cjs.map +1 -0
  176. package/__cjs/utilities/internal/types/Exact.d.cts +2 -0
  177. package/__cjs/utilities/internal/types/IsLooselyEqual.cjs +3 -0
  178. package/__cjs/utilities/internal/types/IsLooselyEqual.cjs.map +1 -0
  179. package/__cjs/utilities/internal/types/IsLooselyEqual.d.cts +10 -0
  180. package/__cjs/utilities/internal/types/IsNeverish.cjs +3 -0
  181. package/__cjs/utilities/internal/types/IsNeverish.cjs.map +1 -0
  182. package/__cjs/utilities/internal/types/IsNeverish.d.cts +4 -0
  183. package/__cjs/utilities/internal/types/StreamInfoTrie.d.cts +2 -0
  184. package/__cjs/utilities/internal/valueToObjectRepresentation.cjs +1 -1
  185. package/__cjs/utilities/policies/pagination.cjs.map +1 -1
  186. package/__cjs/utilities/policies/pagination.d.cts +1 -1
  187. package/__cjs/utilities/subscriptions/relay/index.cjs +1 -0
  188. package/__cjs/utilities/subscriptions/relay/index.cjs.map +1 -1
  189. package/__cjs/version.cjs +1 -1
  190. package/__cjs/version.cjs.map +1 -1
  191. package/cache/core/Scalar.d.ts +19 -0
  192. package/cache/core/Scalar.js +32 -0
  193. package/cache/core/Scalar.js.map +1 -0
  194. package/cache/core/cache.d.ts +89 -6
  195. package/cache/core/cache.js +33 -2
  196. package/cache/core/cache.js.map +1 -1
  197. package/cache/core/types/Cache.d.ts +25 -0
  198. package/cache/core/types/Cache.js.map +1 -1
  199. package/cache/index.d.ts +3 -2
  200. package/cache/index.js +1 -0
  201. package/cache/index.js.map +1 -1
  202. package/cache/inmemory/entityStore.d.ts +3 -0
  203. package/cache/inmemory/entityStore.js +49 -6
  204. package/cache/inmemory/entityStore.js.map +1 -1
  205. package/cache/inmemory/helpers.d.ts +9 -1
  206. package/cache/inmemory/inMemoryCache.d.ts +44 -5
  207. package/cache/inmemory/inMemoryCache.js +84 -5
  208. package/cache/inmemory/inMemoryCache.js.map +1 -1
  209. package/cache/inmemory/key-extractor.js +1 -1
  210. package/cache/inmemory/policies.d.ts +4 -1
  211. package/cache/inmemory/policies.js +35 -6
  212. package/cache/inmemory/policies.js.map +1 -1
  213. package/cache/inmemory/readFromStore.d.ts +11 -2
  214. package/cache/inmemory/readFromStore.js +486 -49
  215. package/cache/inmemory/readFromStore.js.map +1 -1
  216. package/cache/inmemory/types.d.ts +30 -5
  217. package/cache/inmemory/types.js.map +1 -1
  218. package/cache/inmemory/writeToStore.js +7 -7
  219. package/cache/inmemory/writeToStore.js.map +1 -1
  220. package/core/ApolloClient.d.ts +44 -10
  221. package/core/ApolloClient.js +37 -38
  222. package/core/ApolloClient.js.map +1 -1
  223. package/core/ObservableQuery.d.ts +16 -8
  224. package/core/ObservableQuery.js +225 -77
  225. package/core/ObservableQuery.js.map +1 -1
  226. package/core/QueryInfo.d.ts +17 -22
  227. package/core/QueryInfo.js +174 -190
  228. package/core/QueryInfo.js.map +1 -1
  229. package/core/QueryManager.d.ts +1 -3
  230. package/core/QueryManager.js +89 -60
  231. package/core/QueryManager.js.map +1 -1
  232. package/core/RefetchEventManager.js +3 -3
  233. package/core/dataStateErrorCache.d.ts +3 -0
  234. package/core/dataStateErrorCache.js +9 -0
  235. package/core/dataStateErrorCache.js.map +1 -0
  236. package/core/index.d.ts +4 -3
  237. package/core/index.js +1 -1
  238. package/core/index.js.map +1 -1
  239. package/core/types.d.ts +10 -3
  240. package/core/types.js.map +1 -1
  241. package/incremental/GraphQLCodegenIncremental.d.ts +55 -0
  242. package/incremental/GraphQLCodegenIncremental.js +2 -0
  243. package/incremental/GraphQLCodegenIncremental.js.map +1 -0
  244. package/incremental/handlers/defer20220824.d.ts +2 -4
  245. package/incremental/handlers/defer20220824.js.map +1 -1
  246. package/incremental/handlers/graphql17Alpha9.d.ts +29 -6
  247. package/incremental/handlers/graphql17Alpha9.js +48 -17
  248. package/incremental/handlers/graphql17Alpha9.js.map +1 -1
  249. package/incremental/handlers/notImplemented.js +1 -1
  250. package/incremental/index.d.ts +1 -0
  251. package/incremental/index.js.map +1 -1
  252. package/incremental/internal/types.d.ts +17 -0
  253. package/incremental/internal/types.js +2 -0
  254. package/incremental/internal/types.js.map +1 -0
  255. package/incremental/types.d.ts +55 -4
  256. package/incremental/types.js.map +1 -1
  257. package/invariantErrorCodes.js +167 -112
  258. package/link/core/ApolloLink.js +3 -3
  259. package/link/http/checkFetcher.js +1 -1
  260. package/link/http/parseAndCheckHttpResponse.js +2 -2
  261. package/link/http/parseAndCheckHttpResponse.js.map +1 -1
  262. package/link/persisted-queries/index.js +2 -2
  263. package/link/ws/index.js +1 -1
  264. package/local-state/LocalState.d.ts +1 -1
  265. package/local-state/LocalState.js +11 -11
  266. package/local-state/LocalState.js.map +1 -1
  267. package/masking/internal/types.d.ts +1 -2
  268. package/masking/internal/types.js.map +1 -1
  269. package/masking/maskDefinition.js +2 -2
  270. package/masking/maskFragment.js +2 -2
  271. package/masking/maskOperation.js +1 -1
  272. package/masking/utils.js +3 -3
  273. package/package.json +1 -1
  274. package/react/context/ApolloContext.js +1 -1
  275. package/react/context/ApolloProvider.js +1 -1
  276. package/react/hooks/internal/validateSuspenseHookOptions.js +2 -2
  277. package/react/hooks/useApolloClient.js +1 -1
  278. package/react/hooks/useBackgroundQuery.d.ts +100 -47
  279. package/react/hooks/useBackgroundQuery.js.map +1 -1
  280. package/react/hooks/useFragment.d.ts +0 -1
  281. package/react/hooks/useFragment.js.map +1 -1
  282. package/react/hooks/useLazyQuery.d.ts +40 -34
  283. package/react/hooks/useLazyQuery.js +2 -2
  284. package/react/hooks/useLazyQuery.js.map +1 -1
  285. package/react/hooks/useLoadableQuery.d.ts +23 -15
  286. package/react/hooks/useLoadableQuery.js +2 -2
  287. package/react/hooks/useLoadableQuery.js.map +1 -1
  288. package/react/hooks/useMutation.d.ts +10 -7
  289. package/react/hooks/useMutation.js.map +1 -1
  290. package/react/hooks/useQuery.d.ts +74 -32
  291. package/react/hooks/useQuery.js.map +1 -1
  292. package/react/hooks/useQueryRefHandlers.js.map +1 -1
  293. package/react/hooks/useSubscription.d.ts +7 -4
  294. package/react/hooks/useSubscription.js +7 -3
  295. package/react/hooks/useSubscription.js.map +1 -1
  296. package/react/hooks/useSuspenseFragment.d.ts +1 -1
  297. package/react/hooks/useSuspenseFragment.js.map +1 -1
  298. package/react/hooks/useSuspenseQuery.d.ts +83 -34
  299. package/react/hooks/useSuspenseQuery.js.map +1 -1
  300. package/react/hooks/useSyncExternalStore.js +1 -1
  301. package/react/hooks-compiled/internal/validateSuspenseHookOptions.js +2 -2
  302. package/react/hooks-compiled/useApolloClient.js +1 -1
  303. package/react/hooks-compiled/useBackgroundQuery.d.ts +100 -47
  304. package/react/hooks-compiled/useBackgroundQuery.js.map +1 -1
  305. package/react/hooks-compiled/useFragment.d.ts +0 -1
  306. package/react/hooks-compiled/useFragment.js.map +1 -1
  307. package/react/hooks-compiled/useLazyQuery.d.ts +40 -34
  308. package/react/hooks-compiled/useLazyQuery.js +2 -2
  309. package/react/hooks-compiled/useLazyQuery.js.map +1 -1
  310. package/react/hooks-compiled/useLoadableQuery.d.ts +23 -15
  311. package/react/hooks-compiled/useLoadableQuery.js +2 -2
  312. package/react/hooks-compiled/useLoadableQuery.js.map +1 -1
  313. package/react/hooks-compiled/useMutation.d.ts +10 -7
  314. package/react/hooks-compiled/useMutation.js.map +1 -1
  315. package/react/hooks-compiled/useQuery.d.ts +74 -32
  316. package/react/hooks-compiled/useQuery.js.map +1 -1
  317. package/react/hooks-compiled/useQueryRefHandlers.js.map +1 -1
  318. package/react/hooks-compiled/useSubscription.d.ts +7 -4
  319. package/react/hooks-compiled/useSubscription.js +107 -93
  320. package/react/hooks-compiled/useSubscription.js.map +1 -1
  321. package/react/hooks-compiled/useSuspenseFragment.d.ts +1 -1
  322. package/react/hooks-compiled/useSuspenseFragment.js.map +1 -1
  323. package/react/hooks-compiled/useSuspenseQuery.d.ts +83 -34
  324. package/react/hooks-compiled/useSuspenseQuery.js.map +1 -1
  325. package/react/hooks-compiled/useSyncExternalStore.js +1 -1
  326. package/react/internal/cache/QueryReference.js +1 -1
  327. package/react/internal/cache/QueryReference.js.map +1 -1
  328. package/react/internal/types.d.ts +15 -4
  329. package/react/internal/types.js.map +1 -1
  330. package/react/query-preloader/createQueryPreloader.d.ts +20 -5
  331. package/react/query-preloader/createQueryPreloader.js.map +1 -1
  332. package/react/ssr/prerenderStatic.js +2 -2
  333. package/testing/core/mocking/mockLink.d.ts +1 -2
  334. package/testing/core/mocking/mockLink.js +25 -5
  335. package/testing/core/mocking/mockLink.js.map +1 -1
  336. package/utilities/caching/sizes.d.ts +39 -1
  337. package/utilities/caching/sizes.js.map +1 -1
  338. package/utilities/graphql/DocumentTransform.js +1 -1
  339. package/utilities/index.d.ts +1 -0
  340. package/utilities/index.js.map +1 -1
  341. package/utilities/internal/StreamArrayState.d.ts +12 -0
  342. package/utilities/internal/StreamArrayState.js +23 -0
  343. package/utilities/internal/StreamArrayState.js.map +1 -0
  344. package/utilities/internal/addDeferFragmentLabels.d.ts +3 -0
  345. package/utilities/internal/addDeferFragmentLabels.js +30 -0
  346. package/utilities/internal/addDeferFragmentLabels.js.map +1 -0
  347. package/utilities/internal/capitalize.d.ts +7 -0
  348. package/utilities/internal/capitalize.js +9 -0
  349. package/utilities/internal/capitalize.js.map +1 -0
  350. package/utilities/internal/coerceScalarFieldsToParsed.d.ts +9 -0
  351. package/utilities/internal/coerceScalarFieldsToParsed.js +66 -0
  352. package/utilities/internal/coerceScalarFieldsToParsed.js.map +1 -0
  353. package/utilities/internal/constants.d.ts +19 -0
  354. package/utilities/internal/constants.js +19 -0
  355. package/utilities/internal/constants.js.map +1 -1
  356. package/utilities/internal/getDirectiveArgValue.d.ts +9 -0
  357. package/utilities/internal/getDirectiveArgValue.js +16 -0
  358. package/utilities/internal/getDirectiveArgValue.js.map +1 -0
  359. package/utilities/internal/getFragmentDefinition.js +3 -3
  360. package/utilities/internal/getFragmentFromSelection.js +2 -2
  361. package/utilities/internal/getFragmentFromSelection.js.map +1 -1
  362. package/utilities/internal/getFragmentQueryDocument.js +2 -2
  363. package/utilities/internal/getMainDefinition.js +1 -1
  364. package/utilities/internal/getMemoryInternals.d.ts +4 -0
  365. package/utilities/internal/getMemoryInternals.js +6 -0
  366. package/utilities/internal/getMemoryInternals.js.map +1 -1
  367. package/utilities/internal/getQueryDefinition.js +1 -1
  368. package/utilities/internal/getUnwrappedType.d.ts +8 -0
  369. package/utilities/internal/getUnwrappedType.js +17 -0
  370. package/utilities/internal/getUnwrappedType.js.map +1 -0
  371. package/utilities/internal/index.d.ts +16 -2
  372. package/utilities/internal/index.js +12 -1
  373. package/utilities/internal/index.js.map +1 -1
  374. package/utilities/internal/isDeferredFragment.d.ts +9 -0
  375. package/utilities/internal/isDeferredFragment.js +35 -0
  376. package/utilities/internal/isDeferredFragment.js.map +1 -0
  377. package/utilities/internal/isStreamField.d.ts +9 -0
  378. package/utilities/internal/isStreamField.js +34 -0
  379. package/utilities/internal/isStreamField.js.map +1 -0
  380. package/utilities/internal/isTypenameField.d.ts +3 -0
  381. package/utilities/internal/isTypenameField.js +4 -0
  382. package/utilities/internal/isTypenameField.js.map +1 -0
  383. package/utilities/internal/makeStreamInfoTrie.d.ts +8 -0
  384. package/utilities/internal/makeStreamInfoTrie.js +14 -0
  385. package/utilities/internal/makeStreamInfoTrie.js.map +1 -0
  386. package/utilities/internal/removeDirectivesFromDocument.js +1 -1
  387. package/utilities/internal/shouldInclude.js +4 -4
  388. package/utilities/internal/toDiffWithDataState.d.ts +8 -0
  389. package/utilities/internal/toDiffWithDataState.js +17 -0
  390. package/utilities/internal/toDiffWithDataState.js.map +1 -0
  391. package/utilities/internal/types/DeferInfo.d.ts +10 -0
  392. package/utilities/internal/types/DeferInfo.js +2 -0
  393. package/utilities/internal/types/DeferInfo.js.map +1 -0
  394. package/utilities/internal/types/Exact.d.ts +2 -0
  395. package/utilities/internal/types/Exact.js +2 -0
  396. package/utilities/internal/types/Exact.js.map +1 -0
  397. package/utilities/internal/types/IsLooselyEqual.d.ts +10 -0
  398. package/utilities/internal/types/IsLooselyEqual.js +2 -0
  399. package/utilities/internal/types/IsLooselyEqual.js.map +1 -0
  400. package/utilities/internal/types/IsNeverish.d.ts +4 -0
  401. package/utilities/internal/types/IsNeverish.js +2 -0
  402. package/utilities/internal/types/IsNeverish.js.map +1 -0
  403. package/utilities/internal/types/StreamInfoTrie.d.ts +2 -0
  404. package/utilities/internal/types/StreamInfoTrie.js.map +1 -1
  405. package/utilities/internal/valueToObjectRepresentation.js +1 -1
  406. package/utilities/policies/pagination.d.ts +1 -1
  407. package/utilities/policies/pagination.js.map +1 -1
  408. package/utilities/subscriptions/relay/index.js +1 -0
  409. package/utilities/subscriptions/relay/index.js.map +1 -1
  410. package/version.js +1 -1
  411. package/version.js.map +1 -1
  412. package/__cjs/utilities/internal/types/NoInfer.cjs.map +0 -1
  413. package/__cjs/utilities/internal/types/NoInfer.d.cts +0 -35
  414. package/utilities/internal/types/NoInfer.d.ts +0 -35
  415. package/utilities/internal/types/NoInfer.js +0 -2
  416. package/utilities/internal/types/NoInfer.js.map +0 -1
@@ -1,8 +1,10 @@
1
+ import { equal } from "@wry/equality";
2
+ import { Trie } from "@wry/trie";
1
3
  import { Kind } from "graphql";
2
4
  import { wrap } from "optimism";
3
5
  import { addTypenameToDocument, cacheSizes, canonicalStringify, isReference, } from "@apollo/client/utilities";
4
6
  import { __DEV__ } from "@apollo/client/utilities/environment";
5
- import { DeepMerger, getDefaultValues, getFragmentFromSelection, getMainDefinition, getQueryDefinition, isArray, isField, isNonNullObject, makeReference, maybeDeepFreeze, mergeDeepArray, resultKeyNameFromField, shouldInclude, } from "@apollo/client/utilities/internal";
7
+ import { compact, DeepMerger, getDefaultValues, getDirectiveArgValue, getFragmentFromSelection, getMainDefinition, getQueryDefinition, handleIncrementalSymbol, isArray, isDeferredFragment, isField, isNonNullObject, isStreamField, makeReference, maybeDeepFreeze, mergeDeepArray, resultKeyNameFromField, shouldInclude, } from "@apollo/client/utilities/internal";
6
8
  import { invariant, newInvariantError, } from "@apollo/client/utilities/invariant";
7
9
  import { MissingFieldError } from "../core/types/common.js";
8
10
  import { maybeDependOnExistenceOfEntity, supportsResultCaching, } from "./entityStore.js";
@@ -15,8 +17,11 @@ export class StoreReader {
15
17
  executeSelectionSet;
16
18
  // cached version of executeSubSelectedArray
17
19
  executeSubSelectedArray;
20
+ prunePartialStreamArray;
21
+ prunePartialBoundaries;
18
22
  config;
19
23
  knownResults = new WeakMap();
24
+ keyMaker = new Trie();
20
25
  constructor(config) {
21
26
  this.config = config;
22
27
  // memoized functions in this class will be "garbage-collected"
@@ -59,47 +64,124 @@ export class StoreReader {
59
64
  }
60
65
  },
61
66
  });
67
+ this.prunePartialBoundaries = wrap((options) => this.prunePartialBoundariesImpl(options), {
68
+ max: cacheSizes["inMemoryCache.prunePartialBoundaries"] ||
69
+ 20000 /* defaultCacheSizes["inMemoryCache.prunePartialBoundaries"] */,
70
+ makeCacheKey: ({ boundaries, context, selectionSet }) => {
71
+ if (supportsResultCaching(context.store)) {
72
+ return this.keyMaker.lookup(selectionSet, boundaries, context.streamInfo, context.deferInfo);
73
+ }
74
+ },
75
+ });
76
+ this.prunePartialStreamArray = wrap((options) => {
77
+ const { field, context, path } = options;
78
+ if (isStreamField(field, context.variables)) {
79
+ context.streamInfo?.lookupArray(path).state.depend();
80
+ }
81
+ return this.prunePartialStreamArrayImpl(options);
82
+ }, {
83
+ max: cacheSizes["inMemoryCache.prunePartialStreamArray"] ||
84
+ 20000 /* defaultCacheSizes["inMemoryCache.prunePartialStreamArray"] */,
85
+ makeCacheKey: ({ field, context, boundaries }) => {
86
+ if (supportsResultCaching(context.store)) {
87
+ return this.keyMaker.lookup(field, boundaries, context.streamInfo, context.deferInfo);
88
+ }
89
+ },
90
+ });
62
91
  }
63
- /**
64
- * Given a store and a query, return as much of the result as possible and
65
- * identify if any data was missing from the store.
66
- */
67
- diffQueryAgainstStore({ store, query, rootId = "ROOT_QUERY", variables, returnPartialData = true, }) {
92
+ diffQueryAgainstStore({ store, query, rootId = "ROOT_QUERY", variables, returnPartialData = true, ...options }) {
93
+ const returnIncremental = Object.hasOwn(options, handleIncrementalSymbol);
68
94
  const policies = this.config.cache.policies;
69
- variables = {
70
- ...getDefaultValues(getQueryDefinition(query)),
71
- ...variables,
72
- };
95
+ variables = compact(getDefaultValues(getQueryDefinition(query)), variables);
73
96
  const rootRef = makeReference(rootId);
74
- const execResult = this.executeSelectionSet({
97
+ const context = {
98
+ store,
99
+ query,
100
+ policies,
101
+ variables,
102
+ varString: canonicalStringify(variables),
103
+ ...extractFragmentContext(query, this.config.fragments),
104
+ ...options[handleIncrementalSymbol],
105
+ };
106
+ let execResult = this.executeSelectionSet({
75
107
  selectionSet: getMainDefinition(query).selectionSet,
76
108
  objectOrReference: rootRef,
77
109
  enclosingRef: rootRef,
78
- context: {
79
- store,
80
- query,
81
- policies,
82
- variables,
83
- varString: canonicalStringify(variables),
84
- ...extractFragmentContext(query, this.config.fragments),
85
- },
110
+ context,
86
111
  });
87
- let missing;
88
- if (execResult.missing) {
89
- missing = new MissingFieldError(firstMissing(execResult.missing), execResult.missing, query, variables);
112
+ // Since executeSelectionSet doesn't know about returnPartialData, we need
113
+ // to perform a 2nd pass over the result to prune any fields inside
114
+ // partial defer boundaries. The "deferPartial" data state tells us that the
115
+ // only part of the result that contributed to its partiality is data inside
116
+ // a defer boundary.
117
+ if (returnIncremental && shouldPrune(execResult, context)) {
118
+ const pruned = this.prunePartialBoundaries({
119
+ selectionSet: getMainDefinition(query).selectionSet,
120
+ data: execResult.result,
121
+ boundaries: execResult.partialBoundaries,
122
+ context,
123
+ path: [],
124
+ });
125
+ const changed = execResult.result !== pruned.result;
126
+ // It's possible that pruning didn't actually change the result which can
127
+ // happen if a defer boundary is misclassified as "deferPartial" instead
128
+ // of "streaming" (sibling defer boundaries with overlapping selection
129
+ // sets, one of which is complete). In this case, pruning corrects the
130
+ // dataState to streaming instead of leaving it as partial. If we tolerate
131
+ // partial results and pruning changed the result by dropping fields, then
132
+ // we want to keep the original execResult which contains the partial
133
+ // data.
134
+ if (!changed || !returnPartialData) {
135
+ // Omit `missing` property since pruning puts it in a state that doesn't
136
+ // report missing fields.
137
+ execResult = {
138
+ result: pruned.result,
139
+ partialBoundaries: execResult.partialBoundaries,
140
+ dataState: pruned.dataState,
141
+ };
142
+ }
90
143
  }
91
- const complete = !missing;
92
- const { result } = execResult;
93
- return {
94
- result: complete ? result
95
- : returnPartialData ?
96
- Object.keys(result).length === 0 ?
97
- null
98
- : result
99
- : null,
144
+ let { result, dataState, missing } = execResult;
145
+ // Evaluate this condition before we start mucking with dataState for the
146
+ // publicly returned value
147
+ const includeMissing = !!missing &&
148
+ // We don't need to report missing fields inside defer boundaries since
149
+ // the "streaming" dataState tells us that the only missing fields in
150
+ // the object is inside a defer boundary.
151
+ (dataState !== "streaming" || !returnIncremental);
152
+ // If we get all root @defer boundaries with an empty result, report it as
153
+ // empty instead of streaming.
154
+ if (dataState === "streaming" && Object.keys(result).length === 0) {
155
+ dataState = "empty";
156
+ }
157
+ let missingError;
158
+ if (dataState === "deferPartial" ||
159
+ dataState === "streamPartial" ||
160
+ (dataState === "streaming" && !returnIncremental)) {
161
+ dataState = "partial";
162
+ }
163
+ if (dataState === "partial" && !returnPartialData) {
164
+ dataState = "empty";
165
+ }
166
+ const complete = dataState === "complete";
167
+ const keepResult = complete ||
168
+ dataState === "streaming" ||
169
+ (returnPartialData && Object.keys(result).length);
170
+ const diffResult = {
171
+ result: keepResult ? result : null,
100
172
  complete,
101
- missing,
173
+ get missing() {
174
+ if (includeMissing) {
175
+ missingError ||= new MissingFieldError(firstMissing(missing), missing, query, variables);
176
+ }
177
+ return missingError;
178
+ },
102
179
  };
180
+ if (returnIncremental) {
181
+ diffResult.dataState =
182
+ dataState;
183
+ }
184
+ return diffResult;
103
185
  }
104
186
  isFresh(result, parent, selectionSet, context) {
105
187
  if (supportsResultCaching(context.store) &&
@@ -118,14 +200,18 @@ export class StoreReader {
118
200
  !context.store.has(objectOrReference.__ref)) {
119
201
  return {
120
202
  result: {},
203
+ dataState: "empty",
121
204
  missing: `Dangling reference to missing ${objectOrReference.__ref} object`,
205
+ partialBoundaries: new PartialBoundaries(),
122
206
  };
123
207
  }
124
208
  const { variables, policies, store } = context;
125
209
  const typename = store.getFieldValue(objectOrReference, "__typename");
126
210
  const objectsToMerge = [];
211
+ let dataState;
127
212
  let missing;
128
213
  const missingMerger = new DeepMerger();
214
+ const partialBoundaries = new PartialBoundaries();
129
215
  if (typeof typename === "string" && !policies.rootIdsByTypename[typename]) {
130
216
  // Ensure we always include a default value for the __typename
131
217
  // field, if we have one. Note that this field can be overridden by other
@@ -138,7 +224,7 @@ export class StoreReader {
138
224
  [resultName]: result.missing,
139
225
  });
140
226
  }
141
- return result.result;
227
+ return result;
142
228
  }
143
229
  const workSet = new Set(selectionSet.selections);
144
230
  workSet.forEach((selection) => {
@@ -156,36 +242,75 @@ export class StoreReader {
156
242
  const resultName = resultKeyNameFromField(selection);
157
243
  if (fieldValue === void 0) {
158
244
  if (!addTypenameToDocument.added(selection)) {
245
+ const id = isReference(objectOrReference) ? objectOrReference.__ref
246
+ : objectOrReference ? policies.identify(objectOrReference)[0]
247
+ : undefined;
159
248
  missing = missingMerger.merge(missing, {
160
- [resultName]: `Can't find field '${selection.name.value}' on ${isReference(objectOrReference) ?
161
- objectOrReference.__ref + " object"
162
- : "object " + JSON.stringify(objectOrReference, null, 2)}`,
249
+ [resultName]: `Can't find field '${selection.name.value}' on ${id ?
250
+ `${id} object`
251
+ : `object ${JSON.stringify(objectOrReference || {}, null, 2)}`}`,
163
252
  });
253
+ dataState = mergeDataState(dataState, "empty");
164
254
  }
165
255
  }
166
256
  else if (isArray(fieldValue)) {
167
257
  if (fieldValue.length > 0) {
168
- fieldValue = handleMissing(this.executeSubSelectedArray({
258
+ const execResult = handleMissing(this.executeSubSelectedArray({
169
259
  field: selection,
170
260
  array: fieldValue,
171
261
  enclosingRef,
172
262
  context,
173
263
  }), resultName);
264
+ fieldValue = execResult.result;
265
+ dataState = mergeDataState(dataState, execResult.dataState);
266
+ partialBoundaries.set(resultName, execResult.partialBoundaries);
267
+ }
268
+ else {
269
+ dataState = mergeDataState(dataState, "complete");
174
270
  }
175
271
  }
176
272
  else if (!selection.selectionSet) {
177
- // do nothing
273
+ // Auto-inserted __typename should not affect dataState (see empty
274
+ // @defer boundaries, which must stay "empty" → parent "streaming").
275
+ if (!addTypenameToDocument.added(selection)) {
276
+ dataState = mergeDataState(dataState, "complete");
277
+ }
178
278
  }
179
279
  else if (fieldValue != null) {
280
+ if (__DEV__) {
281
+ const fieldName = selection.name.value;
282
+ if (typename) {
283
+ const policy = policies["getFieldPolicy"](typename, fieldName);
284
+ if (policy?.scalar) {
285
+ __DEV__ && invariant.warn(116, `${typename}.${fieldName}`, policy.scalar);
286
+ }
287
+ }
288
+ }
180
289
  // In this case, because we know the field has a selection set,
181
290
  // it must be trying to query a GraphQLObjectType, which is why
182
291
  // fieldValue must be != null.
183
- fieldValue = handleMissing(this.executeSelectionSet({
292
+ const execResult = handleMissing(this.executeSelectionSet({
184
293
  selectionSet: selection.selectionSet,
185
294
  objectOrReference: fieldValue,
186
295
  enclosingRef: isReference(fieldValue) ? fieldValue : enclosingRef,
187
296
  context,
188
297
  }), resultName);
298
+ fieldValue = execResult.result;
299
+ partialBoundaries.set(resultName, execResult.partialBoundaries);
300
+ // If the object's fields resolved to an "empty" dataState (e.g. no
301
+ // field resolved with a non-undefined value), but the fieldValue
302
+ // object itself is present, this object should be considered
303
+ // partial instead of empty. This also ensures defer boundaries that
304
+ // select this object remain as partial defer boundaries rather than
305
+ // mistakenly get reported as streaming. This is especially necessary
306
+ // when combined with GraphQL Codegen which generates its type and
307
+ // relies on the outer object to be absent when its fields haven't
308
+ // streamed in. Reporting the defer boundary as "streaming" instead of
309
+ // "partial" would otherwise have the potential to cause runtime
310
+ // crashes since the runtime values and types would not line up
311
+ // properly (types expect object to be undefined, but its instead
312
+ // present without its fields)
313
+ dataState = mergeDataState(dataState, execResult.dataState === "empty" ? "partial" : execResult.dataState);
189
314
  }
190
315
  if (fieldValue !== void 0) {
191
316
  objectsToMerge.push({ [resultName]: fieldValue });
@@ -194,15 +319,60 @@ export class StoreReader {
194
319
  else {
195
320
  const fragment = getFragmentFromSelection(selection, context.lookupFragment);
196
321
  if (!fragment && selection.kind === Kind.FRAGMENT_SPREAD) {
197
- throw newInvariantError(112, selection.name.value);
322
+ throw newInvariantError(117, selection.name.value);
198
323
  }
199
324
  if (fragment && policies.fragmentMatches(fragment, typename)) {
200
- fragment.selectionSet.selections.forEach(workSet.add, workSet);
325
+ const isDeferBoundary = isDeferredFragment(selection, context.variables);
326
+ // Prior to 4.3, this branch just flattened the fragment's
327
+ // selectionSet into the existing workSet so that it continued
328
+ // iterating as if the fragment didn't exist. The cache is
329
+ // incremental aware as of 4.3 and as such, we need to resolve the
330
+ // per-fragment selection set so that we can properly strip partial
331
+ // defer fragment data when returnPartialData is false. We need to
332
+ // call execSelectionSetImpl directly (non-cached version) so that we
333
+ // scope the dataState correctly for its fields. Using the cached
334
+ // executeSelectionSet can result in cache poisoning when combined
335
+ // with the fragment registry where it might cache either a) an error
336
+ // thrown when a registered fragment references a named fragment that
337
+ // the query is expected to supply and doesn't or b) resolve to the
338
+ // wrong data result when combined with queries that provide different
339
+ // implementations of the same fragment (see inmemory/fragmentRegistry and
340
+ // cache.diff/incremental tests which provide guards against this
341
+ // behavior).
342
+ const execResult = this.execSelectionSetImpl({
343
+ selectionSet: fragment.selectionSet,
344
+ objectOrReference,
345
+ enclosingRef,
346
+ context,
347
+ });
348
+ const { result, dataState: nextDataState } = execResult;
349
+ partialBoundaries.merge(execResult.partialBoundaries);
350
+ if (result !== void 0) {
351
+ objectsToMerge.push(result);
352
+ }
353
+ if (execResult.missing) {
354
+ missing = missingMerger.merge(missing, execResult.missing);
355
+ }
356
+ if (isDeferBoundary &&
357
+ (nextDataState === "partial" || nextDataState === "empty")) {
358
+ partialBoundaries.add(selection);
359
+ }
360
+ dataState = mergeDataState(dataState, isDeferBoundary ?
361
+ nextDataState === "empty" ? "streaming"
362
+ : nextDataState === "partial" ? "deferPartial"
363
+ : nextDataState
364
+ : nextDataState);
201
365
  }
202
366
  }
203
367
  });
368
+ dataState ||= "complete";
204
369
  const result = mergeDeepArray(objectsToMerge);
205
- const finalResult = { result, missing };
370
+ const finalResult = {
371
+ result,
372
+ missing,
373
+ dataState,
374
+ partialBoundaries,
375
+ };
206
376
  const frozen = maybeDeepFreeze(finalResult);
207
377
  // Store this result with its selection set so that we can quickly
208
378
  // recognize it again in the StoreReader#isFresh method.
@@ -213,8 +383,11 @@ export class StoreReader {
213
383
  }
214
384
  // Uncached version of executeSubSelectedArray.
215
385
  execSubSelectedArrayImpl({ field, array, enclosingRef, context, }) {
386
+ let dataState = "complete";
216
387
  let missing;
217
388
  let missingMerger = new DeepMerger();
389
+ const partialBoundaries = new PartialBoundaries();
390
+ const isStreamed = isStreamField(field, context.variables);
218
391
  function handleMissing(childResult, i) {
219
392
  if (childResult.missing) {
220
393
  missing = missingMerger.merge(missing, { [i]: childResult.missing });
@@ -229,23 +402,36 @@ export class StoreReader {
229
402
  if (item === null) {
230
403
  return null;
231
404
  }
405
+ let execResult;
232
406
  // This is a nested array, recurse
233
407
  if (isArray(item)) {
234
- return handleMissing(this.executeSubSelectedArray({
408
+ execResult = this.executeSubSelectedArray({
235
409
  field,
236
410
  array: item,
237
411
  enclosingRef,
238
412
  context,
239
- }), i);
413
+ });
240
414
  }
241
- // This is an object, run the selection set on it
242
- if (field.selectionSet) {
243
- return handleMissing(this.executeSelectionSet({
415
+ else if (field.selectionSet) {
416
+ execResult = this.executeSelectionSet({
244
417
  selectionSet: field.selectionSet,
245
418
  objectOrReference: item,
246
419
  enclosingRef: isReference(item) ? item : enclosingRef,
247
420
  context,
248
- }), i);
421
+ });
422
+ }
423
+ if (execResult) {
424
+ const { dataState: nextDataState } = execResult;
425
+ partialBoundaries.set(i, nextDataState === "partial" ?
426
+ // avoid mutating the execResult partialBoundaries object
427
+ execResult.partialBoundaries.clone().add(field)
428
+ : execResult.partialBoundaries);
429
+ dataState = mergeDataState(dataState, isStreamed ?
430
+ nextDataState === "partial" ?
431
+ "streamPartial"
432
+ : nextDataState
433
+ : nextDataState);
434
+ return handleMissing(execResult, i);
249
435
  }
250
436
  if (__DEV__) {
251
437
  assertSelectionSetForIdValue(context.store, field, item);
@@ -254,9 +440,162 @@ export class StoreReader {
254
440
  });
255
441
  return {
256
442
  result: array,
443
+ dataState,
257
444
  missing,
445
+ partialBoundaries,
258
446
  };
259
447
  }
448
+ prunePartialBoundariesImpl({ boundaries, context, data, path, selectionSet, }) {
449
+ const { variables, lookupFragment, policies } = context;
450
+ if (data == null || !boundaries) {
451
+ return { result: data, dataState: "complete" };
452
+ }
453
+ const merger = new DeepMerger();
454
+ let changed = false;
455
+ let dataState = "complete";
456
+ const result = {};
457
+ // __typename might not be part of the selection set, so preserve it when
458
+ // available, otherwise it gets removed since it's never visited when
459
+ // iterating the selection set.
460
+ if (Object.hasOwn(data, "__typename")) {
461
+ result.__typename = data.__typename;
462
+ }
463
+ const workSet = new Set(selectionSet.selections);
464
+ workSet.forEach((selection) => {
465
+ if (!shouldInclude(selection, variables))
466
+ return;
467
+ if (isField(selection)) {
468
+ const resultName = resultKeyNameFromField(selection);
469
+ if (!Object.hasOwn(data, resultName)) {
470
+ return;
471
+ }
472
+ const fieldValue = data[resultName];
473
+ if (Array.isArray(fieldValue)) {
474
+ const pruned = this.prunePartialStreamArray({
475
+ field: selection,
476
+ array: fieldValue,
477
+ boundaries: boundaries.getChild(resultName),
478
+ context,
479
+ path: path.concat(resultName),
480
+ });
481
+ changed ||= pruned.result !== fieldValue;
482
+ result[resultName] = pruned.result;
483
+ dataState = mergeDataState(dataState, pruned.dataState);
484
+ }
485
+ else if (!selection.selectionSet) {
486
+ result[resultName] = fieldValue;
487
+ }
488
+ else {
489
+ const pruned = this.prunePartialBoundaries({
490
+ data: fieldValue,
491
+ selectionSet: selection.selectionSet,
492
+ boundaries: boundaries.getChild(resultName),
493
+ context,
494
+ path: path.concat(resultName),
495
+ });
496
+ changed ||= pruned.result !== fieldValue;
497
+ dataState = mergeDataState(dataState, pruned.dataState);
498
+ // A response key can be selected by more than one selection (e.g. a
499
+ // field and an overlapping fragment), so merge their kept fields.
500
+ result[resultName] =
501
+ Object.hasOwn(result, resultName) ?
502
+ merger.merge(result[resultName], pruned.result)
503
+ : pruned.result;
504
+ }
505
+ return;
506
+ }
507
+ // Note: we do NOT set `changed` to true anywhere in this branch of the
508
+ // conditional, despite the fact that we might have encountered a
509
+ // partial @defer boundary. Dropping a fragment does not guarantee keys
510
+ // are actually dropped which can happen when overlapping sibling
511
+ // selections contribute to the construction of the object. The final
512
+ // Object.keys(result).length check actually detects whether keys were
513
+ // dropped or not.
514
+ const fragment = getFragmentFromSelection(selection, lookupFragment);
515
+ let prune = false;
516
+ if (context.deferInfo && isDeferredFragment(selection, variables)) {
517
+ const directive = selection.directives?.find((d) => d.name.value === "defer");
518
+ const label = directive && getDirectiveArgValue(directive, "label", Kind.STRING);
519
+ prune = !!context.deferInfo.peekArray(path.concat(label || []));
520
+ }
521
+ if (fragment && policies.fragmentMatches(fragment, data.__typename)) {
522
+ if (boundaries.has(selection) || prune) {
523
+ dataState = mergeDataState(dataState, "streaming");
524
+ }
525
+ else {
526
+ fragment.selectionSet.selections.forEach(workSet.add, workSet);
527
+ }
528
+ }
529
+ });
530
+ if (Object.keys(result).length !== Object.keys(data).length) {
531
+ changed = true;
532
+ }
533
+ else if (changed && boundaries.hasSelections()) {
534
+ // Overlapping siblings may rebuild the same fields under a new object
535
+ // identity (e.g. changed === true) after a partial @defer is skipped.
536
+ // We perform a deep equality check to verify whether anything was
537
+ // actually dropped by the partial @defer fragment.
538
+ changed = !equal(result, data);
539
+ }
540
+ return { result: changed ? result : data, dataState };
541
+ }
542
+ prunePartialStreamArrayImpl({ field, array, boundaries, context, path, }) {
543
+ if (!boundaries)
544
+ return { result: array, dataState: "complete" };
545
+ let changed = false;
546
+ let dataState = "complete";
547
+ let pruned = [];
548
+ const state = context.streamInfo?.peekArray(path)?.state;
549
+ const length = Math.min(array.length, state?.truncate ? state.streamPosition : Number.MAX_SAFE_INTEGER);
550
+ for (let i = 0; i < length; i++) {
551
+ const item = array[i];
552
+ let prunedResult = {
553
+ result: item,
554
+ dataState: "complete",
555
+ };
556
+ const boundary = boundaries.getChild(i);
557
+ if (boundary?.has(field)) {
558
+ // The presence of streamInfo determines how we truncate partial
559
+ // stream arrays. Stream info is only given to cache.diff during
560
+ // in-flight requests so we want keep items in the array equal to the
561
+ // total that have streamed in (this is represented by streamPosition
562
+ // above). For all other cache reads, partial stream boundaries are
563
+ // pruned back to an empty array.
564
+ if (state) {
565
+ state.truncate = true;
566
+ pruned = pruned.slice(0, state.streamPosition);
567
+ }
568
+ else {
569
+ pruned = [];
570
+ dataState = "complete";
571
+ }
572
+ break;
573
+ }
574
+ if (Array.isArray(item)) {
575
+ prunedResult = this.prunePartialStreamArray({
576
+ field,
577
+ array: item,
578
+ boundaries: boundaries.getChild(i),
579
+ context,
580
+ path: path.concat(i),
581
+ });
582
+ }
583
+ else if (field.selectionSet) {
584
+ prunedResult = this.prunePartialBoundaries({
585
+ data: item,
586
+ selectionSet: field.selectionSet,
587
+ boundaries: boundaries.getChild(i),
588
+ context,
589
+ path: path.concat(i),
590
+ });
591
+ }
592
+ pruned.push(prunedResult.result);
593
+ changed ||= prunedResult.result !== item;
594
+ dataState = mergeDataState(dataState, prunedResult.dataState);
595
+ }
596
+ changed ||= pruned.length !== array.length;
597
+ return { result: changed ? pruned : array, dataState };
598
+ }
260
599
  }
261
600
  function firstMissing(tree) {
262
601
  try {
@@ -277,7 +616,7 @@ function assertSelectionSetForIdValue(store, field, fieldValue) {
277
616
  if (isNonNullObject(value)) {
278
617
  invariant(
279
618
  !isReference(value),
280
- 113,
619
+ 118,
281
620
  getTypenameFromStoreObject(store, value),
282
621
  field.name.value
283
622
  );
@@ -286,4 +625,102 @@ function assertSelectionSetForIdValue(store, field, fieldValue) {
286
625
  });
287
626
  }
288
627
  }
628
+ // We deliberately leave `returnPartialData` out of `executeSelectionSet`'s
629
+ // cache key. `isFresh` runs during writes and cannot provide a reliable value
630
+ // for this option, so including it would prevent a reliable cache hit.
631
+ //
632
+ // When `returnPartialData` is false, `diffQueryAgainstStore` prunes data from
633
+ // partial @defer boundaries after reading the cached result. `PartialBoundaries`
634
+ // records the selection paths needed for that pass, including empty nodes along
635
+ // a path. Overlapping non-deferred selections must still be rebuilt so fields
636
+ // contributed only by a partial deferred sibling are removed. The prune pass
637
+ // can then skip unrelated result branches.
638
+ class PartialBoundaries {
639
+ selections = new Set();
640
+ children = new Map();
641
+ add(selection) {
642
+ this.selections.add(selection);
643
+ return this;
644
+ }
645
+ has(selection) {
646
+ return this.selections.has(selection);
647
+ }
648
+ hasSelections() {
649
+ return this.selections.size > 0;
650
+ }
651
+ getChild(key) {
652
+ return this.children.get(key);
653
+ }
654
+ clone() {
655
+ return new PartialBoundaries().merge(this);
656
+ }
657
+ set(key, boundary) {
658
+ const child = this.getChild(key);
659
+ this.children.set(key,
660
+ // Create a new PartialBoundaries instance to avoid mutating any cached
661
+ // execResult partialBoundaries objects
662
+ child ? child.clone().merge(boundary) : boundary);
663
+ }
664
+ merge(boundaries) {
665
+ boundaries.selections.forEach((selection) => this.add(selection));
666
+ boundaries.children.forEach((child, key) => this.set(key, child));
667
+ return this;
668
+ }
669
+ }
670
+ function shouldPrune({ dataState }, context) {
671
+ if (dataState === "deferPartial" || dataState === "streamPartial") {
672
+ return true;
673
+ }
674
+ if (dataState === "complete" || dataState === "streaming") {
675
+ return !!(
676
+ // If the last cache write repaired a partial @stream array to a
677
+ // complete array, the stream array might contain stale entries after
678
+ // the last written value. We only want to deliver the results up to
679
+ // the index the network wrote so we need to prune it too.
680
+ (context.streamInfo ||
681
+ // The network hasn't delivered these @defer boundaries yet, so prune
682
+ // the (possibly complete) cached data sitting at them.
683
+ context.deferInfo));
684
+ }
685
+ return false;
686
+ }
687
+ // Describes the data state transitions that change the running state when it's
688
+ // combined with the next data state. Omitted object values represent
689
+ // "impossible" merges where the data state should remain the same.
690
+ const DATA_STATE_MERGES = {
691
+ empty: {
692
+ complete: "partial",
693
+ deferPartial: "partial",
694
+ streaming: "partial",
695
+ streamPartial: "partial",
696
+ },
697
+ deferPartial: {
698
+ empty: "partial",
699
+ },
700
+ streamPartial: {
701
+ deferPartial: "deferPartial",
702
+ empty: "partial",
703
+ },
704
+ streaming: {
705
+ deferPartial: "deferPartial",
706
+ empty: "partial",
707
+ streamPartial: "streamPartial",
708
+ },
709
+ complete: {
710
+ deferPartial: "deferPartial",
711
+ streaming: "streaming",
712
+ streamPartial: "streamPartial",
713
+ empty: "partial",
714
+ },
715
+ partial: {},
716
+ };
717
+ function mergeDataState(current, next) {
718
+ if (next === "partial") {
719
+ return "partial";
720
+ }
721
+ if (!current || current === next) {
722
+ return next;
723
+ }
724
+ return DATA_STATE_MERGES[current][next] || current;
725
+ }
289
726
  //# sourceMappingURL=readFromStore.js.map