graphql-persisted 0.0.5 → 0.0.6
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/cjs/GraphQLQueryCache.d.ts +46 -2
- package/cjs/GraphQLQueryCache.js +204 -221
- package/cjs/graphqlHooks.js +10 -2
- package/cjs/types.d.ts +1 -1
- package/mjs/GraphQLQueryCache.d.ts +46 -2
- package/mjs/GraphQLQueryCache.js +203 -221
- package/mjs/graphqlHooks.js +10 -2
- package/mjs/types.d.ts +1 -1
- package/package.json +2 -2
|
@@ -1,10 +1,33 @@
|
|
|
1
|
-
import
|
|
1
|
+
import { NormalizeMetaShape } from 'graphql-normalize';
|
|
2
|
+
import type { GraphQLCacheShape, GraphQLMutationResult, GraphQLOperationResult, GraphQLQueryCacheConfig, GraphQLQueryResult, GraphQLRequestBody, InvalidateQueryArgs, MaybePromise, ExecutionOptions, PersistedQueryOptions, ReadQueryArgs, SerializedVariables, SubscribeToQueryArgs, PreloadQueryOptions } from './types';
|
|
2
3
|
/**
|
|
3
4
|
* Manages the cached normalized state, and the execution of
|
|
4
5
|
* data accessed by different components
|
|
5
6
|
*/
|
|
6
7
|
export declare class GraphQLQueryCache {
|
|
7
|
-
|
|
8
|
+
/**
|
|
9
|
+
* If an alterative fetch is provided, we will use that for operations
|
|
10
|
+
* Otherwise we'll use the native 'fetch'
|
|
11
|
+
*/
|
|
12
|
+
private _fetcher?;
|
|
13
|
+
/**
|
|
14
|
+
* GraphQL API endpoint
|
|
15
|
+
* @default /graphql
|
|
16
|
+
*/
|
|
17
|
+
private _endpoint;
|
|
18
|
+
private _persistedOperations;
|
|
19
|
+
private _persistedDocuments?;
|
|
20
|
+
private _configMeta?;
|
|
21
|
+
private _subscribedQueries;
|
|
22
|
+
private _inFlight;
|
|
23
|
+
private _cacheStore;
|
|
24
|
+
private _runtimeCache;
|
|
25
|
+
private _queryInvalidation;
|
|
26
|
+
private _mutationInvalidation;
|
|
27
|
+
/**
|
|
28
|
+
* A list of all "effects" that have run, used to keep track of
|
|
29
|
+
*/
|
|
30
|
+
private _effectsIssued;
|
|
8
31
|
constructor(config: GraphQLQueryCacheConfig);
|
|
9
32
|
/**
|
|
10
33
|
* Invalidates a query by name or predicate fn
|
|
@@ -53,10 +76,31 @@ export declare class GraphQLQueryCache {
|
|
|
53
76
|
*/
|
|
54
77
|
executeQuery<Q extends keyof GraphQLQuery.QueryRegistry>(queryName: Q, variables: SerializedVariables | GraphQLQuery.OperationVariables[Q]): Promise<GraphQLQueryResult<Q>>;
|
|
55
78
|
executeSubscription(): Promise<void>;
|
|
79
|
+
_getKey(operationName: string, variables: SerializedVariables | object): string;
|
|
56
80
|
/**
|
|
57
81
|
* "Subscribes" to a query, meaning that when there are updates to fields in the
|
|
58
82
|
* field cache, we'll re-materialize the known value of the query. We'll also
|
|
59
83
|
* process based on configuration options, such as TTL, invalidateOnMutation
|
|
60
84
|
*/
|
|
61
85
|
subscribeToQuery<Q extends keyof GraphQLQuery.QueryRegistry>(args: SubscribeToQueryArgs<Q>): () => void;
|
|
86
|
+
_executeOperation<QueryName extends keyof GraphQLQuery.QueryRegistry>(operationType: 'query', operationName: QueryName, variables: SerializedVariables | GraphQLQuery.OperationVariables[QueryName], options?: PersistedQueryOptions): Promise<GraphQLQueryResult<QueryName>>;
|
|
87
|
+
_executeOperation<MutationName extends keyof GraphQLQuery.MutationRegistry>(operationType: 'mutation', operationName: MutationName, variables: SerializedVariables | object, options?: ExecutionOptions): Promise<GraphQLMutationResult<MutationName>>;
|
|
88
|
+
_getMeta(opName: string): NormalizeMetaShape;
|
|
89
|
+
/**
|
|
90
|
+
* Handles "fetch", ensuring we catch network errors and handle non-200
|
|
91
|
+
* responses properly so we're able to forward these on in a normalized fashion
|
|
92
|
+
*/
|
|
93
|
+
_fetch(body: GraphQLRequestBody): Promise<GraphQLOperationResult<any>>;
|
|
94
|
+
_makeFetch(body: GraphQLRequestBody): Promise<Response>;
|
|
95
|
+
/**
|
|
96
|
+
* Determine whether we should refetch the query based on the
|
|
97
|
+
* current value of the query, and the options passed to the query
|
|
98
|
+
*/
|
|
99
|
+
_shouldRefetchQuery(): void;
|
|
100
|
+
/**
|
|
101
|
+
* "Garbage collection" for existing operations. If they have
|
|
102
|
+
* a TTL or are invalidated by other operations, and aren't mounted,
|
|
103
|
+
* then we can go ahead and sweep out any data we might have for them
|
|
104
|
+
*/
|
|
105
|
+
_gcOperations(): void;
|
|
62
106
|
}
|
package/cjs/GraphQLQueryCache.js
CHANGED
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
-
var _GraphQLQueryCache_instances, _GraphQLQueryCache_fetcher, _GraphQLQueryCache_endpoint, _GraphQLQueryCache_persistedOperations, _GraphQLQueryCache_persistedDocuments, _GraphQLQueryCache_configMeta, _GraphQLQueryCache_subscribedQueries, _GraphQLQueryCache_inFlight, _GraphQLQueryCache_cacheStore, _GraphQLQueryCache_runtimeCache, _GraphQLQueryCache_queryInvalidation, _GraphQLQueryCache_mutationInvalidation, _GraphQLQueryCache_effectsIssued, _GraphQLQueryCache_getKey, _GraphQLQueryCache_executeOperation, _GraphQLQueryCache_getMeta, _GraphQLQueryCache_fetch, _GraphQLQueryCache_makeFetch, _GraphQLQueryCache_shouldRefetchQuery, _GraphQLQueryCache_gcOperations;
|
|
3
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
4
3
|
exports.GraphQLQueryCache = void 0;
|
|
5
4
|
const tslib_1 = require("tslib");
|
|
@@ -14,67 +13,38 @@ const helpers_1 = require("./helpers");
|
|
|
14
13
|
*/
|
|
15
14
|
class GraphQLQueryCache {
|
|
16
15
|
constructor(config) {
|
|
17
|
-
_GraphQLQueryCache_instances.add(this);
|
|
18
|
-
/**
|
|
19
|
-
* If an alterative fetch is provided, we will use that for operations
|
|
20
|
-
* Otherwise we'll use the native 'fetch'
|
|
21
|
-
*/
|
|
22
|
-
_GraphQLQueryCache_fetcher.set(this, void 0);
|
|
23
|
-
/**
|
|
24
|
-
* GraphQL API endpoint
|
|
25
|
-
* @default /graphql
|
|
26
|
-
*/
|
|
27
|
-
_GraphQLQueryCache_endpoint.set(this, void 0);
|
|
28
|
-
// A mapping of OperationName -> Operation Hash. The operation hash is sent to the
|
|
29
|
-
// server when we issue a query
|
|
30
|
-
_GraphQLQueryCache_persistedOperations.set(this, void 0);
|
|
31
|
-
// Mapping of persisted documents
|
|
32
|
-
_GraphQLQueryCache_persistedDocuments.set(this, void 0);
|
|
33
|
-
// A mapping of metadata between the config string and normalized metadata shape
|
|
34
|
-
_GraphQLQueryCache_configMeta.set(this, void 0);
|
|
35
16
|
// All queries we are "subscribed to", meaning that we React to any changes
|
|
36
17
|
// when there are updates to the cache.
|
|
37
|
-
|
|
18
|
+
this._subscribedQueries = {};
|
|
38
19
|
// All "in-flight" fetches, to deduplicate fetches that are already in-flight
|
|
39
20
|
// for an operation
|
|
40
|
-
|
|
41
|
-
// All "in-flight" fetches, to deduplicate fetches that are already in-flight
|
|
42
|
-
// for an operation
|
|
43
|
-
_GraphQLQueryCache_inFlight.set(this, {}
|
|
44
|
-
// Immutable object containing the normalized cache of all data
|
|
45
|
-
// as well as all operations we're tracking within the application
|
|
46
|
-
);
|
|
47
|
-
// Immutable object containing the normalized cache of all data
|
|
48
|
-
// as well as all operations we're tracking within the application
|
|
49
|
-
_GraphQLQueryCache_cacheStore.set(this, void 0);
|
|
21
|
+
this._inFlight = {};
|
|
50
22
|
// Keeps track of all the operations that have been issued in the application,
|
|
51
23
|
// as well as the metadata indicating the TTL / polling / invalidation / refetch
|
|
52
24
|
// logic necessary to keep things up to date
|
|
53
|
-
|
|
54
|
-
_GraphQLQueryCache_queryInvalidation.set(this, void 0);
|
|
55
|
-
_GraphQLQueryCache_mutationInvalidation.set(this, void 0);
|
|
25
|
+
this._runtimeCache = {};
|
|
56
26
|
/**
|
|
57
27
|
* A list of all "effects" that have run, used to keep track of
|
|
58
28
|
*/
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
29
|
+
this._effectsIssued = []; // TODO: Include subscriptions
|
|
30
|
+
this._fetcher = config.fetcher;
|
|
31
|
+
this._endpoint = config.endpoint || `/graphql`;
|
|
32
|
+
this._persistedOperations = config.persistedOperations;
|
|
33
|
+
this._persistedDocuments = config.persistedDocuments;
|
|
34
|
+
this._configMeta = unwrapMeta(config.meta);
|
|
35
|
+
this._queryInvalidation = config.queryInvalidation ?? {};
|
|
36
|
+
this._mutationInvalidation = config.mutationInvalidation ?? {};
|
|
37
|
+
this._cacheStore = (0, immer_1.produce)(config.hydratedCache ?? {
|
|
68
38
|
meta: {},
|
|
69
39
|
fields: {},
|
|
70
40
|
operations: {},
|
|
71
|
-
}, noop)
|
|
41
|
+
}, noop);
|
|
72
42
|
}
|
|
73
43
|
/**
|
|
74
44
|
* Invalidates a query by name or predicate fn
|
|
75
45
|
*/
|
|
76
46
|
invalidateQuery(toInvalidate) {
|
|
77
|
-
(0, immer_1.produce)(
|
|
47
|
+
(0, immer_1.produce)(this._runtimeCache, () => {
|
|
78
48
|
//
|
|
79
49
|
});
|
|
80
50
|
}
|
|
@@ -82,7 +52,7 @@ class GraphQLQueryCache {
|
|
|
82
52
|
* Invalidates a query by name or predicate fn
|
|
83
53
|
*/
|
|
84
54
|
refetchQuery(toRefetch) {
|
|
85
|
-
(0, immer_1.produce)(
|
|
55
|
+
(0, immer_1.produce)(this._runtimeCache, () => {
|
|
86
56
|
//
|
|
87
57
|
});
|
|
88
58
|
}
|
|
@@ -91,7 +61,7 @@ class GraphQLQueryCache {
|
|
|
91
61
|
* to rehydrate the Client
|
|
92
62
|
*/
|
|
93
63
|
toJSON() {
|
|
94
|
-
const { fields, operations, meta } =
|
|
64
|
+
const { fields, operations, meta } = this._cacheStore;
|
|
95
65
|
return {
|
|
96
66
|
fields,
|
|
97
67
|
operations: operations,
|
|
@@ -105,7 +75,7 @@ class GraphQLQueryCache {
|
|
|
105
75
|
// queryName: Q,
|
|
106
76
|
// variable: SerializedVariables | GraphQLQuery.OperationVariables[Q]
|
|
107
77
|
// ) {
|
|
108
|
-
// // Object.values(this
|
|
78
|
+
// // Object.values(this._cacheStore.operations).find((o) => {
|
|
109
79
|
// // return o.operationType === 'query' && o
|
|
110
80
|
// // })
|
|
111
81
|
// }
|
|
@@ -129,19 +99,19 @@ class GraphQLQueryCache {
|
|
|
129
99
|
*/
|
|
130
100
|
readQuery(args) {
|
|
131
101
|
const { queryName, variables, options } = args;
|
|
132
|
-
const key =
|
|
133
|
-
const op =
|
|
102
|
+
const key = this._getKey(queryName, variables);
|
|
103
|
+
const op = this._cacheStore.operations[key];
|
|
134
104
|
if (op) {
|
|
135
105
|
return op;
|
|
136
106
|
}
|
|
137
107
|
// If we don't have metadata, we can't know how to read the query
|
|
138
108
|
// from the cache
|
|
139
|
-
const meta =
|
|
109
|
+
const meta = this._getMeta(queryName);
|
|
140
110
|
const { result } = (0, graphql_normalize_1.graphqlNormalize)({
|
|
141
111
|
action: 'read',
|
|
142
112
|
variableValues: typeof variables === 'string' ? JSON.parse(variables) : variables,
|
|
143
113
|
meta: meta,
|
|
144
|
-
cache:
|
|
114
|
+
cache: this._cacheStore.fields,
|
|
145
115
|
isEqual: lodash_isequal_1.default,
|
|
146
116
|
});
|
|
147
117
|
return {
|
|
@@ -176,9 +146,9 @@ class GraphQLQueryCache {
|
|
|
176
146
|
preloadQuery(queryName, options) {
|
|
177
147
|
const { blockIfStale = true } = options;
|
|
178
148
|
const variables = (0, helpers_1.variableString)(options.variables ?? {});
|
|
179
|
-
const sha256Hash =
|
|
149
|
+
const sha256Hash = this._persistedOperations[queryName];
|
|
180
150
|
const key = `${sha256Hash}:${variables}`;
|
|
181
|
-
const operation =
|
|
151
|
+
const operation = this._cacheStore.operations[key];
|
|
182
152
|
// TODO: Give an option to eager return if we already have the operation but it's stale
|
|
183
153
|
if (!operation || operation.stale) {
|
|
184
154
|
const inFlight = this.fetchQuery({ queryName, variables: variables, options: {} });
|
|
@@ -187,23 +157,27 @@ class GraphQLQueryCache {
|
|
|
187
157
|
return operation;
|
|
188
158
|
}
|
|
189
159
|
fetchQuery(args) {
|
|
190
|
-
return
|
|
160
|
+
return this._executeOperation('query', args.queryName, args.variables, args.options);
|
|
191
161
|
}
|
|
192
162
|
/**
|
|
193
163
|
* Executes a mutation, returning the result of that mutation
|
|
194
164
|
*/
|
|
195
165
|
async executeMutation(mutationName, variables, options = {}) {
|
|
196
|
-
return
|
|
166
|
+
return this._executeOperation('mutation', mutationName, variables, options);
|
|
197
167
|
}
|
|
198
168
|
/**
|
|
199
169
|
* Executes a query, returning the result of that query
|
|
200
170
|
*/
|
|
201
171
|
async executeQuery(queryName, variables) {
|
|
202
|
-
return
|
|
172
|
+
return this._executeOperation('query', queryName, variables);
|
|
203
173
|
}
|
|
204
174
|
async executeSubscription() {
|
|
205
175
|
throw new Error('Not yet supported');
|
|
206
176
|
}
|
|
177
|
+
_getKey(operationName, variables) {
|
|
178
|
+
const sha256Hash = this._persistedOperations[operationName];
|
|
179
|
+
return `${sha256Hash}:${(0, helpers_1.variableString)(variables)}`;
|
|
180
|
+
}
|
|
207
181
|
/**
|
|
208
182
|
* "Subscribes" to a query, meaning that when there are updates to fields in the
|
|
209
183
|
* field cache, we'll re-materialize the known value of the query. We'll also
|
|
@@ -212,208 +186,217 @@ class GraphQLQueryCache {
|
|
|
212
186
|
subscribeToQuery(args) {
|
|
213
187
|
var _a;
|
|
214
188
|
const { queryName, queryResult, variables, onUpdate, options } = args;
|
|
215
|
-
const key =
|
|
216
|
-
const queries = ((_a =
|
|
189
|
+
const key = this._getKey(queryName, variables);
|
|
190
|
+
const queries = ((_a = this._subscribedQueries)[key] ?? (_a[key] = []));
|
|
217
191
|
queries.push(args);
|
|
218
192
|
// Now that the component is subscribed, we can begin fetching,
|
|
219
193
|
// refetching, and otherwise managing the query
|
|
220
194
|
if (!queryResult) {
|
|
221
|
-
|
|
195
|
+
this.readOrFetchQuery(args);
|
|
222
196
|
}
|
|
223
197
|
else if (options.ttl) {
|
|
224
198
|
//
|
|
225
199
|
}
|
|
226
|
-
// this.fetchQuery(args)
|
|
227
200
|
return () => {
|
|
228
201
|
queries.splice(queries.indexOf(args), 1);
|
|
229
202
|
};
|
|
230
203
|
}
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
operationName,
|
|
248
|
-
variables: operationVariables,
|
|
249
|
-
extensions: {
|
|
250
|
-
persistedQuery: { version: 1, sha256Hash },
|
|
251
|
-
},
|
|
252
|
-
});
|
|
253
|
-
tslib_1.__classPrivateFieldGet(this, _GraphQLQueryCache_inFlight, "f")[key] = operationInFlight;
|
|
254
|
-
const operationResult = await operationInFlight.finally(() => {
|
|
255
|
-
delete tslib_1.__classPrivateFieldGet(this, _GraphQLQueryCache_inFlight, "f")[key];
|
|
256
|
-
});
|
|
257
|
-
if (operationResult.fetchError) {
|
|
258
|
-
return operationResult;
|
|
259
|
-
}
|
|
260
|
-
const meta = operationResult.extensions?.['graphqlNormalizeMeta'] ??
|
|
261
|
-
tslib_1.__classPrivateFieldGet(this, _GraphQLQueryCache_instances, "m", _GraphQLQueryCache_getMeta).call(this, operationName);
|
|
262
|
-
// Ensure we have metadata to be able to normalize the operation in our cache
|
|
263
|
-
if (!meta) {
|
|
264
|
-
throw new errors_1.MissingMetaError(operationName);
|
|
265
|
-
}
|
|
266
|
-
const lastCache = tslib_1.__classPrivateFieldGet(this, _GraphQLQueryCache_cacheStore, "f");
|
|
267
|
-
tslib_1.__classPrivateFieldSet(this, _GraphQLQueryCache_cacheStore, (0, immer_1.produce)(tslib_1.__classPrivateFieldGet(this, _GraphQLQueryCache_cacheStore, "f"), (c) => {
|
|
268
|
-
const currentResult = c.operations[key];
|
|
269
|
-
const { added, modified, result } = (0, graphql_normalize_1.graphqlNormalize)({
|
|
270
|
-
action: 'write',
|
|
271
|
-
operationResult,
|
|
272
|
-
meta,
|
|
273
|
-
cache: c.fields,
|
|
274
|
-
variableValues: operationVariables,
|
|
275
|
-
currentResult,
|
|
276
|
-
isEqual: lodash_isequal_1.default,
|
|
204
|
+
async _executeOperation(operationType, operationName, variables) {
|
|
205
|
+
const sha256Hash = this._persistedOperations[operationName];
|
|
206
|
+
const key = this._getKey(operationName, variables);
|
|
207
|
+
const operationVariables = (0, helpers_1.variableObject)(variables);
|
|
208
|
+
(0, errors_1.assertOperationHash)(sha256Hash, operationType, operationName);
|
|
209
|
+
const inFlight = this._inFlight[key];
|
|
210
|
+
if (operationType === 'query' && inFlight) {
|
|
211
|
+
return inFlight;
|
|
212
|
+
}
|
|
213
|
+
const operationInFlight = this._fetch({
|
|
214
|
+
query: '',
|
|
215
|
+
operationName,
|
|
216
|
+
variables: operationVariables,
|
|
217
|
+
extensions: {
|
|
218
|
+
persistedQuery: { version: 1, sha256Hash },
|
|
219
|
+
},
|
|
277
220
|
});
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
221
|
+
this._inFlight[key] = operationInFlight;
|
|
222
|
+
const operationResult = await operationInFlight.finally(() => {
|
|
223
|
+
delete this._inFlight[key];
|
|
224
|
+
});
|
|
225
|
+
if (operationResult.fetchError) {
|
|
226
|
+
return operationResult;
|
|
227
|
+
}
|
|
228
|
+
const meta = operationResult.extensions?.['graphqlNormalizeMeta'] ??
|
|
229
|
+
this._getMeta(operationName);
|
|
230
|
+
// Ensure we have metadata to be able to normalize the operation in our cache
|
|
231
|
+
if (!meta) {
|
|
232
|
+
throw new errors_1.MissingMetaError(operationName);
|
|
233
|
+
}
|
|
234
|
+
const lastCache = this._cacheStore;
|
|
235
|
+
this._cacheStore = (0, immer_1.produce)(this._cacheStore, (c) => {
|
|
236
|
+
const currentResult = c.operations[key];
|
|
237
|
+
const { added, modified, result } = (0, graphql_normalize_1.graphqlNormalize)({
|
|
238
|
+
action: 'write',
|
|
239
|
+
operationResult,
|
|
282
240
|
meta,
|
|
283
|
-
|
|
241
|
+
cache: c.fields,
|
|
284
242
|
variableValues: operationVariables,
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
243
|
+
currentResult,
|
|
244
|
+
isEqual: lodash_isequal_1.default,
|
|
245
|
+
});
|
|
246
|
+
//
|
|
247
|
+
if (operationType === 'query' && (added || modified)) {
|
|
248
|
+
c.operations[key] = {
|
|
249
|
+
stale: false,
|
|
250
|
+
meta,
|
|
251
|
+
operationName,
|
|
252
|
+
variableValues: operationVariables,
|
|
253
|
+
data: result,
|
|
254
|
+
errors: operationResult.errors,
|
|
255
|
+
extensions: operationResult.extensions,
|
|
256
|
+
operationType: operationType,
|
|
257
|
+
};
|
|
258
|
+
}
|
|
259
|
+
// If we've modified anything in the cache, we also need to update any
|
|
260
|
+
// mounted queries
|
|
261
|
+
if (modified) {
|
|
262
|
+
for (const [k, val] of Object.entries(c.operations)) {
|
|
263
|
+
if (k === key || val.operationType !== 'query') {
|
|
264
|
+
continue;
|
|
265
|
+
}
|
|
266
|
+
//
|
|
267
|
+
if (val.data) {
|
|
268
|
+
const { result } = (0, graphql_normalize_1.graphqlNormalize)({
|
|
269
|
+
action: 'read',
|
|
270
|
+
currentResult: val.data,
|
|
271
|
+
cache: c.fields,
|
|
272
|
+
meta: val.meta,
|
|
273
|
+
variableValues: val.variableValues,
|
|
274
|
+
});
|
|
275
|
+
if (result !== val) {
|
|
276
|
+
val.data = result;
|
|
277
|
+
}
|
|
309
278
|
}
|
|
310
279
|
}
|
|
311
280
|
}
|
|
312
|
-
}
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
281
|
+
});
|
|
282
|
+
// If this was a mutation, we need to go through and determine if we need to mark
|
|
283
|
+
// any Queries as "stale", or eagerly refetch any of the queries
|
|
284
|
+
if (operationType === 'mutation') {
|
|
285
|
+
const toInvalidate = new Set();
|
|
286
|
+
const mutationName = operationName;
|
|
287
|
+
const mutationFn = this._mutationInvalidation?.[mutationName];
|
|
288
|
+
for (const [operationKey, operation] of Object.entries(this._cacheStore.operations)) {
|
|
289
|
+
if (operation.operationType !== 'query') {
|
|
290
|
+
continue;
|
|
291
|
+
}
|
|
292
|
+
const queryName = operation.operationName;
|
|
293
|
+
const queryVariables = operation.variableValues;
|
|
294
|
+
const queryFn = this._queryInvalidation[queryName];
|
|
295
|
+
if (queryFn?.(mutationName, operationVariables, queryVariables)) {
|
|
296
|
+
toInvalidate.add(operationKey);
|
|
297
|
+
}
|
|
298
|
+
if (mutationFn?.(queryName, queryVariables, operationVariables)) {
|
|
299
|
+
toInvalidate.add(operationKey);
|
|
300
|
+
}
|
|
329
301
|
}
|
|
330
|
-
if (
|
|
331
|
-
|
|
302
|
+
if (toInvalidate.size) {
|
|
303
|
+
this._cacheStore = (0, immer_1.produce)(this._cacheStore, (o) => {
|
|
304
|
+
for (const key of toInvalidate) {
|
|
305
|
+
const op = o.operations[key];
|
|
306
|
+
if (op)
|
|
307
|
+
op.stale = true;
|
|
308
|
+
}
|
|
309
|
+
});
|
|
332
310
|
}
|
|
333
311
|
}
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
if (
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
}), "f");
|
|
342
|
-
}
|
|
343
|
-
}
|
|
344
|
-
// If we've updated any operations, we need to update any subscribed components
|
|
345
|
-
if (lastCache.operations !== tslib_1.__classPrivateFieldGet(this, _GraphQLQueryCache_cacheStore, "f").operations) {
|
|
346
|
-
for (const [key, val] of Object.entries(tslib_1.__classPrivateFieldGet(this, _GraphQLQueryCache_cacheStore, "f").operations)) {
|
|
347
|
-
if (tslib_1.__classPrivateFieldGet(this, _GraphQLQueryCache_cacheStore, "f").operations[key] !== lastCache.operations[key]) {
|
|
348
|
-
if (tslib_1.__classPrivateFieldGet(this, _GraphQLQueryCache_subscribedQueries, "f")[key]) {
|
|
349
|
-
tslib_1.__classPrivateFieldGet(this, _GraphQLQueryCache_subscribedQueries, "f")[key]?.forEach((o) => o.onUpdate(val));
|
|
312
|
+
// If we've updated any operations, we need to update any subscribed components
|
|
313
|
+
if (lastCache.operations !== this._cacheStore.operations) {
|
|
314
|
+
for (const [key, val] of Object.entries(this._cacheStore.operations)) {
|
|
315
|
+
if (this._cacheStore.operations[key] !== lastCache.operations[key]) {
|
|
316
|
+
if (this._subscribedQueries[key]) {
|
|
317
|
+
this._subscribedQueries[key]?.forEach((o) => o.onUpdate(val));
|
|
318
|
+
}
|
|
350
319
|
}
|
|
351
320
|
}
|
|
352
321
|
}
|
|
322
|
+
if (operationType === 'query') {
|
|
323
|
+
return this._cacheStore.operations[key];
|
|
324
|
+
}
|
|
325
|
+
return operationResult;
|
|
353
326
|
}
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
}
|
|
359
|
-
|
|
360
|
-
if (!meta) {
|
|
361
|
-
throw new errors_1.MissingMetaError(opName);
|
|
327
|
+
_getMeta(opName) {
|
|
328
|
+
const meta = this._cacheStore.meta[opName] ?? this._configMeta?.[opName];
|
|
329
|
+
if (!meta) {
|
|
330
|
+
throw new errors_1.MissingMetaError(opName);
|
|
331
|
+
}
|
|
332
|
+
return meta;
|
|
362
333
|
}
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
334
|
+
/**
|
|
335
|
+
* Handles "fetch", ensuring we catch network errors and handle non-200
|
|
336
|
+
* responses properly so we're able to forward these on in a normalized fashion
|
|
337
|
+
*/
|
|
338
|
+
async _fetch(body) {
|
|
339
|
+
let result;
|
|
340
|
+
try {
|
|
341
|
+
result = await this._makeFetch(body);
|
|
342
|
+
if (result.status === 200) {
|
|
343
|
+
const json = (await result.json());
|
|
344
|
+
return json;
|
|
345
|
+
}
|
|
346
|
+
else {
|
|
347
|
+
return {
|
|
348
|
+
fetchError: {
|
|
349
|
+
name: 'ResponseError',
|
|
350
|
+
message: await result.text(),
|
|
351
|
+
status: result.status,
|
|
352
|
+
statusText: result.statusText,
|
|
353
|
+
},
|
|
354
|
+
};
|
|
355
|
+
}
|
|
376
356
|
}
|
|
377
|
-
|
|
357
|
+
catch (e) {
|
|
358
|
+
const error = e instanceof Error ? e : new Error(String(e));
|
|
378
359
|
return {
|
|
379
360
|
fetchError: {
|
|
380
|
-
name:
|
|
381
|
-
message:
|
|
382
|
-
|
|
383
|
-
|
|
361
|
+
name: error.name,
|
|
362
|
+
message: error.message,
|
|
363
|
+
stack: error.stack,
|
|
364
|
+
status: result?.status,
|
|
365
|
+
statusText: result?.statusText,
|
|
384
366
|
},
|
|
385
367
|
};
|
|
386
368
|
}
|
|
387
369
|
}
|
|
388
|
-
|
|
389
|
-
const
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
stack: error.stack,
|
|
395
|
-
status: result?.status,
|
|
396
|
-
statusText: result?.statusText,
|
|
370
|
+
_makeFetch(body) {
|
|
371
|
+
const reqInit = {
|
|
372
|
+
method: 'POST',
|
|
373
|
+
body: JSON.stringify(body),
|
|
374
|
+
headers: {
|
|
375
|
+
'content-type': 'application/json',
|
|
397
376
|
},
|
|
398
377
|
};
|
|
378
|
+
if (this._fetcher) {
|
|
379
|
+
return this._fetcher(this._endpoint, reqInit);
|
|
380
|
+
}
|
|
381
|
+
return fetch(this._endpoint, reqInit);
|
|
382
|
+
}
|
|
383
|
+
/**
|
|
384
|
+
* Determine whether we should refetch the query based on the
|
|
385
|
+
* current value of the query, and the options passed to the query
|
|
386
|
+
*/
|
|
387
|
+
_shouldRefetchQuery() {
|
|
388
|
+
//
|
|
399
389
|
}
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
};
|
|
408
|
-
if (tslib_1.__classPrivateFieldGet(this, _GraphQLQueryCache_fetcher, "f")) {
|
|
409
|
-
return tslib_1.__classPrivateFieldGet(this, _GraphQLQueryCache_fetcher, "f").call(this, tslib_1.__classPrivateFieldGet(this, _GraphQLQueryCache_endpoint, "f"), reqInit);
|
|
390
|
+
/**
|
|
391
|
+
* "Garbage collection" for existing operations. If they have
|
|
392
|
+
* a TTL or are invalidated by other operations, and aren't mounted,
|
|
393
|
+
* then we can go ahead and sweep out any data we might have for them
|
|
394
|
+
*/
|
|
395
|
+
_gcOperations() {
|
|
396
|
+
//
|
|
410
397
|
}
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
//
|
|
414
|
-
}, _GraphQLQueryCache_gcOperations = function _GraphQLQueryCache_gcOperations() {
|
|
415
|
-
//
|
|
416
|
-
};
|
|
398
|
+
}
|
|
399
|
+
exports.GraphQLQueryCache = GraphQLQueryCache;
|
|
417
400
|
function unwrapMeta(meta) {
|
|
418
401
|
if (!meta)
|
|
419
402
|
return meta;
|