houdini 0.13.2-alpha.3 → 0.13.2-alpha.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/build/runtime/cache/cache.d.ts +2 -0
- package/build/runtime/cache/cache.js +31 -8
- package/build/runtime-cjs/cache/cache.d.ts +2 -0
- package/build/runtime-cjs/cache/cache.js +31 -8
- package/build/runtime-esm/cache/cache.d.ts +2 -0
- package/build/runtime-esm/cache/cache.js +31 -8
- package/package.json +2 -2
- package/runtime/cache/cache.ts +40 -10
- package/runtime/cache/tests/readwrite.test.ts +105 -5
|
@@ -63,6 +63,7 @@ declare class CacheInternal {
|
|
|
63
63
|
}): {
|
|
64
64
|
data: GraphQLObject | null;
|
|
65
65
|
partial: boolean;
|
|
66
|
+
hasData: boolean;
|
|
66
67
|
};
|
|
67
68
|
id(type: string, data: {
|
|
68
69
|
id?: string;
|
|
@@ -79,6 +80,7 @@ declare class CacheInternal {
|
|
|
79
80
|
}): {
|
|
80
81
|
data: LinkedList<GraphQLValue>;
|
|
81
82
|
partial: boolean;
|
|
83
|
+
hasData: boolean;
|
|
82
84
|
};
|
|
83
85
|
extractNestedListIDs({ value, abstract, recordID, key, linkedType, fields, variables, applyUpdates, specs, layer, startingWith, }: {
|
|
84
86
|
value: GraphQLValue[];
|
|
@@ -117,7 +117,14 @@ var Cache = /** @class */ (function () {
|
|
|
117
117
|
for (var _i = 0; _i < arguments.length; _i++) {
|
|
118
118
|
args[_i] = arguments[_i];
|
|
119
119
|
}
|
|
120
|
-
|
|
120
|
+
var _b = (_a = this._internal_unstable).getSelection.apply(_a, __spread(args)), data = _b.data, partial = _b.partial, hasData = _b.hasData;
|
|
121
|
+
if (!hasData) {
|
|
122
|
+
return { data: null, partial: false };
|
|
123
|
+
}
|
|
124
|
+
return {
|
|
125
|
+
data: data,
|
|
126
|
+
partial: partial,
|
|
127
|
+
};
|
|
121
128
|
};
|
|
122
129
|
// register the provided callbacks with the fields specified by the selection
|
|
123
130
|
Cache.prototype.subscribe = function (spec, variables) {
|
|
@@ -597,7 +604,7 @@ var CacheInternal = /** @class */ (function () {
|
|
|
597
604
|
var selection = _a.selection, _e = _a.parent, parent = _e === void 0 ? exports.rootID : _e, variables = _a.variables;
|
|
598
605
|
// we could be asking for values of null
|
|
599
606
|
if (parent === null) {
|
|
600
|
-
return { data: null, partial: false };
|
|
607
|
+
return { data: null, partial: false, hasData: true };
|
|
601
608
|
}
|
|
602
609
|
var target = {};
|
|
603
610
|
// we need to track if we have a partial data set which means we have _something_ but not everything
|
|
@@ -618,14 +625,14 @@ var CacheInternal = /** @class */ (function () {
|
|
|
618
625
|
if (typeof value === 'undefined') {
|
|
619
626
|
partial = true;
|
|
620
627
|
}
|
|
621
|
-
// as long as the value is not undefined, we have something
|
|
622
|
-
else {
|
|
623
|
-
hasData = true;
|
|
624
|
-
}
|
|
625
628
|
// if we dont have a value to return, use null (we check for non-null fields at the end)
|
|
626
629
|
if (typeof value === 'undefined' || value === null) {
|
|
627
630
|
// set the value to null
|
|
628
631
|
target[attributeName] = null;
|
|
632
|
+
// if we didn't just write undefined, there is officially some data in this object
|
|
633
|
+
if (typeof value !== 'undefined') {
|
|
634
|
+
hasData = true;
|
|
635
|
+
}
|
|
629
636
|
}
|
|
630
637
|
// if the field is a scalar
|
|
631
638
|
else if (!fields) {
|
|
@@ -638,6 +645,7 @@ var CacheInternal = /** @class */ (function () {
|
|
|
638
645
|
else {
|
|
639
646
|
target[attributeName] = value;
|
|
640
647
|
}
|
|
648
|
+
hasData = true;
|
|
641
649
|
}
|
|
642
650
|
// if the field is a list of records
|
|
643
651
|
else if (Array.isArray(value)) {
|
|
@@ -653,6 +661,9 @@ var CacheInternal = /** @class */ (function () {
|
|
|
653
661
|
if (listValue.partial) {
|
|
654
662
|
partial = true;
|
|
655
663
|
}
|
|
664
|
+
if (listValue.hasData) {
|
|
665
|
+
hasData = true;
|
|
666
|
+
}
|
|
656
667
|
}
|
|
657
668
|
// otherwise the field is a linked object
|
|
658
669
|
else {
|
|
@@ -668,6 +679,9 @@ var CacheInternal = /** @class */ (function () {
|
|
|
668
679
|
if (objectFields.partial) {
|
|
669
680
|
partial = true;
|
|
670
681
|
}
|
|
682
|
+
if (objectFields.hasData) {
|
|
683
|
+
hasData = true;
|
|
684
|
+
}
|
|
671
685
|
}
|
|
672
686
|
// regardless of how the field was processed, if we got a null value assigned
|
|
673
687
|
// and the field is not nullable, we need to cascade up
|
|
@@ -688,6 +702,7 @@ var CacheInternal = /** @class */ (function () {
|
|
|
688
702
|
// our value is considered true if there is some data but not everything
|
|
689
703
|
// has a full value
|
|
690
704
|
partial: hasData && partial,
|
|
705
|
+
hasData: hasData,
|
|
691
706
|
};
|
|
692
707
|
};
|
|
693
708
|
CacheInternal.prototype.id = function (type, data) {
|
|
@@ -713,6 +728,7 @@ var CacheInternal = /** @class */ (function () {
|
|
|
713
728
|
// to the corresponding record. can't have that now, can we?
|
|
714
729
|
var result = [];
|
|
715
730
|
var partialData = false;
|
|
731
|
+
var hasValues = false;
|
|
716
732
|
try {
|
|
717
733
|
for (var linkedList_1 = __values(linkedList), linkedList_1_1 = linkedList_1.next(); !linkedList_1_1.done; linkedList_1_1 = linkedList_1.next()) {
|
|
718
734
|
var entry = linkedList_1_1.value;
|
|
@@ -735,11 +751,14 @@ var CacheInternal = /** @class */ (function () {
|
|
|
735
751
|
parent: entry,
|
|
736
752
|
selection: fields,
|
|
737
753
|
variables: variables,
|
|
738
|
-
}), data = _c.data, partial = _c.partial;
|
|
754
|
+
}), data = _c.data, partial = _c.partial, hasData = _c.hasData;
|
|
739
755
|
result.push(data);
|
|
740
756
|
if (partial) {
|
|
741
757
|
partialData = true;
|
|
742
758
|
}
|
|
759
|
+
if (hasData) {
|
|
760
|
+
hasValues = true;
|
|
761
|
+
}
|
|
743
762
|
}
|
|
744
763
|
}
|
|
745
764
|
catch (e_10_1) { e_10 = { error: e_10_1 }; }
|
|
@@ -749,7 +768,11 @@ var CacheInternal = /** @class */ (function () {
|
|
|
749
768
|
}
|
|
750
769
|
finally { if (e_10) throw e_10.error; }
|
|
751
770
|
}
|
|
752
|
-
return {
|
|
771
|
+
return {
|
|
772
|
+
data: result,
|
|
773
|
+
partial: partialData,
|
|
774
|
+
hasData: hasValues,
|
|
775
|
+
};
|
|
753
776
|
};
|
|
754
777
|
CacheInternal.prototype.extractNestedListIDs = function (_a) {
|
|
755
778
|
var e_11, _b;
|
|
@@ -63,6 +63,7 @@ declare class CacheInternal {
|
|
|
63
63
|
}): {
|
|
64
64
|
data: GraphQLObject | null;
|
|
65
65
|
partial: boolean;
|
|
66
|
+
hasData: boolean;
|
|
66
67
|
};
|
|
67
68
|
id(type: string, data: {
|
|
68
69
|
id?: string;
|
|
@@ -79,6 +80,7 @@ declare class CacheInternal {
|
|
|
79
80
|
}): {
|
|
80
81
|
data: LinkedList<GraphQLValue>;
|
|
81
82
|
partial: boolean;
|
|
83
|
+
hasData: boolean;
|
|
82
84
|
};
|
|
83
85
|
extractNestedListIDs({ value, abstract, recordID, key, linkedType, fields, variables, applyUpdates, specs, layer, startingWith, }: {
|
|
84
86
|
value: GraphQLValue[];
|
|
@@ -117,7 +117,14 @@ var Cache = /** @class */ (function () {
|
|
|
117
117
|
for (var _i = 0; _i < arguments.length; _i++) {
|
|
118
118
|
args[_i] = arguments[_i];
|
|
119
119
|
}
|
|
120
|
-
|
|
120
|
+
var _b = (_a = this._internal_unstable).getSelection.apply(_a, __spread(args)), data = _b.data, partial = _b.partial, hasData = _b.hasData;
|
|
121
|
+
if (!hasData) {
|
|
122
|
+
return { data: null, partial: false };
|
|
123
|
+
}
|
|
124
|
+
return {
|
|
125
|
+
data: data,
|
|
126
|
+
partial: partial,
|
|
127
|
+
};
|
|
121
128
|
};
|
|
122
129
|
// register the provided callbacks with the fields specified by the selection
|
|
123
130
|
Cache.prototype.subscribe = function (spec, variables) {
|
|
@@ -597,7 +604,7 @@ var CacheInternal = /** @class */ (function () {
|
|
|
597
604
|
var selection = _a.selection, _e = _a.parent, parent = _e === void 0 ? exports.rootID : _e, variables = _a.variables;
|
|
598
605
|
// we could be asking for values of null
|
|
599
606
|
if (parent === null) {
|
|
600
|
-
return { data: null, partial: false };
|
|
607
|
+
return { data: null, partial: false, hasData: true };
|
|
601
608
|
}
|
|
602
609
|
var target = {};
|
|
603
610
|
// we need to track if we have a partial data set which means we have _something_ but not everything
|
|
@@ -618,14 +625,14 @@ var CacheInternal = /** @class */ (function () {
|
|
|
618
625
|
if (typeof value === 'undefined') {
|
|
619
626
|
partial = true;
|
|
620
627
|
}
|
|
621
|
-
// as long as the value is not undefined, we have something
|
|
622
|
-
else {
|
|
623
|
-
hasData = true;
|
|
624
|
-
}
|
|
625
628
|
// if we dont have a value to return, use null (we check for non-null fields at the end)
|
|
626
629
|
if (typeof value === 'undefined' || value === null) {
|
|
627
630
|
// set the value to null
|
|
628
631
|
target[attributeName] = null;
|
|
632
|
+
// if we didn't just write undefined, there is officially some data in this object
|
|
633
|
+
if (typeof value !== 'undefined') {
|
|
634
|
+
hasData = true;
|
|
635
|
+
}
|
|
629
636
|
}
|
|
630
637
|
// if the field is a scalar
|
|
631
638
|
else if (!fields) {
|
|
@@ -638,6 +645,7 @@ var CacheInternal = /** @class */ (function () {
|
|
|
638
645
|
else {
|
|
639
646
|
target[attributeName] = value;
|
|
640
647
|
}
|
|
648
|
+
hasData = true;
|
|
641
649
|
}
|
|
642
650
|
// if the field is a list of records
|
|
643
651
|
else if (Array.isArray(value)) {
|
|
@@ -653,6 +661,9 @@ var CacheInternal = /** @class */ (function () {
|
|
|
653
661
|
if (listValue.partial) {
|
|
654
662
|
partial = true;
|
|
655
663
|
}
|
|
664
|
+
if (listValue.hasData) {
|
|
665
|
+
hasData = true;
|
|
666
|
+
}
|
|
656
667
|
}
|
|
657
668
|
// otherwise the field is a linked object
|
|
658
669
|
else {
|
|
@@ -668,6 +679,9 @@ var CacheInternal = /** @class */ (function () {
|
|
|
668
679
|
if (objectFields.partial) {
|
|
669
680
|
partial = true;
|
|
670
681
|
}
|
|
682
|
+
if (objectFields.hasData) {
|
|
683
|
+
hasData = true;
|
|
684
|
+
}
|
|
671
685
|
}
|
|
672
686
|
// regardless of how the field was processed, if we got a null value assigned
|
|
673
687
|
// and the field is not nullable, we need to cascade up
|
|
@@ -688,6 +702,7 @@ var CacheInternal = /** @class */ (function () {
|
|
|
688
702
|
// our value is considered true if there is some data but not everything
|
|
689
703
|
// has a full value
|
|
690
704
|
partial: hasData && partial,
|
|
705
|
+
hasData: hasData,
|
|
691
706
|
};
|
|
692
707
|
};
|
|
693
708
|
CacheInternal.prototype.id = function (type, data) {
|
|
@@ -713,6 +728,7 @@ var CacheInternal = /** @class */ (function () {
|
|
|
713
728
|
// to the corresponding record. can't have that now, can we?
|
|
714
729
|
var result = [];
|
|
715
730
|
var partialData = false;
|
|
731
|
+
var hasValues = false;
|
|
716
732
|
try {
|
|
717
733
|
for (var linkedList_1 = __values(linkedList), linkedList_1_1 = linkedList_1.next(); !linkedList_1_1.done; linkedList_1_1 = linkedList_1.next()) {
|
|
718
734
|
var entry = linkedList_1_1.value;
|
|
@@ -735,11 +751,14 @@ var CacheInternal = /** @class */ (function () {
|
|
|
735
751
|
parent: entry,
|
|
736
752
|
selection: fields,
|
|
737
753
|
variables: variables,
|
|
738
|
-
}), data = _c.data, partial = _c.partial;
|
|
754
|
+
}), data = _c.data, partial = _c.partial, hasData = _c.hasData;
|
|
739
755
|
result.push(data);
|
|
740
756
|
if (partial) {
|
|
741
757
|
partialData = true;
|
|
742
758
|
}
|
|
759
|
+
if (hasData) {
|
|
760
|
+
hasValues = true;
|
|
761
|
+
}
|
|
743
762
|
}
|
|
744
763
|
}
|
|
745
764
|
catch (e_10_1) { e_10 = { error: e_10_1 }; }
|
|
@@ -749,7 +768,11 @@ var CacheInternal = /** @class */ (function () {
|
|
|
749
768
|
}
|
|
750
769
|
finally { if (e_10) throw e_10.error; }
|
|
751
770
|
}
|
|
752
|
-
return {
|
|
771
|
+
return {
|
|
772
|
+
data: result,
|
|
773
|
+
partial: partialData,
|
|
774
|
+
hasData: hasValues,
|
|
775
|
+
};
|
|
753
776
|
};
|
|
754
777
|
CacheInternal.prototype.extractNestedListIDs = function (_a) {
|
|
755
778
|
var e_11, _b;
|
|
@@ -63,6 +63,7 @@ declare class CacheInternal {
|
|
|
63
63
|
}): {
|
|
64
64
|
data: GraphQLObject | null;
|
|
65
65
|
partial: boolean;
|
|
66
|
+
hasData: boolean;
|
|
66
67
|
};
|
|
67
68
|
id(type: string, data: {
|
|
68
69
|
id?: string;
|
|
@@ -79,6 +80,7 @@ declare class CacheInternal {
|
|
|
79
80
|
}): {
|
|
80
81
|
data: LinkedList<GraphQLValue>;
|
|
81
82
|
partial: boolean;
|
|
83
|
+
hasData: boolean;
|
|
82
84
|
};
|
|
83
85
|
extractNestedListIDs({ value, abstract, recordID, key, linkedType, fields, variables, applyUpdates, specs, layer, startingWith, }: {
|
|
84
86
|
value: GraphQLValue[];
|
|
@@ -44,7 +44,14 @@ export class Cache {
|
|
|
44
44
|
}
|
|
45
45
|
// reconstruct an object with the fields/relations specified by a selection
|
|
46
46
|
read(...args) {
|
|
47
|
-
|
|
47
|
+
const { data, partial, hasData } = this._internal_unstable.getSelection(...args);
|
|
48
|
+
if (!hasData) {
|
|
49
|
+
return { data: null, partial: false };
|
|
50
|
+
}
|
|
51
|
+
return {
|
|
52
|
+
data,
|
|
53
|
+
partial,
|
|
54
|
+
};
|
|
48
55
|
}
|
|
49
56
|
// register the provided callbacks with the fields specified by the selection
|
|
50
57
|
subscribe(spec, variables = {}) {
|
|
@@ -439,7 +446,7 @@ class CacheInternal {
|
|
|
439
446
|
var _a, _b;
|
|
440
447
|
// we could be asking for values of null
|
|
441
448
|
if (parent === null) {
|
|
442
|
-
return { data: null, partial: false };
|
|
449
|
+
return { data: null, partial: false, hasData: true };
|
|
443
450
|
}
|
|
444
451
|
const target = {};
|
|
445
452
|
// we need to track if we have a partial data set which means we have _something_ but not everything
|
|
@@ -458,14 +465,14 @@ class CacheInternal {
|
|
|
458
465
|
if (typeof value === 'undefined') {
|
|
459
466
|
partial = true;
|
|
460
467
|
}
|
|
461
|
-
// as long as the value is not undefined, we have something
|
|
462
|
-
else {
|
|
463
|
-
hasData = true;
|
|
464
|
-
}
|
|
465
468
|
// if we dont have a value to return, use null (we check for non-null fields at the end)
|
|
466
469
|
if (typeof value === 'undefined' || value === null) {
|
|
467
470
|
// set the value to null
|
|
468
471
|
target[attributeName] = null;
|
|
472
|
+
// if we didn't just write undefined, there is officially some data in this object
|
|
473
|
+
if (typeof value !== 'undefined') {
|
|
474
|
+
hasData = true;
|
|
475
|
+
}
|
|
469
476
|
}
|
|
470
477
|
// if the field is a scalar
|
|
471
478
|
else if (!fields) {
|
|
@@ -478,6 +485,7 @@ class CacheInternal {
|
|
|
478
485
|
else {
|
|
479
486
|
target[attributeName] = value;
|
|
480
487
|
}
|
|
488
|
+
hasData = true;
|
|
481
489
|
}
|
|
482
490
|
// if the field is a list of records
|
|
483
491
|
else if (Array.isArray(value)) {
|
|
@@ -493,6 +501,9 @@ class CacheInternal {
|
|
|
493
501
|
if (listValue.partial) {
|
|
494
502
|
partial = true;
|
|
495
503
|
}
|
|
504
|
+
if (listValue.hasData) {
|
|
505
|
+
hasData = true;
|
|
506
|
+
}
|
|
496
507
|
}
|
|
497
508
|
// otherwise the field is a linked object
|
|
498
509
|
else {
|
|
@@ -508,6 +519,9 @@ class CacheInternal {
|
|
|
508
519
|
if (objectFields.partial) {
|
|
509
520
|
partial = true;
|
|
510
521
|
}
|
|
522
|
+
if (objectFields.hasData) {
|
|
523
|
+
hasData = true;
|
|
524
|
+
}
|
|
511
525
|
}
|
|
512
526
|
// regardless of how the field was processed, if we got a null value assigned
|
|
513
527
|
// and the field is not nullable, we need to cascade up
|
|
@@ -520,6 +534,7 @@ class CacheInternal {
|
|
|
520
534
|
// our value is considered true if there is some data but not everything
|
|
521
535
|
// has a full value
|
|
522
536
|
partial: hasData && partial,
|
|
537
|
+
hasData,
|
|
523
538
|
};
|
|
524
539
|
}
|
|
525
540
|
id(type, data) {
|
|
@@ -543,6 +558,7 @@ class CacheInternal {
|
|
|
543
558
|
// to the corresponding record. can't have that now, can we?
|
|
544
559
|
const result = [];
|
|
545
560
|
let partialData = false;
|
|
561
|
+
let hasValues = false;
|
|
546
562
|
for (const entry of linkedList) {
|
|
547
563
|
// if the entry is an array, keep going
|
|
548
564
|
if (Array.isArray(entry)) {
|
|
@@ -559,7 +575,7 @@ class CacheInternal {
|
|
|
559
575
|
continue;
|
|
560
576
|
}
|
|
561
577
|
// look up the data for the record
|
|
562
|
-
const { data, partial } = this.getSelection({
|
|
578
|
+
const { data, partial, hasData } = this.getSelection({
|
|
563
579
|
parent: entry,
|
|
564
580
|
selection: fields,
|
|
565
581
|
variables,
|
|
@@ -568,8 +584,15 @@ class CacheInternal {
|
|
|
568
584
|
if (partial) {
|
|
569
585
|
partialData = true;
|
|
570
586
|
}
|
|
587
|
+
if (hasData) {
|
|
588
|
+
hasValues = true;
|
|
589
|
+
}
|
|
571
590
|
}
|
|
572
|
-
return {
|
|
591
|
+
return {
|
|
592
|
+
data: result,
|
|
593
|
+
partial: partialData,
|
|
594
|
+
hasData: hasValues,
|
|
595
|
+
};
|
|
573
596
|
}
|
|
574
597
|
extractNestedListIDs({ value, abstract, recordID, key, linkedType, fields, variables, applyUpdates, specs, layer, startingWith, }) {
|
|
575
598
|
var _a;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "houdini",
|
|
3
|
-
"version": "0.13.2-alpha.
|
|
3
|
+
"version": "0.13.2-alpha.4",
|
|
4
4
|
"description": "The disappearing graphql client for SvelteKit",
|
|
5
5
|
"scripts": {
|
|
6
6
|
"build:runtime": "npm run build:runtime:cjs && npm run build:runtime:esm",
|
|
@@ -57,5 +57,5 @@
|
|
|
57
57
|
"rollup-plugin-preserve-shebangs": "^0.2.0",
|
|
58
58
|
"svelte": "^3.34.0"
|
|
59
59
|
},
|
|
60
|
-
"gitHead": "
|
|
60
|
+
"gitHead": "9b4a8076b51a806586ac14560c60b42aab2047ec"
|
|
61
61
|
}
|
package/runtime/cache/cache.ts
CHANGED
|
@@ -70,7 +70,16 @@ export class Cache {
|
|
|
70
70
|
|
|
71
71
|
// reconstruct an object with the fields/relations specified by a selection
|
|
72
72
|
read(...args: Parameters<CacheInternal['getSelection']>) {
|
|
73
|
-
|
|
73
|
+
const { data, partial, hasData } = this._internal_unstable.getSelection(...args)
|
|
74
|
+
|
|
75
|
+
if (!hasData) {
|
|
76
|
+
return { data: null, partial: false }
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
return {
|
|
80
|
+
data,
|
|
81
|
+
partial,
|
|
82
|
+
}
|
|
74
83
|
}
|
|
75
84
|
|
|
76
85
|
// register the provided callbacks with the fields specified by the selection
|
|
@@ -608,10 +617,10 @@ class CacheInternal {
|
|
|
608
617
|
selection: SubscriptionSelection
|
|
609
618
|
parent?: string
|
|
610
619
|
variables?: {}
|
|
611
|
-
}): { data: GraphQLObject | null; partial: boolean } {
|
|
620
|
+
}): { data: GraphQLObject | null; partial: boolean; hasData: boolean } {
|
|
612
621
|
// we could be asking for values of null
|
|
613
622
|
if (parent === null) {
|
|
614
|
-
return { data: null, partial: false }
|
|
623
|
+
return { data: null, partial: false, hasData: true }
|
|
615
624
|
}
|
|
616
625
|
|
|
617
626
|
const target = {} as GraphQLObject
|
|
@@ -638,15 +647,16 @@ class CacheInternal {
|
|
|
638
647
|
if (typeof value === 'undefined') {
|
|
639
648
|
partial = true
|
|
640
649
|
}
|
|
641
|
-
// as long as the value is not undefined, we have something
|
|
642
|
-
else {
|
|
643
|
-
hasData = true
|
|
644
|
-
}
|
|
645
650
|
|
|
646
651
|
// if we dont have a value to return, use null (we check for non-null fields at the end)
|
|
647
652
|
if (typeof value === 'undefined' || value === null) {
|
|
648
653
|
// set the value to null
|
|
649
654
|
target[attributeName] = null
|
|
655
|
+
|
|
656
|
+
// if we didn't just write undefined, there is officially some data in this object
|
|
657
|
+
if (typeof value !== 'undefined') {
|
|
658
|
+
hasData = true
|
|
659
|
+
}
|
|
650
660
|
}
|
|
651
661
|
|
|
652
662
|
// if the field is a scalar
|
|
@@ -662,6 +672,8 @@ class CacheInternal {
|
|
|
662
672
|
else {
|
|
663
673
|
target[attributeName] = value
|
|
664
674
|
}
|
|
675
|
+
|
|
676
|
+
hasData = true
|
|
665
677
|
}
|
|
666
678
|
|
|
667
679
|
// if the field is a list of records
|
|
@@ -680,6 +692,10 @@ class CacheInternal {
|
|
|
680
692
|
if (listValue.partial) {
|
|
681
693
|
partial = true
|
|
682
694
|
}
|
|
695
|
+
|
|
696
|
+
if (listValue.hasData) {
|
|
697
|
+
hasData = true
|
|
698
|
+
}
|
|
683
699
|
}
|
|
684
700
|
|
|
685
701
|
// otherwise the field is a linked object
|
|
@@ -698,6 +714,10 @@ class CacheInternal {
|
|
|
698
714
|
if (objectFields.partial) {
|
|
699
715
|
partial = true
|
|
700
716
|
}
|
|
717
|
+
|
|
718
|
+
if (objectFields.hasData) {
|
|
719
|
+
hasData = true
|
|
720
|
+
}
|
|
701
721
|
}
|
|
702
722
|
|
|
703
723
|
// regardless of how the field was processed, if we got a null value assigned
|
|
@@ -712,6 +732,7 @@ class CacheInternal {
|
|
|
712
732
|
// our value is considered true if there is some data but not everything
|
|
713
733
|
// has a full value
|
|
714
734
|
partial: hasData && partial,
|
|
735
|
+
hasData,
|
|
715
736
|
}
|
|
716
737
|
}
|
|
717
738
|
|
|
@@ -747,12 +768,13 @@ class CacheInternal {
|
|
|
747
768
|
fields: SubscriptionSelection
|
|
748
769
|
variables?: {}
|
|
749
770
|
linkedList: LinkedList
|
|
750
|
-
}): { data: LinkedList<GraphQLValue>; partial: boolean } {
|
|
771
|
+
}): { data: LinkedList<GraphQLValue>; partial: boolean; hasData: boolean } {
|
|
751
772
|
// the linked list could be a deeply nested thing, we need to call getData for each record
|
|
752
773
|
// we can't mutate the lists because that would change the id references in the listLinks map
|
|
753
774
|
// to the corresponding record. can't have that now, can we?
|
|
754
775
|
const result = []
|
|
755
776
|
let partialData = false
|
|
777
|
+
let hasValues = false
|
|
756
778
|
|
|
757
779
|
for (const entry of linkedList) {
|
|
758
780
|
// if the entry is an array, keep going
|
|
@@ -772,7 +794,7 @@ class CacheInternal {
|
|
|
772
794
|
}
|
|
773
795
|
|
|
774
796
|
// look up the data for the record
|
|
775
|
-
const { data, partial } = this.getSelection({
|
|
797
|
+
const { data, partial, hasData } = this.getSelection({
|
|
776
798
|
parent: entry,
|
|
777
799
|
selection: fields,
|
|
778
800
|
variables,
|
|
@@ -783,9 +805,17 @@ class CacheInternal {
|
|
|
783
805
|
if (partial) {
|
|
784
806
|
partialData = true
|
|
785
807
|
}
|
|
808
|
+
|
|
809
|
+
if (hasData) {
|
|
810
|
+
hasValues = true
|
|
811
|
+
}
|
|
786
812
|
}
|
|
787
813
|
|
|
788
|
-
return {
|
|
814
|
+
return {
|
|
815
|
+
data: result,
|
|
816
|
+
partial: partialData,
|
|
817
|
+
hasData: hasValues,
|
|
818
|
+
}
|
|
789
819
|
}
|
|
790
820
|
|
|
791
821
|
extractNestedListIDs({
|
|
@@ -797,6 +797,10 @@ test('null-value cascade from field value', function () {
|
|
|
797
797
|
keyRaw: 'firstName',
|
|
798
798
|
type: 'String',
|
|
799
799
|
},
|
|
800
|
+
id: {
|
|
801
|
+
keyRaw: 'id',
|
|
802
|
+
type: 'String',
|
|
803
|
+
},
|
|
800
804
|
},
|
|
801
805
|
},
|
|
802
806
|
},
|
|
@@ -820,12 +824,17 @@ test('null-value field', function () {
|
|
|
820
824
|
keyRaw: 'id',
|
|
821
825
|
type: 'String',
|
|
822
826
|
},
|
|
827
|
+
firstName: {
|
|
828
|
+
keyRaw: 'firstName',
|
|
829
|
+
type: 'String',
|
|
830
|
+
},
|
|
823
831
|
},
|
|
824
832
|
},
|
|
825
833
|
},
|
|
826
834
|
data: {
|
|
827
835
|
viewer: {
|
|
828
836
|
id: '1',
|
|
837
|
+
firstName: null,
|
|
829
838
|
},
|
|
830
839
|
},
|
|
831
840
|
})
|
|
@@ -852,6 +861,7 @@ test('null-value field', function () {
|
|
|
852
861
|
},
|
|
853
862
|
})
|
|
854
863
|
|
|
864
|
+
console.log('vvvvvvvvvv')
|
|
855
865
|
expect(
|
|
856
866
|
cache.read({
|
|
857
867
|
selection: {
|
|
@@ -921,9 +931,12 @@ test('null-value cascade from object value', function () {
|
|
|
921
931
|
},
|
|
922
932
|
},
|
|
923
933
|
},
|
|
924
|
-
})
|
|
934
|
+
})
|
|
925
935
|
).toEqual({
|
|
926
|
-
|
|
936
|
+
partial: true,
|
|
937
|
+
data: {
|
|
938
|
+
viewer: null,
|
|
939
|
+
},
|
|
927
940
|
})
|
|
928
941
|
|
|
929
942
|
// read the data as if the nested value is not required (parent should be null)
|
|
@@ -935,6 +948,10 @@ test('null-value cascade from object value', function () {
|
|
|
935
948
|
keyRaw: 'viewer',
|
|
936
949
|
nullable: true,
|
|
937
950
|
fields: {
|
|
951
|
+
id: {
|
|
952
|
+
keyRaw: 'id',
|
|
953
|
+
type: 'String',
|
|
954
|
+
},
|
|
938
955
|
parent: {
|
|
939
956
|
keyRaw: 'parent',
|
|
940
957
|
type: 'User',
|
|
@@ -943,10 +960,14 @@ test('null-value cascade from object value', function () {
|
|
|
943
960
|
},
|
|
944
961
|
},
|
|
945
962
|
},
|
|
946
|
-
})
|
|
963
|
+
})
|
|
947
964
|
).toEqual({
|
|
948
|
-
|
|
949
|
-
|
|
965
|
+
partial: true,
|
|
966
|
+
data: {
|
|
967
|
+
viewer: {
|
|
968
|
+
id: '1',
|
|
969
|
+
parent: null,
|
|
970
|
+
},
|
|
950
971
|
},
|
|
951
972
|
})
|
|
952
973
|
})
|
|
@@ -1014,6 +1035,10 @@ test('null-value cascade to root', function () {
|
|
|
1014
1035
|
keyRaw: 'parent',
|
|
1015
1036
|
type: 'User',
|
|
1016
1037
|
},
|
|
1038
|
+
id: {
|
|
1039
|
+
keyRaw: 'id',
|
|
1040
|
+
type: 'String',
|
|
1041
|
+
},
|
|
1017
1042
|
},
|
|
1018
1043
|
},
|
|
1019
1044
|
},
|
|
@@ -1022,3 +1047,78 @@ test('null-value cascade to root', function () {
|
|
|
1022
1047
|
viewer: null,
|
|
1023
1048
|
})
|
|
1024
1049
|
})
|
|
1050
|
+
|
|
1051
|
+
test('must have a single value in order to use partial data', function () {
|
|
1052
|
+
// instantiate the cache
|
|
1053
|
+
const cache = new Cache(config)
|
|
1054
|
+
|
|
1055
|
+
// write the user data without the nested value
|
|
1056
|
+
cache.write({
|
|
1057
|
+
selection: {
|
|
1058
|
+
viewer: {
|
|
1059
|
+
type: 'User',
|
|
1060
|
+
keyRaw: 'viewer',
|
|
1061
|
+
nullable: true,
|
|
1062
|
+
fields: {
|
|
1063
|
+
id: {
|
|
1064
|
+
keyRaw: 'id',
|
|
1065
|
+
type: 'String',
|
|
1066
|
+
},
|
|
1067
|
+
},
|
|
1068
|
+
},
|
|
1069
|
+
},
|
|
1070
|
+
data: {
|
|
1071
|
+
viewer: {
|
|
1072
|
+
id: '1',
|
|
1073
|
+
},
|
|
1074
|
+
},
|
|
1075
|
+
})
|
|
1076
|
+
|
|
1077
|
+
expect(
|
|
1078
|
+
cache.read({
|
|
1079
|
+
selection: {
|
|
1080
|
+
viewer: {
|
|
1081
|
+
type: 'User',
|
|
1082
|
+
keyRaw: 'viewer',
|
|
1083
|
+
nullable: true,
|
|
1084
|
+
fields: {
|
|
1085
|
+
parent: {
|
|
1086
|
+
keyRaw: 'parent',
|
|
1087
|
+
type: 'User',
|
|
1088
|
+
},
|
|
1089
|
+
},
|
|
1090
|
+
},
|
|
1091
|
+
},
|
|
1092
|
+
})
|
|
1093
|
+
).toEqual({
|
|
1094
|
+
partial: false,
|
|
1095
|
+
data: null,
|
|
1096
|
+
})
|
|
1097
|
+
|
|
1098
|
+
expect(
|
|
1099
|
+
cache.read({
|
|
1100
|
+
selection: {
|
|
1101
|
+
viewer: {
|
|
1102
|
+
type: 'User',
|
|
1103
|
+
keyRaw: 'viewer',
|
|
1104
|
+
nullable: true,
|
|
1105
|
+
fields: {
|
|
1106
|
+
id: {
|
|
1107
|
+
keyRaw: 'id',
|
|
1108
|
+
type: 'String',
|
|
1109
|
+
},
|
|
1110
|
+
parent: {
|
|
1111
|
+
keyRaw: 'parent',
|
|
1112
|
+
type: 'User',
|
|
1113
|
+
},
|
|
1114
|
+
},
|
|
1115
|
+
},
|
|
1116
|
+
},
|
|
1117
|
+
})
|
|
1118
|
+
).toEqual({
|
|
1119
|
+
partial: true,
|
|
1120
|
+
data: {
|
|
1121
|
+
viewer: null,
|
|
1122
|
+
},
|
|
1123
|
+
})
|
|
1124
|
+
})
|