@isograph/react 0.0.0-main-3a36e9fb → 0.0.0-main-beecd3bf
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/core/FragmentReference.js +1 -1
- package/dist/core/IsographEnvironment.d.ts +7 -5
- package/dist/core/IsographEnvironment.d.ts.map +1 -1
- package/dist/core/IsographEnvironment.js +7 -15
- package/dist/core/cache.d.ts +6 -2
- package/dist/core/cache.d.ts.map +1 -1
- package/dist/core/cache.js +75 -19
- package/dist/core/check.d.ts +1 -1
- package/dist/core/check.d.ts.map +1 -1
- package/dist/core/check.js +9 -4
- package/dist/core/entrypoint.d.ts +2 -0
- package/dist/core/entrypoint.d.ts.map +1 -1
- package/dist/core/garbageCollection.d.ts +2 -1
- package/dist/core/garbageCollection.d.ts.map +1 -1
- package/dist/core/garbageCollection.js +45 -11
- package/dist/core/logging.d.ts +2 -2
- package/dist/core/logging.d.ts.map +1 -1
- package/dist/core/makeNetworkRequest.d.ts.map +1 -1
- package/dist/core/makeNetworkRequest.js +8 -2
- package/dist/core/read.d.ts +4 -3
- package/dist/core/read.d.ts.map +1 -1
- package/dist/core/read.js +13 -10
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -2
- package/dist/react/useImperativeReference.js +1 -1
- package/package.json +4 -4
- package/schema.graphql +1 -0
- package/src/core/FragmentReference.ts +1 -1
- package/src/core/IsographEnvironment.ts +15 -25
- package/src/core/cache.ts +106 -25
- package/src/core/check.ts +10 -5
- package/src/core/entrypoint.ts +2 -0
- package/src/core/garbageCollection.ts +71 -20
- package/src/core/logging.ts +2 -2
- package/src/core/makeNetworkRequest.ts +8 -1
- package/src/core/read.ts +25 -16
- package/src/index.ts +0 -1
- package/src/react/useImperativeReference.ts +1 -1
- package/src/tests/__isograph/Query/meName/entrypoint.ts +1 -0
- package/src/tests/__isograph/Query/meNameSuccessor/entrypoint.ts +1 -0
- package/src/tests/__isograph/Query/nodeField/entrypoint.ts +1 -0
- package/src/tests/__isograph/Query/subquery/entrypoint.ts +67 -0
- package/src/tests/__isograph/Query/subquery/output_type.ts +3 -0
- package/src/tests/__isograph/Query/subquery/param_type.ts +12 -0
- package/src/tests/__isograph/Query/subquery/parameters_type.ts +3 -0
- package/src/tests/__isograph/Query/subquery/resolver_reader.ts +47 -0
- package/src/tests/__isograph/iso.ts +10 -0
- package/src/tests/garbageCollection.test.ts +43 -36
- package/src/tests/meNameSuccessor.ts +5 -0
- package/src/tests/nodeQuery.ts +2 -0
- package/src/tests/normalizeData.test.ts +120 -0
|
@@ -2,6 +2,7 @@ import { describe, test, expect } from 'vitest';
|
|
|
2
2
|
import {
|
|
3
3
|
ROOT_ID,
|
|
4
4
|
createIsographEnvironment,
|
|
5
|
+
type IsographStore,
|
|
5
6
|
} from '../core/IsographEnvironment';
|
|
6
7
|
import {
|
|
7
8
|
garbageCollectEnvironment,
|
|
@@ -10,32 +11,37 @@ import {
|
|
|
10
11
|
import { iso } from './__isograph/iso';
|
|
11
12
|
import { nodeFieldRetainedQuery } from './nodeQuery';
|
|
12
13
|
|
|
13
|
-
const getDefaultStore = () => ({
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
14
|
+
const getDefaultStore = (): IsographStore => ({
|
|
15
|
+
Query: {
|
|
16
|
+
[ROOT_ID]: {
|
|
17
|
+
me: { __link: '0', __typename: 'Economist' },
|
|
18
|
+
you: { __link: '1', __typename: 'Economist' },
|
|
19
|
+
node____id___0: {
|
|
20
|
+
__link: '0',
|
|
21
|
+
__typename: 'Economist',
|
|
22
|
+
},
|
|
19
23
|
},
|
|
20
24
|
},
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
25
|
+
Economist: {
|
|
26
|
+
0: {
|
|
27
|
+
__typename: 'Economist',
|
|
28
|
+
id: '0',
|
|
29
|
+
name: 'Jeremy Bentham',
|
|
30
|
+
successor: { __link: '1', __typename: 'Economist' },
|
|
31
|
+
},
|
|
32
|
+
1: {
|
|
33
|
+
__typename: 'Economist',
|
|
34
|
+
id: '1',
|
|
35
|
+
name: 'John Stuart Mill',
|
|
36
|
+
predecessor: { __link: '0', __typename: 'Economist' },
|
|
37
|
+
successor: { __link: '2', __typename: 'Economist' },
|
|
38
|
+
},
|
|
39
|
+
2: {
|
|
40
|
+
__typename: 'Economist',
|
|
41
|
+
id: '2',
|
|
42
|
+
name: 'Henry Sidgwick',
|
|
43
|
+
predecessor: { __link: '1', __typename: 'Economist' },
|
|
44
|
+
},
|
|
39
45
|
},
|
|
40
46
|
});
|
|
41
47
|
|
|
@@ -51,6 +57,7 @@ const meNameEntrypoint = iso(`entrypoint Query.meName`);
|
|
|
51
57
|
const meNameRetainedQuery = {
|
|
52
58
|
normalizationAst: meNameEntrypoint.networkRequestInfo.normalizationAst,
|
|
53
59
|
variables: {},
|
|
60
|
+
root: { __link: ROOT_ID, __typename: 'Query' },
|
|
54
61
|
};
|
|
55
62
|
|
|
56
63
|
describe('garbage collection', () => {
|
|
@@ -62,13 +69,13 @@ describe('garbage collection', () => {
|
|
|
62
69
|
null as any,
|
|
63
70
|
);
|
|
64
71
|
|
|
65
|
-
expect(store[1]).not.toBe(undefined);
|
|
72
|
+
expect(store.Economist?.[1]).not.toBe(undefined);
|
|
66
73
|
|
|
67
74
|
// TODO enable babel so we don't have to do this
|
|
68
75
|
retainQuery(environment, meNameRetainedQuery);
|
|
69
76
|
garbageCollectEnvironment(environment);
|
|
70
77
|
|
|
71
|
-
expect(store[1]).toBe(undefined);
|
|
78
|
+
expect(store.Economist?.[1]).toBe(undefined);
|
|
72
79
|
});
|
|
73
80
|
|
|
74
81
|
test('Referenced records should not be garbage collected', () => {
|
|
@@ -79,13 +86,13 @@ describe('garbage collection', () => {
|
|
|
79
86
|
null as any,
|
|
80
87
|
);
|
|
81
88
|
|
|
82
|
-
expect(store[0]).not.toBe(undefined);
|
|
89
|
+
expect(store.Economist?.[0]).not.toBe(undefined);
|
|
83
90
|
|
|
84
91
|
// TODO enable babel so we don't have to do this
|
|
85
92
|
retainQuery(environment, meNameRetainedQuery);
|
|
86
93
|
garbageCollectEnvironment(environment);
|
|
87
94
|
|
|
88
|
-
expect(store[0]).not.toBe(undefined);
|
|
95
|
+
expect(store.Economist?.[0]).not.toBe(undefined);
|
|
89
96
|
});
|
|
90
97
|
|
|
91
98
|
test('Referenced records should not be garbage collected, and this should work with variables', () => {
|
|
@@ -96,12 +103,12 @@ describe('garbage collection', () => {
|
|
|
96
103
|
null as any,
|
|
97
104
|
);
|
|
98
105
|
|
|
99
|
-
expect(store[0]).not.toBe(undefined);
|
|
106
|
+
expect(store.Economist?.[0]).not.toBe(undefined);
|
|
100
107
|
|
|
101
108
|
retainQuery(environment, nodeFieldRetainedQuery);
|
|
102
109
|
garbageCollectEnvironment(environment);
|
|
103
110
|
|
|
104
|
-
expect(store[0]).not.toBe(undefined);
|
|
111
|
+
expect(store.Economist?.[0]).not.toBe(undefined);
|
|
105
112
|
});
|
|
106
113
|
|
|
107
114
|
test('Referenced records should not be garbage collected, and this should work through multiple levels', () => {
|
|
@@ -115,12 +122,12 @@ describe('garbage collection', () => {
|
|
|
115
122
|
retainQuery(environment, meNameSuccessorRetainedQuery);
|
|
116
123
|
garbageCollectEnvironment(environment);
|
|
117
124
|
|
|
118
|
-
expect(store[0]).not.toBe(undefined);
|
|
119
|
-
expect(store[1]).not.toBe(undefined);
|
|
120
|
-
expect(store[2]).not.toBe(undefined);
|
|
125
|
+
expect(store.Economist?.[0]).not.toBe(undefined);
|
|
126
|
+
expect(store.Economist?.[1]).not.toBe(undefined);
|
|
127
|
+
expect(store.Economist?.[2]).not.toBe(undefined);
|
|
121
128
|
});
|
|
122
129
|
|
|
123
|
-
test('ROOT_ID should
|
|
130
|
+
test('ROOT_ID should be garbage collected, if there are no retained queries', () => {
|
|
124
131
|
const store = getDefaultStore();
|
|
125
132
|
const environment = createIsographEnvironment(
|
|
126
133
|
store,
|
|
@@ -129,7 +136,7 @@ describe('garbage collection', () => {
|
|
|
129
136
|
);
|
|
130
137
|
garbageCollectEnvironment(environment);
|
|
131
138
|
|
|
132
|
-
expect(store[ROOT_ID]).
|
|
133
|
-
expect(store[0]).toBe(undefined);
|
|
139
|
+
expect(store.Query?.[ROOT_ID]).toBe(undefined);
|
|
140
|
+
expect(store.Economist?.[0]).toBe(undefined);
|
|
134
141
|
});
|
|
135
142
|
});
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { ROOT_ID } from '../core/IsographEnvironment';
|
|
1
2
|
import { iso } from './__isograph/iso';
|
|
2
3
|
|
|
3
4
|
export const meNameField = iso(`
|
|
@@ -17,4 +18,8 @@ export const meNameSuccessorRetainedQuery = {
|
|
|
17
18
|
normalizationAst:
|
|
18
19
|
meNameSuccessorEntrypoint.networkRequestInfo.normalizationAst,
|
|
19
20
|
variables: {},
|
|
21
|
+
root: {
|
|
22
|
+
__link: ROOT_ID,
|
|
23
|
+
__typename: 'Query',
|
|
24
|
+
},
|
|
20
25
|
};
|
package/src/tests/nodeQuery.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { RetainedQuery } from '../core/garbageCollection';
|
|
2
|
+
import { ROOT_ID } from '../core/IsographEnvironment';
|
|
2
3
|
import { iso } from './__isograph/iso';
|
|
3
4
|
|
|
4
5
|
// TODO investigate why this can't be in garbageCollection.test.ts without
|
|
@@ -14,4 +15,5 @@ const nodeFieldEntrypoint = iso(`entrypoint Query.nodeField`);
|
|
|
14
15
|
export const nodeFieldRetainedQuery: RetainedQuery = {
|
|
15
16
|
normalizationAst: nodeFieldEntrypoint.networkRequestInfo.normalizationAst,
|
|
16
17
|
variables: { id: 0 },
|
|
18
|
+
root: { __link: ROOT_ID, __typename: 'Query' },
|
|
17
19
|
};
|
|
@@ -0,0 +1,120 @@
|
|
|
1
|
+
import { describe, expect, test, vi } from 'vitest';
|
|
2
|
+
import { getOrCreateCacheForArtifact, normalizeData } from '../core/cache';
|
|
3
|
+
import {
|
|
4
|
+
createIsographEnvironment,
|
|
5
|
+
createIsographStore,
|
|
6
|
+
ROOT_ID,
|
|
7
|
+
type IsographStore,
|
|
8
|
+
} from '../core/IsographEnvironment';
|
|
9
|
+
import {
|
|
10
|
+
readButDoNotEvaluate,
|
|
11
|
+
type WithEncounteredRecords,
|
|
12
|
+
} from '../core/read';
|
|
13
|
+
import { iso } from './__isograph/iso';
|
|
14
|
+
import type { Query__subquery__param } from './__isograph/Query/subquery/param_type';
|
|
15
|
+
|
|
16
|
+
export const subquery = iso(`
|
|
17
|
+
field Query.subquery($id: ID!) {
|
|
18
|
+
query {
|
|
19
|
+
node(id: $id) {
|
|
20
|
+
id
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
`)(() => {});
|
|
25
|
+
|
|
26
|
+
const entrypoint = iso(`entrypoint Query.subquery`);
|
|
27
|
+
|
|
28
|
+
describe('normalizeData', () => {
|
|
29
|
+
test('nested Query should be normalized', () => {
|
|
30
|
+
const store = createIsographStore();
|
|
31
|
+
const networkFunction = vi
|
|
32
|
+
.fn()
|
|
33
|
+
.mockRejectedValue(new Error('Fetch failed'));
|
|
34
|
+
const environment = createIsographEnvironment(store, networkFunction);
|
|
35
|
+
|
|
36
|
+
normalizeData(
|
|
37
|
+
environment,
|
|
38
|
+
entrypoint.networkRequestInfo.normalizationAst,
|
|
39
|
+
{
|
|
40
|
+
query: { node____id___v_id: { __typename: 'Economist', id: '1' } },
|
|
41
|
+
},
|
|
42
|
+
{ id: '1' },
|
|
43
|
+
entrypoint.readerWithRefetchQueries.nestedRefetchQueries,
|
|
44
|
+
{ __link: ROOT_ID, __typename: entrypoint.concreteType },
|
|
45
|
+
);
|
|
46
|
+
|
|
47
|
+
expect(store).toStrictEqual({
|
|
48
|
+
Economist: {
|
|
49
|
+
'1': {
|
|
50
|
+
__typename: 'Economist',
|
|
51
|
+
id: '1',
|
|
52
|
+
},
|
|
53
|
+
},
|
|
54
|
+
Query: {
|
|
55
|
+
[ROOT_ID]: {
|
|
56
|
+
node____id___1: {
|
|
57
|
+
__typename: 'Economist',
|
|
58
|
+
__link: '1',
|
|
59
|
+
},
|
|
60
|
+
query: {
|
|
61
|
+
__link: ROOT_ID,
|
|
62
|
+
__typename: 'Query',
|
|
63
|
+
},
|
|
64
|
+
},
|
|
65
|
+
},
|
|
66
|
+
} satisfies IsographStore);
|
|
67
|
+
});
|
|
68
|
+
});
|
|
69
|
+
|
|
70
|
+
describe('readData', () => {
|
|
71
|
+
test('nested Query should be read', () => {
|
|
72
|
+
const store: IsographStore = {
|
|
73
|
+
Economist: {
|
|
74
|
+
'1': {
|
|
75
|
+
__typename: 'Economist',
|
|
76
|
+
id: '1',
|
|
77
|
+
},
|
|
78
|
+
},
|
|
79
|
+
Query: {
|
|
80
|
+
[ROOT_ID]: {
|
|
81
|
+
node____id___1: {
|
|
82
|
+
__typename: 'Economist',
|
|
83
|
+
__link: '1',
|
|
84
|
+
},
|
|
85
|
+
query: {
|
|
86
|
+
__link: ROOT_ID,
|
|
87
|
+
__typename: 'Query',
|
|
88
|
+
},
|
|
89
|
+
},
|
|
90
|
+
},
|
|
91
|
+
};
|
|
92
|
+
const networkFunction = vi
|
|
93
|
+
.fn()
|
|
94
|
+
.mockRejectedValue(new Error('Fetch failed'));
|
|
95
|
+
const environment = createIsographEnvironment(store, networkFunction);
|
|
96
|
+
const [_cacheItem, item, _disposeOfTemporaryRetain] =
|
|
97
|
+
getOrCreateCacheForArtifact(environment, entrypoint, {
|
|
98
|
+
id: '1',
|
|
99
|
+
}).getOrPopulateAndTemporaryRetain();
|
|
100
|
+
|
|
101
|
+
const data = readButDoNotEvaluate(environment, item, {
|
|
102
|
+
suspendIfInFlight: true,
|
|
103
|
+
throwOnNetworkError: false,
|
|
104
|
+
});
|
|
105
|
+
|
|
106
|
+
expect(data).toStrictEqual({
|
|
107
|
+
encounteredRecords: new Map([
|
|
108
|
+
['Economist', new Set(['1'])],
|
|
109
|
+
['Query', new Set([ROOT_ID])],
|
|
110
|
+
]),
|
|
111
|
+
item: {
|
|
112
|
+
query: {
|
|
113
|
+
node: {
|
|
114
|
+
id: '1',
|
|
115
|
+
},
|
|
116
|
+
},
|
|
117
|
+
},
|
|
118
|
+
} satisfies WithEncounteredRecords<Query__subquery__param>);
|
|
119
|
+
});
|
|
120
|
+
});
|