@envelop/response-cache 8.2.0-alpha-20251013081815-d6f74fceb1a32fd336b2664f90f87872e1bbf2fe → 10.0.0-alpha-20251211205538-5005189af5ce4a47150dc63ed3732eee84998197
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/plugin.js +42 -40
- package/esm/plugin.js +42 -40
- package/package.json +2 -2
package/cjs/plugin.js
CHANGED
|
@@ -233,9 +233,11 @@ function useResponseCache({ cache = (0, in_memory_cache_js_1.createInMemoryCache
|
|
|
233
233
|
}
|
|
234
234
|
}
|
|
235
235
|
function invalidateCache(result, setResult) {
|
|
236
|
+
let changed = false;
|
|
236
237
|
if (result.data) {
|
|
237
|
-
|
|
238
|
-
|
|
238
|
+
result = { ...result };
|
|
239
|
+
result.data = removeMetadataFieldsFromResult(result.data, onEntity);
|
|
240
|
+
changed = true;
|
|
239
241
|
}
|
|
240
242
|
const cacheInstance = cacheFactory(onExecuteParams.args.contextValue);
|
|
241
243
|
if (cacheInstance == null) {
|
|
@@ -251,6 +253,9 @@ function useResponseCache({ cache = (0, in_memory_cache_js_1.createInMemoryCache
|
|
|
251
253
|
}));
|
|
252
254
|
}
|
|
253
255
|
}
|
|
256
|
+
if (changed) {
|
|
257
|
+
setResult(result);
|
|
258
|
+
}
|
|
254
259
|
}
|
|
255
260
|
if (invalidateViaMutation !== false) {
|
|
256
261
|
const operationAST = (0, graphql_1.getOperationAST)(onExecuteParams.args.document, onExecuteParams.args.operationName);
|
|
@@ -291,8 +296,7 @@ function useResponseCache({ cache = (0, in_memory_cache_js_1.createInMemoryCache
|
|
|
291
296
|
}
|
|
292
297
|
function maybeCacheResult(result, setResult) {
|
|
293
298
|
if (result.data) {
|
|
294
|
-
|
|
295
|
-
setStringifyWithoutMetadata(result);
|
|
299
|
+
result.data = removeMetadataFieldsFromResult(result.data, onEntity);
|
|
296
300
|
}
|
|
297
301
|
// we only use the global ttl if no currentTtl has been determined.
|
|
298
302
|
let finalTtl = currentTtl ?? globalTtl;
|
|
@@ -340,7 +344,7 @@ function handleAsyncIterableResult(handler) {
|
|
|
340
344
|
onNext(payload) {
|
|
341
345
|
// This is the first result with the initial data payload sent to the client. We use it as the base result
|
|
342
346
|
if (payload.result.data) {
|
|
343
|
-
result.data =
|
|
347
|
+
result.data = payload.result.data;
|
|
344
348
|
}
|
|
345
349
|
if (payload.result.errors) {
|
|
346
350
|
result.errors = payload.result.errors;
|
|
@@ -352,10 +356,7 @@ function handleAsyncIterableResult(handler) {
|
|
|
352
356
|
const { incremental, hasNext } = payload.result;
|
|
353
357
|
if (incremental) {
|
|
354
358
|
for (const patch of incremental) {
|
|
355
|
-
(0, utils_1.mergeIncrementalResult)({
|
|
356
|
-
executionResult: result,
|
|
357
|
-
incrementalResult: structuredClone(patch),
|
|
358
|
-
});
|
|
359
|
+
(0, utils_1.mergeIncrementalResult)({ executionResult: result, incrementalResult: patch });
|
|
359
360
|
}
|
|
360
361
|
}
|
|
361
362
|
if (!hasNext) {
|
|
@@ -363,22 +364,30 @@ function handleAsyncIterableResult(handler) {
|
|
|
363
364
|
handler(result, payload.setResult);
|
|
364
365
|
}
|
|
365
366
|
}
|
|
366
|
-
|
|
367
|
-
|
|
367
|
+
const newResult = { ...payload.result };
|
|
368
|
+
// Handle initial/single result
|
|
369
|
+
if (newResult.data) {
|
|
370
|
+
newResult.data = removeMetadataFieldsFromResult(newResult.data);
|
|
368
371
|
}
|
|
369
372
|
// Handle Incremental results
|
|
370
|
-
if ('hasNext' in
|
|
371
|
-
|
|
373
|
+
if ('hasNext' in newResult && newResult.incremental) {
|
|
374
|
+
newResult.incremental = newResult.incremental.map(value => {
|
|
372
375
|
if ('items' in value && value.items) {
|
|
373
|
-
|
|
376
|
+
return {
|
|
377
|
+
...value,
|
|
378
|
+
items: removeMetadataFieldsFromResult(value.items),
|
|
379
|
+
};
|
|
374
380
|
}
|
|
375
381
|
if ('data' in value && value.data) {
|
|
376
|
-
|
|
382
|
+
return {
|
|
383
|
+
...value,
|
|
384
|
+
data: removeMetadataFieldsFromResult(value.data),
|
|
385
|
+
};
|
|
377
386
|
}
|
|
378
387
|
return value;
|
|
379
388
|
});
|
|
380
389
|
}
|
|
381
|
-
|
|
390
|
+
payload.setResult(newResult);
|
|
382
391
|
},
|
|
383
392
|
};
|
|
384
393
|
}
|
|
@@ -423,45 +432,38 @@ exports.cacheControlDirective = `
|
|
|
423
432
|
|
|
424
433
|
directive @cacheControl(maxAge: Int, scope: CacheControlScope) on FIELD_DEFINITION | OBJECT
|
|
425
434
|
`;
|
|
426
|
-
function
|
|
435
|
+
function removeMetadataFieldsFromResult(data, onEntity) {
|
|
427
436
|
if (Array.isArray(data)) {
|
|
428
|
-
|
|
429
|
-
collectEntities(record, onEntity);
|
|
430
|
-
}
|
|
431
|
-
return;
|
|
437
|
+
return data.map(record => removeMetadataFieldsFromResult(record, onEntity));
|
|
432
438
|
}
|
|
433
439
|
if (typeof data !== 'object' || data == null) {
|
|
434
|
-
return;
|
|
440
|
+
return data;
|
|
435
441
|
}
|
|
436
442
|
const dataPrototype = Object.getPrototypeOf(data);
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
// As a workaround, we can just check that there is no parent prototype, which should be
|
|
440
|
-
// the case only when it's the Object prototype
|
|
441
|
-
// Rollback once migrated to Bun or vitest
|
|
442
|
-
//
|
|
443
|
-
// if (dataPrototype != null && dataPrototype !== Object.prototype) {
|
|
444
|
-
if (dataPrototype != null && Object.getPrototypeOf(dataPrototype) !== null) {
|
|
445
|
-
// It is not a plain object, like a Date, don't inspect further
|
|
446
|
-
return;
|
|
443
|
+
if (dataPrototype != null && dataPrototype !== Object.prototype) {
|
|
444
|
+
return data;
|
|
447
445
|
}
|
|
446
|
+
// clone the data to avoid mutation
|
|
447
|
+
data = { ...data };
|
|
448
448
|
const typename = data.__responseCacheTypeName ?? data.__typename;
|
|
449
449
|
if (typeof typename === 'string') {
|
|
450
450
|
const entity = { typename };
|
|
451
|
+
delete data.__responseCacheTypeName;
|
|
451
452
|
if (data.__responseCacheId &&
|
|
452
453
|
(typeof data.__responseCacheId === 'string' || typeof data.__responseCacheId === 'number')) {
|
|
453
454
|
entity.id = data.__responseCacheId;
|
|
455
|
+
delete data.__responseCacheId;
|
|
454
456
|
}
|
|
455
457
|
onEntity?.(entity, data);
|
|
456
458
|
}
|
|
457
459
|
for (const key in data) {
|
|
458
|
-
|
|
460
|
+
const value = data[key];
|
|
461
|
+
if (Array.isArray(value)) {
|
|
462
|
+
data[key] = removeMetadataFieldsFromResult(value, onEntity);
|
|
463
|
+
}
|
|
464
|
+
if (value !== null && typeof value === 'object') {
|
|
465
|
+
data[key] = removeMetadataFieldsFromResult(value, onEntity);
|
|
466
|
+
}
|
|
459
467
|
}
|
|
468
|
+
return data;
|
|
460
469
|
}
|
|
461
|
-
function setStringifyWithoutMetadata(result) {
|
|
462
|
-
result.stringify = stringifyWithoutMetadata;
|
|
463
|
-
return result;
|
|
464
|
-
}
|
|
465
|
-
const stringifyWithoutMetadata = result => {
|
|
466
|
-
return JSON.stringify(result, (key, value) => key === '__responseCacheId' || key === '__responseCacheTypeName' ? undefined : value);
|
|
467
|
-
};
|
package/esm/plugin.js
CHANGED
|
@@ -224,9 +224,11 @@ export function useResponseCache({ cache = createInMemoryCache(), ttl: globalTtl
|
|
|
224
224
|
}
|
|
225
225
|
}
|
|
226
226
|
function invalidateCache(result, setResult) {
|
|
227
|
+
let changed = false;
|
|
227
228
|
if (result.data) {
|
|
228
|
-
|
|
229
|
-
|
|
229
|
+
result = { ...result };
|
|
230
|
+
result.data = removeMetadataFieldsFromResult(result.data, onEntity);
|
|
231
|
+
changed = true;
|
|
230
232
|
}
|
|
231
233
|
const cacheInstance = cacheFactory(onExecuteParams.args.contextValue);
|
|
232
234
|
if (cacheInstance == null) {
|
|
@@ -242,6 +244,9 @@ export function useResponseCache({ cache = createInMemoryCache(), ttl: globalTtl
|
|
|
242
244
|
}));
|
|
243
245
|
}
|
|
244
246
|
}
|
|
247
|
+
if (changed) {
|
|
248
|
+
setResult(result);
|
|
249
|
+
}
|
|
245
250
|
}
|
|
246
251
|
if (invalidateViaMutation !== false) {
|
|
247
252
|
const operationAST = getOperationAST(onExecuteParams.args.document, onExecuteParams.args.operationName);
|
|
@@ -282,8 +287,7 @@ export function useResponseCache({ cache = createInMemoryCache(), ttl: globalTtl
|
|
|
282
287
|
}
|
|
283
288
|
function maybeCacheResult(result, setResult) {
|
|
284
289
|
if (result.data) {
|
|
285
|
-
|
|
286
|
-
setStringifyWithoutMetadata(result);
|
|
290
|
+
result.data = removeMetadataFieldsFromResult(result.data, onEntity);
|
|
287
291
|
}
|
|
288
292
|
// we only use the global ttl if no currentTtl has been determined.
|
|
289
293
|
let finalTtl = currentTtl ?? globalTtl;
|
|
@@ -331,7 +335,7 @@ function handleAsyncIterableResult(handler) {
|
|
|
331
335
|
onNext(payload) {
|
|
332
336
|
// This is the first result with the initial data payload sent to the client. We use it as the base result
|
|
333
337
|
if (payload.result.data) {
|
|
334
|
-
result.data =
|
|
338
|
+
result.data = payload.result.data;
|
|
335
339
|
}
|
|
336
340
|
if (payload.result.errors) {
|
|
337
341
|
result.errors = payload.result.errors;
|
|
@@ -343,10 +347,7 @@ function handleAsyncIterableResult(handler) {
|
|
|
343
347
|
const { incremental, hasNext } = payload.result;
|
|
344
348
|
if (incremental) {
|
|
345
349
|
for (const patch of incremental) {
|
|
346
|
-
mergeIncrementalResult({
|
|
347
|
-
executionResult: result,
|
|
348
|
-
incrementalResult: structuredClone(patch),
|
|
349
|
-
});
|
|
350
|
+
mergeIncrementalResult({ executionResult: result, incrementalResult: patch });
|
|
350
351
|
}
|
|
351
352
|
}
|
|
352
353
|
if (!hasNext) {
|
|
@@ -354,22 +355,30 @@ function handleAsyncIterableResult(handler) {
|
|
|
354
355
|
handler(result, payload.setResult);
|
|
355
356
|
}
|
|
356
357
|
}
|
|
357
|
-
|
|
358
|
-
|
|
358
|
+
const newResult = { ...payload.result };
|
|
359
|
+
// Handle initial/single result
|
|
360
|
+
if (newResult.data) {
|
|
361
|
+
newResult.data = removeMetadataFieldsFromResult(newResult.data);
|
|
359
362
|
}
|
|
360
363
|
// Handle Incremental results
|
|
361
|
-
if ('hasNext' in
|
|
362
|
-
|
|
364
|
+
if ('hasNext' in newResult && newResult.incremental) {
|
|
365
|
+
newResult.incremental = newResult.incremental.map(value => {
|
|
363
366
|
if ('items' in value && value.items) {
|
|
364
|
-
|
|
367
|
+
return {
|
|
368
|
+
...value,
|
|
369
|
+
items: removeMetadataFieldsFromResult(value.items),
|
|
370
|
+
};
|
|
365
371
|
}
|
|
366
372
|
if ('data' in value && value.data) {
|
|
367
|
-
|
|
373
|
+
return {
|
|
374
|
+
...value,
|
|
375
|
+
data: removeMetadataFieldsFromResult(value.data),
|
|
376
|
+
};
|
|
368
377
|
}
|
|
369
378
|
return value;
|
|
370
379
|
});
|
|
371
380
|
}
|
|
372
|
-
|
|
381
|
+
payload.setResult(newResult);
|
|
373
382
|
},
|
|
374
383
|
};
|
|
375
384
|
}
|
|
@@ -414,45 +423,38 @@ export const cacheControlDirective = /* GraphQL */ `
|
|
|
414
423
|
|
|
415
424
|
directive @cacheControl(maxAge: Int, scope: CacheControlScope) on FIELD_DEFINITION | OBJECT
|
|
416
425
|
`;
|
|
417
|
-
function
|
|
426
|
+
function removeMetadataFieldsFromResult(data, onEntity) {
|
|
418
427
|
if (Array.isArray(data)) {
|
|
419
|
-
|
|
420
|
-
collectEntities(record, onEntity);
|
|
421
|
-
}
|
|
422
|
-
return;
|
|
428
|
+
return data.map(record => removeMetadataFieldsFromResult(record, onEntity));
|
|
423
429
|
}
|
|
424
430
|
if (typeof data !== 'object' || data == null) {
|
|
425
|
-
return;
|
|
431
|
+
return data;
|
|
426
432
|
}
|
|
427
433
|
const dataPrototype = Object.getPrototypeOf(data);
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
// As a workaround, we can just check that there is no parent prototype, which should be
|
|
431
|
-
// the case only when it's the Object prototype
|
|
432
|
-
// Rollback once migrated to Bun or vitest
|
|
433
|
-
//
|
|
434
|
-
// if (dataPrototype != null && dataPrototype !== Object.prototype) {
|
|
435
|
-
if (dataPrototype != null && Object.getPrototypeOf(dataPrototype) !== null) {
|
|
436
|
-
// It is not a plain object, like a Date, don't inspect further
|
|
437
|
-
return;
|
|
434
|
+
if (dataPrototype != null && dataPrototype !== Object.prototype) {
|
|
435
|
+
return data;
|
|
438
436
|
}
|
|
437
|
+
// clone the data to avoid mutation
|
|
438
|
+
data = { ...data };
|
|
439
439
|
const typename = data.__responseCacheTypeName ?? data.__typename;
|
|
440
440
|
if (typeof typename === 'string') {
|
|
441
441
|
const entity = { typename };
|
|
442
|
+
delete data.__responseCacheTypeName;
|
|
442
443
|
if (data.__responseCacheId &&
|
|
443
444
|
(typeof data.__responseCacheId === 'string' || typeof data.__responseCacheId === 'number')) {
|
|
444
445
|
entity.id = data.__responseCacheId;
|
|
446
|
+
delete data.__responseCacheId;
|
|
445
447
|
}
|
|
446
448
|
onEntity?.(entity, data);
|
|
447
449
|
}
|
|
448
450
|
for (const key in data) {
|
|
449
|
-
|
|
451
|
+
const value = data[key];
|
|
452
|
+
if (Array.isArray(value)) {
|
|
453
|
+
data[key] = removeMetadataFieldsFromResult(value, onEntity);
|
|
454
|
+
}
|
|
455
|
+
if (value !== null && typeof value === 'object') {
|
|
456
|
+
data[key] = removeMetadataFieldsFromResult(value, onEntity);
|
|
457
|
+
}
|
|
450
458
|
}
|
|
459
|
+
return data;
|
|
451
460
|
}
|
|
452
|
-
function setStringifyWithoutMetadata(result) {
|
|
453
|
-
result.stringify = stringifyWithoutMetadata;
|
|
454
|
-
return result;
|
|
455
|
-
}
|
|
456
|
-
const stringifyWithoutMetadata = result => {
|
|
457
|
-
return JSON.stringify(result, (key, value) => key === '__responseCacheId' || key === '__responseCacheTypeName' ? undefined : value);
|
|
458
|
-
};
|
package/package.json
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@envelop/response-cache",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "10.0.0-alpha-20251211205538-5005189af5ce4a47150dc63ed3732eee84998197",
|
|
4
4
|
"sideEffects": false,
|
|
5
5
|
"peerDependencies": {
|
|
6
6
|
"graphql": "^14.0.0 || ^15.0.0 || ^16.0.0",
|
|
7
|
-
"@envelop/core": "^5.
|
|
7
|
+
"@envelop/core": "^5.5.0-alpha-20251211205538-5005189af5ce4a47150dc63ed3732eee84998197"
|
|
8
8
|
},
|
|
9
9
|
"dependencies": {
|
|
10
10
|
"@graphql-tools/utils": "^10.0.3",
|