From bae5f156722f725f4eb080d3dd95d9a578e64bca Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Phil=20Pl=C3=BCckthun?= Date: Wed, 22 Apr 2020 19:23:19 +0100 Subject: [PATCH] Fix persistedFetchExchange import and add debug messages (#741) * Fix import of non-ESM module js-sha256 * Add dispatchDebug devtools messages to persistedFetchExchange * Add persistedFetchError debug type to core types * Fix linting errors * Remove special persistedFetchError event --- .../src/persistedFetchExchange.ts | 96 ++++++++++++++++--- exchanges/persisted-fetch/src/sha256.ts | 4 +- 2 files changed, 85 insertions(+), 15 deletions(-) diff --git a/exchanges/persisted-fetch/src/persistedFetchExchange.ts b/exchanges/persisted-fetch/src/persistedFetchExchange.ts index bd50ecd7cf..1a148960de 100644 --- a/exchanges/persisted-fetch/src/persistedFetchExchange.ts +++ b/exchanges/persisted-fetch/src/persistedFetchExchange.ts @@ -8,11 +8,13 @@ import { mergeMap, pipe, share, + onPush, takeUntil, } from 'wonka'; import { CombinedError, + ExchangeInput, Exchange, Operation, OperationResult, @@ -27,7 +29,10 @@ import { import { hash } from './sha256'; -export const persistedFetchExchange: Exchange = ({ forward }) => { +export const persistedFetchExchange: Exchange = ({ + forward, + dispatchDebug, +}) => { let supportsPersistedQueries = true; return ops$ => { @@ -43,17 +48,20 @@ export const persistedFetchExchange: Exchange = ({ forward }) => { ); if (!supportsPersistedQueries) { - return pipe(makeNormalFetchSource(operation), takeUntil(teardown$)); + return pipe( + makeNormalFetchSource(operation, dispatchDebug), + takeUntil(teardown$) + ); } return pipe( - makePersistedFetchSource(operation), + makePersistedFetchSource(operation, dispatchDebug), mergeMap(result => { if (result.error && isPersistedUnsupported(result.error)) { supportsPersistedQueries = false; - return makeNormalFetchSource(operation); + return makeNormalFetchSource(operation, dispatchDebug); } else if (result.error && isPersistedMiss(result.error)) { - return makeNormalFetchSource(operation); + return makeNormalFetchSource(operation, dispatchDebug); } return fromValue(result); @@ -74,7 +82,8 @@ export const persistedFetchExchange: Exchange = ({ forward }) => { }; const makePersistedFetchSource = ( - operation: Operation + operation: Operation, + dispatchDebug: ExchangeInput['dispatchDebug'] ): Source => { const body = makeFetchBody(operation); const query: string = body.query!; @@ -90,24 +99,85 @@ const makePersistedFetchSource = ( }, }; - return makeFetchSource( + const url = makeFetchURL(operation, { ...body, query: '' }); + const fetchOptions = makeFetchOptions(operation, body); + + dispatchDebug({ + type: 'fetchRequest', + message: 'A fetch request for a persisted query is being executed.', operation, - makeFetchURL(operation, { ...body, query: '' }), - makeFetchOptions(operation, body) + data: { + url, + fetchOptions, + }, + }); + + return pipe( + makeFetchSource(operation, url, fetchOptions), + onPush(result => { + const persistFail = + result.error && + (isPersistedMiss(result.error) || + isPersistedUnsupported(result.error)); + const error = !result.data ? result.error : undefined; + + dispatchDebug({ + // TODO: Assign a new name to this once @urql/devtools supports it + type: persistFail || error ? 'fetchError' : 'fetchSuccess', + message: persistFail + ? 'A Persisted Query request has failed. A non-persisted GraphQL request will follow.' + : `A ${ + error ? 'failed' : 'successful' + } fetch response has been returned.`, + operation, + data: { + url, + fetchOptions, + value: persistFail ? result.error! : error || result, + }, + }); + }) ); }) ); }; const makeNormalFetchSource = ( - operation: Operation + operation: Operation, + dispatchDebug: ExchangeInput['dispatchDebug'] ): Source => { const body = makeFetchBody(operation); + const url = makeFetchURL(operation, body); + const fetchOptions = makeFetchOptions(operation, body); - return makeFetchSource( + dispatchDebug({ + type: 'fetchRequest', + message: 'A fetch request is being executed.', operation, - makeFetchURL(operation, body), - makeFetchOptions(operation, body) + data: { + url, + fetchOptions, + }, + }); + + return pipe( + makeFetchSource(operation, url, fetchOptions), + onPush(result => { + const error = !result.data ? result.error : undefined; + + dispatchDebug({ + type: error ? 'fetchError' : 'fetchSuccess', + message: `A ${ + error ? 'failed' : 'successful' + } fetch response has been returned.`, + operation, + data: { + url, + fetchOptions, + value: error || result, + }, + }); + }) ); }; diff --git a/exchanges/persisted-fetch/src/sha256.ts b/exchanges/persisted-fetch/src/sha256.ts index a0b9b803c2..c37aa2622e 100644 --- a/exchanges/persisted-fetch/src/sha256.ts +++ b/exchanges/persisted-fetch/src/sha256.ts @@ -1,4 +1,4 @@ -import { sha256 as sha256Standard } from 'js-sha256'; +import sha256Standard from 'js-sha256'; const jsCrypto = typeof window !== 'undefined' @@ -46,7 +46,7 @@ const sha256 = (bytes: Uint8Array): Promise => { export const hash = async (query: string): Promise => { // Node.js support if (typeof window === 'undefined') { - return Promise.resolve(sha256Standard(query)); + return Promise.resolve(sha256Standard.sha256(query)); } let buf: Uint8Array;