@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.
Files changed (52) hide show
  1. package/dist/core/FragmentReference.js +1 -1
  2. package/dist/core/IsographEnvironment.d.ts +7 -5
  3. package/dist/core/IsographEnvironment.d.ts.map +1 -1
  4. package/dist/core/IsographEnvironment.js +7 -15
  5. package/dist/core/cache.d.ts +6 -2
  6. package/dist/core/cache.d.ts.map +1 -1
  7. package/dist/core/cache.js +75 -19
  8. package/dist/core/check.d.ts +1 -1
  9. package/dist/core/check.d.ts.map +1 -1
  10. package/dist/core/check.js +9 -4
  11. package/dist/core/entrypoint.d.ts +2 -0
  12. package/dist/core/entrypoint.d.ts.map +1 -1
  13. package/dist/core/garbageCollection.d.ts +2 -1
  14. package/dist/core/garbageCollection.d.ts.map +1 -1
  15. package/dist/core/garbageCollection.js +45 -11
  16. package/dist/core/logging.d.ts +2 -2
  17. package/dist/core/logging.d.ts.map +1 -1
  18. package/dist/core/makeNetworkRequest.d.ts.map +1 -1
  19. package/dist/core/makeNetworkRequest.js +8 -2
  20. package/dist/core/read.d.ts +4 -3
  21. package/dist/core/read.d.ts.map +1 -1
  22. package/dist/core/read.js +13 -10
  23. package/dist/index.d.ts +1 -1
  24. package/dist/index.d.ts.map +1 -1
  25. package/dist/index.js +1 -2
  26. package/dist/react/useImperativeReference.js +1 -1
  27. package/package.json +4 -4
  28. package/schema.graphql +1 -0
  29. package/src/core/FragmentReference.ts +1 -1
  30. package/src/core/IsographEnvironment.ts +15 -25
  31. package/src/core/cache.ts +106 -25
  32. package/src/core/check.ts +10 -5
  33. package/src/core/entrypoint.ts +2 -0
  34. package/src/core/garbageCollection.ts +71 -20
  35. package/src/core/logging.ts +2 -2
  36. package/src/core/makeNetworkRequest.ts +8 -1
  37. package/src/core/read.ts +25 -16
  38. package/src/index.ts +0 -1
  39. package/src/react/useImperativeReference.ts +1 -1
  40. package/src/tests/__isograph/Query/meName/entrypoint.ts +1 -0
  41. package/src/tests/__isograph/Query/meNameSuccessor/entrypoint.ts +1 -0
  42. package/src/tests/__isograph/Query/nodeField/entrypoint.ts +1 -0
  43. package/src/tests/__isograph/Query/subquery/entrypoint.ts +67 -0
  44. package/src/tests/__isograph/Query/subquery/output_type.ts +3 -0
  45. package/src/tests/__isograph/Query/subquery/param_type.ts +12 -0
  46. package/src/tests/__isograph/Query/subquery/parameters_type.ts +3 -0
  47. package/src/tests/__isograph/Query/subquery/resolver_reader.ts +47 -0
  48. package/src/tests/__isograph/iso.ts +10 -0
  49. package/src/tests/garbageCollection.test.ts +43 -36
  50. package/src/tests/meNameSuccessor.ts +5 -0
  51. package/src/tests/nodeQuery.ts +2 -0
  52. 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
- [ROOT_ID]: {
15
- me: { __link: '0' },
16
- you: { __link: '1' },
17
- node____id___0: {
18
- __link: '0',
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
- 0: {
22
- __typename: 'Economist',
23
- id: '0',
24
- name: 'Jeremy Bentham',
25
- successor: { __link: '1' },
26
- },
27
- 1: {
28
- __typename: 'Economist',
29
- id: '1',
30
- name: 'John Stuart Mill',
31
- predecessor: { __link: '0' },
32
- successor: { __link: '2' },
33
- },
34
- 2: {
35
- __typename: 'Economist',
36
- id: '2',
37
- name: 'Henry Sidgwick',
38
- predecessor: { __link: '1' },
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 not be garbage collected, even if there are no retained queries', () => {
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]).not.toBe(undefined);
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
  };
@@ -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
+ });