houdini 0.17.9 → 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 (121) hide show
  1. package/README.md +33 -0
  2. package/build/cmd-cjs/index.js +2 -2
  3. package/build/cmd-esm/index.js +2 -2
  4. package/package.json +16 -1
  5. package/.turbo/turbo-compile.log +0 -5
  6. package/.turbo/turbo-typedefs.log +0 -5
  7. package/CHANGELOG.md +0 -377
  8. package/src/cmd/generate.ts +0 -54
  9. package/src/cmd/index.ts +0 -60
  10. package/src/cmd/init.ts +0 -637
  11. package/src/cmd/pullSchema.ts +0 -40
  12. package/src/codegen/generators/artifacts/artifacts.test.ts +0 -3246
  13. package/src/codegen/generators/artifacts/fieldKey.ts +0 -60
  14. package/src/codegen/generators/artifacts/index.ts +0 -330
  15. package/src/codegen/generators/artifacts/indexFile.ts +0 -24
  16. package/src/codegen/generators/artifacts/inputs.ts +0 -81
  17. package/src/codegen/generators/artifacts/operations.ts +0 -281
  18. package/src/codegen/generators/artifacts/pagination.test.ts +0 -664
  19. package/src/codegen/generators/artifacts/policy.test.ts +0 -298
  20. package/src/codegen/generators/artifacts/selection.ts +0 -208
  21. package/src/codegen/generators/artifacts/utils.test.ts +0 -118
  22. package/src/codegen/generators/artifacts/utils.ts +0 -108
  23. package/src/codegen/generators/definitions/enums.test.ts +0 -61
  24. package/src/codegen/generators/definitions/enums.ts +0 -68
  25. package/src/codegen/generators/definitions/index.ts +0 -11
  26. package/src/codegen/generators/definitions/schema.test.ts +0 -236
  27. package/src/codegen/generators/index.ts +0 -6
  28. package/src/codegen/generators/indexFile/index.ts +0 -63
  29. package/src/codegen/generators/indexFile/indexFile.test.ts +0 -72
  30. package/src/codegen/generators/persistedQueries/index.ts +0 -55
  31. package/src/codegen/generators/persistedQueries/persistedQuery.test.ts +0 -26
  32. package/src/codegen/generators/runtime/index.test.ts +0 -74
  33. package/src/codegen/generators/runtime/index.ts +0 -64
  34. package/src/codegen/generators/runtime/runtime.test.ts +0 -25
  35. package/src/codegen/generators/typescript/addReferencedInputTypes.ts +0 -77
  36. package/src/codegen/generators/typescript/index.ts +0 -412
  37. package/src/codegen/generators/typescript/inlineType.ts +0 -409
  38. package/src/codegen/generators/typescript/typeReference.ts +0 -44
  39. package/src/codegen/generators/typescript/types.ts +0 -81
  40. package/src/codegen/generators/typescript/typescript.test.ts +0 -1434
  41. package/src/codegen/index.ts +0 -406
  42. package/src/codegen/transforms/addID.test.ts +0 -93
  43. package/src/codegen/transforms/addID.ts +0 -86
  44. package/src/codegen/transforms/composeQueries.test.ts +0 -50
  45. package/src/codegen/transforms/composeQueries.ts +0 -154
  46. package/src/codegen/transforms/fragmentVariables.test.ts +0 -636
  47. package/src/codegen/transforms/fragmentVariables.ts +0 -417
  48. package/src/codegen/transforms/index.ts +0 -7
  49. package/src/codegen/transforms/list.ts +0 -484
  50. package/src/codegen/transforms/lists.test.ts +0 -530
  51. package/src/codegen/transforms/paginate.test.ts +0 -1528
  52. package/src/codegen/transforms/paginate.ts +0 -770
  53. package/src/codegen/transforms/schema.test.ts +0 -136
  54. package/src/codegen/transforms/schema.ts +0 -109
  55. package/src/codegen/transforms/typename.test.ts +0 -125
  56. package/src/codegen/transforms/typename.ts +0 -55
  57. package/src/codegen/utils/commonjs.ts +0 -26
  58. package/src/codegen/utils/flattenSelections.ts +0 -179
  59. package/src/codegen/utils/graphql.test.ts +0 -35
  60. package/src/codegen/utils/graphql.ts +0 -79
  61. package/src/codegen/utils/index.ts +0 -5
  62. package/src/codegen/utils/moduleExport.ts +0 -27
  63. package/src/codegen/utils/murmur.ts +0 -79
  64. package/src/codegen/validators/index.ts +0 -4
  65. package/src/codegen/validators/noIDAlias.test.ts +0 -71
  66. package/src/codegen/validators/noIDAlias.ts +0 -39
  67. package/src/codegen/validators/plugins.ts +0 -25
  68. package/src/codegen/validators/typeCheck.test.ts +0 -960
  69. package/src/codegen/validators/typeCheck.ts +0 -1086
  70. package/src/codegen/validators/uniqueNames.test.ts +0 -59
  71. package/src/codegen/validators/uniqueNames.ts +0 -39
  72. package/src/lib/cleanupFiles.ts +0 -20
  73. package/src/lib/config.test.ts +0 -13
  74. package/src/lib/config.ts +0 -954
  75. package/src/lib/constants.ts +0 -11
  76. package/src/lib/error.ts +0 -24
  77. package/src/lib/fs.ts +0 -285
  78. package/src/lib/graphql.test.ts +0 -211
  79. package/src/lib/graphql.ts +0 -200
  80. package/src/lib/imports.ts +0 -82
  81. package/src/lib/index.ts +0 -17
  82. package/src/lib/introspection.ts +0 -39
  83. package/src/lib/parse.test.ts +0 -75
  84. package/src/lib/parse.ts +0 -23
  85. package/src/lib/path.ts +0 -49
  86. package/src/lib/pipeline.ts +0 -17
  87. package/src/lib/types.ts +0 -34
  88. package/src/lib/walk.ts +0 -104
  89. package/src/runtime/cache/cache.ts +0 -1026
  90. package/src/runtime/cache/gc.ts +0 -56
  91. package/src/runtime/cache/index.ts +0 -3
  92. package/src/runtime/cache/lists.ts +0 -516
  93. package/src/runtime/cache/storage.ts +0 -574
  94. package/src/runtime/cache/stuff.ts +0 -77
  95. package/src/runtime/cache/subscription.ts +0 -329
  96. package/src/runtime/cache/tests/availability.test.ts +0 -408
  97. package/src/runtime/cache/tests/gc.test.ts +0 -319
  98. package/src/runtime/cache/tests/keys.test.ts +0 -36
  99. package/src/runtime/cache/tests/list.test.ts +0 -3854
  100. package/src/runtime/cache/tests/readwrite.test.ts +0 -1201
  101. package/src/runtime/cache/tests/scalars.test.ts +0 -218
  102. package/src/runtime/cache/tests/storage.test.ts +0 -426
  103. package/src/runtime/cache/tests/subscriptions.test.ts +0 -1757
  104. package/src/runtime/index.ts +0 -29
  105. package/src/runtime/lib/config.ts +0 -211
  106. package/src/runtime/lib/constants.ts +0 -17
  107. package/src/runtime/lib/deepEquals.ts +0 -32
  108. package/src/runtime/lib/errors.ts +0 -8
  109. package/src/runtime/lib/index.ts +0 -8
  110. package/src/runtime/lib/log.ts +0 -69
  111. package/src/runtime/lib/network.ts +0 -303
  112. package/src/runtime/lib/networkUtils.ts +0 -151
  113. package/src/runtime/lib/scalars.test.ts +0 -877
  114. package/src/runtime/lib/scalars.ts +0 -195
  115. package/src/runtime/lib/types.ts +0 -195
  116. package/src/test/index.ts +0 -294
  117. package/src/vite/ast.ts +0 -107
  118. package/src/vite/houdini.ts +0 -113
  119. package/src/vite/imports.ts +0 -129
  120. package/src/vite/index.ts +0 -55
  121. 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
- })