@isograph/react 0.3.1 → 0.4.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 (130) hide show
  1. package/.turbo/turbo-compile-libs.log +5 -0
  2. package/dist/core/FragmentReference.d.ts +5 -5
  3. package/dist/core/FragmentReference.d.ts.map +1 -1
  4. package/dist/core/IsographEnvironment.d.ts +15 -10
  5. package/dist/core/IsographEnvironment.d.ts.map +1 -1
  6. package/dist/core/PromiseWrapper.d.ts +4 -4
  7. package/dist/core/PromiseWrapper.d.ts.map +1 -1
  8. package/dist/core/PromiseWrapper.js +2 -9
  9. package/dist/core/areEqualWithDeepComparison.d.ts +1 -3
  10. package/dist/core/areEqualWithDeepComparison.d.ts.map +1 -1
  11. package/dist/core/areEqualWithDeepComparison.js +0 -2
  12. package/dist/core/brand.d.ts +2 -0
  13. package/dist/core/brand.d.ts.map +1 -0
  14. package/dist/core/brand.js +2 -0
  15. package/dist/core/cache.d.ts +7 -6
  16. package/dist/core/cache.d.ts.map +1 -1
  17. package/dist/core/cache.js +57 -36
  18. package/dist/core/check.d.ts +3 -3
  19. package/dist/core/check.d.ts.map +1 -1
  20. package/dist/core/componentCache.d.ts.map +1 -1
  21. package/dist/core/componentCache.js +3 -2
  22. package/dist/core/entrypoint.d.ts +20 -2
  23. package/dist/core/entrypoint.d.ts.map +1 -1
  24. package/dist/core/garbageCollection.d.ts +2 -2
  25. package/dist/core/garbageCollection.d.ts.map +1 -1
  26. package/dist/core/logging.d.ts +13 -4
  27. package/dist/core/logging.d.ts.map +1 -1
  28. package/dist/core/makeNetworkRequest.d.ts +3 -3
  29. package/dist/core/makeNetworkRequest.d.ts.map +1 -1
  30. package/dist/core/makeNetworkRequest.js +15 -15
  31. package/dist/core/read.d.ts +8 -8
  32. package/dist/core/read.d.ts.map +1 -1
  33. package/dist/core/read.js +98 -29
  34. package/dist/core/reader.d.ts +12 -8
  35. package/dist/core/reader.d.ts.map +1 -1
  36. package/dist/core/startUpdate.d.ts +7 -4
  37. package/dist/core/startUpdate.d.ts.map +1 -1
  38. package/dist/core/startUpdate.js +153 -5
  39. package/dist/core/util.d.ts +2 -1
  40. package/dist/core/util.d.ts.map +1 -1
  41. package/dist/index.d.ts +8 -5
  42. package/dist/index.d.ts.map +1 -1
  43. package/dist/index.js +8 -1
  44. package/dist/loadable-hooks/useConnectionSpecPagination.d.ts.map +1 -1
  45. package/dist/loadable-hooks/useConnectionSpecPagination.js +1 -1
  46. package/dist/loadable-hooks/useImperativeExposedMutationField.d.ts +1 -1
  47. package/dist/loadable-hooks/useImperativeExposedMutationField.d.ts.map +1 -1
  48. package/dist/loadable-hooks/useImperativeExposedMutationField.js +1 -1
  49. package/dist/loadable-hooks/useImperativeLoadableField.d.ts +1 -1
  50. package/dist/loadable-hooks/useImperativeLoadableField.d.ts.map +1 -1
  51. package/dist/loadable-hooks/useImperativeLoadableField.js +1 -1
  52. package/dist/loadable-hooks/useSkipLimitPagination.d.ts.map +1 -1
  53. package/dist/loadable-hooks/useSkipLimitPagination.js +1 -1
  54. package/dist/react/FragmentReader.d.ts +7 -13
  55. package/dist/react/FragmentReader.d.ts.map +1 -1
  56. package/dist/react/FragmentReader.js +3 -30
  57. package/dist/react/FragmentRenderer.d.ts +15 -0
  58. package/dist/react/FragmentRenderer.d.ts.map +1 -0
  59. package/dist/react/FragmentRenderer.js +35 -0
  60. package/dist/react/LoadableFieldReader.d.ts +12 -0
  61. package/dist/react/LoadableFieldReader.d.ts.map +1 -0
  62. package/dist/react/LoadableFieldReader.js +10 -0
  63. package/dist/react/LoadableFieldRenderer.d.ts +13 -0
  64. package/dist/react/LoadableFieldRenderer.d.ts.map +1 -0
  65. package/dist/react/LoadableFieldRenderer.js +37 -0
  66. package/dist/react/useImperativeReference.d.ts.map +1 -1
  67. package/dist/react/useImperativeReference.js +6 -6
  68. package/dist/react/useResult.d.ts.map +1 -1
  69. package/dist/react/useResult.js +1 -1
  70. package/package.json +4 -5
  71. package/src/core/FragmentReference.ts +16 -7
  72. package/src/core/IsographEnvironment.ts +20 -10
  73. package/src/core/PromiseWrapper.ts +13 -16
  74. package/src/core/areEqualWithDeepComparison.ts +5 -5
  75. package/src/core/brand.ts +18 -0
  76. package/src/core/cache.ts +74 -51
  77. package/src/core/check.ts +4 -4
  78. package/src/core/componentCache.ts +7 -2
  79. package/src/core/entrypoint.ts +32 -5
  80. package/src/core/garbageCollection.ts +3 -3
  81. package/src/core/logging.ts +16 -4
  82. package/src/core/makeNetworkRequest.ts +48 -23
  83. package/src/core/read.ts +153 -48
  84. package/src/core/reader.ts +11 -7
  85. package/src/core/startUpdate.ts +313 -7
  86. package/src/core/util.ts +4 -2
  87. package/src/index.ts +11 -3
  88. package/src/loadable-hooks/useConnectionSpecPagination.ts +1 -0
  89. package/src/loadable-hooks/useImperativeExposedMutationField.ts +2 -2
  90. package/src/loadable-hooks/useImperativeLoadableField.ts +2 -2
  91. package/src/loadable-hooks/useSkipLimitPagination.ts +1 -0
  92. package/src/react/FragmentReader.tsx +23 -39
  93. package/src/react/FragmentRenderer.tsx +46 -0
  94. package/src/react/LoadableFieldReader.tsx +40 -0
  95. package/src/react/LoadableFieldRenderer.tsx +41 -0
  96. package/src/react/useImperativeReference.ts +9 -8
  97. package/src/react/useResult.ts +1 -0
  98. package/src/tests/__isograph/Economist/link/output_type.ts +2 -0
  99. package/src/tests/__isograph/Node/asEconomist/resolver_reader.ts +28 -0
  100. package/src/tests/__isograph/Node/link/output_type.ts +3 -0
  101. package/src/tests/__isograph/Query/linkedUpdate/entrypoint.ts +31 -0
  102. package/src/tests/__isograph/Query/linkedUpdate/normalization_ast.ts +95 -0
  103. package/src/tests/__isograph/Query/linkedUpdate/output_type.ts +3 -0
  104. package/src/tests/__isograph/Query/linkedUpdate/param_type.ts +51 -0
  105. package/src/tests/__isograph/Query/linkedUpdate/query_text.ts +20 -0
  106. package/src/tests/__isograph/Query/linkedUpdate/resolver_reader.ts +93 -0
  107. package/src/tests/__isograph/Query/meName/entrypoint.ts +4 -1
  108. package/src/tests/__isograph/Query/meName/query_text.ts +1 -1
  109. package/src/tests/__isograph/Query/meName/resolver_reader.ts +1 -0
  110. package/src/tests/__isograph/Query/meNameSuccessor/entrypoint.ts +4 -1
  111. package/src/tests/__isograph/Query/meNameSuccessor/query_text.ts +1 -1
  112. package/src/tests/__isograph/Query/meNameSuccessor/resolver_reader.ts +3 -0
  113. package/src/tests/__isograph/Query/nodeField/entrypoint.ts +4 -1
  114. package/src/tests/__isograph/Query/nodeField/query_text.ts +1 -1
  115. package/src/tests/__isograph/Query/nodeField/resolver_reader.ts +1 -0
  116. package/src/tests/__isograph/Query/startUpdate/entrypoint.ts +31 -0
  117. package/src/tests/__isograph/Query/startUpdate/normalization_ast.ts +51 -0
  118. package/src/tests/__isograph/Query/startUpdate/output_type.ts +3 -0
  119. package/src/tests/__isograph/Query/startUpdate/param_type.ts +26 -0
  120. package/src/tests/__isograph/Query/startUpdate/parameters_type.ts +3 -0
  121. package/src/tests/__isograph/Query/startUpdate/query_text.ts +11 -0
  122. package/src/tests/__isograph/Query/startUpdate/resolver_reader.ts +55 -0
  123. package/src/tests/__isograph/Query/subquery/entrypoint.ts +4 -1
  124. package/src/tests/__isograph/Query/subquery/query_text.ts +1 -1
  125. package/src/tests/__isograph/Query/subquery/resolver_reader.ts +2 -0
  126. package/src/tests/__isograph/iso.ts +21 -1
  127. package/src/tests/__isograph/tsconfig.json +8 -0
  128. package/src/tests/normalizeData.test.ts +0 -1
  129. package/src/tests/startUpdate.test.ts +205 -0
  130. package/.turbo/turbo-compile-typescript.log +0 -4
package/src/core/read.ts CHANGED
@@ -1,7 +1,7 @@
1
- import { CleanupFn } from '@isograph/disposable-types';
1
+ import { CleanupFn, type ItemCleanupPair } from '@isograph/disposable-types';
2
2
  import {
3
3
  getParentRecordKey,
4
- insertIfNotExists,
4
+ insertEmptySetIfMissing,
5
5
  onNextChangeToRecord,
6
6
  type EncounteredIds,
7
7
  } from './cache';
@@ -23,24 +23,24 @@ import {
23
23
  getOrLoadIsographArtifact,
24
24
  IsographEnvironment,
25
25
  type DataTypeValue,
26
- type Link,
26
+ type StoreLink,
27
27
  type StoreRecord,
28
28
  } from './IsographEnvironment';
29
29
  import { logMessage } from './logging';
30
30
  import { maybeMakeNetworkRequest } from './makeNetworkRequest';
31
31
  import {
32
32
  getPromiseState,
33
+ NOT_SET,
33
34
  PromiseWrapper,
34
35
  readPromise,
35
- Result,
36
36
  wrapPromise,
37
37
  wrapResolvedValue,
38
38
  } from './PromiseWrapper';
39
39
  import {
40
40
  ReaderAst,
41
+ type LoadablySelectedField,
41
42
  type ReaderImperativelyLoadedField,
42
43
  type ReaderLinkedField,
43
- type ReaderLoadableField,
44
44
  type ReaderNonLoadableResolverField,
45
45
  type ReaderScalarField,
46
46
  } from './reader';
@@ -104,12 +104,8 @@ export function readButDoNotEvaluate<
104
104
  // promise results in an infinite loop (including re-issuing the query until the
105
105
  // process OOM's or something.) Hence, we throw an error.
106
106
 
107
- // TODO investigate why we cannot check against NOT_SET here and we have to cast
108
- const result = fragmentReference.networkRequest.result as Result<
109
- any,
110
- any
111
- >;
112
- if (result.kind === 'Err') {
107
+ const result = fragmentReference.networkRequest.result;
108
+ if (result !== NOT_SET && result.kind === 'Err') {
113
109
  throw new Error('NetworkError', { cause: result.error });
114
110
  }
115
111
 
@@ -138,20 +134,20 @@ export type ReadDataResult<Data> =
138
134
  readonly kind: 'MissingData';
139
135
  readonly reason: string;
140
136
  readonly nestedReason?: ReadDataResult<unknown>;
141
- readonly recordLink: Link;
137
+ readonly recordLink: StoreLink;
142
138
  };
143
139
 
144
140
  function readData<TReadFromStore>(
145
141
  environment: IsographEnvironment,
146
142
  ast: ReaderAst<TReadFromStore>,
147
- root: Link,
143
+ root: StoreLink,
148
144
  variables: Variables,
149
145
  nestedRefetchQueries: RefetchQueryNormalizationArtifactWrapper[],
150
146
  networkRequest: PromiseWrapper<void, any>,
151
147
  networkRequestOptions: NetworkRequestReaderOptions,
152
148
  mutableEncounteredRecords: EncounteredIds,
153
149
  ): ReadDataResult<ExtractData<TReadFromStore>> {
154
- const encounteredIds = insertIfNotExists(
150
+ const encounteredIds = insertEmptySetIfMissing(
155
151
  mutableEncounteredRecords,
156
152
  root.__typename,
157
153
  );
@@ -196,7 +192,9 @@ function readData<TReadFromStore>(
196
192
  storeRecord,
197
193
  root,
198
194
  variables,
195
+ nestedRefetchQueries,
199
196
  networkRequest,
197
+ networkRequestOptions,
200
198
  (ast, root) =>
201
199
  readData(
202
200
  environment,
@@ -282,8 +280,8 @@ function readData<TReadFromStore>(
282
280
 
283
281
  export function readLoadablySelectedFieldData(
284
282
  environment: IsographEnvironment,
285
- field: ReaderLoadableField,
286
- root: Link,
283
+ field: LoadablySelectedField,
284
+ root: StoreLink,
287
285
  variables: Variables,
288
286
  networkRequest: PromiseWrapper<void, any>,
289
287
  networkRequestOptions: NetworkRequestReaderOptions,
@@ -346,23 +344,23 @@ export function readLoadablySelectedFieldData(
346
344
  const fragmentReferenceAndDisposeFromEntrypoint = (
347
345
  entrypoint: IsographEntrypoint<any, any, any>,
348
346
  ): [FragmentReference<any, any>, CleanupFn] => {
347
+ const readerWithRefetchQueries =
348
+ entrypoint.readerWithRefetchQueries.kind ===
349
+ 'ReaderWithRefetchQueriesLoader'
350
+ ? wrapPromise(entrypoint.readerWithRefetchQueries.loader())
351
+ : wrapResolvedValue(entrypoint.readerWithRefetchQueries);
349
352
  const [networkRequest, disposeNetworkRequest] =
350
353
  maybeMakeNetworkRequest(
351
354
  environment,
352
355
  entrypoint,
353
356
  localVariables,
354
- fetchOptions,
357
+ readerWithRefetchQueries,
358
+ fetchOptions ?? null,
355
359
  );
356
360
 
357
361
  const fragmentReference: FragmentReference<any, any> = {
358
362
  kind: 'FragmentReference',
359
- readerWithRefetchQueries: wrapResolvedValue({
360
- kind: 'ReaderWithRefetchQueries',
361
- readerArtifact:
362
- entrypoint.readerWithRefetchQueries.readerArtifact,
363
- nestedRefetchQueries:
364
- entrypoint.readerWithRefetchQueries.nestedRefetchQueries,
365
- } as const),
363
+ readerWithRefetchQueries,
366
364
 
367
365
  // TODO localVariables is not guaranteed to have an id field
368
366
  root,
@@ -396,6 +394,14 @@ export function readLoadablySelectedFieldData(
396
394
  }
397
395
  | { kind: 'Disposed' } = { kind: 'EntrypointNotLoaded' };
398
396
 
397
+ const readerWithRefetchQueries = wrapPromise(
398
+ isographArtifactPromiseWrapper.promise.then((entrypoint) =>
399
+ entrypoint.readerWithRefetchQueries.kind ===
400
+ 'ReaderWithRefetchQueriesLoader'
401
+ ? entrypoint.readerWithRefetchQueries.loader()
402
+ : entrypoint.readerWithRefetchQueries,
403
+ ),
404
+ );
399
405
  const networkRequest = wrapPromise(
400
406
  isographArtifactPromiseWrapper.promise.then((entrypoint) => {
401
407
  if (entrypointLoaderState.kind === 'EntrypointNotLoaded') {
@@ -404,7 +410,8 @@ export function readLoadablySelectedFieldData(
404
410
  environment,
405
411
  entrypoint,
406
412
  localVariables,
407
- fetchOptions,
413
+ readerWithRefetchQueries,
414
+ fetchOptions ?? null,
408
415
  );
409
416
  entrypointLoaderState = {
410
417
  kind: 'NetworkRequestStarted',
@@ -414,14 +421,10 @@ export function readLoadablySelectedFieldData(
414
421
  }
415
422
  }),
416
423
  );
417
- const readerWithRefetchPromise =
418
- isographArtifactPromiseWrapper.promise.then(
419
- (entrypoint) => entrypoint.readerWithRefetchQueries,
420
- );
421
424
 
422
425
  const fragmentReference: FragmentReference<any, any> = {
423
426
  kind: 'FragmentReference',
424
- readerWithRefetchQueries: wrapPromise(readerWithRefetchPromise),
427
+ readerWithRefetchQueries,
425
428
 
426
429
  // TODO localVariables is not guaranteed to have an id field
427
430
  root,
@@ -531,7 +534,7 @@ function writeQueryArgsToVariables(
531
534
  export function readResolverFieldData(
532
535
  environment: IsographEnvironment,
533
536
  field: ReaderNonLoadableResolverField,
534
- root: Link,
537
+ root: StoreLink,
535
538
  variables: Variables,
536
539
  nestedRefetchQueries: RefetchQueryNormalizationArtifactWrapper[],
537
540
  networkRequest: PromiseWrapper<void, any>,
@@ -591,6 +594,7 @@ export function readResolverFieldData(
591
594
  environment,
592
595
  fragment,
593
596
  readerWithRefetchQueries.readerArtifact.fieldName,
597
+ networkRequestOptions,
594
598
  )
595
599
  : undefined,
596
600
  };
@@ -621,9 +625,11 @@ export function readResolverFieldData(
621
625
  export function readScalarFieldData(
622
626
  field: ReaderScalarField,
623
627
  storeRecord: StoreRecord,
624
- root: Link,
628
+ root: StoreLink,
625
629
  variables: Variables,
626
- ): ReadDataResult<string | number | boolean | Link | DataTypeValue[] | null> {
630
+ ): ReadDataResult<
631
+ string | number | boolean | StoreLink | DataTypeValue[] | null
632
+ > {
627
633
  const storeRecordName = getParentRecordKey(field, variables);
628
634
  const value = storeRecord[storeRecordName];
629
635
  // TODO consider making scalars into discriminated unions. This probably has
@@ -642,13 +648,14 @@ export function readLinkedFieldData(
642
648
  environment: IsographEnvironment,
643
649
  field: ReaderLinkedField,
644
650
  storeRecord: StoreRecord,
645
- root: Link,
651
+ root: StoreLink,
646
652
  variables: Variables,
653
+ nestedRefetchQueries: RefetchQueryNormalizationArtifactWrapper[],
647
654
  networkRequest: PromiseWrapper<void, any>,
648
-
655
+ networkRequestOptions: NetworkRequestReaderOptions,
649
656
  readData: <TReadFromStore>(
650
657
  ast: ReaderAst<TReadFromStore>,
651
- root: Link,
658
+ root: StoreLink,
652
659
  ) => ReadDataResult<object>,
653
660
  ): ReadDataResult<unknown> {
654
661
  const storeRecordName = getParentRecordKey(field, variables);
@@ -726,7 +733,7 @@ export function readLinkedFieldData(
726
733
  variables: generateChildVariableMap(
727
734
  variables,
728
735
  // TODO this is wrong
729
- // should use field.condition.variables
736
+ // should use field.arguments
730
737
  // but it doesn't exist
731
738
  [],
732
739
  ),
@@ -742,17 +749,12 @@ export function readLinkedFieldData(
742
749
  environment,
743
750
  fragment,
744
751
  readerWithRefetchQueries.readerArtifact.fieldName,
752
+ networkRequestOptions,
745
753
  ),
746
754
  }
747
755
  : undefined),
748
756
  });
749
- if (condition === true) {
750
- link = root;
751
- } else if (condition === false) {
752
- link = null;
753
- } else {
754
- link = condition;
755
- }
757
+ link = condition;
756
758
  }
757
759
 
758
760
  if (link === undefined) {
@@ -797,6 +799,109 @@ export function readLinkedFieldData(
797
799
  };
798
800
  }
799
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
+ if (refetchReaderParams.kind === 'MissingData') {
820
+ return {
821
+ kind: 'MissingData',
822
+ reason:
823
+ 'Missing data for ' + field.alias + ' on root ' + targetId.__link,
824
+ nestedReason: refetchReaderParams,
825
+ recordLink: refetchReaderParams.recordLink,
826
+ };
827
+ }
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
+ };
904
+ }
800
905
  const data = readData(field.selections, targetId);
801
906
  if (data.kind === 'MissingData') {
802
907
  return {
@@ -841,7 +946,7 @@ function stableStringifyArgs(args: object) {
841
946
  export function readImperativelyLoadedField(
842
947
  environment: IsographEnvironment,
843
948
  field: ReaderImperativelyLoadedField,
844
- root: Link,
949
+ root: StoreLink,
845
950
  variables: Variables,
846
951
  nestedRefetchQueries: RefetchQueryNormalizationArtifactWrapper[],
847
952
  networkRequest: PromiseWrapper<void, any>,
@@ -871,11 +976,11 @@ export function readImperativelyLoadedField(
871
976
  recordLink: data.recordLink,
872
977
  };
873
978
  } else {
874
- const refetchQueryIndex = field.refetchQuery;
979
+ const { refetchQueryIndex } = field;
875
980
  const refetchQuery = nestedRefetchQueries[refetchQueryIndex];
876
981
  if (refetchQuery == null) {
877
982
  throw new Error(
878
- 'refetchQuery is null in RefetchField. This is indicative of a bug in Isograph.',
983
+ 'Refetch query not found. This is indicative of a bug in Isograph.',
879
984
  );
880
985
  }
881
986
  const refetchQueryArtifact = refetchQuery.artifact;
@@ -887,7 +992,7 @@ export function readImperativelyLoadedField(
887
992
  kind: 'Success',
888
993
  data: (args: any) => [
889
994
  // Stable id
890
- root.__link + '__' + field.name,
995
+ root.__typename + ':' + root.__link + '__' + field.name,
891
996
  // Fetcher
892
997
  field.refetchReaderArtifact.resolver(
893
998
  environment,
@@ -14,7 +14,7 @@ import {
14
14
  import {
15
15
  ComponentOrFieldName,
16
16
  IsographEnvironment,
17
- type Link,
17
+ type StoreLink,
18
18
  } from './IsographEnvironment';
19
19
  import { Arguments } from './util';
20
20
 
@@ -71,7 +71,7 @@ export type RefetchReaderArtifact = {
71
71
  variables: any,
72
72
  // TODO type this better
73
73
  filteredVariables: any,
74
- rootLink: Link,
74
+ rootLink: StoreLink,
75
75
  readerArtifact: TopLevelReaderArtifact<any, any, any> | null,
76
76
  // TODO type this better
77
77
  nestedRefetchQueries: RefetchQueryNormalizationArtifactWrapper[],
@@ -83,7 +83,7 @@ export type ReaderAstNode =
83
83
  | ReaderLinkedField
84
84
  | ReaderNonLoadableResolverField
85
85
  | ReaderImperativelyLoadedField
86
- | ReaderLoadableField
86
+ | LoadablySelectedField
87
87
  | ReaderLinkField;
88
88
 
89
89
  // @ts-ignore
@@ -109,10 +109,14 @@ export type ReaderLinkedField = {
109
109
  readonly selections: ReaderAst<unknown>;
110
110
  readonly arguments: Arguments | null;
111
111
  readonly condition: EagerReaderArtifact<
112
- { data: object; parameters: any; startUpdate?: StartUpdate<object> },
113
- boolean | Link | null
112
+ { data: any; parameters: any; startUpdate?: StartUpdate<any> },
113
+ StoreLink | null
114
114
  > | null;
115
115
  readonly isUpdatable: boolean;
116
+ /**
117
+ * If refetchQueryIndex != null, then the linked field is a client pointer.
118
+ */
119
+ readonly refetchQueryIndex: number | null;
116
120
  };
117
121
 
118
122
  export type ReaderNonLoadableResolverField = {
@@ -128,11 +132,11 @@ export type ReaderImperativelyLoadedField = {
128
132
  readonly kind: 'ImperativelyLoadedField';
129
133
  readonly alias: string;
130
134
  readonly refetchReaderArtifact: RefetchReaderArtifact;
131
- readonly refetchQuery: number;
135
+ readonly refetchQueryIndex: number;
132
136
  readonly name: string;
133
137
  };
134
138
 
135
- export type ReaderLoadableField = {
139
+ export type LoadablySelectedField = {
136
140
  readonly kind: 'LoadablySelectedField';
137
141
  readonly alias: string;
138
142