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.

add includeExtensions option to ssrExchange (#1985)

authored by

David Dios and committed by
GitHub
0dfa972d 847e9884

+52 -10
+5
.changeset/tidy-tables-promise.md
··· 1 + --- 2 + '@urql/core': patch 3 + --- 4 + 5 + Adding option to `ssrExchange` to include the `extensions` field of operation results in the cache.
+1 -1
exchanges/graphcache/default-storage/package.json
··· 16 16 "./package.json": "./package.json" 17 17 }, 18 18 "dependencies": { 19 - "@urql/core": ">=2.1.5", 19 + "@urql/core": ">=2.3.2", 20 20 "wonka": "^4.0.14" 21 21 } 22 22 }
+28
packages/core/src/exchanges/ssr.test.ts
··· 116 116 }); 117 117 }); 118 118 119 + it('caches extensions when includeExtensions=true', () => { 120 + output.mockReturnValueOnce({ 121 + ...queryResponse, 122 + extensions: { 123 + foo: 'bar', 124 + }, 125 + }); 126 + 127 + const ssr = ssrExchange({ 128 + includeExtensions: true, 129 + }); 130 + const { source: ops$, next } = input; 131 + const exchange = ssr(exchangeInput)(ops$); 132 + 133 + publish(exchange); 134 + next(queryOperation); 135 + 136 + const data = ssr.extractData(); 137 + expect(Object.keys(data)).toEqual(['' + queryOperation.key]); 138 + 139 + expect(data).toEqual({ 140 + [queryOperation.key]: { 141 + data: '{"user":{"name":"Clive"}}', 142 + extensions: '{"foo":"bar"}', 143 + }, 144 + }); 145 + }); 146 + 119 147 it('caches complex GraphQLErrors in query results correctly', () => { 120 148 output.mockReturnValueOnce({ 121 149 ...queryResponse,
+18 -9
packages/core/src/exchanges/ssr.ts
··· 7 7 export interface SerializedResult { 8 8 hasNext?: boolean; 9 9 data?: string | undefined; // JSON string of data 10 + extensions?: string | undefined; // JSON string of data 10 11 error?: { 11 12 graphQLErrors: Array<Partial<GraphQLError> | string>; 12 13 networkError?: string; ··· 21 22 isClient?: boolean; 22 23 initialState?: SSRData; 23 24 staleWhileRevalidate?: boolean; 25 + includeExtensions?: boolean; 24 26 } 25 27 26 28 export interface SSRExchange extends Exchange { ··· 31 33 } 32 34 33 35 /** Serialize an OperationResult to plain JSON */ 34 - const serializeResult = ({ 35 - hasNext, 36 - data, 37 - error, 38 - }: OperationResult): SerializedResult => { 36 + const serializeResult = ( 37 + { hasNext, data, extensions, error }: OperationResult, 38 + includeExtensions: boolean 39 + ): SerializedResult => { 39 40 const result: SerializedResult = {}; 40 41 if (data !== undefined) result.data = JSON.stringify(data); 42 + if (includeExtensions && extensions !== undefined) { 43 + result.extensions = JSON.stringify(extensions); 44 + } 41 45 if (hasNext) result.hasNext = true; 42 46 43 47 if (error) { ··· 64 68 /** Deserialize plain JSON to an OperationResult */ 65 69 const deserializeResult = ( 66 70 operation: Operation, 67 - result: SerializedResult 71 + result: SerializedResult, 72 + includeExtensions: boolean 68 73 ): OperationResult => ({ 69 74 operation, 70 75 data: result.data ? JSON.parse(result.data) : undefined, 71 - extensions: undefined, 76 + extensions: 77 + includeExtensions && result.extensions 78 + ? JSON.parse(result.extensions) 79 + : undefined, 72 80 error: result.error 73 81 ? new CombinedError({ 74 82 networkError: result.error.networkError ··· 85 93 /** The ssrExchange can be created to capture data during SSR and also to rehydrate it on the client */ 86 94 export const ssrExchange = (params?: SSRExchangeParams): SSRExchange => { 87 95 const staleWhileRevalidate = !!(params && params.staleWhileRevalidate); 96 + const includeExtensions = !!(params && params.includeExtensions); 88 97 const data: Record<string, SerializedResult | null> = {}; 89 98 90 99 // On the client-side, we delete results from the cache as they're resolved ··· 129 138 filter(operation => !!data[operation.key]), 130 139 map(op => { 131 140 const serialized = data[op.key]!; 132 - const result = deserializeResult(op, serialized); 141 + const result = deserializeResult(op, serialized, includeExtensions); 133 142 if (staleWhileRevalidate && !revalidated.has(op.key)) { 134 143 result.stale = true; 135 144 revalidated.add(op.key); ··· 147 156 tap((result: OperationResult) => { 148 157 const { operation } = result; 149 158 if (operation.kind !== 'mutation') { 150 - const serialized = serializeResult(result); 159 + const serialized = serializeResult(result, includeExtensions); 151 160 data[operation.key] = serialized; 152 161 } 153 162 })