houdini 0.17.8 → 0.17.10

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 (148) hide show
  1. package/README.md +33 -0
  2. package/build/cmd-cjs/index.js +124 -38
  3. package/build/cmd-esm/index.js +124 -38
  4. package/build/codegen-cjs/index.js +112 -36
  5. package/build/codegen-esm/index.js +112 -36
  6. package/build/lib/config.d.ts +3 -0
  7. package/build/lib-cjs/index.js +31 -12
  8. package/build/lib-esm/index.js +31 -12
  9. package/build/runtime/cache/cache.d.ts +1 -1
  10. package/build/runtime/cache/lists.d.ts +1 -1
  11. package/build/runtime/lib/config.d.ts +10 -2
  12. package/build/runtime/lib/types.d.ts +1 -0
  13. package/build/runtime-cjs/cache/cache.d.ts +1 -1
  14. package/build/runtime-cjs/cache/cache.js +6 -6
  15. package/build/runtime-cjs/cache/lists.d.ts +1 -1
  16. package/build/runtime-cjs/cache/lists.js +15 -6
  17. package/build/runtime-cjs/cache/tests/list.test.js +160 -70
  18. package/build/runtime-cjs/lib/config.d.ts +10 -2
  19. package/build/runtime-cjs/lib/types.d.ts +1 -0
  20. package/build/runtime-esm/cache/cache.d.ts +1 -1
  21. package/build/runtime-esm/cache/cache.js +6 -6
  22. package/build/runtime-esm/cache/lists.d.ts +1 -1
  23. package/build/runtime-esm/cache/lists.js +15 -6
  24. package/build/runtime-esm/cache/tests/list.test.js +160 -70
  25. package/build/runtime-esm/lib/config.d.ts +10 -2
  26. package/build/runtime-esm/lib/types.d.ts +1 -0
  27. package/build/test-cjs/index.js +122 -36
  28. package/build/test-esm/index.js +122 -36
  29. package/build/vite-cjs/index.js +122 -36
  30. package/build/vite-esm/index.js +122 -36
  31. package/package.json +16 -1
  32. package/.turbo/turbo-compile.log +0 -5
  33. package/.turbo/turbo-typedefs.log +0 -5
  34. package/CHANGELOG.md +0 -367
  35. package/src/cmd/generate.ts +0 -54
  36. package/src/cmd/index.ts +0 -60
  37. package/src/cmd/init.ts +0 -637
  38. package/src/cmd/pullSchema.ts +0 -40
  39. package/src/codegen/generators/artifacts/artifacts.test.ts +0 -2978
  40. package/src/codegen/generators/artifacts/fieldKey.ts +0 -60
  41. package/src/codegen/generators/artifacts/index.ts +0 -330
  42. package/src/codegen/generators/artifacts/indexFile.ts +0 -24
  43. package/src/codegen/generators/artifacts/inputs.ts +0 -81
  44. package/src/codegen/generators/artifacts/operations.ts +0 -263
  45. package/src/codegen/generators/artifacts/pagination.test.ts +0 -664
  46. package/src/codegen/generators/artifacts/policy.test.ts +0 -298
  47. package/src/codegen/generators/artifacts/selection.ts +0 -208
  48. package/src/codegen/generators/artifacts/utils.test.ts +0 -118
  49. package/src/codegen/generators/artifacts/utils.ts +0 -108
  50. package/src/codegen/generators/definitions/enums.test.ts +0 -61
  51. package/src/codegen/generators/definitions/enums.ts +0 -68
  52. package/src/codegen/generators/definitions/index.ts +0 -11
  53. package/src/codegen/generators/definitions/schema.test.ts +0 -227
  54. package/src/codegen/generators/index.ts +0 -6
  55. package/src/codegen/generators/indexFile/index.ts +0 -63
  56. package/src/codegen/generators/indexFile/indexFile.test.ts +0 -72
  57. package/src/codegen/generators/persistedQueries/index.ts +0 -55
  58. package/src/codegen/generators/persistedQueries/persistedQuery.test.ts +0 -26
  59. package/src/codegen/generators/runtime/index.test.ts +0 -74
  60. package/src/codegen/generators/runtime/index.ts +0 -64
  61. package/src/codegen/generators/runtime/runtime.test.ts +0 -25
  62. package/src/codegen/generators/typescript/addReferencedInputTypes.ts +0 -77
  63. package/src/codegen/generators/typescript/index.ts +0 -412
  64. package/src/codegen/generators/typescript/inlineType.ts +0 -409
  65. package/src/codegen/generators/typescript/typeReference.ts +0 -44
  66. package/src/codegen/generators/typescript/types.ts +0 -81
  67. package/src/codegen/generators/typescript/typescript.test.ts +0 -1434
  68. package/src/codegen/index.ts +0 -406
  69. package/src/codegen/transforms/addID.test.ts +0 -93
  70. package/src/codegen/transforms/addID.ts +0 -86
  71. package/src/codegen/transforms/composeQueries.test.ts +0 -50
  72. package/src/codegen/transforms/composeQueries.ts +0 -154
  73. package/src/codegen/transforms/fragmentVariables.test.ts +0 -636
  74. package/src/codegen/transforms/fragmentVariables.ts +0 -417
  75. package/src/codegen/transforms/index.ts +0 -7
  76. package/src/codegen/transforms/list.ts +0 -485
  77. package/src/codegen/transforms/lists.test.ts +0 -530
  78. package/src/codegen/transforms/paginate.test.ts +0 -1481
  79. package/src/codegen/transforms/paginate.ts +0 -750
  80. package/src/codegen/transforms/schema.test.ts +0 -136
  81. package/src/codegen/transforms/schema.ts +0 -104
  82. package/src/codegen/transforms/typename.test.ts +0 -125
  83. package/src/codegen/transforms/typename.ts +0 -55
  84. package/src/codegen/utils/commonjs.ts +0 -26
  85. package/src/codegen/utils/flattenSelections.ts +0 -179
  86. package/src/codegen/utils/graphql.test.ts +0 -35
  87. package/src/codegen/utils/graphql.ts +0 -79
  88. package/src/codegen/utils/index.ts +0 -5
  89. package/src/codegen/utils/moduleExport.ts +0 -27
  90. package/src/codegen/utils/murmur.ts +0 -79
  91. package/src/codegen/validators/index.ts +0 -4
  92. package/src/codegen/validators/noIDAlias.test.ts +0 -71
  93. package/src/codegen/validators/noIDAlias.ts +0 -39
  94. package/src/codegen/validators/plugins.ts +0 -25
  95. package/src/codegen/validators/typeCheck.test.ts +0 -904
  96. package/src/codegen/validators/typeCheck.ts +0 -1031
  97. package/src/codegen/validators/uniqueNames.test.ts +0 -59
  98. package/src/codegen/validators/uniqueNames.ts +0 -39
  99. package/src/lib/cleanupFiles.ts +0 -20
  100. package/src/lib/config.test.ts +0 -13
  101. package/src/lib/config.ts +0 -943
  102. package/src/lib/constants.ts +0 -11
  103. package/src/lib/error.ts +0 -24
  104. package/src/lib/fs.ts +0 -285
  105. package/src/lib/graphql.test.ts +0 -211
  106. package/src/lib/graphql.ts +0 -200
  107. package/src/lib/imports.ts +0 -82
  108. package/src/lib/index.ts +0 -17
  109. package/src/lib/introspection.ts +0 -39
  110. package/src/lib/parse.test.ts +0 -75
  111. package/src/lib/parse.ts +0 -23
  112. package/src/lib/path.ts +0 -49
  113. package/src/lib/pipeline.ts +0 -17
  114. package/src/lib/types.ts +0 -34
  115. package/src/lib/walk.ts +0 -104
  116. package/src/runtime/cache/cache.ts +0 -1023
  117. package/src/runtime/cache/gc.ts +0 -56
  118. package/src/runtime/cache/index.ts +0 -3
  119. package/src/runtime/cache/lists.ts +0 -502
  120. package/src/runtime/cache/storage.ts +0 -574
  121. package/src/runtime/cache/stuff.ts +0 -77
  122. package/src/runtime/cache/subscription.ts +0 -329
  123. package/src/runtime/cache/tests/availability.test.ts +0 -408
  124. package/src/runtime/cache/tests/gc.test.ts +0 -319
  125. package/src/runtime/cache/tests/keys.test.ts +0 -36
  126. package/src/runtime/cache/tests/list.test.ts +0 -3747
  127. package/src/runtime/cache/tests/readwrite.test.ts +0 -1201
  128. package/src/runtime/cache/tests/scalars.test.ts +0 -218
  129. package/src/runtime/cache/tests/storage.test.ts +0 -426
  130. package/src/runtime/cache/tests/subscriptions.test.ts +0 -1757
  131. package/src/runtime/index.ts +0 -29
  132. package/src/runtime/lib/config.ts +0 -201
  133. package/src/runtime/lib/constants.ts +0 -17
  134. package/src/runtime/lib/deepEquals.ts +0 -32
  135. package/src/runtime/lib/errors.ts +0 -8
  136. package/src/runtime/lib/index.ts +0 -8
  137. package/src/runtime/lib/log.ts +0 -69
  138. package/src/runtime/lib/network.ts +0 -303
  139. package/src/runtime/lib/networkUtils.ts +0 -151
  140. package/src/runtime/lib/scalars.test.ts +0 -877
  141. package/src/runtime/lib/scalars.ts +0 -195
  142. package/src/runtime/lib/types.ts +0 -194
  143. package/src/test/index.ts +0 -294
  144. package/src/vite/ast.ts +0 -107
  145. package/src/vite/houdini.ts +0 -113
  146. package/src/vite/imports.ts +0 -129
  147. package/src/vite/index.ts +0 -55
  148. package/src/vite/schema.ts +0 -80
@@ -1,218 +0,0 @@
1
- import { test, expect } from 'vitest'
2
-
3
- import { testConfigFile } from '../../../test'
4
- import { SubscriptionSelection } from '../../lib/types'
5
- import { Cache, rootID } from '../cache'
6
-
7
- const config = testConfigFile({
8
- scalars: {
9
- DateTime: {
10
- type: 'Date',
11
- marshal(val: Date) {
12
- return val.getTime()
13
- },
14
- unmarshal(val: number) {
15
- return new Date(val)
16
- },
17
- },
18
- },
19
- })
20
-
21
- test('extracting data with custom scalars unmarshals the value', () => {
22
- // instantiate a cache we'll test against
23
- const cache = new Cache(config)
24
-
25
- // the selection we are gonna write
26
- const selection = {
27
- node: {
28
- type: 'Node',
29
- keyRaw: 'node',
30
- fields: {
31
- date: {
32
- type: 'DateTime',
33
- keyRaw: 'date',
34
- },
35
- id: {
36
- type: 'ID',
37
- keyRaw: 'id',
38
- },
39
- },
40
- },
41
- }
42
-
43
- // save the data
44
- const data = {
45
- node: {
46
- id: '1',
47
- date: new Date().getTime(),
48
- },
49
- }
50
-
51
- // write the data to cache
52
- cache.write({ selection, data })
53
-
54
- // pull the data out of the cache
55
- expect(cache.read({ parent: rootID, selection }).data).toEqual({
56
- node: {
57
- id: '1',
58
- date: new Date(data.node.date),
59
- },
60
- })
61
- })
62
-
63
- test('can store and retrieve lists of lists of scalars', function () {
64
- // instantiate the cache
65
- const cache = new Cache(config)
66
-
67
- const selection = {
68
- viewer: {
69
- type: 'User',
70
- keyRaw: 'viewer',
71
- fields: {
72
- id: {
73
- type: 'ID',
74
- keyRaw: 'id',
75
- },
76
- strings: {
77
- type: 'String',
78
- keyRaw: 'strings',
79
- },
80
- },
81
- },
82
- }
83
-
84
- // add some data to the cache
85
- cache.write({
86
- selection,
87
- data: {
88
- viewer: {
89
- id: '1',
90
- strings: ['bob', 'john'],
91
- },
92
- },
93
- })
94
-
95
- // make sure we can get the linked lists back
96
- expect(cache.read({ parent: rootID, selection }).data).toEqual({
97
- viewer: {
98
- id: '1',
99
- strings: ['bob', 'john'],
100
- },
101
- })
102
- })
103
-
104
- test('can write list of scalars', function () {
105
- // instantiate the cache
106
- const cache = new Cache(config)
107
-
108
- const selection = {
109
- viewer: {
110
- type: 'User',
111
- keyRaw: 'viewer',
112
- fields: {
113
- id: {
114
- type: 'ID',
115
- keyRaw: 'id',
116
- },
117
- firstName: {
118
- type: 'String',
119
- keyRaw: 'firstName',
120
- },
121
- friends: {
122
- type: 'Int',
123
- keyRaw: 'friends',
124
- },
125
- },
126
- },
127
- }
128
-
129
- // add some data to the cache
130
- cache.write({
131
- selection,
132
- data: {
133
- viewer: {
134
- id: '1',
135
- firstName: 'bob',
136
- friends: [1],
137
- },
138
- },
139
- })
140
-
141
- // make sure we can get the linked lists back
142
- expect(cache.read({ parent: rootID, selection }).data).toEqual({
143
- viewer: {
144
- id: '1',
145
- firstName: 'bob',
146
- friends: [1],
147
- },
148
- })
149
- })
150
-
151
- test('writing a scalar marked with replace', function () {
152
- // instantiate the cache
153
- const cache = new Cache(config)
154
-
155
- const selection = {
156
- viewer: {
157
- type: 'User',
158
- keyRaw: 'viewer',
159
- fields: {
160
- id: {
161
- type: 'ID',
162
- keyRaw: 'id',
163
- },
164
- firstName: {
165
- type: 'String',
166
- keyRaw: 'firstName',
167
- },
168
- friends: {
169
- type: 'Int',
170
- keyRaw: 'friends',
171
- update: 'append',
172
- },
173
- },
174
- },
175
- } as SubscriptionSelection
176
-
177
- // add some data to the cache
178
- cache.write({
179
- selection,
180
- data: {
181
- viewer: {
182
- id: '1',
183
- firstName: 'bob',
184
- friends: [1],
185
- },
186
- },
187
- })
188
-
189
- // make sure we can get the linked lists back
190
- expect(cache.read({ parent: rootID, selection }).data).toEqual({
191
- viewer: {
192
- id: '1',
193
- firstName: 'bob',
194
- friends: [1],
195
- },
196
- })
197
-
198
- // add some data to the cache
199
- cache.write({
200
- selection,
201
- data: {
202
- viewer: {
203
- id: '1',
204
- firstName: 'bob',
205
- friends: [2],
206
- },
207
- },
208
- })
209
-
210
- // make sure we can get the updated lists back
211
- expect(cache.read({ parent: rootID, selection }).data).toEqual({
212
- viewer: {
213
- id: '1',
214
- firstName: 'bob',
215
- friends: [2],
216
- },
217
- })
218
- })
@@ -1,426 +0,0 @@
1
- import { test, expect, describe } from 'vitest'
2
-
3
- import { InMemoryStorage, OperationLocation } from '../storage'
4
-
5
- describe('in memory layers', function () {
6
- test('first layer written can be looked up', function () {
7
- // instantiate an storage layer with an in-memory layer
8
- const storage = new InMemoryStorage()
9
-
10
- // create the layer and write some data
11
- const layer = storage.createLayer()
12
- layer.writeField('User:1', 'firstName', 'John')
13
-
14
- // can get the data back
15
- expect(storage.get('User:1', 'firstName')).toEqual({
16
- value: 'John',
17
- displayLayers: [layer.id],
18
- kind: 'scalar',
19
- })
20
- expect(storage.layerCount).toEqual(1)
21
- })
22
-
23
- test('non-optimistic layer overwrites base', function () {
24
- // instantiate an storage layer with an in-memory layer
25
- const storage = new InMemoryStorage()
26
-
27
- // create the two layers and write overlapping data
28
- storage.writeField('User:1', 'firstName', 'John')
29
- const layerID = storage.writeField('User:1', 'firstName', 'Marshal')
30
-
31
- // can get the data back
32
- expect(storage.get('User:1', 'firstName')).toEqual({
33
- value: 'Marshal',
34
- displayLayers: [layerID],
35
- kind: 'scalar',
36
- })
37
- expect(storage.layerCount).toEqual(1)
38
- })
39
-
40
- test('optimistic layer overwrites base', function () {
41
- // instantiate an storage layer with an in-memory layer
42
- const storage = new InMemoryStorage()
43
-
44
- // create the two layers and write overlapping data
45
- storage.writeField('User:1', 'firstName', 'John')
46
- const optimisticLayerID = storage
47
- .createLayer(true)
48
- .writeField('User:1', 'firstName', 'Marshal')
49
-
50
- // can get the data back
51
- expect(storage.get('User:1', 'firstName')).toEqual({
52
- value: 'Marshal',
53
- kind: 'scalar',
54
- displayLayers: [optimisticLayerID],
55
- })
56
- expect(storage.layerCount).toEqual(2)
57
- })
58
-
59
- test('resolving layer merges into base', function () {
60
- // instantiate an storage layer with an in-memory layer
61
- const storage = new InMemoryStorage()
62
-
63
- // write the layer
64
- const baseLayerID = storage.writeField('User:1', 'firstName', 'John')
65
- expect(storage.get('User:1', 'firstName')).toEqual({
66
- value: 'John',
67
- displayLayers: [baseLayerID],
68
- kind: 'scalar',
69
- })
70
- expect(storage.layerCount).toEqual(1)
71
-
72
- // add an optimistic layer
73
- const optimisticLayer = storage.createLayer(true)
74
- optimisticLayer.writeField('User:1', 'firstName', 'Marshal')
75
-
76
- // sanity check
77
- expect(storage.get('User:1', 'firstName')).toEqual({
78
- value: 'Marshal',
79
- kind: 'scalar',
80
- displayLayers: [optimisticLayer.id],
81
- })
82
- expect(storage.layerCount).toEqual(2)
83
-
84
- // resolve the middle layer with different data
85
- optimisticLayer.writeField('User:1', 'firstName', 'Mike')
86
- storage.resolveLayer(optimisticLayer.id)
87
-
88
- // make sure the layer was committed correctly
89
- expect(storage.get('User:1', 'firstName')).toEqual({
90
- value: 'Mike',
91
- displayLayers: [baseLayerID],
92
- kind: 'scalar',
93
- })
94
- expect(storage.layerCount).toEqual(1)
95
- })
96
-
97
- test('resolving layer merges up', function () {
98
- // instantiate an storage layer with an in-memory layer
99
- const storage = new InMemoryStorage()
100
-
101
- // write the layer
102
- const baseLayerID = storage.writeField('User:1', 'firstName', 'John')
103
-
104
- // write an optimistic layer above the base
105
- const layer1 = storage.createLayer(true)
106
- layer1.writeField('User:1', 'firstName', 'Michael')
107
-
108
- // add a layer above it
109
- const layer2 = storage.createLayer()
110
- layer2.writeField('User:1', 'firstName', 'Jeremy')
111
- layer2.writeField('User:1', 'lastName', 'Michelson')
112
-
113
- // sanity check
114
- expect(storage.get('User:1', 'firstName')).toEqual({
115
- value: 'Jeremy',
116
- displayLayers: [layer2.id],
117
- kind: 'scalar',
118
- })
119
- expect(storage.layerCount).toEqual(3)
120
-
121
- // flatten the data down to a single layer
122
- layer1.writeField('User:1', 'firstName', 'Michael')
123
- layer1.writeField('User:1', 'lastName', "George'")
124
- layer1.writeField('User:1', 'age', 5)
125
- storage.resolveLayer(layer1.id)
126
-
127
- // make sure the data is what we expect
128
- expect(storage.layerCount).toEqual(1)
129
- expect(storage.get('User:1', 'age')).toEqual({
130
- value: 5,
131
- displayLayers: [baseLayerID],
132
- kind: 'scalar',
133
- })
134
- expect(storage.get('User:1', 'firstName')).toEqual({
135
- value: 'Jeremy',
136
- displayLayers: [baseLayerID],
137
- kind: 'scalar',
138
- })
139
- expect(storage.get('User:1', 'lastName')).toEqual({
140
- value: 'Michelson',
141
- displayLayers: [baseLayerID],
142
- kind: 'scalar',
143
- })
144
- })
145
-
146
- test('can write links', function () {
147
- const storage = new InMemoryStorage()
148
- const layerID = storage.writeLink('User:1', 'bestFriend', 'User:2')
149
- expect(storage.get('User:1', 'bestFriend')).toEqual({
150
- value: 'User:2',
151
- displayLayers: [layerID],
152
- kind: 'link',
153
- })
154
- })
155
-
156
- test('can write list of links', function () {
157
- const storage = new InMemoryStorage()
158
- const layerID = storage.writeLink('User:1', 'friends', ['User:1'])
159
- expect(storage.get('User:1', 'friends')).toEqual({
160
- value: ['User:1'],
161
- displayLayers: [layerID],
162
- kind: 'link',
163
- })
164
- })
165
-
166
- test('values are reset when layer is cleared', function () {
167
- const storage = new InMemoryStorage()
168
- const layer = storage.createLayer(true)
169
-
170
- layer.writeField('User:1', 'firstName', 'Alec')
171
-
172
- // sanity check
173
- expect(storage.get('User:1', 'firstName')).toEqual({
174
- value: 'Alec',
175
- displayLayers: [layer.id],
176
- kind: 'scalar',
177
- })
178
-
179
- // clear the layer
180
- layer.clear()
181
-
182
- // make sure we dont have any data back
183
- expect(storage.get('User:1', 'firstName').value).toBeUndefined()
184
- })
185
-
186
- test('can overwrite deletes for a specific link list', function () {
187
- const storage = new InMemoryStorage()
188
-
189
- // add a base layer with some value
190
- storage.writeLink('User:1', 'friends', ['User:2'])
191
-
192
- // add an optimistic layer that deletes the first entry
193
- const layer = storage.createLayer(true)
194
- layer.delete('User:2')
195
-
196
- // make sure its removed
197
- expect(storage.get('User:1', 'friends').value).toEqual([])
198
-
199
- // resolve the optimistic layer
200
- storage.resolveLayer(layer.id)
201
- // sanity check
202
- expect(storage.get('User:1', 'friends').value).toEqual([])
203
-
204
- // add the entry back to the list
205
- storage.writeLink('User:1', 'friends', ['User:2'])
206
-
207
- expect(storage.get('User:1', 'friends').value).toEqual(['User:2'])
208
- })
209
-
210
- test('deleting specific fields removes the field', function () {
211
- const storage = new InMemoryStorage()
212
-
213
- // write some data to the storage we will delete
214
- storage.writeField('User:1', 'firstName', 'Michael')
215
- storage.writeField('User:1', 'lastName', 'Aivazis')
216
-
217
- expect(storage.get('User:1', 'firstName')).toEqual({
218
- value: 'Michael',
219
- displayLayers: [storage.topLayer.id],
220
- kind: 'scalar',
221
- })
222
-
223
- // delete the value
224
- storage.deleteField('User:1', 'firstName')
225
- storage.topLayer.removeUndefinedFields()
226
-
227
- // look up the value now that it's been deleted
228
- expect(storage.get('User:1', 'firstName')).toEqual({
229
- value: undefined,
230
- displayLayers: [],
231
- kind: 'unknown',
232
- })
233
-
234
- // make sure that the top layer doesn't actually hold the value
235
- expect(Object.keys(storage.topLayer.fields['User:1'])).toEqual(['lastName'])
236
- })
237
-
238
- test('deleting all fields of a record deletes the record', function () {
239
- const storage = new InMemoryStorage()
240
-
241
- // write some data to the storage we will delete
242
- storage.writeField('User:1', 'firstName', 'Michael')
243
-
244
- expect(storage.get('User:1', 'firstName')).toEqual({
245
- value: 'Michael',
246
- displayLayers: [storage.topLayer.id],
247
- kind: 'scalar',
248
- })
249
-
250
- // delete the value
251
- storage.deleteField('User:1', 'firstName')
252
- storage.topLayer.removeUndefinedFields()
253
-
254
- // look up the value now that it's been deleted
255
- expect(storage.get('User:1', 'firstName')).toEqual({
256
- value: undefined,
257
- displayLayers: [],
258
- kind: 'unknown',
259
- })
260
-
261
- // make sure that the top layer doesn't actually hold the value
262
- expect(storage.topLayer.fields['User:1']).toBeUndefined()
263
- })
264
-
265
- test('create and resolve on base layer', function () {
266
- // note: this situation happens if a mutation fires before any queries
267
- // are sent to the server to create a non-optimistic layer
268
-
269
- const storage = new InMemoryStorage()
270
-
271
- // create an optimistic layer
272
- const layer = storage.createLayer(true)
273
-
274
- layer.writeField('User:1', 'firstName', 'bob')
275
-
276
- // resolve the layer
277
- storage.resolveLayer(layer.id)
278
-
279
- expect(storage.get('User:1', 'firstName').value).toEqual('bob')
280
- })
281
-
282
- test.todo('links are reset when layer is cleared')
283
-
284
- describe('operations', function () {
285
- test('optimistic deletes', function () {
286
- const storage = new InMemoryStorage()
287
-
288
- // add some information on the base layer we will delete
289
- storage.writeField('User:1', 'firstName', 'John')
290
- storage.writeField('User:1', 'lastName', 'Schmidt')
291
-
292
- // add the user we're going to delete to a linked list to make sure they are removed from it
293
- const baseLayerID = storage.writeLink('User:2', 'friends', ['User:1', 'User:3'])
294
-
295
- // create a layer that deletes the record
296
- const middleLayer = storage.createLayer(true)
297
- middleLayer.delete('User:1')
298
-
299
- // add some more information for the record
300
- const topLayerID = storage.writeField('User:1', 'middleName', 'Jingleheymer')
301
-
302
- // we should be able to retrieve the top layer of information
303
- expect(storage.get('User:1', 'middleName')).toEqual({
304
- value: 'Jingleheymer',
305
- displayLayers: [topLayerID],
306
- kind: 'scalar',
307
- })
308
- expect(storage.get('User:2', 'friends')).toEqual({
309
- value: ['User:3'],
310
- kind: 'link',
311
- displayLayers: [middleLayer.id, baseLayerID],
312
- })
313
-
314
- // and the information in the lower layer should be inaccessible
315
- expect(storage.get('User:1', 'firstName').value).toBeUndefined()
316
- expect(storage.get('User:1', 'lastName').value).toBeUndefined()
317
-
318
- // resolving the middle layer should delete the information even if its different
319
- // than the original source
320
- middleLayer.clear()
321
- middleLayer.delete('User:3')
322
- storage.resolveLayer(middleLayer.id)
323
-
324
- expect(storage.layerCount).toEqual(1)
325
-
326
- // the original fields of User:1 should still exist
327
- expect(storage.get('User:1', 'firstName')).toEqual({
328
- value: 'John',
329
- displayLayers: [baseLayerID],
330
- kind: 'scalar',
331
- })
332
- expect(storage.get('User:1', 'lastName')).toEqual({
333
- value: 'Schmidt',
334
- displayLayers: [baseLayerID],
335
- kind: 'scalar',
336
- })
337
- expect(storage.get('User:1', 'middleName')).toEqual({
338
- value: 'Jingleheymer',
339
- displayLayers: [baseLayerID],
340
- kind: 'scalar',
341
- })
342
- expect(storage.get('User:2', 'friends')).toEqual({
343
- value: ['User:1'],
344
- displayLayers: [baseLayerID],
345
- kind: 'link',
346
- })
347
- })
348
-
349
- test('insert into linked list', function () {
350
- const storage = new InMemoryStorage()
351
-
352
- // add a linked list that we will append to in an optimistic layer
353
- const baseLayerID = storage.writeLink('User:1', 'friends', ['User:2'])
354
-
355
- // create an optimistic layer and insert a new friend
356
- const layer = storage.createLayer(true)
357
- layer.insert('User:1', 'friends', OperationLocation.end, 'User:3')
358
-
359
- // insert some more records in a non-optimistic layer
360
- storage.insert('User:1', 'friends', OperationLocation.end, 'User:5')
361
-
362
- // make sure we got the full list back
363
- expect(storage.get('User:1', 'friends')).toEqual({
364
- value: ['User:2', 'User:3', 'User:5'],
365
- displayLayers: [storage.topLayer.id, layer.id, baseLayerID],
366
- kind: 'link',
367
- })
368
-
369
- // simulate a mutation response with different data (clear the layer, add a new record, and resolve it)
370
- layer.clear()
371
- layer.insert('User:1', 'friends', OperationLocation.end, 'User:4')
372
- storage.resolveLayer(layer.id)
373
-
374
- // look up the linked list
375
- expect(storage.get('User:1', 'friends')).toEqual({
376
- value: ['User:2', 'User:5', 'User:4'],
377
- displayLayers: [baseLayerID],
378
- kind: 'link',
379
- })
380
- // there should only be one layer
381
- expect(storage.layerCount).toEqual(1)
382
- })
383
-
384
- test('remove from linked list', function () {
385
- const storage = new InMemoryStorage()
386
-
387
- // add a linked list we will remove from in a layer
388
- const baseLayerID = storage.writeLink('User:1', 'friends', [
389
- 'User:2',
390
- 'User:3',
391
- 'User:4',
392
- ])
393
-
394
- // create an optimistic layer we will use to mutate the list
395
- const layer = storage.createLayer(true)
396
- layer.remove('User:1', 'friends', 'User:2')
397
-
398
- // make sure we removed the user from the list
399
- expect(storage.get('User:1', 'friends')).toEqual({
400
- value: ['User:3', 'User:4'],
401
- displayLayers: [layer.id, baseLayerID],
402
- kind: 'link',
403
- })
404
-
405
- // simulate a mutation response with different data (clear the layer, remove a different one, and resolve it)
406
- layer.clear()
407
- layer.remove('User:1', 'friends', 'User:4')
408
- layer.remove('User:1', 'friends', 'User:3')
409
- storage.resolveLayer(layer.id)
410
-
411
- // make sure we got the correct final result
412
- expect(storage.get('User:1', 'friends')).toEqual({
413
- value: ['User:2'],
414
- displayLayers: [baseLayerID],
415
- kind: 'link',
416
- })
417
- expect(storage.layerCount).toEqual(1)
418
- })
419
-
420
- test.todo(
421
- 'resolving layer with deletes and fields removes old data and retains the new stuff'
422
- )
423
-
424
- test.todo('an optimistic layer after a stack non-optimistic survives resolution')
425
- })
426
- })