@isograph/react 0.1.0 → 0.2.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.
Files changed (107) hide show
  1. package/dist/core/FragmentReference.d.ts +15 -0
  2. package/dist/core/FragmentReference.js +17 -0
  3. package/dist/core/IsographEnvironment.d.ts +71 -0
  4. package/dist/core/IsographEnvironment.js +72 -0
  5. package/dist/core/PromiseWrapper.d.ts +27 -0
  6. package/dist/core/PromiseWrapper.js +58 -0
  7. package/dist/core/areEqualWithDeepComparison.d.ts +3 -0
  8. package/dist/core/areEqualWithDeepComparison.js +61 -0
  9. package/dist/core/cache.d.ts +28 -0
  10. package/dist/core/cache.js +452 -0
  11. package/dist/core/componentCache.d.ts +5 -0
  12. package/dist/core/componentCache.js +38 -0
  13. package/dist/core/entrypoint.d.ts +50 -0
  14. package/dist/core/entrypoint.js +8 -0
  15. package/dist/core/garbageCollection.d.ts +11 -0
  16. package/dist/core/garbageCollection.js +74 -0
  17. package/dist/core/makeNetworkRequest.d.ts +6 -0
  18. package/dist/core/makeNetworkRequest.js +62 -0
  19. package/dist/core/read.d.ts +12 -0
  20. package/dist/core/read.js +415 -0
  21. package/dist/core/reader.d.ts +63 -0
  22. package/dist/core/reader.js +2 -0
  23. package/dist/core/util.d.ts +17 -0
  24. package/dist/core/util.js +2 -0
  25. package/dist/index.d.ts +21 -118
  26. package/dist/index.js +50 -303
  27. package/dist/loadable-hooks/useClientSideDefer.d.ts +4 -0
  28. package/dist/loadable-hooks/useClientSideDefer.js +15 -0
  29. package/dist/loadable-hooks/useImperativeExposedMutationField.d.ts +5 -0
  30. package/dist/loadable-hooks/useImperativeExposedMutationField.js +15 -0
  31. package/dist/loadable-hooks/useImperativeLoadableField.d.ts +9 -0
  32. package/dist/loadable-hooks/useImperativeLoadableField.js +15 -0
  33. package/dist/loadable-hooks/useSkipLimitPagination.d.ts +33 -0
  34. package/dist/loadable-hooks/useSkipLimitPagination.js +118 -0
  35. package/dist/react/FragmentReader.d.ts +13 -0
  36. package/dist/react/FragmentReader.js +33 -0
  37. package/dist/react/IsographEnvironmentProvider.d.ts +10 -0
  38. package/dist/{IsographEnvironment.js → react/IsographEnvironmentProvider.js} +2 -20
  39. package/dist/react/useImperativeReference.d.ts +7 -0
  40. package/dist/react/useImperativeReference.js +36 -0
  41. package/dist/react/useLazyReference.d.ts +5 -0
  42. package/dist/react/useLazyReference.js +14 -0
  43. package/dist/react/useReadAndSubscribe.d.ts +11 -0
  44. package/dist/react/useReadAndSubscribe.js +41 -0
  45. package/dist/react/useRerenderOnChange.d.ts +3 -0
  46. package/dist/react/useRerenderOnChange.js +23 -0
  47. package/dist/react/useResult.d.ts +5 -0
  48. package/dist/react/useResult.js +36 -0
  49. package/docs/how-useLazyReference-works.md +117 -0
  50. package/package.json +12 -6
  51. package/src/core/FragmentReference.ts +37 -0
  52. package/src/core/IsographEnvironment.ts +183 -0
  53. package/src/core/PromiseWrapper.ts +86 -0
  54. package/src/core/areEqualWithDeepComparison.ts +78 -0
  55. package/src/core/cache.ts +721 -0
  56. package/src/core/componentCache.ts +61 -0
  57. package/src/core/entrypoint.ts +99 -0
  58. package/src/core/garbageCollection.ts +122 -0
  59. package/src/core/makeNetworkRequest.ts +99 -0
  60. package/src/core/read.ts +615 -0
  61. package/src/core/reader.ts +133 -0
  62. package/src/core/util.ts +23 -0
  63. package/src/index.ts +86 -0
  64. package/src/loadable-hooks/useClientSideDefer.ts +28 -0
  65. package/src/loadable-hooks/useImperativeExposedMutationField.ts +17 -0
  66. package/src/loadable-hooks/useImperativeLoadableField.ts +26 -0
  67. package/src/loadable-hooks/useSkipLimitPagination.ts +211 -0
  68. package/src/react/FragmentReader.tsx +34 -0
  69. package/src/react/IsographEnvironmentProvider.tsx +33 -0
  70. package/src/react/useImperativeReference.ts +57 -0
  71. package/src/react/useLazyReference.ts +22 -0
  72. package/src/react/useReadAndSubscribe.ts +66 -0
  73. package/src/react/useRerenderOnChange.ts +33 -0
  74. package/src/react/useResult.ts +65 -0
  75. package/src/tests/__isograph/Query/meName/entrypoint.ts +47 -0
  76. package/src/tests/__isograph/Query/meName/output_type.ts +3 -0
  77. package/src/tests/__isograph/Query/meName/param_type.ts +6 -0
  78. package/src/tests/__isograph/Query/meName/resolver_reader.ts +32 -0
  79. package/src/tests/__isograph/Query/meNameSuccessor/entrypoint.ts +83 -0
  80. package/src/tests/__isograph/Query/meNameSuccessor/output_type.ts +3 -0
  81. package/src/tests/__isograph/Query/meNameSuccessor/param_type.ts +11 -0
  82. package/src/tests/__isograph/Query/meNameSuccessor/resolver_reader.ts +54 -0
  83. package/src/tests/__isograph/Query/nodeField/entrypoint.ts +46 -0
  84. package/src/tests/__isograph/Query/nodeField/output_type.ts +3 -0
  85. package/src/tests/__isograph/Query/nodeField/param_type.ts +6 -0
  86. package/src/tests/__isograph/Query/nodeField/resolver_reader.ts +37 -0
  87. package/src/tests/__isograph/iso.ts +88 -0
  88. package/src/tests/garbageCollection.test.ts +136 -0
  89. package/src/tests/isograph.config.json +7 -0
  90. package/src/tests/meNameSuccessor.ts +20 -0
  91. package/src/tests/nodeQuery.ts +17 -0
  92. package/src/tests/schema.graphql +16 -0
  93. package/src/tests/tsconfig.json +21 -0
  94. package/tsconfig.json +6 -0
  95. package/tsconfig.pkg.json +2 -1
  96. package/dist/IsographEnvironment.d.ts +0 -56
  97. package/dist/PromiseWrapper.d.ts +0 -13
  98. package/dist/PromiseWrapper.js +0 -22
  99. package/dist/cache.d.ts +0 -26
  100. package/dist/cache.js +0 -274
  101. package/dist/componentCache.d.ts +0 -6
  102. package/dist/componentCache.js +0 -31
  103. package/src/IsographEnvironment.tsx +0 -120
  104. package/src/PromiseWrapper.ts +0 -29
  105. package/src/cache.tsx +0 -484
  106. package/src/componentCache.ts +0 -44
  107. package/src/index.tsx +0 -651
@@ -0,0 +1,66 @@
1
+ import { useEffect, useState } from 'react';
2
+ import {
3
+ FragmentReference,
4
+ stableIdForFragmentReference,
5
+ } from '../core/FragmentReference';
6
+ import {
7
+ NetworkRequestReaderOptions,
8
+ readButDoNotEvaluate,
9
+ WithEncounteredRecords,
10
+ } from '../core/read';
11
+ import { useRerenderOnChange } from './useRerenderOnChange';
12
+ import { useIsographEnvironment } from './IsographEnvironmentProvider';
13
+ import { subscribe } from '../core/cache';
14
+
15
+ /**
16
+ * Read the data from a fragment reference and subscribe to updates.
17
+ */
18
+ export function useReadAndSubscribe<TReadFromStore extends Object>(
19
+ fragmentReference: FragmentReference<TReadFromStore, any>,
20
+ networkRequestOptions: NetworkRequestReaderOptions,
21
+ ): TReadFromStore {
22
+ const environment = useIsographEnvironment();
23
+ const [readOutDataAndRecords, setReadOutDataAndRecords] = useState(() =>
24
+ readButDoNotEvaluate(environment, fragmentReference, networkRequestOptions),
25
+ );
26
+ useRerenderOnChange(
27
+ readOutDataAndRecords,
28
+ fragmentReference,
29
+ setReadOutDataAndRecords,
30
+ );
31
+ return readOutDataAndRecords.item;
32
+ }
33
+
34
+ export function useSubscribeToMultiple<TReadFromStore extends Object>(
35
+ items: ReadonlyArray<{
36
+ records: WithEncounteredRecords<TReadFromStore>;
37
+ callback: (updatedRecords: WithEncounteredRecords<TReadFromStore>) => void;
38
+ fragmentReference: FragmentReference<TReadFromStore, any>;
39
+ }>,
40
+ ) {
41
+ const environment = useIsographEnvironment();
42
+ useEffect(
43
+ () => {
44
+ const cleanupFns = items.map(
45
+ ({ records, callback, fragmentReference }) => {
46
+ return subscribe(environment, records, fragmentReference, callback);
47
+ },
48
+ );
49
+ return () => {
50
+ cleanupFns.forEach((loader) => {
51
+ loader();
52
+ });
53
+ };
54
+ },
55
+ // By analogy to useReadAndSubscribe, we can have an empty dependency array?
56
+ // Maybe callback has to be depended on. I don't know!
57
+ // TODO find out
58
+ [
59
+ items
60
+ .map(({ fragmentReference }) =>
61
+ stableIdForFragmentReference(fragmentReference),
62
+ )
63
+ .join('.'),
64
+ ],
65
+ );
66
+ }
@@ -0,0 +1,33 @@
1
+ import { useEffect } from 'react';
2
+ import { subscribe } from '../core/cache';
3
+ import { WithEncounteredRecords } from '../core/read';
4
+ import { FragmentReference } from '../core/FragmentReference';
5
+ import { useIsographEnvironment } from './IsographEnvironmentProvider';
6
+
7
+ // TODO add unit tests for this. Add integration tests that test
8
+ // behavior when the encounteredRecords underneath a fragment change.
9
+ export function useRerenderOnChange<TReadFromStore extends Object>(
10
+ encounteredDataAndRecords: WithEncounteredRecords<TReadFromStore>,
11
+ fragmentReference: FragmentReference<any, any>,
12
+ setEncounteredDataAndRecords: (
13
+ data: WithEncounteredRecords<TReadFromStore>,
14
+ ) => void,
15
+ ) {
16
+ const environment = useIsographEnvironment();
17
+ useEffect(() => {
18
+ return subscribe(
19
+ environment,
20
+ encounteredDataAndRecords,
21
+ fragmentReference,
22
+ (newEncounteredDataAndRecords) => {
23
+ setEncounteredDataAndRecords(newEncounteredDataAndRecords);
24
+ },
25
+ );
26
+ // Note: this is an empty array on purpose:
27
+ // - the fragment reference is stable for the life of the component
28
+ // - ownership of encounteredDataAndRecords is transferred into the
29
+ // environment
30
+ // - though maybe we need to include setEncounteredDataAndRecords in
31
+ // the dependency array
32
+ }, []);
33
+ }
@@ -0,0 +1,65 @@
1
+ import { useIsographEnvironment } from '../react/IsographEnvironmentProvider';
2
+ import { FragmentReference } from '../core/FragmentReference';
3
+ import { getOrCreateCachedComponent } from '../core/componentCache';
4
+ import { useReadAndSubscribe } from './useReadAndSubscribe';
5
+ import {
6
+ getNetworkRequestOptionsWithDefaults,
7
+ NetworkRequestReaderOptions,
8
+ } from '../core/read';
9
+ import {
10
+ getPromiseState,
11
+ PromiseWrapper,
12
+ readPromise,
13
+ } from '../core/PromiseWrapper';
14
+
15
+ export function useResult<TReadFromStore extends Object, TClientFieldValue>(
16
+ fragmentReference: FragmentReference<TReadFromStore, TClientFieldValue>,
17
+ partialNetworkRequestOptions?: Partial<NetworkRequestReaderOptions> | void,
18
+ ): TClientFieldValue {
19
+ const environment = useIsographEnvironment();
20
+ const networkRequestOptions = getNetworkRequestOptionsWithDefaults(
21
+ partialNetworkRequestOptions,
22
+ );
23
+
24
+ maybeUnwrapNetworkRequest(
25
+ fragmentReference.networkRequest,
26
+ networkRequestOptions,
27
+ );
28
+ const readerWithRefetchQueries = readPromise(
29
+ fragmentReference.readerWithRefetchQueries,
30
+ );
31
+
32
+ switch (readerWithRefetchQueries.readerArtifact.kind) {
33
+ case 'ComponentReaderArtifact': {
34
+ // @ts-expect-error
35
+ return getOrCreateCachedComponent(
36
+ environment,
37
+ readerWithRefetchQueries.readerArtifact.componentName,
38
+ fragmentReference,
39
+ networkRequestOptions,
40
+ );
41
+ }
42
+ case 'EagerReaderArtifact': {
43
+ const data = useReadAndSubscribe(
44
+ fragmentReference,
45
+ networkRequestOptions,
46
+ );
47
+ return readerWithRefetchQueries.readerArtifact.resolver(data);
48
+ }
49
+ }
50
+ }
51
+
52
+ export function maybeUnwrapNetworkRequest(
53
+ networkRequest: PromiseWrapper<void, any>,
54
+ networkRequestOptions: NetworkRequestReaderOptions,
55
+ ) {
56
+ const state = getPromiseState(networkRequest);
57
+ if (state.kind === 'Err' && networkRequestOptions.throwOnNetworkError) {
58
+ throw state.error;
59
+ } else if (
60
+ state.kind === 'Pending' &&
61
+ networkRequestOptions.suspendIfInFlight
62
+ ) {
63
+ throw state.promise;
64
+ }
65
+ }
@@ -0,0 +1,47 @@
1
+ import type {IsographEntrypoint, NormalizationAst, RefetchQueryNormalizationArtifactWrapper} from '@isograph/react';
2
+ import {Query__meName__param} from './param_type';
3
+ import {Query__meName__output_type} from './output_type';
4
+ import readerResolver from './resolver_reader';
5
+ const nestedRefetchQueries: RefetchQueryNormalizationArtifactWrapper[] = [];
6
+
7
+ const queryText = 'query meName {\
8
+ me {\
9
+ id,\
10
+ name,\
11
+ },\
12
+ }';
13
+
14
+ const normalizationAst: NormalizationAst = [
15
+ {
16
+ kind: "Linked",
17
+ fieldName: "me",
18
+ arguments: null,
19
+ selections: [
20
+ {
21
+ kind: "Scalar",
22
+ fieldName: "id",
23
+ arguments: null,
24
+ },
25
+ {
26
+ kind: "Scalar",
27
+ fieldName: "name",
28
+ arguments: null,
29
+ },
30
+ ],
31
+ },
32
+ ];
33
+ const artifact: IsographEntrypoint<
34
+ Query__meName__param,
35
+ Query__meName__output_type
36
+ > = {
37
+ kind: "Entrypoint",
38
+ queryText,
39
+ normalizationAst,
40
+ readerWithRefetchQueries: {
41
+ kind: "ReaderWithRefetchQueries",
42
+ nestedRefetchQueries,
43
+ readerArtifact: readerResolver,
44
+ },
45
+ };
46
+
47
+ export default artifact;
@@ -0,0 +1,3 @@
1
+ import type React from 'react';
2
+ import { meNameField as resolver } from '../../../garbageCollection.test';
3
+ export type Query__meName__output_type = ReturnType<typeof resolver>;
@@ -0,0 +1,6 @@
1
+
2
+ export type Query__meName__param = {
3
+ me: {
4
+ name: string,
5
+ },
6
+ };
@@ -0,0 +1,32 @@
1
+ import type { EagerReaderArtifact, ReaderAst } from '@isograph/react';
2
+ import { Query__meName__param } from './param_type';
3
+ import { Query__meName__output_type } from './output_type';
4
+ import { meNameField as resolver } from '../../../garbageCollection.test';
5
+
6
+ const readerAst: ReaderAst<Query__meName__param> = [
7
+ {
8
+ kind: "Linked",
9
+ fieldName: "me",
10
+ alias: null,
11
+ arguments: null,
12
+ selections: [
13
+ {
14
+ kind: "Scalar",
15
+ fieldName: "name",
16
+ alias: null,
17
+ arguments: null,
18
+ },
19
+ ],
20
+ },
21
+ ];
22
+
23
+ const artifact: EagerReaderArtifact<
24
+ Query__meName__param,
25
+ Query__meName__output_type
26
+ > = {
27
+ kind: "EagerReaderArtifact",
28
+ resolver,
29
+ readerAst,
30
+ };
31
+
32
+ export default artifact;
@@ -0,0 +1,83 @@
1
+ import type {IsographEntrypoint, NormalizationAst, RefetchQueryNormalizationArtifactWrapper} from '@isograph/react';
2
+ import {Query__meNameSuccessor__param} from './param_type';
3
+ import {Query__meNameSuccessor__output_type} from './output_type';
4
+ import readerResolver from './resolver_reader';
5
+ const nestedRefetchQueries: RefetchQueryNormalizationArtifactWrapper[] = [];
6
+
7
+ const queryText = 'query meNameSuccessor {\
8
+ me {\
9
+ id,\
10
+ name,\
11
+ successor {\
12
+ id,\
13
+ successor {\
14
+ id,\
15
+ name,\
16
+ },\
17
+ },\
18
+ },\
19
+ }';
20
+
21
+ const normalizationAst: NormalizationAst = [
22
+ {
23
+ kind: "Linked",
24
+ fieldName: "me",
25
+ arguments: null,
26
+ selections: [
27
+ {
28
+ kind: "Scalar",
29
+ fieldName: "id",
30
+ arguments: null,
31
+ },
32
+ {
33
+ kind: "Scalar",
34
+ fieldName: "name",
35
+ arguments: null,
36
+ },
37
+ {
38
+ kind: "Linked",
39
+ fieldName: "successor",
40
+ arguments: null,
41
+ selections: [
42
+ {
43
+ kind: "Scalar",
44
+ fieldName: "id",
45
+ arguments: null,
46
+ },
47
+ {
48
+ kind: "Linked",
49
+ fieldName: "successor",
50
+ arguments: null,
51
+ selections: [
52
+ {
53
+ kind: "Scalar",
54
+ fieldName: "id",
55
+ arguments: null,
56
+ },
57
+ {
58
+ kind: "Scalar",
59
+ fieldName: "name",
60
+ arguments: null,
61
+ },
62
+ ],
63
+ },
64
+ ],
65
+ },
66
+ ],
67
+ },
68
+ ];
69
+ const artifact: IsographEntrypoint<
70
+ Query__meNameSuccessor__param,
71
+ Query__meNameSuccessor__output_type
72
+ > = {
73
+ kind: "Entrypoint",
74
+ queryText,
75
+ normalizationAst,
76
+ readerWithRefetchQueries: {
77
+ kind: "ReaderWithRefetchQueries",
78
+ nestedRefetchQueries,
79
+ readerArtifact: readerResolver,
80
+ },
81
+ };
82
+
83
+ export default artifact;
@@ -0,0 +1,3 @@
1
+ import type React from 'react';
2
+ import { meNameField as resolver } from '../../../meNameSuccessor';
3
+ export type Query__meNameSuccessor__output_type = ReturnType<typeof resolver>;
@@ -0,0 +1,11 @@
1
+
2
+ export type Query__meNameSuccessor__param = {
3
+ me: {
4
+ name: string,
5
+ successor: ({
6
+ successor: ({
7
+ name: string,
8
+ } | null),
9
+ } | null),
10
+ },
11
+ };
@@ -0,0 +1,54 @@
1
+ import type { EagerReaderArtifact, ReaderAst } from '@isograph/react';
2
+ import { Query__meNameSuccessor__param } from './param_type';
3
+ import { Query__meNameSuccessor__output_type } from './output_type';
4
+ import { meNameField as resolver } from '../../../meNameSuccessor';
5
+
6
+ const readerAst: ReaderAst<Query__meNameSuccessor__param> = [
7
+ {
8
+ kind: "Linked",
9
+ fieldName: "me",
10
+ alias: null,
11
+ arguments: null,
12
+ selections: [
13
+ {
14
+ kind: "Scalar",
15
+ fieldName: "name",
16
+ alias: null,
17
+ arguments: null,
18
+ },
19
+ {
20
+ kind: "Linked",
21
+ fieldName: "successor",
22
+ alias: null,
23
+ arguments: null,
24
+ selections: [
25
+ {
26
+ kind: "Linked",
27
+ fieldName: "successor",
28
+ alias: null,
29
+ arguments: null,
30
+ selections: [
31
+ {
32
+ kind: "Scalar",
33
+ fieldName: "name",
34
+ alias: null,
35
+ arguments: null,
36
+ },
37
+ ],
38
+ },
39
+ ],
40
+ },
41
+ ],
42
+ },
43
+ ];
44
+
45
+ const artifact: EagerReaderArtifact<
46
+ Query__meNameSuccessor__param,
47
+ Query__meNameSuccessor__output_type
48
+ > = {
49
+ kind: "EagerReaderArtifact",
50
+ resolver,
51
+ readerAst,
52
+ };
53
+
54
+ export default artifact;
@@ -0,0 +1,46 @@
1
+ import type {IsographEntrypoint, NormalizationAst, RefetchQueryNormalizationArtifactWrapper} from '@isograph/react';
2
+ import {Query__nodeField__param} from './param_type';
3
+ import {Query__nodeField__output_type} from './output_type';
4
+ import readerResolver from './resolver_reader';
5
+ const nestedRefetchQueries: RefetchQueryNormalizationArtifactWrapper[] = [];
6
+
7
+ const queryText = 'query nodeField ($id: ID!) {\
8
+ node____id___v_id: node(id: $id) {\
9
+ id,\
10
+ },\
11
+ }';
12
+
13
+ const normalizationAst: NormalizationAst = [
14
+ {
15
+ kind: "Linked",
16
+ fieldName: "node",
17
+ arguments: [
18
+ [
19
+ "id",
20
+ { kind: "Variable", name: "id" },
21
+ ],
22
+ ],
23
+ selections: [
24
+ {
25
+ kind: "Scalar",
26
+ fieldName: "id",
27
+ arguments: null,
28
+ },
29
+ ],
30
+ },
31
+ ];
32
+ const artifact: IsographEntrypoint<
33
+ Query__nodeField__param,
34
+ Query__nodeField__output_type
35
+ > = {
36
+ kind: "Entrypoint",
37
+ queryText,
38
+ normalizationAst,
39
+ readerWithRefetchQueries: {
40
+ kind: "ReaderWithRefetchQueries",
41
+ nestedRefetchQueries,
42
+ readerArtifact: readerResolver,
43
+ },
44
+ };
45
+
46
+ export default artifact;
@@ -0,0 +1,3 @@
1
+ import type React from 'react';
2
+ import { nodeField as resolver } from '../../../nodeQuery';
3
+ export type Query__nodeField__output_type = ReturnType<typeof resolver>;
@@ -0,0 +1,6 @@
1
+
2
+ export type Query__nodeField__param = {
3
+ node: ({
4
+ id: string,
5
+ } | null),
6
+ };
@@ -0,0 +1,37 @@
1
+ import type { EagerReaderArtifact, ReaderAst } from '@isograph/react';
2
+ import { Query__nodeField__param } from './param_type';
3
+ import { Query__nodeField__output_type } from './output_type';
4
+ import { nodeField as resolver } from '../../../nodeQuery';
5
+
6
+ const readerAst: ReaderAst<Query__nodeField__param> = [
7
+ {
8
+ kind: "Linked",
9
+ fieldName: "node",
10
+ alias: null,
11
+ arguments: [
12
+ [
13
+ "id",
14
+ { kind: "Variable", name: "id" },
15
+ ],
16
+ ],
17
+ selections: [
18
+ {
19
+ kind: "Scalar",
20
+ fieldName: "id",
21
+ alias: null,
22
+ arguments: null,
23
+ },
24
+ ],
25
+ },
26
+ ];
27
+
28
+ const artifact: EagerReaderArtifact<
29
+ Query__nodeField__param,
30
+ Query__nodeField__output_type
31
+ > = {
32
+ kind: "EagerReaderArtifact",
33
+ resolver,
34
+ readerAst,
35
+ };
36
+
37
+ export default artifact;
@@ -0,0 +1,88 @@
1
+ import type {IsographEntrypoint} from '@isograph/react';
2
+ import { Query__meNameSuccessor__param } from './Query/meNameSuccessor/param_type';
3
+ import { Query__meName__param } from './Query/meName/param_type';
4
+ import { Query__nodeField__param } from './Query/nodeField/param_type';
5
+ import entrypoint_Query__meNameSuccessor from '../__isograph/Query/meNameSuccessor/entrypoint';
6
+ import entrypoint_Query__meName from '../__isograph/Query/meName/entrypoint';
7
+ import entrypoint_Query__nodeField from '../__isograph/Query/nodeField/entrypoint';
8
+
9
+ // This is the type given to regular client fields.
10
+ // This means that the type of the exported iso literal is exactly
11
+ // the type of the passed-in function, which takes one parameter
12
+ // of type TParam.
13
+ type IdentityWithParam<TParam> = <TClientFieldReturn>(
14
+ clientField: (param: TParam) => TClientFieldReturn
15
+ ) => (param: TParam) => TClientFieldReturn;
16
+
17
+ // This is the type given it to client fields with @component.
18
+ // This means that the type of the exported iso literal is exactly
19
+ // the type of the passed-in function, which takes two parameters.
20
+ // The first has type TParam, and the second has type TComponentProps.
21
+ //
22
+ // TComponentProps becomes the types of the props you must pass
23
+ // whenever the @component field is rendered.
24
+ type IdentityWithParamComponent<TParam> = <TClientFieldReturn, TComponentProps = Record<string, never>>(
25
+ clientComponentField: (data: TParam, componentProps: TComponentProps) => TClientFieldReturn
26
+ ) => (data: TParam, componentProps: TComponentProps) => TClientFieldReturn;
27
+
28
+ type WhitespaceCharacter = ' ' | '\t' | '\n';
29
+ type Whitespace<In> = In extends `${WhitespaceCharacter}${infer In}`
30
+ ? Whitespace<In>
31
+ : In;
32
+
33
+ // This is a recursive TypeScript type that matches strings that
34
+ // start with whitespace, followed by TString. So e.g. if we have
35
+ // ```
36
+ // export function iso<T>(
37
+ // isographLiteralText: T & MatchesWhitespaceAndString<'field Query.foo', T>
38
+ // ): Bar;
39
+ // ```
40
+ // then, when you call
41
+ // ```
42
+ // const x = iso(`
43
+ // field Query.foo ...
44
+ // `);
45
+ // ```
46
+ // then the type of `x` will be `Bar`, both in VSCode and when running
47
+ // tsc. This is how we achieve type safety — you can only use fields
48
+ // that you have explicitly selected.
49
+ type MatchesWhitespaceAndString<
50
+ TString extends string,
51
+ T
52
+ > = Whitespace<T> extends `${TString}${string}` ? T : never;
53
+
54
+ export function iso<T>(
55
+ param: T & MatchesWhitespaceAndString<'field Query.meNameSuccessor', T>
56
+ ): IdentityWithParam<Query__meNameSuccessor__param>;
57
+
58
+ export function iso<T>(
59
+ param: T & MatchesWhitespaceAndString<'field Query.meName', T>
60
+ ): IdentityWithParam<Query__meName__param>;
61
+
62
+ export function iso<T>(
63
+ param: T & MatchesWhitespaceAndString<'field Query.nodeField', T>
64
+ ): IdentityWithParam<Query__nodeField__param>;
65
+
66
+ export function iso<T>(
67
+ param: T & MatchesWhitespaceAndString<'entrypoint Query.meNameSuccessor', T>
68
+ ): typeof entrypoint_Query__meNameSuccessor;
69
+
70
+ export function iso<T>(
71
+ param: T & MatchesWhitespaceAndString<'entrypoint Query.meName', T>
72
+ ): typeof entrypoint_Query__meName;
73
+
74
+ export function iso<T>(
75
+ param: T & MatchesWhitespaceAndString<'entrypoint Query.nodeField', T>
76
+ ): typeof entrypoint_Query__nodeField;
77
+
78
+ export function iso(_isographLiteralText: string):
79
+ | IdentityWithParam<any>
80
+ | IdentityWithParamComponent<any>
81
+ | IsographEntrypoint<any, any>
82
+ {
83
+ return function identity<TClientFieldReturn>(
84
+ clientFieldOrEntrypoint: (param: any) => TClientFieldReturn,
85
+ ): (param: any) => TClientFieldReturn {
86
+ return clientFieldOrEntrypoint;
87
+ };
88
+ }