houdini 0.13.7-alpha.1 → 0.13.7
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/cmd.js +0 -0
- package/build/runtime/cache/cache.d.ts +8 -4
- package/build/runtime/cache/cache.js +16 -12
- package/build/runtime/cache/storage.d.ts +1 -0
- package/build/runtime/cache/storage.js +8 -0
- package/build/runtime/mutation.js +11 -5
- package/build/runtime-cjs/cache/cache.d.ts +8 -4
- package/build/runtime-cjs/cache/cache.js +16 -12
- package/build/runtime-cjs/cache/storage.d.ts +1 -0
- package/build/runtime-cjs/cache/storage.js +8 -0
- package/build/runtime-cjs/mutation.js +11 -5
- package/build/runtime-esm/cache/cache.d.ts +8 -4
- package/build/runtime-esm/cache/cache.js +14 -10
- package/build/runtime-esm/cache/storage.d.ts +1 -0
- package/build/runtime-esm/cache/storage.js +8 -0
- package/build/runtime-esm/mutation.js +12 -4
- package/package.json +2 -2
- package/runtime/cache/cache.ts +19 -8
- package/runtime/cache/storage.ts +12 -0
- package/runtime/cache/tests/subscriptions.test.ts +168 -0
- package/runtime/mutation.ts +13 -6
- package/build/runtime-esm/cache/list.d.ts +0 -35
- package/build/runtime-esm/cache/list.js +0 -203
- package/build/runtime-esm/cache/record.d.ts +0 -40
- package/build/runtime-esm/cache/record.js +0 -195
package/build/cmd.js
CHANGED
|
File without changes
|
|
@@ -7,7 +7,7 @@ import { InMemorySubscriptions } from './subscription';
|
|
|
7
7
|
export declare class Cache {
|
|
8
8
|
_internal_unstable: CacheInternal;
|
|
9
9
|
constructor(config: Config);
|
|
10
|
-
write({ layer: layerID, ...args }: {
|
|
10
|
+
write({ layer: layerID, notifySubscribers, ...args }: {
|
|
11
11
|
data: {
|
|
12
12
|
[key: string]: GraphQLValue;
|
|
13
13
|
};
|
|
@@ -16,7 +16,9 @@ export declare class Cache {
|
|
|
16
16
|
parent?: string;
|
|
17
17
|
layer?: LayerID | null;
|
|
18
18
|
applyUpdates?: boolean;
|
|
19
|
-
|
|
19
|
+
notifySubscribers?: SubscriptionSpec[];
|
|
20
|
+
forceNotify?: boolean;
|
|
21
|
+
}): SubscriptionSpec[];
|
|
20
22
|
read(...args: Parameters<CacheInternal['getSelection']>): {
|
|
21
23
|
data: GraphQLObject | null;
|
|
22
24
|
partial: boolean;
|
|
@@ -42,7 +44,7 @@ declare class CacheInternal {
|
|
|
42
44
|
cache: Cache;
|
|
43
45
|
lifetimes: GarbageCollector;
|
|
44
46
|
});
|
|
45
|
-
writeSelection({ data, selection, variables, root, parent, applyUpdates, layer, toNotify, }: {
|
|
47
|
+
writeSelection({ data, selection, variables, root, parent, applyUpdates, layer, toNotify, forceNotify, }: {
|
|
46
48
|
data: {
|
|
47
49
|
[key: string]: GraphQLValue;
|
|
48
50
|
};
|
|
@@ -55,6 +57,7 @@ declare class CacheInternal {
|
|
|
55
57
|
layer: Layer;
|
|
56
58
|
toNotify?: SubscriptionSpec[];
|
|
57
59
|
applyUpdates?: boolean;
|
|
60
|
+
forceNotify?: boolean;
|
|
58
61
|
}): SubscriptionSpec[];
|
|
59
62
|
getSelection({ selection, parent, variables, }: {
|
|
60
63
|
selection: SubscriptionSelection;
|
|
@@ -82,7 +85,7 @@ declare class CacheInternal {
|
|
|
82
85
|
partial: boolean;
|
|
83
86
|
hasData: boolean;
|
|
84
87
|
};
|
|
85
|
-
extractNestedListIDs({ value, abstract, recordID, key, linkedType, fields, variables, applyUpdates, specs, layer, startingWith, }: {
|
|
88
|
+
extractNestedListIDs({ value, abstract, recordID, key, linkedType, fields, variables, applyUpdates, specs, layer, startingWith, forceNotify, }: {
|
|
86
89
|
value: GraphQLValue[];
|
|
87
90
|
recordID: string;
|
|
88
91
|
key: string;
|
|
@@ -94,6 +97,7 @@ declare class CacheInternal {
|
|
|
94
97
|
fields: SubscriptionSelection;
|
|
95
98
|
layer: Layer;
|
|
96
99
|
startingWith: number;
|
|
100
|
+
forceNotify?: boolean;
|
|
97
101
|
}): {
|
|
98
102
|
nestedIDs: LinkedList;
|
|
99
103
|
newIDs: (string | null)[];
|
|
@@ -75,7 +75,7 @@ var Cache = /** @class */ (function () {
|
|
|
75
75
|
Cache.prototype.write = function (_a) {
|
|
76
76
|
var e_1, _b;
|
|
77
77
|
var _c;
|
|
78
|
-
var layerID = _a.layer, args = __rest(_a, ["layer"]);
|
|
78
|
+
var layerID = _a.layer, _d = _a.notifySubscribers, notifySubscribers = _d === void 0 ? [] : _d, args = __rest(_a, ["layer", "notifySubscribers"]);
|
|
79
79
|
// find the correct layer
|
|
80
80
|
var layer = layerID
|
|
81
81
|
? this._internal_unstable.storage.getLayer(layerID)
|
|
@@ -86,8 +86,8 @@ var Cache = /** @class */ (function () {
|
|
|
86
86
|
// function's identity
|
|
87
87
|
var notified = [];
|
|
88
88
|
try {
|
|
89
|
-
for (var
|
|
90
|
-
var spec =
|
|
89
|
+
for (var _e = __values(subscribers.concat(notifySubscribers)), _f = _e.next(); !_f.done; _f = _e.next()) {
|
|
90
|
+
var spec = _f.value;
|
|
91
91
|
// if we haven't added the set yet
|
|
92
92
|
if (!notified.includes(spec.set)) {
|
|
93
93
|
notified.push(spec.set);
|
|
@@ -103,12 +103,12 @@ var Cache = /** @class */ (function () {
|
|
|
103
103
|
catch (e_1_1) { e_1 = { error: e_1_1 }; }
|
|
104
104
|
finally {
|
|
105
105
|
try {
|
|
106
|
-
if (
|
|
106
|
+
if (_f && !_f.done && (_b = _e.return)) _b.call(_e);
|
|
107
107
|
}
|
|
108
108
|
finally { if (e_1) throw e_1.error; }
|
|
109
109
|
}
|
|
110
110
|
// return the id to the caller so they can resolve the layer if it was optimistic
|
|
111
|
-
return
|
|
111
|
+
return subscribers;
|
|
112
112
|
};
|
|
113
113
|
// reconstruct an object with the fields/relations specified by a selection
|
|
114
114
|
Cache.prototype.read = function () {
|
|
@@ -187,7 +187,7 @@ var CacheInternal = /** @class */ (function () {
|
|
|
187
187
|
var e_2, _b;
|
|
188
188
|
var _this = this;
|
|
189
189
|
var _c;
|
|
190
|
-
var data = _a.data, selection = _a.selection, _d = _a.variables, variables = _d === void 0 ? {} : _d, _e = _a.root, root = _e === void 0 ? exports.rootID : _e, _f = _a.parent, parent = _f === void 0 ? exports.rootID : _f, _g = _a.applyUpdates, applyUpdates = _g === void 0 ? false : _g, layer = _a.layer, _h = _a.toNotify, toNotify = _h === void 0 ? [] : _h;
|
|
190
|
+
var data = _a.data, selection = _a.selection, _d = _a.variables, variables = _d === void 0 ? {} : _d, _e = _a.root, root = _e === void 0 ? exports.rootID : _e, _f = _a.parent, parent = _f === void 0 ? exports.rootID : _f, _g = _a.applyUpdates, applyUpdates = _g === void 0 ? false : _g, layer = _a.layer, _h = _a.toNotify, toNotify = _h === void 0 ? [] : _h, forceNotify = _a.forceNotify;
|
|
191
191
|
// if the cache is disabled, dont do anything
|
|
192
192
|
if (this._disabled) {
|
|
193
193
|
return [];
|
|
@@ -212,12 +212,12 @@ var CacheInternal = /** @class */ (function () {
|
|
|
212
212
|
// if the layer we are updating is the top most layer for the field
|
|
213
213
|
// then its value is "live". It is providing the current value and
|
|
214
214
|
// subscribers need to know if the value changed
|
|
215
|
-
var displayLayer =
|
|
215
|
+
var displayLayer = layer.isDisplayLayer(displayLayers);
|
|
216
216
|
// if we are writing to the display layer we need to refresh the lifetime of the value
|
|
217
217
|
if (displayLayer) {
|
|
218
218
|
this_1.lifetimes.resetLifetime(parent, key);
|
|
219
219
|
}
|
|
220
|
-
// any
|
|
220
|
+
// any scalar is defined as a field with no selection
|
|
221
221
|
if (!fields) {
|
|
222
222
|
// the value to write to the layer
|
|
223
223
|
var newValue = value;
|
|
@@ -234,7 +234,7 @@ var CacheInternal = /** @class */ (function () {
|
|
|
234
234
|
}
|
|
235
235
|
// if the value changed on a layer that impacts the current latest value
|
|
236
236
|
var valueChanged = JSON.stringify(newValue) !== JSON.stringify(previousValue);
|
|
237
|
-
if (
|
|
237
|
+
if (displayLayer && (valueChanged || forceNotify)) {
|
|
238
238
|
// we need to add the fields' subscribers to the set of callbacks
|
|
239
239
|
// we need to invoke
|
|
240
240
|
toNotify.push.apply(toNotify, __spread(currentSubcribers));
|
|
@@ -290,7 +290,7 @@ var CacheInternal = /** @class */ (function () {
|
|
|
290
290
|
// write the link to the layer
|
|
291
291
|
layer.writeLink(parent, key, linkedID);
|
|
292
292
|
// if the link target of this field changed and it was responsible for the current subscription
|
|
293
|
-
if (linkedID && displayLayer && linkChange) {
|
|
293
|
+
if (linkedID && displayLayer && (linkChange || forceNotify)) {
|
|
294
294
|
// we need to clear the subscriptions in the previous link
|
|
295
295
|
// and add them to the new link
|
|
296
296
|
if (previousValue && typeof previousValue === 'string') {
|
|
@@ -317,6 +317,7 @@ var CacheInternal = /** @class */ (function () {
|
|
|
317
317
|
toNotify: toNotify,
|
|
318
318
|
applyUpdates: applyUpdates,
|
|
319
319
|
layer: layer,
|
|
320
|
+
forceNotify: true,
|
|
320
321
|
});
|
|
321
322
|
}
|
|
322
323
|
}
|
|
@@ -373,6 +374,7 @@ var CacheInternal = /** @class */ (function () {
|
|
|
373
374
|
fields: fields,
|
|
374
375
|
layer: layer,
|
|
375
376
|
startingWith: applyUpdates && update === 'append' ? oldIDs_2.length : 0,
|
|
377
|
+
forceNotify: forceNotify,
|
|
376
378
|
}), newIDs = _j.newIDs, nestedIDs = _j.nestedIDs;
|
|
377
379
|
// if we're supposed to apply this write as an update, we need to figure out how
|
|
378
380
|
if (applyUpdates && update) {
|
|
@@ -447,7 +449,7 @@ var CacheInternal = /** @class */ (function () {
|
|
|
447
449
|
// is still valid would not be triggered
|
|
448
450
|
var contentChanged = JSON.stringify(linkedIDs) !== JSON.stringify(oldIDs_2);
|
|
449
451
|
// we need to look at the last time we saw each subscriber to check if they need to be added to the spec
|
|
450
|
-
if (contentChanged) {
|
|
452
|
+
if (contentChanged || forceNotify) {
|
|
451
453
|
toNotify.push.apply(toNotify, __spread(currentSubcribers));
|
|
452
454
|
}
|
|
453
455
|
try {
|
|
@@ -777,7 +779,7 @@ var CacheInternal = /** @class */ (function () {
|
|
|
777
779
|
CacheInternal.prototype.extractNestedListIDs = function (_a) {
|
|
778
780
|
var e_11, _b;
|
|
779
781
|
var _c;
|
|
780
|
-
var value = _a.value, abstract = _a.abstract, recordID = _a.recordID, key = _a.key, linkedType = _a.linkedType, fields = _a.fields, variables = _a.variables, applyUpdates = _a.applyUpdates, specs = _a.specs, layer = _a.layer, startingWith = _a.startingWith;
|
|
782
|
+
var value = _a.value, abstract = _a.abstract, recordID = _a.recordID, key = _a.key, linkedType = _a.linkedType, fields = _a.fields, variables = _a.variables, applyUpdates = _a.applyUpdates, specs = _a.specs, layer = _a.layer, startingWith = _a.startingWith, forceNotify = _a.forceNotify;
|
|
781
783
|
// build up the two lists
|
|
782
784
|
var nestedIDs = [];
|
|
783
785
|
var newIDs = [];
|
|
@@ -798,6 +800,7 @@ var CacheInternal = /** @class */ (function () {
|
|
|
798
800
|
specs: specs,
|
|
799
801
|
layer: layer,
|
|
800
802
|
startingWith: startingWith,
|
|
803
|
+
forceNotify: forceNotify,
|
|
801
804
|
});
|
|
802
805
|
// add the list of new ids to our list
|
|
803
806
|
newIDs.push.apply(newIDs, __spread(inner.newIDs));
|
|
@@ -849,6 +852,7 @@ var CacheInternal = /** @class */ (function () {
|
|
|
849
852
|
toNotify: specs,
|
|
850
853
|
applyUpdates: applyUpdates,
|
|
851
854
|
layer: layer,
|
|
855
|
+
forceNotify: forceNotify,
|
|
852
856
|
});
|
|
853
857
|
newIDs.push(linkedID);
|
|
854
858
|
nestedIDs[i] = linkedID;
|
|
@@ -32,6 +32,7 @@ export declare class Layer {
|
|
|
32
32
|
getOperations(id: string, field: string): Operation[] | undefined;
|
|
33
33
|
writeField(id: string, field: string, value: GraphQLField): LayerID;
|
|
34
34
|
writeLink(id: string, field: string, value: null | string | LinkedList): LayerID;
|
|
35
|
+
isDisplayLayer(displayLayers: number[]): boolean;
|
|
35
36
|
clear(): void;
|
|
36
37
|
applyDeletes(): void;
|
|
37
38
|
delete(id: string): void;
|
|
@@ -243,6 +243,7 @@ var InMemoryStorage = /** @class */ (function () {
|
|
|
243
243
|
var layer = this.data[layerIndex++];
|
|
244
244
|
// if the layer is optimistic, we can't go further
|
|
245
245
|
if (layer.optimistic) {
|
|
246
|
+
layerIndex--;
|
|
246
247
|
break;
|
|
247
248
|
}
|
|
248
249
|
// apply the layer onto our base
|
|
@@ -351,7 +352,14 @@ var Layer = /** @class */ (function () {
|
|
|
351
352
|
this.links[id] = __assign(__assign({}, this.links[id]), (_b = {}, _b[field] = value, _b));
|
|
352
353
|
return this.id;
|
|
353
354
|
};
|
|
355
|
+
Layer.prototype.isDisplayLayer = function (displayLayers) {
|
|
356
|
+
return (displayLayers.length === 0 ||
|
|
357
|
+
displayLayers.includes(this.id) ||
|
|
358
|
+
Math.max.apply(Math, __spread(displayLayers)) < this.id);
|
|
359
|
+
};
|
|
354
360
|
Layer.prototype.clear = function () {
|
|
361
|
+
// before we clear the data of the layer, look for any subscribers that need to be updated
|
|
362
|
+
// now that everything has been notified we can reset the data
|
|
355
363
|
this.links = {};
|
|
356
364
|
this.fields = {};
|
|
357
365
|
this.operations = {};
|
|
@@ -63,15 +63,15 @@ function mutation(document) {
|
|
|
63
63
|
var sessionStore = adapter_mjs_1.getSession();
|
|
64
64
|
// return an async function that sends the mutation go the server
|
|
65
65
|
return function (variables, mutationConfig) { return __awaiter(_this, void 0, void 0, function () {
|
|
66
|
-
var optimisticResponse,
|
|
66
|
+
var layer, optimisticResponse, toNotify, result, error_1;
|
|
67
67
|
return __generator(this, function (_a) {
|
|
68
68
|
switch (_a.label) {
|
|
69
69
|
case 0:
|
|
70
|
-
optimisticResponse = mutationConfig === null || mutationConfig === void 0 ? void 0 : mutationConfig.optimisticResponse;
|
|
71
70
|
layer = cache_1.default._internal_unstable.storage.createLayer(true);
|
|
72
|
-
|
|
71
|
+
optimisticResponse = mutationConfig === null || mutationConfig === void 0 ? void 0 : mutationConfig.optimisticResponse;
|
|
72
|
+
toNotify = [];
|
|
73
73
|
if (optimisticResponse) {
|
|
74
|
-
cache_1.default.write({
|
|
74
|
+
toNotify = cache_1.default.write({
|
|
75
75
|
selection: artifact.selection,
|
|
76
76
|
// make sure that any scalar values get processed into something we can cache
|
|
77
77
|
data: scalars_1.marshalSelection({
|
|
@@ -102,8 +102,14 @@ function mutation(document) {
|
|
|
102
102
|
selection: artifact.selection,
|
|
103
103
|
data: result.data,
|
|
104
104
|
variables: variables,
|
|
105
|
-
//
|
|
105
|
+
// write to the mutation's layer
|
|
106
106
|
layer: layer.id,
|
|
107
|
+
// notify any subscribers that we updated with the optimistic response
|
|
108
|
+
// in order to address situations where the optimistic update was wrong
|
|
109
|
+
notifySubscribers: toNotify,
|
|
110
|
+
// make sure that we notify subscribers for any values that we overwrite
|
|
111
|
+
// in order to address any race conditions when comparing the previous value
|
|
112
|
+
forceNotify: true,
|
|
107
113
|
});
|
|
108
114
|
// merge the layer back into the cache
|
|
109
115
|
cache_1.default._internal_unstable.storage.resolveLayer(layer.id);
|
|
@@ -7,7 +7,7 @@ import { InMemorySubscriptions } from './subscription';
|
|
|
7
7
|
export declare class Cache {
|
|
8
8
|
_internal_unstable: CacheInternal;
|
|
9
9
|
constructor(config: Config);
|
|
10
|
-
write({ layer: layerID, ...args }: {
|
|
10
|
+
write({ layer: layerID, notifySubscribers, ...args }: {
|
|
11
11
|
data: {
|
|
12
12
|
[key: string]: GraphQLValue;
|
|
13
13
|
};
|
|
@@ -16,7 +16,9 @@ export declare class Cache {
|
|
|
16
16
|
parent?: string;
|
|
17
17
|
layer?: LayerID | null;
|
|
18
18
|
applyUpdates?: boolean;
|
|
19
|
-
|
|
19
|
+
notifySubscribers?: SubscriptionSpec[];
|
|
20
|
+
forceNotify?: boolean;
|
|
21
|
+
}): SubscriptionSpec[];
|
|
20
22
|
read(...args: Parameters<CacheInternal['getSelection']>): {
|
|
21
23
|
data: GraphQLObject | null;
|
|
22
24
|
partial: boolean;
|
|
@@ -42,7 +44,7 @@ declare class CacheInternal {
|
|
|
42
44
|
cache: Cache;
|
|
43
45
|
lifetimes: GarbageCollector;
|
|
44
46
|
});
|
|
45
|
-
writeSelection({ data, selection, variables, root, parent, applyUpdates, layer, toNotify, }: {
|
|
47
|
+
writeSelection({ data, selection, variables, root, parent, applyUpdates, layer, toNotify, forceNotify, }: {
|
|
46
48
|
data: {
|
|
47
49
|
[key: string]: GraphQLValue;
|
|
48
50
|
};
|
|
@@ -55,6 +57,7 @@ declare class CacheInternal {
|
|
|
55
57
|
layer: Layer;
|
|
56
58
|
toNotify?: SubscriptionSpec[];
|
|
57
59
|
applyUpdates?: boolean;
|
|
60
|
+
forceNotify?: boolean;
|
|
58
61
|
}): SubscriptionSpec[];
|
|
59
62
|
getSelection({ selection, parent, variables, }: {
|
|
60
63
|
selection: SubscriptionSelection;
|
|
@@ -82,7 +85,7 @@ declare class CacheInternal {
|
|
|
82
85
|
partial: boolean;
|
|
83
86
|
hasData: boolean;
|
|
84
87
|
};
|
|
85
|
-
extractNestedListIDs({ value, abstract, recordID, key, linkedType, fields, variables, applyUpdates, specs, layer, startingWith, }: {
|
|
88
|
+
extractNestedListIDs({ value, abstract, recordID, key, linkedType, fields, variables, applyUpdates, specs, layer, startingWith, forceNotify, }: {
|
|
86
89
|
value: GraphQLValue[];
|
|
87
90
|
recordID: string;
|
|
88
91
|
key: string;
|
|
@@ -94,6 +97,7 @@ declare class CacheInternal {
|
|
|
94
97
|
fields: SubscriptionSelection;
|
|
95
98
|
layer: Layer;
|
|
96
99
|
startingWith: number;
|
|
100
|
+
forceNotify?: boolean;
|
|
97
101
|
}): {
|
|
98
102
|
nestedIDs: LinkedList;
|
|
99
103
|
newIDs: (string | null)[];
|
|
@@ -75,7 +75,7 @@ var Cache = /** @class */ (function () {
|
|
|
75
75
|
Cache.prototype.write = function (_a) {
|
|
76
76
|
var e_1, _b;
|
|
77
77
|
var _c;
|
|
78
|
-
var layerID = _a.layer, args = __rest(_a, ["layer"]);
|
|
78
|
+
var layerID = _a.layer, _d = _a.notifySubscribers, notifySubscribers = _d === void 0 ? [] : _d, args = __rest(_a, ["layer", "notifySubscribers"]);
|
|
79
79
|
// find the correct layer
|
|
80
80
|
var layer = layerID
|
|
81
81
|
? this._internal_unstable.storage.getLayer(layerID)
|
|
@@ -86,8 +86,8 @@ var Cache = /** @class */ (function () {
|
|
|
86
86
|
// function's identity
|
|
87
87
|
var notified = [];
|
|
88
88
|
try {
|
|
89
|
-
for (var
|
|
90
|
-
var spec =
|
|
89
|
+
for (var _e = __values(subscribers.concat(notifySubscribers)), _f = _e.next(); !_f.done; _f = _e.next()) {
|
|
90
|
+
var spec = _f.value;
|
|
91
91
|
// if we haven't added the set yet
|
|
92
92
|
if (!notified.includes(spec.set)) {
|
|
93
93
|
notified.push(spec.set);
|
|
@@ -103,12 +103,12 @@ var Cache = /** @class */ (function () {
|
|
|
103
103
|
catch (e_1_1) { e_1 = { error: e_1_1 }; }
|
|
104
104
|
finally {
|
|
105
105
|
try {
|
|
106
|
-
if (
|
|
106
|
+
if (_f && !_f.done && (_b = _e.return)) _b.call(_e);
|
|
107
107
|
}
|
|
108
108
|
finally { if (e_1) throw e_1.error; }
|
|
109
109
|
}
|
|
110
110
|
// return the id to the caller so they can resolve the layer if it was optimistic
|
|
111
|
-
return
|
|
111
|
+
return subscribers;
|
|
112
112
|
};
|
|
113
113
|
// reconstruct an object with the fields/relations specified by a selection
|
|
114
114
|
Cache.prototype.read = function () {
|
|
@@ -187,7 +187,7 @@ var CacheInternal = /** @class */ (function () {
|
|
|
187
187
|
var e_2, _b;
|
|
188
188
|
var _this = this;
|
|
189
189
|
var _c;
|
|
190
|
-
var data = _a.data, selection = _a.selection, _d = _a.variables, variables = _d === void 0 ? {} : _d, _e = _a.root, root = _e === void 0 ? exports.rootID : _e, _f = _a.parent, parent = _f === void 0 ? exports.rootID : _f, _g = _a.applyUpdates, applyUpdates = _g === void 0 ? false : _g, layer = _a.layer, _h = _a.toNotify, toNotify = _h === void 0 ? [] : _h;
|
|
190
|
+
var data = _a.data, selection = _a.selection, _d = _a.variables, variables = _d === void 0 ? {} : _d, _e = _a.root, root = _e === void 0 ? exports.rootID : _e, _f = _a.parent, parent = _f === void 0 ? exports.rootID : _f, _g = _a.applyUpdates, applyUpdates = _g === void 0 ? false : _g, layer = _a.layer, _h = _a.toNotify, toNotify = _h === void 0 ? [] : _h, forceNotify = _a.forceNotify;
|
|
191
191
|
// if the cache is disabled, dont do anything
|
|
192
192
|
if (this._disabled) {
|
|
193
193
|
return [];
|
|
@@ -212,12 +212,12 @@ var CacheInternal = /** @class */ (function () {
|
|
|
212
212
|
// if the layer we are updating is the top most layer for the field
|
|
213
213
|
// then its value is "live". It is providing the current value and
|
|
214
214
|
// subscribers need to know if the value changed
|
|
215
|
-
var displayLayer =
|
|
215
|
+
var displayLayer = layer.isDisplayLayer(displayLayers);
|
|
216
216
|
// if we are writing to the display layer we need to refresh the lifetime of the value
|
|
217
217
|
if (displayLayer) {
|
|
218
218
|
this_1.lifetimes.resetLifetime(parent, key);
|
|
219
219
|
}
|
|
220
|
-
// any
|
|
220
|
+
// any scalar is defined as a field with no selection
|
|
221
221
|
if (!fields) {
|
|
222
222
|
// the value to write to the layer
|
|
223
223
|
var newValue = value;
|
|
@@ -234,7 +234,7 @@ var CacheInternal = /** @class */ (function () {
|
|
|
234
234
|
}
|
|
235
235
|
// if the value changed on a layer that impacts the current latest value
|
|
236
236
|
var valueChanged = JSON.stringify(newValue) !== JSON.stringify(previousValue);
|
|
237
|
-
if (
|
|
237
|
+
if (displayLayer && (valueChanged || forceNotify)) {
|
|
238
238
|
// we need to add the fields' subscribers to the set of callbacks
|
|
239
239
|
// we need to invoke
|
|
240
240
|
toNotify.push.apply(toNotify, __spread(currentSubcribers));
|
|
@@ -290,7 +290,7 @@ var CacheInternal = /** @class */ (function () {
|
|
|
290
290
|
// write the link to the layer
|
|
291
291
|
layer.writeLink(parent, key, linkedID);
|
|
292
292
|
// if the link target of this field changed and it was responsible for the current subscription
|
|
293
|
-
if (linkedID && displayLayer && linkChange) {
|
|
293
|
+
if (linkedID && displayLayer && (linkChange || forceNotify)) {
|
|
294
294
|
// we need to clear the subscriptions in the previous link
|
|
295
295
|
// and add them to the new link
|
|
296
296
|
if (previousValue && typeof previousValue === 'string') {
|
|
@@ -317,6 +317,7 @@ var CacheInternal = /** @class */ (function () {
|
|
|
317
317
|
toNotify: toNotify,
|
|
318
318
|
applyUpdates: applyUpdates,
|
|
319
319
|
layer: layer,
|
|
320
|
+
forceNotify: true,
|
|
320
321
|
});
|
|
321
322
|
}
|
|
322
323
|
}
|
|
@@ -373,6 +374,7 @@ var CacheInternal = /** @class */ (function () {
|
|
|
373
374
|
fields: fields,
|
|
374
375
|
layer: layer,
|
|
375
376
|
startingWith: applyUpdates && update === 'append' ? oldIDs_2.length : 0,
|
|
377
|
+
forceNotify: forceNotify,
|
|
376
378
|
}), newIDs = _j.newIDs, nestedIDs = _j.nestedIDs;
|
|
377
379
|
// if we're supposed to apply this write as an update, we need to figure out how
|
|
378
380
|
if (applyUpdates && update) {
|
|
@@ -447,7 +449,7 @@ var CacheInternal = /** @class */ (function () {
|
|
|
447
449
|
// is still valid would not be triggered
|
|
448
450
|
var contentChanged = JSON.stringify(linkedIDs) !== JSON.stringify(oldIDs_2);
|
|
449
451
|
// we need to look at the last time we saw each subscriber to check if they need to be added to the spec
|
|
450
|
-
if (contentChanged) {
|
|
452
|
+
if (contentChanged || forceNotify) {
|
|
451
453
|
toNotify.push.apply(toNotify, __spread(currentSubcribers));
|
|
452
454
|
}
|
|
453
455
|
try {
|
|
@@ -777,7 +779,7 @@ var CacheInternal = /** @class */ (function () {
|
|
|
777
779
|
CacheInternal.prototype.extractNestedListIDs = function (_a) {
|
|
778
780
|
var e_11, _b;
|
|
779
781
|
var _c;
|
|
780
|
-
var value = _a.value, abstract = _a.abstract, recordID = _a.recordID, key = _a.key, linkedType = _a.linkedType, fields = _a.fields, variables = _a.variables, applyUpdates = _a.applyUpdates, specs = _a.specs, layer = _a.layer, startingWith = _a.startingWith;
|
|
782
|
+
var value = _a.value, abstract = _a.abstract, recordID = _a.recordID, key = _a.key, linkedType = _a.linkedType, fields = _a.fields, variables = _a.variables, applyUpdates = _a.applyUpdates, specs = _a.specs, layer = _a.layer, startingWith = _a.startingWith, forceNotify = _a.forceNotify;
|
|
781
783
|
// build up the two lists
|
|
782
784
|
var nestedIDs = [];
|
|
783
785
|
var newIDs = [];
|
|
@@ -798,6 +800,7 @@ var CacheInternal = /** @class */ (function () {
|
|
|
798
800
|
specs: specs,
|
|
799
801
|
layer: layer,
|
|
800
802
|
startingWith: startingWith,
|
|
803
|
+
forceNotify: forceNotify,
|
|
801
804
|
});
|
|
802
805
|
// add the list of new ids to our list
|
|
803
806
|
newIDs.push.apply(newIDs, __spread(inner.newIDs));
|
|
@@ -849,6 +852,7 @@ var CacheInternal = /** @class */ (function () {
|
|
|
849
852
|
toNotify: specs,
|
|
850
853
|
applyUpdates: applyUpdates,
|
|
851
854
|
layer: layer,
|
|
855
|
+
forceNotify: forceNotify,
|
|
852
856
|
});
|
|
853
857
|
newIDs.push(linkedID);
|
|
854
858
|
nestedIDs[i] = linkedID;
|
|
@@ -32,6 +32,7 @@ export declare class Layer {
|
|
|
32
32
|
getOperations(id: string, field: string): Operation[] | undefined;
|
|
33
33
|
writeField(id: string, field: string, value: GraphQLField): LayerID;
|
|
34
34
|
writeLink(id: string, field: string, value: null | string | LinkedList): LayerID;
|
|
35
|
+
isDisplayLayer(displayLayers: number[]): boolean;
|
|
35
36
|
clear(): void;
|
|
36
37
|
applyDeletes(): void;
|
|
37
38
|
delete(id: string): void;
|
|
@@ -243,6 +243,7 @@ var InMemoryStorage = /** @class */ (function () {
|
|
|
243
243
|
var layer = this.data[layerIndex++];
|
|
244
244
|
// if the layer is optimistic, we can't go further
|
|
245
245
|
if (layer.optimistic) {
|
|
246
|
+
layerIndex--;
|
|
246
247
|
break;
|
|
247
248
|
}
|
|
248
249
|
// apply the layer onto our base
|
|
@@ -351,7 +352,14 @@ var Layer = /** @class */ (function () {
|
|
|
351
352
|
this.links[id] = __assign(__assign({}, this.links[id]), (_b = {}, _b[field] = value, _b));
|
|
352
353
|
return this.id;
|
|
353
354
|
};
|
|
355
|
+
Layer.prototype.isDisplayLayer = function (displayLayers) {
|
|
356
|
+
return (displayLayers.length === 0 ||
|
|
357
|
+
displayLayers.includes(this.id) ||
|
|
358
|
+
Math.max.apply(Math, __spread(displayLayers)) < this.id);
|
|
359
|
+
};
|
|
354
360
|
Layer.prototype.clear = function () {
|
|
361
|
+
// before we clear the data of the layer, look for any subscribers that need to be updated
|
|
362
|
+
// now that everything has been notified we can reset the data
|
|
355
363
|
this.links = {};
|
|
356
364
|
this.fields = {};
|
|
357
365
|
this.operations = {};
|
|
@@ -63,15 +63,15 @@ function mutation(document) {
|
|
|
63
63
|
var sessionStore = adapter_mjs_1.getSession();
|
|
64
64
|
// return an async function that sends the mutation go the server
|
|
65
65
|
return function (variables, mutationConfig) { return __awaiter(_this, void 0, void 0, function () {
|
|
66
|
-
var optimisticResponse,
|
|
66
|
+
var layer, optimisticResponse, toNotify, result, error_1;
|
|
67
67
|
return __generator(this, function (_a) {
|
|
68
68
|
switch (_a.label) {
|
|
69
69
|
case 0:
|
|
70
|
-
optimisticResponse = mutationConfig === null || mutationConfig === void 0 ? void 0 : mutationConfig.optimisticResponse;
|
|
71
70
|
layer = cache_1.default._internal_unstable.storage.createLayer(true);
|
|
72
|
-
|
|
71
|
+
optimisticResponse = mutationConfig === null || mutationConfig === void 0 ? void 0 : mutationConfig.optimisticResponse;
|
|
72
|
+
toNotify = [];
|
|
73
73
|
if (optimisticResponse) {
|
|
74
|
-
cache_1.default.write({
|
|
74
|
+
toNotify = cache_1.default.write({
|
|
75
75
|
selection: artifact.selection,
|
|
76
76
|
// make sure that any scalar values get processed into something we can cache
|
|
77
77
|
data: scalars_1.marshalSelection({
|
|
@@ -102,8 +102,14 @@ function mutation(document) {
|
|
|
102
102
|
selection: artifact.selection,
|
|
103
103
|
data: result.data,
|
|
104
104
|
variables: variables,
|
|
105
|
-
//
|
|
105
|
+
// write to the mutation's layer
|
|
106
106
|
layer: layer.id,
|
|
107
|
+
// notify any subscribers that we updated with the optimistic response
|
|
108
|
+
// in order to address situations where the optimistic update was wrong
|
|
109
|
+
notifySubscribers: toNotify,
|
|
110
|
+
// make sure that we notify subscribers for any values that we overwrite
|
|
111
|
+
// in order to address any race conditions when comparing the previous value
|
|
112
|
+
forceNotify: true,
|
|
107
113
|
});
|
|
108
114
|
// merge the layer back into the cache
|
|
109
115
|
cache_1.default._internal_unstable.storage.resolveLayer(layer.id);
|
|
@@ -7,7 +7,7 @@ import { InMemorySubscriptions } from './subscription';
|
|
|
7
7
|
export declare class Cache {
|
|
8
8
|
_internal_unstable: CacheInternal;
|
|
9
9
|
constructor(config: Config);
|
|
10
|
-
write({ layer: layerID, ...args }: {
|
|
10
|
+
write({ layer: layerID, notifySubscribers, ...args }: {
|
|
11
11
|
data: {
|
|
12
12
|
[key: string]: GraphQLValue;
|
|
13
13
|
};
|
|
@@ -16,7 +16,9 @@ export declare class Cache {
|
|
|
16
16
|
parent?: string;
|
|
17
17
|
layer?: LayerID | null;
|
|
18
18
|
applyUpdates?: boolean;
|
|
19
|
-
|
|
19
|
+
notifySubscribers?: SubscriptionSpec[];
|
|
20
|
+
forceNotify?: boolean;
|
|
21
|
+
}): SubscriptionSpec[];
|
|
20
22
|
read(...args: Parameters<CacheInternal['getSelection']>): {
|
|
21
23
|
data: GraphQLObject;
|
|
22
24
|
partial: boolean;
|
|
@@ -42,7 +44,7 @@ declare class CacheInternal {
|
|
|
42
44
|
cache: Cache;
|
|
43
45
|
lifetimes: GarbageCollector;
|
|
44
46
|
});
|
|
45
|
-
writeSelection({ data, selection, variables, root, parent, applyUpdates, layer, toNotify, }: {
|
|
47
|
+
writeSelection({ data, selection, variables, root, parent, applyUpdates, layer, toNotify, forceNotify, }: {
|
|
46
48
|
data: {
|
|
47
49
|
[key: string]: GraphQLValue;
|
|
48
50
|
};
|
|
@@ -55,6 +57,7 @@ declare class CacheInternal {
|
|
|
55
57
|
layer: Layer;
|
|
56
58
|
toNotify?: SubscriptionSpec[];
|
|
57
59
|
applyUpdates?: boolean;
|
|
60
|
+
forceNotify?: boolean;
|
|
58
61
|
}): SubscriptionSpec[];
|
|
59
62
|
getSelection({ selection, parent, variables, }: {
|
|
60
63
|
selection: SubscriptionSelection;
|
|
@@ -82,7 +85,7 @@ declare class CacheInternal {
|
|
|
82
85
|
partial: boolean;
|
|
83
86
|
hasData: boolean;
|
|
84
87
|
};
|
|
85
|
-
extractNestedListIDs({ value, abstract, recordID, key, linkedType, fields, variables, applyUpdates, specs, layer, startingWith, }: {
|
|
88
|
+
extractNestedListIDs({ value, abstract, recordID, key, linkedType, fields, variables, applyUpdates, specs, layer, startingWith, forceNotify, }: {
|
|
86
89
|
value: GraphQLValue[];
|
|
87
90
|
recordID: string;
|
|
88
91
|
key: string;
|
|
@@ -94,6 +97,7 @@ declare class CacheInternal {
|
|
|
94
97
|
fields: SubscriptionSelection;
|
|
95
98
|
layer: Layer;
|
|
96
99
|
startingWith: number;
|
|
100
|
+
forceNotify?: boolean;
|
|
97
101
|
}): {
|
|
98
102
|
nestedIDs: LinkedList;
|
|
99
103
|
newIDs: (string | null)[];
|