From 323a5d954ca598b22cad469fe17957a8a9627032 Mon Sep 17 00:00:00 2001 From: FaberVitale Date: Mon, 28 Jun 2021 11:59:51 +0200 Subject: [PATCH] feat(rtk-query): display median of timings Other changes: * improved shouldExpandNode logic of QueryPreviewActions * tweaked mean logic --- .../src/components/QueryPreviewActions.tsx | 31 +++++++++++++------ .../src/types.ts | 1 + .../src/utils/rtk-query.ts | 12 +++++-- .../src/utils/statistics.ts | 27 +++++++++++++++- 4 files changed, 59 insertions(+), 12 deletions(-) diff --git a/packages/redux-devtools-rtk-query-monitor/src/components/QueryPreviewActions.tsx b/packages/redux-devtools-rtk-query-monitor/src/components/QueryPreviewActions.tsx index bb32c2f9..754e8ff1 100644 --- a/packages/redux-devtools-rtk-query-monitor/src/components/QueryPreviewActions.tsx +++ b/packages/redux-devtools-rtk-query-monitor/src/components/QueryPreviewActions.tsx @@ -32,22 +32,35 @@ export class QueryPreviewActions extends PureComponent return output; }); + isLastActionNode = (keyPath: (string | number)[], layer: number): boolean => { + if (layer >= 1) { + const len = this.props.actionsOfQuery.length; + const actionKey = keyPath[keyPath.length - 1]; + + if (typeof actionKey === 'string') { + const index = Number(actionKey.split(keySep)[0]); + + return len > 0 && len - index < 2; + } + } + + return false; + }; + shouldExpandNode = ( keyPath: (string | number)[], value: unknown, layer: number ): boolean => { if (layer === 1) { - const len = this.props.actionsOfQuery.length; - const lastKey = keyPath[keyPath.length - 1]; + return this.isLastActionNode(keyPath, layer); + } - if (typeof lastKey === 'string') { - const index = Number(lastKey.split(keySep)[0]); - - return len - index < 2; - } - - return false; + if (layer === 2) { + return ( + this.isLastActionNode(keyPath, layer) && + (keyPath[0] === 'meta' || keyPath[0] === 'error') + ); } return layer <= 1; diff --git a/packages/redux-devtools-rtk-query-monitor/src/types.ts b/packages/redux-devtools-rtk-query-monitor/src/types.ts index cad3bf1e..6960eadb 100644 --- a/packages/redux-devtools-rtk-query-monitor/src/types.ts +++ b/packages/redux-devtools-rtk-query-monitor/src/types.ts @@ -117,6 +117,7 @@ export interface QueryTimings { readonly slowest: { key: string; duration: string } | null; readonly fastest: { key: string; duration: string } | null; readonly average: string; + readonly median: string; } export interface ApiTimings { diff --git a/packages/redux-devtools-rtk-query-monitor/src/utils/rtk-query.ts b/packages/redux-devtools-rtk-query-monitor/src/utils/rtk-query.ts index 83fa3d14..c3845988 100644 --- a/packages/redux-devtools-rtk-query-monitor/src/utils/rtk-query.ts +++ b/packages/redux-devtools-rtk-query-monitor/src/utils/rtk-query.ts @@ -20,7 +20,7 @@ import { missingTagId } from '../monitor-config'; import { Comparator } from './comparators'; import { emptyArray } from './object'; import { formatMs } from './formatters'; -import { mean } from './statistics'; +import * as statistics from './statistics'; const rtkqueryApiStateKeys: ReadonlyArray = [ 'queries', @@ -283,7 +283,14 @@ function computeQueryApiTimings( } const average = - pendingDurations.length > 0 ? formatMs(mean(pendingDurations)) : '-'; + pendingDurations.length > 0 + ? formatMs(statistics.mean(pendingDurations)) + : '-'; + + const median = + pendingDurations.length > 0 + ? formatMs(statistics.median(pendingDurations)) + : '-'; return { latestFetch, @@ -291,6 +298,7 @@ function computeQueryApiTimings( slowest, fastest, average, + median, } as QueryTimings; } diff --git a/packages/redux-devtools-rtk-query-monitor/src/utils/statistics.ts b/packages/redux-devtools-rtk-query-monitor/src/utils/statistics.ts index daaff19c..7fe0f1c0 100644 --- a/packages/redux-devtools-rtk-query-monitor/src/utils/statistics.ts +++ b/packages/redux-devtools-rtk-query-monitor/src/utils/statistics.ts @@ -39,5 +39,30 @@ export function mean(nums: number[]): number { return NaN; } - return sum(nums) / nums.length; + return +(sum(nums) / nums.length).toFixed(6); +} + +/** + * Returns median value of a numeric sequence. + * @param nums + * @returns + */ +export function median(nums: number[]): number { + const len = nums.length; + + if (len === 0) { + return NaN; + } + + if (len === 1) { + return nums[0]; + } + + const sorted = nums.slice().sort(); + + if (len % 2 === 1) { + return sorted[(len + 1) / 2 - 1]; + } + + return +(0.5 * (sorted[len / 2 - 1] + sorted[len / 2])).toFixed(6); }