Mirror: The highly customizable and versatile GraphQL client with which you add on features like normalized caching as you grow.
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

fix(core): ensure operationKey is different when dealing with files (#3601)

authored by

Jovi De Croock and committed by
GitHub
ff1fd76a d7473856

+19 -10
+8
.changeset/shaggy-wasps-bow.md
··· 1 + --- 2 + '@urql/core': patch 3 + --- 4 + 5 + Change how we calculate the `OperationKey` to take files into account, before we 6 + would encode them to `null` resulting in every mutation with the same variables 7 + (excluding the files) to have the same key. This resulted in mutations that upload 8 + different files at the same time to share a result in GraphCache.
+11 -10
packages/core/src/utils/variables.ts
··· 3 3 const seen: Set<any> = new Set(); 4 4 const cache: WeakMap<any, any> = new WeakMap(); 5 5 6 - const stringify = (x: any): string => { 6 + const stringify = (x: any, includeFiles: boolean): string => { 7 7 if (x === null || seen.has(x)) { 8 8 return 'null'; 9 9 } else if (typeof x !== 'object') { 10 10 return JSON.stringify(x) || ''; 11 11 } else if (x.toJSON) { 12 - return stringify(x.toJSON()); 12 + return stringify(x.toJSON(), includeFiles); 13 13 } else if (Array.isArray(x)) { 14 14 let out = '['; 15 15 for (const value of x) { 16 16 if (out.length > 1) out += ','; 17 - out += stringify(value) || 'null'; 17 + out += stringify(value, includeFiles) || 'null'; 18 18 } 19 19 out += ']'; 20 20 return out; 21 21 } else if ( 22 - (FileConstructor !== NoopConstructor && x instanceof FileConstructor) || 23 - (BlobConstructor !== NoopConstructor && x instanceof BlobConstructor) 22 + !includeFiles && 23 + ((FileConstructor !== NoopConstructor && x instanceof FileConstructor) || 24 + (BlobConstructor !== NoopConstructor && x instanceof BlobConstructor)) 24 25 ) { 25 26 return 'null'; 26 27 } ··· 33 34 ) { 34 35 const key = cache.get(x) || Math.random().toString(36).slice(2); 35 36 cache.set(x, key); 36 - return stringify({ __key: key }); 37 + return stringify({ __key: key }, includeFiles); 37 38 } 38 39 39 40 seen.add(x); 40 41 let out = '{'; 41 42 for (const key of keys) { 42 - const value = stringify(x[key]); 43 + const value = stringify(x[key], includeFiles); 43 44 if (value) { 44 45 if (out.length > 1) out += ','; 45 - out += stringify(key) + ':' + value; 46 + out += stringify(key, includeFiles) + ':' + value; 46 47 } 47 48 } 48 49 ··· 79 80 * replacing their values, which remain stable for the objects’ 80 81 * instance. 81 82 */ 82 - export const stringifyVariables = (x: any): string => { 83 + export const stringifyVariables = (x: any, includeFiles?: boolean): string => { 83 84 seen.clear(); 84 - return stringify(x); 85 + return stringify(x, includeFiles || false); 85 86 }; 86 87 87 88 class NoopConstructor {}