houdini 0.17.13 → 0.18.0

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 (57) hide show
  1. package/build/cmd-cjs/index.js +438 -201
  2. package/build/cmd-esm/index.js +438 -201
  3. package/build/codegen/utils/flattenSelections.d.ts +3 -1
  4. package/build/codegen-cjs/index.js +405 -180
  5. package/build/codegen-esm/index.js +405 -180
  6. package/build/lib/config.d.ts +8 -3
  7. package/build/lib-cjs/index.js +141 -81
  8. package/build/lib-esm/index.js +141 -81
  9. package/build/runtime/cache/subscription.d.ts +3 -3
  10. package/build/runtime/lib/config.d.ts +2 -1
  11. package/build/runtime/lib/scalars.d.ts +2 -2
  12. package/build/runtime/lib/selection.d.ts +2 -0
  13. package/build/runtime/lib/types.d.ts +26 -16
  14. package/build/runtime-cjs/cache/cache.js +38 -23
  15. package/build/runtime-cjs/cache/lists.js +40 -26
  16. package/build/runtime-cjs/cache/subscription.d.ts +3 -3
  17. package/build/runtime-cjs/cache/subscription.js +23 -21
  18. package/build/runtime-cjs/lib/config.d.ts +2 -1
  19. package/build/runtime-cjs/lib/scalars.d.ts +2 -2
  20. package/build/runtime-cjs/lib/scalars.js +9 -6
  21. package/build/runtime-cjs/lib/selection.d.ts +2 -0
  22. package/build/runtime-cjs/lib/selection.js +39 -0
  23. package/build/runtime-cjs/lib/types.d.ts +26 -16
  24. package/build/runtime-esm/cache/cache.js +38 -23
  25. package/build/runtime-esm/cache/lists.js +40 -26
  26. package/build/runtime-esm/cache/subscription.d.ts +3 -3
  27. package/build/runtime-esm/cache/subscription.js +23 -21
  28. package/build/runtime-esm/lib/config.d.ts +2 -1
  29. package/build/runtime-esm/lib/scalars.d.ts +2 -2
  30. package/build/runtime-esm/lib/scalars.js +9 -6
  31. package/build/runtime-esm/lib/selection.d.ts +2 -0
  32. package/build/runtime-esm/lib/selection.js +15 -0
  33. package/build/runtime-esm/lib/types.d.ts +26 -16
  34. package/build/test/index.d.ts +1 -2
  35. package/build/test-cjs/index.js +485 -195
  36. package/build/test-esm/index.js +485 -195
  37. package/build/vite-cjs/index.js +438 -193
  38. package/build/vite-esm/index.js +438 -193
  39. package/package.json +2 -2
  40. package/build/runtime-cjs/cache/tests/availability.test.js +0 -357
  41. package/build/runtime-cjs/cache/tests/gc.test.js +0 -271
  42. package/build/runtime-cjs/cache/tests/keys.test.js +0 -34
  43. package/build/runtime-cjs/cache/tests/list.test.js +0 -3390
  44. package/build/runtime-cjs/cache/tests/readwrite.test.js +0 -1076
  45. package/build/runtime-cjs/cache/tests/scalars.test.js +0 -181
  46. package/build/runtime-cjs/cache/tests/storage.test.js +0 -280
  47. package/build/runtime-cjs/cache/tests/subscriptions.test.js +0 -1469
  48. package/build/runtime-cjs/lib/scalars.test.js +0 -736
  49. package/build/runtime-esm/cache/tests/availability.test.js +0 -356
  50. package/build/runtime-esm/cache/tests/gc.test.js +0 -270
  51. package/build/runtime-esm/cache/tests/keys.test.js +0 -33
  52. package/build/runtime-esm/cache/tests/list.test.js +0 -3389
  53. package/build/runtime-esm/cache/tests/readwrite.test.js +0 -1075
  54. package/build/runtime-esm/cache/tests/scalars.test.js +0 -180
  55. package/build/runtime-esm/cache/tests/storage.test.js +0 -279
  56. package/build/runtime-esm/cache/tests/subscriptions.test.js +0 -1468
  57. package/build/runtime-esm/lib/scalars.test.js +0 -735
@@ -1,1468 +0,0 @@
1
- import { test, expect, vi } from "vitest";
2
- import { testConfigFile } from "../../../test";
3
- import { RefetchUpdateMode } from "../../lib";
4
- import { Cache } from "../cache";
5
- const config = testConfigFile();
6
- test("root subscribe - field change", function() {
7
- const cache = new Cache(config);
8
- const selection = {
9
- viewer: {
10
- type: "User",
11
- keyRaw: "viewer",
12
- fields: {
13
- id: {
14
- type: "ID",
15
- keyRaw: "id"
16
- },
17
- firstName: {
18
- type: "String",
19
- keyRaw: "firstName"
20
- },
21
- favoriteColors: {
22
- type: "String",
23
- keyRaw: "favoriteColors"
24
- }
25
- }
26
- }
27
- };
28
- cache.write({
29
- selection,
30
- data: {
31
- viewer: {
32
- id: "1",
33
- firstName: "bob",
34
- favoriteColors: ["red", "green", "blue"]
35
- }
36
- }
37
- });
38
- const set = vi.fn();
39
- cache.subscribe({
40
- rootType: "Query",
41
- selection,
42
- set
43
- });
44
- cache.write({
45
- selection,
46
- data: {
47
- viewer: {
48
- id: "1",
49
- firstName: "mary"
50
- }
51
- }
52
- });
53
- expect(set).toHaveBeenCalledWith({
54
- viewer: {
55
- firstName: "mary",
56
- favoriteColors: ["red", "green", "blue"],
57
- id: "1"
58
- }
59
- });
60
- });
61
- test("root subscribe - linked object changed", function() {
62
- const cache = new Cache(config);
63
- const selection = {
64
- viewer: {
65
- type: "User",
66
- keyRaw: "viewer",
67
- fields: {
68
- id: {
69
- type: "ID",
70
- keyRaw: "id"
71
- },
72
- firstName: {
73
- type: "String",
74
- keyRaw: "firstName"
75
- },
76
- favoriteColors: {
77
- type: "String",
78
- keyRaw: 'favoriteColors(where: "foo")',
79
- nullable: true
80
- }
81
- }
82
- }
83
- };
84
- cache.write({
85
- selection,
86
- data: {
87
- viewer: {
88
- id: "1",
89
- firstName: "bob",
90
- favoriteColors: ["red", "green", "blue"]
91
- }
92
- }
93
- });
94
- const set = vi.fn();
95
- cache.subscribe({
96
- rootType: "Query",
97
- selection,
98
- set
99
- });
100
- cache.write({
101
- selection,
102
- data: {
103
- viewer: {
104
- id: "2",
105
- firstName: "mary"
106
- }
107
- }
108
- });
109
- expect(set).toHaveBeenCalledWith({
110
- viewer: {
111
- firstName: "mary",
112
- favoriteColors: null,
113
- id: "2"
114
- }
115
- });
116
- cache.write({
117
- selection: {
118
- firstName: {
119
- type: "String",
120
- keyRaw: "firstName"
121
- }
122
- },
123
- data: {
124
- firstName: "Michelle"
125
- },
126
- parent: "User:2"
127
- });
128
- expect(set).toHaveBeenCalledTimes(2);
129
- expect(set).toHaveBeenLastCalledWith({
130
- viewer: {
131
- firstName: "Michelle",
132
- id: "2",
133
- favoriteColors: null
134
- }
135
- });
136
- expect(cache._internal_unstable.subscriptions.get("User:1", "firstName")).toHaveLength(0);
137
- });
138
- test("subscribing to null object doesn't explode", function() {
139
- const cache = new Cache(config);
140
- const selection = {
141
- viewer: {
142
- type: "User",
143
- keyRaw: "viewer",
144
- fields: {
145
- id: {
146
- type: "ID",
147
- keyRaw: "id"
148
- },
149
- firstName: {
150
- type: "String",
151
- keyRaw: "firstName"
152
- },
153
- favoriteColors: {
154
- nullable: true,
155
- type: "String",
156
- keyRaw: 'favoriteColors(where: "foo")'
157
- }
158
- }
159
- }
160
- };
161
- cache.write({
162
- selection,
163
- data: {
164
- viewer: null
165
- }
166
- });
167
- const set = vi.fn();
168
- cache.subscribe({
169
- rootType: "Query",
170
- selection,
171
- set
172
- });
173
- cache.write({
174
- selection,
175
- data: {
176
- viewer: {
177
- id: "2",
178
- firstName: "mary"
179
- }
180
- }
181
- });
182
- expect(set).toHaveBeenCalledWith({
183
- viewer: {
184
- firstName: "mary",
185
- favoriteColors: null,
186
- id: "2"
187
- }
188
- });
189
- });
190
- test("overwriting a reference with null clears its subscribers", function() {
191
- const cache = new Cache(config);
192
- const selection = {
193
- viewer: {
194
- type: "User",
195
- keyRaw: "viewer",
196
- nullable: true,
197
- fields: {
198
- id: {
199
- type: "ID",
200
- keyRaw: "id"
201
- },
202
- firstName: {
203
- type: "String",
204
- keyRaw: "firstName"
205
- },
206
- favoriteColors: {
207
- type: "String",
208
- keyRaw: 'favoriteColors(where: "foo")'
209
- }
210
- }
211
- }
212
- };
213
- cache.write({
214
- selection,
215
- data: {
216
- viewer: {
217
- id: "2",
218
- firstName: "mary"
219
- }
220
- }
221
- });
222
- const set = vi.fn();
223
- cache.subscribe({
224
- rootType: "Query",
225
- selection,
226
- set
227
- });
228
- cache.write({
229
- selection,
230
- data: {
231
- viewer: null
232
- }
233
- });
234
- expect(set).toHaveBeenCalledWith({
235
- viewer: null
236
- });
237
- expect(cache._internal_unstable.subscriptions.get("User:2", "firstName")).toHaveLength(0);
238
- });
239
- test("overwriting a linked list with null clears its subscribers", function() {
240
- const cache = new Cache(config);
241
- const selection = {
242
- viewer: {
243
- type: "User",
244
- keyRaw: "viewer",
245
- fields: {
246
- id: {
247
- type: "ID",
248
- keyRaw: "id"
249
- },
250
- friends: {
251
- type: "User",
252
- keyRaw: "friends",
253
- nullable: true,
254
- fields: {
255
- firstName: {
256
- type: "String",
257
- keyRaw: "firstName"
258
- },
259
- id: {
260
- type: "ID",
261
- keyRaw: "id"
262
- }
263
- }
264
- }
265
- }
266
- }
267
- };
268
- const set = vi.fn();
269
- cache.subscribe({
270
- rootType: "Query",
271
- selection,
272
- set
273
- });
274
- cache.write({
275
- selection,
276
- data: {
277
- viewer: {
278
- id: "1",
279
- friends: [
280
- { id: "2", firstName: "Jason" },
281
- { id: "3", firstName: "Nick" }
282
- ]
283
- }
284
- }
285
- });
286
- expect(cache._internal_unstable.subscriptions.get("User:1", "friends")).toHaveLength(1);
287
- expect(cache._internal_unstable.subscriptions.get("User:2", "firstName")).toHaveLength(1);
288
- expect(cache._internal_unstable.subscriptions.get("User:3", "firstName")).toHaveLength(1);
289
- cache.write({
290
- selection: {
291
- id: {
292
- type: "String",
293
- keyRaw: "id"
294
- },
295
- friends: selection.viewer.fields.friends
296
- },
297
- data: {
298
- id: "1",
299
- friends: null
300
- },
301
- parent: "User:1"
302
- });
303
- expect(set).toHaveBeenNthCalledWith(2, {
304
- viewer: {
305
- id: "1",
306
- friends: null
307
- }
308
- });
309
- expect(cache._internal_unstable.subscriptions.get("User:2", "firstName")).toHaveLength(0);
310
- expect(cache._internal_unstable.subscriptions.get("User:3", "firstName")).toHaveLength(0);
311
- });
312
- test("root subscribe - linked list lost entry", function() {
313
- const cache = new Cache(config);
314
- const selection = {
315
- viewer: {
316
- type: "User",
317
- keyRaw: "viewer",
318
- fields: {
319
- id: {
320
- type: "ID",
321
- keyRaw: "id"
322
- },
323
- friends: {
324
- type: "User",
325
- keyRaw: "friends",
326
- fields: {
327
- id: {
328
- type: "ID",
329
- keyRaw: "id"
330
- },
331
- firstName: {
332
- type: "String",
333
- keyRaw: "firstName"
334
- }
335
- }
336
- }
337
- }
338
- }
339
- };
340
- cache.write({
341
- selection,
342
- data: {
343
- viewer: {
344
- id: "1",
345
- friends: [
346
- {
347
- id: "2",
348
- firstName: "jane"
349
- },
350
- {
351
- id: "3",
352
- firstName: "mary"
353
- }
354
- ]
355
- }
356
- }
357
- });
358
- const set = vi.fn();
359
- cache.subscribe({
360
- rootType: "Query",
361
- selection,
362
- set
363
- });
364
- cache.write({
365
- selection,
366
- data: {
367
- viewer: {
368
- id: "1",
369
- friends: [
370
- {
371
- id: "2"
372
- }
373
- ]
374
- }
375
- }
376
- });
377
- expect(set).toHaveBeenCalledWith({
378
- viewer: {
379
- id: "1",
380
- friends: [
381
- {
382
- firstName: "jane",
383
- id: "2"
384
- }
385
- ]
386
- }
387
- });
388
- expect(cache._internal_unstable.subscriptions.get("User:3", "firstName")).toHaveLength(0);
389
- });
390
- test("subscribing to list with null values doesn't explode", function() {
391
- const cache = new Cache(config);
392
- const selection = {
393
- viewer: {
394
- type: "User",
395
- keyRaw: "viewer",
396
- fields: {
397
- id: {
398
- type: "ID",
399
- keyRaw: "id"
400
- },
401
- friends: {
402
- type: "User",
403
- keyRaw: "friends",
404
- fields: {
405
- id: {
406
- type: "ID",
407
- keyRaw: "id"
408
- },
409
- firstName: {
410
- type: "String",
411
- keyRaw: "firstName"
412
- }
413
- }
414
- }
415
- }
416
- }
417
- };
418
- cache.write({
419
- selection,
420
- data: {
421
- viewer: {
422
- id: "1",
423
- friends: [
424
- {
425
- id: "2",
426
- firstName: "jane"
427
- },
428
- null
429
- ]
430
- }
431
- }
432
- });
433
- const set = vi.fn();
434
- cache.subscribe({
435
- rootType: "Query",
436
- selection,
437
- set
438
- });
439
- cache.write({
440
- selection,
441
- data: {
442
- viewer: {
443
- id: "1",
444
- friends: [
445
- {
446
- id: "2"
447
- }
448
- ]
449
- }
450
- }
451
- });
452
- expect(set).toHaveBeenCalledWith({
453
- viewer: {
454
- id: "1",
455
- friends: [
456
- {
457
- firstName: "jane",
458
- id: "2"
459
- }
460
- ]
461
- }
462
- });
463
- });
464
- test("root subscribe - linked list reorder", function() {
465
- const cache = new Cache(config);
466
- const selection = {
467
- viewer: {
468
- type: "User",
469
- keyRaw: "viewer",
470
- fields: {
471
- id: {
472
- type: "ID",
473
- keyRaw: "id"
474
- },
475
- friends: {
476
- type: "User",
477
- keyRaw: "friends",
478
- fields: {
479
- id: {
480
- type: "ID",
481
- keyRaw: "id"
482
- },
483
- firstName: {
484
- type: "String",
485
- keyRaw: "firstName"
486
- }
487
- }
488
- }
489
- }
490
- }
491
- };
492
- cache.write({
493
- selection,
494
- data: {
495
- viewer: {
496
- id: "1",
497
- friends: [
498
- {
499
- id: "2",
500
- firstName: "jane"
501
- },
502
- {
503
- id: "3",
504
- firstName: "mary"
505
- }
506
- ]
507
- }
508
- }
509
- });
510
- const set = vi.fn();
511
- cache.subscribe({
512
- rootType: "Query",
513
- set,
514
- selection
515
- });
516
- cache.write({
517
- selection,
518
- data: {
519
- viewer: {
520
- id: "1",
521
- friends: [
522
- {
523
- id: "3"
524
- },
525
- {
526
- id: "2"
527
- }
528
- ]
529
- }
530
- }
531
- });
532
- expect(set).toHaveBeenCalledWith({
533
- viewer: {
534
- id: "1",
535
- friends: [
536
- {
537
- id: "3",
538
- firstName: "mary"
539
- },
540
- {
541
- id: "2",
542
- firstName: "jane"
543
- }
544
- ]
545
- }
546
- });
547
- expect(cache._internal_unstable.subscriptions.get("User:2", "firstName")).toHaveLength(1);
548
- expect(cache._internal_unstable.subscriptions.get("User:3", "firstName")).toHaveLength(1);
549
- });
550
- test("unsubscribe", function() {
551
- const cache = new Cache(config);
552
- const selection = {
553
- viewer: {
554
- type: "User",
555
- keyRaw: "viewer",
556
- fields: {
557
- id: {
558
- type: "ID",
559
- keyRaw: "id"
560
- },
561
- firstName: {
562
- type: "String",
563
- keyRaw: "firstName"
564
- },
565
- favoriteColors: {
566
- type: "String",
567
- keyRaw: 'favoriteColors(where: "foo")'
568
- }
569
- }
570
- }
571
- };
572
- cache.write({
573
- selection,
574
- data: {
575
- viewer: {
576
- id: "1",
577
- firstName: "bob",
578
- favoriteColors: ["red", "green", "blue"]
579
- }
580
- }
581
- });
582
- const spec = {
583
- rootType: "Query",
584
- selection,
585
- set: vi.fn()
586
- };
587
- cache.subscribe(spec);
588
- expect(cache._internal_unstable.subscriptions.get("User:1", "firstName")).toHaveLength(1);
589
- cache.unsubscribe(spec);
590
- expect(cache._internal_unstable.subscriptions.get("User:1", "firstName")).toHaveLength(0);
591
- });
592
- test("subscribe to new list nodes", function() {
593
- const cache = new Cache(config);
594
- const selection = {
595
- viewer: {
596
- type: "User",
597
- keyRaw: "viewer",
598
- fields: {
599
- id: {
600
- type: "ID",
601
- keyRaw: "id"
602
- },
603
- friends: {
604
- type: "User",
605
- keyRaw: "friends",
606
- list: {
607
- name: "All_Users",
608
- connection: false,
609
- type: "User"
610
- },
611
- fields: {
612
- id: {
613
- type: "ID",
614
- keyRaw: "id"
615
- },
616
- firstName: {
617
- type: "String",
618
- keyRaw: "firstName"
619
- }
620
- }
621
- }
622
- }
623
- }
624
- };
625
- const set = vi.fn();
626
- cache.subscribe({
627
- rootType: "Query",
628
- set,
629
- selection
630
- });
631
- cache.write({
632
- selection,
633
- data: {
634
- viewer: {
635
- id: "1",
636
- friends: [
637
- {
638
- id: "2",
639
- firstName: "jane"
640
- }
641
- ]
642
- }
643
- }
644
- });
645
- cache.write({
646
- selection: {
647
- id: {
648
- type: "String",
649
- keyRaw: "id"
650
- },
651
- firstName: {
652
- type: "String",
653
- keyRaw: "firstName"
654
- }
655
- },
656
- data: {
657
- id: "2",
658
- firstName: "jane-prime"
659
- },
660
- parent: "User:2"
661
- });
662
- expect(set).toHaveBeenNthCalledWith(2, {
663
- viewer: {
664
- id: "1",
665
- friends: [
666
- {
667
- firstName: "jane-prime",
668
- id: "2"
669
- }
670
- ]
671
- }
672
- });
673
- cache.write({
674
- selection,
675
- data: {
676
- viewer: {
677
- id: "1",
678
- friends: [
679
- {
680
- id: "2",
681
- firstName: "jane-prime"
682
- },
683
- {
684
- id: "3",
685
- firstName: "mary"
686
- }
687
- ]
688
- }
689
- }
690
- });
691
- cache.write({
692
- selection: {
693
- id: {
694
- type: "String",
695
- keyRaw: "id"
696
- },
697
- firstName: {
698
- type: "String",
699
- keyRaw: "firstName"
700
- }
701
- },
702
- data: {
703
- id: "3",
704
- firstName: "mary-prime"
705
- },
706
- parent: "User:3"
707
- });
708
- expect(set).toHaveBeenNthCalledWith(4, {
709
- viewer: {
710
- id: "1",
711
- friends: [
712
- {
713
- firstName: "jane-prime",
714
- id: "2"
715
- },
716
- {
717
- firstName: "mary-prime",
718
- id: "3"
719
- }
720
- ]
721
- }
722
- });
723
- });
724
- test("variables in query and subscription", function() {
725
- const cache = new Cache(config);
726
- const selection = {
727
- viewer: {
728
- type: "User",
729
- keyRaw: "viewer",
730
- fields: {
731
- id: {
732
- type: "ID",
733
- keyRaw: "id"
734
- },
735
- friends: {
736
- type: "User",
737
- keyRaw: "friends(filter: $filter)",
738
- list: {
739
- name: "All_Users",
740
- connection: false,
741
- type: "User"
742
- },
743
- fields: {
744
- id: {
745
- type: "ID",
746
- keyRaw: "id"
747
- },
748
- firstName: {
749
- type: "String",
750
- keyRaw: "firstName"
751
- }
752
- }
753
- }
754
- }
755
- }
756
- };
757
- cache.write({
758
- selection,
759
- data: {
760
- viewer: {
761
- id: "1",
762
- friends: [
763
- {
764
- id: "2",
765
- firstName: "jane"
766
- },
767
- {
768
- id: "3",
769
- firstName: "mary"
770
- }
771
- ]
772
- }
773
- },
774
- variables: {
775
- filter: "foo"
776
- }
777
- });
778
- const set = vi.fn();
779
- cache.subscribe(
780
- {
781
- rootType: "Query",
782
- selection,
783
- set,
784
- variables: () => ({ filter: "foo" })
785
- },
786
- {
787
- filter: "foo"
788
- }
789
- );
790
- expect(cache.list("All_Users").lists[0].key).toEqual('friends(filter: "foo")');
791
- cache.write({
792
- selection,
793
- data: {
794
- viewer: {
795
- id: "1",
796
- friends: [
797
- {
798
- id: "2"
799
- }
800
- ]
801
- }
802
- },
803
- variables: {
804
- filter: "foo"
805
- }
806
- });
807
- expect(set).toHaveBeenCalledWith({
808
- viewer: {
809
- id: "1",
810
- friends: [
811
- {
812
- firstName: "jane",
813
- id: "2"
814
- }
815
- ]
816
- }
817
- });
818
- expect(cache._internal_unstable.subscriptions.get("User:3", "firstName")).toHaveLength(0);
819
- });
820
- test("deleting a node removes nested subscriptions", function() {
821
- const cache = new Cache(config);
822
- const selection = {
823
- viewer: {
824
- type: "User",
825
- keyRaw: "viewer",
826
- fields: {
827
- id: {
828
- type: "ID",
829
- keyRaw: "id"
830
- },
831
- friends: {
832
- type: "User",
833
- keyRaw: "friends",
834
- list: {
835
- name: "All_Users",
836
- connection: false,
837
- type: "User"
838
- },
839
- fields: {
840
- id: {
841
- type: "ID",
842
- keyRaw: "id"
843
- },
844
- firstName: {
845
- type: "String",
846
- keyRaw: "firstName"
847
- }
848
- }
849
- }
850
- }
851
- }
852
- };
853
- cache.write({
854
- selection,
855
- data: {
856
- viewer: {
857
- id: "1",
858
- friends: [
859
- {
860
- id: "2",
861
- firstName: "jane"
862
- }
863
- ]
864
- }
865
- }
866
- });
867
- const set = vi.fn();
868
- cache.subscribe({
869
- rootType: "Query",
870
- selection,
871
- set
872
- });
873
- expect(cache._internal_unstable.subscriptions.get("User:2", "firstName")).toHaveLength(1);
874
- cache.delete("User:1");
875
- expect(cache._internal_unstable.subscriptions.get("User:2", "firstName")).toHaveLength(0);
876
- });
877
- test("same record twice in a query survives one unsubscribe (reference counting)", function() {
878
- const cache = new Cache(config);
879
- const selection = {
880
- viewer: {
881
- type: "User",
882
- keyRaw: "viewer",
883
- fields: {
884
- id: {
885
- type: "ID",
886
- keyRaw: "id"
887
- },
888
- firstName: {
889
- type: "String",
890
- keyRaw: "firstName"
891
- },
892
- friends: {
893
- type: "User",
894
- keyRaw: "friends",
895
- list: {
896
- name: "All_Users",
897
- connection: false,
898
- type: "User"
899
- },
900
- fields: {
901
- id: {
902
- type: "ID",
903
- keyRaw: "id"
904
- },
905
- firstName: {
906
- type: "String",
907
- keyRaw: "firstName"
908
- }
909
- }
910
- }
911
- }
912
- }
913
- };
914
- cache.write({
915
- selection,
916
- data: {
917
- viewer: {
918
- id: "1",
919
- firstName: "bob",
920
- friends: [
921
- {
922
- id: "1",
923
- firstName: "bob"
924
- }
925
- ]
926
- }
927
- },
928
- variables: {
929
- filter: "foo"
930
- }
931
- });
932
- const set = vi.fn();
933
- cache.subscribe(
934
- {
935
- rootType: "Query",
936
- selection,
937
- set
938
- },
939
- {
940
- filter: "foo"
941
- }
942
- );
943
- expect(cache._internal_unstable.subscriptions.get("User:1", "firstName")).toHaveLength(1);
944
- cache.list("All_Users").remove({ id: "1" });
945
- expect(cache._internal_unstable.subscriptions.get("User:1", "firstName")).toHaveLength(1);
946
- });
947
- test("embedded references", function() {
948
- const cache = new Cache(config);
949
- const selection = {
950
- viewer: {
951
- type: "User",
952
- keyRaw: "viewer",
953
- fields: {
954
- id: {
955
- type: "ID",
956
- keyRaw: "id"
957
- },
958
- friends: {
959
- type: "User",
960
- keyRaw: "friends",
961
- fields: {
962
- edges: {
963
- type: "UserEdge",
964
- keyRaw: "edges",
965
- fields: {
966
- node: {
967
- type: "User",
968
- keyRaw: "node",
969
- fields: {
970
- id: {
971
- type: "ID",
972
- keyRaw: "id"
973
- },
974
- firstName: {
975
- type: "String",
976
- keyRaw: "firstName"
977
- }
978
- }
979
- }
980
- }
981
- }
982
- }
983
- }
984
- }
985
- }
986
- };
987
- cache.write({
988
- selection,
989
- data: {
990
- viewer: {
991
- id: "1",
992
- friends: {
993
- edges: [
994
- {
995
- node: {
996
- id: "2",
997
- firstName: "jane"
998
- }
999
- },
1000
- {
1001
- node: {
1002
- id: "3",
1003
- firstName: "mary"
1004
- }
1005
- }
1006
- ]
1007
- }
1008
- }
1009
- }
1010
- });
1011
- const set = vi.fn();
1012
- cache.subscribe(
1013
- {
1014
- rootType: "Query",
1015
- selection,
1016
- set
1017
- },
1018
- {
1019
- filter: "foo"
1020
- }
1021
- );
1022
- cache.write({
1023
- selection: {
1024
- user: {
1025
- type: "User",
1026
- keyRaw: "user",
1027
- fields: {
1028
- id: {
1029
- type: "ID",
1030
- keyRaw: "id"
1031
- },
1032
- firstName: {
1033
- type: "String",
1034
- keyRaw: "firstName"
1035
- }
1036
- }
1037
- }
1038
- },
1039
- data: {
1040
- user: {
1041
- id: "2",
1042
- firstName: "not-jane"
1043
- }
1044
- }
1045
- });
1046
- expect(set).toHaveBeenCalledWith({
1047
- viewer: {
1048
- id: "1",
1049
- friends: {
1050
- edges: [
1051
- {
1052
- node: {
1053
- id: "2",
1054
- firstName: "not-jane"
1055
- }
1056
- },
1057
- {
1058
- node: {
1059
- id: "3",
1060
- firstName: "mary"
1061
- }
1062
- }
1063
- ]
1064
- }
1065
- }
1066
- });
1067
- });
1068
- test("self-referencing linked lists can be unsubscribed (avoid infinite recursion)", function() {
1069
- const cache = new Cache(config);
1070
- const selection = {
1071
- viewer: {
1072
- type: "User",
1073
- keyRaw: "viewer",
1074
- fields: {
1075
- id: {
1076
- type: "ID",
1077
- keyRaw: "id"
1078
- },
1079
- firstName: {
1080
- type: "String",
1081
- keyRaw: "firstName"
1082
- },
1083
- friends: {
1084
- type: "User",
1085
- keyRaw: "friends",
1086
- fields: {
1087
- id: {
1088
- type: "ID",
1089
- keyRaw: "id"
1090
- },
1091
- firstName: {
1092
- type: "String",
1093
- keyRaw: "firstName"
1094
- },
1095
- friends: {
1096
- type: "User",
1097
- keyRaw: "friends",
1098
- fields: {
1099
- id: {
1100
- type: "ID",
1101
- keyRaw: "id"
1102
- },
1103
- firstName: {
1104
- type: "String",
1105
- keyRaw: "firstName"
1106
- }
1107
- }
1108
- }
1109
- }
1110
- }
1111
- }
1112
- }
1113
- };
1114
- cache.write({
1115
- selection,
1116
- data: {
1117
- viewer: {
1118
- id: "1",
1119
- firstName: "bob",
1120
- friends: [
1121
- {
1122
- id: "1",
1123
- firstName: "bob",
1124
- friends: [
1125
- {
1126
- id: "1",
1127
- firstName: "bob"
1128
- }
1129
- ]
1130
- }
1131
- ]
1132
- }
1133
- }
1134
- });
1135
- const spec = {
1136
- set: vi.fn(),
1137
- selection,
1138
- rootType: "Query"
1139
- };
1140
- cache.subscribe(spec);
1141
- cache.unsubscribe(spec);
1142
- expect(cache._internal_unstable.subscriptions.get("User:1", "firstName")).toHaveLength(0);
1143
- });
1144
- test("self-referencing links can be unsubscribed (avoid infinite recursion)", function() {
1145
- const cache = new Cache(config);
1146
- const selection = {
1147
- viewer: {
1148
- type: "User",
1149
- keyRaw: "viewer",
1150
- fields: {
1151
- id: {
1152
- type: "ID",
1153
- keyRaw: "id"
1154
- },
1155
- firstName: {
1156
- type: "String",
1157
- keyRaw: "firstName"
1158
- },
1159
- friend: {
1160
- type: "User",
1161
- keyRaw: "friend",
1162
- fields: {
1163
- id: {
1164
- type: "ID",
1165
- keyRaw: "id"
1166
- },
1167
- firstName: {
1168
- type: "String",
1169
- keyRaw: "firstName"
1170
- },
1171
- friend: {
1172
- type: "User",
1173
- keyRaw: "friend",
1174
- fields: {
1175
- id: {
1176
- type: "ID",
1177
- keyRaw: "id"
1178
- },
1179
- firstName: {
1180
- type: "String",
1181
- keyRaw: "firstName"
1182
- },
1183
- friend: {
1184
- type: "User",
1185
- keyRaw: "friend",
1186
- fields: {
1187
- id: {
1188
- type: "ID",
1189
- keyRaw: "id"
1190
- },
1191
- firstName: {
1192
- type: "String",
1193
- keyRaw: "firstName"
1194
- }
1195
- }
1196
- }
1197
- }
1198
- }
1199
- }
1200
- }
1201
- }
1202
- }
1203
- };
1204
- cache.write({
1205
- selection,
1206
- data: {
1207
- viewer: {
1208
- id: "1",
1209
- firstName: "bob",
1210
- friend: {
1211
- id: "1",
1212
- firstName: "bob",
1213
- friend: {
1214
- id: "1",
1215
- firstName: "bob",
1216
- friend: {
1217
- id: "1",
1218
- firstName: "bob"
1219
- }
1220
- }
1221
- }
1222
- }
1223
- }
1224
- });
1225
- const spec = {
1226
- set: vi.fn(),
1227
- selection,
1228
- rootType: "Query"
1229
- };
1230
- cache.subscribe(spec);
1231
- cache.unsubscribe(spec);
1232
- expect(cache._internal_unstable.subscriptions.get("User:1", "firstName")).toHaveLength(0);
1233
- });
1234
- test("overwriting a value in an optimistic layer triggers subscribers", function() {
1235
- const cache = new Cache(config);
1236
- const selection = {
1237
- viewer: {
1238
- type: "User",
1239
- keyRaw: "viewer",
1240
- fields: {
1241
- id: {
1242
- type: "ID",
1243
- keyRaw: "id"
1244
- },
1245
- firstName: {
1246
- type: "String",
1247
- keyRaw: "firstName"
1248
- },
1249
- favoriteColors: {
1250
- type: "String",
1251
- keyRaw: "favoriteColors"
1252
- }
1253
- }
1254
- }
1255
- };
1256
- cache.write({
1257
- selection,
1258
- data: {
1259
- viewer: {
1260
- id: "1",
1261
- firstName: "bob",
1262
- favoriteColors: ["red", "green", "blue"]
1263
- }
1264
- }
1265
- });
1266
- const set = vi.fn();
1267
- cache.subscribe({
1268
- rootType: "Query",
1269
- selection,
1270
- set
1271
- });
1272
- const layer = cache._internal_unstable.storage.createLayer(true);
1273
- cache.write({
1274
- selection,
1275
- data: {
1276
- viewer: {
1277
- id: "1",
1278
- firstName: "mary"
1279
- }
1280
- },
1281
- layer: layer.id
1282
- });
1283
- expect(set).toHaveBeenCalledWith({
1284
- viewer: {
1285
- firstName: "mary",
1286
- favoriteColors: ["red", "green", "blue"],
1287
- id: "1"
1288
- }
1289
- });
1290
- });
1291
- test("clearing a display layer updates subscribers", function() {
1292
- const cache = new Cache(config);
1293
- const selection = {
1294
- viewer: {
1295
- type: "User",
1296
- keyRaw: "viewer",
1297
- fields: {
1298
- id: {
1299
- type: "ID",
1300
- keyRaw: "id"
1301
- },
1302
- firstName: {
1303
- type: "String",
1304
- keyRaw: "firstName"
1305
- },
1306
- favoriteColors: {
1307
- type: "String",
1308
- keyRaw: "favoriteColors"
1309
- }
1310
- }
1311
- }
1312
- };
1313
- cache.write({
1314
- selection,
1315
- data: {
1316
- viewer: {
1317
- id: "1",
1318
- firstName: "bob",
1319
- favoriteColors: ["red", "green", "blue"]
1320
- }
1321
- }
1322
- });
1323
- const set = vi.fn();
1324
- cache.subscribe({
1325
- rootType: "Query",
1326
- selection,
1327
- set
1328
- });
1329
- const layer = cache._internal_unstable.storage.createLayer(true);
1330
- cache.write({
1331
- selection,
1332
- data: {
1333
- viewer: {
1334
- id: "1",
1335
- firstName: "mary"
1336
- }
1337
- },
1338
- layer: layer.id
1339
- });
1340
- expect(set).toHaveBeenCalledWith({
1341
- viewer: {
1342
- firstName: "mary",
1343
- favoriteColors: ["red", "green", "blue"],
1344
- id: "1"
1345
- }
1346
- });
1347
- layer.clear();
1348
- cache.write({
1349
- selection,
1350
- data: {
1351
- viewer: {
1352
- firstName: "mary",
1353
- favoriteColors: ["red", "green", "blue"],
1354
- id: "1"
1355
- }
1356
- },
1357
- layer: layer.id
1358
- });
1359
- expect(set).toHaveBeenNthCalledWith(2, {
1360
- viewer: {
1361
- firstName: "mary",
1362
- favoriteColors: ["red", "green", "blue"],
1363
- id: "1"
1364
- }
1365
- });
1366
- });
1367
- test("ensure parent type is properly passed for nested lists", function() {
1368
- const cache = new Cache(config);
1369
- const selection = {
1370
- cities: {
1371
- type: "City",
1372
- keyRaw: "cities",
1373
- list: {
1374
- name: "City_List",
1375
- connection: false,
1376
- type: "City"
1377
- },
1378
- update: RefetchUpdateMode.append,
1379
- fields: {
1380
- id: {
1381
- type: "ID",
1382
- keyRaw: "id"
1383
- },
1384
- name: {
1385
- type: "String",
1386
- keyRaw: "name"
1387
- },
1388
- libraries: {
1389
- type: "Library",
1390
- keyRaw: "libraries",
1391
- update: RefetchUpdateMode.append,
1392
- list: {
1393
- name: "Library_List",
1394
- connection: false,
1395
- type: "Library"
1396
- },
1397
- fields: {
1398
- id: {
1399
- type: "ID",
1400
- keyRaw: "id"
1401
- },
1402
- name: {
1403
- type: "String",
1404
- keyRaw: "name"
1405
- },
1406
- books: {
1407
- type: "Book",
1408
- keyRaw: "books",
1409
- list: {
1410
- name: "Book_List",
1411
- connection: false,
1412
- type: "Book"
1413
- },
1414
- fields: {
1415
- id: {
1416
- type: "ID",
1417
- keyRaw: "id"
1418
- },
1419
- title: {
1420
- type: "String",
1421
- keyRaw: "title"
1422
- }
1423
- }
1424
- }
1425
- }
1426
- }
1427
- }
1428
- }
1429
- };
1430
- const set = vi.fn();
1431
- cache.subscribe({
1432
- rootType: "Query",
1433
- selection,
1434
- set
1435
- });
1436
- cache.write({
1437
- selection,
1438
- data: {
1439
- cities: [
1440
- {
1441
- id: "1",
1442
- name: "Alexandria",
1443
- libraries: [
1444
- {
1445
- id: "1",
1446
- name: "The Library of Alexandria",
1447
- books: []
1448
- },
1449
- {
1450
- id: "2",
1451
- name: "Bibliotheca Alexandrina",
1452
- books: []
1453
- }
1454
- ]
1455
- },
1456
- {
1457
- id: "2",
1458
- name: "Aalborg",
1459
- libraries: []
1460
- }
1461
- ]
1462
- }
1463
- });
1464
- expect(() => cache.list("Library_List", "2")).not.toThrow();
1465
- expect(() => cache.list("Book_List", "2")).not.toThrow();
1466
- });
1467
- test.todo("can write to and resolve layers");
1468
- test.todo("resolving a layer with the same value as the most recent doesn't notify subscribers");