@isograph/react 0.4.3 → 0.5.0
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.
- package/.turbo/turbo-compile-libs.log +2 -2
- package/dist/core/FragmentReference.d.ts +4 -2
- package/dist/core/FragmentReference.d.ts.map +1 -1
- package/dist/core/FragmentReference.js +2 -2
- package/dist/core/IsographEnvironment.d.ts +19 -11
- package/dist/core/IsographEnvironment.d.ts.map +1 -1
- package/dist/core/IsographEnvironment.js +27 -2
- package/dist/core/PromiseWrapper.d.ts +13 -7
- package/dist/core/PromiseWrapper.d.ts.map +1 -1
- package/dist/core/brand.d.ts +17 -0
- package/dist/core/brand.d.ts.map +1 -1
- package/dist/core/cache.d.ts +10 -7
- package/dist/core/cache.d.ts.map +1 -1
- package/dist/core/cache.js +102 -74
- package/dist/core/check.d.ts +8 -4
- package/dist/core/check.d.ts.map +1 -1
- package/dist/core/check.js +10 -7
- package/dist/core/componentCache.d.ts +1 -1
- package/dist/core/componentCache.d.ts.map +1 -1
- package/dist/core/componentCache.js +6 -4
- package/dist/core/entrypoint.d.ts +17 -7
- package/dist/core/entrypoint.d.ts.map +1 -1
- package/dist/core/garbageCollection.d.ts +8 -2
- package/dist/core/garbageCollection.d.ts.map +1 -1
- package/dist/core/garbageCollection.js +36 -14
- package/dist/core/logging.d.ts +16 -3
- package/dist/core/logging.d.ts.map +1 -1
- package/dist/core/makeNetworkRequest.d.ts +4 -2
- package/dist/core/makeNetworkRequest.d.ts.map +1 -1
- package/dist/core/makeNetworkRequest.js +115 -38
- package/dist/core/optimisticProxy.d.ts +59 -0
- package/dist/core/optimisticProxy.d.ts.map +1 -0
- package/dist/core/optimisticProxy.js +399 -0
- package/dist/core/read.d.ts +3 -2
- package/dist/core/read.d.ts.map +1 -1
- package/dist/core/read.js +158 -123
- package/dist/core/reader.d.ts +7 -4
- package/dist/core/reader.d.ts.map +1 -1
- package/dist/core/startUpdate.d.ts +3 -2
- package/dist/core/startUpdate.d.ts.map +1 -1
- package/dist/core/startUpdate.js +33 -34
- package/dist/index.d.ts +2 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -1
- package/dist/loadable-hooks/useClientSideDefer.d.ts +9 -4
- package/dist/loadable-hooks/useClientSideDefer.d.ts.map +1 -1
- package/dist/loadable-hooks/useClientSideDefer.js +34 -1
- package/dist/loadable-hooks/useConnectionSpecPagination.d.ts +5 -3
- package/dist/loadable-hooks/useConnectionSpecPagination.d.ts.map +1 -1
- package/dist/loadable-hooks/useConnectionSpecPagination.js +27 -13
- package/dist/loadable-hooks/useImperativeLoadableField.d.ts +1 -1
- package/dist/loadable-hooks/useImperativeLoadableField.d.ts.map +1 -1
- package/dist/loadable-hooks/useSkipLimitPagination.d.ts +1 -1
- package/dist/loadable-hooks/useSkipLimitPagination.d.ts.map +1 -1
- package/dist/loadable-hooks/useSkipLimitPagination.js +1 -1
- package/dist/react/FragmentReader.d.ts +2 -1
- package/dist/react/FragmentReader.d.ts.map +1 -1
- package/dist/react/FragmentRenderer.d.ts +2 -1
- package/dist/react/FragmentRenderer.d.ts.map +1 -1
- package/dist/react/LoadableFieldReader.d.ts +9 -3
- package/dist/react/LoadableFieldReader.d.ts.map +1 -1
- package/dist/react/LoadableFieldReader.js +40 -1
- package/dist/react/LoadableFieldRenderer.d.ts +9 -3
- package/dist/react/LoadableFieldRenderer.d.ts.map +1 -1
- package/dist/react/LoadableFieldRenderer.js +36 -1
- package/dist/react/useImperativeReference.d.ts +4 -3
- package/dist/react/useImperativeReference.d.ts.map +1 -1
- package/dist/react/useImperativeReference.js +3 -5
- package/dist/react/useLazyReference.d.ts +2 -1
- package/dist/react/useLazyReference.d.ts.map +1 -1
- package/dist/react/useReadAndSubscribe.d.ts.map +1 -1
- package/dist/react/useReadAndSubscribe.js +1 -3
- package/dist/react/useResult.d.ts.map +1 -1
- package/dist/react/useResult.js +6 -5
- package/package.json +16 -17
- package/src/core/FragmentReference.ts +10 -4
- package/src/core/IsographEnvironment.ts +59 -13
- package/src/core/PromiseWrapper.ts +14 -7
- package/src/core/brand.ts +18 -0
- package/src/core/cache.ts +186 -91
- package/src/core/check.ts +21 -10
- package/src/core/componentCache.ts +8 -4
- package/src/core/entrypoint.ts +35 -6
- package/src/core/garbageCollection.ts +61 -19
- package/src/core/logging.ts +15 -3
- package/src/core/makeNetworkRequest.ts +307 -74
- package/src/core/optimisticProxy.ts +563 -0
- package/src/core/read.ts +233 -163
- package/src/core/reader.ts +10 -6
- package/src/core/startUpdate.ts +45 -30
- package/src/index.ts +2 -1
- package/src/loadable-hooks/useClientSideDefer.ts +76 -26
- package/src/loadable-hooks/useConnectionSpecPagination.ts +34 -17
- package/src/loadable-hooks/useImperativeLoadableField.ts +2 -2
- package/src/loadable-hooks/useSkipLimitPagination.ts +2 -3
- package/src/react/FragmentReader.tsx +3 -1
- package/src/react/FragmentRenderer.tsx +8 -1
- package/src/react/LoadableFieldReader.tsx +123 -12
- package/src/react/LoadableFieldRenderer.tsx +122 -12
- package/src/react/useImperativeReference.ts +20 -11
- package/src/react/useLazyReference.ts +17 -6
- package/src/react/useReadAndSubscribe.ts +1 -8
- package/src/react/useResult.ts +9 -11
- package/src/tests/__isograph/Node/asEconomist/resolver_reader.ts +1 -1
- package/src/tests/__isograph/Query/linkedUpdate/entrypoint.ts +3 -1
- package/src/tests/__isograph/Query/linkedUpdate/raw_response_type.ts +13 -0
- package/src/tests/__isograph/Query/linkedUpdate/resolver_reader.ts +1 -1
- package/src/tests/__isograph/Query/meName/entrypoint.ts +3 -1
- package/src/tests/__isograph/Query/meName/raw_response_type.ts +7 -0
- package/src/tests/__isograph/Query/meName/resolver_reader.ts +1 -1
- package/src/tests/__isograph/Query/meNameSuccessor/entrypoint.ts +3 -1
- package/src/tests/__isograph/Query/meNameSuccessor/raw_response_type.ts +14 -0
- package/src/tests/__isograph/Query/meNameSuccessor/resolver_reader.ts +1 -1
- package/src/tests/__isograph/Query/nodeField/entrypoint.ts +3 -1
- package/src/tests/__isograph/Query/nodeField/raw_response_type.ts +7 -0
- package/src/tests/__isograph/Query/nodeField/resolver_reader.ts +1 -1
- package/src/tests/__isograph/Query/normalizeUndefinedField/entrypoint.ts +33 -0
- package/src/tests/__isograph/Query/normalizeUndefinedField/normalization_ast.ts +25 -0
- package/src/tests/__isograph/Query/normalizeUndefinedField/output_type.ts +3 -0
- package/src/tests/__isograph/Query/normalizeUndefinedField/param_type.ts +9 -0
- package/src/tests/__isograph/Query/normalizeUndefinedField/query_text.ts +6 -0
- package/src/tests/__isograph/Query/normalizeUndefinedField/raw_response_type.ts +7 -0
- package/src/tests/__isograph/Query/normalizeUndefinedField/resolver_reader.ts +38 -0
- package/src/tests/__isograph/Query/startUpdate/entrypoint.ts +3 -1
- package/src/tests/__isograph/Query/startUpdate/raw_response_type.ts +8 -0
- package/src/tests/__isograph/Query/startUpdate/resolver_reader.ts +1 -1
- package/src/tests/__isograph/Query/subquery/entrypoint.ts +3 -1
- package/src/tests/__isograph/Query/subquery/raw_response_type.ts +9 -0
- package/src/tests/__isograph/Query/subquery/resolver_reader.ts +1 -1
- package/src/tests/__isograph/iso.ts +11 -1
- package/src/tests/garbageCollection.test.ts +8 -5
- package/src/tests/meNameSuccessor.ts +6 -3
- package/src/tests/nodeQuery.ts +4 -2
- package/src/tests/normalizeData.test.ts +89 -15
- package/src/tests/optimisticProxy.test.ts +860 -0
- package/src/tests/startUpdate.test.ts +7 -5
- package/src/tests/__isograph/Economist/__link/output_type.ts +0 -2
package/src/core/read.ts
CHANGED
|
@@ -21,6 +21,7 @@ import {
|
|
|
21
21
|
import {
|
|
22
22
|
assertLink,
|
|
23
23
|
getOrLoadIsographArtifact,
|
|
24
|
+
getOrLoadReaderWithRefetchQueries,
|
|
24
25
|
IsographEnvironment,
|
|
25
26
|
type DataTypeValue,
|
|
26
27
|
type StoreLink,
|
|
@@ -28,6 +29,7 @@ import {
|
|
|
28
29
|
} from './IsographEnvironment';
|
|
29
30
|
import { logMessage } from './logging';
|
|
30
31
|
import { maybeMakeNetworkRequest } from './makeNetworkRequest';
|
|
32
|
+
import { getStoreRecordProxy } from './optimisticProxy';
|
|
31
33
|
import {
|
|
32
34
|
getPromiseState,
|
|
33
35
|
NOT_SET,
|
|
@@ -39,6 +41,7 @@ import {
|
|
|
39
41
|
import {
|
|
40
42
|
ReaderAst,
|
|
41
43
|
type LoadablySelectedField,
|
|
44
|
+
type ReaderClientPointer,
|
|
42
45
|
type ReaderImperativelyLoadedField,
|
|
43
46
|
type ReaderLinkedField,
|
|
44
47
|
type ReaderNonLoadableResolverField,
|
|
@@ -152,7 +155,7 @@ function readData<TReadFromStore>(
|
|
|
152
155
|
root.__typename,
|
|
153
156
|
);
|
|
154
157
|
encounteredIds.add(root.__link);
|
|
155
|
-
let storeRecord = environment.store
|
|
158
|
+
let storeRecord = getStoreRecordProxy(environment.store, root);
|
|
156
159
|
if (storeRecord === undefined) {
|
|
157
160
|
return {
|
|
158
161
|
kind: 'MissingData',
|
|
@@ -313,7 +316,7 @@ export function readLoadablySelectedFieldData(
|
|
|
313
316
|
data: (
|
|
314
317
|
args: any,
|
|
315
318
|
// TODO get the associated type for FetchOptions from the loadably selected field
|
|
316
|
-
fetchOptions?: FetchOptions<any>,
|
|
319
|
+
fetchOptions?: FetchOptions<any, never>,
|
|
317
320
|
) => {
|
|
318
321
|
// TODO we should use the reader AST for this
|
|
319
322
|
const includeReadOutData = (variables: any, readOutData: any) => {
|
|
@@ -342,13 +345,13 @@ export function readLoadablySelectedFieldData(
|
|
|
342
345
|
// Fetcher
|
|
343
346
|
() => {
|
|
344
347
|
const fragmentReferenceAndDisposeFromEntrypoint = (
|
|
345
|
-
entrypoint: IsographEntrypoint<any, any, any>,
|
|
348
|
+
entrypoint: IsographEntrypoint<any, any, any, {}>,
|
|
346
349
|
): [FragmentReference<any, any>, CleanupFn] => {
|
|
347
|
-
const readerWithRefetchQueries =
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
350
|
+
const { fieldName, readerArtifactKind, readerWithRefetchQueries } =
|
|
351
|
+
getOrLoadReaderWithRefetchQueries(
|
|
352
|
+
environment,
|
|
353
|
+
entrypoint.readerWithRefetchQueries,
|
|
354
|
+
);
|
|
352
355
|
const [networkRequest, disposeNetworkRequest] =
|
|
353
356
|
maybeMakeNetworkRequest(
|
|
354
357
|
environment,
|
|
@@ -361,7 +364,8 @@ export function readLoadablySelectedFieldData(
|
|
|
361
364
|
const fragmentReference: FragmentReference<any, any> = {
|
|
362
365
|
kind: 'FragmentReference',
|
|
363
366
|
readerWithRefetchQueries,
|
|
364
|
-
|
|
367
|
+
fieldName,
|
|
368
|
+
readerArtifactKind,
|
|
365
369
|
// TODO localVariables is not guaranteed to have an id field
|
|
366
370
|
root,
|
|
367
371
|
variables: localVariables,
|
|
@@ -395,11 +399,12 @@ export function readLoadablySelectedFieldData(
|
|
|
395
399
|
| { kind: 'Disposed' } = { kind: 'EntrypointNotLoaded' };
|
|
396
400
|
|
|
397
401
|
const readerWithRefetchQueries = wrapPromise(
|
|
398
|
-
isographArtifactPromiseWrapper.promise.then(
|
|
399
|
-
entrypoint
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
402
|
+
isographArtifactPromiseWrapper.promise.then(
|
|
403
|
+
(entrypoint) =>
|
|
404
|
+
getOrLoadReaderWithRefetchQueries(
|
|
405
|
+
environment,
|
|
406
|
+
entrypoint.readerWithRefetchQueries,
|
|
407
|
+
).readerWithRefetchQueries.promise,
|
|
403
408
|
),
|
|
404
409
|
);
|
|
405
410
|
const networkRequest = wrapPromise(
|
|
@@ -425,7 +430,8 @@ export function readLoadablySelectedFieldData(
|
|
|
425
430
|
const fragmentReference: FragmentReference<any, any> = {
|
|
426
431
|
kind: 'FragmentReference',
|
|
427
432
|
readerWithRefetchQueries,
|
|
428
|
-
|
|
433
|
+
fieldName: field.name,
|
|
434
|
+
readerArtifactKind: field.entrypoint.readerArtifactKind,
|
|
429
435
|
// TODO localVariables is not guaranteed to have an id field
|
|
430
436
|
root,
|
|
431
437
|
variables: localVariables,
|
|
@@ -561,6 +567,8 @@ export function readResolverFieldData(
|
|
|
561
567
|
const fragment = {
|
|
562
568
|
kind: 'FragmentReference',
|
|
563
569
|
readerWithRefetchQueries: wrapResolvedValue(readerWithRefetchQueries),
|
|
570
|
+
fieldName: field.readerArtifact.fieldName,
|
|
571
|
+
readerArtifactKind: field.readerArtifact.kind,
|
|
564
572
|
root,
|
|
565
573
|
variables: generateChildVariableMap(variables, field.arguments),
|
|
566
574
|
networkRequest,
|
|
@@ -593,7 +601,6 @@ export function readResolverFieldData(
|
|
|
593
601
|
? getOrCreateCachedStartUpdate(
|
|
594
602
|
environment,
|
|
595
603
|
fragment,
|
|
596
|
-
readerWithRefetchQueries.readerArtifact.fieldName,
|
|
597
604
|
networkRequestOptions,
|
|
598
605
|
)
|
|
599
606
|
: undefined,
|
|
@@ -608,7 +615,6 @@ export function readResolverFieldData(
|
|
|
608
615
|
kind: 'Success',
|
|
609
616
|
data: getOrCreateCachedComponent(
|
|
610
617
|
environment,
|
|
611
|
-
field.readerArtifact.fieldName,
|
|
612
618
|
fragment,
|
|
613
619
|
networkRequestOptions,
|
|
614
620
|
),
|
|
@@ -628,7 +634,7 @@ export function readScalarFieldData(
|
|
|
628
634
|
root: StoreLink,
|
|
629
635
|
variables: Variables,
|
|
630
636
|
): ReadDataResult<
|
|
631
|
-
string | number | boolean | StoreLink | DataTypeValue[] | null
|
|
637
|
+
string | number | boolean | StoreLink | readonly DataTypeValue[] | null
|
|
632
638
|
> {
|
|
633
639
|
const storeRecordName = getParentRecordKey(field, variables);
|
|
634
640
|
const value = storeRecord[storeRecordName];
|
|
@@ -659,51 +665,7 @@ export function readLinkedFieldData(
|
|
|
659
665
|
) => ReadDataResult<object>,
|
|
660
666
|
): ReadDataResult<unknown> {
|
|
661
667
|
const storeRecordName = getParentRecordKey(field, variables);
|
|
662
|
-
|
|
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);
|
|
668
|
+
let value = storeRecord[storeRecordName];
|
|
707
669
|
|
|
708
670
|
if (field.condition) {
|
|
709
671
|
const data = readData(field.condition.readerAst, root);
|
|
@@ -730,6 +692,8 @@ export function readLinkedFieldData(
|
|
|
730
692
|
kind: 'FragmentReference',
|
|
731
693
|
readerWithRefetchQueries: wrapResolvedValue(readerWithRefetchQueries),
|
|
732
694
|
root,
|
|
695
|
+
fieldName: field.condition.fieldName,
|
|
696
|
+
readerArtifactKind: field.condition.kind,
|
|
733
697
|
variables: generateChildVariableMap(
|
|
734
698
|
variables,
|
|
735
699
|
// TODO this is wrong
|
|
@@ -748,14 +712,85 @@ export function readLinkedFieldData(
|
|
|
748
712
|
startUpdate: getOrCreateCachedStartUpdate(
|
|
749
713
|
environment,
|
|
750
714
|
fragment,
|
|
751
|
-
readerWithRefetchQueries.readerArtifact.fieldName,
|
|
752
715
|
networkRequestOptions,
|
|
753
716
|
),
|
|
754
717
|
}
|
|
755
718
|
: undefined),
|
|
756
719
|
});
|
|
757
|
-
|
|
720
|
+
value = condition;
|
|
721
|
+
}
|
|
722
|
+
|
|
723
|
+
if (Array.isArray(value)) {
|
|
724
|
+
const results = [];
|
|
725
|
+
for (const item of value) {
|
|
726
|
+
const link = assertLink(item);
|
|
727
|
+
if (link === undefined) {
|
|
728
|
+
return {
|
|
729
|
+
kind: 'MissingData',
|
|
730
|
+
reason:
|
|
731
|
+
'No link for ' +
|
|
732
|
+
storeRecordName +
|
|
733
|
+
' on root ' +
|
|
734
|
+
root.__link +
|
|
735
|
+
'. Link is ' +
|
|
736
|
+
JSON.stringify(item),
|
|
737
|
+
recordLink: root,
|
|
738
|
+
};
|
|
739
|
+
} else if (link === null) {
|
|
740
|
+
results.push(null);
|
|
741
|
+
continue;
|
|
742
|
+
}
|
|
743
|
+
|
|
744
|
+
if (isClientPointer(field)) {
|
|
745
|
+
const result = readClientPointerData(
|
|
746
|
+
environment,
|
|
747
|
+
field,
|
|
748
|
+
link,
|
|
749
|
+
variables,
|
|
750
|
+
nestedRefetchQueries,
|
|
751
|
+
readData,
|
|
752
|
+
);
|
|
753
|
+
if (result.kind === 'MissingData') {
|
|
754
|
+
return {
|
|
755
|
+
kind: 'MissingData',
|
|
756
|
+
reason:
|
|
757
|
+
'Missing data for ' +
|
|
758
|
+
storeRecordName +
|
|
759
|
+
' on root ' +
|
|
760
|
+
root.__link +
|
|
761
|
+
'. Link is ' +
|
|
762
|
+
JSON.stringify(item),
|
|
763
|
+
nestedReason: result,
|
|
764
|
+
recordLink: result.recordLink,
|
|
765
|
+
};
|
|
766
|
+
}
|
|
767
|
+
results.push(result.data);
|
|
768
|
+
continue;
|
|
769
|
+
}
|
|
770
|
+
|
|
771
|
+
const result = readData(field.selections, link);
|
|
772
|
+
if (result.kind === 'MissingData') {
|
|
773
|
+
return {
|
|
774
|
+
kind: 'MissingData',
|
|
775
|
+
reason:
|
|
776
|
+
'Missing data for ' +
|
|
777
|
+
storeRecordName +
|
|
778
|
+
' on root ' +
|
|
779
|
+
root.__link +
|
|
780
|
+
'. Link is ' +
|
|
781
|
+
JSON.stringify(item),
|
|
782
|
+
nestedReason: result,
|
|
783
|
+
recordLink: result.recordLink,
|
|
784
|
+
};
|
|
785
|
+
}
|
|
786
|
+
results.push(result.data);
|
|
787
|
+
}
|
|
788
|
+
return {
|
|
789
|
+
kind: 'Success',
|
|
790
|
+
data: results,
|
|
791
|
+
};
|
|
758
792
|
}
|
|
793
|
+
let link = assertLink(value);
|
|
759
794
|
|
|
760
795
|
if (link === undefined) {
|
|
761
796
|
// TODO make this configurable, and also generated and derived from the schema
|
|
@@ -798,111 +833,28 @@ export function readLinkedFieldData(
|
|
|
798
833
|
data: null,
|
|
799
834
|
};
|
|
800
835
|
}
|
|
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
836
|
|
|
819
|
-
|
|
837
|
+
if (isClientPointer(field)) {
|
|
838
|
+
const data = readClientPointerData(
|
|
839
|
+
environment,
|
|
840
|
+
field,
|
|
841
|
+
link,
|
|
842
|
+
variables,
|
|
843
|
+
nestedRefetchQueries,
|
|
844
|
+
readData,
|
|
845
|
+
);
|
|
846
|
+
if (data.kind === 'MissingData') {
|
|
820
847
|
return {
|
|
821
848
|
kind: 'MissingData',
|
|
822
849
|
reason:
|
|
823
|
-
'Missing data for ' +
|
|
824
|
-
nestedReason:
|
|
825
|
-
recordLink:
|
|
850
|
+
'Missing data for ' + storeRecordName + ' on root ' + root.__link,
|
|
851
|
+
nestedReason: data,
|
|
852
|
+
recordLink: data.recordLink,
|
|
826
853
|
};
|
|
827
854
|
}
|
|
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
|
-
};
|
|
855
|
+
return data;
|
|
904
856
|
}
|
|
905
|
-
const data = readData(field.selections,
|
|
857
|
+
const data = readData(field.selections, link);
|
|
906
858
|
if (data.kind === 'MissingData') {
|
|
907
859
|
return {
|
|
908
860
|
kind: 'MissingData',
|
|
@@ -914,6 +866,124 @@ export function readLinkedFieldData(
|
|
|
914
866
|
return data;
|
|
915
867
|
}
|
|
916
868
|
|
|
869
|
+
function isClientPointer(
|
|
870
|
+
field: ReaderLinkedField,
|
|
871
|
+
): field is ReaderClientPointer {
|
|
872
|
+
return field.refetchQueryIndex !== null;
|
|
873
|
+
}
|
|
874
|
+
|
|
875
|
+
export function readClientPointerData(
|
|
876
|
+
environment: IsographEnvironment,
|
|
877
|
+
field: ReaderClientPointer,
|
|
878
|
+
root: StoreLink,
|
|
879
|
+
variables: Variables,
|
|
880
|
+
nestedRefetchQueries: RefetchQueryNormalizationArtifactWrapper[],
|
|
881
|
+
readData: <TReadFromStore>(
|
|
882
|
+
ast: ReaderAst<TReadFromStore>,
|
|
883
|
+
root: StoreLink,
|
|
884
|
+
) => ReadDataResult<object>,
|
|
885
|
+
): ReadDataResult<unknown> {
|
|
886
|
+
const refetchReaderParams = readData(
|
|
887
|
+
[
|
|
888
|
+
{
|
|
889
|
+
kind: 'Scalar',
|
|
890
|
+
fieldName: 'id',
|
|
891
|
+
alias: null,
|
|
892
|
+
arguments: null,
|
|
893
|
+
isUpdatable: false,
|
|
894
|
+
},
|
|
895
|
+
],
|
|
896
|
+
root,
|
|
897
|
+
);
|
|
898
|
+
|
|
899
|
+
if (refetchReaderParams.kind === 'MissingData') {
|
|
900
|
+
return {
|
|
901
|
+
kind: 'MissingData',
|
|
902
|
+
reason: 'Missing data for ' + field.alias + ' on root ' + root.__link,
|
|
903
|
+
nestedReason: refetchReaderParams,
|
|
904
|
+
recordLink: refetchReaderParams.recordLink,
|
|
905
|
+
};
|
|
906
|
+
}
|
|
907
|
+
|
|
908
|
+
const refetchQuery = nestedRefetchQueries[field.refetchQueryIndex];
|
|
909
|
+
if (refetchQuery == null) {
|
|
910
|
+
throw new Error(
|
|
911
|
+
'refetchQuery is null in RefetchField. This is indicative of a bug in Isograph.',
|
|
912
|
+
);
|
|
913
|
+
}
|
|
914
|
+
const refetchQueryArtifact = refetchQuery.artifact;
|
|
915
|
+
const allowedVariables = refetchQuery.allowedVariables;
|
|
916
|
+
|
|
917
|
+
return {
|
|
918
|
+
kind: 'Success',
|
|
919
|
+
data: (
|
|
920
|
+
args: any,
|
|
921
|
+
// TODO get the associated type for FetchOptions from the loadably selected field
|
|
922
|
+
fetchOptions?: FetchOptions<any, never>,
|
|
923
|
+
) => {
|
|
924
|
+
const includeReadOutData = (variables: any, readOutData: any) => {
|
|
925
|
+
variables.id = readOutData.id;
|
|
926
|
+
return variables;
|
|
927
|
+
};
|
|
928
|
+
const localVariables = includeReadOutData(
|
|
929
|
+
args ?? {},
|
|
930
|
+
refetchReaderParams.data,
|
|
931
|
+
);
|
|
932
|
+
writeQueryArgsToVariables(localVariables, field.arguments, variables);
|
|
933
|
+
|
|
934
|
+
return [
|
|
935
|
+
// Stable id
|
|
936
|
+
root.__typename +
|
|
937
|
+
':' +
|
|
938
|
+
root.__link +
|
|
939
|
+
'/' +
|
|
940
|
+
field.fieldName +
|
|
941
|
+
'/' +
|
|
942
|
+
stableStringifyArgs(localVariables),
|
|
943
|
+
// Fetcher
|
|
944
|
+
(): ItemCleanupPair<FragmentReference<any, any>> | undefined => {
|
|
945
|
+
const variables = includeReadOutData(
|
|
946
|
+
filterVariables({ ...args, ...localVariables }, allowedVariables),
|
|
947
|
+
refetchReaderParams.data,
|
|
948
|
+
);
|
|
949
|
+
|
|
950
|
+
const readerWithRefetchQueries = wrapResolvedValue({
|
|
951
|
+
kind: 'ReaderWithRefetchQueries',
|
|
952
|
+
readerArtifact: {
|
|
953
|
+
kind: 'EagerReaderArtifact',
|
|
954
|
+
fieldName: field.fieldName,
|
|
955
|
+
readerAst: field.selections,
|
|
956
|
+
resolver: ({ data }: { data: any }) => data,
|
|
957
|
+
hasUpdatable: false,
|
|
958
|
+
},
|
|
959
|
+
nestedRefetchQueries,
|
|
960
|
+
} as const);
|
|
961
|
+
|
|
962
|
+
const [networkRequest, disposeNetworkRequest] =
|
|
963
|
+
maybeMakeNetworkRequest(
|
|
964
|
+
environment,
|
|
965
|
+
refetchQueryArtifact,
|
|
966
|
+
variables,
|
|
967
|
+
readerWithRefetchQueries,
|
|
968
|
+
fetchOptions ?? null,
|
|
969
|
+
);
|
|
970
|
+
|
|
971
|
+
const fragmentReference: FragmentReference<any, any> = {
|
|
972
|
+
kind: 'FragmentReference',
|
|
973
|
+
fieldName: field.fieldName,
|
|
974
|
+
readerArtifactKind: 'EagerReaderArtifact',
|
|
975
|
+
readerWithRefetchQueries: readerWithRefetchQueries,
|
|
976
|
+
root,
|
|
977
|
+
variables,
|
|
978
|
+
networkRequest,
|
|
979
|
+
};
|
|
980
|
+
return [fragmentReference, disposeNetworkRequest];
|
|
981
|
+
},
|
|
982
|
+
];
|
|
983
|
+
},
|
|
984
|
+
};
|
|
985
|
+
}
|
|
986
|
+
|
|
917
987
|
export type NetworkRequestReaderOptions = {
|
|
918
988
|
suspendIfInFlight: boolean;
|
|
919
989
|
throwOnNetworkError: boolean;
|
package/src/core/reader.ts
CHANGED
|
@@ -31,7 +31,7 @@ export type EagerReaderArtifact<
|
|
|
31
31
|
TClientFieldValue,
|
|
32
32
|
> = {
|
|
33
33
|
readonly kind: 'EagerReaderArtifact';
|
|
34
|
-
readonly fieldName:
|
|
34
|
+
readonly fieldName: ComponentOrFieldName;
|
|
35
35
|
readonly readerAst: ReaderAst<TReadFromStore>;
|
|
36
36
|
readonly resolver: (
|
|
37
37
|
data: ResolverFirstParameter<TReadFromStore>,
|
|
@@ -110,7 +110,7 @@ export type ReaderLinkedField = {
|
|
|
110
110
|
readonly arguments: Arguments | null;
|
|
111
111
|
readonly condition: EagerReaderArtifact<
|
|
112
112
|
{ data: any; parameters: any; startUpdate?: StartUpdate<any> },
|
|
113
|
-
StoreLink | null
|
|
113
|
+
StoreLink | null | (StoreLink | null)[] | StoreLink[]
|
|
114
114
|
> | null;
|
|
115
115
|
readonly isUpdatable: boolean;
|
|
116
116
|
/**
|
|
@@ -119,6 +119,10 @@ export type ReaderLinkedField = {
|
|
|
119
119
|
readonly refetchQueryIndex: number | null;
|
|
120
120
|
};
|
|
121
121
|
|
|
122
|
+
export interface ReaderClientPointer extends ReaderLinkedField {
|
|
123
|
+
readonly refetchQueryIndex: number;
|
|
124
|
+
}
|
|
125
|
+
|
|
122
126
|
export type ReaderNonLoadableResolverField = {
|
|
123
127
|
readonly kind: 'Resolver';
|
|
124
128
|
readonly alias: string;
|
|
@@ -147,10 +151,10 @@ export type LoadablySelectedField = {
|
|
|
147
151
|
readonly queryArguments: Arguments | null;
|
|
148
152
|
readonly refetchReaderAst: ReaderAst<any>;
|
|
149
153
|
|
|
150
|
-
// TODO we should not type these as any
|
|
154
|
+
// TODO we should not type these as any.
|
|
151
155
|
readonly entrypoint:
|
|
152
|
-
| IsographEntrypoint<any, any, any>
|
|
153
|
-
| IsographEntrypointLoader<any, any>;
|
|
156
|
+
| IsographEntrypoint<any, any, any, any>
|
|
157
|
+
| IsographEntrypointLoader<any, any, any>;
|
|
154
158
|
};
|
|
155
159
|
|
|
156
160
|
export type StableId = string;
|
|
@@ -173,5 +177,5 @@ export type LoadableField<
|
|
|
173
177
|
// user-facing API. Users should only interact with LoadableFields via APIs
|
|
174
178
|
// like useClientSideDefer. These APIs should have a nullable fetchOptions
|
|
175
179
|
// parameter, and provide a default value ({}) to the LoadableField.
|
|
176
|
-
fetchOptions: FetchOptions<TResult>,
|
|
180
|
+
fetchOptions: FetchOptions<TResult, never>,
|
|
177
181
|
) => [StableId, Factory<FragmentReference<TReadFromStore, TResult>>];
|