@isograph/react 0.0.0-main-2f494978 → 0.0.0-main-6b81bb01

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/dist/cache.d.ts CHANGED
@@ -15,7 +15,7 @@ declare global {
15
15
  */
16
16
  export declare function stableCopy<T>(value: T): T;
17
17
  type IsoResolver = IsographEntrypoint<any, any>;
18
- export declare function getOrCreateCacheForArtifact<T>(environment: IsographEnvironment, artifact: IsographEntrypoint<any, T>, variables: object): ParentCache<PromiseWrapper<T>>;
18
+ export declare function getOrCreateCacheForArtifact<TReadFromStore extends Object, TClientFieldValue>(environment: IsographEnvironment, artifact: IsographEntrypoint<TReadFromStore, TClientFieldValue>, variables: object): ParentCache<PromiseWrapper<TClientFieldValue>>;
19
19
  export declare function makeNetworkRequest<T>(environment: IsographEnvironment, artifact: IsoResolver, variables: object): ItemCleanupPair<PromiseWrapper<T>>;
20
20
  export declare function subscribe(environment: IsographEnvironment, callback: () => void): () => void;
21
21
  export declare function onNextChange(environment: IsographEnvironment): Promise<void>;
@@ -1,8 +1,8 @@
1
1
  import { UnassignedState } from '@isograph/react-disposable-state';
2
- import { ExtractReadFromStore, ExtractResolverResult, IsographEntrypoint } from './entrypoint';
2
+ import { IsographEntrypoint } from './entrypoint';
3
3
  import { FragmentReference } from './FragmentReference';
4
- export declare function useImperativeReference<TEntrypoint extends IsographEntrypoint<any, any>>(entrypoint: TEntrypoint): {
5
- queryReference: FragmentReference<ExtractReadFromStore<TEntrypoint>, ExtractResolverResult<TEntrypoint>> | UnassignedState;
4
+ export declare function useImperativeReference<TReadFromStore extends Object, TClientFieldValue>(entrypoint: IsographEntrypoint<TReadFromStore, TClientFieldValue>): {
5
+ queryReference: FragmentReference<TReadFromStore, TClientFieldValue> | UnassignedState;
6
6
  loadQueryReference: (variables: {
7
7
  [index: string]: string;
8
8
  }) => void;
@@ -1,7 +1,7 @@
1
1
  import { FragmentReference, Variable } from './FragmentReference';
2
- import { ExtractReadFromStore, ExtractResolverResult } from './entrypoint';
3
- export declare function useLazyReference<TEntrypoint>(entrypoint: TEntrypoint | ((_: any) => any), variables: {
2
+ import { IsographEntrypoint } from './entrypoint';
3
+ export declare function useLazyReference<TReadFromStore extends Object, TClientFieldValue>(entrypoint: IsographEntrypoint<TReadFromStore, TClientFieldValue>, variables: {
4
4
  [key: string]: Variable;
5
5
  }): {
6
- queryReference: FragmentReference<ExtractReadFromStore<TEntrypoint>, ExtractResolverResult<TEntrypoint>>;
6
+ queryReference: FragmentReference<TReadFromStore, TClientFieldValue>;
7
7
  };
@@ -3,20 +3,14 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.useLazyReference = void 0;
4
4
  const IsographEnvironmentProvider_1 = require("./IsographEnvironmentProvider");
5
5
  const IsographEnvironment_1 = require("./IsographEnvironment");
6
- const entrypoint_1 = require("./entrypoint");
7
6
  const cache_1 = require("./cache");
8
7
  const react_disposable_state_1 = require("@isograph/react-disposable-state");
9
- // Note: we cannot write TEntrypoint extends IsographEntrypoint<any, any, any>, or else
10
- // if we do not explicitly pass a type, the read out type will be any.
11
- // We cannot write TEntrypoint extends IsographEntrypoint<never, never, never>, or else
12
- // any actual Entrypoint we pass will not be valid.
13
8
  function useLazyReference(entrypoint, variables) {
14
9
  const environment = (0, IsographEnvironmentProvider_1.useIsographEnvironment)();
15
- (0, entrypoint_1.assertIsEntrypoint)(entrypoint);
16
10
  const cache = (0, cache_1.getOrCreateCacheForArtifact)(environment, entrypoint, variables);
17
11
  // TODO add comment explaining why we never use this value
18
- // @ts-ignore
19
- const data = (0, react_disposable_state_1.useLazyDisposableState)(cache).state;
12
+ // @ts-ignore(6133)
13
+ const _data = (0, react_disposable_state_1.useLazyDisposableState)(cache).state;
20
14
  return {
21
15
  queryReference: {
22
16
  kind: 'FragmentReference',
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@isograph/react",
3
- "version": "0.0.0-main-2f494978",
3
+ "version": "0.0.0-main-6b81bb01",
4
4
  "description": "Use Isograph with React",
5
5
  "homepage": "https://isograph.dev",
6
6
  "main": "dist/index.js",
@@ -10,14 +10,14 @@
10
10
  "scripts": {
11
11
  "compile": "rm -rf dist/* && tsc -p tsconfig.pkg.json",
12
12
  "compile-watch": "tsc -p tsconfig.pkg.json --watch",
13
- "test": "echo no tests yet",
13
+ "test": "vitest run",
14
14
  "test-watch": "vitest watch",
15
15
  "coverage": "vitest run --coverage",
16
16
  "prepack": "yarn run test && yarn run compile"
17
17
  },
18
18
  "dependencies": {
19
- "@isograph/disposable-types": "0.0.0-main-2f494978",
20
- "@isograph/react-disposable-state": "0.0.0-main-2f494978",
19
+ "@isograph/disposable-types": "0.0.0-main-6b81bb01",
20
+ "@isograph/react-disposable-state": "0.0.0-main-6b81bb01",
21
21
  "react": "^18.2.0"
22
22
  },
23
23
  "devDependencies": {
package/src/cache.ts CHANGED
@@ -76,15 +76,22 @@ export function stableCopy<T>(value: T): T {
76
76
 
77
77
  type IsoResolver = IsographEntrypoint<any, any>;
78
78
 
79
- export function getOrCreateCacheForArtifact<T>(
79
+ export function getOrCreateCacheForArtifact<
80
+ TReadFromStore extends Object,
81
+ TClientFieldValue,
82
+ >(
80
83
  environment: IsographEnvironment,
81
- artifact: IsographEntrypoint<any, T>,
84
+ artifact: IsographEntrypoint<TReadFromStore, TClientFieldValue>,
82
85
  variables: object,
83
- ): ParentCache<PromiseWrapper<T>> {
86
+ ): ParentCache<PromiseWrapper<TClientFieldValue>> {
84
87
  const cacheKey = artifact.queryText + JSON.stringify(stableCopy(variables));
85
- const factory: Factory<PromiseWrapper<T>> = () =>
86
- makeNetworkRequest<T>(environment, artifact, variables);
87
- return getOrCreateCache<PromiseWrapper<T>>(environment, cacheKey, factory);
88
+ const factory: Factory<PromiseWrapper<TClientFieldValue>> = () =>
89
+ makeNetworkRequest<TClientFieldValue>(environment, artifact, variables);
90
+ return getOrCreateCache<PromiseWrapper<TClientFieldValue>>(
91
+ environment,
92
+ cacheKey,
93
+ factory,
94
+ );
88
95
  }
89
96
 
90
97
  type NetworkRequestStatus =
@@ -0,0 +1,43 @@
1
+ import type {IsographEntrypoint, NormalizationAst, RefetchQueryArtifactWrapper} from '@isograph/react';
2
+ import type {Query__meName__param, Query__meName__outputType} from './reader';
3
+ import readerResolver from './reader';
4
+ const nestedRefetchQueries: RefetchQueryArtifactWrapper[] = [];
5
+
6
+ const queryText = 'query meName {\
7
+ me {\
8
+ id,\
9
+ name,\
10
+ },\
11
+ }';
12
+
13
+ const normalizationAst: NormalizationAst = [
14
+ {
15
+ kind: "Linked",
16
+ fieldName: "me",
17
+ arguments: null,
18
+ selections: [
19
+ {
20
+ kind: "Scalar",
21
+ fieldName: "id",
22
+ arguments: null,
23
+ },
24
+ {
25
+ kind: "Scalar",
26
+ fieldName: "name",
27
+ arguments: null,
28
+ },
29
+ ],
30
+ },
31
+ ];
32
+ const artifact: IsographEntrypoint<
33
+ Query__meName__param,
34
+ Query__meName__outputType
35
+ > = {
36
+ kind: "Entrypoint",
37
+ queryText,
38
+ normalizationAst,
39
+ nestedRefetchQueries,
40
+ readerArtifact: readerResolver,
41
+ };
42
+
43
+ export default artifact;
@@ -0,0 +1,40 @@
1
+ import type {ReaderArtifact, ReaderAst, ExtractSecondParam} from '@isograph/react';
2
+ import { meNameField as resolver } from '../../../garbageCollection.test.ts';
3
+
4
+ // the type, when read out (either via useLazyReference or via graph)
5
+ export type Query__meName__outputType = ReturnType<typeof resolver>;
6
+
7
+ const readerAst: ReaderAst<Query__meName__param> = [
8
+ {
9
+ kind: "Linked",
10
+ fieldName: "me",
11
+ alias: null,
12
+ arguments: null,
13
+ selections: [
14
+ {
15
+ kind: "Scalar",
16
+ fieldName: "name",
17
+ alias: null,
18
+ arguments: null,
19
+ },
20
+ ],
21
+ },
22
+ ];
23
+
24
+ export type Query__meName__param = {
25
+ me: {
26
+ name: string,
27
+ },
28
+ };
29
+
30
+ const artifact: ReaderArtifact<
31
+ Query__meName__param,
32
+ Query__meName__outputType
33
+ > = {
34
+ kind: "ReaderArtifact",
35
+ resolver: resolver as any,
36
+ readerAst,
37
+ variant: { kind: "Eager" },
38
+ };
39
+
40
+ export default artifact;
@@ -0,0 +1,79 @@
1
+ import type {IsographEntrypoint, NormalizationAst, RefetchQueryArtifactWrapper} from '@isograph/react';
2
+ import type {Query__meNameSuccessor__param, Query__meNameSuccessor__outputType} from './reader';
3
+ import readerResolver from './reader';
4
+ const nestedRefetchQueries: RefetchQueryArtifactWrapper[] = [];
5
+
6
+ const queryText = 'query meNameSuccessor {\
7
+ me {\
8
+ id,\
9
+ name,\
10
+ successor {\
11
+ id,\
12
+ successor {\
13
+ id,\
14
+ name,\
15
+ },\
16
+ },\
17
+ },\
18
+ }';
19
+
20
+ const normalizationAst: NormalizationAst = [
21
+ {
22
+ kind: "Linked",
23
+ fieldName: "me",
24
+ arguments: null,
25
+ selections: [
26
+ {
27
+ kind: "Scalar",
28
+ fieldName: "id",
29
+ arguments: null,
30
+ },
31
+ {
32
+ kind: "Scalar",
33
+ fieldName: "name",
34
+ arguments: null,
35
+ },
36
+ {
37
+ kind: "Linked",
38
+ fieldName: "successor",
39
+ arguments: null,
40
+ selections: [
41
+ {
42
+ kind: "Scalar",
43
+ fieldName: "id",
44
+ arguments: null,
45
+ },
46
+ {
47
+ kind: "Linked",
48
+ fieldName: "successor",
49
+ arguments: null,
50
+ selections: [
51
+ {
52
+ kind: "Scalar",
53
+ fieldName: "id",
54
+ arguments: null,
55
+ },
56
+ {
57
+ kind: "Scalar",
58
+ fieldName: "name",
59
+ arguments: null,
60
+ },
61
+ ],
62
+ },
63
+ ],
64
+ },
65
+ ],
66
+ },
67
+ ];
68
+ const artifact: IsographEntrypoint<
69
+ Query__meNameSuccessor__param,
70
+ Query__meNameSuccessor__outputType
71
+ > = {
72
+ kind: "Entrypoint",
73
+ queryText,
74
+ normalizationAst,
75
+ nestedRefetchQueries,
76
+ readerArtifact: readerResolver,
77
+ };
78
+
79
+ export default artifact;
@@ -0,0 +1,67 @@
1
+ import type {ReaderArtifact, ReaderAst, ExtractSecondParam} from '@isograph/react';
2
+ import { meNameField as resolver } from '../../../meNameSuccessor.ts';
3
+
4
+ // the type, when read out (either via useLazyReference or via graph)
5
+ export type Query__meNameSuccessor__outputType = ReturnType<typeof resolver>;
6
+
7
+ const readerAst: ReaderAst<Query__meNameSuccessor__param> = [
8
+ {
9
+ kind: "Linked",
10
+ fieldName: "me",
11
+ alias: null,
12
+ arguments: null,
13
+ selections: [
14
+ {
15
+ kind: "Scalar",
16
+ fieldName: "name",
17
+ alias: null,
18
+ arguments: null,
19
+ },
20
+ {
21
+ kind: "Linked",
22
+ fieldName: "successor",
23
+ alias: null,
24
+ arguments: null,
25
+ selections: [
26
+ {
27
+ kind: "Linked",
28
+ fieldName: "successor",
29
+ alias: null,
30
+ arguments: null,
31
+ selections: [
32
+ {
33
+ kind: "Scalar",
34
+ fieldName: "name",
35
+ alias: null,
36
+ arguments: null,
37
+ },
38
+ ],
39
+ },
40
+ ],
41
+ },
42
+ ],
43
+ },
44
+ ];
45
+
46
+ export type Query__meNameSuccessor__param = {
47
+ me: {
48
+ name: string,
49
+ successor: ({
50
+ successor: ({
51
+ name: string,
52
+ } | null),
53
+ } | null),
54
+ },
55
+ };
56
+
57
+ const artifact: ReaderArtifact<
58
+ Query__meNameSuccessor__param,
59
+ Query__meNameSuccessor__outputType
60
+ > = {
61
+ kind: "ReaderArtifact",
62
+ resolver: resolver as any,
63
+ readerAst,
64
+ variant: { kind: "Eager" },
65
+ };
66
+
67
+ export default artifact;
@@ -0,0 +1,42 @@
1
+ import type {IsographEntrypoint, NormalizationAst, RefetchQueryArtifactWrapper} from '@isograph/react';
2
+ import type {Query__nodeField__param, Query__nodeField__outputType} from './reader';
3
+ import readerResolver from './reader';
4
+ const nestedRefetchQueries: RefetchQueryArtifactWrapper[] = [];
5
+
6
+ const queryText = 'query nodeField ($id: ID!) {\
7
+ node____id___v_id: node(id: $id) {\
8
+ id,\
9
+ },\
10
+ }';
11
+
12
+ const normalizationAst: NormalizationAst = [
13
+ {
14
+ kind: "Linked",
15
+ fieldName: "node",
16
+ arguments: [
17
+ [
18
+ "id",
19
+ { kind: "Variable", name: "id" },
20
+ ],
21
+ ],
22
+ selections: [
23
+ {
24
+ kind: "Scalar",
25
+ fieldName: "id",
26
+ arguments: null,
27
+ },
28
+ ],
29
+ },
30
+ ];
31
+ const artifact: IsographEntrypoint<
32
+ Query__nodeField__param,
33
+ Query__nodeField__outputType
34
+ > = {
35
+ kind: "Entrypoint",
36
+ queryText,
37
+ normalizationAst,
38
+ nestedRefetchQueries,
39
+ readerArtifact: readerResolver,
40
+ };
41
+
42
+ export default artifact;
@@ -0,0 +1,45 @@
1
+ import type {ReaderArtifact, ReaderAst, ExtractSecondParam} from '@isograph/react';
2
+ import { nodeField as resolver } from '../../../nodeQuery.ts';
3
+
4
+ // the type, when read out (either via useLazyReference or via graph)
5
+ export type Query__nodeField__outputType = ReturnType<typeof resolver>;
6
+
7
+ const readerAst: ReaderAst<Query__nodeField__param> = [
8
+ {
9
+ kind: "Linked",
10
+ fieldName: "node",
11
+ alias: null,
12
+ arguments: [
13
+ [
14
+ "id",
15
+ { kind: "Variable", name: "id" },
16
+ ],
17
+ ],
18
+ selections: [
19
+ {
20
+ kind: "Scalar",
21
+ fieldName: "id",
22
+ alias: null,
23
+ arguments: null,
24
+ },
25
+ ],
26
+ },
27
+ ];
28
+
29
+ export type Query__nodeField__param = {
30
+ node: ({
31
+ id: string,
32
+ } | null),
33
+ };
34
+
35
+ const artifact: ReaderArtifact<
36
+ Query__nodeField__param,
37
+ Query__nodeField__outputType
38
+ > = {
39
+ kind: "ReaderArtifact",
40
+ resolver: resolver as any,
41
+ readerAst,
42
+ variant: { kind: "Eager" },
43
+ };
44
+
45
+ export default artifact;
@@ -0,0 +1,60 @@
1
+ import type {IsographEntrypoint} from '@isograph/react';
2
+ import { Query__meNameSuccessor__param } from './Query/meNameSuccessor/reader'
3
+ import { Query__meName__param } from './Query/meName/reader'
4
+ import { Query__nodeField__param } from './Query/nodeField/reader'
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
+ type IdentityWithParam<TParam> = <TResolverReturn>(
10
+ x: (param: TParam) => TResolverReturn
11
+ ) => (param: TParam) => TResolverReturn;
12
+ type IdentityWithParamComponent<TParam> = <TResolverReturn, TSecondParam = Record<string, never>>(
13
+ x: (data: TParam, secondParam: TSecondParam) => TResolverReturn
14
+ ) => (data: TParam, secondParam: TSecondParam) => TResolverReturn;
15
+
16
+ type WhitespaceCharacter = ' ' | '\t' | '\n';
17
+ type Whitespace<In> = In extends `${WhitespaceCharacter}${infer In}`
18
+ ? Whitespace<In>
19
+ : In;
20
+
21
+ type MatchesWhitespaceAndString<
22
+ TString extends string,
23
+ T
24
+ > = Whitespace<T> extends `${TString}${string}` ? T : never;
25
+
26
+ export function iso<T>(
27
+ param: T & MatchesWhitespaceAndString<'field Query.meNameSuccessor', T>
28
+ ): IdentityWithParam<Query__meNameSuccessor__param>;
29
+
30
+ export function iso<T>(
31
+ param: T & MatchesWhitespaceAndString<'field Query.meName', T>
32
+ ): IdentityWithParam<Query__meName__param>;
33
+
34
+ export function iso<T>(
35
+ param: T & MatchesWhitespaceAndString<'field Query.nodeField', T>
36
+ ): IdentityWithParam<Query__nodeField__param>;
37
+
38
+ export function iso<T>(
39
+ param: T & MatchesWhitespaceAndString<'entrypoint Query.meNameSuccessor', T>
40
+ ): typeof entrypoint_Query__meNameSuccessor;
41
+
42
+ export function iso<T>(
43
+ param: T & MatchesWhitespaceAndString<'entrypoint Query.meName', T>
44
+ ): typeof entrypoint_Query__meName;
45
+
46
+ export function iso<T>(
47
+ param: T & MatchesWhitespaceAndString<'entrypoint Query.nodeField', T>
48
+ ): typeof entrypoint_Query__nodeField;
49
+
50
+ export function iso(_isographLiteralText: string):
51
+ | IdentityWithParam<any>
52
+ | IdentityWithParamComponent<any>
53
+ | IsographEntrypoint<any, any>
54
+ {
55
+ return function identity<TResolverReturn>(
56
+ clientFieldOrEntrypoint: (param: any) => TResolverReturn,
57
+ ): (param: any) => TResolverReturn {
58
+ return clientFieldOrEntrypoint;
59
+ };
60
+ }
@@ -0,0 +1,130 @@
1
+ import { describe, test, expect } from 'vitest';
2
+ import { ROOT_ID, createIsographEnvironment } from '../IsographEnvironment';
3
+ import { garbageCollectEnvironment, retainQuery } from '../garbageCollection';
4
+ import { iso } from './__isograph/iso';
5
+ import { nodeFieldRetainedQuery } from './nodeQuery';
6
+
7
+ const getDefaultStore = () => ({
8
+ [ROOT_ID]: {
9
+ me: { __link: '0' },
10
+ you: { __link: '1' },
11
+ node____id___0: {
12
+ __link: '0',
13
+ },
14
+ },
15
+ 0: {
16
+ __typename: 'Economist',
17
+ id: '0',
18
+ name: 'Jeremy Bentham',
19
+ successor: { __link: '1' },
20
+ },
21
+ 1: {
22
+ __typename: 'Economist',
23
+ id: '1',
24
+ name: 'John Stuart Mill',
25
+ predecessor: { __link: '0' },
26
+ successor: { __link: '2' },
27
+ },
28
+ 2: {
29
+ __typename: 'Economist',
30
+ id: '2',
31
+ name: 'Henry Sidgwick',
32
+ predecessor: { __link: '1' },
33
+ },
34
+ });
35
+
36
+ export const meNameField = iso(`
37
+ field Query.meName {
38
+ me {
39
+ name
40
+ }
41
+ }
42
+ `)(() => {});
43
+ import meNameEntrypoint from './__isograph/Query/meName/entrypoint';
44
+ import { meNameSuccessorRetainedQuery } from './meNameSuccessor';
45
+ iso(`entrypoint Query.meName`);
46
+ const meNameRetainedQuery = {
47
+ normalizationAst: meNameEntrypoint.normalizationAst,
48
+ variables: {},
49
+ };
50
+
51
+ describe('garbage collection', () => {
52
+ test('Unreferenced records should be garbage collected', () => {
53
+ const store = getDefaultStore();
54
+ const environment = createIsographEnvironment(
55
+ store,
56
+ null as any,
57
+ null as any,
58
+ );
59
+
60
+ expect(store[1]).not.toBe(undefined);
61
+
62
+ // TODO enable babel so we don't have to do this
63
+ retainQuery(environment, meNameRetainedQuery);
64
+ garbageCollectEnvironment(environment);
65
+
66
+ expect(store[1]).toBe(undefined);
67
+ });
68
+
69
+ test('Referenced records should not be garbage collected', () => {
70
+ const store = getDefaultStore();
71
+ const environment = createIsographEnvironment(
72
+ store,
73
+ null as any,
74
+ null as any,
75
+ );
76
+
77
+ expect(store[0]).not.toBe(undefined);
78
+
79
+ // TODO enable babel so we don't have to do this
80
+ retainQuery(environment, meNameRetainedQuery);
81
+ garbageCollectEnvironment(environment);
82
+
83
+ expect(store[0]).not.toBe(undefined);
84
+ });
85
+
86
+ test('Referenced records should not be garbage collected, and this should work with variables', () => {
87
+ const store = getDefaultStore();
88
+ const environment = createIsographEnvironment(
89
+ store,
90
+ null as any,
91
+ null as any,
92
+ );
93
+
94
+ expect(store[0]).not.toBe(undefined);
95
+
96
+ retainQuery(environment, nodeFieldRetainedQuery);
97
+ garbageCollectEnvironment(environment);
98
+
99
+ expect(store[0]).not.toBe(undefined);
100
+ });
101
+
102
+ test('Referenced records should not be garbage collected, and this should work through multiple levels', () => {
103
+ const store = getDefaultStore();
104
+ const environment = createIsographEnvironment(
105
+ store,
106
+ null as any,
107
+ null as any,
108
+ );
109
+
110
+ retainQuery(environment, meNameSuccessorRetainedQuery);
111
+ garbageCollectEnvironment(environment);
112
+
113
+ expect(store[0]).not.toBe(undefined);
114
+ expect(store[1]).not.toBe(undefined);
115
+ expect(store[2]).not.toBe(undefined);
116
+ });
117
+
118
+ test('ROOT_ID should not be garbage collected, even if there are no retained queries', () => {
119
+ const store = getDefaultStore();
120
+ const environment = createIsographEnvironment(
121
+ store,
122
+ null as any,
123
+ null as any,
124
+ );
125
+ garbageCollectEnvironment(environment);
126
+
127
+ expect(store[ROOT_ID]).not.toBe(undefined);
128
+ expect(store[0]).toBe(undefined);
129
+ });
130
+ });
@@ -0,0 +1,7 @@
1
+ {
2
+ "project_root": ".",
3
+ "schema": "./schema.graphql",
4
+ "options": {
5
+ "on_invalid_id_type": "error"
6
+ }
7
+ }
@@ -0,0 +1,20 @@
1
+ import { iso } from './__isograph/iso';
2
+
3
+ export const meNameField = iso(`
4
+ field Query.meNameSuccessor {
5
+ me {
6
+ name
7
+ successor {
8
+ successor {
9
+ name
10
+ }
11
+ }
12
+ }
13
+ }
14
+ `)(() => {});
15
+ import meNameSuccessorEntrypoint from './__isograph/Query/meNameSuccessor/entrypoint';
16
+ iso(`entrypoint Query.meNameSuccessor`);
17
+ export const meNameSuccessorRetainedQuery = {
18
+ normalizationAst: meNameSuccessorEntrypoint.normalizationAst,
19
+ variables: {},
20
+ };
@@ -0,0 +1,17 @@
1
+ import { iso } from './__isograph/iso';
2
+
3
+ // TODO investigate why this can't be in garbageCollection.test.ts without
4
+ // typescript incorrectly thinking it is referenced in its own initializer
5
+ export const nodeField = iso(`
6
+ field Query.nodeField($id: ID!) {
7
+ node(id: $id) {
8
+ id
9
+ }
10
+ }
11
+ `)(() => {});
12
+ import nodeFieldEntrypoint from './__isograph/Query/nodeField/entrypoint';
13
+ iso(`entrypoint Query.nodeField`);
14
+ export const nodeFieldRetainedQuery = {
15
+ normalizationAst: nodeFieldEntrypoint.normalizationAst,
16
+ variables: { id: 0 },
17
+ };
@@ -0,0 +1,16 @@
1
+ type Query {
2
+ me: Economist!
3
+ you: Economist!
4
+ node(id: ID!): Node
5
+ }
6
+
7
+ type Economist implements Node {
8
+ id: ID!
9
+ name: String!
10
+ predecessor: Economist
11
+ successor: Economist
12
+ }
13
+
14
+ interface Node {
15
+ id: ID!
16
+ }
@@ -0,0 +1,21 @@
1
+ {
2
+ "compilerOptions": {
3
+ "target": "es5",
4
+ "lib": ["dom", "dom.iterable", "esnext"],
5
+ "allowJs": true,
6
+ "skipLibCheck": true,
7
+ "strict": true,
8
+ "noEmit": true,
9
+ "esModuleInterop": true,
10
+ "module": "esnext",
11
+ "moduleResolution": "bundler",
12
+ "resolveJsonModule": true,
13
+ "isolatedModules": true,
14
+ "jsx": "preserve",
15
+ "incremental": true,
16
+ "allowImportingTsExtensions": true,
17
+ "paths": {
18
+ "@isograph/react": ["../index.ts"],
19
+ },
20
+ },
21
+ }
@@ -2,35 +2,26 @@ import {
2
2
  UnassignedState,
3
3
  useUpdatableDisposableState,
4
4
  } from '@isograph/react-disposable-state';
5
- import {
6
- ExtractReadFromStore,
7
- ExtractResolverResult,
8
- IsographEntrypoint,
9
- } from './entrypoint';
5
+ import { IsographEntrypoint } from './entrypoint';
10
6
  import { FragmentReference } from './FragmentReference';
11
7
  import { useIsographEnvironment } from './IsographEnvironmentProvider';
12
8
  import { makeNetworkRequest } from './cache';
13
9
  import { ROOT_ID } from './IsographEnvironment';
14
10
 
15
11
  export function useImperativeReference<
16
- TEntrypoint extends IsographEntrypoint<any, any>,
12
+ TReadFromStore extends Object,
13
+ TClientFieldValue,
17
14
  >(
18
- entrypoint: TEntrypoint,
15
+ entrypoint: IsographEntrypoint<TReadFromStore, TClientFieldValue>,
19
16
  ): {
20
17
  queryReference:
21
- | FragmentReference<
22
- ExtractReadFromStore<TEntrypoint>,
23
- ExtractResolverResult<TEntrypoint>
24
- >
18
+ | FragmentReference<TReadFromStore, TClientFieldValue>
25
19
  | UnassignedState;
26
20
  loadQueryReference: (variables: { [index: string]: string }) => void;
27
21
  } {
28
22
  const { state, setState } =
29
23
  useUpdatableDisposableState<
30
- FragmentReference<
31
- ExtractReadFromStore<TEntrypoint>,
32
- ExtractResolverResult<TEntrypoint>
33
- >
24
+ FragmentReference<TReadFromStore, TClientFieldValue>
34
25
  >();
35
26
  const environment = useIsographEnvironment();
36
27
  return {
@@ -1,50 +1,25 @@
1
1
  import { FragmentReference, Variable } from './FragmentReference';
2
2
  import { useIsographEnvironment } from './IsographEnvironmentProvider';
3
3
  import { ROOT_ID } from './IsographEnvironment';
4
- import {
5
- ExtractReadFromStore,
6
- ExtractResolverResult,
7
- assertIsEntrypoint,
8
- } from './entrypoint';
4
+ import { IsographEntrypoint } from './entrypoint';
9
5
  import { getOrCreateCacheForArtifact } from './cache';
10
6
  import { useLazyDisposableState } from '@isograph/react-disposable-state';
11
- import { type PromiseWrapper } from './PromiseWrapper';
12
7
 
13
- // Note: we cannot write TEntrypoint extends IsographEntrypoint<any, any, any>, or else
14
- // if we do not explicitly pass a type, the read out type will be any.
15
- // We cannot write TEntrypoint extends IsographEntrypoint<never, never, never>, or else
16
- // any actual Entrypoint we pass will not be valid.
17
- export function useLazyReference<TEntrypoint>(
18
- entrypoint:
19
- | TEntrypoint
20
- // Temporarily, we need to allow useLazyReference to take the result of calling
21
- // iso(`...`). At runtime, we confirm that the passed-in `iso` literal is actually
22
- // an entrypoint.
23
- | ((_: any) => any),
8
+ export function useLazyReference<
9
+ TReadFromStore extends Object,
10
+ TClientFieldValue,
11
+ >(
12
+ entrypoint: IsographEntrypoint<TReadFromStore, TClientFieldValue>,
24
13
  variables: { [key: string]: Variable },
25
14
  ): {
26
- queryReference: FragmentReference<
27
- ExtractReadFromStore<TEntrypoint>,
28
- ExtractResolverResult<TEntrypoint>
29
- >;
15
+ queryReference: FragmentReference<TReadFromStore, TClientFieldValue>;
30
16
  } {
31
17
  const environment = useIsographEnvironment();
32
- assertIsEntrypoint<
33
- ExtractReadFromStore<TEntrypoint>,
34
- ExtractResolverResult<TEntrypoint>
35
- >(entrypoint);
36
- const cache = getOrCreateCacheForArtifact<ExtractResolverResult<TEntrypoint>>(
37
- environment,
38
- entrypoint,
39
- variables,
40
- );
18
+ const cache = getOrCreateCacheForArtifact(environment, entrypoint, variables);
41
19
 
42
20
  // TODO add comment explaining why we never use this value
43
- // @ts-ignore
44
- const data =
45
- useLazyDisposableState<PromiseWrapper<ExtractResolverResult<TEntrypoint>>>(
46
- cache,
47
- ).state;
21
+ // @ts-ignore(6133)
22
+ const _data = useLazyDisposableState(cache).state;
48
23
 
49
24
  return {
50
25
  queryReference: {
package/tsconfig.pkg.json CHANGED
@@ -7,5 +7,6 @@
7
7
  "jsx": "react",
8
8
  "lib": ["es2017", "DOM"]
9
9
  },
10
- "include": ["./**/*.ts", "./**/*.tsx"]
10
+ "include": ["./**/*.ts", "./**/*.tsx"],
11
+ "exclude": ["./src/tests/**/*"]
11
12
  }