From 203f896bf1e24e45cdbea45ae52be3d5496177a0 Mon Sep 17 00:00:00 2001 From: George He Date: Tue, 7 May 2024 10:11:14 +0800 Subject: [PATCH 01/26] feat: display status of sending request steps --- packages/insomnia/src/common/constants.ts | 1 - .../insomnia/src/network/request-timing.ts | 69 +++++++++++++++++++ .../src/ui/components/panes/response-pane.tsx | 1 + .../src/ui/components/response-timer.tsx | 58 ++++++++++++++-- packages/insomnia/src/ui/css/main.css | 3 + packages/insomnia/src/ui/routes/request.tsx | 39 +++++++++++ 6 files changed, 163 insertions(+), 8 deletions(-) create mode 100644 packages/insomnia/src/network/request-timing.ts diff --git a/packages/insomnia/src/common/constants.ts b/packages/insomnia/src/common/constants.ts index c8c0bedca27..edff8feec69 100644 --- a/packages/insomnia/src/common/constants.ts +++ b/packages/insomnia/src/common/constants.ts @@ -57,7 +57,6 @@ export const getClientString = () => `${getAppEnvironment()}::${getAppPlatform() // Global Stuff export const DEBOUNCE_MILLIS = 100; -export const REQUEST_TIME_TO_SHOW_COUNTER = 1; // Seconds /** * A number in milliseconds representing the time required to setup and teardown a request. diff --git a/packages/insomnia/src/network/request-timing.ts b/packages/insomnia/src/network/request-timing.ts new file mode 100644 index 00000000000..362754b550d --- /dev/null +++ b/packages/insomnia/src/network/request-timing.ts @@ -0,0 +1,69 @@ +export interface TimingRecord { + stepName: string; + isDone: boolean; + startedAt: number; + endedAt: number; +} + +export interface RequestTiming { + records: TimingRecord[]; + cb?: (records: TimingRecord[]) => void; +} + +type TimingCallback = (records: TimingRecord[]) => void; + +const requestTimingRecords = new Map(); +// only one observer is allowed for simplicity +const requestTimingObservers = new Map(); + +export function addRequestTimingRecord( + executionId: string, + record: TimingRecord, +) { + const existingRecords = requestTimingRecords.get(executionId); + + if (existingRecords) { + if (existingRecords?.length > 0) { + const theLatestRecord = existingRecords[existingRecords.length - 1]; + theLatestRecord.isDone = true; + theLatestRecord.endedAt = Date.now(); + } + existingRecords.push(record); + requestTimingRecords.set(executionId, existingRecords); + + const observer = requestTimingObservers.get(executionId); + if (observer) { + observer(existingRecords); + } + } else { + requestTimingRecords.set(executionId, [record]); + + const observer = requestTimingObservers.get(executionId); + if (observer) { + observer([record]); + } + } +} + +export function endRequestTiming(executionId: string, endedAt: number) { + const existingRecords = requestTimingRecords.get(executionId); + + if (existingRecords && existingRecords.length > 0) { + const theLatestRecord = existingRecords[existingRecords.length - 1]; + theLatestRecord.endedAt = endedAt; + + const observer = requestTimingObservers.get(executionId); + if (observer) { + observer(existingRecords); + } + } +} + +export function deleteRequestTiming(executionId: string) { + requestTimingRecords.delete(executionId); + requestTimingObservers.delete(executionId); +} + +export function watchRequestTiming(executionId: string, cb: TimingCallback) { + requestTimingObservers.set(executionId, cb); +} diff --git a/packages/insomnia/src/ui/components/panes/response-pane.tsx b/packages/insomnia/src/ui/components/panes/response-pane.tsx index f6f137f4daf..d49ca695ce0 100644 --- a/packages/insomnia/src/ui/components/panes/response-pane.tsx +++ b/packages/insomnia/src/ui/components/panes/response-pane.tsx @@ -231,6 +231,7 @@ export const ResponsePane: FC = ({ {runningRequests[activeRequest._id] && cancelRequestById(activeRequest._id)} + activeRequestId={activeRequest._id} />} diff --git a/packages/insomnia/src/ui/components/response-timer.tsx b/packages/insomnia/src/ui/components/response-timer.tsx index a4352c5143f..bbe19c371d1 100644 --- a/packages/insomnia/src/ui/components/response-timer.tsx +++ b/packages/insomnia/src/ui/components/response-timer.tsx @@ -1,13 +1,18 @@ import React, { DOMAttributes, FunctionComponent, useEffect, useState } from 'react'; -import { REQUEST_SETUP_TEARDOWN_COMPENSATION, REQUEST_TIME_TO_SHOW_COUNTER } from '../../common/constants'; +import { REQUEST_SETUP_TEARDOWN_COMPENSATION } from '../../common/constants'; +import { TimingRecord, watchRequestTiming } from '../../network/request-timing'; +import { invariant } from '../../utils/invariant'; interface Props { handleCancel: DOMAttributes['onClick']; + activeRequestId?: string; } -export const ResponseTimer: FunctionComponent = ({ handleCancel }) => { +export const ResponseTimer: FunctionComponent = ({ handleCancel, activeRequestId }) => { const [milliseconds, setMilliseconds] = useState(0); + const [timingCount, setTimingCount] = useState(0); + const [timingRecords, setTimingRecords] = useState(new Array()); useEffect(() => { let interval: NodeJS.Timeout | null = null; @@ -24,15 +29,54 @@ export const ResponseTimer: FunctionComponent = ({ handleCancel }) => { }; }, []); + const executionId = activeRequestId; + + useEffect(() => { + invariant(executionId, 'activeRequestId is undefined'); + + const cb = (records: TimingRecord[]) => { + if (records && records.length !== timingCount) { + setMilliseconds(0); + setTimingCount(records.length); + } + setTimingRecords(records); + }; + + watchRequestTiming(executionId, cb); + }); + const seconds = milliseconds / 1000; + + const timingList = timingRecords.map((record: TimingRecord) => { + const timingToDisplay = record.isDone ? + ((record.endedAt - record.startedAt) / 1000) : seconds; + + return ( +
+
+ { + record.isDone ? + () : + () + } + {record.stepName} +
+
+ {timingToDisplay > 0 ? `${timingToDisplay.toFixed(2)}s` : '0s'} +
+
+ ); + }); + return (
-

- {seconds >= REQUEST_TIME_TO_SHOW_COUNTER ? `${seconds.toFixed(1)} seconds` : 'Loading'}... -

-
- +
+ {timingList}
+
); }); From 963543c87c4581a74290072cfd9abef3379266b9 Mon Sep 17 00:00:00 2001 From: George He Date: Tue, 21 May 2024 16:39:45 +0800 Subject: [PATCH 06/26] fix: spinner line height --- packages/insomnia/src/ui/css/main.css | 1 + 1 file changed, 1 insertion(+) diff --git a/packages/insomnia/src/ui/css/main.css b/packages/insomnia/src/ui/css/main.css index 0469760c8c7..0262af20db3 100644 --- a/packages/insomnia/src/ui/css/main.css +++ b/packages/insomnia/src/ui/css/main.css @@ -2913,6 +2913,7 @@ input.editable { } .response-pane .overlay .timer-list i.fa { font-size: 1.2rem; + line-height: 2rem; } .response-pane .response-pane__notify { display: flex; From 4d952e830c752e99898d2f796beba1ef7489078b Mon Sep 17 00:00:00 2001 From: George He Date: Wed, 29 May 2024 10:45:40 +0800 Subject: [PATCH 07/26] feat: add after-response script step to the progress --- packages/insomnia/src/network/request-timing.ts | 2 +- packages/insomnia/src/ui/routes/request.tsx | 10 ++++++++++ 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/packages/insomnia/src/network/request-timing.ts b/packages/insomnia/src/network/request-timing.ts index 42b171b7926..513c2526575 100644 --- a/packages/insomnia/src/network/request-timing.ts +++ b/packages/insomnia/src/network/request-timing.ts @@ -1,4 +1,4 @@ -type StepName = 'Executing pre-request script' | 'Rendering request' | 'Preparing and sending request'; +type StepName = 'Executing pre-request script' | 'Rendering request' | 'Preparing and sending request' | 'Executing after-response script'; export interface TimingRecord { stepName: StepName; diff --git a/packages/insomnia/src/ui/routes/request.tsx b/packages/insomnia/src/ui/routes/request.tsx index a8613e77da1..8a29d5dbbe2 100644 --- a/packages/insomnia/src/ui/routes/request.tsx +++ b/packages/insomnia/src/ui/routes/request.tsx @@ -451,6 +451,16 @@ export const sendAction: ActionFunction = async ({ request, params }) => { mutatedContext.request.afterResponseScript = afterResponseScript; if (requestData.request.afterResponseScript) { + addRequestTimingRecord( + requestId, + { + stepName: 'Executing after-response script', + isDone: false, + startedAt: Date.now(), + endedAt: 0, + }, + ); + const baseEnvironment = await models.environment.getOrCreateForParentId(workspaceId); const cookieJar = await models.cookieJar.getOrCreateForParentId(workspaceId); From 5e61ffcf639dd08ad44081da99880a77f78ffd81 Mon Sep 17 00:00:00 2001 From: George He Date: Tue, 4 Jun 2024 11:03:56 +0800 Subject: [PATCH 08/26] fix: add useEffect deps --- packages/insomnia/src/ui/components/response-timer.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/insomnia/src/ui/components/response-timer.tsx b/packages/insomnia/src/ui/components/response-timer.tsx index 7708cc8a60e..d6a27828c81 100644 --- a/packages/insomnia/src/ui/components/response-timer.tsx +++ b/packages/insomnia/src/ui/components/response-timer.tsx @@ -40,7 +40,7 @@ export const ResponseTimer: FunctionComponent = ({ handleCancel, activeRe }; watchRequestTiming(executionId, cb); - }); + }, [executionId, timingCount]); const seconds = milliseconds / 1000; From 54bb821263742d936e137a02cb11b36bb2982457 Mon Sep 17 00:00:00 2001 From: George He Date: Wed, 5 Jun 2024 14:44:29 +0800 Subject: [PATCH 09/26] refactor: add a function for finish last timing record and compact logic a bit --- .../insomnia/src/network/request-timing.ts | 42 +++++++------------ packages/insomnia/src/ui/routes/request.tsx | 10 ++--- 2 files changed, 19 insertions(+), 33 deletions(-) diff --git a/packages/insomnia/src/network/request-timing.ts b/packages/insomnia/src/network/request-timing.ts index 513c2526575..4c7285dd063 100644 --- a/packages/insomnia/src/network/request-timing.ts +++ b/packages/insomnia/src/network/request-timing.ts @@ -22,43 +22,29 @@ export function addRequestTimingRecord( executionId: string, record: TimingRecord, ) { - const existingRecords = requestTimingRecords.get(executionId); - + let existingRecords = requestTimingRecords.get(executionId); if (existingRecords) { - if (existingRecords?.length > 0) { - const theLatestRecord = existingRecords[existingRecords.length - 1]; - theLatestRecord.isDone = true; - theLatestRecord.endedAt = Date.now(); - } existingRecords.push(record); - requestTimingRecords.set(executionId, existingRecords); - - const observer = requestTimingObservers.get(executionId); - if (observer) { - observer(existingRecords); - } } else { - requestTimingRecords.set(executionId, [record]); + existingRecords = [record]; + } - const observer = requestTimingObservers.get(executionId); - if (observer) { - observer([record]); - } + requestTimingRecords.set(executionId, existingRecords); + const observer = requestTimingObservers.get(executionId); + if (observer) { + observer(existingRecords); } } -export function endRequestTiming(executionId: string, endedAt: number) { +export function finishLastRequestTimingRecord(executionId: string) { const existingRecords = requestTimingRecords.get(executionId); - - if (existingRecords && existingRecords.length > 0) { - const theLatestRecord = existingRecords[existingRecords.length - 1]; - theLatestRecord.endedAt = endedAt; - - const observer = requestTimingObservers.get(executionId); - if (observer) { - observer(existingRecords); - } + if (!existingRecords || existingRecords.length === 0) { + return; } + + const theLatestRecord = existingRecords[existingRecords.length - 1]; + theLatestRecord.isDone = true; + theLatestRecord.endedAt = Date.now(); } export function deleteRequestTiming(executionId: string) { diff --git a/packages/insomnia/src/ui/routes/request.tsx b/packages/insomnia/src/ui/routes/request.tsx index 8a29d5dbbe2..5ead0425240 100644 --- a/packages/insomnia/src/ui/routes/request.tsx +++ b/packages/insomnia/src/ui/routes/request.tsx @@ -30,7 +30,7 @@ import { fetchRequestData, getPreRequestScriptOutput, responseTransform, savePat import { addRequestTimingRecord, deleteRequestTiming, - endRequestTiming, + finishLastRequestTimingRecord, } from '../../network/request-timing'; import { RenderErrorSubType } from '../../templating'; import { invariant } from '../../utils/invariant'; @@ -389,6 +389,7 @@ export const sendAction: ActionFunction = async ({ request, params }) => { const afterResponseScript = `${mutatedContext.request.afterResponseScript}`; mutatedContext.request.afterResponseScript = ''; + finishLastRequestTimingRecord(requestId); addRequestTimingRecord( requestId, { @@ -422,6 +423,7 @@ export const sendAction: ActionFunction = async ({ request, params }) => { } } + finishLastRequestTimingRecord(requestId); addRequestTimingRecord( requestId, { @@ -441,14 +443,13 @@ export const sendAction: ActionFunction = async ({ request, params }) => { requestData.responseId ); - endRequestTiming(requestId, Date.now()); - const requestMeta = await models.requestMeta.getByParentId(requestId); invariant(requestMeta, 'RequestMeta not found'); const responsePatch = await responseTransform(response, requestData.activeEnvironmentId, renderedRequest, renderedResult.context); const is2XXWithBodyPath = responsePatch.statusCode && responsePatch.statusCode >= 200 && responsePatch.statusCode < 300 && responsePatch.bodyPath; const shouldWriteToFile = shouldPromptForPathAfterResponse && is2XXWithBodyPath; + finishLastRequestTimingRecord(requestId); mutatedContext.request.afterResponseScript = afterResponseScript; if (requestData.request.afterResponseScript) { addRequestTimingRecord( @@ -557,6 +558,7 @@ export const createAndSendToMockbinAction: ActionFunction = async ({ request }) const renderResult = await tryToInterpolateRequest(req, environment._id, RENDER_PURPOSE_SEND); const renderedRequest = await tryToTransformRequestWithPlugins(renderResult); + finishLastRequestTimingRecord(mockRoute._id); addRequestTimingRecord( mockRoute._id, { @@ -576,8 +578,6 @@ export const createAndSendToMockbinAction: ActionFunction = async ({ request }) responseId, ); - endRequestTiming(mockRoute._id, Date.now()); - const response = await responseTransform(res, activeEnvironmentId, renderedRequest, renderResult.context); await models.response.create(response); return null; From 25adf31c97dacb88b5383f697e13ad94cc597d3f Mon Sep 17 00:00:00 2001 From: jackkav Date: Thu, 6 Jun 2024 18:15:20 +0200 Subject: [PATCH 10/26] simplify --- .../insomnia/src/network/request-timing.ts | 27 ++++++------------- 1 file changed, 8 insertions(+), 19 deletions(-) diff --git a/packages/insomnia/src/network/request-timing.ts b/packages/insomnia/src/network/request-timing.ts index 4c7285dd063..407d1bcd972 100644 --- a/packages/insomnia/src/network/request-timing.ts +++ b/packages/insomnia/src/network/request-timing.ts @@ -22,29 +22,18 @@ export function addRequestTimingRecord( executionId: string, record: TimingRecord, ) { - let existingRecords = requestTimingRecords.get(executionId); - if (existingRecords) { - existingRecords.push(record); - } else { - existingRecords = [record]; - } - - requestTimingRecords.set(executionId, existingRecords); - const observer = requestTimingObservers.get(executionId); - if (observer) { - observer(existingRecords); - } + // append to new step to execution + const execution = [...(requestTimingRecords.get(executionId) || []), record]; + requestTimingRecords.set(executionId, execution); + requestTimingObservers.get(executionId)?.(execution); } export function finishLastRequestTimingRecord(executionId: string) { - const existingRecords = requestTimingRecords.get(executionId); - if (!existingRecords || existingRecords.length === 0) { - return; + const latest = requestTimingRecords.get(executionId)?.at(-1); + if (latest) { + latest.isDone = true; + latest.endedAt = Date.now(); } - - const theLatestRecord = existingRecords[existingRecords.length - 1]; - theLatestRecord.isDone = true; - theLatestRecord.endedAt = Date.now(); } export function deleteRequestTiming(executionId: string) { From ba7f6ccc08d39a1dda0f0ea7c81b565f0f1149fc Mon Sep 17 00:00:00 2001 From: jackkav Date: Fri, 7 Jun 2024 10:36:07 +0200 Subject: [PATCH 11/26] add tooltip --- .../insomnia/src/network/request-timing.ts | 26 ++--- .../components/mocks/mock-response-pane.tsx | 2 +- .../src/ui/components/panes/response-pane.tsx | 2 +- .../src/ui/components/tags/time-tag.tsx | 16 ++- .../websockets/realtime-response-pane.tsx | 2 +- packages/insomnia/src/ui/routes/request.tsx | 102 +++++++++--------- 6 files changed, 75 insertions(+), 75 deletions(-) diff --git a/packages/insomnia/src/network/request-timing.ts b/packages/insomnia/src/network/request-timing.ts index 407d1bcd972..c128c83fa86 100644 --- a/packages/insomnia/src/network/request-timing.ts +++ b/packages/insomnia/src/network/request-timing.ts @@ -14,33 +14,29 @@ export interface RequestTiming { type TimingCallback = (records: TimingRecord[]) => void; -const requestTimingRecords = new Map(); +export const requestTimingRecords = new Map(); // only one observer is allowed for simplicity const requestTimingObservers = new Map(); - +export const getExecution = (requestId?: string) => requestId ? requestTimingRecords.get(requestId) : []; +export const startRequestTimingExecution = (requestId: string) => requestTimingRecords.set(requestId, []); export function addRequestTimingRecord( - executionId: string, + requestId: string, record: TimingRecord, ) { // append to new step to execution - const execution = [...(requestTimingRecords.get(executionId) || []), record]; - requestTimingRecords.set(executionId, execution); - requestTimingObservers.get(executionId)?.(execution); + const execution = [...(requestTimingRecords.get(requestId) || []), record]; + requestTimingRecords.set(requestId, execution); + requestTimingObservers.get(requestId)?.(execution); } -export function finishLastRequestTimingRecord(executionId: string) { - const latest = requestTimingRecords.get(executionId)?.at(-1); +export function finishLastRequestTimingRecord(requestId: string) { + const latest = requestTimingRecords.get(requestId)?.at(-1); if (latest) { latest.isDone = true; latest.endedAt = Date.now(); } } -export function deleteRequestTiming(executionId: string) { - requestTimingRecords.delete(executionId); - requestTimingObservers.delete(executionId); -} - -export function watchRequestTiming(executionId: string, cb: TimingCallback) { - requestTimingObservers.set(executionId, cb); +export function watchRequestTiming(requestId: string, cb: TimingCallback) { + requestTimingObservers.set(requestId, cb); } diff --git a/packages/insomnia/src/ui/components/mocks/mock-response-pane.tsx b/packages/insomnia/src/ui/components/mocks/mock-response-pane.tsx index 8b832d6091d..063d9c570e4 100644 --- a/packages/insomnia/src/ui/components/mocks/mock-response-pane.tsx +++ b/packages/insomnia/src/ui/components/mocks/mock-response-pane.tsx @@ -80,7 +80,7 @@ export const MockResponsePane = () => {
- +
diff --git a/packages/insomnia/src/ui/components/panes/response-pane.tsx b/packages/insomnia/src/ui/components/panes/response-pane.tsx index d9bfbcdbd58..c2afb2599cb 100644 --- a/packages/insomnia/src/ui/components/panes/response-pane.tsx +++ b/packages/insomnia/src/ui/components/panes/response-pane.tsx @@ -145,7 +145,7 @@ export const ResponsePane: FC = ({
- +
= memo(({ milliseconds, small, className, tooltipDelay }) => { +export const TimeTag: FC = memo(({ milliseconds, small, className, tooltipDelay, requestId }) => { let unit = 'ms'; let number = milliseconds; @@ -30,8 +32,7 @@ export const TimeTag: FC = memo(({ milliseconds, small, className, toolti } else { number = Math.round(number * 100) / 100; } - - const description = `${milliseconds.toFixed(3)} milliseconds`; + const steparray = getExecution(requestId); return (
= memo(({ milliseconds, small, className, toolti className, )} > - + +
{milliseconds.toFixed(3)} ms
+ {steparray?.map(step => (
{step.stepName} {step.endedAt - step.startedAt}ms
))} + } + position="bottom" + delay={tooltipDelay} + > {number} {unit}
diff --git a/packages/insomnia/src/ui/components/websockets/realtime-response-pane.tsx b/packages/insomnia/src/ui/components/websockets/realtime-response-pane.tsx index a156d22b1d5..e387bd6cc3f 100644 --- a/packages/insomnia/src/ui/components/websockets/realtime-response-pane.tsx +++ b/packages/insomnia/src/ui/components/websockets/realtime-response-pane.tsx @@ -128,7 +128,7 @@ const RealtimeActiveResponsePane: FC<{ response: WebSocketResponse | Response }>
- +
{ invariant(workspaceId, 'Workspace ID is required'); const { shouldPromptForPathAfterResponse, ignoreUndefinedEnvVariable } = await request.json() as SendActionParams; try { + startRequestTimingExecution(requestId); addRequestTimingRecord( requestId, { @@ -472,6 +473,7 @@ export const sendAction: ActionFunction = async ({ request, params }) => { cookieJar, response, }); + finishLastRequestTimingRecord(requestId); if (!postMutatedContext?.request) { // exiy early if there was a problem with the pre-request script // TODO: improve error message? @@ -516,8 +518,6 @@ export const sendAction: ActionFunction = async ({ request, params }) => { url.searchParams.set('missingKey', e?.extraInfo?.missingKey); } return redirect(`${url.pathname}?${url.searchParams}`); - } finally { - deleteRequestTiming(requestId); } }; @@ -534,56 +534,52 @@ export const createAndSendToMockbinAction: ActionFunction = async ({ request }) invariant(testRequest, 'mock route is missing a testing request'); const req = await models.request.update(testRequest, patch); - try { - const { - environment, - settings, - clientCertificates, - caCert, - activeEnvironmentId, - timelinePath, - responseId, - } = await fetchRequestData(req._id); - - addRequestTimingRecord( - mockRoute._id, - { - stepName: 'Rendering request', - isDone: false, - startedAt: Date.now(), - endedAt: 0, - }, - ); - - const renderResult = await tryToInterpolateRequest(req, environment._id, RENDER_PURPOSE_SEND); - const renderedRequest = await tryToTransformRequestWithPlugins(renderResult); - - finishLastRequestTimingRecord(mockRoute._id); - addRequestTimingRecord( - mockRoute._id, - { - stepName: 'Preparing and sending request', - isDone: false, - startedAt: Date.now(), - endedAt: 0, - }, - ); - - const res = await sendCurlAndWriteTimeline( - renderedRequest, - clientCertificates, - caCert, - settings, - timelinePath, - responseId, - ); - - const response = await responseTransform(res, activeEnvironmentId, renderedRequest, renderResult.context); - await models.response.create(response); - return null; - } finally { - deleteRequestTiming(mockRoute._id); - } + const { + environment, + settings, + clientCertificates, + caCert, + activeEnvironmentId, + timelinePath, + responseId, + } = await fetchRequestData(req._id); + startRequestTimingExecution(req._id); + addRequestTimingRecord( + req._id, + { + stepName: 'Rendering request', + isDone: false, + startedAt: Date.now(), + endedAt: 0, + }, + ); + + const renderResult = await tryToInterpolateRequest(req, environment._id, RENDER_PURPOSE_SEND); + const renderedRequest = await tryToTransformRequestWithPlugins(renderResult); + + finishLastRequestTimingRecord(req._id); + addRequestTimingRecord( + req._id, + { + stepName: 'Preparing and sending request', + isDone: false, + startedAt: Date.now(), + endedAt: 0, + }, + ); + + const res = await sendCurlAndWriteTimeline( + renderedRequest, + clientCertificates, + caCert, + settings, + timelinePath, + responseId, + ); + + const response = await responseTransform(res, activeEnvironmentId, renderedRequest, renderResult.context); + await models.response.create(response); + return null; }; export const deleteAllResponsesAction: ActionFunction = async ({ params }) => { const { workspaceId, requestId } = params; From 6a69d49ce4e35a26e88d8742105f96e1f3ced2bb Mon Sep 17 00:00:00 2001 From: jackkav Date: Fri, 7 Jun 2024 12:07:14 +0200 Subject: [PATCH 12/26] fix timer --- packages/insomnia/src/common/constants.ts | 10 ---- .../insomnia/src/network/request-timing.ts | 33 ++++++------ .../src/ui/components/panes/response-pane.tsx | 5 +- .../src/ui/components/response-timer.tsx | 50 ++++++++----------- 4 files changed, 38 insertions(+), 60 deletions(-) diff --git a/packages/insomnia/src/common/constants.ts b/packages/insomnia/src/common/constants.ts index edff8feec69..9b434b7e0c8 100644 --- a/packages/insomnia/src/common/constants.ts +++ b/packages/insomnia/src/common/constants.ts @@ -58,16 +58,6 @@ export const getClientString = () => `${getAppEnvironment()}::${getAppPlatform() // Global Stuff export const DEBOUNCE_MILLIS = 100; -/** - * A number in milliseconds representing the time required to setup and teardown a request. - * - * Should not be used for anything a user may rely on for performance metrics of any kind. - * - * While this isn't a perfect "magic-number" (it can be as low as 120ms and as high as 300) it serves as a rough average. - * - * For initial introduction, see https://github.com/Kong/insomnia/blob/8aa274d21b351c4710f0bb833cba7deea3d56c29/app/ui/components/ResponsePane.js#L100 -*/ -export const REQUEST_SETUP_TEARDOWN_COMPENSATION = 200; export const STATUS_CODE_PLUGIN_ERROR = -222; export const LARGE_RESPONSE_MB = 5; export const HUGE_RESPONSE_MB = 100; diff --git a/packages/insomnia/src/network/request-timing.ts b/packages/insomnia/src/network/request-timing.ts index c128c83fa86..3234201f669 100644 --- a/packages/insomnia/src/network/request-timing.ts +++ b/packages/insomnia/src/network/request-timing.ts @@ -1,42 +1,37 @@ type StepName = 'Executing pre-request script' | 'Rendering request' | 'Preparing and sending request' | 'Executing after-response script'; -export interface TimingRecord { +export interface TimingStep { stepName: StepName; isDone: boolean; startedAt: number; endedAt: number; } -export interface RequestTiming { - records: TimingRecord[]; - cb?: (records: TimingRecord[]) => void; -} - -type TimingCallback = (records: TimingRecord[]) => void; - -export const requestTimingRecords = new Map(); +type TimingCallback = (steps: TimingStep[]) => void; +// this is intentially ephemeral state because we only use breifly while waiting for requests or checking the timings +export const executions = new Map(); // only one observer is allowed for simplicity -const requestTimingObservers = new Map(); -export const getExecution = (requestId?: string) => requestId ? requestTimingRecords.get(requestId) : []; -export const startRequestTimingExecution = (requestId: string) => requestTimingRecords.set(requestId, []); +const executionObservers = new Map(); +export const getExecution = (requestId?: string) => requestId ? executions.get(requestId) : []; +export const startRequestTimingExecution = (requestId: string) => executions.set(requestId, []); export function addRequestTimingRecord( requestId: string, - record: TimingRecord, + record: TimingStep, ) { // append to new step to execution - const execution = [...(requestTimingRecords.get(requestId) || []), record]; - requestTimingRecords.set(requestId, execution); - requestTimingObservers.get(requestId)?.(execution); + const execution = [...(executions.get(requestId) || []), record]; + executions.set(requestId, execution); + executionObservers.get(requestId)?.(execution); } export function finishLastRequestTimingRecord(requestId: string) { - const latest = requestTimingRecords.get(requestId)?.at(-1); + const latest = executions.get(requestId)?.at(-1); if (latest) { latest.isDone = true; latest.endedAt = Date.now(); } } -export function watchRequestTiming(requestId: string, cb: TimingCallback) { - requestTimingObservers.set(requestId, cb); +export function watchExecution(requestId: string, cb: TimingCallback) { + executionObservers.set(requestId, cb); } diff --git a/packages/insomnia/src/ui/components/panes/response-pane.tsx b/packages/insomnia/src/ui/components/panes/response-pane.tsx index c2afb2599cb..edec8af9d36 100644 --- a/packages/insomnia/src/ui/components/panes/response-pane.tsx +++ b/packages/insomnia/src/ui/components/panes/response-pane.tsx @@ -127,7 +127,7 @@ export const ResponsePane: FC = ({ } // If there is no previous response, show placeholder for loading indicator - if (!activeResponse) { + if (runningRequests[activeRequest._id]) { return ( {runningRequests[activeRequest._id] && = ({ ); } + if (!activeResponse) { + return (); + } const timeline = models.response.getTimeline(activeResponse); const cookieHeaders = getSetCookieHeaders(activeResponse.headers); return ( diff --git a/packages/insomnia/src/ui/components/response-timer.tsx b/packages/insomnia/src/ui/components/response-timer.tsx index d6a27828c81..bfef1898ac9 100644 --- a/packages/insomnia/src/ui/components/response-timer.tsx +++ b/packages/insomnia/src/ui/components/response-timer.tsx @@ -1,26 +1,20 @@ import React, { DOMAttributes, FunctionComponent, useEffect, useState } from 'react'; -import { REQUEST_SETUP_TEARDOWN_COMPENSATION } from '../../common/constants'; -import { TimingRecord, watchRequestTiming } from '../../network/request-timing'; +import { getExecution, TimingStep, watchExecution } from '../../network/request-timing'; interface Props { handleCancel: DOMAttributes['onClick']; activeRequestId: string; } - -export const ResponseTimer: FunctionComponent = ({ handleCancel, activeRequestId }) => { +// triggers a 100 ms render in order to show a incrementing counter +const MillisecondTimer = () => { const [milliseconds, setMilliseconds] = useState(0); - const [timingCount, setTimingCount] = useState(0); - const [timingRecords, setTimingRecords] = useState(new Array()); - - const executionId = activeRequestId; - useEffect(() => { let interval: NodeJS.Timeout | null = null; const loadStartTime = Date.now(); - interval = setInterval(() => { - setMilliseconds(Date.now() - loadStartTime - REQUEST_SETUP_TEARDOWN_COMPENSATION); + const delta = Date.now() - loadStartTime; + setMilliseconds(delta); }, 100); return () => { if (interval !== null) { @@ -29,28 +23,23 @@ export const ResponseTimer: FunctionComponent = ({ handleCancel, activeRe } }; }, []); + const ms = (milliseconds / 1000); + return ms > 0 ? `${ms.toFixed(1)} s` : '0 s'; +}; +export const ResponseTimer: FunctionComponent = ({ handleCancel, activeRequestId }) => { + const execution = getExecution(activeRequestId); + const [steps, setSteps] = useState(execution || new Array()); useEffect(() => { - const cb = (records: TimingRecord[]) => { - if (records && records.length !== timingCount) { - setMilliseconds(0); - setTimingCount(records.length); - } - setTimingRecords(records); - }; - - watchRequestTiming(executionId, cb); - }, [executionId, timingCount]); - - const seconds = milliseconds / 1000; - - const timingList = timingRecords.map((record: TimingRecord) => { - const timingToDisplay = record.isDone ? - ((record.endedAt - record.startedAt) / 1000) : seconds; + watchExecution(activeRequestId, (steps: TimingStep[]) => { + setSteps(steps); + }); + }, [activeRequestId, steps.length]); + const timingList = steps.map((record: TimingStep) => { return (
@@ -65,9 +54,10 @@ export const ResponseTimer: FunctionComponent = ({ handleCancel, activeRe {record.stepName}
-
+ {record.isDone ? `${((record.endedAt - record.startedAt) / 1000).toFixed(1)} s` : ()} + {/*
{timingToDisplay > 0 ? `${timingToDisplay.toFixed(2)}s` : '0s'} -
+
*/}
); }); From 7c0b09acfa2a23d0b8f90096654eaa4d69222f0d Mon Sep 17 00:00:00 2001 From: jackkav Date: Fri, 7 Jun 2024 12:56:14 +0200 Subject: [PATCH 13/26] use duration --- packages/insomnia/src/network/request-timing.ts | 6 ++---- .../insomnia/src/ui/components/response-timer.tsx | 7 ++----- .../insomnia/src/ui/components/tags/time-tag.tsx | 4 ++-- packages/insomnia/src/ui/routes/request.tsx | 12 ------------ 4 files changed, 6 insertions(+), 23 deletions(-) diff --git a/packages/insomnia/src/network/request-timing.ts b/packages/insomnia/src/network/request-timing.ts index 3234201f669..6cfb9a6b81f 100644 --- a/packages/insomnia/src/network/request-timing.ts +++ b/packages/insomnia/src/network/request-timing.ts @@ -2,9 +2,8 @@ type StepName = 'Executing pre-request script' | 'Rendering request' | 'Preparin export interface TimingStep { stepName: StepName; - isDone: boolean; startedAt: number; - endedAt: number; + duration?: number; } type TimingCallback = (steps: TimingStep[]) => void; @@ -27,8 +26,7 @@ export function addRequestTimingRecord( export function finishLastRequestTimingRecord(requestId: string) { const latest = executions.get(requestId)?.at(-1); if (latest) { - latest.isDone = true; - latest.endedAt = Date.now(); + latest.duration = (Date.now() - latest.startedAt); } } diff --git a/packages/insomnia/src/ui/components/response-timer.tsx b/packages/insomnia/src/ui/components/response-timer.tsx index bfef1898ac9..f61a12f9aab 100644 --- a/packages/insomnia/src/ui/components/response-timer.tsx +++ b/packages/insomnia/src/ui/components/response-timer.tsx @@ -45,7 +45,7 @@ export const ResponseTimer: FunctionComponent = ({ handleCancel, activeRe
{ - record.isDone ? + record.duration ? () : () } @@ -54,10 +54,7 @@ export const ResponseTimer: FunctionComponent = ({ handleCancel, activeRe {record.stepName}
- {record.isDone ? `${((record.endedAt - record.startedAt) / 1000).toFixed(1)} s` : ()} - {/*
- {timingToDisplay > 0 ? `${timingToDisplay.toFixed(2)}s` : '0s'} -
*/} + {record.duration ? `${((record.duration) / 1000).toFixed(1)} s` : ()}
); }); diff --git a/packages/insomnia/src/ui/components/tags/time-tag.tsx b/packages/insomnia/src/ui/components/tags/time-tag.tsx index 5aff8a46dc7..d4b540f66a0 100644 --- a/packages/insomnia/src/ui/components/tags/time-tag.tsx +++ b/packages/insomnia/src/ui/components/tags/time-tag.tsx @@ -45,8 +45,8 @@ export const TimeTag: FC = memo(({ milliseconds, small, className, toolti > -
{milliseconds.toFixed(3)} ms
- {steparray?.map(step => (
{step.stepName} {step.endedAt - step.startedAt}ms
))} +
{(milliseconds / 1000).toFixed(2)} s
+ {steparray?.map(step => (
{step.stepName} {step.duration?.toFixed(2) || '?'} s
))} } position="bottom" delay={tooltipDelay} diff --git a/packages/insomnia/src/ui/routes/request.tsx b/packages/insomnia/src/ui/routes/request.tsx index 77168f55ebf..3729828f6b2 100644 --- a/packages/insomnia/src/ui/routes/request.tsx +++ b/packages/insomnia/src/ui/routes/request.tsx @@ -375,9 +375,7 @@ export const sendAction: ActionFunction = async ({ request, params }) => { requestId, { stepName: 'Executing pre-request script', - isDone: false, startedAt: Date.now(), - endedAt: 0, }, ); @@ -395,9 +393,7 @@ export const sendAction: ActionFunction = async ({ request, params }) => { requestId, { stepName: 'Rendering request', - isDone: false, startedAt: Date.now(), - endedAt: 0, }, ); @@ -429,9 +425,7 @@ export const sendAction: ActionFunction = async ({ request, params }) => { requestId, { stepName: 'Preparing and sending request', - isDone: false, startedAt: Date.now(), - endedAt: 0, }, ); @@ -457,9 +451,7 @@ export const sendAction: ActionFunction = async ({ request, params }) => { requestId, { stepName: 'Executing after-response script', - isDone: false, startedAt: Date.now(), - endedAt: 0, }, ); @@ -548,9 +540,7 @@ export const createAndSendToMockbinAction: ActionFunction = async ({ request }) req._id, { stepName: 'Rendering request', - isDone: false, startedAt: Date.now(), - endedAt: 0, }, ); @@ -562,9 +552,7 @@ export const createAndSendToMockbinAction: ActionFunction = async ({ request }) req._id, { stepName: 'Preparing and sending request', - isDone: false, startedAt: Date.now(), - endedAt: 0, }, ); From a2274cb11b9e48f1e687fabe0bf61586055255c1 Mon Sep 17 00:00:00 2001 From: jackkav Date: Wed, 12 Jun 2024 07:12:55 +0200 Subject: [PATCH 14/26] improve time tag --- .../insomnia/src/network/request-timing.ts | 5 +++- .../src/ui/components/tags/time-tag.tsx | 24 ++++++++++++++----- packages/insomnia/src/ui/routes/request.tsx | 4 ++-- 3 files changed, 24 insertions(+), 9 deletions(-) diff --git a/packages/insomnia/src/network/request-timing.ts b/packages/insomnia/src/network/request-timing.ts index 6cfb9a6b81f..ae12c72bcdc 100644 --- a/packages/insomnia/src/network/request-timing.ts +++ b/packages/insomnia/src/network/request-timing.ts @@ -1,4 +1,7 @@ -type StepName = 'Executing pre-request script' | 'Rendering request' | 'Preparing and sending request' | 'Executing after-response script'; +type StepName = 'Executing pre-request script' + | 'Rendering request' + | 'Sending request' + | 'Executing after-response script'; export interface TimingStep { stepName: StepName; diff --git a/packages/insomnia/src/ui/components/tags/time-tag.tsx b/packages/insomnia/src/ui/components/tags/time-tag.tsx index d4b540f66a0..bbe007e48fc 100644 --- a/packages/insomnia/src/ui/components/tags/time-tag.tsx +++ b/packages/insomnia/src/ui/components/tags/time-tag.tsx @@ -11,8 +11,7 @@ interface Props { tooltipDelay?: number; requestId?: string; } - -export const TimeTag: FC = memo(({ milliseconds, small, className, tooltipDelay, requestId }) => { +const getTimeAndUnit = (milliseconds: number) => { let unit = 'ms'; let number = milliseconds; @@ -32,7 +31,14 @@ export const TimeTag: FC = memo(({ milliseconds, small, className, toolti } else { number = Math.round(number * 100) / 100; } + + return { number, unit }; +}; +export const TimeTag: FC = memo(({ milliseconds, small, className, tooltipDelay, requestId }) => { const steparray = getExecution(requestId); + const totalMs = steparray?.reduce((acc, step) => acc + (step.duration || 0), 0) || milliseconds; + const { number, unit } = getTimeAndUnit(totalMs); + return (
= memo(({ milliseconds, small, className, toolti )} > -
{(milliseconds / 1000).toFixed(2)} s
- {steparray?.map(step => (
{step.stepName} {step.duration?.toFixed(2) || '?'} s
))} - } + message={( +
+ {steparray?.map(step => { + const { number, unit } = getTimeAndUnit(step.duration || 0); + return (
+
{step.stepName}
{number} {unit}
+
); + })} +
Total {number} {unit}
+
)} position="bottom" delay={tooltipDelay} > diff --git a/packages/insomnia/src/ui/routes/request.tsx b/packages/insomnia/src/ui/routes/request.tsx index 3729828f6b2..ee5a87ffeee 100644 --- a/packages/insomnia/src/ui/routes/request.tsx +++ b/packages/insomnia/src/ui/routes/request.tsx @@ -424,7 +424,7 @@ export const sendAction: ActionFunction = async ({ request, params }) => { addRequestTimingRecord( requestId, { - stepName: 'Preparing and sending request', + stepName: 'Sending request', startedAt: Date.now(), }, ); @@ -551,7 +551,7 @@ export const createAndSendToMockbinAction: ActionFunction = async ({ request }) addRequestTimingRecord( req._id, { - stepName: 'Preparing and sending request', + stepName: 'Sending request', startedAt: Date.now(), }, ); From 00d09d7f8fd7a8c3f23fef852e9255ac4b4fba10 Mon Sep 17 00:00:00 2001 From: George He Date: Thu, 13 Jun 2024 18:01:50 +0800 Subject: [PATCH 15/26] refactor: replace callback with hook --- .../src/ui/components/panes/response-pane.tsx | 16 ++++++++-------- .../src/ui/components/request-url-bar.tsx | 11 ++--------- .../src/ui/components/response-timer.tsx | 16 +++++----------- packages/insomnia/src/ui/routes/debug.tsx | 9 ++++++++- 4 files changed, 23 insertions(+), 29 deletions(-) diff --git a/packages/insomnia/src/ui/components/panes/response-pane.tsx b/packages/insomnia/src/ui/components/panes/response-pane.tsx index edec8af9d36..ee105395149 100644 --- a/packages/insomnia/src/ui/components/panes/response-pane.tsx +++ b/packages/insomnia/src/ui/components/panes/response-pane.tsx @@ -8,6 +8,7 @@ import { getSetCookieHeaders } from '../../../common/misc'; import * as models from '../../../models'; import { cancelRequestById } from '../../../network/cancellation'; import { jsonPrettify } from '../../../utils/prettify/json'; +import { useExecutionState } from '../../hooks/use-execution-state'; import { useRequestMetaPatcher } from '../../hooks/use-request'; import { RequestLoaderData } from '../../routes/request'; import { useRootLoaderData } from '../../routes/root'; @@ -30,11 +31,9 @@ import { Pane, PaneHeader } from './pane'; import { PlaceholderResponsePane } from './placeholder-response-pane'; interface Props { - runningRequests: Record; activeRequestId: string; } export const ResponsePane: FC = ({ - runningRequests, activeRequestId, }) => { const { activeRequest, activeRequestMeta, activeResponse } = useRouteLoaderData('request/:requestId') as RequestLoaderData; @@ -75,6 +74,9 @@ export const ResponsePane: FC = ({ window.clipboard.writeText(bodyBuffer.toString('utf8')); } }, [handleGetResponseBody]); + + const { isLoading } = useExecutionState({ requestId: activeRequest._id }); + const handleDownloadResponseBody = useCallback(async (prettify: boolean) => { if (!activeResponse || !activeRequest) { console.warn('Nothing to download'); @@ -127,19 +129,17 @@ export const ResponsePane: FC = ({ } // If there is no previous response, show placeholder for loading indicator - if (runningRequests[activeRequest._id]) { + if (!activeResponse) { return ( - {runningRequests[activeRequest._id] && cancelRequestById(activeRequest._id)} activeRequestId={activeRequestId} />} ); } - if (!activeResponse) { - return (); - } + const timeline = models.response.getTimeline(activeResponse); const cookieHeaders = getSetCookieHeaders(activeResponse.headers); return ( @@ -235,7 +235,7 @@ export const ResponsePane: FC = ({ - {runningRequests[activeRequest._id] && cancelRequestById(activeRequest._id)} activeRequestId={activeRequestId} />} diff --git a/packages/insomnia/src/ui/components/request-url-bar.tsx b/packages/insomnia/src/ui/components/request-url-bar.tsx index 871894fe326..32ca48cad0a 100644 --- a/packages/insomnia/src/ui/components/request-url-bar.tsx +++ b/packages/insomnia/src/ui/components/request-url-bar.tsx @@ -53,7 +53,7 @@ export interface RequestUrlBarHandle { export const RequestUrlBar = forwardRef(({ handleAutocompleteUrls, uniquenessKey, - setLoading, + // setLoading, onPaste, }, ref) => { const [searchParams, setSearchParams] = useSearchParams(); @@ -105,14 +105,7 @@ export const RequestUrlBar = forwardRef(({ const [currentInterval, setCurrentInterval] = useState(null); const [currentTimeout, setCurrentTimeout] = useState(undefined); const fetcher = useFetcher(); - // TODO: unpick this loading hack. This could be simplified if submit provides a way to update state when it finishes. https://github.com/remix-run/remix/discussions/9020 - useEffect(() => { - if (fetcher.state !== 'idle') { - setLoading(true); - } else { - setLoading(false); - } - }, [fetcher.state, setLoading]); + const { organizationId, projectId, workspaceId, requestId } = useParams() as { organizationId: string; projectId: string; workspaceId: string; requestId: string }; const connect = useCallback((connectParams: ConnectActionParams) => { fetcher.submit(JSON.stringify(connectParams), diff --git a/packages/insomnia/src/ui/components/response-timer.tsx b/packages/insomnia/src/ui/components/response-timer.tsx index f61a12f9aab..a96b96667c4 100644 --- a/packages/insomnia/src/ui/components/response-timer.tsx +++ b/packages/insomnia/src/ui/components/response-timer.tsx @@ -1,6 +1,7 @@ import React, { DOMAttributes, FunctionComponent, useEffect, useState } from 'react'; -import { getExecution, TimingStep, watchExecution } from '../../network/request-timing'; +import { TimingStep } from '../../network/request-timing'; +import { useExecutionState } from '../hooks/use-execution-state'; interface Props { handleCancel: DOMAttributes['onClick']; @@ -27,16 +28,9 @@ const MillisecondTimer = () => { return ms > 0 ? `${ms.toFixed(1)} s` : '0 s'; }; export const ResponseTimer: FunctionComponent = ({ handleCancel, activeRequestId }) => { - const execution = getExecution(activeRequestId); - const [steps, setSteps] = useState(execution || new Array()); + const { steps, isLoading } = useExecutionState({ requestId: activeRequestId }); - useEffect(() => { - watchExecution(activeRequestId, (steps: TimingStep[]) => { - setSteps(steps); - }); - }, [activeRequestId, steps.length]); - - const timingList = steps.map((record: TimingStep) => { + const timingList = isLoading ? (steps || []).map((record: TimingStep) => { return (
= ({ handleCancel, activeRe {record.duration ? `${((record.duration) / 1000).toFixed(1)} s` : ()}
); - }); + }) : []; return (
diff --git a/packages/insomnia/src/ui/routes/debug.tsx b/packages/insomnia/src/ui/routes/debug.tsx index db5a57464b5..9f68da8bfe6 100644 --- a/packages/insomnia/src/ui/routes/debug.tsx +++ b/packages/insomnia/src/ui/routes/debug.tsx @@ -91,6 +91,7 @@ import { getMethodShortHand } from '../components/tags/method-tag'; import { ConnectionCircle } from '../components/websockets/action-bar'; import { RealtimeResponsePane } from '../components/websockets/realtime-response-pane'; import { WebSocketRequestPane } from '../components/websockets/websocket-request-pane'; +import { useExecutionState } from '../hooks/use-execution-state'; import { useReadyState } from '../hooks/use-ready-state'; import { CreateRequestType, @@ -164,6 +165,11 @@ const getRequestNameOrFallback = (doc: Request | RequestGroup | GrpcRequest | We return !isRequestGroup(doc) ? doc.name || doc.url || 'Untitled request' : doc.name || 'Untitled folder'; }; +const RequestTiming = ({ requestId }: { requestId: string }) => { + const { isLoading } = useExecutionState({ requestId }); + return isLoading ? : null; +}; + export const Debug: FC = () => { const { activeWorkspace, @@ -1252,6 +1258,7 @@ export const Debug: FC = () => { }} /> {isWebSocketRequest(item.doc) && } + {isRequest(item.doc) && } {isEventStreamRequest(item.doc) && } {item.pinned && ( @@ -1376,7 +1383,7 @@ export const Debug: FC = () => { )} {activeRequest && isRequest(activeRequest) && !isRealtimeRequest && ( - + )} From 9a011534909e39950b2ee7a765a066bdee0db3a5 Mon Sep 17 00:00:00 2001 From: George He Date: Thu, 13 Jun 2024 22:38:48 +0800 Subject: [PATCH 16/26] fix: add the missing hook --- .../src/ui/hooks/use-execution-state.ts | 49 +++++++++++++++++++ 1 file changed, 49 insertions(+) create mode 100644 packages/insomnia/src/ui/hooks/use-execution-state.ts diff --git a/packages/insomnia/src/ui/hooks/use-execution-state.ts b/packages/insomnia/src/ui/hooks/use-execution-state.ts new file mode 100644 index 00000000000..02d0c0a0967 --- /dev/null +++ b/packages/insomnia/src/ui/hooks/use-execution-state.ts @@ -0,0 +1,49 @@ +// import { protocol } from 'electron'; +import { useEffect, useState } from 'react'; + +import { getExecution, TimingStep, watchExecution } from '../../network/request-timing'; + +export function useExecutionState({ requestId }: { requestId: string }) { + const [steps, setSteps] = useState(); + + useEffect(() => { + let isMounted = true; + const fn = () => { + const targetSteps = getExecution(requestId); + if (targetSteps) { + isMounted && setSteps(targetSteps); + } + }; + + fn(); + + return () => { + isMounted = false; + }; + }, [requestId]); + + useEffect(() => { + let isMounted = true; + + watchExecution(requestId, (steps: TimingStep[]) => { + isMounted && setSteps(steps); + }); + + return () => { + isMounted = false; + }; + }, [requestId]); + + const isExecuting = () => { + if (!steps) { + return false; + } else if (steps.length === 0) { + return true; + } + + const latest = steps[steps.length - 1]; + return latest.duration === undefined; + }; + + return { steps, isLoading: isExecuting() }; +} From 7d44de57149f0ac4c7731a7f8db438164e97789b Mon Sep 17 00:00:00 2001 From: jackkav Date: Thu, 13 Jun 2024 17:24:45 +0200 Subject: [PATCH 17/26] rename isExecuting --- .../src/ui/components/panes/request-pane.tsx | 3 --- .../src/ui/components/panes/response-pane.tsx | 6 +++--- .../src/ui/components/request-url-bar.tsx | 2 -- .../src/ui/components/response-timer.tsx | 4 ++-- .../src/ui/hooks/use-execution-state.ts | 2 +- packages/insomnia/src/ui/routes/debug.tsx | 17 ++--------------- packages/insomnia/src/ui/routes/request.tsx | 2 -- 7 files changed, 8 insertions(+), 28 deletions(-) diff --git a/packages/insomnia/src/ui/components/panes/request-pane.tsx b/packages/insomnia/src/ui/components/panes/request-pane.tsx index 15f9b1b59e1..93433373565 100644 --- a/packages/insomnia/src/ui/components/panes/request-pane.tsx +++ b/packages/insomnia/src/ui/components/panes/request-pane.tsx @@ -31,14 +31,12 @@ import { PlaceholderRequestPane } from './placeholder-request-pane'; interface Props { environmentId: string; settings: Settings; - setLoading: (l: boolean) => void; onPaste: (text: string) => void; } export const RequestPane: FC = ({ environmentId, settings, - setLoading, onPaste, }) => { const { activeRequest, activeRequestMeta } = useRouteLoaderData('request/:requestId') as RequestLoaderData; @@ -104,7 +102,6 @@ export const RequestPane: FC = ({ uniquenessKey={uniqueKey} handleAutocompleteUrls={() => queryAllWorkspaceUrls(workspaceId, models.request.type, requestId)} nunjucksPowerUserMode={settings.nunjucksPowerUserMode} - setLoading={setLoading} onPaste={onPaste} /> diff --git a/packages/insomnia/src/ui/components/panes/response-pane.tsx b/packages/insomnia/src/ui/components/panes/response-pane.tsx index ee105395149..292a5b5b707 100644 --- a/packages/insomnia/src/ui/components/panes/response-pane.tsx +++ b/packages/insomnia/src/ui/components/panes/response-pane.tsx @@ -75,7 +75,7 @@ export const ResponsePane: FC = ({ } }, [handleGetResponseBody]); - const { isLoading } = useExecutionState({ requestId: activeRequest._id }); + const { isExecuting } = useExecutionState({ requestId: activeRequest._id }); const handleDownloadResponseBody = useCallback(async (prettify: boolean) => { if (!activeResponse || !activeRequest) { @@ -132,7 +132,7 @@ export const ResponsePane: FC = ({ if (!activeResponse) { return ( - {isLoading && cancelRequestById(activeRequest._id)} activeRequestId={activeRequestId} />} @@ -235,7 +235,7 @@ export const ResponsePane: FC = ({ - {isLoading && cancelRequestById(activeRequest._id)} activeRequestId={activeRequestId} />} diff --git a/packages/insomnia/src/ui/components/request-url-bar.tsx b/packages/insomnia/src/ui/components/request-url-bar.tsx index 32ca48cad0a..5f1ef3d8e05 100644 --- a/packages/insomnia/src/ui/components/request-url-bar.tsx +++ b/packages/insomnia/src/ui/components/request-url-bar.tsx @@ -42,7 +42,6 @@ interface Props { handleAutocompleteUrls: () => Promise; nunjucksPowerUserMode: boolean; uniquenessKey: string; - setLoading: (l: boolean) => void; onPaste: (text: string) => void; } @@ -53,7 +52,6 @@ export interface RequestUrlBarHandle { export const RequestUrlBar = forwardRef(({ handleAutocompleteUrls, uniquenessKey, - // setLoading, onPaste, }, ref) => { const [searchParams, setSearchParams] = useSearchParams(); diff --git a/packages/insomnia/src/ui/components/response-timer.tsx b/packages/insomnia/src/ui/components/response-timer.tsx index a96b96667c4..d49c9db2dbc 100644 --- a/packages/insomnia/src/ui/components/response-timer.tsx +++ b/packages/insomnia/src/ui/components/response-timer.tsx @@ -28,9 +28,9 @@ const MillisecondTimer = () => { return ms > 0 ? `${ms.toFixed(1)} s` : '0 s'; }; export const ResponseTimer: FunctionComponent = ({ handleCancel, activeRequestId }) => { - const { steps, isLoading } = useExecutionState({ requestId: activeRequestId }); + const { steps, isExecuting } = useExecutionState({ requestId: activeRequestId }); - const timingList = isLoading ? (steps || []).map((record: TimingStep) => { + const timingList = isExecuting ? (steps || []).map((record: TimingStep) => { return (
{ - const { isLoading } = useExecutionState({ requestId }); - return isLoading ? : null; + const { isExecuting } = useExecutionState({ requestId }); + return isExecuting ? : null; }; export const Debug: FC = () => { @@ -233,18 +233,6 @@ export const Debug: FC = () => { }, []); const { settings } = useRootLoaderData(); - const [runningRequests, setRunningRequests] = useState< - Record - >({}); - const setLoading = (isLoading: boolean) => { - invariant(requestId, 'No active request'); - if (Boolean(runningRequests?.[requestId]) !== isLoading) { - setRunningRequests({ - ...runningRequests, - [requestId]: isLoading ? true : false, - }); - } - }; const grpcState = grpcStates.find(s => s.requestId === requestId); const setGrpcState = (newState: GrpcRequestState) => @@ -1355,7 +1343,6 @@ export const Debug: FC = () => { { setPastedCurl(text); setPasteCurlModalOpen(true); diff --git a/packages/insomnia/src/ui/routes/request.tsx b/packages/insomnia/src/ui/routes/request.tsx index ee5a87ffeee..22c5a0f1075 100644 --- a/packages/insomnia/src/ui/routes/request.tsx +++ b/packages/insomnia/src/ui/routes/request.tsx @@ -476,7 +476,6 @@ export const sendAction: ActionFunction = async ({ request, params }) => { if (!shouldWriteToFile) { const response = await models.response.create(responsePatch, requestData.settings.maxHistoryResponses); await models.requestMeta.update(requestMeta, { activeResponseId: response._id }); - // setLoading(false); return null; } @@ -495,7 +494,6 @@ export const sendAction: ActionFunction = async ({ request, params }) => { ...(defaultPath ? { defaultPath } : {}), }); if (!filePath) { - // setLoading(false); return null; } window.localStorage.setItem('insomnia.sendAndDownloadLocation', filePath); From fe4fa81343c3a0cfea3be816cf181e4326d5ec0b Mon Sep 17 00:00:00 2001 From: jackkav Date: Fri, 14 Jun 2024 14:51:27 +0200 Subject: [PATCH 18/26] delay snippet --- .../src/ui/components/editors/request-script-editor.tsx | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/packages/insomnia/src/ui/components/editors/request-script-editor.tsx b/packages/insomnia/src/ui/components/editors/request-script-editor.tsx index 69da1b265bb..a70aa31e735 100644 --- a/packages/insomnia/src/ui/components/editors/request-script-editor.tsx +++ b/packages/insomnia/src/ui/components/editors/request-script-editor.tsx @@ -58,6 +58,7 @@ const updateRequestAuth = 'bearer' );`; const requireAModule = "const atob = require('atob');"; +const delay = 'new Promise((resolve)=>setTimeout(resolve, 1000));'; const getStatusCode = 'const statusCode = insomnia.response.code;'; const getStatusMsg = 'const status = insomnia.response.status;'; @@ -336,6 +337,11 @@ const miscMenu: SnippetMenuItem = { 'name': 'Require a module', 'snippet': requireAModule, }, + { + 'id': 'delay', + 'name': 'Delay', + 'snippet': delay, + }, ], }; From aee342fbd6a0d19a91fa9e384d9960b4de421b15 Mon Sep 17 00:00:00 2001 From: jackkav Date: Mon, 17 Jun 2024 13:29:37 +0200 Subject: [PATCH 19/26] works --- packages/insomnia/src/main/ipc/electron.ts | 6 ++- packages/insomnia/src/main/ipc/main.ts | 17 ++++++ .../src/{ => main}/network/request-timing.ts | 17 +++--- packages/insomnia/src/preload.ts | 4 ++ .../components/mocks/mock-response-pane.tsx | 2 +- .../src/ui/components/panes/response-pane.tsx | 4 +- .../src/ui/components/response-timer.tsx | 2 +- .../src/ui/components/tags/time-tag.tsx | 11 ++-- .../websockets/realtime-response-pane.tsx | 2 +- .../src/ui/hooks/use-execution-state.ts | 20 ++++--- packages/insomnia/src/ui/routes/request.tsx | 54 +++++++++---------- 11 files changed, 80 insertions(+), 59 deletions(-) rename packages/insomnia/src/{ => main}/network/request-timing.ts (67%) diff --git a/packages/insomnia/src/main/ipc/electron.ts b/packages/insomnia/src/main/ipc/electron.ts index a892267b75d..1383698300f 100644 --- a/packages/insomnia/src/main/ipc/electron.ts +++ b/packages/insomnia/src/main/ipc/electron.ts @@ -14,6 +14,7 @@ export type HandleChannels = | 'curl.readyState' | 'curlRequest' | 'database.caCertificate.create' + | 'getExecution' | 'grpc.loadMethods' | 'grpc.loadMethodsFromReflection' | 'installPlugin' @@ -63,7 +64,10 @@ export type MainOnChannels = | 'trackSegmentEvent' | 'webSocket.close' | 'webSocket.closeAll' - | 'writeText'; + | 'writeText' + | 'addRequestTimingRecord' + | 'finishLastRequestTimingRecord' + | 'startRequestTimingExecution'; export type RendererOnChannels = 'clear-all-models' | 'clear-model' diff --git a/packages/insomnia/src/main/ipc/main.ts b/packages/insomnia/src/main/ipc/main.ts index 800ee7529fa..1949c88d8a6 100644 --- a/packages/insomnia/src/main/ipc/main.ts +++ b/packages/insomnia/src/main/ipc/main.ts @@ -9,6 +9,7 @@ import { backup, restoreBackup } from '../backup'; import installPlugin from '../install-plugin'; import { CurlBridgeAPI } from '../network/curl'; import { cancelCurlRequest, curlRequest } from '../network/libcurl-promise'; +import { addRequestTimingRecord, finishLastRequestTimingRecord, getExecution, startRequestTimingExecution, TimingStep } from '../network/request-timing'; import { WebSocketBridgeAPI } from '../network/websocket'; import { ipcMainHandle, ipcMainOn, type RendererOnChannels } from './electron'; import { gRPCBridgeAPI } from './grpc'; @@ -41,8 +42,24 @@ export interface RendererToMainBridgeAPI { }; }; hiddenBrowserWindow: HiddenBrowserWindowBridgeAPI; + getExecution: (options: { requestId: string }) => Promise; + addRequestTimingRecord: (options: { requestId: string; record: TimingStep }) => void; + startRequestTimingExecution: (options: { requestId: string }) => void; + finishLastRequestTimingRecord: (options: { requestId: string }) => void; } export function registerMainHandlers() { + ipcMainOn('addRequestTimingRecord', (_, options: { requestId: string; record: TimingStep }) => { + addRequestTimingRecord(options.requestId, options.record); + }); + ipcMainOn('startRequestTimingExecution', (_, options: { requestId: string }) => { + return startRequestTimingExecution(options.requestId); + }); + ipcMainOn('finishLastRequestTimingRecord', (_, options: { requestId: string }) => { + return finishLastRequestTimingRecord(options.requestId); + }); + ipcMainHandle('getExecution', (_, options: { requestId: string }) => { + return getExecution(options.requestId); + }); ipcMainHandle('database.caCertificate.create', async (_, options: { parentId: string; path: string }) => { return models.caCertificate.create(options); }); diff --git a/packages/insomnia/src/network/request-timing.ts b/packages/insomnia/src/main/network/request-timing.ts similarity index 67% rename from packages/insomnia/src/network/request-timing.ts rename to packages/insomnia/src/main/network/request-timing.ts index ae12c72bcdc..4105b3ac1aa 100644 --- a/packages/insomnia/src/network/request-timing.ts +++ b/packages/insomnia/src/main/network/request-timing.ts @@ -1,3 +1,5 @@ +import { BrowserWindow } from 'electron'; + type StepName = 'Executing pre-request script' | 'Rendering request' | 'Sending request' @@ -9,11 +11,7 @@ export interface TimingStep { duration?: number; } -type TimingCallback = (steps: TimingStep[]) => void; -// this is intentially ephemeral state because we only use breifly while waiting for requests or checking the timings export const executions = new Map(); -// only one observer is allowed for simplicity -const executionObservers = new Map(); export const getExecution = (requestId?: string) => requestId ? executions.get(requestId) : []; export const startRequestTimingExecution = (requestId: string) => executions.set(requestId, []); export function addRequestTimingRecord( @@ -23,7 +21,9 @@ export function addRequestTimingRecord( // append to new step to execution const execution = [...(executions.get(requestId) || []), record]; executions.set(requestId, execution); - executionObservers.get(requestId)?.(execution); + for (const window of BrowserWindow.getAllWindows()) { + window.webContents.send(`syncTimers.${requestId}`, { executions: executions.get(requestId) }); + } } export function finishLastRequestTimingRecord(requestId: string) { @@ -31,8 +31,7 @@ export function finishLastRequestTimingRecord(requestId: string) { if (latest) { latest.duration = (Date.now() - latest.startedAt); } -} - -export function watchExecution(requestId: string, cb: TimingCallback) { - executionObservers.set(requestId, cb); + for (const window of BrowserWindow.getAllWindows()) { + window.webContents.send(`syncTimers.${requestId}`, { executions: executions.get(requestId) }); + } } diff --git a/packages/insomnia/src/preload.ts b/packages/insomnia/src/preload.ts index a56a5daac7b..d3da189d16e 100644 --- a/packages/insomnia/src/preload.ts +++ b/packages/insomnia/src/preload.ts @@ -41,6 +41,10 @@ const grpc: gRPCBridgeAPI = { loadMethodsFromReflection: options => ipcRenderer.invoke('grpc.loadMethodsFromReflection', options), }; const main: Window['main'] = { + startRequestTimingExecution: options => ipcRenderer.send('startRequestTimingExecution', options), + addRequestTimingRecord: options => ipcRenderer.send('addRequestTimingRecord', options), + finishLastRequestTimingRecord: options => ipcRenderer.send('finishLastRequestTimingRecord', options), + getExecution: options => ipcRenderer.invoke('getExecution', options), loginStateChange: () => ipcRenderer.send('loginStateChange'), restart: () => ipcRenderer.send('restart'), openInBrowser: options => ipcRenderer.send('openInBrowser', options), diff --git a/packages/insomnia/src/ui/components/mocks/mock-response-pane.tsx b/packages/insomnia/src/ui/components/mocks/mock-response-pane.tsx index 063d9c570e4..f92121b3644 100644 --- a/packages/insomnia/src/ui/components/mocks/mock-response-pane.tsx +++ b/packages/insomnia/src/ui/components/mocks/mock-response-pane.tsx @@ -80,7 +80,7 @@ export const MockResponsePane = () => {
- +
diff --git a/packages/insomnia/src/ui/components/panes/response-pane.tsx b/packages/insomnia/src/ui/components/panes/response-pane.tsx index 292a5b5b707..506ef67bc47 100644 --- a/packages/insomnia/src/ui/components/panes/response-pane.tsx +++ b/packages/insomnia/src/ui/components/panes/response-pane.tsx @@ -75,7 +75,7 @@ export const ResponsePane: FC = ({ } }, [handleGetResponseBody]); - const { isExecuting } = useExecutionState({ requestId: activeRequest._id }); + const { isExecuting, steps } = useExecutionState({ requestId: activeRequest._id }); const handleDownloadResponseBody = useCallback(async (prettify: boolean) => { if (!activeResponse || !activeRequest) { @@ -148,7 +148,7 @@ export const ResponsePane: FC = ({
- +
{ let unit = 'ms'; @@ -34,9 +34,8 @@ const getTimeAndUnit = (milliseconds: number) => { return { number, unit }; }; -export const TimeTag: FC = memo(({ milliseconds, small, className, tooltipDelay, requestId }) => { - const steparray = getExecution(requestId); - const totalMs = steparray?.reduce((acc, step) => acc + (step.duration || 0), 0) || milliseconds; +export const TimeTag: FC = memo(({ milliseconds, small, className, tooltipDelay, steps }) => { + const totalMs = steps?.reduce((acc, step) => acc + (step.duration || 0), 0) || milliseconds; const { number, unit } = getTimeAndUnit(totalMs); return ( @@ -52,7 +51,7 @@ export const TimeTag: FC = memo(({ milliseconds, small, className, toolti - {steparray?.map(step => { + {steps?.map(step => { const { number, unit } = getTimeAndUnit(step.duration || 0); return (
{step.stepName}
{number} {unit}
diff --git a/packages/insomnia/src/ui/components/websockets/realtime-response-pane.tsx b/packages/insomnia/src/ui/components/websockets/realtime-response-pane.tsx index e387bd6cc3f..6fdfb074148 100644 --- a/packages/insomnia/src/ui/components/websockets/realtime-response-pane.tsx +++ b/packages/insomnia/src/ui/components/websockets/realtime-response-pane.tsx @@ -128,7 +128,7 @@ const RealtimeActiveResponsePane: FC<{ response: WebSocketResponse | Response }>
- +
(); useEffect(() => { let isMounted = true; - const fn = () => { - const targetSteps = getExecution(requestId); + const fn = async () => { + const targetSteps = await window.main.getExecution({ requestId }); if (targetSteps) { isMounted && setSteps(targetSteps); } }; - fn(); - return () => { isMounted = false; }; @@ -24,13 +21,14 @@ export function useExecutionState({ requestId }: { requestId: string }) { useEffect(() => { let isMounted = true; - - watchExecution(requestId, (steps: TimingStep[]) => { - isMounted && setSteps(steps); - }); - + // @ts-expect-error -- we use a dynamic channel here + const unsubscribe = window.main.on(`syncTimers.${requestId}`, + (_, { executions }: { executions: TimingStep[] }) => { + isMounted && setSteps(executions); + }); return () => { isMounted = false; + unsubscribe(); }; }, [requestId]); diff --git a/packages/insomnia/src/ui/routes/request.tsx b/packages/insomnia/src/ui/routes/request.tsx index 22c5a0f1075..6b0f2127b9a 100644 --- a/packages/insomnia/src/ui/routes/request.tsx +++ b/packages/insomnia/src/ui/routes/request.tsx @@ -27,11 +27,6 @@ import { isWebSocketRequest, isWebSocketRequestId, WebSocketRequest } from '../. import { WebSocketResponse } from '../../models/websocket-response'; import { getAuthHeader } from '../../network/authentication'; import { fetchRequestData, getPreRequestScriptOutput, responseTransform, savePatchesMadeByScript, sendCurlAndWriteTimeline, tryToExecuteAfterResponseScript, tryToInterpolateRequest, tryToTransformRequestWithPlugins } from '../../network/network'; -import { - addRequestTimingRecord, - finishLastRequestTimingRecord, - startRequestTimingExecution, -} from '../../network/request-timing'; import { RenderErrorSubType } from '../../templating'; import { invariant } from '../../utils/invariant'; import { SegmentEvent } from '../analytics'; @@ -370,13 +365,14 @@ export const sendAction: ActionFunction = async ({ request, params }) => { invariant(workspaceId, 'Workspace ID is required'); const { shouldPromptForPathAfterResponse, ignoreUndefinedEnvVariable } = await request.json() as SendActionParams; try { - startRequestTimingExecution(requestId); - addRequestTimingRecord( + window.main.startRequestTimingExecution({ requestId }); + window.main.addRequestTimingRecord({ requestId, - { + record: { stepName: 'Executing pre-request script', startedAt: Date.now(), }, + } ); const requestData = await fetchRequestData(requestId); @@ -388,13 +384,14 @@ export const sendAction: ActionFunction = async ({ request, params }) => { const afterResponseScript = `${mutatedContext.request.afterResponseScript}`; mutatedContext.request.afterResponseScript = ''; - finishLastRequestTimingRecord(requestId); - addRequestTimingRecord( + window.main.finishLastRequestTimingRecord({ requestId }); + window.main.addRequestTimingRecord({ requestId, - { + record: { stepName: 'Rendering request', startedAt: Date.now(), }, + } ); const renderedResult = await tryToInterpolateRequest( @@ -420,13 +417,14 @@ export const sendAction: ActionFunction = async ({ request, params }) => { } } - finishLastRequestTimingRecord(requestId); - addRequestTimingRecord( + window.main.finishLastRequestTimingRecord({ requestId }); + window.main.addRequestTimingRecord({ requestId, - { + record: { stepName: 'Sending request', startedAt: Date.now(), }, + } ); const response = await sendCurlAndWriteTimeline( @@ -444,15 +442,16 @@ export const sendAction: ActionFunction = async ({ request, params }) => { const is2XXWithBodyPath = responsePatch.statusCode && responsePatch.statusCode >= 200 && responsePatch.statusCode < 300 && responsePatch.bodyPath; const shouldWriteToFile = shouldPromptForPathAfterResponse && is2XXWithBodyPath; - finishLastRequestTimingRecord(requestId); + window.main.finishLastRequestTimingRecord({ requestId }); mutatedContext.request.afterResponseScript = afterResponseScript; if (requestData.request.afterResponseScript) { - addRequestTimingRecord( + window.main.addRequestTimingRecord({ requestId, - { + record: { stepName: 'Executing after-response script', startedAt: Date.now(), }, + } ); const baseEnvironment = await models.environment.getOrCreateForParentId(workspaceId); @@ -465,7 +464,7 @@ export const sendAction: ActionFunction = async ({ request, params }) => { cookieJar, response, }); - finishLastRequestTimingRecord(requestId); + window.main.finishLastRequestTimingRecord({ requestId }); if (!postMutatedContext?.request) { // exiy early if there was a problem with the pre-request script // TODO: improve error message? @@ -533,26 +532,27 @@ export const createAndSendToMockbinAction: ActionFunction = async ({ request }) timelinePath, responseId, } = await fetchRequestData(req._id); - startRequestTimingExecution(req._id); - addRequestTimingRecord( - req._id, - { + window.main.startRequestTimingExecution({ requestId: req._id }); + window.main.addRequestTimingRecord({ + requestId: req._id, + record: { stepName: 'Rendering request', startedAt: Date.now(), }, + } ); const renderResult = await tryToInterpolateRequest(req, environment._id, RENDER_PURPOSE_SEND); const renderedRequest = await tryToTransformRequestWithPlugins(renderResult); - finishLastRequestTimingRecord(req._id); - addRequestTimingRecord( - req._id, - { + window.main.finishLastRequestTimingRecord({ requestId: req._id }); + window.main.addRequestTimingRecord({ + requestId: req._id, + record: { stepName: 'Sending request', startedAt: Date.now(), }, - ); + }); const res = await sendCurlAndWriteTimeline( renderedRequest, From 24e1307a31bf6cf05b836838d06582e08ea446b2 Mon Sep 17 00:00:00 2001 From: jackkav Date: Mon, 17 Jun 2024 18:16:25 +0200 Subject: [PATCH 20/26] rename bridge methods --- packages/insomnia/src/main/ipc/electron.ts | 6 ++--- packages/insomnia/src/main/ipc/main.ts | 20 +++++++------- .../src/main/network/request-timing.ts | 8 +++--- packages/insomnia/src/preload.ts | 6 ++--- .../components/mocks/mock-response-pane.tsx | 3 +++ .../src/ui/components/panes/response-pane.tsx | 1 + .../src/ui/components/response-timer.tsx | 10 +++---- .../src/ui/hooks/use-execution-state.ts | 7 +++-- packages/insomnia/src/ui/routes/request.tsx | 26 +++++++++---------- 9 files changed, 45 insertions(+), 42 deletions(-) diff --git a/packages/insomnia/src/main/ipc/electron.ts b/packages/insomnia/src/main/ipc/electron.ts index 1383698300f..8b17633f4fb 100644 --- a/packages/insomnia/src/main/ipc/electron.ts +++ b/packages/insomnia/src/main/ipc/electron.ts @@ -65,9 +65,9 @@ export type MainOnChannels = | 'webSocket.close' | 'webSocket.closeAll' | 'writeText' - | 'addRequestTimingRecord' - | 'finishLastRequestTimingRecord' - | 'startRequestTimingExecution'; + | 'addExecutionStep' + | 'completeExecutionStep' + | 'startExecution'; export type RendererOnChannels = 'clear-all-models' | 'clear-model' diff --git a/packages/insomnia/src/main/ipc/main.ts b/packages/insomnia/src/main/ipc/main.ts index 1949c88d8a6..6fa3d9c0b94 100644 --- a/packages/insomnia/src/main/ipc/main.ts +++ b/packages/insomnia/src/main/ipc/main.ts @@ -9,7 +9,7 @@ import { backup, restoreBackup } from '../backup'; import installPlugin from '../install-plugin'; import { CurlBridgeAPI } from '../network/curl'; import { cancelCurlRequest, curlRequest } from '../network/libcurl-promise'; -import { addRequestTimingRecord, finishLastRequestTimingRecord, getExecution, startRequestTimingExecution, TimingStep } from '../network/request-timing'; +import { addExecutionStep, completeExecutionStep, getExecution, startExecution, TimingStep } from '../network/request-timing'; import { WebSocketBridgeAPI } from '../network/websocket'; import { ipcMainHandle, ipcMainOn, type RendererOnChannels } from './electron'; import { gRPCBridgeAPI } from './grpc'; @@ -43,19 +43,19 @@ export interface RendererToMainBridgeAPI { }; hiddenBrowserWindow: HiddenBrowserWindowBridgeAPI; getExecution: (options: { requestId: string }) => Promise; - addRequestTimingRecord: (options: { requestId: string; record: TimingStep }) => void; - startRequestTimingExecution: (options: { requestId: string }) => void; - finishLastRequestTimingRecord: (options: { requestId: string }) => void; + addExecutionStep: (options: { requestId: string; record: TimingStep }) => void; + startExecution: (options: { requestId: string }) => void; + completeExecutionStep: (options: { requestId: string }) => void; } export function registerMainHandlers() { - ipcMainOn('addRequestTimingRecord', (_, options: { requestId: string; record: TimingStep }) => { - addRequestTimingRecord(options.requestId, options.record); + ipcMainOn('addExecutionStep', (_, options: { requestId: string; record: TimingStep }) => { + addExecutionStep(options.requestId, options.record); }); - ipcMainOn('startRequestTimingExecution', (_, options: { requestId: string }) => { - return startRequestTimingExecution(options.requestId); + ipcMainOn('startExecution', (_, options: { requestId: string }) => { + return startExecution(options.requestId); }); - ipcMainOn('finishLastRequestTimingRecord', (_, options: { requestId: string }) => { - return finishLastRequestTimingRecord(options.requestId); + ipcMainOn('completeExecutionStep', (_, options: { requestId: string }) => { + return completeExecutionStep(options.requestId); }); ipcMainHandle('getExecution', (_, options: { requestId: string }) => { return getExecution(options.requestId); diff --git a/packages/insomnia/src/main/network/request-timing.ts b/packages/insomnia/src/main/network/request-timing.ts index 4105b3ac1aa..4369fae5c22 100644 --- a/packages/insomnia/src/main/network/request-timing.ts +++ b/packages/insomnia/src/main/network/request-timing.ts @@ -10,11 +10,10 @@ export interface TimingStep { startedAt: number; duration?: number; } - export const executions = new Map(); export const getExecution = (requestId?: string) => requestId ? executions.get(requestId) : []; -export const startRequestTimingExecution = (requestId: string) => executions.set(requestId, []); -export function addRequestTimingRecord( +export const startExecution = (requestId: string) => executions.set(requestId, []); +export function addExecutionStep( requestId: string, record: TimingStep, ) { @@ -25,8 +24,7 @@ export function addRequestTimingRecord( window.webContents.send(`syncTimers.${requestId}`, { executions: executions.get(requestId) }); } } - -export function finishLastRequestTimingRecord(requestId: string) { +export function completeExecutionStep(requestId: string) { const latest = executions.get(requestId)?.at(-1); if (latest) { latest.duration = (Date.now() - latest.startedAt); diff --git a/packages/insomnia/src/preload.ts b/packages/insomnia/src/preload.ts index d3da189d16e..e22b1267815 100644 --- a/packages/insomnia/src/preload.ts +++ b/packages/insomnia/src/preload.ts @@ -41,9 +41,9 @@ const grpc: gRPCBridgeAPI = { loadMethodsFromReflection: options => ipcRenderer.invoke('grpc.loadMethodsFromReflection', options), }; const main: Window['main'] = { - startRequestTimingExecution: options => ipcRenderer.send('startRequestTimingExecution', options), - addRequestTimingRecord: options => ipcRenderer.send('addRequestTimingRecord', options), - finishLastRequestTimingRecord: options => ipcRenderer.send('finishLastRequestTimingRecord', options), + startExecution: options => ipcRenderer.send('startExecution', options), + addExecutionStep: options => ipcRenderer.send('addExecutionStep', options), + completeExecutionStep: options => ipcRenderer.send('completeExecutionStep', options), getExecution: options => ipcRenderer.invoke('getExecution', options), loginStateChange: () => ipcRenderer.send('loginStateChange'), restart: () => ipcRenderer.send('restart'), diff --git a/packages/insomnia/src/ui/components/mocks/mock-response-pane.tsx b/packages/insomnia/src/ui/components/mocks/mock-response-pane.tsx index f92121b3644..094ddf63c9c 100644 --- a/packages/insomnia/src/ui/components/mocks/mock-response-pane.tsx +++ b/packages/insomnia/src/ui/components/mocks/mock-response-pane.tsx @@ -15,6 +15,7 @@ import { Response } from '../../../models/response'; import { cancelRequestById } from '../../../network/cancellation'; import { insomniaFetch } from '../../../ui/insomniaFetch'; import { jsonPrettify } from '../../../utils/prettify/json'; +import { useExecutionState } from '../../hooks/use-execution-state'; import { MockRouteLoaderData } from '../../routes/mock-route'; import { useRootLoaderData } from '../../routes/root'; import { Dropdown, DropdownButton, DropdownItem, DropdownSection, ItemContent } from '../base/dropdown'; @@ -54,6 +55,7 @@ export const MockResponsePane = () => { const [timeline, setTimeline] = useState([]); const [previewMode, setPreviewMode] = useState(PREVIEW_MODE_FRIENDLY); const requestFetcher = useFetcher({ key: 'mock-request-fetcher' }); + const { steps } = useExecutionState({ requestId: activeResponse?.parentId }); useEffect(() => { const fn = async () => { @@ -70,6 +72,7 @@ export const MockResponsePane = () => { { activeResponse && cancelRequestById(activeResponse.parentId)} activeRequestId={mockRoute._id} + steps={steps} />} ); diff --git a/packages/insomnia/src/ui/components/panes/response-pane.tsx b/packages/insomnia/src/ui/components/panes/response-pane.tsx index 506ef67bc47..51cab16922f 100644 --- a/packages/insomnia/src/ui/components/panes/response-pane.tsx +++ b/packages/insomnia/src/ui/components/panes/response-pane.tsx @@ -135,6 +135,7 @@ export const ResponsePane: FC = ({ {isExecuting && cancelRequestById(activeRequest._id)} activeRequestId={activeRequestId} + steps={steps} />} ); diff --git a/packages/insomnia/src/ui/components/response-timer.tsx b/packages/insomnia/src/ui/components/response-timer.tsx index b79b8a32572..73e289a7bf7 100644 --- a/packages/insomnia/src/ui/components/response-timer.tsx +++ b/packages/insomnia/src/ui/components/response-timer.tsx @@ -1,11 +1,11 @@ import React, { DOMAttributes, FunctionComponent, useEffect, useState } from 'react'; import type { TimingStep } from '../../main/network/request-timing'; -import { useExecutionState } from '../hooks/use-execution-state'; interface Props { handleCancel: DOMAttributes['onClick']; activeRequestId: string; + steps: TimingStep[]; } // triggers a 100 ms render in order to show a incrementing counter const MillisecondTimer = () => { @@ -27,10 +27,8 @@ const MillisecondTimer = () => { const ms = (milliseconds / 1000); return ms > 0 ? `${ms.toFixed(1)} s` : '0 s'; }; -export const ResponseTimer: FunctionComponent = ({ handleCancel, activeRequestId }) => { - const { steps, isExecuting } = useExecutionState({ requestId: activeRequestId }); - - const timingList = isExecuting ? (steps || []).map((record: TimingStep) => { +export const ResponseTimer: FunctionComponent = ({ handleCancel, activeRequestId, steps }) => { + const timingList = steps.map((record: TimingStep) => { return (
= ({ handleCancel, activeRe {record.duration ? `${((record.duration) / 1000).toFixed(1)} s` : ()}
); - }) : []; + }); return (
diff --git a/packages/insomnia/src/ui/hooks/use-execution-state.ts b/packages/insomnia/src/ui/hooks/use-execution-state.ts index 542b6002a31..d92c516b8a7 100644 --- a/packages/insomnia/src/ui/hooks/use-execution-state.ts +++ b/packages/insomnia/src/ui/hooks/use-execution-state.ts @@ -2,12 +2,15 @@ import { useEffect, useState } from 'react'; import { TimingStep } from '../../main/network/request-timing'; -export function useExecutionState({ requestId }: { requestId: string }) { - const [steps, setSteps] = useState(); +export function useExecutionState({ requestId }: { requestId?: string }) { + const [steps, setSteps] = useState([]); useEffect(() => { let isMounted = true; const fn = async () => { + if (!requestId) { + return; + } const targetSteps = await window.main.getExecution({ requestId }); if (targetSteps) { isMounted && setSteps(targetSteps); diff --git a/packages/insomnia/src/ui/routes/request.tsx b/packages/insomnia/src/ui/routes/request.tsx index 6b0f2127b9a..8fa4bb546b0 100644 --- a/packages/insomnia/src/ui/routes/request.tsx +++ b/packages/insomnia/src/ui/routes/request.tsx @@ -365,8 +365,8 @@ export const sendAction: ActionFunction = async ({ request, params }) => { invariant(workspaceId, 'Workspace ID is required'); const { shouldPromptForPathAfterResponse, ignoreUndefinedEnvVariable } = await request.json() as SendActionParams; try { - window.main.startRequestTimingExecution({ requestId }); - window.main.addRequestTimingRecord({ + window.main.startExecution({ requestId }); + window.main.addExecutionStep({ requestId, record: { stepName: 'Executing pre-request script', @@ -384,8 +384,8 @@ export const sendAction: ActionFunction = async ({ request, params }) => { const afterResponseScript = `${mutatedContext.request.afterResponseScript}`; mutatedContext.request.afterResponseScript = ''; - window.main.finishLastRequestTimingRecord({ requestId }); - window.main.addRequestTimingRecord({ + window.main.completeExecutionStep({ requestId }); + window.main.addExecutionStep({ requestId, record: { stepName: 'Rendering request', @@ -417,8 +417,8 @@ export const sendAction: ActionFunction = async ({ request, params }) => { } } - window.main.finishLastRequestTimingRecord({ requestId }); - window.main.addRequestTimingRecord({ + window.main.completeExecutionStep({ requestId }); + window.main.addExecutionStep({ requestId, record: { stepName: 'Sending request', @@ -442,10 +442,10 @@ export const sendAction: ActionFunction = async ({ request, params }) => { const is2XXWithBodyPath = responsePatch.statusCode && responsePatch.statusCode >= 200 && responsePatch.statusCode < 300 && responsePatch.bodyPath; const shouldWriteToFile = shouldPromptForPathAfterResponse && is2XXWithBodyPath; - window.main.finishLastRequestTimingRecord({ requestId }); + window.main.completeExecutionStep({ requestId }); mutatedContext.request.afterResponseScript = afterResponseScript; if (requestData.request.afterResponseScript) { - window.main.addRequestTimingRecord({ + window.main.addExecutionStep({ requestId, record: { stepName: 'Executing after-response script', @@ -464,7 +464,7 @@ export const sendAction: ActionFunction = async ({ request, params }) => { cookieJar, response, }); - window.main.finishLastRequestTimingRecord({ requestId }); + window.main.completeExecutionStep({ requestId }); if (!postMutatedContext?.request) { // exiy early if there was a problem with the pre-request script // TODO: improve error message? @@ -532,8 +532,8 @@ export const createAndSendToMockbinAction: ActionFunction = async ({ request }) timelinePath, responseId, } = await fetchRequestData(req._id); - window.main.startRequestTimingExecution({ requestId: req._id }); - window.main.addRequestTimingRecord({ + window.main.startExecution({ requestId: req._id }); + window.main.addExecutionStep({ requestId: req._id, record: { stepName: 'Rendering request', @@ -545,8 +545,8 @@ export const createAndSendToMockbinAction: ActionFunction = async ({ request }) const renderResult = await tryToInterpolateRequest(req, environment._id, RENDER_PURPOSE_SEND); const renderedRequest = await tryToTransformRequestWithPlugins(renderResult); - window.main.finishLastRequestTimingRecord({ requestId: req._id }); - window.main.addRequestTimingRecord({ + window.main.completeExecutionStep({ requestId: req._id }); + window.main.addExecutionStep({ requestId: req._id, record: { stepName: 'Sending request', From baaa8fb758a0035aa7bdf4a9e37a13018b2afcdc Mon Sep 17 00:00:00 2001 From: jackkav Date: Mon, 17 Jun 2024 18:46:43 +0200 Subject: [PATCH 21/26] remove undefined initial state --- .../src/ui/components/panes/response-pane.tsx | 1 + .../src/ui/components/response-timer.tsx | 44 +++++++++---------- .../src/ui/hooks/use-execution-state.ts | 6 +-- 3 files changed, 23 insertions(+), 28 deletions(-) diff --git a/packages/insomnia/src/ui/components/panes/response-pane.tsx b/packages/insomnia/src/ui/components/panes/response-pane.tsx index 51cab16922f..850a8b84444 100644 --- a/packages/insomnia/src/ui/components/panes/response-pane.tsx +++ b/packages/insomnia/src/ui/components/panes/response-pane.tsx @@ -239,6 +239,7 @@ export const ResponsePane: FC = ({ {isExecuting && cancelRequestById(activeRequest._id)} activeRequestId={activeRequestId} + steps={steps} />} diff --git a/packages/insomnia/src/ui/components/response-timer.tsx b/packages/insomnia/src/ui/components/response-timer.tsx index 73e289a7bf7..a44432e649d 100644 --- a/packages/insomnia/src/ui/components/response-timer.tsx +++ b/packages/insomnia/src/ui/components/response-timer.tsx @@ -28,33 +28,29 @@ const MillisecondTimer = () => { return ms > 0 ? `${ms.toFixed(1)} s` : '0 s'; }; export const ResponseTimer: FunctionComponent = ({ handleCancel, activeRequestId, steps }) => { - const timingList = steps.map((record: TimingStep) => { - return ( -
-
- - { - record.duration ? - () : - () - } - - - {record.stepName} - -
- {record.duration ? `${((record.duration) / 1000).toFixed(1)} s` : ()} -
- ); - }); - return (
- {timingList} + {steps.map((record: TimingStep) => ( +
+
+ + { + record.duration ? + () : + () + } + + + {record.stepName} + +
+ {record.duration ? `${((record.duration) / 1000).toFixed(1)} s` : ()} +
+ ))}
diff --git a/packages/insomnia/src/ui/hooks/use-execution-state.ts b/packages/insomnia/src/ui/hooks/use-execution-state.ts index d92c516b8a7..21bb1e5f8e7 100644 --- a/packages/insomnia/src/ui/hooks/use-execution-state.ts +++ b/packages/insomnia/src/ui/hooks/use-execution-state.ts @@ -36,12 +36,10 @@ export function useExecutionState({ requestId }: { requestId?: string }) { }, [requestId]); const isExecuting = () => { - if (!steps) { + const hasSteps = steps && steps.length > 0; + if (!hasSteps) { return false; - } else if (steps.length === 0) { - return true; } - const latest = steps[steps.length - 1]; return latest.duration === undefined; }; From c17f4b5a83989580991dda4e7a83bfd5d13dda56 Mon Sep 17 00:00:00 2001 From: jackkav Date: Tue, 18 Jun 2024 08:20:31 +0200 Subject: [PATCH 22/26] force stop execution before cancel --- packages/insomnia/src/network/cancellation.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/packages/insomnia/src/network/cancellation.ts b/packages/insomnia/src/network/cancellation.ts index ebcba8ede09..1588cd96185 100644 --- a/packages/insomnia/src/network/cancellation.ts +++ b/packages/insomnia/src/network/cancellation.ts @@ -7,6 +7,7 @@ import { Request } from '../models/request'; const cancelRequestFunctionMap = new Map void>(); export async function cancelRequestById(requestId: string) { + window.main.completeExecutionStep({ requestId }); const cancel = cancelRequestFunctionMap.get(requestId); if (cancel) { return cancel(); From e0567de656adc98f230618a4d8f5b295ba7956fd Mon Sep 17 00:00:00 2001 From: jackkav Date: Tue, 18 Jun 2024 08:26:48 +0200 Subject: [PATCH 23/26] fix time tag layout --- .../src/ui/components/tags/time-tag.tsx | 20 +++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-) diff --git a/packages/insomnia/src/ui/components/tags/time-tag.tsx b/packages/insomnia/src/ui/components/tags/time-tag.tsx index 78610087dfc..66f5dc44e96 100644 --- a/packages/insomnia/src/ui/components/tags/time-tag.tsx +++ b/packages/insomnia/src/ui/components/tags/time-tag.tsx @@ -37,7 +37,10 @@ const getTimeAndUnit = (milliseconds: number) => { export const TimeTag: FC = memo(({ milliseconds, small, className, tooltipDelay, steps }) => { const totalMs = steps?.reduce((acc, step) => acc + (step.duration || 0), 0) || milliseconds; const { number, unit } = getTimeAndUnit(totalMs); - + const timesandunits = steps?.map(step => { + const { number, unit } = getTimeAndUnit(step.duration || 0); + return { stepName: step.stepName, number, unit }; + }); return (
= memo(({ milliseconds, small, className, toolti - {steps?.map(step => { - const { number, unit } = getTimeAndUnit(step.duration || 0); - return (
-
{step.stepName}
{number} {unit}
-
); - })} -
Total {number} {unit}
+ {timesandunits?.map(step => + (
+
{step.stepName}
{step.number} {step.unit}
+
) + )} +
+
Total
{number} {unit}
+
)} position="bottom" delay={tooltipDelay} From 3212cb92537662a03d068f00b2fe1a02fe3ce4c3 Mon Sep 17 00:00:00 2001 From: jackkav Date: Tue, 18 Jun 2024 08:41:07 +0200 Subject: [PATCH 24/26] fix hang --- packages/insomnia/src/ui/routes/request.tsx | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/packages/insomnia/src/ui/routes/request.tsx b/packages/insomnia/src/ui/routes/request.tsx index 8fa4bb546b0..11235501c33 100644 --- a/packages/insomnia/src/ui/routes/request.tsx +++ b/packages/insomnia/src/ui/routes/request.tsx @@ -377,6 +377,7 @@ export const sendAction: ActionFunction = async ({ request, params }) => { const requestData = await fetchRequestData(requestId); const mutatedContext = await getPreRequestScriptOutput(requestData, workspaceId); + window.main.completeExecutionStep({ requestId }); if (mutatedContext === null) { return null; } @@ -384,7 +385,6 @@ export const sendAction: ActionFunction = async ({ request, params }) => { const afterResponseScript = `${mutatedContext.request.afterResponseScript}`; mutatedContext.request.afterResponseScript = ''; - window.main.completeExecutionStep({ requestId }); window.main.addExecutionStep({ requestId, record: { @@ -500,6 +500,7 @@ export const sendAction: ActionFunction = async ({ request, params }) => { } } catch (e) { console.log('Failed to send request', e); + window.main.completeExecutionStep({ requestId }); const url = new URL(request.url); url.searchParams.set('error', e); if (e?.extraInfo && e?.extraInfo?.subType === RenderErrorSubType.EnvironmentVariable) { @@ -565,6 +566,7 @@ export const createAndSendToMockbinAction: ActionFunction = async ({ request }) const response = await responseTransform(res, activeEnvironmentId, renderedRequest, renderResult.context); await models.response.create(response); + window.main.completeExecutionStep({ requestId: req._id }); return null; }; export const deleteAllResponsesAction: ActionFunction = async ({ params }) => { From 831aa7564fba9858eb821ee086270dff80389bca Mon Sep 17 00:00:00 2001 From: jackkav Date: Tue, 18 Jun 2024 08:43:07 +0200 Subject: [PATCH 25/26] simplify api --- packages/insomnia/src/main/ipc/main.ts | 8 ++--- .../src/main/network/request-timing.ts | 8 +++-- packages/insomnia/src/ui/routes/request.tsx | 30 ++++--------------- 3 files changed, 16 insertions(+), 30 deletions(-) diff --git a/packages/insomnia/src/main/ipc/main.ts b/packages/insomnia/src/main/ipc/main.ts index 6fa3d9c0b94..18b31acbf5b 100644 --- a/packages/insomnia/src/main/ipc/main.ts +++ b/packages/insomnia/src/main/ipc/main.ts @@ -9,7 +9,7 @@ import { backup, restoreBackup } from '../backup'; import installPlugin from '../install-plugin'; import { CurlBridgeAPI } from '../network/curl'; import { cancelCurlRequest, curlRequest } from '../network/libcurl-promise'; -import { addExecutionStep, completeExecutionStep, getExecution, startExecution, TimingStep } from '../network/request-timing'; +import { addExecutionStep, completeExecutionStep, getExecution, startExecution, StepName, TimingStep } from '../network/request-timing'; import { WebSocketBridgeAPI } from '../network/websocket'; import { ipcMainHandle, ipcMainOn, type RendererOnChannels } from './electron'; import { gRPCBridgeAPI } from './grpc'; @@ -43,13 +43,13 @@ export interface RendererToMainBridgeAPI { }; hiddenBrowserWindow: HiddenBrowserWindowBridgeAPI; getExecution: (options: { requestId: string }) => Promise; - addExecutionStep: (options: { requestId: string; record: TimingStep }) => void; + addExecutionStep: (options: { requestId: string; stepName: StepName }) => void; startExecution: (options: { requestId: string }) => void; completeExecutionStep: (options: { requestId: string }) => void; } export function registerMainHandlers() { - ipcMainOn('addExecutionStep', (_, options: { requestId: string; record: TimingStep }) => { - addExecutionStep(options.requestId, options.record); + ipcMainOn('addExecutionStep', (_, options: { requestId: string; stepName: StepName }) => { + addExecutionStep(options.requestId, options.stepName); }); ipcMainOn('startExecution', (_, options: { requestId: string }) => { return startExecution(options.requestId); diff --git a/packages/insomnia/src/main/network/request-timing.ts b/packages/insomnia/src/main/network/request-timing.ts index 4369fae5c22..8f4d25b14ec 100644 --- a/packages/insomnia/src/main/network/request-timing.ts +++ b/packages/insomnia/src/main/network/request-timing.ts @@ -1,6 +1,6 @@ import { BrowserWindow } from 'electron'; -type StepName = 'Executing pre-request script' +export type StepName = 'Executing pre-request script' | 'Rendering request' | 'Sending request' | 'Executing after-response script'; @@ -15,9 +15,13 @@ export const getExecution = (requestId?: string) => requestId ? executions.get(r export const startExecution = (requestId: string) => executions.set(requestId, []); export function addExecutionStep( requestId: string, - record: TimingStep, + stepName: StepName, ) { // append to new step to execution + const record: TimingStep = { + stepName, + startedAt: Date.now(), + }; const execution = [...(executions.get(requestId) || []), record]; executions.set(requestId, execution); for (const window of BrowserWindow.getAllWindows()) { diff --git a/packages/insomnia/src/ui/routes/request.tsx b/packages/insomnia/src/ui/routes/request.tsx index 11235501c33..e14c6c2cfce 100644 --- a/packages/insomnia/src/ui/routes/request.tsx +++ b/packages/insomnia/src/ui/routes/request.tsx @@ -368,10 +368,7 @@ export const sendAction: ActionFunction = async ({ request, params }) => { window.main.startExecution({ requestId }); window.main.addExecutionStep({ requestId, - record: { - stepName: 'Executing pre-request script', - startedAt: Date.now(), - }, + stepName: 'Executing pre-request script', } ); @@ -387,10 +384,7 @@ export const sendAction: ActionFunction = async ({ request, params }) => { window.main.addExecutionStep({ requestId, - record: { - stepName: 'Rendering request', - startedAt: Date.now(), - }, + stepName: 'Rendering request', } ); @@ -420,10 +414,7 @@ export const sendAction: ActionFunction = async ({ request, params }) => { window.main.completeExecutionStep({ requestId }); window.main.addExecutionStep({ requestId, - record: { - stepName: 'Sending request', - startedAt: Date.now(), - }, + stepName: 'Sending request', } ); @@ -447,10 +438,7 @@ export const sendAction: ActionFunction = async ({ request, params }) => { if (requestData.request.afterResponseScript) { window.main.addExecutionStep({ requestId, - record: { - stepName: 'Executing after-response script', - startedAt: Date.now(), - }, + stepName: 'Executing after-response script', } ); @@ -536,10 +524,7 @@ export const createAndSendToMockbinAction: ActionFunction = async ({ request }) window.main.startExecution({ requestId: req._id }); window.main.addExecutionStep({ requestId: req._id, - record: { - stepName: 'Rendering request', - startedAt: Date.now(), - }, + stepName: 'Rendering request', } ); @@ -549,10 +534,7 @@ export const createAndSendToMockbinAction: ActionFunction = async ({ request }) window.main.completeExecutionStep({ requestId: req._id }); window.main.addExecutionStep({ requestId: req._id, - record: { - stepName: 'Sending request', - startedAt: Date.now(), - }, + stepName: 'Sending request', }); const res = await sendCurlAndWriteTimeline( From 0a65e7dbaa6b9b457976ce6651a768011655526c Mon Sep 17 00:00:00 2001 From: jackkav Date: Tue, 18 Jun 2024 08:45:25 +0200 Subject: [PATCH 26/26] tidy up --- packages/insomnia/src/ui/routes/request.tsx | 33 ++++----------------- 1 file changed, 6 insertions(+), 27 deletions(-) diff --git a/packages/insomnia/src/ui/routes/request.tsx b/packages/insomnia/src/ui/routes/request.tsx index e14c6c2cfce..ea7f3665a1b 100644 --- a/packages/insomnia/src/ui/routes/request.tsx +++ b/packages/insomnia/src/ui/routes/request.tsx @@ -366,13 +366,8 @@ export const sendAction: ActionFunction = async ({ request, params }) => { const { shouldPromptForPathAfterResponse, ignoreUndefinedEnvVariable } = await request.json() as SendActionParams; try { window.main.startExecution({ requestId }); - window.main.addExecutionStep({ - requestId, - stepName: 'Executing pre-request script', - } - ); - const requestData = await fetchRequestData(requestId); + window.main.addExecutionStep({ requestId, stepName: 'Executing pre-request script' }); const mutatedContext = await getPreRequestScriptOutput(requestData, workspaceId); window.main.completeExecutionStep({ requestId }); if (mutatedContext === null) { @@ -382,12 +377,7 @@ export const sendAction: ActionFunction = async ({ request, params }) => { const afterResponseScript = `${mutatedContext.request.afterResponseScript}`; mutatedContext.request.afterResponseScript = ''; - window.main.addExecutionStep({ - requestId, - stepName: 'Rendering request', - } - ); - + window.main.addExecutionStep({ requestId, stepName: 'Rendering request' }); const renderedResult = await tryToInterpolateRequest( mutatedContext.request, mutatedContext.environment, @@ -397,6 +387,7 @@ export const sendAction: ActionFunction = async ({ request, params }) => { ignoreUndefinedEnvVariable, ); const renderedRequest = await tryToTransformRequestWithPlugins(renderedResult); + window.main.completeExecutionStep({ requestId }); // TODO: remove this temporary hack to support GraphQL variables in the request body properly if (renderedRequest && renderedRequest.body?.text && renderedRequest.body?.mimeType === 'application/graphql') { @@ -411,13 +402,7 @@ export const sendAction: ActionFunction = async ({ request, params }) => { } } - window.main.completeExecutionStep({ requestId }); - window.main.addExecutionStep({ - requestId, - stepName: 'Sending request', - } - ); - + window.main.addExecutionStep({ requestId, stepName: 'Sending request' }); const response = await sendCurlAndWriteTimeline( renderedRequest, mutatedContext.clientCertificates, @@ -426,6 +411,7 @@ export const sendAction: ActionFunction = async ({ request, params }) => { requestData.timelinePath, requestData.responseId ); + window.main.completeExecutionStep({ requestId }); const requestMeta = await models.requestMeta.getByParentId(requestId); invariant(requestMeta, 'RequestMeta not found'); @@ -433,18 +419,11 @@ export const sendAction: ActionFunction = async ({ request, params }) => { const is2XXWithBodyPath = responsePatch.statusCode && responsePatch.statusCode >= 200 && responsePatch.statusCode < 300 && responsePatch.bodyPath; const shouldWriteToFile = shouldPromptForPathAfterResponse && is2XXWithBodyPath; - window.main.completeExecutionStep({ requestId }); mutatedContext.request.afterResponseScript = afterResponseScript; if (requestData.request.afterResponseScript) { - window.main.addExecutionStep({ - requestId, - stepName: 'Executing after-response script', - } - ); - const baseEnvironment = await models.environment.getOrCreateForParentId(workspaceId); const cookieJar = await models.cookieJar.getOrCreateForParentId(workspaceId); - + window.main.addExecutionStep({ requestId, stepName: 'Executing after-response script' }); const postMutatedContext = await tryToExecuteAfterResponseScript({ ...requestData, ...mutatedContext,