diff --git a/packages/passport/sdk/src/magicAdapter.ts b/packages/passport/sdk/src/magicAdapter.ts index d33afe4cfb..81e806898e 100644 --- a/packages/passport/sdk/src/magicAdapter.ts +++ b/packages/passport/sdk/src/magicAdapter.ts @@ -2,10 +2,11 @@ import { SDKBase, InstanceWithExtensions } from '@magic-sdk/provider'; import { Magic } from 'magic-sdk'; import { OpenIdExtension } from '@magic-ext/oidc'; import { ethers } from 'ethers'; -import { trackDuration } from '@imtbl/metrics'; +import { Flow, trackDuration } from '@imtbl/metrics'; import { PassportErrorType, withPassportError } from './errors/passportError'; import { PassportConfiguration } from './config'; import { lazyDocumentReady } from './utils/lazyLoad'; +import { withMetricsAsync } from './utils/metrics'; type MagicClient = InstanceWithExtensions; @@ -40,23 +41,28 @@ export default class MagicAdapter { async login( idToken: string, ): Promise { - return withPassportError(async () => { - const startTime = performance.now(); + return withPassportError(async () => ( + withMetricsAsync(async (flow: Flow) => { + const startTime = performance.now(); - const magicClient = await this.magicClient; - await magicClient.openid.loginWithOIDC({ - jwt: idToken, - providerId: this.config.magicProviderId, - }); + const magicClient = await this.magicClient; + flow.addEvent('endMagicClientInit'); + + await magicClient.openid.loginWithOIDC({ + jwt: idToken, + providerId: this.config.magicProviderId, + }); + flow.addEvent('endLoginWithOIDC'); - trackDuration( - 'passport', - 'magicLogin', - Math.round(performance.now() - startTime), - ); + trackDuration( + 'passport', + flow.details.flowName, + Math.round(performance.now() - startTime), + ); - return magicClient.rpcProvider as unknown as ethers.providers.ExternalProvider; - }, PassportErrorType.WALLET_CONNECTION_ERROR); + return magicClient.rpcProvider as unknown as ethers.providers.ExternalProvider; + }, 'magicLogin') + ), PassportErrorType.WALLET_CONNECTION_ERROR); } async logout() { diff --git a/packages/passport/sdk/src/utils/lazyLoad.ts b/packages/passport/sdk/src/utils/lazyLoad.ts index 2c22dfeec6..e932c61acf 100644 --- a/packages/passport/sdk/src/utils/lazyLoad.ts +++ b/packages/passport/sdk/src/utils/lazyLoad.ts @@ -5,16 +5,18 @@ export const lazyLoad = ( export const lazyDocumentReady = (initialiseFunction: () => Promise | T): Promise => { const documentReadyPromise = () => new Promise((resolve) => { + const onReadyStateChange = () => { + if (window.document.readyState === 'complete') { + resolve(); + window.document.removeEventListener('readystatechange', onReadyStateChange); + } + }; + + // Add a handler before checking `readyState` to ensure that we don't miss the event + window.document.addEventListener('readystatechange', onReadyStateChange); if (window.document.readyState === 'complete') { resolve(); - } else { - const onReadyStateChange = () => { - if (window.document.readyState === 'complete') { - resolve(); - window.document.removeEventListener('readystatechange', onReadyStateChange); - } - }; - window.document.addEventListener('readystatechange', onReadyStateChange); + window.document.removeEventListener('readystatechange', onReadyStateChange); } }); diff --git a/packages/passport/sdk/src/utils/metrics.test.ts b/packages/passport/sdk/src/utils/metrics.test.ts index fb6792e8d0..5b64fab5ba 100644 --- a/packages/passport/sdk/src/utils/metrics.test.ts +++ b/packages/passport/sdk/src/utils/metrics.test.ts @@ -16,7 +16,7 @@ describe('passport metrics', () => { const mockFn = jest.fn(); mockFn.mockReturnValue(returnValue); - expect(withMetrics(mockFn, 'event')).toEqual(returnValue); + expect(withMetrics(mockFn, 'myFlow')).toEqual(returnValue); }); it('should track and re-throw error', () => { @@ -25,7 +25,7 @@ describe('passport metrics', () => { }); try { - withMetrics(mockFn, 'event'); + withMetrics(mockFn, 'myFlow'); } catch (error) { expect(error).toBeInstanceOf(Error); expect(error).toMatchObject({ @@ -34,7 +34,7 @@ describe('passport metrics', () => { expect(trackFlow).toBeCalledTimes(1); expect(trackError).toHaveBeenCalledWith( 'passport', - 'event', + 'myFlow', error, ); } @@ -47,7 +47,7 @@ describe('passport metrics', () => { const mockFn = jest.fn(); mockFn.mockResolvedValue(returnValue); - expect(await withMetricsAsync(mockFn, 'event')).toEqual(returnValue); + expect(await withMetricsAsync(mockFn, 'myFlow')).toEqual(returnValue); }); it('should track and re-throw error', async () => { @@ -55,7 +55,7 @@ describe('passport metrics', () => { errorFunction.mockRejectedValue(new Error('error')); try { - await withMetricsAsync(errorFunction, 'event'); + await withMetricsAsync(errorFunction, 'myFlow'); } catch (error) { expect(error).toBeInstanceOf(Error); expect(error).toMatchObject({ @@ -64,7 +64,7 @@ describe('passport metrics', () => { expect(trackFlow).toBeCalledTimes(1); expect(trackError).toHaveBeenCalledWith( 'passport', - 'event', + 'myFlow', error, ); } diff --git a/packages/passport/sdk/src/utils/metrics.ts b/packages/passport/sdk/src/utils/metrics.ts index 6f9fed8517..9c1ca8e75e 100644 --- a/packages/passport/sdk/src/utils/metrics.ts +++ b/packages/passport/sdk/src/utils/metrics.ts @@ -1,16 +1,16 @@ -import { trackError, trackFlow } from '@imtbl/metrics'; +import { Flow, trackError, trackFlow } from '@imtbl/metrics'; export const withMetrics = ( - fn: () => T, - event: string, + fn: (flow: Flow) => T, + flowName: string, ): T => { - const flow = trackFlow('passport', event); + const flow: Flow = trackFlow('passport', flowName); try { - return fn(); + return fn(flow); } catch (error) { if (error instanceof Error) { - trackError('passport', event, error); + trackError('passport', flowName, error); } flow.addEvent('errored'); throw error; @@ -20,16 +20,16 @@ export const withMetrics = ( }; export const withMetricsAsync = async ( - fn: () => Promise, - event: string, + fn: (flow: Flow) => Promise, + flowName: string, ): Promise => { - const flow = trackFlow('passport', event); + const flow: Flow = trackFlow('passport', flowName); try { - return await fn(); + return await fn(flow); } catch (error) { if (error instanceof Error) { - trackError('passport', event, error); + trackError('passport', flowName, error); } flow.addEvent('errored'); throw error;