@isograph/react 0.4.3 → 0.5.1

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 (327) hide show
  1. package/.turbo/turbo-compile-libs.log +10 -3
  2. package/dist/_virtual/rolldown_runtime.js +25 -0
  3. package/dist/core/FragmentReference.d.mts +38 -0
  4. package/dist/core/FragmentReference.d.mts.map +1 -0
  5. package/dist/core/FragmentReference.d.ts +31 -27
  6. package/dist/core/FragmentReference.d.ts.map +1 -1
  7. package/dist/core/FragmentReference.js +8 -6
  8. package/dist/core/FragmentReference.mjs +10 -0
  9. package/dist/core/FragmentReference.mjs.map +1 -0
  10. package/dist/core/IsographEnvironment.d.mts +89 -0
  11. package/dist/core/IsographEnvironment.d.mts.map +1 -0
  12. package/dist/core/IsographEnvironment.d.ts +77 -72
  13. package/dist/core/IsographEnvironment.d.ts.map +1 -1
  14. package/dist/core/IsographEnvironment.js +62 -59
  15. package/dist/core/IsographEnvironment.mjs +67 -0
  16. package/dist/core/IsographEnvironment.mjs.map +1 -0
  17. package/dist/core/PromiseWrapper.d.mts +36 -0
  18. package/dist/core/PromiseWrapper.d.mts.map +1 -0
  19. package/dist/core/PromiseWrapper.d.ts +27 -18
  20. package/dist/core/PromiseWrapper.d.ts.map +1 -1
  21. package/dist/core/PromiseWrapper.js +45 -43
  22. package/dist/core/PromiseWrapper.mjs +49 -0
  23. package/dist/core/PromiseWrapper.mjs.map +1 -0
  24. package/dist/core/areEqualWithDeepComparison.js +56 -108
  25. package/dist/core/areEqualWithDeepComparison.mjs +62 -0
  26. package/dist/core/areEqualWithDeepComparison.mjs.map +1 -0
  27. package/dist/core/brand.d.mts +19 -0
  28. package/dist/core/brand.d.mts.map +1 -0
  29. package/dist/core/brand.d.ts +18 -1
  30. package/dist/core/brand.d.ts.map +1 -1
  31. package/dist/core/cache.d.mts +20 -0
  32. package/dist/core/cache.d.mts.map +1 -0
  33. package/dist/core/cache.d.ts +18 -34
  34. package/dist/core/cache.d.ts.map +1 -1
  35. package/dist/core/cache.js +210 -516
  36. package/dist/core/cache.mjs +237 -0
  37. package/dist/core/cache.mjs.map +1 -0
  38. package/dist/core/check.d.mts +28 -0
  39. package/dist/core/check.d.mts.map +1 -0
  40. package/dist/core/check.d.ts +24 -18
  41. package/dist/core/check.d.ts.map +1 -1
  42. package/dist/core/check.js +80 -124
  43. package/dist/core/check.mjs +84 -0
  44. package/dist/core/check.mjs.map +1 -0
  45. package/dist/core/componentCache.js +10 -34
  46. package/dist/core/componentCache.mjs +12 -0
  47. package/dist/core/componentCache.mjs.map +1 -0
  48. package/dist/core/entrypoint.d.mts +99 -0
  49. package/dist/core/entrypoint.d.mts.map +1 -0
  50. package/dist/core/entrypoint.d.ts +83 -68
  51. package/dist/core/entrypoint.d.ts.map +1 -1
  52. package/dist/core/entrypoint.js +6 -5
  53. package/dist/core/entrypoint.mjs +8 -0
  54. package/dist/core/entrypoint.mjs.map +1 -0
  55. package/dist/core/garbageCollection.d.mts +18 -0
  56. package/dist/core/garbageCollection.d.mts.map +1 -0
  57. package/dist/core/garbageCollection.d.ts +15 -10
  58. package/dist/core/garbageCollection.d.ts.map +1 -1
  59. package/dist/core/garbageCollection.js +82 -99
  60. package/dist/core/garbageCollection.mjs +89 -0
  61. package/dist/core/garbageCollection.mjs.map +1 -0
  62. package/dist/core/getOrCreateCacheForArtifact.js +37 -0
  63. package/dist/core/getOrCreateCacheForArtifact.mjs +38 -0
  64. package/dist/core/getOrCreateCacheForArtifact.mjs.map +1 -0
  65. package/dist/core/logging.d.mts +95 -0
  66. package/dist/core/logging.d.mts.map +1 -0
  67. package/dist/core/logging.d.ts +78 -60
  68. package/dist/core/logging.d.ts.map +1 -1
  69. package/dist/core/logging.js +17 -18
  70. package/dist/core/logging.mjs +20 -0
  71. package/dist/core/logging.mjs.map +1 -0
  72. package/dist/core/makeNetworkRequest.d.mts +13 -0
  73. package/dist/core/makeNetworkRequest.d.mts.map +1 -0
  74. package/dist/core/makeNetworkRequest.d.ts +12 -8
  75. package/dist/core/makeNetworkRequest.d.ts.map +1 -1
  76. package/dist/core/makeNetworkRequest.js +188 -195
  77. package/dist/core/makeNetworkRequest.mjs +195 -0
  78. package/dist/core/makeNetworkRequest.mjs.map +1 -0
  79. package/dist/core/optimisticProxy.d.mts +43 -0
  80. package/dist/core/optimisticProxy.d.mts.map +1 -0
  81. package/dist/core/optimisticProxy.d.ts +43 -0
  82. package/dist/core/optimisticProxy.d.ts.map +1 -0
  83. package/dist/core/optimisticProxy.js +273 -0
  84. package/dist/core/optimisticProxy.mjs +268 -0
  85. package/dist/core/optimisticProxy.mjs.map +1 -0
  86. package/dist/core/read.d.mts +29 -0
  87. package/dist/core/read.d.mts.map +1 -0
  88. package/dist/core/read.d.ts +23 -27
  89. package/dist/core/read.d.ts.map +1 -1
  90. package/dist/core/read.js +438 -618
  91. package/dist/core/read.mjs +456 -0
  92. package/dist/core/read.mjs.map +1 -0
  93. package/dist/core/reader.d.mts +89 -0
  94. package/dist/core/reader.d.mts.map +1 -0
  95. package/dist/core/reader.d.ts +78 -74
  96. package/dist/core/reader.d.ts.map +1 -1
  97. package/dist/core/startUpdate.js +118 -156
  98. package/dist/core/startUpdate.mjs +125 -0
  99. package/dist/core/startUpdate.mjs.map +1 -0
  100. package/dist/core/subscribe.d.mts +12 -0
  101. package/dist/core/subscribe.d.mts.map +1 -0
  102. package/dist/core/subscribe.d.ts +12 -0
  103. package/dist/core/subscribe.d.ts.map +1 -0
  104. package/dist/core/subscribe.js +79 -0
  105. package/dist/core/subscribe.mjs +79 -0
  106. package/dist/core/subscribe.mjs.map +1 -0
  107. package/dist/core/util.d.mts +27 -0
  108. package/dist/core/util.d.mts.map +1 -0
  109. package/dist/core/util.d.ts +21 -17
  110. package/dist/core/util.d.ts.map +1 -1
  111. package/dist/core/util.js +22 -2
  112. package/dist/core/util.mjs +21 -0
  113. package/dist/core/util.mjs.map +1 -0
  114. package/dist/core/writeData.d.mts +11 -0
  115. package/dist/core/writeData.d.mts.map +1 -0
  116. package/dist/core/writeData.d.ts +11 -0
  117. package/dist/core/writeData.d.ts.map +1 -0
  118. package/dist/core/writeData.js +41 -0
  119. package/dist/core/writeData.mjs +42 -0
  120. package/dist/core/writeData.mjs.map +1 -0
  121. package/dist/index.d.mts +32 -0
  122. package/dist/index.d.ts +32 -29
  123. package/dist/index.js +70 -68
  124. package/dist/index.mjs +31 -0
  125. package/dist/loadable-hooks/useClientSideDefer.d.mts +12 -0
  126. package/dist/loadable-hooks/useClientSideDefer.d.mts.map +1 -0
  127. package/dist/loadable-hooks/useClientSideDefer.d.ts +10 -8
  128. package/dist/loadable-hooks/useClientSideDefer.d.ts.map +1 -1
  129. package/dist/loadable-hooks/useClientSideDefer.js +14 -12
  130. package/dist/loadable-hooks/useClientSideDefer.mjs +14 -0
  131. package/dist/loadable-hooks/useClientSideDefer.mjs.map +1 -0
  132. package/dist/loadable-hooks/useConnectionSpecPagination.d.mts +33 -0
  133. package/dist/loadable-hooks/useConnectionSpecPagination.d.mts.map +1 -0
  134. package/dist/loadable-hooks/useConnectionSpecPagination.d.ts +27 -21
  135. package/dist/loadable-hooks/useConnectionSpecPagination.d.ts.map +1 -1
  136. package/dist/loadable-hooks/useConnectionSpecPagination.js +133 -158
  137. package/dist/loadable-hooks/useConnectionSpecPagination.mjs +134 -0
  138. package/dist/loadable-hooks/useConnectionSpecPagination.mjs.map +1 -0
  139. package/dist/loadable-hooks/useImperativeExposedMutationField.d.mts +8 -0
  140. package/dist/loadable-hooks/useImperativeExposedMutationField.d.mts.map +1 -0
  141. package/dist/loadable-hooks/useImperativeExposedMutationField.d.ts +6 -3
  142. package/dist/loadable-hooks/useImperativeExposedMutationField.d.ts.map +1 -1
  143. package/dist/loadable-hooks/useImperativeExposedMutationField.js +9 -12
  144. package/dist/loadable-hooks/useImperativeExposedMutationField.mjs +11 -0
  145. package/dist/loadable-hooks/useImperativeExposedMutationField.mjs.map +1 -0
  146. package/dist/loadable-hooks/useImperativeLoadableField.d.mts +19 -0
  147. package/dist/loadable-hooks/useImperativeLoadableField.d.mts.map +1 -0
  148. package/dist/loadable-hooks/useImperativeLoadableField.d.ts +15 -11
  149. package/dist/loadable-hooks/useImperativeLoadableField.d.ts.map +1 -1
  150. package/dist/loadable-hooks/useImperativeLoadableField.js +16 -12
  151. package/dist/loadable-hooks/useImperativeLoadableField.mjs +17 -0
  152. package/dist/loadable-hooks/useImperativeLoadableField.mjs.map +1 -0
  153. package/dist/loadable-hooks/useSkipLimitPagination.d.mts +24 -0
  154. package/dist/loadable-hooks/useSkipLimitPagination.d.mts.map +1 -0
  155. package/dist/loadable-hooks/useSkipLimitPagination.d.ts +19 -15
  156. package/dist/loadable-hooks/useSkipLimitPagination.d.ts.map +1 -1
  157. package/dist/loadable-hooks/useSkipLimitPagination.js +118 -160
  158. package/dist/loadable-hooks/useSkipLimitPagination.mjs +119 -0
  159. package/dist/loadable-hooks/useSkipLimitPagination.mjs.map +1 -0
  160. package/dist/react/FragmentReader.d.mts +18 -0
  161. package/dist/react/FragmentReader.d.mts.map +1 -0
  162. package/dist/react/FragmentReader.d.ts +16 -7
  163. package/dist/react/FragmentReader.d.ts.map +1 -1
  164. package/dist/react/FragmentReader.js +8 -7
  165. package/dist/react/FragmentReader.mjs +10 -0
  166. package/dist/react/FragmentReader.mjs.map +1 -0
  167. package/dist/react/FragmentRenderer.d.mts +20 -0
  168. package/dist/react/FragmentRenderer.d.mts.map +1 -0
  169. package/dist/react/FragmentRenderer.d.ts +18 -13
  170. package/dist/react/FragmentRenderer.d.ts.map +1 -1
  171. package/dist/react/FragmentRenderer.js +11 -33
  172. package/dist/react/FragmentRenderer.mjs +12 -0
  173. package/dist/react/FragmentRenderer.mjs.map +1 -0
  174. package/dist/react/IsographEnvironmentProvider.d.mts +17 -0
  175. package/dist/react/IsographEnvironmentProvider.d.mts.map +1 -0
  176. package/dist/react/IsographEnvironmentProvider.d.ts +15 -9
  177. package/dist/react/IsographEnvironmentProvider.d.ts.map +1 -1
  178. package/dist/react/IsographEnvironmentProvider.js +15 -39
  179. package/dist/react/IsographEnvironmentProvider.mjs +17 -0
  180. package/dist/react/IsographEnvironmentProvider.mjs.map +1 -0
  181. package/dist/react/LoadableFieldReader.d.mts +21 -0
  182. package/dist/react/LoadableFieldReader.d.mts.map +1 -0
  183. package/dist/react/LoadableFieldReader.d.ts +20 -11
  184. package/dist/react/LoadableFieldReader.d.ts.map +1 -1
  185. package/dist/react/LoadableFieldReader.js +13 -8
  186. package/dist/react/LoadableFieldReader.mjs +14 -0
  187. package/dist/react/LoadableFieldReader.mjs.map +1 -0
  188. package/dist/react/LoadableFieldRenderer.d.mts +22 -0
  189. package/dist/react/LoadableFieldRenderer.d.mts.map +1 -0
  190. package/dist/react/LoadableFieldRenderer.d.ts +21 -12
  191. package/dist/react/LoadableFieldRenderer.d.ts.map +1 -1
  192. package/dist/react/LoadableFieldRenderer.js +13 -35
  193. package/dist/react/LoadableFieldRenderer.mjs +14 -0
  194. package/dist/react/LoadableFieldRenderer.mjs.map +1 -0
  195. package/dist/react/RenderAfterCommit__DO_NOT_USE.d.mts +18 -0
  196. package/dist/react/RenderAfterCommit__DO_NOT_USE.d.mts.map +1 -0
  197. package/dist/react/RenderAfterCommit__DO_NOT_USE.d.ts +11 -3
  198. package/dist/react/RenderAfterCommit__DO_NOT_USE.d.ts.map +1 -1
  199. package/dist/react/RenderAfterCommit__DO_NOT_USE.js +17 -13
  200. package/dist/react/RenderAfterCommit__DO_NOT_USE.mjs +18 -0
  201. package/dist/react/RenderAfterCommit__DO_NOT_USE.mjs.map +1 -0
  202. package/dist/react/createIsographEnvironment.d.mts +9 -0
  203. package/dist/react/createIsographEnvironment.d.mts.map +1 -0
  204. package/dist/react/createIsographEnvironment.d.ts +8 -0
  205. package/dist/react/createIsographEnvironment.d.ts.map +1 -0
  206. package/dist/react/createIsographEnvironment.js +10 -0
  207. package/dist/react/createIsographEnvironment.mjs +11 -0
  208. package/dist/react/createIsographEnvironment.mjs.map +1 -0
  209. package/dist/react/maybeUnwrapNetworkRequest.js +11 -0
  210. package/dist/react/maybeUnwrapNetworkRequest.mjs +12 -0
  211. package/dist/react/maybeUnwrapNetworkRequest.mjs.map +1 -0
  212. package/dist/react/useImperativeReference.d.mts +15 -0
  213. package/dist/react/useImperativeReference.d.mts.map +1 -0
  214. package/dist/react/useImperativeReference.d.ts +13 -7
  215. package/dist/react/useImperativeReference.d.ts.map +1 -1
  216. package/dist/react/useImperativeReference.js +34 -32
  217. package/dist/react/useImperativeReference.mjs +35 -0
  218. package/dist/react/useImperativeReference.mjs.map +1 -0
  219. package/dist/react/useLazyReference.d.mts +13 -0
  220. package/dist/react/useLazyReference.d.mts.map +1 -0
  221. package/dist/react/useLazyReference.d.ts +11 -5
  222. package/dist/react/useLazyReference.d.ts.map +1 -1
  223. package/dist/react/useLazyReference.js +17 -40
  224. package/dist/react/useLazyReference.mjs +18 -0
  225. package/dist/react/useLazyReference.mjs.map +1 -0
  226. package/dist/react/useReadAndSubscribe.d.mts +20 -0
  227. package/dist/react/useReadAndSubscribe.d.mts.map +1 -0
  228. package/dist/react/useReadAndSubscribe.d.ts +14 -9
  229. package/dist/react/useReadAndSubscribe.d.ts.map +1 -1
  230. package/dist/react/useReadAndSubscribe.js +57 -39
  231. package/dist/react/useReadAndSubscribe.mjs +59 -0
  232. package/dist/react/useReadAndSubscribe.mjs.map +1 -0
  233. package/dist/react/useRerenderOnChange.d.mts +12 -0
  234. package/dist/react/useRerenderOnChange.d.mts.map +1 -0
  235. package/dist/react/useRerenderOnChange.d.ts +10 -6
  236. package/dist/react/useRerenderOnChange.d.ts.map +1 -1
  237. package/dist/react/useRerenderOnChange.js +16 -20
  238. package/dist/react/useRerenderOnChange.mjs +17 -0
  239. package/dist/react/useRerenderOnChange.mjs.map +1 -0
  240. package/dist/react/useResult.d.mts +8 -0
  241. package/dist/react/useResult.d.mts.map +1 -0
  242. package/dist/react/useResult.d.ts +7 -5
  243. package/dist/react/useResult.d.ts.map +1 -1
  244. package/dist/react/useResult.js +27 -39
  245. package/dist/react/useResult.mjs +30 -0
  246. package/dist/react/useResult.mjs.map +1 -0
  247. package/package.json +26 -19
  248. package/src/core/FragmentReference.ts +13 -7
  249. package/src/core/IsographEnvironment.ts +80 -21
  250. package/src/core/PromiseWrapper.ts +14 -7
  251. package/src/core/areEqualWithDeepComparison.ts +2 -18
  252. package/src/core/brand.ts +18 -0
  253. package/src/core/cache.ts +62 -332
  254. package/src/core/check.ts +30 -26
  255. package/src/core/componentCache.ts +11 -44
  256. package/src/core/entrypoint.ts +50 -9
  257. package/src/core/garbageCollection.ts +81 -28
  258. package/src/core/getOrCreateCacheForArtifact.ts +86 -0
  259. package/src/core/logging.ts +25 -13
  260. package/src/core/makeNetworkRequest.ts +320 -94
  261. package/src/core/optimisticProxy.ts +544 -0
  262. package/src/core/read.ts +251 -198
  263. package/src/core/reader.ts +18 -17
  264. package/src/core/startUpdate.ts +47 -36
  265. package/src/core/subscribe.ts +189 -0
  266. package/src/core/util.ts +26 -0
  267. package/src/core/writeData.ts +79 -0
  268. package/src/index.ts +6 -4
  269. package/src/loadable-hooks/useClientSideDefer.ts +80 -30
  270. package/src/loadable-hooks/useConnectionSpecPagination.ts +54 -35
  271. package/src/loadable-hooks/useImperativeLoadableField.ts +5 -5
  272. package/src/loadable-hooks/useSkipLimitPagination.ts +22 -21
  273. package/src/react/FragmentReader.tsx +3 -1
  274. package/src/react/FragmentRenderer.tsx +8 -1
  275. package/src/react/IsographEnvironmentProvider.tsx +2 -1
  276. package/src/react/LoadableFieldReader.tsx +125 -16
  277. package/src/react/LoadableFieldRenderer.tsx +124 -16
  278. package/src/react/createIsographEnvironment.ts +23 -0
  279. package/src/react/maybeUnwrapNetworkRequest.ts +17 -0
  280. package/src/react/useImperativeReference.ts +25 -15
  281. package/src/react/useLazyReference.ts +20 -10
  282. package/src/react/useReadAndSubscribe.ts +53 -12
  283. package/src/react/useRerenderOnChange.ts +3 -3
  284. package/src/react/useResult.ts +15 -35
  285. package/src/tests/__isograph/Node/asEconomist/resolver_reader.ts +1 -1
  286. package/src/tests/__isograph/Query/linkedUpdate/entrypoint.ts +3 -1
  287. package/src/tests/__isograph/Query/linkedUpdate/raw_response_type.ts +13 -0
  288. package/src/tests/__isograph/Query/linkedUpdate/resolver_reader.ts +1 -1
  289. package/src/tests/__isograph/Query/meName/entrypoint.ts +3 -1
  290. package/src/tests/__isograph/Query/meName/raw_response_type.ts +7 -0
  291. package/src/tests/__isograph/Query/meName/resolver_reader.ts +1 -1
  292. package/src/tests/__isograph/Query/meNameSuccessor/entrypoint.ts +3 -1
  293. package/src/tests/__isograph/Query/meNameSuccessor/raw_response_type.ts +14 -0
  294. package/src/tests/__isograph/Query/meNameSuccessor/resolver_reader.ts +1 -1
  295. package/src/tests/__isograph/Query/nodeField/entrypoint.ts +3 -1
  296. package/src/tests/__isograph/Query/nodeField/raw_response_type.ts +7 -0
  297. package/src/tests/__isograph/Query/nodeField/resolver_reader.ts +1 -1
  298. package/src/tests/__isograph/Query/normalizeUndefinedField/entrypoint.ts +33 -0
  299. package/src/tests/__isograph/Query/normalizeUndefinedField/normalization_ast.ts +25 -0
  300. package/src/tests/__isograph/Query/normalizeUndefinedField/output_type.ts +3 -0
  301. package/src/tests/__isograph/Query/normalizeUndefinedField/param_type.ts +9 -0
  302. package/src/tests/__isograph/Query/normalizeUndefinedField/query_text.ts +6 -0
  303. package/src/tests/__isograph/Query/normalizeUndefinedField/raw_response_type.ts +7 -0
  304. package/src/tests/__isograph/Query/normalizeUndefinedField/resolver_reader.ts +38 -0
  305. package/src/tests/__isograph/Query/startUpdate/entrypoint.ts +3 -1
  306. package/src/tests/__isograph/Query/startUpdate/raw_response_type.ts +8 -0
  307. package/src/tests/__isograph/Query/startUpdate/resolver_reader.ts +1 -1
  308. package/src/tests/__isograph/Query/subquery/entrypoint.ts +3 -1
  309. package/src/tests/__isograph/Query/subquery/raw_response_type.ts +9 -0
  310. package/src/tests/__isograph/Query/subquery/resolver_reader.ts +1 -1
  311. package/src/tests/__isograph/iso.ts +11 -1
  312. package/src/tests/garbageCollection.test.ts +10 -10
  313. package/src/tests/meNameSuccessor.ts +7 -4
  314. package/src/tests/nodeQuery.ts +6 -4
  315. package/src/tests/normalizeData.test.ts +94 -18
  316. package/src/tests/optimisticProxy.test.ts +862 -0
  317. package/src/tests/startUpdate.test.ts +11 -11
  318. package/vitest.config.ts +5 -0
  319. package/dist/core/areEqualWithDeepComparison.d.ts +0 -3
  320. package/dist/core/areEqualWithDeepComparison.d.ts.map +0 -1
  321. package/dist/core/brand.js +0 -2
  322. package/dist/core/componentCache.d.ts +0 -5
  323. package/dist/core/componentCache.d.ts.map +0 -1
  324. package/dist/core/reader.js +0 -2
  325. package/dist/core/startUpdate.d.ts +0 -8
  326. package/dist/core/startUpdate.d.ts.map +0 -1
  327. package/dist/index.d.ts.map +0 -1
package/src/core/read.ts CHANGED
@@ -1,51 +1,54 @@
1
- import { CleanupFn, type ItemCleanupPair } from '@isograph/disposable-types';
1
+ import type { CleanupFn, ItemCleanupPair } from '@isograph/disposable-types';
2
2
  import {
3
3
  getParentRecordKey,
4
4
  insertEmptySetIfMissing,
5
5
  onNextChangeToRecord,
6
6
  type EncounteredIds,
7
7
  } from './cache';
8
- import { FetchOptions } from './check';
8
+ import type { FetchOptions } from './check';
9
9
  import { getOrCreateCachedComponent } from './componentCache';
10
- import {
10
+ import type {
11
11
  IsographEntrypoint,
12
+ ReaderWithRefetchQueries,
12
13
  RefetchQueryNormalizationArtifactWrapper,
13
- type ReaderWithRefetchQueries,
14
14
  } from './entrypoint';
15
- import {
15
+ import type {
16
16
  ExtractData,
17
17
  FragmentReference,
18
+ UnknownTReadFromStore,
18
19
  Variables,
19
- type UnknownTReadFromStore,
20
20
  } from './FragmentReference';
21
+ import type { IsographEnvironment } from './IsographEnvironment';
21
22
  import {
22
23
  assertLink,
23
24
  getOrLoadIsographArtifact,
24
- IsographEnvironment,
25
+ getOrLoadReaderWithRefetchQueries,
25
26
  type DataTypeValue,
26
27
  type StoreLink,
27
28
  type StoreRecord,
28
29
  } from './IsographEnvironment';
29
30
  import { logMessage } from './logging';
30
31
  import { maybeMakeNetworkRequest } from './makeNetworkRequest';
32
+ import { getStoreRecordProxy } from './optimisticProxy';
33
+ import type { PromiseWrapper } from './PromiseWrapper';
31
34
  import {
32
35
  getPromiseState,
33
36
  NOT_SET,
34
- PromiseWrapper,
35
37
  readPromise,
36
38
  wrapPromise,
37
39
  wrapResolvedValue,
38
40
  } from './PromiseWrapper';
39
- import {
41
+ import type {
42
+ LoadablySelectedField,
40
43
  ReaderAst,
41
- type LoadablySelectedField,
42
- type ReaderImperativelyLoadedField,
43
- type ReaderLinkedField,
44
- type ReaderNonLoadableResolverField,
45
- type ReaderScalarField,
44
+ ReaderClientPointer,
45
+ ReaderImperativelyLoadedField,
46
+ ReaderLinkedField,
47
+ ReaderNonLoadableResolverField,
48
+ ReaderScalarField,
46
49
  } from './reader';
47
50
  import { getOrCreateCachedStartUpdate } from './startUpdate';
48
- import { Arguments } from './util';
51
+ import type { Arguments } from './util';
49
52
 
50
53
  export type WithEncounteredRecords<T> = {
51
54
  readonly encounteredRecords: EncounteredIds;
@@ -152,7 +155,7 @@ function readData<TReadFromStore>(
152
155
  root.__typename,
153
156
  );
154
157
  encounteredIds.add(root.__link);
155
- let storeRecord = environment.store[root.__typename]?.[root.__link];
158
+ let storeRecord = getStoreRecordProxy(environment.store, root);
156
159
  if (storeRecord === undefined) {
157
160
  return {
158
161
  kind: 'MissingData',
@@ -161,7 +164,7 @@ function readData<TReadFromStore>(
161
164
  };
162
165
  }
163
166
 
164
- if (storeRecord === null) {
167
+ if (storeRecord == null) {
165
168
  return {
166
169
  kind: 'Success',
167
170
  data: null as any,
@@ -263,13 +266,6 @@ function readData<TReadFromStore>(
263
266
  target[field.alias] = data.data;
264
267
  break;
265
268
  }
266
-
267
- default: {
268
- // Ensure we have covered all variants
269
- let _: never = field;
270
- _;
271
- throw new Error('Unexpected case.');
272
- }
273
269
  }
274
270
  }
275
271
  return {
@@ -313,7 +309,7 @@ export function readLoadablySelectedFieldData(
313
309
  data: (
314
310
  args: any,
315
311
  // TODO get the associated type for FetchOptions from the loadably selected field
316
- fetchOptions?: FetchOptions<any>,
312
+ fetchOptions?: FetchOptions<any, never>,
317
313
  ) => {
318
314
  // TODO we should use the reader AST for this
319
315
  const includeReadOutData = (variables: any, readOutData: any) => {
@@ -342,13 +338,13 @@ export function readLoadablySelectedFieldData(
342
338
  // Fetcher
343
339
  () => {
344
340
  const fragmentReferenceAndDisposeFromEntrypoint = (
345
- entrypoint: IsographEntrypoint<any, any, any>,
341
+ entrypoint: IsographEntrypoint<any, any, any, {}>,
346
342
  ): [FragmentReference<any, any>, CleanupFn] => {
347
- const readerWithRefetchQueries =
348
- entrypoint.readerWithRefetchQueries.kind ===
349
- 'ReaderWithRefetchQueriesLoader'
350
- ? wrapPromise(entrypoint.readerWithRefetchQueries.loader())
351
- : wrapResolvedValue(entrypoint.readerWithRefetchQueries);
343
+ const { fieldName, readerArtifactKind, readerWithRefetchQueries } =
344
+ getOrLoadReaderWithRefetchQueries(
345
+ environment,
346
+ entrypoint.readerWithRefetchQueries,
347
+ );
352
348
  const [networkRequest, disposeNetworkRequest] =
353
349
  maybeMakeNetworkRequest(
354
350
  environment,
@@ -361,7 +357,8 @@ export function readLoadablySelectedFieldData(
361
357
  const fragmentReference: FragmentReference<any, any> = {
362
358
  kind: 'FragmentReference',
363
359
  readerWithRefetchQueries,
364
-
360
+ fieldName,
361
+ readerArtifactKind,
365
362
  // TODO localVariables is not guaranteed to have an id field
366
363
  root,
367
364
  variables: localVariables,
@@ -395,11 +392,12 @@ export function readLoadablySelectedFieldData(
395
392
  | { kind: 'Disposed' } = { kind: 'EntrypointNotLoaded' };
396
393
 
397
394
  const readerWithRefetchQueries = wrapPromise(
398
- isographArtifactPromiseWrapper.promise.then((entrypoint) =>
399
- entrypoint.readerWithRefetchQueries.kind ===
400
- 'ReaderWithRefetchQueriesLoader'
401
- ? entrypoint.readerWithRefetchQueries.loader()
402
- : entrypoint.readerWithRefetchQueries,
395
+ isographArtifactPromiseWrapper.promise.then(
396
+ (entrypoint) =>
397
+ getOrLoadReaderWithRefetchQueries(
398
+ environment,
399
+ entrypoint.readerWithRefetchQueries,
400
+ ).readerWithRefetchQueries.promise,
403
401
  ),
404
402
  );
405
403
  const networkRequest = wrapPromise(
@@ -425,7 +423,8 @@ export function readLoadablySelectedFieldData(
425
423
  const fragmentReference: FragmentReference<any, any> = {
426
424
  kind: 'FragmentReference',
427
425
  readerWithRefetchQueries,
428
-
426
+ fieldName: field.name,
427
+ readerArtifactKind: field.entrypoint.readerArtifactKind,
429
428
  // TODO localVariables is not guaranteed to have an id field
430
429
  root,
431
430
  variables: localVariables,
@@ -522,11 +521,6 @@ function writeQueryArgsToVariables(
522
521
  targetVariables[name] = argType.value;
523
522
  break;
524
523
  }
525
- default: {
526
- const _: never = argType;
527
- _;
528
- throw new Error('Unexpected case');
529
- }
530
524
  }
531
525
  }
532
526
  }
@@ -561,6 +555,8 @@ export function readResolverFieldData(
561
555
  const fragment = {
562
556
  kind: 'FragmentReference',
563
557
  readerWithRefetchQueries: wrapResolvedValue(readerWithRefetchQueries),
558
+ fieldName: field.readerArtifact.fieldName,
559
+ readerArtifactKind: field.readerArtifact.kind,
564
560
  root,
565
561
  variables: generateChildVariableMap(variables, field.arguments),
566
562
  networkRequest,
@@ -593,7 +589,6 @@ export function readResolverFieldData(
593
589
  ? getOrCreateCachedStartUpdate(
594
590
  environment,
595
591
  fragment,
596
- readerWithRefetchQueries.readerArtifact.fieldName,
597
592
  networkRequestOptions,
598
593
  )
599
594
  : undefined,
@@ -608,17 +603,11 @@ export function readResolverFieldData(
608
603
  kind: 'Success',
609
604
  data: getOrCreateCachedComponent(
610
605
  environment,
611
- field.readerArtifact.fieldName,
612
606
  fragment,
613
607
  networkRequestOptions,
614
608
  ),
615
609
  };
616
610
  }
617
- default: {
618
- let _: never = field.readerArtifact;
619
- _;
620
- throw new Error('Unexpected kind');
621
- }
622
611
  }
623
612
  }
624
613
 
@@ -628,7 +617,7 @@ export function readScalarFieldData(
628
617
  root: StoreLink,
629
618
  variables: Variables,
630
619
  ): ReadDataResult<
631
- string | number | boolean | StoreLink | DataTypeValue[] | null
620
+ string | number | boolean | StoreLink | readonly DataTypeValue[] | null
632
621
  > {
633
622
  const storeRecordName = getParentRecordKey(field, variables);
634
623
  const value = storeRecord[storeRecordName];
@@ -659,53 +648,9 @@ export function readLinkedFieldData(
659
648
  ) => ReadDataResult<object>,
660
649
  ): ReadDataResult<unknown> {
661
650
  const storeRecordName = getParentRecordKey(field, variables);
662
- const value = storeRecord[storeRecordName];
663
- if (Array.isArray(value)) {
664
- const results = [];
665
- for (const item of value) {
666
- const link = assertLink(item);
667
- if (link === undefined) {
668
- return {
669
- kind: 'MissingData',
670
- reason:
671
- 'No link for ' +
672
- storeRecordName +
673
- ' on root ' +
674
- root.__link +
675
- '. Link is ' +
676
- JSON.stringify(item),
677
- recordLink: root,
678
- };
679
- } else if (link === null) {
680
- results.push(null);
681
- continue;
682
- }
683
-
684
- const result = readData(field.selections, link);
685
- if (result.kind === 'MissingData') {
686
- return {
687
- kind: 'MissingData',
688
- reason:
689
- 'Missing data for ' +
690
- storeRecordName +
691
- ' on root ' +
692
- root.__link +
693
- '. Link is ' +
694
- JSON.stringify(item),
695
- nestedReason: result,
696
- recordLink: result.recordLink,
697
- };
698
- }
699
- results.push(result.data);
700
- }
701
- return {
702
- kind: 'Success',
703
- data: results,
704
- };
705
- }
706
- let link = assertLink(value);
651
+ let value = storeRecord[storeRecordName];
707
652
 
708
- if (field.condition) {
653
+ if (field.condition != null) {
709
654
  const data = readData(field.condition.readerAst, root);
710
655
  if (data.kind === 'MissingData') {
711
656
  return {
@@ -730,6 +675,8 @@ export function readLinkedFieldData(
730
675
  kind: 'FragmentReference',
731
676
  readerWithRefetchQueries: wrapResolvedValue(readerWithRefetchQueries),
732
677
  root,
678
+ fieldName: field.condition.fieldName,
679
+ readerArtifactKind: field.condition.kind,
733
680
  variables: generateChildVariableMap(
734
681
  variables,
735
682
  // TODO this is wrong
@@ -748,15 +695,86 @@ export function readLinkedFieldData(
748
695
  startUpdate: getOrCreateCachedStartUpdate(
749
696
  environment,
750
697
  fragment,
751
- readerWithRefetchQueries.readerArtifact.fieldName,
752
698
  networkRequestOptions,
753
699
  ),
754
700
  }
755
701
  : undefined),
756
702
  });
757
- link = condition;
703
+ value = condition;
758
704
  }
759
705
 
706
+ if (Array.isArray(value)) {
707
+ const results = [];
708
+ for (const item of value) {
709
+ const link = assertLink(item);
710
+ if (link === undefined) {
711
+ return {
712
+ kind: 'MissingData',
713
+ reason:
714
+ 'No link for ' +
715
+ storeRecordName +
716
+ ' on root ' +
717
+ root.__link +
718
+ '. Link is ' +
719
+ JSON.stringify(item),
720
+ recordLink: root,
721
+ };
722
+ } else if (link == null) {
723
+ results.push(null);
724
+ continue;
725
+ }
726
+
727
+ if (isClientPointer(field)) {
728
+ const result = readClientPointerData(
729
+ environment,
730
+ field,
731
+ link,
732
+ variables,
733
+ nestedRefetchQueries,
734
+ readData,
735
+ );
736
+ if (result.kind === 'MissingData') {
737
+ return {
738
+ kind: 'MissingData',
739
+ reason:
740
+ 'Missing data for ' +
741
+ storeRecordName +
742
+ ' on root ' +
743
+ root.__link +
744
+ '. Link is ' +
745
+ JSON.stringify(item),
746
+ nestedReason: result,
747
+ recordLink: result.recordLink,
748
+ };
749
+ }
750
+ results.push(result.data);
751
+ continue;
752
+ }
753
+
754
+ const result = readData(field.selections, link);
755
+ if (result.kind === 'MissingData') {
756
+ return {
757
+ kind: 'MissingData',
758
+ reason:
759
+ 'Missing data for ' +
760
+ storeRecordName +
761
+ ' on root ' +
762
+ root.__link +
763
+ '. Link is ' +
764
+ JSON.stringify(item),
765
+ nestedReason: result,
766
+ recordLink: result.recordLink,
767
+ };
768
+ }
769
+ results.push(result.data);
770
+ }
771
+ return {
772
+ kind: 'Success',
773
+ data: results,
774
+ };
775
+ }
776
+ let link = assertLink(value);
777
+
760
778
  if (link === undefined) {
761
779
  // TODO make this configurable, and also generated and derived from the schema
762
780
  const missingFieldHandler = environment.missingFieldHandler;
@@ -792,117 +810,34 @@ export function readLinkedFieldData(
792
810
  } else {
793
811
  link = altLink;
794
812
  }
795
- } else if (link === null) {
813
+ } else if (link == null) {
796
814
  return {
797
815
  kind: 'Success',
798
816
  data: null,
799
817
  };
800
818
  }
801
- const targetId = link;
802
- const { refetchQueryIndex } = field;
803
- if (refetchQueryIndex != null) {
804
- // if field.refetchQueryIndex is not null, then the field is a client pointer, i.e.
805
- // it is like a loadable field that returns the selections.
806
- const refetchReaderParams = readData(
807
- [
808
- {
809
- kind: 'Scalar',
810
- fieldName: 'id',
811
- alias: null,
812
- arguments: null,
813
- isUpdatable: false,
814
- },
815
- ],
816
- targetId,
817
- );
818
819
 
819
- if (refetchReaderParams.kind === 'MissingData') {
820
+ if (isClientPointer(field)) {
821
+ const data = readClientPointerData(
822
+ environment,
823
+ field,
824
+ link,
825
+ variables,
826
+ nestedRefetchQueries,
827
+ readData,
828
+ );
829
+ if (data.kind === 'MissingData') {
820
830
  return {
821
831
  kind: 'MissingData',
822
832
  reason:
823
- 'Missing data for ' + field.alias + ' on root ' + targetId.__link,
824
- nestedReason: refetchReaderParams,
825
- recordLink: refetchReaderParams.recordLink,
833
+ 'Missing data for ' + storeRecordName + ' on root ' + root.__link,
834
+ nestedReason: data,
835
+ recordLink: data.recordLink,
826
836
  };
827
837
  }
828
-
829
- const refetchQuery = nestedRefetchQueries[refetchQueryIndex];
830
- if (refetchQuery == null) {
831
- throw new Error(
832
- 'refetchQuery is null in RefetchField. This is indicative of a bug in Isograph.',
833
- );
834
- }
835
- const refetchQueryArtifact = refetchQuery.artifact;
836
- const allowedVariables = refetchQuery.allowedVariables;
837
-
838
- return {
839
- kind: 'Success',
840
- data: (
841
- args: any,
842
- // TODO get the associated type for FetchOptions from the loadably selected field
843
- fetchOptions?: FetchOptions<any>,
844
- ) => {
845
- const includeReadOutData = (variables: any, readOutData: any) => {
846
- variables.id = readOutData.id;
847
- return variables;
848
- };
849
- const localVariables = includeReadOutData(
850
- args ?? {},
851
- refetchReaderParams.data,
852
- );
853
- writeQueryArgsToVariables(localVariables, field.arguments, variables);
854
-
855
- return [
856
- // Stable id
857
- targetId.__typename +
858
- ':' +
859
- targetId.__link +
860
- '/' +
861
- field.fieldName +
862
- '/' +
863
- stableStringifyArgs(localVariables),
864
- // Fetcher
865
- (): ItemCleanupPair<FragmentReference<any, any>> | undefined => {
866
- const variables = includeReadOutData(
867
- filterVariables({ ...args, ...localVariables }, allowedVariables),
868
- refetchReaderParams.data,
869
- );
870
-
871
- const readerWithRefetchQueries = wrapResolvedValue({
872
- kind: 'ReaderWithRefetchQueries',
873
- readerArtifact: {
874
- kind: 'EagerReaderArtifact',
875
- fieldName: field.fieldName,
876
- readerAst: field.selections,
877
- resolver: ({ data }: { data: any }) => data,
878
- hasUpdatable: false,
879
- },
880
- nestedRefetchQueries,
881
- } as const);
882
-
883
- const [networkRequest, disposeNetworkRequest] =
884
- maybeMakeNetworkRequest(
885
- environment,
886
- refetchQueryArtifact,
887
- variables,
888
- readerWithRefetchQueries,
889
- fetchOptions ?? null,
890
- );
891
-
892
- const fragmentReference: FragmentReference<any, any> = {
893
- kind: 'FragmentReference',
894
- readerWithRefetchQueries: readerWithRefetchQueries,
895
- root: targetId,
896
- variables,
897
- networkRequest,
898
- };
899
- return [fragmentReference, disposeNetworkRequest];
900
- },
901
- ];
902
- },
903
- };
838
+ return data;
904
839
  }
905
- const data = readData(field.selections, targetId);
840
+ const data = readData(field.selections, link);
906
841
  if (data.kind === 'MissingData') {
907
842
  return {
908
843
  kind: 'MissingData',
@@ -914,6 +849,124 @@ export function readLinkedFieldData(
914
849
  return data;
915
850
  }
916
851
 
852
+ function isClientPointer(
853
+ field: ReaderLinkedField,
854
+ ): field is ReaderClientPointer {
855
+ return field.refetchQueryIndex != null;
856
+ }
857
+
858
+ export function readClientPointerData(
859
+ environment: IsographEnvironment,
860
+ field: ReaderClientPointer,
861
+ root: StoreLink,
862
+ variables: Variables,
863
+ nestedRefetchQueries: RefetchQueryNormalizationArtifactWrapper[],
864
+ readData: <TReadFromStore>(
865
+ ast: ReaderAst<TReadFromStore>,
866
+ root: StoreLink,
867
+ ) => ReadDataResult<object>,
868
+ ): ReadDataResult<unknown> {
869
+ const refetchReaderParams = readData(
870
+ [
871
+ {
872
+ kind: 'Scalar',
873
+ fieldName: 'id',
874
+ alias: null,
875
+ arguments: null,
876
+ isUpdatable: false,
877
+ },
878
+ ],
879
+ root,
880
+ );
881
+
882
+ if (refetchReaderParams.kind === 'MissingData') {
883
+ return {
884
+ kind: 'MissingData',
885
+ reason: 'Missing data for ' + field.alias + ' on root ' + root.__link,
886
+ nestedReason: refetchReaderParams,
887
+ recordLink: refetchReaderParams.recordLink,
888
+ };
889
+ }
890
+
891
+ const refetchQuery = nestedRefetchQueries[field.refetchQueryIndex];
892
+ if (refetchQuery == null) {
893
+ throw new Error(
894
+ 'refetchQuery is null in RefetchField. This is indicative of a bug in Isograph.',
895
+ );
896
+ }
897
+ const refetchQueryArtifact = refetchQuery.artifact;
898
+ const allowedVariables = refetchQuery.allowedVariables;
899
+
900
+ return {
901
+ kind: 'Success',
902
+ data: (
903
+ args: any,
904
+ // TODO get the associated type for FetchOptions from the loadably selected field
905
+ fetchOptions?: FetchOptions<any, never>,
906
+ ) => {
907
+ const includeReadOutData = (variables: any, readOutData: any) => {
908
+ variables.id = readOutData.id;
909
+ return variables;
910
+ };
911
+ const localVariables = includeReadOutData(
912
+ args ?? {},
913
+ refetchReaderParams.data,
914
+ );
915
+ writeQueryArgsToVariables(localVariables, field.arguments, variables);
916
+
917
+ return [
918
+ // Stable id
919
+ root.__typename +
920
+ ':' +
921
+ root.__link +
922
+ '/' +
923
+ field.fieldName +
924
+ '/' +
925
+ stableStringifyArgs(localVariables),
926
+ // Fetcher
927
+ (): ItemCleanupPair<FragmentReference<any, any>> | undefined => {
928
+ const variables = includeReadOutData(
929
+ filterVariables({ ...args, ...localVariables }, allowedVariables),
930
+ refetchReaderParams.data,
931
+ );
932
+
933
+ const readerWithRefetchQueries = wrapResolvedValue({
934
+ kind: 'ReaderWithRefetchQueries',
935
+ readerArtifact: {
936
+ kind: 'EagerReaderArtifact',
937
+ fieldName: field.fieldName,
938
+ readerAst: field.selections,
939
+ resolver: ({ data }: { data: any }) => data,
940
+ hasUpdatable: false,
941
+ },
942
+ nestedRefetchQueries,
943
+ } as const);
944
+
945
+ const [networkRequest, disposeNetworkRequest] =
946
+ maybeMakeNetworkRequest(
947
+ environment,
948
+ refetchQueryArtifact,
949
+ variables,
950
+ readerWithRefetchQueries,
951
+ fetchOptions ?? null,
952
+ );
953
+
954
+ const fragmentReference: FragmentReference<any, any> = {
955
+ kind: 'FragmentReference',
956
+ fieldName: field.fieldName,
957
+ readerArtifactKind: 'EagerReaderArtifact',
958
+ readerWithRefetchQueries: readerWithRefetchQueries,
959
+ root,
960
+ variables,
961
+ networkRequest,
962
+ };
963
+ return [fragmentReference, disposeNetworkRequest];
964
+ },
965
+ ];
966
+ },
967
+ };
968
+ }
969
+
917
970
  export type NetworkRequestReaderOptions = {
918
971
  suspendIfInFlight: boolean;
919
972
  throwOnNetworkError: boolean;
@@ -1,22 +1,19 @@
1
- import { Factory } from '@isograph/disposable-types';
2
- import { FetchOptions } from './check';
3
- import {
1
+ import type { Factory } from '@isograph/disposable-types';
2
+ import type { FetchOptions } from './check';
3
+ import type {
4
4
  IsographEntrypoint,
5
5
  IsographEntrypointLoader,
6
6
  RefetchQueryNormalizationArtifact,
7
7
  RefetchQueryNormalizationArtifactWrapper,
8
8
  } from './entrypoint';
9
- import {
10
- ExtractParameters,
11
- FragmentReference,
12
- type UnknownTReadFromStore,
13
- } from './FragmentReference';
14
- import {
9
+ import type { ExtractParameters, FragmentReference } from './FragmentReference';
10
+ import { type UnknownTReadFromStore } from './FragmentReference';
11
+ import type {
15
12
  ComponentOrFieldName,
16
13
  IsographEnvironment,
17
- type StoreLink,
18
14
  } from './IsographEnvironment';
19
- import { Arguments } from './util';
15
+ import { type StoreLink } from './IsographEnvironment';
16
+ import type { Arguments } from './util';
20
17
 
21
18
  export type TopLevelReaderArtifact<
22
19
  TReadFromStore extends UnknownTReadFromStore,
@@ -31,7 +28,7 @@ export type EagerReaderArtifact<
31
28
  TClientFieldValue,
32
29
  > = {
33
30
  readonly kind: 'EagerReaderArtifact';
34
- readonly fieldName: string;
31
+ readonly fieldName: ComponentOrFieldName;
35
32
  readonly readerAst: ReaderAst<TReadFromStore>;
36
33
  readonly resolver: (
37
34
  data: ResolverFirstParameter<TReadFromStore>,
@@ -110,7 +107,7 @@ export type ReaderLinkedField = {
110
107
  readonly arguments: Arguments | null;
111
108
  readonly condition: EagerReaderArtifact<
112
109
  { data: any; parameters: any; startUpdate?: StartUpdate<any> },
113
- StoreLink | null
110
+ StoreLink | null | (StoreLink | null)[] | StoreLink[]
114
111
  > | null;
115
112
  readonly isUpdatable: boolean;
116
113
  /**
@@ -119,6 +116,10 @@ export type ReaderLinkedField = {
119
116
  readonly refetchQueryIndex: number | null;
120
117
  };
121
118
 
119
+ export interface ReaderClientPointer extends ReaderLinkedField {
120
+ readonly refetchQueryIndex: number;
121
+ }
122
+
122
123
  export type ReaderNonLoadableResolverField = {
123
124
  readonly kind: 'Resolver';
124
125
  readonly alias: string;
@@ -147,10 +148,10 @@ export type LoadablySelectedField = {
147
148
  readonly queryArguments: Arguments | null;
148
149
  readonly refetchReaderAst: ReaderAst<any>;
149
150
 
150
- // TODO we should not type these as any
151
+ // TODO we should not type these as any.
151
152
  readonly entrypoint:
152
- | IsographEntrypoint<any, any, any>
153
- | IsographEntrypointLoader<any, any>;
153
+ | IsographEntrypoint<any, any, any, any>
154
+ | IsographEntrypointLoader<any, any, any>;
154
155
  };
155
156
 
156
157
  export type StableId = string;
@@ -173,5 +174,5 @@ export type LoadableField<
173
174
  // user-facing API. Users should only interact with LoadableFields via APIs
174
175
  // like useClientSideDefer. These APIs should have a nullable fetchOptions
175
176
  // parameter, and provide a default value ({}) to the LoadableField.
176
- fetchOptions: FetchOptions<TResult>,
177
+ fetchOptions: FetchOptions<TResult, never>,
177
178
  ) => [StableId, Factory<FragmentReference<TReadFromStore, TResult>>];