@isograph/react 0.3.0 → 0.3.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 (128) hide show
  1. package/.turbo/turbo-compile-typescript.log +4 -0
  2. package/dist/core/FragmentReference.d.ts +16 -7
  3. package/dist/core/FragmentReference.d.ts.map +1 -1
  4. package/dist/core/FragmentReference.js +3 -12
  5. package/dist/core/IsographEnvironment.d.ts +17 -27
  6. package/dist/core/IsographEnvironment.d.ts.map +1 -1
  7. package/dist/core/IsographEnvironment.js +4 -0
  8. package/dist/core/PromiseWrapper.d.ts +3 -4
  9. package/dist/core/PromiseWrapper.d.ts.map +1 -1
  10. package/dist/core/PromiseWrapper.js +5 -4
  11. package/dist/core/areEqualWithDeepComparison.d.ts.map +1 -1
  12. package/dist/core/areEqualWithDeepComparison.js +16 -0
  13. package/dist/core/cache.d.ts +11 -20
  14. package/dist/core/cache.d.ts.map +1 -1
  15. package/dist/core/cache.js +60 -45
  16. package/dist/core/check.d.ts +9 -5
  17. package/dist/core/check.d.ts.map +1 -1
  18. package/dist/core/check.js +2 -2
  19. package/dist/core/componentCache.d.ts +1 -1
  20. package/dist/core/componentCache.d.ts.map +1 -1
  21. package/dist/core/componentCache.js +27 -31
  22. package/dist/core/entrypoint.d.ts +23 -26
  23. package/dist/core/entrypoint.d.ts.map +1 -1
  24. package/dist/core/garbageCollection.d.ts +3 -4
  25. package/dist/core/garbageCollection.d.ts.map +1 -1
  26. package/dist/core/garbageCollection.js +1 -1
  27. package/dist/core/logging.d.ts +12 -13
  28. package/dist/core/logging.d.ts.map +1 -1
  29. package/dist/core/logging.js +8 -5
  30. package/dist/core/makeNetworkRequest.d.ts +5 -5
  31. package/dist/core/makeNetworkRequest.d.ts.map +1 -1
  32. package/dist/core/makeNetworkRequest.js +107 -22
  33. package/dist/core/read.d.ts +15 -10
  34. package/dist/core/read.d.ts.map +1 -1
  35. package/dist/core/read.js +398 -304
  36. package/dist/core/reader.d.ts +24 -32
  37. package/dist/core/reader.d.ts.map +1 -1
  38. package/dist/core/startUpdate.d.ts +5 -0
  39. package/dist/core/startUpdate.d.ts.map +1 -0
  40. package/dist/core/startUpdate.js +15 -0
  41. package/dist/core/util.d.ts +3 -0
  42. package/dist/core/util.d.ts.map +1 -1
  43. package/dist/index.d.ts +16 -16
  44. package/dist/index.d.ts.map +1 -1
  45. package/dist/index.js +2 -1
  46. package/dist/loadable-hooks/useClientSideDefer.d.ts +4 -10
  47. package/dist/loadable-hooks/useClientSideDefer.d.ts.map +1 -1
  48. package/dist/loadable-hooks/useClientSideDefer.js +2 -2
  49. package/dist/loadable-hooks/useConnectionSpecPagination.d.ts +8 -15
  50. package/dist/loadable-hooks/useConnectionSpecPagination.d.ts.map +1 -1
  51. package/dist/loadable-hooks/useConnectionSpecPagination.js +6 -4
  52. package/dist/loadable-hooks/useImperativeExposedMutationField.d.ts +1 -2
  53. package/dist/loadable-hooks/useImperativeExposedMutationField.d.ts.map +1 -1
  54. package/dist/loadable-hooks/useImperativeLoadableField.d.ts +4 -6
  55. package/dist/loadable-hooks/useImperativeLoadableField.d.ts.map +1 -1
  56. package/dist/loadable-hooks/useImperativeLoadableField.js +1 -1
  57. package/dist/loadable-hooks/useSkipLimitPagination.d.ts +6 -13
  58. package/dist/loadable-hooks/useSkipLimitPagination.d.ts.map +1 -1
  59. package/dist/loadable-hooks/useSkipLimitPagination.js +11 -9
  60. package/dist/react/FragmentReader.d.ts +2 -3
  61. package/dist/react/FragmentReader.d.ts.map +1 -1
  62. package/dist/react/IsographEnvironmentProvider.d.ts.map +1 -1
  63. package/dist/react/useImperativeReference.d.ts +7 -10
  64. package/dist/react/useImperativeReference.d.ts.map +1 -1
  65. package/dist/react/useImperativeReference.js +2 -3
  66. package/dist/react/useLazyReference.d.ts +4 -7
  67. package/dist/react/useLazyReference.d.ts.map +1 -1
  68. package/dist/react/useLazyReference.js +26 -5
  69. package/dist/react/useReadAndSubscribe.d.ts +3 -9
  70. package/dist/react/useReadAndSubscribe.d.ts.map +1 -1
  71. package/dist/react/useReadAndSubscribe.js +7 -3
  72. package/dist/react/useRerenderOnChange.d.ts +1 -1
  73. package/dist/react/useRerenderOnChange.d.ts.map +1 -1
  74. package/dist/react/useResult.d.ts +3 -6
  75. package/dist/react/useResult.d.ts.map +1 -1
  76. package/dist/react/useResult.js +10 -8
  77. package/isograph.config.json +1 -0
  78. package/package.json +7 -6
  79. package/src/core/FragmentReference.ts +30 -15
  80. package/src/core/IsographEnvironment.ts +39 -31
  81. package/src/core/PromiseWrapper.ts +3 -3
  82. package/src/core/areEqualWithDeepComparison.ts +20 -0
  83. package/src/core/cache.ts +105 -72
  84. package/src/core/check.ts +13 -8
  85. package/src/core/componentCache.ts +45 -52
  86. package/src/core/entrypoint.ts +34 -16
  87. package/src/core/garbageCollection.ts +6 -6
  88. package/src/core/logging.ts +24 -22
  89. package/src/core/makeNetworkRequest.ts +183 -30
  90. package/src/core/read.ts +618 -435
  91. package/src/core/reader.ts +37 -24
  92. package/src/core/startUpdate.ts +28 -0
  93. package/src/core/util.ts +4 -0
  94. package/src/index.ts +82 -9
  95. package/src/loadable-hooks/useClientSideDefer.ts +11 -10
  96. package/src/loadable-hooks/useConnectionSpecPagination.ts +26 -13
  97. package/src/loadable-hooks/useImperativeExposedMutationField.ts +1 -1
  98. package/src/loadable-hooks/useImperativeLoadableField.ts +10 -12
  99. package/src/loadable-hooks/useSkipLimitPagination.ts +37 -19
  100. package/src/react/FragmentReader.tsx +3 -3
  101. package/src/react/IsographEnvironmentProvider.tsx +1 -1
  102. package/src/react/useImperativeReference.ts +40 -19
  103. package/src/react/useLazyReference.ts +62 -14
  104. package/src/react/useReadAndSubscribe.ts +17 -9
  105. package/src/react/useRerenderOnChange.ts +2 -2
  106. package/src/react/useResult.ts +21 -8
  107. package/src/tests/__isograph/Query/meName/entrypoint.ts +4 -28
  108. package/src/tests/__isograph/Query/meName/normalization_ast.ts +25 -0
  109. package/src/tests/__isograph/Query/meName/query_text.ts +6 -0
  110. package/src/tests/__isograph/Query/meName/resolver_reader.ts +4 -0
  111. package/src/tests/__isograph/Query/meNameSuccessor/entrypoint.ts +4 -66
  112. package/src/tests/__isograph/Query/meNameSuccessor/normalization_ast.ts +56 -0
  113. package/src/tests/__isograph/Query/meNameSuccessor/query_text.ts +13 -0
  114. package/src/tests/__isograph/Query/meNameSuccessor/resolver_reader.ts +7 -0
  115. package/src/tests/__isograph/Query/nodeField/entrypoint.ts +4 -33
  116. package/src/tests/__isograph/Query/nodeField/normalization_ast.ts +30 -0
  117. package/src/tests/__isograph/Query/nodeField/query_text.ts +6 -0
  118. package/src/tests/__isograph/Query/nodeField/resolver_reader.ts +4 -0
  119. package/src/tests/__isograph/Query/subquery/entrypoint.ts +4 -43
  120. package/src/tests/__isograph/Query/subquery/normalization_ast.ts +38 -0
  121. package/src/tests/__isograph/Query/subquery/query_text.ts +8 -0
  122. package/src/tests/__isograph/Query/subquery/resolver_reader.ts +5 -0
  123. package/src/tests/__isograph/iso.ts +3 -2
  124. package/src/tests/garbageCollection.test.ts +10 -8
  125. package/src/tests/meNameSuccessor.ts +1 -1
  126. package/src/tests/nodeQuery.ts +2 -1
  127. package/src/tests/normalizeData.test.ts +1 -1
  128. package/tsconfig.pkg.json +1 -2
@@ -1,31 +1,25 @@
1
1
  import { CleanupFn } from '@isograph/disposable-types';
2
+ import { NetworkResponseObject, type EncounteredIds } from './cache';
3
+ import { CheckResult } from './check';
4
+ import {
5
+ IsographEntrypoint,
6
+ RefetchQueryNormalizationArtifact,
7
+ type NormalizationAstNodes,
8
+ } from './entrypoint';
9
+ import { FragmentReference, Variables } from './FragmentReference';
2
10
  import {
3
11
  IsographEnvironment,
4
12
  IsographStore,
5
13
  StoreRecord,
6
14
  type Link,
7
15
  } from './IsographEnvironment';
8
- import {
9
- IsographEntrypoint,
10
- NormalizationAst,
11
- RefetchQueryNormalizationArtifact,
12
- } from './entrypoint';
13
- import { FragmentReference, Variables } from './FragmentReference';
14
- import { NetworkResponseObject, type EncounteredIds } from './cache';
15
- import { Arguments } from './util';
16
16
  import { ReadDataResult } from './read';
17
- import { CheckResult } from './check';
17
+ import { Arguments } from './util';
18
18
 
19
19
  export type LogMessage =
20
- | {
21
- kind: 'GettingSuspenseCacheItem';
22
- index: string;
23
- availableCacheItems: ReadonlyArray<string>;
24
- found: boolean;
25
- }
26
20
  | {
27
21
  kind: 'AboutToNormalize';
28
- normalizationAst: NormalizationAst;
22
+ normalizationAst: NormalizationAstNodes;
29
23
  networkResponse: NetworkResponseObject;
30
24
  variables: Variables;
31
25
  }
@@ -50,7 +44,7 @@ export type LogMessage =
50
44
  kind: 'MakeNetworkRequest';
51
45
  artifact:
52
46
  | RefetchQueryNormalizationArtifact
53
- | IsographEntrypoint<any, any>;
47
+ | IsographEntrypoint<any, any, any>;
54
48
  variables: Variables;
55
49
  networkRequestId: string;
56
50
  }
@@ -76,6 +70,8 @@ export type LogMessage =
76
70
  | {
77
71
  kind: 'DoneReading';
78
72
  response: ReadDataResult<any>;
73
+ fieldName: string;
74
+ root: Link;
79
75
  }
80
76
  | {
81
77
  kind: 'NonEntrypointReceived';
@@ -84,6 +80,9 @@ export type LogMessage =
84
80
  | {
85
81
  kind: 'EnvironmentCheck';
86
82
  result: CheckResult;
83
+ }
84
+ | {
85
+ kind: 'EnvironmentCreated';
87
86
  };
88
87
 
89
88
  export type LogFunction = (logMessage: LogMessage) => void;
@@ -95,12 +94,15 @@ export type WrappedLogFunction = {
95
94
 
96
95
  export function logMessage(
97
96
  environment: IsographEnvironment,
98
- message: LogMessage,
97
+ getMessage: () => LogMessage,
99
98
  ) {
100
- for (const logger of environment.loggers) {
101
- try {
102
- logger.log(message);
103
- } catch {}
99
+ if (environment.loggers.size > 0) {
100
+ const message = getMessage();
101
+ for (const logger of environment.loggers) {
102
+ try {
103
+ logger.log(message);
104
+ } catch {}
105
+ }
104
106
  }
105
107
  }
106
108
 
@@ -1,33 +1,48 @@
1
1
  import { ItemCleanupPair } from '@isograph/disposable-types';
2
+ import { normalizeData } from './cache';
3
+ import { check, DEFAULT_SHOULD_FETCH_VALUE, FetchOptions } from './check';
4
+ import { getOrCreateCachedComponent } from './componentCache';
2
5
  import {
3
6
  IsographEntrypoint,
4
7
  RefetchQueryNormalizationArtifact,
8
+ type NormalizationAst,
9
+ type NormalizationAstLoader,
5
10
  } from './entrypoint';
6
- import { Variables } from './FragmentReference';
11
+ import {
12
+ ExtractParameters,
13
+ type FragmentReference,
14
+ type UnknownTReadFromStore,
15
+ } from './FragmentReference';
7
16
  import {
8
17
  garbageCollectEnvironment,
9
18
  RetainedQuery,
10
19
  retainQuery,
11
20
  unretainQuery,
12
21
  } from './garbageCollection';
13
- import { IsographEnvironment, ROOT_ID } from './IsographEnvironment';
22
+ import { IsographEnvironment, Link, ROOT_ID } from './IsographEnvironment';
23
+ import { logMessage } from './logging';
14
24
  import {
15
25
  AnyError,
16
26
  PromiseWrapper,
17
27
  wrapPromise,
18
28
  wrapResolvedValue,
19
29
  } from './PromiseWrapper';
20
- import { normalizeData } from './cache';
21
- import { logMessage } from './logging';
22
- import { check, DEFAULT_SHOULD_FETCH_VALUE, FetchOptions } from './check';
30
+ import { readButDoNotEvaluate } from './read';
31
+ import { getOrCreateCachedStartUpdate } from './startUpdate';
23
32
 
24
33
  let networkRequestId = 0;
25
34
 
26
- export function maybeMakeNetworkRequest(
35
+ export function maybeMakeNetworkRequest<
36
+ TReadFromStore extends UnknownTReadFromStore,
37
+ TClientFieldValue,
38
+ TNormalizationAst extends NormalizationAst | NormalizationAstLoader,
39
+ >(
27
40
  environment: IsographEnvironment,
28
- artifact: RefetchQueryNormalizationArtifact | IsographEntrypoint<any, any>,
29
- variables: Variables,
30
- fetchOptions?: FetchOptions,
41
+ artifact:
42
+ | RefetchQueryNormalizationArtifact
43
+ | IsographEntrypoint<TReadFromStore, TClientFieldValue, TNormalizationAst>,
44
+ variables: ExtractParameters<TReadFromStore>,
45
+ fetchOptions?: FetchOptions<TClientFieldValue>,
31
46
  ): ItemCleanupPair<PromiseWrapper<void, AnyError>> {
32
47
  switch (fetchOptions?.shouldFetch ?? DEFAULT_SHOULD_FETCH_VALUE) {
33
48
  case 'Yes': {
@@ -37,15 +52,24 @@ export function maybeMakeNetworkRequest(
37
52
  return [wrapResolvedValue(undefined), () => {}];
38
53
  }
39
54
  case 'IfNecessary': {
55
+ if (
56
+ artifact.networkRequestInfo.normalizationAst.kind ===
57
+ 'NormalizationAstLoader'
58
+ ) {
59
+ throw new Error(
60
+ 'Using lazy loaded normalizationAst with shouldFetch: "IfNecessary" is not supported as it will lead to slower initial load time.',
61
+ );
62
+ }
40
63
  const result = check(
41
64
  environment,
42
- artifact.networkRequestInfo.normalizationAst,
65
+ artifact.networkRequestInfo.normalizationAst.selections,
43
66
  variables,
44
67
  {
45
68
  __link: ROOT_ID,
46
69
  __typename: artifact.concreteType,
47
70
  },
48
71
  );
72
+
49
73
  if (result.kind === 'EnoughData') {
50
74
  return [wrapResolvedValue(undefined), () => {}];
51
75
  } else {
@@ -60,51 +84,74 @@ export function maybeMakeNetworkRequest(
60
84
  }
61
85
  }
62
86
 
63
- export function makeNetworkRequest(
87
+ function loadNormalizationAst(
88
+ normalizationAst: NormalizationAstLoader | NormalizationAst,
89
+ ) {
90
+ switch (normalizationAst.kind) {
91
+ case 'NormalizationAst': {
92
+ return normalizationAst;
93
+ }
94
+ case 'NormalizationAstLoader': {
95
+ return normalizationAst.loader();
96
+ }
97
+ }
98
+ }
99
+
100
+ export function makeNetworkRequest<
101
+ TReadFromStore extends UnknownTReadFromStore,
102
+ TClientFieldValue,
103
+ TNormalizationAst extends NormalizationAst | NormalizationAstLoader,
104
+ >(
64
105
  environment: IsographEnvironment,
65
- artifact: RefetchQueryNormalizationArtifact | IsographEntrypoint<any, any>,
66
- variables: Variables,
67
- fetchOptions?: FetchOptions,
106
+ artifact:
107
+ | RefetchQueryNormalizationArtifact
108
+ | IsographEntrypoint<TReadFromStore, TClientFieldValue, TNormalizationAst>,
109
+ variables: ExtractParameters<TReadFromStore>,
110
+ fetchOptions?: FetchOptions<TClientFieldValue>,
68
111
  ): ItemCleanupPair<PromiseWrapper<void, AnyError>> {
69
112
  // TODO this should be a DataId and stored in the store
70
113
  const myNetworkRequestId = networkRequestId + '';
71
114
  networkRequestId++;
72
115
 
73
- logMessage(environment, {
116
+ logMessage(environment, () => ({
74
117
  kind: 'MakeNetworkRequest',
75
118
  artifact,
76
119
  variables,
77
120
  networkRequestId: myNetworkRequestId,
78
- });
121
+ }));
79
122
 
80
123
  let status: NetworkRequestStatus = {
81
124
  kind: 'UndisposedIncomplete',
82
125
  };
83
126
  // This should be an observable, not a promise
84
- const promise = environment
85
- .networkFunction(artifact.networkRequestInfo.queryText, variables)
86
- .then((networkResponse) => {
87
- logMessage(environment, {
127
+ const promise = Promise.all([
128
+ environment.networkFunction(
129
+ artifact.networkRequestInfo.queryText,
130
+ variables,
131
+ ),
132
+ loadNormalizationAst(artifact.networkRequestInfo.normalizationAst),
133
+ ])
134
+ .then(([networkResponse, normalizationAst]) => {
135
+ logMessage(environment, () => ({
88
136
  kind: 'ReceivedNetworkResponse',
89
137
  networkResponse,
90
138
  networkRequestId: myNetworkRequestId,
91
- });
139
+ }));
92
140
 
93
141
  if (networkResponse.errors != null) {
94
142
  try {
95
143
  fetchOptions?.onError?.();
96
144
  } catch {}
97
- // @ts-expect-error Why are we getting the wrong constructor here?
98
145
  throw new Error('GraphQL network response had errors', {
99
146
  cause: networkResponse,
100
147
  });
101
148
  }
102
149
 
150
+ const root = { __link: ROOT_ID, __typename: artifact.concreteType };
103
151
  if (status.kind === 'UndisposedIncomplete') {
104
- const root = { __link: ROOT_ID, __typename: artifact.concreteType };
105
152
  normalizeData(
106
153
  environment,
107
- artifact.networkRequestInfo.normalizationAst,
154
+ normalizationAst.selections,
108
155
  networkResponse.data ?? {},
109
156
  variables,
110
157
  artifact.kind === 'Entrypoint'
@@ -113,7 +160,7 @@ export function makeNetworkRequest(
113
160
  root,
114
161
  );
115
162
  const retainedQuery = {
116
- normalizationAst: artifact.networkRequestInfo.normalizationAst,
163
+ normalizationAst: normalizationAst.selections,
117
164
  variables,
118
165
  root,
119
166
  };
@@ -124,16 +171,30 @@ export function makeNetworkRequest(
124
171
  retainQuery(environment, retainedQuery);
125
172
  }
126
173
 
127
- try {
128
- fetchOptions?.onComplete?.();
129
- } catch {}
174
+ const onComplete = fetchOptions?.onComplete;
175
+ if (onComplete != null) {
176
+ let data = readDataForOnComplete(
177
+ artifact,
178
+ environment,
179
+ root,
180
+ variables,
181
+ );
182
+
183
+ try {
184
+ // @ts-expect-error this problem will be fixed when we remove RefetchQueryNormalizationArtifact
185
+ // (or we can fix this by having a single param of type { kind: 'Entrypoint', entrypoint,
186
+ // fetchOptions: FetchOptions<TReadFromStore> } | { kind: 'RefetchQuery', refetchQuery,
187
+ // fetchOptions: FetchOptions<void> }).
188
+ onComplete(data);
189
+ } catch {}
190
+ }
130
191
  })
131
192
  .catch((e) => {
132
- logMessage(environment, {
193
+ logMessage(environment, () => ({
133
194
  kind: 'ReceivedNetworkError',
134
195
  networkRequestId: myNetworkRequestId,
135
196
  error: e,
136
- });
197
+ }));
137
198
  try {
138
199
  fetchOptions?.onError?.();
139
200
  } catch {}
@@ -173,3 +234,95 @@ type NetworkRequestStatus =
173
234
  readonly kind: 'UndisposedComplete';
174
235
  readonly retainedQuery: RetainedQuery;
175
236
  };
237
+
238
+ function readDataForOnComplete<
239
+ TReadFromStore extends UnknownTReadFromStore,
240
+ TClientFieldValue,
241
+ TNormalizationAst extends NormalizationAst | NormalizationAstLoader,
242
+ >(
243
+ artifact:
244
+ | RefetchQueryNormalizationArtifact
245
+ | IsographEntrypoint<TReadFromStore, TClientFieldValue, TNormalizationAst>,
246
+ environment: IsographEnvironment,
247
+ root: Link,
248
+ variables: ExtractParameters<TReadFromStore>,
249
+ ): TClientFieldValue | null {
250
+ // An entrypoint, but not a RefetchQueryNormalizationArtifact, has a reader ASTs.
251
+ // So, we can only pass data to onComplete if makeNetworkRequest was passed an entrypoint.
252
+ // This is awkward, since we don't express that in the types of the parameters
253
+ // (i.e. FetchOptions could be passed, along with a RefetchQueryNormalizationArtifact).
254
+ //
255
+ // However, this isn't a big deal: RefetchQueryNormalizationArtifact is going away.
256
+ if (artifact.kind === 'Entrypoint') {
257
+ // TODO this is a smell!
258
+ const fakeNetworkRequest = wrapResolvedValue(undefined);
259
+ // TODO this is a smell — we know the network response is not in flight,
260
+ // so we don't really care!
261
+ const fakeNetworkRequestOptions = {
262
+ suspendIfInFlight: false,
263
+ throwOnNetworkError: false,
264
+ };
265
+
266
+ const fragment: FragmentReference<TReadFromStore, TClientFieldValue> = {
267
+ kind: 'FragmentReference',
268
+ // TODO this smells.
269
+ readerWithRefetchQueries: wrapResolvedValue(
270
+ artifact.readerWithRefetchQueries,
271
+ ),
272
+ root,
273
+ variables,
274
+ networkRequest: fakeNetworkRequest,
275
+ };
276
+ const fragmentResult = readButDoNotEvaluate(
277
+ environment,
278
+ fragment,
279
+ fakeNetworkRequestOptions,
280
+ ).item;
281
+ const readerArtifact = artifact.readerWithRefetchQueries.readerArtifact;
282
+ switch (readerArtifact.kind) {
283
+ case 'ComponentReaderArtifact': {
284
+ // @ts-expect-error We should find a way to encode this in the type system:
285
+ // if we have a ComponentReaderArtifact, we will necessarily have a
286
+ // TClientFieldValue which is a React.FC<...>
287
+ return getOrCreateCachedComponent(
288
+ environment,
289
+ readerArtifact.fieldName,
290
+ {
291
+ kind: 'FragmentReference',
292
+ readerWithRefetchQueries: wrapResolvedValue({
293
+ kind: 'ReaderWithRefetchQueries',
294
+ readerArtifact: readerArtifact,
295
+ nestedRefetchQueries:
296
+ artifact.readerWithRefetchQueries.nestedRefetchQueries,
297
+ }),
298
+ root,
299
+ variables,
300
+ networkRequest: fakeNetworkRequest,
301
+ } as const,
302
+ fakeNetworkRequestOptions,
303
+ );
304
+ }
305
+ case 'EagerReaderArtifact': {
306
+ return readerArtifact.resolver({
307
+ data: fragmentResult,
308
+ parameters: variables,
309
+ ...(readerArtifact.hasUpdatable
310
+ ? {
311
+ startUpdate: getOrCreateCachedStartUpdate(
312
+ environment,
313
+ fragment,
314
+ artifact.readerWithRefetchQueries.readerArtifact.fieldName,
315
+ ),
316
+ }
317
+ : undefined),
318
+ });
319
+ }
320
+ default: {
321
+ const _: never = readerArtifact;
322
+ _;
323
+ throw new Error('Expected case');
324
+ }
325
+ }
326
+ }
327
+ return null;
328
+ }